puma 3.12.0 → 5.6.8
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puma might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/History.md +1620 -439
- data/LICENSE +23 -20
- data/README.md +175 -63
- data/bin/puma-wild +3 -9
- data/docs/architecture.md +59 -21
- data/docs/compile_options.md +21 -0
- data/docs/deployment.md +69 -58
- data/docs/fork_worker.md +33 -0
- data/docs/jungle/README.md +9 -0
- data/{tools → docs}/jungle/rc.d/README.md +1 -1
- data/{tools → docs}/jungle/rc.d/puma +2 -2
- data/docs/kubernetes.md +66 -0
- data/docs/nginx.md +1 -1
- data/docs/plugins.md +22 -12
- data/docs/rails_dev_mode.md +28 -0
- data/docs/restart.md +47 -22
- data/docs/signals.md +13 -11
- data/docs/stats.md +142 -0
- data/docs/systemd.md +95 -120
- data/ext/puma_http11/PumaHttp11Service.java +2 -2
- data/ext/puma_http11/ext_help.h +1 -1
- data/ext/puma_http11/extconf.rb +57 -2
- data/ext/puma_http11/http11_parser.c +105 -117
- data/ext/puma_http11/http11_parser.h +1 -1
- data/ext/puma_http11/http11_parser.java.rl +22 -38
- data/ext/puma_http11/http11_parser.rl +4 -2
- data/ext/puma_http11/http11_parser_common.rl +4 -4
- data/ext/puma_http11/mini_ssl.c +347 -94
- data/ext/puma_http11/no_ssl/PumaHttp11Service.java +15 -0
- data/ext/puma_http11/org/jruby/puma/Http11.java +108 -116
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +84 -99
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +124 -71
- data/ext/puma_http11/puma_http11.c +35 -51
- data/lib/puma/app/status.rb +71 -49
- data/lib/puma/binder.rb +241 -143
- data/lib/puma/cli.rb +30 -18
- data/lib/puma/client.rb +379 -229
- data/lib/puma/cluster/worker.rb +173 -0
- data/lib/puma/cluster/worker_handle.rb +94 -0
- data/lib/puma/cluster.rb +249 -232
- data/lib/puma/commonlogger.rb +4 -2
- data/lib/puma/configuration.rb +63 -51
- data/lib/puma/const.rb +44 -21
- data/lib/puma/control_cli.rb +123 -73
- data/lib/puma/detect.rb +31 -2
- data/lib/puma/dsl.rb +631 -125
- data/lib/puma/error_logger.rb +104 -0
- data/lib/puma/events.rb +57 -31
- data/lib/puma/io_buffer.rb +9 -5
- data/lib/puma/jruby_restart.rb +2 -58
- data/lib/puma/json_serialization.rb +96 -0
- data/lib/puma/launcher.rb +196 -70
- data/lib/puma/minissl/context_builder.rb +81 -0
- data/lib/puma/minissl.rb +172 -65
- data/lib/puma/null_io.rb +20 -1
- data/lib/puma/plugin/tmp_restart.rb +2 -0
- data/lib/puma/plugin.rb +9 -13
- data/lib/puma/queue_close.rb +26 -0
- data/lib/puma/rack/builder.rb +5 -6
- data/lib/puma/rack/urlmap.rb +2 -0
- data/lib/puma/rack_default.rb +2 -0
- data/lib/puma/reactor.rb +87 -316
- data/lib/puma/request.rb +476 -0
- data/lib/puma/runner.rb +50 -55
- data/lib/puma/server.rb +307 -695
- data/lib/puma/single.rb +13 -67
- data/lib/puma/state_file.rb +49 -7
- data/lib/puma/systemd.rb +46 -0
- data/lib/puma/thread_pool.rb +134 -82
- data/lib/puma/util.rb +34 -10
- data/lib/puma.rb +56 -0
- data/lib/rack/handler/puma.rb +8 -6
- data/lib/rack/version_restriction.rb +15 -0
- data/tools/Dockerfile +16 -0
- data/tools/trickletest.rb +0 -1
- metadata +49 -32
- data/ext/puma_http11/io_buffer.c +0 -155
- data/lib/puma/accept_nonblock.rb +0 -23
- data/lib/puma/compat.rb +0 -14
- data/lib/puma/convenient.rb +0 -23
- data/lib/puma/daemon_ext.rb +0 -31
- data/lib/puma/delegation.rb +0 -11
- data/lib/puma/java_io_buffer.rb +0 -45
- data/lib/puma/rack/backports/uri/common_193.rb +0 -33
- data/lib/puma/tcp_logger.rb +0 -39
- data/tools/jungle/README.md +0 -19
- data/tools/jungle/init.d/README.md +0 -61
- data/tools/jungle/init.d/puma +0 -421
- data/tools/jungle/init.d/run-puma +0 -18
- data/tools/jungle/upstart/README.md +0 -61
- data/tools/jungle/upstart/puma-manager.conf +0 -31
- data/tools/jungle/upstart/puma.conf +0 -69
- /data/{tools → docs}/jungle/rc.d/puma.conf +0 -0
@@ -1,5 +1,5 @@
|
|
1
1
|
%%{
|
2
|
-
|
2
|
+
|
3
3
|
machine puma_parser_common;
|
4
4
|
|
5
5
|
#### HTTP PROTOCOL GRAMMAR
|
@@ -16,7 +16,7 @@
|
|
16
16
|
unreserved = (alpha | digit | safe | extra | national);
|
17
17
|
escape = ("%" xdigit xdigit);
|
18
18
|
uchar = (unreserved | escape | "%");
|
19
|
-
pchar = (uchar | ":" | "@" | "&" | "=" | "+");
|
19
|
+
pchar = (uchar | ":" | "@" | "&" | "=" | "+" | ";");
|
20
20
|
tspecials = ("(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\\" | "\"" | "/" | "[" | "]" | "?" | "=" | "{" | "}" | " " | "\t");
|
21
21
|
|
22
22
|
# elements
|
@@ -30,7 +30,7 @@
|
|
30
30
|
query = ( uchar | reserved )* %query_string ;
|
31
31
|
param = ( pchar | "/" )* ;
|
32
32
|
params = ( param ( ";" param )* ) ;
|
33
|
-
rel_path = ( path? %request_path
|
33
|
+
rel_path = ( path? %request_path ) ("?" %start_query query)?;
|
34
34
|
absolute_path = ( "/"+ rel_path );
|
35
35
|
|
36
36
|
Request_URI = ( "*" | absolute_uri | absolute_path ) >mark %request_uri;
|
@@ -43,7 +43,7 @@
|
|
43
43
|
|
44
44
|
field_name = ( token -- ":" )+ >start_field $snake_upcase_field %write_field;
|
45
45
|
|
46
|
-
field_value = any* >start_value %write_value;
|
46
|
+
field_value = ( (any -- CTL) | "\t" )* >start_value %write_value;
|
47
47
|
|
48
48
|
message_header = field_name ":" " "* field_value :> CRLF;
|
49
49
|
|
data/ext/puma_http11/mini_ssl.c
CHANGED
@@ -2,12 +2,7 @@
|
|
2
2
|
|
3
3
|
#include <ruby.h>
|
4
4
|
#include <ruby/version.h>
|
5
|
-
|
6
|
-
#if RUBY_API_VERSION_MAJOR == 1
|
7
|
-
#include <rubyio.h>
|
8
|
-
#else
|
9
5
|
#include <ruby/io.h>
|
10
|
-
#endif
|
11
6
|
|
12
7
|
#ifdef HAVE_OPENSSL_BIO_H
|
13
8
|
|
@@ -33,7 +28,16 @@ typedef struct {
|
|
33
28
|
int bytes;
|
34
29
|
} ms_cert_buf;
|
35
30
|
|
36
|
-
|
31
|
+
VALUE eError;
|
32
|
+
|
33
|
+
NORETURN(void raise_file_error(const char* caller, const char *filename));
|
34
|
+
|
35
|
+
void raise_file_error(const char* caller, const char *filename) {
|
36
|
+
rb_raise(eError, "%s: error in file '%s': %s", caller, filename, ERR_error_string(ERR_get_error(), NULL));
|
37
|
+
}
|
38
|
+
|
39
|
+
void engine_free(void *ptr) {
|
40
|
+
ms_conn *conn = ptr;
|
37
41
|
ms_cert_buf* cert_buf = (ms_cert_buf*)SSL_get_app_data(conn->ssl);
|
38
42
|
if(cert_buf) {
|
39
43
|
OPENSSL_free(cert_buf->buf);
|
@@ -45,61 +49,72 @@ void engine_free(ms_conn* conn) {
|
|
45
49
|
free(conn);
|
46
50
|
}
|
47
51
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
conn->read = BIO_new(BIO_s_mem());
|
54
|
-
BIO_set_nbio(conn->read, 1);
|
55
|
-
|
56
|
-
conn->write = BIO_new(BIO_s_mem());
|
57
|
-
BIO_set_nbio(conn->write, 1);
|
58
|
-
|
59
|
-
conn->ssl = 0;
|
60
|
-
conn->ctx = 0;
|
61
|
-
|
62
|
-
return conn;
|
63
|
-
}
|
52
|
+
const rb_data_type_t engine_data_type = {
|
53
|
+
"MiniSSL/ENGINE",
|
54
|
+
{ 0, engine_free, 0 },
|
55
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
56
|
+
};
|
64
57
|
|
65
|
-
|
66
|
-
|
58
|
+
#ifndef HAVE_SSL_CTX_SET_DH_AUTO
|
59
|
+
DH *get_dh2048(void) {
|
60
|
+
/* `openssl dhparam -C 2048`
|
67
61
|
* -----BEGIN DH PARAMETERS-----
|
68
|
-
*
|
69
|
-
*
|
70
|
-
*
|
62
|
+
* MIIBCAKCAQEAjmh1uQHdTfxOyxEbKAV30fUfzqMDF/ChPzjfyzl2jcrqQMhrk76o
|
63
|
+
* 2NPNXqxHwsddMZ1RzvU8/jl+uhRuPWjXCFZbhET4N1vrviZM3VJhV8PPHuiVOACO
|
64
|
+
* y32jFd+Szx4bo2cXSK83hJ6jRd+0asP1awWjz9/06dFkrILCXMIfQLo0D8rqmppn
|
65
|
+
* EfDDAwuudCpM9kcDmBRAm9JsKbQ6gzZWjkc5+QWSaQofojIHbjvj3xzguaCJn+oQ
|
66
|
+
* vHWM+hsAnaOgEwCyeZ3xqs+/5lwSbkE/tqJW98cEZGygBUVo9jxZRZx6KOfjpdrb
|
67
|
+
* yenO9LJr/qtyrZB31WJbqxI0m0AKTAO8UwIBAg==
|
71
68
|
* -----END DH PARAMETERS-----
|
72
69
|
*/
|
73
|
-
static unsigned char
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
70
|
+
static unsigned char dh2048_p[] = {
|
71
|
+
0x8E, 0x68, 0x75, 0xB9, 0x01, 0xDD, 0x4D, 0xFC, 0x4E, 0xCB,
|
72
|
+
0x11, 0x1B, 0x28, 0x05, 0x77, 0xD1, 0xF5, 0x1F, 0xCE, 0xA3,
|
73
|
+
0x03, 0x17, 0xF0, 0xA1, 0x3F, 0x38, 0xDF, 0xCB, 0x39, 0x76,
|
74
|
+
0x8D, 0xCA, 0xEA, 0x40, 0xC8, 0x6B, 0x93, 0xBE, 0xA8, 0xD8,
|
75
|
+
0xD3, 0xCD, 0x5E, 0xAC, 0x47, 0xC2, 0xC7, 0x5D, 0x31, 0x9D,
|
76
|
+
0x51, 0xCE, 0xF5, 0x3C, 0xFE, 0x39, 0x7E, 0xBA, 0x14, 0x6E,
|
77
|
+
0x3D, 0x68, 0xD7, 0x08, 0x56, 0x5B, 0x84, 0x44, 0xF8, 0x37,
|
78
|
+
0x5B, 0xEB, 0xBE, 0x26, 0x4C, 0xDD, 0x52, 0x61, 0x57, 0xC3,
|
79
|
+
0xCF, 0x1E, 0xE8, 0x95, 0x38, 0x00, 0x8E, 0xCB, 0x7D, 0xA3,
|
80
|
+
0x15, 0xDF, 0x92, 0xCF, 0x1E, 0x1B, 0xA3, 0x67, 0x17, 0x48,
|
81
|
+
0xAF, 0x37, 0x84, 0x9E, 0xA3, 0x45, 0xDF, 0xB4, 0x6A, 0xC3,
|
82
|
+
0xF5, 0x6B, 0x05, 0xA3, 0xCF, 0xDF, 0xF4, 0xE9, 0xD1, 0x64,
|
83
|
+
0xAC, 0x82, 0xC2, 0x5C, 0xC2, 0x1F, 0x40, 0xBA, 0x34, 0x0F,
|
84
|
+
0xCA, 0xEA, 0x9A, 0x9A, 0x67, 0x11, 0xF0, 0xC3, 0x03, 0x0B,
|
85
|
+
0xAE, 0x74, 0x2A, 0x4C, 0xF6, 0x47, 0x03, 0x98, 0x14, 0x40,
|
86
|
+
0x9B, 0xD2, 0x6C, 0x29, 0xB4, 0x3A, 0x83, 0x36, 0x56, 0x8E,
|
87
|
+
0x47, 0x39, 0xF9, 0x05, 0x92, 0x69, 0x0A, 0x1F, 0xA2, 0x32,
|
88
|
+
0x07, 0x6E, 0x3B, 0xE3, 0xDF, 0x1C, 0xE0, 0xB9, 0xA0, 0x89,
|
89
|
+
0x9F, 0xEA, 0x10, 0xBC, 0x75, 0x8C, 0xFA, 0x1B, 0x00, 0x9D,
|
90
|
+
0xA3, 0xA0, 0x13, 0x00, 0xB2, 0x79, 0x9D, 0xF1, 0xAA, 0xCF,
|
91
|
+
0xBF, 0xE6, 0x5C, 0x12, 0x6E, 0x41, 0x3F, 0xB6, 0xA2, 0x56,
|
92
|
+
0xF7, 0xC7, 0x04, 0x64, 0x6C, 0xA0, 0x05, 0x45, 0x68, 0xF6,
|
93
|
+
0x3C, 0x59, 0x45, 0x9C, 0x7A, 0x28, 0xE7, 0xE3, 0xA5, 0xDA,
|
94
|
+
0xDB, 0xC9, 0xE9, 0xCE, 0xF4, 0xB2, 0x6B, 0xFE, 0xAB, 0x72,
|
95
|
+
0xAD, 0x90, 0x77, 0xD5, 0x62, 0x5B, 0xAB, 0x12, 0x34, 0x9B,
|
96
|
+
0x40, 0x0A, 0x4C, 0x03, 0xBC, 0x53
|
85
97
|
};
|
86
|
-
static unsigned char
|
98
|
+
static unsigned char dh2048_g[] = { 0x02 };
|
87
99
|
|
88
100
|
DH *dh;
|
101
|
+
#if !(OPENSSL_VERSION_NUMBER < 0x10100005L)
|
102
|
+
BIGNUM *p, *g;
|
103
|
+
#endif
|
104
|
+
|
89
105
|
dh = DH_new();
|
90
106
|
|
91
|
-
#if OPENSSL_VERSION_NUMBER < 0x10100005L
|
92
|
-
dh->p = BN_bin2bn(
|
93
|
-
dh->g = BN_bin2bn(
|
107
|
+
#if OPENSSL_VERSION_NUMBER < 0x10100005L
|
108
|
+
dh->p = BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL);
|
109
|
+
dh->g = BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL);
|
94
110
|
|
95
111
|
if ((dh->p == NULL) || (dh->g == NULL)) {
|
96
112
|
DH_free(dh);
|
97
113
|
return NULL;
|
98
114
|
}
|
99
115
|
#else
|
100
|
-
|
101
|
-
|
102
|
-
g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL);
|
116
|
+
p = BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL);
|
117
|
+
g = BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL);
|
103
118
|
|
104
119
|
if (p == NULL || g == NULL || !DH_set0_pqg(dh, p, NULL, g)) {
|
105
120
|
DH_free(dh);
|
@@ -111,6 +126,38 @@ DH *get_dh1024() {
|
|
111
126
|
|
112
127
|
return dh;
|
113
128
|
}
|
129
|
+
#endif
|
130
|
+
|
131
|
+
static void
|
132
|
+
sslctx_free(void *ptr) {
|
133
|
+
SSL_CTX *ctx = ptr;
|
134
|
+
SSL_CTX_free(ctx);
|
135
|
+
}
|
136
|
+
|
137
|
+
static const rb_data_type_t sslctx_type = {
|
138
|
+
"MiniSSL/SSLContext",
|
139
|
+
{
|
140
|
+
0, sslctx_free,
|
141
|
+
},
|
142
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
|
143
|
+
};
|
144
|
+
|
145
|
+
ms_conn* engine_alloc(VALUE klass, VALUE* obj) {
|
146
|
+
ms_conn* conn;
|
147
|
+
|
148
|
+
*obj = TypedData_Make_Struct(klass, ms_conn, &engine_data_type, conn);
|
149
|
+
|
150
|
+
conn->read = BIO_new(BIO_s_mem());
|
151
|
+
BIO_set_nbio(conn->read, 1);
|
152
|
+
|
153
|
+
conn->write = BIO_new(BIO_s_mem());
|
154
|
+
BIO_set_nbio(conn->write, 1);
|
155
|
+
|
156
|
+
conn->ssl = 0;
|
157
|
+
conn->ctx = 0;
|
158
|
+
|
159
|
+
return conn;
|
160
|
+
}
|
114
161
|
|
115
162
|
static int engine_verify_callback(int preverify_ok, X509_STORE_CTX* ctx) {
|
116
163
|
X509* err_cert;
|
@@ -138,44 +185,150 @@ static int engine_verify_callback(int preverify_ok, X509_STORE_CTX* ctx) {
|
|
138
185
|
return preverify_ok;
|
139
186
|
}
|
140
187
|
|
141
|
-
|
142
|
-
|
188
|
+
static VALUE
|
189
|
+
sslctx_alloc(VALUE klass) {
|
190
|
+
SSL_CTX *ctx;
|
191
|
+
long mode = 0 |
|
192
|
+
SSL_MODE_ENABLE_PARTIAL_WRITE |
|
193
|
+
SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
|
194
|
+
SSL_MODE_RELEASE_BUFFERS;
|
195
|
+
|
196
|
+
#ifdef HAVE_TLS_SERVER_METHOD
|
197
|
+
ctx = SSL_CTX_new(TLS_method());
|
198
|
+
// printf("\nctx using TLS_method security_level %d\n", SSL_CTX_get_security_level(ctx));
|
199
|
+
#else
|
200
|
+
ctx = SSL_CTX_new(SSLv23_method());
|
201
|
+
#endif
|
202
|
+
if (!ctx) {
|
203
|
+
rb_raise(eError, "SSL_CTX_new");
|
204
|
+
}
|
205
|
+
SSL_CTX_set_mode(ctx, mode);
|
206
|
+
|
207
|
+
return TypedData_Wrap_Struct(klass, &sslctx_type, ctx);
|
208
|
+
}
|
209
|
+
|
210
|
+
VALUE
|
211
|
+
sslctx_initialize(VALUE self, VALUE mini_ssl_ctx) {
|
143
212
|
SSL_CTX* ctx;
|
144
|
-
SSL* ssl;
|
145
213
|
|
146
|
-
|
214
|
+
#ifdef HAVE_SSL_CTX_SET_MIN_PROTO_VERSION
|
215
|
+
int min;
|
216
|
+
#endif
|
217
|
+
int ssl_options;
|
218
|
+
VALUE key, cert, ca, verify_mode, ssl_cipher_filter, no_tlsv1, no_tlsv1_1,
|
219
|
+
verification_flags, session_id_bytes, cert_pem, key_pem;
|
220
|
+
#ifndef HAVE_SSL_CTX_SET_DH_AUTO
|
221
|
+
DH *dh;
|
222
|
+
#endif
|
223
|
+
BIO *bio;
|
224
|
+
X509 *x509;
|
225
|
+
EVP_PKEY *pkey;
|
226
|
+
|
227
|
+
#if OPENSSL_VERSION_NUMBER < 0x10002000L
|
228
|
+
EC_KEY *ecdh;
|
229
|
+
#endif
|
230
|
+
|
231
|
+
TypedData_Get_Struct(self, SSL_CTX, &sslctx_type, ctx);
|
232
|
+
|
233
|
+
key = rb_funcall(mini_ssl_ctx, rb_intern_const("key"), 0);
|
234
|
+
|
235
|
+
cert = rb_funcall(mini_ssl_ctx, rb_intern_const("cert"), 0);
|
147
236
|
|
148
|
-
|
149
|
-
VALUE key = rb_funcall(mini_ssl_ctx, sym_key, 0);
|
237
|
+
ca = rb_funcall(mini_ssl_ctx, rb_intern_const("ca"), 0);
|
150
238
|
|
151
|
-
|
239
|
+
cert_pem = rb_funcall(mini_ssl_ctx, rb_intern_const("cert_pem"), 0);
|
152
240
|
|
153
|
-
|
154
|
-
VALUE cert = rb_funcall(mini_ssl_ctx, sym_cert, 0);
|
241
|
+
key_pem = rb_funcall(mini_ssl_ctx, rb_intern_const("key_pem"), 0);
|
155
242
|
|
156
|
-
|
243
|
+
verify_mode = rb_funcall(mini_ssl_ctx, rb_intern_const("verify_mode"), 0);
|
157
244
|
|
158
|
-
|
159
|
-
|
245
|
+
ssl_cipher_filter = rb_funcall(mini_ssl_ctx, rb_intern_const("ssl_cipher_filter"), 0);
|
246
|
+
|
247
|
+
no_tlsv1 = rb_funcall(mini_ssl_ctx, rb_intern_const("no_tlsv1"), 0);
|
248
|
+
|
249
|
+
no_tlsv1_1 = rb_funcall(mini_ssl_ctx, rb_intern_const("no_tlsv1_1"), 0);
|
250
|
+
|
251
|
+
if (!NIL_P(cert)) {
|
252
|
+
StringValue(cert);
|
253
|
+
|
254
|
+
if (SSL_CTX_use_certificate_chain_file(ctx, RSTRING_PTR(cert)) != 1) {
|
255
|
+
raise_file_error("SSL_CTX_use_certificate_chain_file", RSTRING_PTR(cert));
|
256
|
+
}
|
257
|
+
}
|
258
|
+
|
259
|
+
if (!NIL_P(key)) {
|
260
|
+
StringValue(key);
|
261
|
+
|
262
|
+
if (SSL_CTX_use_PrivateKey_file(ctx, RSTRING_PTR(key), SSL_FILETYPE_PEM) != 1) {
|
263
|
+
raise_file_error("SSL_CTX_use_PrivateKey_file", RSTRING_PTR(key));
|
264
|
+
}
|
265
|
+
}
|
266
|
+
|
267
|
+
if (!NIL_P(cert_pem)) {
|
268
|
+
bio = BIO_new(BIO_s_mem());
|
269
|
+
BIO_puts(bio, RSTRING_PTR(cert_pem));
|
270
|
+
x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
|
271
|
+
|
272
|
+
if (SSL_CTX_use_certificate(ctx, x509) != 1) {
|
273
|
+
raise_file_error("SSL_CTX_use_certificate", RSTRING_PTR(cert_pem));
|
274
|
+
}
|
275
|
+
}
|
160
276
|
|
161
|
-
|
162
|
-
|
277
|
+
if (!NIL_P(key_pem)) {
|
278
|
+
bio = BIO_new(BIO_s_mem());
|
279
|
+
BIO_puts(bio, RSTRING_PTR(key_pem));
|
280
|
+
pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
|
163
281
|
|
164
|
-
|
165
|
-
|
282
|
+
if (SSL_CTX_use_PrivateKey(ctx, pkey) != 1) {
|
283
|
+
raise_file_error("SSL_CTX_use_PrivateKey", RSTRING_PTR(key_pem));
|
284
|
+
}
|
285
|
+
}
|
166
286
|
|
167
|
-
|
168
|
-
conn->ctx = ctx;
|
287
|
+
verification_flags = rb_funcall(mini_ssl_ctx, rb_intern_const("verification_flags"), 0);
|
169
288
|
|
170
|
-
|
171
|
-
|
289
|
+
if (!NIL_P(verification_flags)) {
|
290
|
+
X509_VERIFY_PARAM *param = SSL_CTX_get0_param(ctx);
|
291
|
+
X509_VERIFY_PARAM_set_flags(param, NUM2INT(verification_flags));
|
292
|
+
SSL_CTX_set1_param(ctx, param);
|
293
|
+
}
|
172
294
|
|
173
295
|
if (!NIL_P(ca)) {
|
174
296
|
StringValue(ca);
|
175
|
-
SSL_CTX_load_verify_locations(ctx, RSTRING_PTR(ca), NULL)
|
297
|
+
if (SSL_CTX_load_verify_locations(ctx, RSTRING_PTR(ca), NULL) != 1) {
|
298
|
+
raise_file_error("SSL_CTX_load_verify_locations", RSTRING_PTR(ca));
|
299
|
+
}
|
300
|
+
}
|
301
|
+
|
302
|
+
ssl_options = SSL_OP_CIPHER_SERVER_PREFERENCE | SSL_OP_SINGLE_ECDH_USE | SSL_OP_NO_COMPRESSION;
|
303
|
+
|
304
|
+
#ifdef HAVE_SSL_CTX_SET_MIN_PROTO_VERSION
|
305
|
+
if (RTEST(no_tlsv1_1)) {
|
306
|
+
min = TLS1_2_VERSION;
|
307
|
+
}
|
308
|
+
else if (RTEST(no_tlsv1)) {
|
309
|
+
min = TLS1_1_VERSION;
|
310
|
+
}
|
311
|
+
else {
|
312
|
+
min = TLS1_VERSION;
|
176
313
|
}
|
177
314
|
|
178
|
-
|
315
|
+
SSL_CTX_set_min_proto_version(ctx, min);
|
316
|
+
|
317
|
+
SSL_CTX_set_options(ctx, ssl_options);
|
318
|
+
|
319
|
+
#else
|
320
|
+
/* As of 1.0.2f, SSL_OP_SINGLE_DH_USE key use is always on */
|
321
|
+
ssl_options |= SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_SINGLE_DH_USE;
|
322
|
+
|
323
|
+
if (RTEST(no_tlsv1)) {
|
324
|
+
ssl_options |= SSL_OP_NO_TLSv1;
|
325
|
+
}
|
326
|
+
if(RTEST(no_tlsv1_1)) {
|
327
|
+
ssl_options |= SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1;
|
328
|
+
}
|
329
|
+
SSL_CTX_set_options(ctx, ssl_options);
|
330
|
+
#endif
|
331
|
+
|
179
332
|
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
|
180
333
|
|
181
334
|
if (!NIL_P(ssl_cipher_filter)) {
|
@@ -186,29 +339,66 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
|
|
186
339
|
SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL@STRENGTH");
|
187
340
|
}
|
188
341
|
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
EC_KEY *ecdh = EC_KEY_new_by_curve_name(NID_secp521r1);
|
342
|
+
#if OPENSSL_VERSION_NUMBER < 0x10002000L
|
343
|
+
// Remove this case if OpenSSL 1.0.1 (now EOL) support is no
|
344
|
+
// longer needed.
|
345
|
+
ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
|
194
346
|
if (ecdh) {
|
195
347
|
SSL_CTX_set_tmp_ecdh(ctx, ecdh);
|
196
348
|
EC_KEY_free(ecdh);
|
197
349
|
}
|
350
|
+
#elif OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
351
|
+
SSL_CTX_set_ecdh_auto(ctx, 1);
|
198
352
|
#endif
|
199
353
|
|
200
|
-
ssl = SSL_new(ctx);
|
201
|
-
conn->ssl = ssl;
|
202
|
-
SSL_set_app_data(ssl, NULL);
|
203
|
-
|
204
354
|
if (NIL_P(verify_mode)) {
|
205
|
-
/*
|
355
|
+
/* SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); */
|
206
356
|
} else {
|
207
|
-
|
357
|
+
SSL_CTX_set_verify(ctx, NUM2INT(verify_mode), engine_verify_callback);
|
208
358
|
}
|
209
359
|
|
210
|
-
|
360
|
+
// Random.bytes available in Ruby 2.5 and later, Random::DEFAULT deprecated in 3.0
|
361
|
+
session_id_bytes = rb_funcall(
|
362
|
+
#ifdef HAVE_RANDOM_BYTES
|
363
|
+
rb_cRandom,
|
364
|
+
#else
|
365
|
+
rb_const_get(rb_cRandom, rb_intern_const("DEFAULT")),
|
366
|
+
#endif
|
367
|
+
rb_intern_const("bytes"),
|
368
|
+
1, ULL2NUM(SSL_MAX_SSL_SESSION_ID_LENGTH));
|
369
|
+
|
370
|
+
SSL_CTX_set_session_id_context(ctx,
|
371
|
+
(unsigned char *) RSTRING_PTR(session_id_bytes),
|
372
|
+
SSL_MAX_SSL_SESSION_ID_LENGTH);
|
373
|
+
|
374
|
+
// printf("\ninitialize end security_level %d\n", SSL_CTX_get_security_level(ctx));
|
375
|
+
|
376
|
+
#ifdef HAVE_SSL_CTX_SET_DH_AUTO
|
377
|
+
// https://www.openssl.org/docs/man3.0/man3/SSL_CTX_set_dh_auto.html
|
378
|
+
SSL_CTX_set_dh_auto(ctx, 1);
|
379
|
+
#else
|
380
|
+
dh = get_dh2048();
|
381
|
+
SSL_CTX_set_tmp_dh(ctx, dh);
|
382
|
+
#endif
|
383
|
+
|
384
|
+
rb_obj_freeze(self);
|
385
|
+
return self;
|
386
|
+
}
|
387
|
+
|
388
|
+
VALUE engine_init_server(VALUE self, VALUE sslctx) {
|
389
|
+
ms_conn* conn;
|
390
|
+
VALUE obj;
|
391
|
+
SSL_CTX* ctx;
|
392
|
+
SSL* ssl;
|
393
|
+
|
394
|
+
conn = engine_alloc(self, &obj);
|
211
395
|
|
396
|
+
TypedData_Get_Struct(sslctx, SSL_CTX, &sslctx_type, ctx);
|
397
|
+
|
398
|
+
ssl = SSL_new(ctx);
|
399
|
+
conn->ssl = ssl;
|
400
|
+
SSL_set_app_data(ssl, NULL);
|
401
|
+
SSL_set_bio(ssl, conn->read, conn->write);
|
212
402
|
SSL_set_accept_state(ssl);
|
213
403
|
return obj;
|
214
404
|
}
|
@@ -216,8 +406,11 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
|
|
216
406
|
VALUE engine_init_client(VALUE klass) {
|
217
407
|
VALUE obj;
|
218
408
|
ms_conn* conn = engine_alloc(klass, &obj);
|
219
|
-
|
409
|
+
#ifdef HAVE_DTLS_METHOD
|
410
|
+
conn->ctx = SSL_CTX_new(DTLS_method());
|
411
|
+
#else
|
220
412
|
conn->ctx = SSL_CTX_new(DTLSv1_method());
|
413
|
+
#endif
|
221
414
|
conn->ssl = SSL_new(conn->ctx);
|
222
415
|
SSL_set_app_data(conn->ssl, NULL);
|
223
416
|
SSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL);
|
@@ -232,7 +425,7 @@ VALUE engine_inject(VALUE self, VALUE str) {
|
|
232
425
|
ms_conn* conn;
|
233
426
|
long used;
|
234
427
|
|
235
|
-
|
428
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
236
429
|
|
237
430
|
StringValue(str);
|
238
431
|
|
@@ -245,13 +438,14 @@ VALUE engine_inject(VALUE self, VALUE str) {
|
|
245
438
|
return INT2FIX(used);
|
246
439
|
}
|
247
440
|
|
248
|
-
|
441
|
+
NORETURN(void raise_error(SSL* ssl, int result));
|
249
442
|
|
250
443
|
void raise_error(SSL* ssl, int result) {
|
251
444
|
char buf[512];
|
252
445
|
char msg[512];
|
253
446
|
const char* err_str;
|
254
447
|
int err = errno;
|
448
|
+
int mask = 4095;
|
255
449
|
int ssl_err = SSL_get_error(ssl, result);
|
256
450
|
int verify_err = (int) SSL_get_verify_result(ssl);
|
257
451
|
|
@@ -268,8 +462,7 @@ void raise_error(SSL* ssl, int result) {
|
|
268
462
|
} else {
|
269
463
|
err = (int) ERR_get_error();
|
270
464
|
ERR_error_string_n(err, buf, sizeof(buf));
|
271
|
-
snprintf(msg, sizeof(msg), "OpenSSL error: %s - %d", buf, err);
|
272
|
-
|
465
|
+
snprintf(msg, sizeof(msg), "OpenSSL error: %s - %d", buf, err & mask);
|
273
466
|
}
|
274
467
|
} else {
|
275
468
|
snprintf(msg, sizeof(msg), "Unknown OpenSSL error: %d", ssl_err);
|
@@ -284,7 +477,7 @@ VALUE engine_read(VALUE self) {
|
|
284
477
|
char buf[512];
|
285
478
|
int bytes, error;
|
286
479
|
|
287
|
-
|
480
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
288
481
|
|
289
482
|
ERR_clear_error();
|
290
483
|
|
@@ -311,7 +504,7 @@ VALUE engine_write(VALUE self, VALUE str) {
|
|
311
504
|
ms_conn* conn;
|
312
505
|
int bytes;
|
313
506
|
|
314
|
-
|
507
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
315
508
|
|
316
509
|
StringValue(str);
|
317
510
|
|
@@ -333,9 +526,11 @@ VALUE engine_extract(VALUE self) {
|
|
333
526
|
ms_conn* conn;
|
334
527
|
int bytes;
|
335
528
|
size_t pending;
|
336
|
-
|
529
|
+
// https://www.openssl.org/docs/manmaster/man3/BIO_f_buffer.html
|
530
|
+
// crypto/bio/bf_buff.c DEFAULT_BUFFER_SIZE
|
531
|
+
char buf[4096];
|
337
532
|
|
338
|
-
|
533
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
339
534
|
|
340
535
|
pending = BIO_pending(conn->write);
|
341
536
|
if(pending > 0) {
|
@@ -354,7 +549,7 @@ VALUE engine_shutdown(VALUE self) {
|
|
354
549
|
ms_conn* conn;
|
355
550
|
int ok;
|
356
551
|
|
357
|
-
|
552
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
358
553
|
|
359
554
|
ERR_clear_error();
|
360
555
|
|
@@ -369,7 +564,7 @@ VALUE engine_shutdown(VALUE self) {
|
|
369
564
|
VALUE engine_init(VALUE self) {
|
370
565
|
ms_conn* conn;
|
371
566
|
|
372
|
-
|
567
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
373
568
|
|
374
569
|
return SSL_in_init(conn->ssl) ? Qtrue : Qfalse;
|
375
570
|
}
|
@@ -382,9 +577,13 @@ VALUE engine_peercert(VALUE self) {
|
|
382
577
|
ms_cert_buf* cert_buf = NULL;
|
383
578
|
VALUE rb_cert_buf;
|
384
579
|
|
385
|
-
|
580
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
386
581
|
|
582
|
+
#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
|
583
|
+
cert = SSL_get1_peer_certificate(conn->ssl);
|
584
|
+
#else
|
387
585
|
cert = SSL_get_peer_certificate(conn->ssl);
|
586
|
+
#endif
|
388
587
|
if(!cert) {
|
389
588
|
/*
|
390
589
|
* See if there was a failed certificate associated with this client.
|
@@ -413,12 +612,22 @@ VALUE engine_peercert(VALUE self) {
|
|
413
612
|
return rb_cert_buf;
|
414
613
|
}
|
415
614
|
|
615
|
+
/* @see Puma::MiniSSL::Socket#ssl_version_state
|
616
|
+
* @version 5.0.0
|
617
|
+
*/
|
618
|
+
static VALUE
|
619
|
+
engine_ssl_vers_st(VALUE self) {
|
620
|
+
ms_conn* conn;
|
621
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
622
|
+
return rb_ary_new3(2, rb_str_new2(SSL_get_version(conn->ssl)), rb_str_new2(SSL_state_string(conn->ssl)));
|
623
|
+
}
|
624
|
+
|
416
625
|
VALUE noop(VALUE self) {
|
417
626
|
return Qnil;
|
418
627
|
}
|
419
628
|
|
420
629
|
void Init_mini_ssl(VALUE puma) {
|
421
|
-
VALUE mod, eng;
|
630
|
+
VALUE mod, eng, sslctx;
|
422
631
|
|
423
632
|
/* Fake operation for documentation (RDoc, YARD) */
|
424
633
|
#if 0 == 1
|
@@ -431,7 +640,48 @@ void Init_mini_ssl(VALUE puma) {
|
|
431
640
|
ERR_load_crypto_strings();
|
432
641
|
|
433
642
|
mod = rb_define_module_under(puma, "MiniSSL");
|
643
|
+
|
434
644
|
eng = rb_define_class_under(mod, "Engine", rb_cObject);
|
645
|
+
rb_undef_alloc_func(eng);
|
646
|
+
|
647
|
+
sslctx = rb_define_class_under(mod, "SSLContext", rb_cObject);
|
648
|
+
rb_define_alloc_func(sslctx, sslctx_alloc);
|
649
|
+
rb_define_method(sslctx, "initialize", sslctx_initialize, 1);
|
650
|
+
rb_undef_method(sslctx, "initialize_copy");
|
651
|
+
|
652
|
+
|
653
|
+
// OpenSSL Build / Runtime/Load versions
|
654
|
+
|
655
|
+
/* Version of OpenSSL that Puma was compiled with */
|
656
|
+
rb_define_const(mod, "OPENSSL_VERSION", rb_str_new2(OPENSSL_VERSION_TEXT));
|
657
|
+
|
658
|
+
#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000
|
659
|
+
/* Version of OpenSSL that Puma loaded with */
|
660
|
+
rb_define_const(mod, "OPENSSL_LIBRARY_VERSION", rb_str_new2(OpenSSL_version(OPENSSL_VERSION)));
|
661
|
+
#else
|
662
|
+
rb_define_const(mod, "OPENSSL_LIBRARY_VERSION", rb_str_new2(SSLeay_version(SSLEAY_VERSION)));
|
663
|
+
#endif
|
664
|
+
|
665
|
+
#if defined(OPENSSL_NO_SSL3) || defined(OPENSSL_NO_SSL3_METHOD)
|
666
|
+
/* True if SSL3 is not available */
|
667
|
+
rb_define_const(mod, "OPENSSL_NO_SSL3", Qtrue);
|
668
|
+
#else
|
669
|
+
rb_define_const(mod, "OPENSSL_NO_SSL3", Qfalse);
|
670
|
+
#endif
|
671
|
+
|
672
|
+
#if defined(OPENSSL_NO_TLS1) || defined(OPENSSL_NO_TLS1_METHOD)
|
673
|
+
/* True if TLS1 is not available */
|
674
|
+
rb_define_const(mod, "OPENSSL_NO_TLS1", Qtrue);
|
675
|
+
#else
|
676
|
+
rb_define_const(mod, "OPENSSL_NO_TLS1", Qfalse);
|
677
|
+
#endif
|
678
|
+
|
679
|
+
#if defined(OPENSSL_NO_TLS1_1) || defined(OPENSSL_NO_TLS1_1_METHOD)
|
680
|
+
/* True if TLS1_1 is not available */
|
681
|
+
rb_define_const(mod, "OPENSSL_NO_TLS1_1", Qtrue);
|
682
|
+
#else
|
683
|
+
rb_define_const(mod, "OPENSSL_NO_TLS1_1", Qfalse);
|
684
|
+
#endif
|
435
685
|
|
436
686
|
rb_define_singleton_method(mod, "check", noop, 0);
|
437
687
|
|
@@ -451,13 +701,16 @@ void Init_mini_ssl(VALUE puma) {
|
|
451
701
|
rb_define_method(eng, "init?", engine_init, 0);
|
452
702
|
|
453
703
|
rb_define_method(eng, "peercert", engine_peercert, 0);
|
704
|
+
|
705
|
+
rb_define_method(eng, "ssl_vers_st", engine_ssl_vers_st, 0);
|
454
706
|
}
|
455
707
|
|
456
708
|
#else
|
457
709
|
|
710
|
+
NORETURN(VALUE raise_error(VALUE self));
|
711
|
+
|
458
712
|
VALUE raise_error(VALUE self) {
|
459
713
|
rb_raise(rb_eStandardError, "SSL not available in this build");
|
460
|
-
return Qnil;
|
461
714
|
}
|
462
715
|
|
463
716
|
void Init_mini_ssl(VALUE puma) {
|
@@ -0,0 +1,15 @@
|
|
1
|
+
package puma;
|
2
|
+
|
3
|
+
import java.io.IOException;
|
4
|
+
|
5
|
+
import org.jruby.Ruby;
|
6
|
+
import org.jruby.runtime.load.BasicLibraryService;
|
7
|
+
|
8
|
+
import org.jruby.puma.Http11;
|
9
|
+
|
10
|
+
public class PumaHttp11Service implements BasicLibraryService {
|
11
|
+
public boolean basicLoad(final Ruby runtime) throws IOException {
|
12
|
+
Http11.createHttp11(runtime);
|
13
|
+
return true;
|
14
|
+
}
|
15
|
+
}
|