Mercurial > prosody-hg
comparison net/server.lua @ 65:9c471840acb9 tls
TLS: Handshake works, no data after that
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Sun, 05 Oct 2008 17:33:38 +0100 |
| parents | bcd0a3975580 |
| children | 018705d57f09 |
comparison
equal
deleted
inserted
replaced
| 64:bcd0a3975580 | 65:9c471840acb9 |
|---|---|
| 37 local string_sub = use'string'.sub | 37 local string_sub = use'string'.sub |
| 38 local coroutine_wrap = coroutine.wrap | 38 local coroutine_wrap = coroutine.wrap |
| 39 local coroutine_yield = coroutine.yield | 39 local coroutine_yield = coroutine.yield |
| 40 local print = print; | 40 local print = print; |
| 41 local out_put = function () end --print; | 41 local out_put = function () end --print; |
| 42 local out_put = print; | |
| 42 local out_error = print; | 43 local out_error = print; |
| 43 | 44 |
| 44 --// extern libs //-- | 45 --// extern libs //-- |
| 45 | 46 |
| 46 local luasec = require "ssl" | 47 local luasec = require "ssl" |
| 103 local wrapclient, err | 104 local wrapclient, err |
| 104 | 105 |
| 105 if sslctx then | 106 if sslctx then |
| 106 if not ssl_newcontext then | 107 if not ssl_newcontext then |
| 107 return nil, "luasec not found" | 108 return nil, "luasec not found" |
| 108 -- elseif not cfg_get "use_ssl" then | |
| 109 -- return nil, "ssl is deactivated" | |
| 110 end | 109 end |
| 111 if type( sslctx ) ~= "table" then | 110 if type( sslctx ) ~= "table" then |
| 112 out_error "server.lua: wrong server sslctx" | 111 out_error "server.lua: wrong server sslctx" |
| 113 return nil, "wrong server sslctx" | 112 return nil, "wrong server sslctx" |
| 114 end | 113 end |
| 117 err = err or "wrong sslctx parameters" | 116 err = err or "wrong sslctx parameters" |
| 118 out_error( "server.lua: ", err ) | 117 out_error( "server.lua: ", err ) |
| 119 return nil, err | 118 return nil, err |
| 120 end | 119 end |
| 121 wrapclient = wrapsslclient | 120 wrapclient = wrapsslclient |
| 121 wrapclient = wraptlsclient | |
| 122 else | 122 else |
| 123 wrapclient = wraptcpclient | 123 wrapclient = wraptcpclient |
| 124 end | 124 end |
| 125 | 125 |
| 126 local accept = socket.accept | 126 local accept = socket.accept |
| 354 readlist[ readlen ] = socket | 354 readlist[ readlen ] = socket |
| 355 | 355 |
| 356 return handler, socket | 356 return handler, socket |
| 357 end | 357 end |
| 358 | 358 |
| 359 wraptlsclient = function( listener, socket, ip, serverport, clientport, mode, sslctx ) -- this function wraps a tls cleint | |
| 360 | |
| 361 local dispatch, disconnect = listener.listener, listener.disconnect | |
| 362 | |
| 363 --// transform socket to ssl object //-- | |
| 364 | |
| 365 local err | |
| 366 | |
| 367 socket:settimeout( 0 ) | |
| 368 | |
| 369 --// private closures of the object //-- | |
| 370 | |
| 371 local writequeue = { } -- buffer for messages to send | |
| 372 | |
| 373 local eol -- end of buffer | |
| 374 | |
| 375 local sstat, rstat = 0, 0 | |
| 376 | |
| 377 --// local import of socket methods //-- | |
| 378 | |
| 379 local send = socket.send | |
| 380 local receive = socket.receive | |
| 381 local close = socket.close | |
| 382 --local shutdown = socket.shutdown | |
| 383 | |
| 384 --// public methods of the object //-- | |
| 385 | |
| 386 local handler = { } | |
| 387 | |
| 388 handler.getstats = function( ) | |
| 389 return rstat, sstat | |
| 390 end | |
| 391 | |
| 392 handler.listener = function( data, err ) | |
| 393 return listener( handler, data, err ) | |
| 394 end | |
| 395 handler.ssl = function( ) | |
| 396 return false | |
| 397 end | |
| 398 handler.send = function( _, data, i, j ) | |
| 399 return send( socket, data, i, j ) | |
| 400 end | |
| 401 handler.receive = function( pattern, prefix ) | |
| 402 return receive( socket, pattern, prefix ) | |
| 403 end | |
| 404 handler.shutdown = function( pattern ) | |
| 405 --return shutdown( socket, pattern ) | |
| 406 end | |
| 407 handler.close = function( closed ) | |
| 408 close( socket ) | |
| 409 writelen = ( eol and removesocket( writelist, socket, writelen ) ) or writelen | |
| 410 readlen = removesocket( readlist, socket, readlen ) | |
| 411 socketlist[ socket ] = nil | |
| 412 out_put "server.lua: closed handler and removed socket from list" | |
| 413 end | |
| 414 handler.ip = function( ) | |
| 415 return ip | |
| 416 end | |
| 417 handler.serverport = function( ) | |
| 418 return serverport | |
| 419 end | |
| 420 handler.clientport = function( ) | |
| 421 return clientport | |
| 422 end | |
| 423 | |
| 424 handler.write = function( data ) | |
| 425 if not eol then | |
| 426 writelen = writelen + 1 | |
| 427 writelist[ writelen ] = socket | |
| 428 eol = 0 | |
| 429 end | |
| 430 eol = eol + 1 | |
| 431 writequeue[ eol ] = data | |
| 432 end | |
| 433 handler.writequeue = function( ) | |
| 434 return writequeue | |
| 435 end | |
| 436 handler.socket = function( ) | |
| 437 return socket | |
| 438 end | |
| 439 handler.mode = function( ) | |
| 440 return mode | |
| 441 end | |
| 442 handler._receivedata = function( ) | |
| 443 local data, err, part = receive( socket, mode ) -- receive data in "mode" | |
| 444 if not err or ( err == "timeout" or err == "wantread" ) then -- received something | |
| 445 local data = data or part or "" | |
| 446 local count = #data * STAT_UNIT | |
| 447 rstat = rstat + count | |
| 448 receivestat = receivestat + count | |
| 449 out_put( "server.lua: read data '", data, "', error: ", err ) | |
| 450 return dispatch( handler, data, err ) | |
| 451 else -- connections was closed or fatal error | |
| 452 out_put( "server.lua: client ", ip, ":", clientport, " error: ", err ) | |
| 453 handler.close( ) | |
| 454 disconnect( handler, err ) | |
| 455 writequeue = nil | |
| 456 handler = nil | |
| 457 return false | |
| 458 end | |
| 459 end | |
| 460 handler._dispatchdata = function( ) -- this function writes data to handlers | |
| 461 local buffer = table_concat( writequeue, "", 1, eol ) | |
| 462 local succ, err, byte = send( socket, buffer ) | |
| 463 local count = ( succ or 0 ) * STAT_UNIT | |
| 464 sstat = sstat + count | |
| 465 sendstat = sendstat + count | |
| 466 out_put( "server.lua: sended '", buffer, "', bytes: ", succ, ", error: ", err, ", part: ", byte, ", to: ", ip, ":", clientport ) | |
| 467 if succ then -- sending succesful | |
| 468 --writequeue = { } | |
| 469 eol = nil | |
| 470 writelen = removesocket( writelist, socket, writelen ) -- delete socket from writelist | |
| 471 if handler.need_tls then | |
| 472 out_put("server.lua: connection is ready for tls handshake"); | |
| 473 handler.need_tls = not handler.starttls(true); | |
| 474 end | |
| 475 return true | |
| 476 elseif byte and ( err == "timeout" or err == "wantwrite" ) then -- want write | |
| 477 buffer = string_sub( buffer, byte + 1, -1 ) -- new buffer | |
| 478 writequeue[ 1 ] = buffer -- insert new buffer in queue | |
| 479 eol = 1 | |
| 480 return true | |
| 481 else -- connection was closed during sending or fatal error | |
| 482 out_put( "server.lua: client ", ip, ":", clientport, " error: ", err ) | |
| 483 handler.close( ) | |
| 484 disconnect( handler, err ) | |
| 485 writequeue = nil | |
| 486 handler = nil | |
| 487 return false | |
| 488 end | |
| 489 end | |
| 490 | |
| 491 handler.receivedata, handler.dispatchdata = handler._receivedata, handler._dispatchdata; | |
| 492 -- // COMPAT // -- | |
| 493 | |
| 494 handler.getIp = handler.ip | |
| 495 handler.getPort = handler.clientport | |
| 496 | |
| 497 --// handshake //-- | |
| 498 | |
| 499 local wrote, read | |
| 500 | |
| 501 handler.starttls = function (now) | |
| 502 if not now then handler.need_tls = true; return; end | |
| 503 out_put( "server.lua: attempting to start tls on "..tostring(socket) ) | |
| 504 socket, err = ssl_wrap( socket, sslctx ) -- wrap socket | |
| 505 out_put("sslwrapped socket is "..tostring(socket)); | |
| 506 if err then | |
| 507 out_put( "server.lua: ssl error: ", err ) | |
| 508 return nil, nil, err -- fatal error | |
| 509 end | |
| 510 socket:settimeout( 1 ) | |
| 511 send = socket.send | |
| 512 receive = socket.receive | |
| 513 close = socket.close | |
| 514 print(readlen, writelen) | |
| 515 for _, s in ipairs(readlist) do print("R:", tostring(s)) end | |
| 516 for _, s in ipairs(writelist) do print("W:", tostring(s)) end | |
| 517 handler.ssl = function( ) | |
| 518 return true | |
| 519 end | |
| 520 handler.send = function( _, data, i, j ) | |
| 521 return send( socket, data, i, j ) | |
| 522 end | |
| 523 handler.receive = function( pattern, prefix ) | |
| 524 return receive( socket, pattern, prefix ) | |
| 525 end | |
| 526 | |
| 527 handler.handshake = function (conn) | |
| 528 local succ, msg | |
| 529 out_put("ssl handshaking on socket "..tostring(conn)) | |
| 530 conn:settimeout() | |
| 531 while not succ do | |
| 532 succ, msg = conn:dohandshake() | |
| 533 out_put("msg: "..tostring(msg)) | |
| 534 if msg == 'wantread' then | |
| 535 socket_select({conn}, nil) | |
| 536 elseif msg == 'wantwrite' then | |
| 537 socket_select(nil, {conn}) | |
| 538 elseif not succ then | |
| 539 -- other error | |
| 540 _ = err ~= "closed" and close( socket ) | |
| 541 handler.close( ) | |
| 542 disconnect( handler, err ) | |
| 543 writequeue = nil | |
| 544 handler = nil | |
| 545 out_error("server.lua: ssl handshake failed"); | |
| 546 return false -- handshake failed | |
| 547 end | |
| 548 | |
| 549 end | |
| 550 out_put("server.lua: ssl handshake succeeded!"); | |
| 551 handler.receivedata = handler._receivedata; | |
| 552 handler.dispatchdata = handler._dispatchdata; | |
| 553 return true; | |
| 554 end | |
| 555 | |
| 556 handler.receivedata = handler.handshake | |
| 557 handler.dispatchdata = handler.handshake | |
| 558 | |
| 559 return handler.handshake( socket ) -- do handshake | |
| 560 end | |
| 561 | |
| 562 socketlist[ socket ] = handler | |
| 563 readlen = readlen + 1 | |
| 564 readlist[ readlen ] = socket | |
| 565 | |
| 566 return handler, socket | |
| 567 end | |
| 568 | |
| 359 wraptcpclient = function( listener, socket, ip, serverport, clientport, mode ) -- this function wraps a socket | 569 wraptcpclient = function( listener, socket, ip, serverport, clientport, mode ) -- this function wraps a socket |
| 360 | 570 |
| 361 local dispatch, disconnect = listener.listener, listener.disconnect | 571 local dispatch, disconnect = listener.listener, listener.disconnect |
| 362 | 572 |
| 363 --// private closures of the object //-- | 573 --// private closures of the object //-- |
| 431 return socket | 641 return socket |
| 432 end | 642 end |
| 433 handler.mode = function( ) | 643 handler.mode = function( ) |
| 434 return mode | 644 return mode |
| 435 end | 645 end |
| 646 | |
| 436 handler.receivedata = function( ) | 647 handler.receivedata = function( ) |
| 437 local data, err, part = receive( socket, mode ) -- receive data in "mode" | 648 local data, err, part = receive( socket, mode ) -- receive data in "mode" |
| 438 if not err or ( err == "timeout" or err == "wantread" ) then -- received something | 649 if not err or ( err == "timeout" or err == "wantread" ) then -- received something |
| 439 local data = data or part or "" | 650 local data = data or part or "" |
| 440 local count = #data * STAT_UNIT | 651 local count = #data * STAT_UNIT |
| 449 writequeue = nil | 660 writequeue = nil |
| 450 handler = nil | 661 handler = nil |
| 451 return false | 662 return false |
| 452 end | 663 end |
| 453 end | 664 end |
| 665 | |
| 454 handler.dispatchdata = function( ) -- this function writes data to handlers | 666 handler.dispatchdata = function( ) -- this function writes data to handlers |
| 455 local buffer = table_concat( writequeue, "", 1, eol ) | 667 local buffer = table_concat( writequeue, "", 1, eol ) |
| 456 local succ, err, byte = send( socket, buffer ) | 668 local succ, err, byte = send( socket, buffer ) |
| 457 local count = ( succ or 0 ) * STAT_UNIT | 669 local count = ( succ or 0 ) * STAT_UNIT |
| 458 sstat = sstat + count | 670 sstat = sstat + count |
| 571 end | 783 end |
| 572 | 784 |
| 573 loop = function( ) -- this is the main loop of the program | 785 loop = function( ) -- this is the main loop of the program |
| 574 --signal_set( "hub", "run" ) | 786 --signal_set( "hub", "run" ) |
| 575 repeat | 787 repeat |
| 788 out_put("select()") | |
| 576 local read, write, err = socket_select( readlist, writelist, 1 ) -- 1 sec timeout, nice for timers | 789 local read, write, err = socket_select( readlist, writelist, 1 ) -- 1 sec timeout, nice for timers |
| 577 for i, socket in ipairs( write ) do -- send data waiting in writequeues | 790 for i, socket in ipairs( write ) do -- send data waiting in writequeues |
| 578 local handler = socketlist[ socket ] | 791 local handler = socketlist[ socket ] |
| 579 if handler then | 792 if handler then |
| 580 handler.dispatchdata( ) | 793 handler.dispatchdata( ) |
| 591 closesocket( socket ) | 804 closesocket( socket ) |
| 592 out_put "server.lua: found no handler and closed socket (readlist)" -- this can happen | 805 out_put "server.lua: found no handler and closed socket (readlist)" -- this can happen |
| 593 end | 806 end |
| 594 end | 807 end |
| 595 firetimer( ) | 808 firetimer( ) |
| 596 --collectgarbage "collect" | 809 until false |
| 597 until false --signal_get "hub" ~= "run" | 810 return |
| 598 return --signal_get "hub" | |
| 599 end | 811 end |
| 600 | 812 |
| 601 ----------------------------------// BEGIN //-- | 813 ----------------------------------// BEGIN //-- |
| 602 | 814 |
| 603 ----------------------------------// PUBLIC INTERFACE //-- | 815 ----------------------------------// PUBLIC INTERFACE //-- |
