This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

TCP over SSL
#1
Question 
Hi,

anybody had any success creating an SSL server listener in LUA ?

There seems to be an issue with the server socket not being able to receive() from the client. Sending from server to client however, works just fine.

Note that I tried using it in a copas handler first, and then as a simple standalone luasec handler (running on my machine, not in LM)

Simple test code looks like this:


Code:
local socket = require("socket")
local ssl    = require("ssl")

local params = {
   mode = "server",
   protocol = "tlsv1_2",
   key = "C:\\ .... \\serverkey.pem",
   certificate  = "C:\\ .... \\server.pem",
   cafile = "C:\\ .... \\root.pem",
   verify = {"peer", "fail_if_no_peer_cert"},
   options = "all",
}

local server = socket.tcp()
local ctx = assert(ssl.newcontext(params))
server:setoption('reuseaddr', true)
assert( server:bind("10.20.2.92", 2000) )
server:listen()

local peer = server:accept()
peer = assert( ssl.wrap(peer, ctx) )
peer:dohandshake()
data = peer:receive()  -- <--- HANGS !
print("receieved: " .. data)
peer:send("Pong!\n")
peer:close()
Reply
#2
SSL server is not yet supported, we'll try to prepare an update this week though Smile
Reply
#3
(01.11.2016, 09:30)admin Wrote: SSL server is not yet supported, we'll try to prepare an update this week though Smile

Ok ! I assume it will be via luasec ?

I got my code working though, turned out to be a hickup on the client side.
Reply
#4
Hi Admin,

Is there any update on running an ssl server on the lm? Can this be done without a cert?

Thanks,


Roger
Reply
#5
It's possible, but you cannot run it without a certificate. You can reuse web-server's self-signed certificate though. Here's a short example:
Code:
if not tcpserver then
  require('copas')

  sslparams = {
    mode = 'server',
    protocol = 'tlsv12',
    key = '/etc/nginx_sha256.key',
    certificate = '/etc/nginx_sha256.crt',
    options = 'all',
  }

  -- connection handler
  function connhandler(sock)
    local ip, port = sock:getpeername()

    sock = copas.wrap(sock, sslparams)
    sock:dohandshake()

    alert('[server] connection from %s:%d', ip, port)

    -- main reader loop
    while true do
      -- wait for single line of data (until \n, \r is ignored)
      local data, err = copas.receive(sock, '*l')

      -- error while receiving
      if err then
        alert('[server] closed connection from %s:%d', ip, port)
        return
      end

      -- handle data frame
      if data == 'HELLO' then
        sock:send('HELLO TO YOU\r\n')
        sock:close()
      end
    end
  end

  -- bind to port 12345
  tcpserver = socket.bind('*', 12345)

  -- error while binding, try again later
  if not tcpserver then
    os.sleep(5)
    error('[server] error: cannot bind')
  end

  -- set server connection handler
  copas.addserver(tcpserver, connhandler)
end

copas.step(1)
Reply
#6
Thanks Admin, that works..
Reply
#7
Hi Admin,

A couple of questions,

Will this server support multiple clients? I added a basic authentication, that just sets a global variable on connecting and closes the connection if the password is incorrect.

The data received is passed another function parseC. Now I need to be able to respond back to the connected client where I declared a global function in this handler. Is this the right way to do this?
Code:
-- handle data frame
      if data then
       if(first==true)then
          if(data ~='mypassword')then
            first=false
            sock:close()
          end
        end
        Sclient= function (param)
          sock:send(param)
        end
        local fd,prtd = pcall(parseC,data)            
        if(fd==false)then              
          alert("[elk-client] Error with parsemsg %s ",prtd)            
        end
      end

Thanks,


Roger
Reply
#8
Yes, it supports multiple clients.

See this example on how to pass data to all connected clients:
http://openrb.com/example-lm2-as-tcp-ser...-requests/

You can pass any number of arguments via pcall, you can pass both data and socket if you want to send a reply to a specific client.
Reply


Forum Jump: