Mercurial > prosody-hg
comparison net/server_select.lua @ 2541:2febd008214e
net.server_select: Remove startssl parameter to the client/server creation functions - passing a sslctx now indicates you want to use SSL from the start
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Sun, 31 Jan 2010 15:37:08 +0000 |
| parents | 7be72eca5666 |
| children | 55a50e75c0c0 |
comparison
equal
deleted
inserted
replaced
| 2540:8c52b023f0b9 | 2541:2febd008214e |
|---|---|
| 158 _maxclientsperserver = 1000 | 158 _maxclientsperserver = 1000 |
| 159 | 159 |
| 160 _maxsslhandshake = 30 -- max handshake round-trips | 160 _maxsslhandshake = 30 -- max handshake round-trips |
| 161 ----------------------------------// PRIVATE //-- | 161 ----------------------------------// PRIVATE //-- |
| 162 | 162 |
| 163 wrapserver = function( listeners, socket, ip, serverport, pattern, sslctx, maxconnections, startssl ) -- this function wraps a server | 163 wrapserver = function( listeners, socket, ip, serverport, pattern, sslctx, maxconnections ) -- this function wraps a server |
| 164 | 164 |
| 165 maxconnections = maxconnections or _maxclientsperserver | 165 maxconnections = maxconnections or _maxclientsperserver |
| 166 | 166 |
| 167 local connections = 0 | 167 local connections = 0 |
| 168 | 168 |
| 169 local dispatch, disconnect = listeners.onincoming, listeners.ondisconnect | 169 local dispatch, disconnect = listeners.onincoming, listeners.ondisconnect |
| 170 | 170 |
| 171 local err | |
| 172 | |
| 173 local ssl = false | |
| 174 | |
| 175 if sslctx then | |
| 176 ssl = true | |
| 177 if not ssl_newcontext then | |
| 178 out_error "luasec not found" | |
| 179 ssl = false | |
| 180 end | |
| 181 if type( sslctx ) ~= "table" then | |
| 182 out_error "server.lua: wrong server sslctx" | |
| 183 ssl = false | |
| 184 end | |
| 185 local ctx; | |
| 186 ctx, err = ssl_newcontext( sslctx ) | |
| 187 if not ctx then | |
| 188 err = err or "wrong sslctx parameters" | |
| 189 local file; | |
| 190 file = err:match("^error loading (.-) %("); | |
| 191 if file then | |
| 192 if file == "private key" then | |
| 193 file = sslctx.key or "your private key"; | |
| 194 elseif file == "certificate" then | |
| 195 file = sslctx.certificate or "your certificate file"; | |
| 196 end | |
| 197 local reason = err:match("%((.+)%)$") or "some reason"; | |
| 198 if reason == "Permission denied" then | |
| 199 reason = "Check that the permissions allow Prosody to read this file."; | |
| 200 elseif reason == "No such file or directory" then | |
| 201 reason = "Check that the path is correct, and the file exists."; | |
| 202 elseif reason == "system lib" then | |
| 203 reason = "Previous error (see logs), or other system error."; | |
| 204 else | |
| 205 reason = "Reason: "..tostring(reason or "unknown"):lower(); | |
| 206 end | |
| 207 log("error", "SSL/TLS: Failed to load %s: %s", file, reason); | |
| 208 else | |
| 209 log("error", "SSL/TLS: Error initialising for port %d: %s", serverport, err ); | |
| 210 end | |
| 211 ssl = false | |
| 212 end | |
| 213 sslctx = ctx; | |
| 214 end | |
| 215 if not ssl then | |
| 216 sslctx = false; | |
| 217 if startssl then | |
| 218 log("error", "Failed to listen on port %d due to SSL/TLS to SSL/TLS initialisation errors (see logs)", serverport ) | |
| 219 return nil, "Cannot start ssl, see log for details" | |
| 220 end | |
| 221 end | |
| 222 | |
| 223 local accept = socket.accept | 171 local accept = socket.accept |
| 224 | 172 |
| 225 --// public methods of the object //-- | 173 --// public methods of the object //-- |
| 226 | 174 |
| 227 local handler = { } | 175 local handler = { } |
| 228 | 176 |
| 229 handler.shutdown = function( ) end | 177 handler.shutdown = function( ) end |
| 230 | 178 |
| 231 handler.ssl = function( ) | 179 handler.ssl = function( ) |
| 232 return ssl | 180 return sslctx ~= nil |
| 233 end | 181 end |
| 234 handler.sslctx = function( ) | 182 handler.sslctx = function( ) |
| 235 return sslctx | 183 return sslctx |
| 236 end | 184 end |
| 237 handler.remove = function( ) | 185 handler.remove = function( ) |
| 269 end | 217 end |
| 270 local client, err = accept( socket ) -- try to accept | 218 local client, err = accept( socket ) -- try to accept |
| 271 if client then | 219 if client then |
| 272 local ip, clientport = client:getpeername( ) | 220 local ip, clientport = client:getpeername( ) |
| 273 client:settimeout( 0 ) | 221 client:settimeout( 0 ) |
| 274 local handler, client, err = wrapconnection( handler, listeners, client, ip, serverport, clientport, pattern, sslctx, startssl ) -- wrap new client socket | 222 local handler, client, err = wrapconnection( handler, listeners, client, ip, serverport, clientport, pattern, sslctx ) -- wrap new client socket |
| 275 if err then -- error while wrapping ssl socket | 223 if err then -- error while wrapping ssl socket |
| 276 return false | 224 return false |
| 277 end | 225 end |
| 278 connections = connections + 1 | 226 connections = connections + 1 |
| 279 out_put( "server.lua: accepted new client connection from ", tostring(ip), ":", tostring(clientport), " to ", tostring(serverport)) | 227 out_put( "server.lua: accepted new client connection from ", tostring(ip), ":", tostring(clientport), " to ", tostring(serverport)) |
| 284 end | 232 end |
| 285 end | 233 end |
| 286 return handler | 234 return handler |
| 287 end | 235 end |
| 288 | 236 |
| 289 wrapconnection = function( server, listeners, socket, ip, serverport, clientport, pattern, sslctx, startssl ) -- this function wraps a client to a handler object | 237 wrapconnection = function( server, listeners, socket, ip, serverport, clientport, pattern, sslctx ) -- this function wraps a client to a handler object |
| 290 | 238 |
| 291 socket:settimeout( 0 ) | 239 socket:settimeout( 0 ) |
| 292 | 240 |
| 293 --// local import of socket methods //-- | 241 --// local import of socket methods //-- |
| 294 | 242 |
| 518 end | 466 end |
| 519 if succ then -- sending succesful | 467 if succ then -- sending succesful |
| 520 bufferqueuelen = 0 | 468 bufferqueuelen = 0 |
| 521 bufferlen = 0 | 469 bufferlen = 0 |
| 522 _sendlistlen = removesocket( _sendlist, socket, _sendlistlen ) -- delete socket from writelist | 470 _sendlistlen = removesocket( _sendlist, socket, _sendlistlen ) -- delete socket from writelist |
| 523 _ = needtls and handler:starttls(true) | 471 _ = needtls and handler:starttls(nil, true) |
| 524 _writetimes[ handler ] = nil | 472 _writetimes[ handler ] = nil |
| 525 _ = toclose and handler.close( ) | 473 _ = toclose and handler.close( ) |
| 526 return true | 474 return true |
| 527 elseif byte and ( err == "timeout" or err == "wantwrite" ) then -- want write | 475 elseif byte and ( err == "timeout" or err == "wantwrite" ) then -- want write |
| 528 buffer = string_sub( buffer, byte + 1, bufferlen ) -- new buffer | 476 buffer = string_sub( buffer, byte + 1, bufferlen ) -- new buffer |
| 582 end | 530 end |
| 583 ) | 531 ) |
| 584 end | 532 end |
| 585 if sslctx then -- ssl? | 533 if sslctx then -- ssl? |
| 586 handler:set_sslctx(sslctx); | 534 handler:set_sslctx(sslctx); |
| 587 if startssl then -- ssl now? | 535 out_put("server.lua: ", "starting ssl handshake") |
| 588 --out_put("server.lua: ", "starting ssl handshake") | 536 local err |
| 589 local err | 537 socket, err = ssl_wrap( socket, sslctx ) -- wrap socket |
| 538 if err then | |
| 539 out_put( "server.lua: ssl error: ", tostring(err) ) | |
| 540 --mem_free( ) | |
| 541 return nil, nil, err -- fatal error | |
| 542 end | |
| 543 socket:settimeout( 0 ) | |
| 544 handler.readbuffer = handshake | |
| 545 handler.sendbuffer = handshake | |
| 546 handshake( socket ) -- do handshake | |
| 547 if not socket then | |
| 548 return nil, nil, "ssl handshake failed"; | |
| 549 end | |
| 550 else | |
| 551 local sslctx; | |
| 552 handler.starttls = function( self, _sslctx, now ) | |
| 553 if _sslctx then | |
| 554 sslctx = _sslctx; | |
| 555 handler:set_sslctx(sslctx); | |
| 556 end | |
| 557 if not now then | |
| 558 out_put "server.lua: we need to do tls, but delaying until later" | |
| 559 needtls = true | |
| 560 return | |
| 561 end | |
| 562 out_put( "server.lua: attempting to start tls on " .. tostring( socket ) ) | |
| 563 local oldsocket, err = socket | |
| 590 socket, err = ssl_wrap( socket, sslctx ) -- wrap socket | 564 socket, err = ssl_wrap( socket, sslctx ) -- wrap socket |
| 565 --out_put( "server.lua: sslwrapped socket is " .. tostring( socket ) ) | |
| 591 if err then | 566 if err then |
| 592 out_put( "server.lua: ssl error: ", tostring(err) ) | 567 out_put( "server.lua: error while starting tls on client: ", tostring(err) ) |
| 593 --mem_free( ) | 568 return nil, err -- fatal error |
| 594 return nil, nil, err -- fatal error | 569 end |
| 595 end | 570 |
| 596 socket:settimeout( 0 ) | 571 socket:settimeout( 0 ) |
| 572 | |
| 573 -- add the new socket to our system | |
| 574 | |
| 575 send = socket.send | |
| 576 receive = socket.receive | |
| 577 shutdown = id | |
| 578 | |
| 579 _socketlist[ socket ] = handler | |
| 580 _readlistlen = addsocket(_readlist, socket, _readlistlen) | |
| 581 | |
| 582 -- remove traces of the old socket | |
| 583 | |
| 584 _readlistlen = removesocket( _readlist, oldsocket, _readlistlen ) | |
| 585 _sendlistlen = removesocket( _sendlist, oldsocket, _sendlistlen ) | |
| 586 _socketlist[ oldsocket ] = nil | |
| 587 | |
| 588 handler.starttls = nil | |
| 589 needtls = nil | |
| 590 | |
| 591 -- Secure now | |
| 592 ssl = true | |
| 593 | |
| 597 handler.readbuffer = handshake | 594 handler.readbuffer = handshake |
| 598 handler.sendbuffer = handshake | 595 handler.sendbuffer = handshake |
| 599 handshake( socket ) -- do handshake | 596 handshake( socket ) -- do handshake |
| 600 if not socket then | 597 end |
| 601 return nil, nil, "ssl handshake failed"; | |
| 602 end | |
| 603 else | |
| 604 -- We're not automatically doing SSL, so we're not secure (yet) | |
| 605 ssl = false | |
| 606 handler.starttls = function( self, now ) | |
| 607 if not now then | |
| 608 --out_put "server.lua: we need to do tls, but delaying until later" | |
| 609 needtls = true | |
| 610 return | |
| 611 end | |
| 612 --out_put( "server.lua: attempting to start tls on " .. tostring( socket ) ) | |
| 613 local oldsocket, err = socket | |
| 614 socket, err = ssl_wrap( socket, sslctx ) -- wrap socket | |
| 615 --out_put( "server.lua: sslwrapped socket is " .. tostring( socket ) ) | |
| 616 if err then | |
| 617 out_put( "server.lua: error while starting tls on client: ", tostring(err) ) | |
| 618 return nil, err -- fatal error | |
| 619 end | |
| 620 | |
| 621 socket:settimeout( 0 ) | |
| 622 | |
| 623 -- add the new socket to our system | |
| 624 | |
| 625 send = socket.send | |
| 626 receive = socket.receive | |
| 627 shutdown = id | |
| 628 | |
| 629 _socketlist[ socket ] = handler | |
| 630 _readlistlen = addsocket(_readlist, socket, _readlistlen) | |
| 631 | |
| 632 -- remove traces of the old socket | |
| 633 | |
| 634 _readlistlen = removesocket( _readlist, oldsocket, _readlistlen ) | |
| 635 _sendlistlen = removesocket( _sendlist, oldsocket, _sendlistlen ) | |
| 636 _socketlist[ oldsocket ] = nil | |
| 637 | |
| 638 handler.starttls = nil | |
| 639 needtls = nil | |
| 640 | |
| 641 -- Secure now | |
| 642 ssl = true | |
| 643 | |
| 644 handler.readbuffer = handshake | |
| 645 handler.sendbuffer = handshake | |
| 646 handshake( socket ) -- do handshake | |
| 647 end | |
| 648 handler.readbuffer = _readbuffer | |
| 649 handler.sendbuffer = _sendbuffer | |
| 650 end | |
| 651 else -- normal connection | |
| 652 ssl = false | |
| 653 handler.readbuffer = _readbuffer | 598 handler.readbuffer = _readbuffer |
| 654 handler.sendbuffer = _sendbuffer | 599 handler.sendbuffer = _sendbuffer |
| 655 end | 600 end |
| 656 | 601 |
| 657 send = socket.send | 602 send = socket.send |
| 703 --mem_free( ) | 648 --mem_free( ) |
| 704 end | 649 end |
| 705 | 650 |
| 706 ----------------------------------// PUBLIC //-- | 651 ----------------------------------// PUBLIC //-- |
| 707 | 652 |
| 708 addserver = function( addr, port, listeners, pattern, sslctx, startssl ) -- this function provides a way for other scripts to reg a server | 653 addserver = function( addr, port, listeners, pattern, sslctx ) -- this function provides a way for other scripts to reg a server |
| 709 local err | 654 local err |
| 710 --out_put("server.lua: autossl on ", port, " is ", startssl) | |
| 711 if type( listeners ) ~= "table" then | 655 if type( listeners ) ~= "table" then |
| 712 err = "invalid listener table" | 656 err = "invalid listener table" |
| 713 end | 657 end |
| 714 if not type( port ) == "number" or not ( port >= 0 and port <= 65535 ) then | 658 if not type( port ) == "number" or not ( port >= 0 and port <= 65535 ) then |
| 715 err = "invalid port" | 659 err = "invalid port" |
| 726 local server, err = socket_bind( addr, port ) | 670 local server, err = socket_bind( addr, port ) |
| 727 if err then | 671 if err then |
| 728 out_error( "server.lua, port ", port, ": ", err ) | 672 out_error( "server.lua, port ", port, ": ", err ) |
| 729 return nil, err | 673 return nil, err |
| 730 end | 674 end |
| 731 local handler, err = wrapserver( listeners, server, addr, port, pattern, sslctx, _maxclientsperserver, startssl ) -- wrap new server socket | 675 local handler, err = wrapserver( listeners, server, addr, port, pattern, sslctx, _maxclientsperserver ) -- wrap new server socket |
| 732 if not handler then | 676 if not handler then |
| 733 server:close( ) | 677 server:close( ) |
| 734 return nil, err | 678 return nil, err |
| 735 end | 679 end |
| 736 server:settimeout( 0 ) | 680 server:settimeout( 0 ) |
| 855 return "select"; | 799 return "select"; |
| 856 end | 800 end |
| 857 | 801 |
| 858 --// EXPERIMENTAL //-- | 802 --// EXPERIMENTAL //-- |
| 859 | 803 |
| 860 local wrapclient = function( socket, ip, serverport, listeners, pattern, sslctx, startssl ) | 804 local wrapclient = function( socket, ip, serverport, listeners, pattern, sslctx ) |
| 861 local handler = wrapconnection( nil, listeners, socket, ip, serverport, "clientport", pattern, sslctx, startssl ) | 805 local handler = wrapconnection( nil, listeners, socket, ip, serverport, "clientport", pattern, sslctx ) |
| 862 _socketlist[ socket ] = handler | 806 _socketlist[ socket ] = handler |
| 863 _sendlistlen = addsocket(_sendlist, socket, _sendlistlen) | 807 _sendlistlen = addsocket(_sendlist, socket, _sendlistlen) |
| 864 return handler, socket | 808 return handler, socket |
| 865 end | 809 end |
| 866 | 810 |
| 867 local addclient = function( address, port, listeners, pattern, sslctx, startssl ) | 811 local addclient = function( address, port, listeners, pattern, sslctx ) |
| 868 local client, err = luasocket.tcp( ) | 812 local client, err = luasocket.tcp( ) |
| 869 if err then | 813 if err then |
| 870 return nil, err | 814 return nil, err |
| 871 end | 815 end |
| 872 client:settimeout( 0 ) | 816 client:settimeout( 0 ) |
| 873 _, err = client:connect( address, port ) | 817 _, err = client:connect( address, port ) |
| 874 if err then -- try again | 818 if err then -- try again |
| 875 local handler = wrapclient( client, address, port, listeners ) | 819 local handler = wrapclient( client, address, port, listeners ) |
| 876 else | 820 else |
| 877 wrapconnection( nil, listeners, client, address, port, "clientport", pattern, sslctx, startssl ) | 821 wrapconnection( nil, listeners, client, address, port, "clientport", pattern, sslctx ) |
| 878 end | 822 end |
| 879 end | 823 end |
| 880 | 824 |
| 881 --// EXPERIMENTAL //-- | 825 --// EXPERIMENTAL //-- |
| 882 | 826 |
