Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

R4R: Initial Pass at TLS Connect and Bug Fixes #551

Merged
merged 15 commits into from
Dec 2, 2014
50 changes: 26 additions & 24 deletions app/modules/childprocess.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ limitations under the License.

--]]

local net = require('net')
local core = require('core')
local timer = require('timer')
local uv = require('uv')
Expand All @@ -25,7 +26,7 @@ local Writable = require('stream_writable').Writable
local function spawn(command, args, options)
local envPairs = {}, env, em, onCallback
local stdout, stdin, stderr, stdio
local onImmediate
local onImmediate, kill, cleanup

args = args or {}
options = options or {}
Expand All @@ -37,19 +38,31 @@ local function spawn(command, args, options)
end
end

stdout = core.Stream:new(uv.new_pipe(false))
stdin = core.Stream:new(uv.new_pipe(false))
stderr = core.Stream:new(uv.new_pipe(false))
stdout = net.Socket:new({ handle = uv.new_pipe(false) })
stderr = net.Socket:new({ handle = uv.new_pipe(false) })
stdin = net.Socket:new({ handle = uv.new_pipe(false) })
stdio = { stdin._handle, stdout._handle, stderr._handle}

stdio = { stdin.handle, stdout.handle, stderr.handle}
function kill(self, signal)
uv.process_kill(em.handle, signal or 'SIGTERM')
cleanup()
end

function cleanup()
if em.handle then uv.close(em.handle) ; em.handle = nil end
em.stdout:on('end', function()
em.stdout:destroy()
end)
em.stdout:resume() -- drain stdout
stderr:destroy()
stdin:destroy()
end

em = core.Emitter:new()
em.stdin = Writable:new():wrap(stdin)
em.stdout = Readable:new():wrap(stdout)
em.stderr = Readable:new():wrap(stderr)
em.stdout:once('end', function()
stdout:close()
end)
em.kill = kill
em.stdin = stdin
em.stdout = stdout
em.stderr = stderr
em.handle, em.pid = uv.spawn(command, {
stdio = stdio,
args = args,
Expand All @@ -63,21 +76,10 @@ local function spawn(command, args, options)
em.exitCode = code
end

function onImmediate()
em.stdout:resume() -- drain stdout
stderr:close()
stdin:close()
em:emit('exit', code, signal)
end

uv.close(em.handle)
timer.setImmediate(onImmediate)
cleanup()
em:emit('exit', code, signal)
end)

for _, v in pairs({stdin, stdout, stderr}) do
v:readStart()
end

return em
end

Expand Down
126 changes: 126 additions & 0 deletions app/modules/codecs/_common_tls.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
--[[

Copyright 2014 The Luvit Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS-IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

--]]

local Object = require('core').Object
local bit = require('bit')

exports.DEFAULT_CIPHERS = 'ECDHE-RSA-AES128-SHA256:AES128-GCM-SHA256:' .. -- TLS 1.2
'RC4:HIGH:!MD5:!aNULL:!EDH' -- TLS 1.0

-------------------------------------------------------------------------------

local getSecureOptions = function(protocol, options)
return bit.bor(openssl.ssl.no_sslv2,
openssl.ssl.no_sslv3,
openssl.ssl.no_compression)
end

-------------------------------------------------------------------------------

local CertificateStoreCtx = Object:extend()
function CertificateStoreCtx:initialize(ctx)
self.ctx = ctx
self.cert_store = openssl.x509.store:new()
end

function CertificateStoreCtx:add(cert)
p('adding', cert:subject())
return self.cert_store:add(cert)
end

function CertificateStoreCtx:load(filename)
return self.cert_store:load(filename)
end

exports.CertificateStoreCtx = CertificateStoreCtx

-------------------------------------------------------------------------------

local Credential = Object:extend()
function Credential:initialize(secureProtocol, defaultCiphers, flags, rejectUnauthorized, context)
self.rejectUnauthorized = rejectUnauthorized

if context then
self.context = context
else
self.context = openssl.ssl.ctx_new(secureProtocol or 'TLSv1',
defaultCiphers or DEFAULT_CIPHERS)
self.context:options(getSecureOptions(secureProtocol, flags))
end
end

function Credential:addRootCerts()
local store = self.context:cert_store()
for _, cert in pairs(_root_ca.roots) do
cert = assert(openssl.x509.read(cert))
p(cert)
p(cert:subject())
assert(store(cert))
end
p('addRootCerts end')
end

function Credential:addCACert(certs)
local new_store = false, cert
if not self.store then
self.store = CertificateStoreCtx:new(self.context)
new_store = true
end
self.store:load('test.pem')
if type(certs) == 'table' then
for _, cert in pairs(certs) do
cert = openssl.x509.read(cert)
self.store:add(cert)
end
else
cert = openssl.x509.read(certs)
self.store:add(cert)
end
if new_store then
self.context:cert_store(self.store.cert_store)
end
end

function Credential:createBIO()
return openssl.bio.mem(8192), openssl.bio.mem(8192)
end

function Credential:createSSLContext(bin, bout, server)
return self.context:ssl(bin, bout, server)
end

exports.Credential = Credential

-------------------------------------------------------------------------------

exports.createCredentials = function(options, context)
local ctx
options = options or {}
ctx = Credential:new(options.secureProtocol, options.ciphers,
options.secureOptions, options.rejectUnauthorized,
context)
if context then
return ctx
end

ctx.context:set_verify({"none"}, function()
return 1
end)

return ctx
end
Loading