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
parent 2478:7be72eca5666
child 2549: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