puma 3.12.6 → 6.2.2
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 +1775 -451
- data/LICENSE +23 -20
- data/README.md +193 -65
- data/bin/puma-wild +3 -9
- data/docs/architecture.md +59 -21
- data/docs/compile_options.md +55 -0
- data/docs/deployment.md +69 -58
- data/docs/fork_worker.md +31 -0
- data/docs/images/puma-connection-flow-no-reactor.png +0 -0
- data/docs/images/puma-connection-flow.png +0 -0
- data/docs/images/puma-general-arch.png +0 -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/{tools → docs}/jungle/rc.d/puma.conf +0 -0
- data/docs/kubernetes.md +66 -0
- data/docs/nginx.md +2 -2
- 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 +94 -120
- data/docs/testing_benchmarks_local_files.md +150 -0
- data/docs/testing_test_rackup_ci_files.md +36 -0
- data/ext/puma_http11/PumaHttp11Service.java +2 -2
- data/ext/puma_http11/ext_help.h +1 -1
- data/ext/puma_http11/extconf.rb +61 -3
- data/ext/puma_http11/http11_parser.c +103 -117
- data/ext/puma_http11/http11_parser.h +2 -2
- data/ext/puma_http11/http11_parser.java.rl +22 -38
- data/ext/puma_http11/http11_parser.rl +3 -3
- data/ext/puma_http11/http11_parser_common.rl +6 -6
- data/ext/puma_http11/mini_ssl.c +361 -99
- 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 +248 -92
- data/ext/puma_http11/puma_http11.c +49 -57
- data/lib/puma/app/status.rb +71 -49
- data/lib/puma/binder.rb +242 -150
- data/lib/puma/cli.rb +38 -34
- data/lib/puma/client.rb +387 -244
- data/lib/puma/cluster/worker.rb +180 -0
- data/lib/puma/cluster/worker_handle.rb +97 -0
- data/lib/puma/cluster.rb +261 -243
- data/lib/puma/commonlogger.rb +21 -14
- data/lib/puma/configuration.rb +116 -88
- data/lib/puma/const.rb +101 -100
- data/lib/puma/control_cli.rb +115 -70
- data/lib/puma/detect.rb +33 -2
- data/lib/puma/dsl.rb +731 -134
- data/lib/puma/error_logger.rb +113 -0
- data/lib/puma/events.rb +16 -112
- data/lib/puma/io_buffer.rb +42 -5
- data/lib/puma/jruby_restart.rb +2 -59
- data/lib/puma/json_serialization.rb +96 -0
- data/lib/puma/launcher/bundle_pruner.rb +104 -0
- data/lib/puma/launcher.rb +184 -133
- data/lib/puma/log_writer.rb +147 -0
- data/lib/puma/minissl/context_builder.rb +92 -0
- data/lib/puma/minissl.rb +246 -70
- data/lib/puma/null_io.rb +18 -1
- data/lib/puma/plugin/systemd.rb +90 -0
- data/lib/puma/plugin/tmp_restart.rb +3 -1
- data/lib/puma/plugin.rb +7 -13
- data/lib/puma/rack/builder.rb +7 -9
- data/lib/puma/rack/urlmap.rb +2 -0
- data/lib/puma/rack_default.rb +21 -4
- data/lib/puma/reactor.rb +85 -316
- data/lib/puma/request.rb +665 -0
- data/lib/puma/runner.rb +94 -69
- data/lib/puma/sd_notify.rb +149 -0
- data/lib/puma/server.rb +314 -771
- data/lib/puma/single.rb +20 -74
- data/lib/puma/state_file.rb +45 -8
- data/lib/puma/thread_pool.rb +142 -92
- data/lib/puma/util.rb +22 -10
- data/lib/puma.rb +60 -5
- data/lib/rack/handler/puma.rb +113 -91
- data/tools/Dockerfile +16 -0
- data/tools/trickletest.rb +0 -1
- metadata +54 -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 -25
- data/lib/puma/daemon_ext.rb +0 -33
- data/lib/puma/delegation.rb +0 -13
- data/lib/puma/java_io_buffer.rb +0 -47
- data/lib/puma/rack/backports/uri/common_193.rb +0 -33
- data/lib/puma/tcp_logger.rb +0 -41
- 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/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,45 +185,173 @@ 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
|
-
|
213
|
+
int ssl_options;
|
214
|
+
VALUE key, cert, ca, verify_mode, ssl_cipher_filter, no_tlsv1, no_tlsv1_1,
|
215
|
+
verification_flags, session_id_bytes, cert_pem, key_pem;
|
216
|
+
BIO *bio;
|
217
|
+
X509 *x509;
|
218
|
+
EVP_PKEY *pkey;
|
219
|
+
#ifdef HAVE_SSL_CTX_SET_MIN_PROTO_VERSION
|
220
|
+
int min;
|
221
|
+
#endif
|
222
|
+
#ifndef HAVE_SSL_CTX_SET_DH_AUTO
|
223
|
+
DH *dh;
|
224
|
+
#endif
|
225
|
+
#if OPENSSL_VERSION_NUMBER < 0x10002000L
|
226
|
+
EC_KEY *ecdh;
|
227
|
+
#endif
|
228
|
+
#ifdef HAVE_SSL_CTX_SET_SESSION_CACHE_MODE
|
229
|
+
VALUE reuse, reuse_cache_size, reuse_timeout;
|
230
|
+
|
231
|
+
reuse = rb_funcall(mini_ssl_ctx, rb_intern_const("reuse"), 0);
|
232
|
+
reuse_cache_size = rb_funcall(mini_ssl_ctx, rb_intern_const("reuse_cache_size"), 0);
|
233
|
+
reuse_timeout = rb_funcall(mini_ssl_ctx, rb_intern_const("reuse_timeout"), 0);
|
234
|
+
#endif
|
235
|
+
|
236
|
+
key = rb_funcall(mini_ssl_ctx, rb_intern_const("key"), 0);
|
237
|
+
|
238
|
+
cert = rb_funcall(mini_ssl_ctx, rb_intern_const("cert"), 0);
|
145
239
|
|
146
|
-
|
240
|
+
ca = rb_funcall(mini_ssl_ctx, rb_intern_const("ca"), 0);
|
147
241
|
|
148
|
-
|
149
|
-
VALUE key = rb_funcall(mini_ssl_ctx, sym_key, 0);
|
242
|
+
cert_pem = rb_funcall(mini_ssl_ctx, rb_intern_const("cert_pem"), 0);
|
150
243
|
|
151
|
-
|
244
|
+
key_pem = rb_funcall(mini_ssl_ctx, rb_intern_const("key_pem"), 0);
|
152
245
|
|
153
|
-
|
154
|
-
VALUE cert = rb_funcall(mini_ssl_ctx, sym_cert, 0);
|
246
|
+
verify_mode = rb_funcall(mini_ssl_ctx, rb_intern_const("verify_mode"), 0);
|
155
247
|
|
156
|
-
|
248
|
+
ssl_cipher_filter = rb_funcall(mini_ssl_ctx, rb_intern_const("ssl_cipher_filter"), 0);
|
157
249
|
|
158
|
-
|
159
|
-
|
250
|
+
no_tlsv1 = rb_funcall(mini_ssl_ctx, rb_intern_const("no_tlsv1"), 0);
|
251
|
+
|
252
|
+
no_tlsv1_1 = rb_funcall(mini_ssl_ctx, rb_intern_const("no_tlsv1_1"), 0);
|
253
|
+
|
254
|
+
TypedData_Get_Struct(self, SSL_CTX, &sslctx_type, ctx);
|
255
|
+
|
256
|
+
if (!NIL_P(cert)) {
|
257
|
+
StringValue(cert);
|
258
|
+
|
259
|
+
if (SSL_CTX_use_certificate_chain_file(ctx, RSTRING_PTR(cert)) != 1) {
|
260
|
+
raise_file_error("SSL_CTX_use_certificate_chain_file", RSTRING_PTR(cert));
|
261
|
+
}
|
262
|
+
}
|
263
|
+
|
264
|
+
if (!NIL_P(key)) {
|
265
|
+
StringValue(key);
|
266
|
+
|
267
|
+
if (SSL_CTX_use_PrivateKey_file(ctx, RSTRING_PTR(key), SSL_FILETYPE_PEM) != 1) {
|
268
|
+
raise_file_error("SSL_CTX_use_PrivateKey_file", RSTRING_PTR(key));
|
269
|
+
}
|
270
|
+
}
|
271
|
+
|
272
|
+
if (!NIL_P(cert_pem)) {
|
273
|
+
bio = BIO_new(BIO_s_mem());
|
274
|
+
BIO_puts(bio, RSTRING_PTR(cert_pem));
|
275
|
+
x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
|
276
|
+
|
277
|
+
if (SSL_CTX_use_certificate(ctx, x509) != 1) {
|
278
|
+
BIO_free(bio);
|
279
|
+
raise_file_error("SSL_CTX_use_certificate", RSTRING_PTR(cert_pem));
|
280
|
+
}
|
281
|
+
X509_free(x509);
|
282
|
+
BIO_free(bio);
|
283
|
+
}
|
160
284
|
|
161
|
-
|
162
|
-
|
285
|
+
if (!NIL_P(key_pem)) {
|
286
|
+
bio = BIO_new(BIO_s_mem());
|
287
|
+
BIO_puts(bio, RSTRING_PTR(key_pem));
|
288
|
+
pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
|
163
289
|
|
164
|
-
|
165
|
-
|
290
|
+
if (SSL_CTX_use_PrivateKey(ctx, pkey) != 1) {
|
291
|
+
BIO_free(bio);
|
292
|
+
raise_file_error("SSL_CTX_use_PrivateKey", RSTRING_PTR(key_pem));
|
293
|
+
}
|
294
|
+
EVP_PKEY_free(pkey);
|
295
|
+
BIO_free(bio);
|
296
|
+
}
|
166
297
|
|
167
|
-
|
168
|
-
conn->ctx = ctx;
|
298
|
+
verification_flags = rb_funcall(mini_ssl_ctx, rb_intern_const("verification_flags"), 0);
|
169
299
|
|
170
|
-
|
171
|
-
|
300
|
+
if (!NIL_P(verification_flags)) {
|
301
|
+
X509_VERIFY_PARAM *param = SSL_CTX_get0_param(ctx);
|
302
|
+
X509_VERIFY_PARAM_set_flags(param, NUM2INT(verification_flags));
|
303
|
+
SSL_CTX_set1_param(ctx, param);
|
304
|
+
}
|
172
305
|
|
173
306
|
if (!NIL_P(ca)) {
|
174
307
|
StringValue(ca);
|
175
|
-
SSL_CTX_load_verify_locations(ctx, RSTRING_PTR(ca), NULL)
|
308
|
+
if (SSL_CTX_load_verify_locations(ctx, RSTRING_PTR(ca), NULL) != 1) {
|
309
|
+
raise_file_error("SSL_CTX_load_verify_locations", RSTRING_PTR(ca));
|
310
|
+
}
|
311
|
+
}
|
312
|
+
|
313
|
+
ssl_options = SSL_OP_CIPHER_SERVER_PREFERENCE | SSL_OP_SINGLE_ECDH_USE | SSL_OP_NO_COMPRESSION;
|
314
|
+
|
315
|
+
#ifdef HAVE_SSL_CTX_SET_MIN_PROTO_VERSION
|
316
|
+
if (RTEST(no_tlsv1_1)) {
|
317
|
+
min = TLS1_2_VERSION;
|
318
|
+
}
|
319
|
+
else if (RTEST(no_tlsv1)) {
|
320
|
+
min = TLS1_1_VERSION;
|
321
|
+
}
|
322
|
+
else {
|
323
|
+
min = TLS1_VERSION;
|
324
|
+
}
|
325
|
+
|
326
|
+
SSL_CTX_set_min_proto_version(ctx, min);
|
327
|
+
|
328
|
+
#else
|
329
|
+
/* As of 1.0.2f, SSL_OP_SINGLE_DH_USE key use is always on */
|
330
|
+
ssl_options |= SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_SINGLE_DH_USE;
|
331
|
+
|
332
|
+
if (RTEST(no_tlsv1)) {
|
333
|
+
ssl_options |= SSL_OP_NO_TLSv1;
|
334
|
+
}
|
335
|
+
if(RTEST(no_tlsv1_1)) {
|
336
|
+
ssl_options |= SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1;
|
337
|
+
}
|
338
|
+
#endif
|
339
|
+
|
340
|
+
#ifdef HAVE_SSL_CTX_SET_SESSION_CACHE_MODE
|
341
|
+
if (!NIL_P(reuse)) {
|
342
|
+
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER);
|
343
|
+
if (!NIL_P(reuse_cache_size)) {
|
344
|
+
SSL_CTX_sess_set_cache_size(ctx, NUM2INT(reuse_cache_size));
|
345
|
+
}
|
346
|
+
if (!NIL_P(reuse_timeout)) {
|
347
|
+
SSL_CTX_set_timeout(ctx, NUM2INT(reuse_timeout));
|
348
|
+
}
|
349
|
+
} else {
|
350
|
+
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
|
176
351
|
}
|
352
|
+
#endif
|
177
353
|
|
178
|
-
SSL_CTX_set_options(ctx,
|
179
|
-
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
|
354
|
+
SSL_CTX_set_options(ctx, ssl_options);
|
180
355
|
|
181
356
|
if (!NIL_P(ssl_cipher_filter)) {
|
182
357
|
StringValue(ssl_cipher_filter);
|
@@ -186,29 +361,65 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
|
|
186
361
|
SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL@STRENGTH");
|
187
362
|
}
|
188
363
|
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
#ifndef OPENSSL_NO_ECDH
|
193
|
-
EC_KEY *ecdh = EC_KEY_new_by_curve_name(NID_secp521r1);
|
364
|
+
#if OPENSSL_VERSION_NUMBER < 0x10002000L
|
365
|
+
// Remove this case if OpenSSL 1.0.1 (now EOL) support is no longer needed.
|
366
|
+
ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
|
194
367
|
if (ecdh) {
|
195
368
|
SSL_CTX_set_tmp_ecdh(ctx, ecdh);
|
196
369
|
EC_KEY_free(ecdh);
|
197
370
|
}
|
371
|
+
#elif OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
372
|
+
SSL_CTX_set_ecdh_auto(ctx, 1);
|
198
373
|
#endif
|
199
374
|
|
200
|
-
ssl = SSL_new(ctx);
|
201
|
-
conn->ssl = ssl;
|
202
|
-
SSL_set_app_data(ssl, NULL);
|
203
|
-
|
204
375
|
if (NIL_P(verify_mode)) {
|
205
|
-
/*
|
376
|
+
/* SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); */
|
206
377
|
} else {
|
207
|
-
|
378
|
+
SSL_CTX_set_verify(ctx, NUM2INT(verify_mode), engine_verify_callback);
|
208
379
|
}
|
209
380
|
|
210
|
-
|
381
|
+
// Random.bytes available in Ruby 2.5 and later, Random::DEFAULT deprecated in 3.0
|
382
|
+
session_id_bytes = rb_funcall(
|
383
|
+
#ifdef HAVE_RANDOM_BYTES
|
384
|
+
rb_cRandom,
|
385
|
+
#else
|
386
|
+
rb_const_get(rb_cRandom, rb_intern_const("DEFAULT")),
|
387
|
+
#endif
|
388
|
+
rb_intern_const("bytes"),
|
389
|
+
1, ULL2NUM(SSL_MAX_SSL_SESSION_ID_LENGTH));
|
390
|
+
|
391
|
+
SSL_CTX_set_session_id_context(ctx,
|
392
|
+
(unsigned char *) RSTRING_PTR(session_id_bytes),
|
393
|
+
SSL_MAX_SSL_SESSION_ID_LENGTH);
|
394
|
+
|
395
|
+
// printf("\ninitialize end security_level %d\n", SSL_CTX_get_security_level(ctx));
|
396
|
+
|
397
|
+
#ifdef HAVE_SSL_CTX_SET_DH_AUTO
|
398
|
+
// https://www.openssl.org/docs/man3.0/man3/SSL_CTX_set_dh_auto.html
|
399
|
+
SSL_CTX_set_dh_auto(ctx, 1);
|
400
|
+
#else
|
401
|
+
dh = get_dh2048();
|
402
|
+
SSL_CTX_set_tmp_dh(ctx, dh);
|
403
|
+
#endif
|
211
404
|
|
405
|
+
rb_obj_freeze(self);
|
406
|
+
return self;
|
407
|
+
}
|
408
|
+
|
409
|
+
VALUE engine_init_server(VALUE self, VALUE sslctx) {
|
410
|
+
ms_conn* conn;
|
411
|
+
VALUE obj;
|
412
|
+
SSL_CTX* ctx;
|
413
|
+
SSL* ssl;
|
414
|
+
|
415
|
+
conn = engine_alloc(self, &obj);
|
416
|
+
|
417
|
+
TypedData_Get_Struct(sslctx, SSL_CTX, &sslctx_type, ctx);
|
418
|
+
|
419
|
+
ssl = SSL_new(ctx);
|
420
|
+
conn->ssl = ssl;
|
421
|
+
SSL_set_app_data(ssl, NULL);
|
422
|
+
SSL_set_bio(ssl, conn->read, conn->write);
|
212
423
|
SSL_set_accept_state(ssl);
|
213
424
|
return obj;
|
214
425
|
}
|
@@ -216,8 +427,11 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
|
|
216
427
|
VALUE engine_init_client(VALUE klass) {
|
217
428
|
VALUE obj;
|
218
429
|
ms_conn* conn = engine_alloc(klass, &obj);
|
219
|
-
|
430
|
+
#ifdef HAVE_DTLS_METHOD
|
431
|
+
conn->ctx = SSL_CTX_new(DTLS_method());
|
432
|
+
#else
|
220
433
|
conn->ctx = SSL_CTX_new(DTLSv1_method());
|
434
|
+
#endif
|
221
435
|
conn->ssl = SSL_new(conn->ctx);
|
222
436
|
SSL_set_app_data(conn->ssl, NULL);
|
223
437
|
SSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL);
|
@@ -232,7 +446,7 @@ VALUE engine_inject(VALUE self, VALUE str) {
|
|
232
446
|
ms_conn* conn;
|
233
447
|
long used;
|
234
448
|
|
235
|
-
|
449
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
236
450
|
|
237
451
|
StringValue(str);
|
238
452
|
|
@@ -245,13 +459,14 @@ VALUE engine_inject(VALUE self, VALUE str) {
|
|
245
459
|
return INT2FIX(used);
|
246
460
|
}
|
247
461
|
|
248
|
-
|
462
|
+
NORETURN(void raise_error(SSL* ssl, int result));
|
249
463
|
|
250
464
|
void raise_error(SSL* ssl, int result) {
|
251
465
|
char buf[512];
|
252
466
|
char msg[512];
|
253
467
|
const char* err_str;
|
254
468
|
int err = errno;
|
469
|
+
int mask = 4095;
|
255
470
|
int ssl_err = SSL_get_error(ssl, result);
|
256
471
|
int verify_err = (int) SSL_get_verify_result(ssl);
|
257
472
|
|
@@ -268,8 +483,7 @@ void raise_error(SSL* ssl, int result) {
|
|
268
483
|
} else {
|
269
484
|
err = (int) ERR_get_error();
|
270
485
|
ERR_error_string_n(err, buf, sizeof(buf));
|
271
|
-
snprintf(msg, sizeof(msg), "OpenSSL error: %s - %d", buf, err);
|
272
|
-
|
486
|
+
snprintf(msg, sizeof(msg), "OpenSSL error: %s - %d", buf, err & mask);
|
273
487
|
}
|
274
488
|
} else {
|
275
489
|
snprintf(msg, sizeof(msg), "Unknown OpenSSL error: %d", ssl_err);
|
@@ -284,7 +498,7 @@ VALUE engine_read(VALUE self) {
|
|
284
498
|
char buf[512];
|
285
499
|
int bytes, error;
|
286
500
|
|
287
|
-
|
501
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
288
502
|
|
289
503
|
ERR_clear_error();
|
290
504
|
|
@@ -311,7 +525,7 @@ VALUE engine_write(VALUE self, VALUE str) {
|
|
311
525
|
ms_conn* conn;
|
312
526
|
int bytes;
|
313
527
|
|
314
|
-
|
528
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
315
529
|
|
316
530
|
StringValue(str);
|
317
531
|
|
@@ -333,9 +547,11 @@ VALUE engine_extract(VALUE self) {
|
|
333
547
|
ms_conn* conn;
|
334
548
|
int bytes;
|
335
549
|
size_t pending;
|
336
|
-
|
550
|
+
// https://www.openssl.org/docs/manmaster/man3/BIO_f_buffer.html
|
551
|
+
// crypto/bio/bf_buff.c DEFAULT_BUFFER_SIZE
|
552
|
+
char buf[4096];
|
337
553
|
|
338
|
-
|
554
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
339
555
|
|
340
556
|
pending = BIO_pending(conn->write);
|
341
557
|
if(pending > 0) {
|
@@ -354,7 +570,7 @@ VALUE engine_shutdown(VALUE self) {
|
|
354
570
|
ms_conn* conn;
|
355
571
|
int ok;
|
356
572
|
|
357
|
-
|
573
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
358
574
|
|
359
575
|
ERR_clear_error();
|
360
576
|
|
@@ -369,7 +585,7 @@ VALUE engine_shutdown(VALUE self) {
|
|
369
585
|
VALUE engine_init(VALUE self) {
|
370
586
|
ms_conn* conn;
|
371
587
|
|
372
|
-
|
588
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
373
589
|
|
374
590
|
return SSL_in_init(conn->ssl) ? Qtrue : Qfalse;
|
375
591
|
}
|
@@ -382,9 +598,13 @@ VALUE engine_peercert(VALUE self) {
|
|
382
598
|
ms_cert_buf* cert_buf = NULL;
|
383
599
|
VALUE rb_cert_buf;
|
384
600
|
|
385
|
-
|
601
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
386
602
|
|
603
|
+
#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
|
604
|
+
cert = SSL_get1_peer_certificate(conn->ssl);
|
605
|
+
#else
|
387
606
|
cert = SSL_get_peer_certificate(conn->ssl);
|
607
|
+
#endif
|
388
608
|
if(!cert) {
|
389
609
|
/*
|
390
610
|
* See if there was a failed certificate associated with this client.
|
@@ -413,12 +633,22 @@ VALUE engine_peercert(VALUE self) {
|
|
413
633
|
return rb_cert_buf;
|
414
634
|
}
|
415
635
|
|
636
|
+
/* @see Puma::MiniSSL::Socket#ssl_version_state
|
637
|
+
* @version 5.0.0
|
638
|
+
*/
|
639
|
+
static VALUE
|
640
|
+
engine_ssl_vers_st(VALUE self) {
|
641
|
+
ms_conn* conn;
|
642
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
643
|
+
return rb_ary_new3(2, rb_str_new2(SSL_get_version(conn->ssl)), rb_str_new2(SSL_state_string(conn->ssl)));
|
644
|
+
}
|
645
|
+
|
416
646
|
VALUE noop(VALUE self) {
|
417
647
|
return Qnil;
|
418
648
|
}
|
419
649
|
|
420
650
|
void Init_mini_ssl(VALUE puma) {
|
421
|
-
VALUE mod, eng;
|
651
|
+
VALUE mod, eng, sslctx;
|
422
652
|
|
423
653
|
/* Fake operation for documentation (RDoc, YARD) */
|
424
654
|
#if 0 == 1
|
@@ -431,18 +661,47 @@ void Init_mini_ssl(VALUE puma) {
|
|
431
661
|
ERR_load_crypto_strings();
|
432
662
|
|
433
663
|
mod = rb_define_module_under(puma, "MiniSSL");
|
664
|
+
|
434
665
|
eng = rb_define_class_under(mod, "Engine", rb_cObject);
|
666
|
+
rb_undef_alloc_func(eng);
|
667
|
+
|
668
|
+
sslctx = rb_define_class_under(mod, "SSLContext", rb_cObject);
|
669
|
+
rb_define_alloc_func(sslctx, sslctx_alloc);
|
670
|
+
rb_define_method(sslctx, "initialize", sslctx_initialize, 1);
|
671
|
+
rb_undef_method(sslctx, "initialize_copy");
|
672
|
+
|
435
673
|
|
436
674
|
// OpenSSL Build / Runtime/Load versions
|
437
675
|
|
438
676
|
/* Version of OpenSSL that Puma was compiled with */
|
439
|
-
|
677
|
+
rb_define_const(mod, "OPENSSL_VERSION", rb_str_new2(OPENSSL_VERSION_TEXT));
|
440
678
|
|
441
679
|
#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000
|
442
|
-
|
443
|
-
|
680
|
+
/* Version of OpenSSL that Puma loaded with */
|
681
|
+
rb_define_const(mod, "OPENSSL_LIBRARY_VERSION", rb_str_new2(OpenSSL_version(OPENSSL_VERSION)));
|
682
|
+
#else
|
683
|
+
rb_define_const(mod, "OPENSSL_LIBRARY_VERSION", rb_str_new2(SSLeay_version(SSLEAY_VERSION)));
|
684
|
+
#endif
|
685
|
+
|
686
|
+
#if defined(OPENSSL_NO_SSL3) || defined(OPENSSL_NO_SSL3_METHOD)
|
687
|
+
/* True if SSL3 is not available */
|
688
|
+
rb_define_const(mod, "OPENSSL_NO_SSL3", Qtrue);
|
444
689
|
#else
|
445
|
-
|
690
|
+
rb_define_const(mod, "OPENSSL_NO_SSL3", Qfalse);
|
691
|
+
#endif
|
692
|
+
|
693
|
+
#if defined(OPENSSL_NO_TLS1) || defined(OPENSSL_NO_TLS1_METHOD)
|
694
|
+
/* True if TLS1 is not available */
|
695
|
+
rb_define_const(mod, "OPENSSL_NO_TLS1", Qtrue);
|
696
|
+
#else
|
697
|
+
rb_define_const(mod, "OPENSSL_NO_TLS1", Qfalse);
|
698
|
+
#endif
|
699
|
+
|
700
|
+
#if defined(OPENSSL_NO_TLS1_1) || defined(OPENSSL_NO_TLS1_1_METHOD)
|
701
|
+
/* True if TLS1_1 is not available */
|
702
|
+
rb_define_const(mod, "OPENSSL_NO_TLS1_1", Qtrue);
|
703
|
+
#else
|
704
|
+
rb_define_const(mod, "OPENSSL_NO_TLS1_1", Qfalse);
|
446
705
|
#endif
|
447
706
|
|
448
707
|
rb_define_singleton_method(mod, "check", noop, 0);
|
@@ -463,13 +722,16 @@ void Init_mini_ssl(VALUE puma) {
|
|
463
722
|
rb_define_method(eng, "init?", engine_init, 0);
|
464
723
|
|
465
724
|
rb_define_method(eng, "peercert", engine_peercert, 0);
|
725
|
+
|
726
|
+
rb_define_method(eng, "ssl_vers_st", engine_ssl_vers_st, 0);
|
466
727
|
}
|
467
728
|
|
468
729
|
#else
|
469
730
|
|
731
|
+
NORETURN(VALUE raise_error(VALUE self));
|
732
|
+
|
470
733
|
VALUE raise_error(VALUE self) {
|
471
734
|
rb_raise(rb_eStandardError, "SSL not available in this build");
|
472
|
-
return Qnil;
|
473
735
|
}
|
474
736
|
|
475
737
|
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
|
+
}
|