1
0
Fork 0
mirror of https://github.com/puma/puma.git synced 2022-11-09 13:48:40 -05:00

Get OpenSSL driven version working

This commit is contained in:
Evan Phoenix 2012-08-22 21:43:40 -07:00
parent f792702dab
commit 327e2013e1
6 changed files with 51 additions and 66 deletions

View file

@ -3,5 +3,6 @@ require 'mkmf'
dir_config("puma_http11")
$defs.push "-Wno-deprecated-declarations"
$libs += " -lssl -lcrypto "
create_makefile("puma/puma_http11")

View file

@ -41,18 +41,17 @@ VALUE engine_init_server(VALUE self, VALUE key, VALUE cert) {
StringValue(key);
StringValue(cert);
SSL_CTX* ctx = SSL_CTX_new(DTLSv1_method());
SSL_CTX* ctx = SSL_CTX_new(SSLv23_server_method());
conn->ctx = ctx;
SSL_CTX_use_certificate_chain_file(ctx, RSTRING_PTR(cert));
SSL_CTX_use_PrivateKey_file(ctx, RSTRING_PTR(key), SSL_FILETYPE_PEM);
SSL_CTX_use_certificate_file(ctx, RSTRING_PTR(cert), SSL_FILETYPE_PEM);
SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE);
SSL_CTX_use_PrivateKey_file(ctx, RSTRING_PTR(key), SSL_FILETYPE_PEM);
/* SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE); */
SSL* ssl = SSL_new(ctx);
conn->ssl = ssl;
SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
/* SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL); */
SSL_set_bio(ssl, conn->read, conn->write);
@ -74,7 +73,7 @@ VALUE engine_init_client(VALUE klass) {
return obj;
}
VALUE engine_input(VALUE self, VALUE str) {
VALUE engine_inject(VALUE self, VALUE str) {
ms_conn* conn;
long used;
@ -97,10 +96,6 @@ void raise_error(SSL* ssl, int result) {
int error = SSL_get_error(ssl, result);
char buffer[256];
if(error == SSL_ERROR_WANT_READ) {
printf("OpenSSL WANT READ!\n");
}
ERR_error_string_n(error, buffer, sizeof(buffer));
rb_raise(eError, "OpenSSL error: %s", buffer);
@ -112,24 +107,12 @@ VALUE engine_read(VALUE self) {
int bytes, n;
Data_Get_Struct(self, ms_conn, conn);
printf("pre_read: %d\n", BIO_pending(conn->read));
if(!SSL_is_init_finished(conn->ssl)) {
n = SSL_accept(conn->ssl);
printf("SSL_accept: %d\n", n);
if(n < 0) {
if(SSL_want_read(conn->ssl)) return Qnil;
raise_error(conn->ssl, n);
}
}
bytes = SSL_read(conn->ssl, (void*)buf, sizeof(buf));
printf("ssl_read: %d => %d\n", BIO_pending(conn->read), bytes);
if(bytes > 0) {
return rb_str_new(buf, bytes);
}
raise_error(conn->ssl, bytes);
if(SSL_want_read(conn->ssl)) return Qnil;
@ -155,7 +138,7 @@ VALUE engine_write(VALUE self, VALUE str) {
raise_error(conn->ssl, bytes);
}
VALUE engine_output(VALUE self) {
VALUE engine_extract(VALUE self) {
ms_conn* conn;
int bytes;
size_t pending;
@ -177,6 +160,11 @@ VALUE engine_output(VALUE self) {
}
void Init_mini_ssl() {
SSL_library_init();
OpenSSL_add_ssl_algorithms();
SSL_load_error_strings();
ERR_load_crypto_strings();
VALUE mod = rb_define_module("MiniSSL");
VALUE eng = rb_define_class_under(mod, "Engine", rb_cObject);
@ -185,9 +173,9 @@ void Init_mini_ssl() {
rb_define_singleton_method(eng, "server", engine_init_server, 2);
rb_define_singleton_method(eng, "client", engine_init_client, 0);
rb_define_method(eng, "input", engine_input, 1);
rb_define_method(eng, "inject", engine_inject, 1);
rb_define_method(eng, "read", engine_read, 0);
rb_define_method(eng, "write", engine_write, 1);
rb_define_method(eng, "output", engine_output, 0);
rb_define_method(eng, "extract", engine_extract, 0);
}

View file

@ -10,40 +10,17 @@ module MiniSSL
end
def readpartial(size)
p :start
p :a1 => @engine.read
p :w1 => @engine.output
data = @socket.readpartial(size)
p :data => data
@engine.input data
p :a2 => @engine.read
p :w1 => @engine.output
return
while true
output = @engine.read
return output if output
if IO.select([@socket], nil, nil, 1)
data = @socket.readpartial(size)
p :rp => [size, data.size, data]
p :in => @engine.input(data)
end
data = @socket.readpartial(size)
@engine.inject(data)
output = @engine.read
p :read => output
return output if output
neg_data = @engine.output
p :neg => neg_data
if neg_data
while neg_data = @engine.extract
@socket.write neg_data
end
end
@ -54,7 +31,7 @@ module MiniSSL
while true
wrote = @engine.write data
enc = @engine.output
enc = @engine.extract
if enc
@socket.write enc
@ -71,8 +48,23 @@ module MiniSSL
def flush
@socket.flush
end
def close
@socket.close
end
def peeraddr
@socket.peeraddr
end
end
class Context
attr_accessor :key, :cert, :verify_mode
end
VERIFY_NONE = 0
VERIFY_PEER = 1
class Server
def initialize(socket, ctx)
@socket = socket
@ -85,9 +77,13 @@ module MiniSSL
def accept
io = @socket.accept
engine = Engine.server @ctx[:key], @ctx[:cert]
engine = Engine.server @ctx.key, @ctx.cert
Socket.new io, engine
end
def close
@socket.close
end
end
end

View file

@ -351,22 +351,20 @@ module Puma
params = Rack::Utils.parse_query uri.query
require 'minissl'
# ctx = OpenSSL::SSL::SSLContext.new
ctx = MiniSSL::Context.new
unless params['key']
error "Please specify the SSL key via 'key='"
end
# ctx.key = OpenSSL::PKey::RSA.new File.read(params['key'])
ctx.key = params['key']
unless params['cert']
error "Please specify the SSL cert via 'cert='"
end
# ctx.cert = OpenSSL::X509::Certificate.new File.read(params['cert'])
ctx.cert = params['cert']
# ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE
#
ctx = { :key => params['key'], :cert => params['cert'] }
ctx.verify_mode = MiniSSL::VERIFY_NONE
if fd = @inherited_fds.delete(str)
log "* Inherited #{str}"

View file

@ -129,6 +129,8 @@ module Puma
end
def add_ssl_listener(host, port, ctx, optimize_for_latency=true, backlog=1024)
require 'minissl'
s = TCPServer.new(host, port)
if optimize_for_latency
s.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)

View file

@ -3,6 +3,7 @@ require 'test/unit'
require 'socket'
require 'openssl'
require 'minissl'
require 'puma/server'
require 'net/https'
@ -27,20 +28,19 @@ class TestPumaServer < Test::Unit::TestCase
end
def test_url_scheme_for_https
ctx = OpenSSL::SSL::SSLContext.new
ctx = MiniSSL::Context.new
ctx.key = OpenSSL::PKey::RSA.new File.read(@ssl_key)
ctx.key = @ssl_key
ctx.cert = @ssl_cert
ctx.cert = OpenSSL::X509::Certificate.new File.read(@ssl_cert)
ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE
ctx.verify_mode = MiniSSL::VERIFY_NONE
@server.add_ssl_listener @host, @port, ctx
@server.run
http = Net::HTTP.new @host, @port
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
http.verify_mode = MiniSSL::VERIFY_NONE
body = nil
http.start do