Skip to content

Instantly share code, notes, and snippets.

@lipp
Created May 23, 2013 10:34
Show Gist options
  • Save lipp/5635191 to your computer and use it in GitHub Desktop.
Save lipp/5635191 to your computer and use it in GitHub Desktop.
luasec non block example based on luasec/sample/want (dont forget to generate certs from luasec/sample/certs!) start like this: $ lua server_ev.lua & $ lua client.lua & $ lua client.lua & $ lua handshake.lua &
--
-- Test the conn:want() function
--
-- Public domain
--
require("socket")
require("ssl")
local params = {
mode = "client",
protocol = "sslv3",
key = "../certs/clientAkey.pem",
certificate = "../certs/clientA.pem",
cafile = "../certs/rootA.pem",
verify = {"peer", "fail_if_no_peer_cert"},
options = {"all", "no_sslv2"},
}
-- Wait until socket is ready (for reading or writing)
local function wait(peer)
-- What event blocked us?
local err
if peer.want then -- Is it an SSL connection?
err = peer:want()
print("Want? ", err)
else
-- No, it's a normal TCP connection...
err = "timeout"
end
if err == "read" or err == "timeout" then
socket.select({peer}, nil)
elseif err == "write" then
socket.select(nil, {peer})
else
peer:close()
os.exit(1)
end
end
-- Start the TCP connection
local peer = socket.tcp()
assert( peer:connect("127.0.0.1", 8888) )
-- [[ SSL wrapper
peer = assert( ssl.wrap(peer, params) )
peer:settimeout(0.3)
local succ = peer:dohandshake()
while not succ do
wait(peer)
succ = peer:dohandshake()
end
print("** Handshake done")
--]]
-- If the section above is commented, the timeout is not set.
-- We set it again for safetiness.
peer:settimeout(0.3)
-- Try to receive a line
local str = peer:receive("*l")
while true do
print(peer:receive("*l"))
local n = math.random(1,100)
if (n % 5) == 0 then
print('reset',n)
peer:send(tostring(n))
if arg[1] then
socket.sleep(2)
end
peer:send('\n')
end
end
peer:close()
--
-- Test the conn:want() function
--
-- Public domain
--
require("socket")
require("ssl")
local params = {
mode = "client",
protocol = "sslv3",
key = "../certs/clientAkey.pem",
certificate = "../certs/clientA.pem",
cafile = "../certs/rootA.pem",
verify = {"peer", "fail_if_no_peer_cert"},
options = {"all", "no_sslv2"},
}
local function wait(peer)
-- What event blocked us?
local err
if peer.want then -- Is it an SSL connection?
err = peer:want()
socket.sleep(1)
print("Want? ", err)
else
-- No, it's a normal TCP connection...
err = "timeout"
end
if err == "read" or err == "timeout" then
socket.select({peer}, nil)
elseif err == "write" then
socket.select(nil, {peer})
else
peer:close()
os.exit(1)
end
end
while true do
-- Start the TCP connection
local peer = socket.tcp()
assert( peer:connect("127.0.0.1", 8888) )
-- [[ SSL wrapper
peer = assert( ssl.wrap(peer, params) )
peer:settimeout(0)
local succ = peer:dohandshake()
while not succ do
wait(peer)
succ = peer:dohandshake()
end
print("** Handshake done")
--]]
print(peer:receive("*l"))
peer:close()
end
--
-- Public domain
--
require("socket")
require("ssl")
local ev = require'ev'
local params = {
mode = "server",
protocol = "sslv3",
key = "../certs/serverAkey.pem",
certificate = "../certs/serverA.pem",
cafile = "../certs/rootA.pem",
verify = {"peer", "fail_if_no_peer_cert"},
options = {"all", "no_sslv2"},
}
local ctx = assert(ssl.newcontext(params))
local server = socket.bind("127.0.0.1", 8888)
server:settimeout(0)
assert(server and server:getfd() > 0)
ev.IO.new(function()
local peer = server:accept()
local dispatch
local retry
peer:settimeout(0)
peer = assert( ssl.wrap(peer, ctx) )
peer:settimeout(0)
local try_handshake = function(loop,watcher)
watcher:stop(loop)
local ok = peer:dohandshake()
if ok then
dispatch()
else
retry()
end
end
retry = function()
local want = peer:want()
if want == 'read' then
ev.IO.new(try_handshake,peer:getfd(),ev.READ):start(ev.Loop.default)
elseif want == 'write' then
ev.IO.new(try_handshake,peer:getfd(),ev.WRITE):start(ev.Loop.default)
else
assert(false,'should not happen')
end
end
ev.Timer.new(try_handshake,0.0000001):start(ev.Loop.default)
dispatch = function()
local i = 0
ev.Timer.new(function(loop,timer)
i = i + 1
timer:stop(loop)
local last
ev.IO.new(function(loop,io)
local ok,err,last = peer:send(tostring(i)..'\n',last)
if ok then
io:stop(loop)
timer:start(loop)
elseif err == 'closed' then
io:stop(loop)
end
end,peer:getfd(),ev.WRITE):start(loop)
end,.01,.01):start(ev.Loop.default)
local last
ev.IO.new(function(loop,io)
local line,err,part = peer:receive('*l')
if part then
last = (last or '')..part
end
if line then
if last then
line = last..line
last = nil
end
local ok,new_i = pcall(tonumber,line)
if ok then
i = new_i
end
elseif err == 'closed' then
io:stop(loop)
end
end,peer:getfd(),ev.READ):start(ev.Loop.default)
end
end,server:getfd(),ev.READ):start(ev.Loop.default)
ev.Loop.default:loop()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment