mirror of
https://github.com/bjc/prosody.git
synced 2025-04-04 21:57:45 +03:00
Merged local TLS branch
This commit is contained in:
commit
3b33f15654
4 changed files with 228 additions and 7 deletions
|
@ -49,6 +49,7 @@ function loadall()
|
||||||
load("legacyauth");
|
load("legacyauth");
|
||||||
load("roster");
|
load("roster");
|
||||||
load("register");
|
load("register");
|
||||||
|
load("tls");
|
||||||
end
|
end
|
||||||
|
|
||||||
function load(name)
|
function load(name)
|
||||||
|
|
|
@ -11,6 +11,7 @@ require "util.jid"
|
||||||
local jid_split = jid.split;
|
local jid_split = jid.split;
|
||||||
|
|
||||||
function core_process_stanza(origin, stanza)
|
function core_process_stanza(origin, stanza)
|
||||||
|
log("debug", "Received: "..tostring(stanza))
|
||||||
local to = stanza.attr.to;
|
local to = stanza.attr.to;
|
||||||
|
|
||||||
if not to or (hosts[to] and hosts[to].type == "local") then
|
if not to or (hosts[to] and hosts[to].type == "local") then
|
||||||
|
|
4
main.lua
4
main.lua
|
@ -101,7 +101,7 @@ setmetatable(_G, { __index = function (t, k) print("WARNING: ATTEMPT TO READ A N
|
||||||
local protected_handler = function (conn, data, err) local success, ret = pcall(handler, conn, data, err); if not success then print("ERROR on "..tostring(conn)..": "..ret); conn:close(); end end;
|
local protected_handler = function (conn, data, err) local success, ret = pcall(handler, conn, data, err); if not success then print("ERROR on "..tostring(conn)..": "..ret); conn:close(); end end;
|
||||||
local protected_disconnect = function (conn, err) local success, ret = pcall(disconnect, conn, err); if not success then print("ERROR on "..tostring(conn).." disconnect: "..ret); conn:close(); end end;
|
local protected_disconnect = function (conn, err) local success, ret = pcall(disconnect, conn, err); if not success then print("ERROR on "..tostring(conn).." disconnect: "..ret); conn:close(); end end;
|
||||||
|
|
||||||
server.add( { listener = protected_handler, disconnect = protected_disconnect }, 5222, "*", 1, nil ) -- server.add will send a status message
|
server.add( { listener = protected_handler, disconnect = protected_disconnect }, 5222, "*", 1, ssl_ctx ) -- server.add will send a status message
|
||||||
server.add( { listener = protected_handler, disconnect = protected_disconnect }, 5223, "*", 1, ssl_ctx ) -- server.add will send a status message
|
--server.add( { listener = protected_handler, disconnect = protected_disconnect }, 5223, "*", 1, ssl_ctx ) -- server.add will send a status message
|
||||||
|
|
||||||
server.loop();
|
server.loop();
|
||||||
|
|
229
net/server.lua
229
net/server.lua
|
@ -39,6 +39,7 @@ local coroutine_wrap = coroutine.wrap
|
||||||
local coroutine_yield = coroutine.yield
|
local coroutine_yield = coroutine.yield
|
||||||
local print = print;
|
local print = print;
|
||||||
local out_put = function () end --print;
|
local out_put = function () end --print;
|
||||||
|
local out_put = print;
|
||||||
local out_error = print;
|
local out_error = print;
|
||||||
|
|
||||||
--// extern libs //--
|
--// extern libs //--
|
||||||
|
@ -105,8 +106,6 @@ wrapserver = function( listener, socket, ip, serverport, mode, sslctx ) -- th
|
||||||
if sslctx then
|
if sslctx then
|
||||||
if not ssl_newcontext then
|
if not ssl_newcontext then
|
||||||
return nil, "luasec not found"
|
return nil, "luasec not found"
|
||||||
-- elseif not cfg_get "use_ssl" then
|
|
||||||
-- return nil, "ssl is deactivated"
|
|
||||||
end
|
end
|
||||||
if type( sslctx ) ~= "table" then
|
if type( sslctx ) ~= "table" then
|
||||||
out_error "server.lua: wrong server sslctx"
|
out_error "server.lua: wrong server sslctx"
|
||||||
|
@ -119,6 +118,7 @@ wrapserver = function( listener, socket, ip, serverport, mode, sslctx ) -- th
|
||||||
return nil, err
|
return nil, err
|
||||||
end
|
end
|
||||||
wrapclient = wrapsslclient
|
wrapclient = wrapsslclient
|
||||||
|
wrapclient = wraptlsclient
|
||||||
else
|
else
|
||||||
wrapclient = wraptcpclient
|
wrapclient = wraptcpclient
|
||||||
end
|
end
|
||||||
|
@ -356,6 +356,220 @@ wrapsslclient = function( listener, socket, ip, serverport, clientport, mode, ss
|
||||||
return handler, socket
|
return handler, socket
|
||||||
end
|
end
|
||||||
|
|
||||||
|
wraptlsclient = function( listener, socket, ip, serverport, clientport, mode, sslctx ) -- this function wraps a tls cleint
|
||||||
|
|
||||||
|
local dispatch, disconnect = listener.listener, listener.disconnect
|
||||||
|
|
||||||
|
--// transform socket to ssl object //--
|
||||||
|
|
||||||
|
local err
|
||||||
|
|
||||||
|
socket:settimeout( 0 )
|
||||||
|
|
||||||
|
--// private closures of the object //--
|
||||||
|
|
||||||
|
local writequeue = { } -- buffer for messages to send
|
||||||
|
|
||||||
|
local eol -- end of buffer
|
||||||
|
|
||||||
|
local sstat, rstat = 0, 0
|
||||||
|
|
||||||
|
--// local import of socket methods //--
|
||||||
|
|
||||||
|
local send = socket.send
|
||||||
|
local receive = socket.receive
|
||||||
|
local close = socket.close
|
||||||
|
--local shutdown = socket.shutdown
|
||||||
|
|
||||||
|
--// public methods of the object //--
|
||||||
|
|
||||||
|
local handler = { }
|
||||||
|
|
||||||
|
handler.getstats = function( )
|
||||||
|
return rstat, sstat
|
||||||
|
end
|
||||||
|
|
||||||
|
handler.listener = function( data, err )
|
||||||
|
return listener( handler, data, err )
|
||||||
|
end
|
||||||
|
handler.ssl = function( )
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
handler.send = function( _, data, i, j )
|
||||||
|
return send( socket, data, i, j )
|
||||||
|
end
|
||||||
|
handler.receive = function( pattern, prefix )
|
||||||
|
return receive( socket, pattern, prefix )
|
||||||
|
end
|
||||||
|
handler.shutdown = function( pattern )
|
||||||
|
--return shutdown( socket, pattern )
|
||||||
|
end
|
||||||
|
handler.close = function( closed )
|
||||||
|
close( socket )
|
||||||
|
writelen = ( eol and removesocket( writelist, socket, writelen ) ) or writelen
|
||||||
|
readlen = removesocket( readlist, socket, readlen )
|
||||||
|
socketlist[ socket ] = nil
|
||||||
|
out_put "server.lua: closed handler and removed socket from list"
|
||||||
|
end
|
||||||
|
handler.ip = function( )
|
||||||
|
return ip
|
||||||
|
end
|
||||||
|
handler.serverport = function( )
|
||||||
|
return serverport
|
||||||
|
end
|
||||||
|
handler.clientport = function( )
|
||||||
|
return clientport
|
||||||
|
end
|
||||||
|
|
||||||
|
handler.write = function( data )
|
||||||
|
if not eol then
|
||||||
|
writelen = writelen + 1
|
||||||
|
writelist[ writelen ] = socket
|
||||||
|
eol = 0
|
||||||
|
end
|
||||||
|
eol = eol + 1
|
||||||
|
writequeue[ eol ] = data
|
||||||
|
end
|
||||||
|
handler.writequeue = function( )
|
||||||
|
return writequeue
|
||||||
|
end
|
||||||
|
handler.socket = function( )
|
||||||
|
return socket
|
||||||
|
end
|
||||||
|
handler.mode = function( )
|
||||||
|
return mode
|
||||||
|
end
|
||||||
|
handler._receivedata = function( )
|
||||||
|
local data, err, part = receive( socket, mode ) -- receive data in "mode"
|
||||||
|
if not err or ( err == "timeout" or err == "wantread" ) then -- received something
|
||||||
|
local data = data or part or ""
|
||||||
|
local count = #data * STAT_UNIT
|
||||||
|
rstat = rstat + count
|
||||||
|
receivestat = receivestat + count
|
||||||
|
--out_put( "server.lua: read data '", data, "', error: ", err )
|
||||||
|
return dispatch( handler, data, err )
|
||||||
|
else -- connections was closed or fatal error
|
||||||
|
out_put( "server.lua: client ", ip, ":", clientport, " error: ", err )
|
||||||
|
handler.close( )
|
||||||
|
disconnect( handler, err )
|
||||||
|
writequeue = nil
|
||||||
|
handler = nil
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
handler._dispatchdata = function( ) -- this function writes data to handlers
|
||||||
|
local buffer = table_concat( writequeue, "", 1, eol )
|
||||||
|
local succ, err, byte = send( socket, buffer )
|
||||||
|
local count = ( succ or 0 ) * STAT_UNIT
|
||||||
|
sstat = sstat + count
|
||||||
|
sendstat = sendstat + count
|
||||||
|
out_put( "server.lua: sended '", buffer, "', bytes: ", succ, ", error: ", err, ", part: ", byte, ", to: ", ip, ":", clientport )
|
||||||
|
if succ then -- sending succesful
|
||||||
|
--writequeue = { }
|
||||||
|
eol = nil
|
||||||
|
writelen = removesocket( writelist, socket, writelen ) -- delete socket from writelist
|
||||||
|
if handler.need_tls then
|
||||||
|
out_put("server.lua: connection is ready for tls handshake");
|
||||||
|
handler.starttls(true);
|
||||||
|
if handler.need_tls then
|
||||||
|
out_put("server.lua: uh-oh... we still want tls, something must be wrong");
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
elseif byte and ( err == "timeout" or err == "wantwrite" ) then -- want write
|
||||||
|
buffer = string_sub( buffer, byte + 1, -1 ) -- new buffer
|
||||||
|
writequeue[ 1 ] = buffer -- insert new buffer in queue
|
||||||
|
eol = 1
|
||||||
|
return true
|
||||||
|
else -- connection was closed during sending or fatal error
|
||||||
|
out_put( "server.lua: client ", ip, ":", clientport, " error: ", err )
|
||||||
|
handler.close( )
|
||||||
|
disconnect( handler, err )
|
||||||
|
writequeue = nil
|
||||||
|
handler = nil
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
handler.receivedata, handler.dispatchdata = handler._receivedata, handler._dispatchdata;
|
||||||
|
-- // COMPAT // --
|
||||||
|
|
||||||
|
handler.getIp = handler.ip
|
||||||
|
handler.getPort = handler.clientport
|
||||||
|
|
||||||
|
--// handshake //--
|
||||||
|
|
||||||
|
local wrote, read
|
||||||
|
|
||||||
|
handler.starttls = function (now)
|
||||||
|
if not now then out_put("server.lua: we need to do tls, but delaying until later"); handler.need_tls = true; return; end
|
||||||
|
out_put( "server.lua: attempting to start tls on "..tostring(socket) )
|
||||||
|
socket, err = ssl_wrap( socket, sslctx ) -- wrap socket
|
||||||
|
out_put("sslwrapped socket is "..tostring(socket));
|
||||||
|
if err then
|
||||||
|
out_put( "server.lua: ssl error: ", err )
|
||||||
|
return nil, nil, err -- fatal error
|
||||||
|
end
|
||||||
|
socket:settimeout( 1 )
|
||||||
|
send = socket.send
|
||||||
|
receive = socket.receive
|
||||||
|
close = socket.close
|
||||||
|
handler.ssl = function( )
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
handler.send = function( _, data, i, j )
|
||||||
|
return send( socket, data, i, j )
|
||||||
|
end
|
||||||
|
handler.receive = function( pattern, prefix )
|
||||||
|
return receive( socket, pattern, prefix )
|
||||||
|
end
|
||||||
|
|
||||||
|
handler.handshake = coroutine_wrap( function( client )
|
||||||
|
local err
|
||||||
|
for i = 1, 10 do -- 10 handshake attemps
|
||||||
|
_, err = client:dohandshake( )
|
||||||
|
if not err then
|
||||||
|
out_put( "server.lua: ssl handshake done" )
|
||||||
|
writelen = ( wrote and removesocket( writelist, socket, writelen ) ) or writelen
|
||||||
|
handler.receivedata = handler._receivedata -- when handshake is done, replace the handshake function with regular functions
|
||||||
|
handler.dispatchdata = handler._dispatchdata
|
||||||
|
handler.need_tls = nil
|
||||||
|
socketlist[ client ] = handler
|
||||||
|
readlen = readlen + 1
|
||||||
|
readlist[ readlen ] = client
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
out_put( "server.lua: error during ssl handshake: ", err )
|
||||||
|
if err == "wantwrite" then
|
||||||
|
if wrote == nil then
|
||||||
|
writelen = writelen + 1
|
||||||
|
writelist[ writelen ] = client
|
||||||
|
wrote = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
coroutine_yield( handler, nil, err ) -- handshake not finished
|
||||||
|
end
|
||||||
|
end
|
||||||
|
_ = err ~= "closed" and close( socket )
|
||||||
|
handler.close( )
|
||||||
|
disconnect( handler, err )
|
||||||
|
writequeue = nil
|
||||||
|
handler = nil
|
||||||
|
return false -- handshake failed
|
||||||
|
end
|
||||||
|
)
|
||||||
|
handler.receivedata = handler.handshake
|
||||||
|
handler.dispatchdata = handler.handshake
|
||||||
|
|
||||||
|
handler.handshake( socket ) -- do handshake
|
||||||
|
end
|
||||||
|
socketlist[ socket ] = handler
|
||||||
|
readlen = readlen + 1
|
||||||
|
readlist[ readlen ] = socket
|
||||||
|
|
||||||
|
return handler, socket
|
||||||
|
end
|
||||||
|
|
||||||
wraptcpclient = function( listener, socket, ip, serverport, clientport, mode ) -- this function wraps a socket
|
wraptcpclient = function( listener, socket, ip, serverport, clientport, mode ) -- this function wraps a socket
|
||||||
|
|
||||||
local dispatch, disconnect = listener.listener, listener.disconnect
|
local dispatch, disconnect = listener.listener, listener.disconnect
|
||||||
|
@ -433,6 +647,7 @@ wraptcpclient = function( listener, socket, ip, serverport, clientport, mode )
|
||||||
handler.mode = function( )
|
handler.mode = function( )
|
||||||
return mode
|
return mode
|
||||||
end
|
end
|
||||||
|
|
||||||
handler.receivedata = function( )
|
handler.receivedata = function( )
|
||||||
local data, err, part = receive( socket, mode ) -- receive data in "mode"
|
local data, err, part = receive( socket, mode ) -- receive data in "mode"
|
||||||
if not err or ( err == "timeout" or err == "wantread" ) then -- received something
|
if not err or ( err == "timeout" or err == "wantread" ) then -- received something
|
||||||
|
@ -451,6 +666,7 @@ wraptcpclient = function( listener, socket, ip, serverport, clientport, mode )
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
handler.dispatchdata = function( ) -- this function writes data to handlers
|
handler.dispatchdata = function( ) -- this function writes data to handlers
|
||||||
local buffer = table_concat( writequeue, "", 1, eol )
|
local buffer = table_concat( writequeue, "", 1, eol )
|
||||||
local succ, err, byte = send( socket, buffer )
|
local succ, err, byte = send( socket, buffer )
|
||||||
|
@ -573,6 +789,10 @@ end
|
||||||
loop = function( ) -- this is the main loop of the program
|
loop = function( ) -- this is the main loop of the program
|
||||||
--signal_set( "hub", "run" )
|
--signal_set( "hub", "run" )
|
||||||
repeat
|
repeat
|
||||||
|
--[[print(readlen, writelen)
|
||||||
|
for _, s in ipairs(readlist) do print("R:", tostring(s)) end
|
||||||
|
for _, s in ipairs(writelist) do print("W:", tostring(s)) end
|
||||||
|
out_put("select()"..os.time())]]
|
||||||
local read, write, err = socket_select( readlist, writelist, 1 ) -- 1 sec timeout, nice for timers
|
local read, write, err = socket_select( readlist, writelist, 1 ) -- 1 sec timeout, nice for timers
|
||||||
for i, socket in ipairs( write ) do -- send data waiting in writequeues
|
for i, socket in ipairs( write ) do -- send data waiting in writequeues
|
||||||
local handler = socketlist[ socket ]
|
local handler = socketlist[ socket ]
|
||||||
|
@ -593,9 +813,8 @@ loop = function( ) -- this is the main loop of the program
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
firetimer( )
|
firetimer( )
|
||||||
--collectgarbage "collect"
|
until false
|
||||||
until false --signal_get "hub" ~= "run"
|
return
|
||||||
return --signal_get "hub"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
----------------------------------// BEGIN //--
|
----------------------------------// BEGIN //--
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue