puma 3.11.2 → 6.0.0
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 +5 -5
- data/History.md +1708 -422
- data/LICENSE +23 -20
- data/README.md +190 -64
- 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/docs/jungle/rc.d/README.md +74 -0
- data/docs/jungle/rc.d/puma +61 -0
- data/docs/jungle/rc.d/puma.conf +10 -0
- 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 +100 -115
- 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 +106 -118
- 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 +6 -4
- data/ext/puma_http11/http11_parser_common.rl +6 -6
- data/ext/puma_http11/mini_ssl.c +376 -93
- 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 +250 -88
- data/ext/puma_http11/puma_http11.c +49 -57
- data/lib/puma/app/status.rb +71 -49
- data/lib/puma/binder.rb +243 -148
- data/lib/puma/cli.rb +50 -35
- data/lib/puma/client.rb +369 -232
- data/lib/puma/cluster/worker.rb +175 -0
- data/lib/puma/cluster/worker_handle.rb +97 -0
- data/lib/puma/cluster.rb +268 -235
- data/lib/puma/commonlogger.rb +4 -2
- data/lib/puma/configuration.rb +116 -88
- data/lib/puma/const.rb +49 -30
- data/lib/puma/control_cli.rb +124 -77
- data/lib/puma/detect.rb +33 -2
- data/lib/puma/dsl.rb +685 -138
- data/lib/puma/error_logger.rb +112 -0
- data/lib/puma/events.rb +17 -111
- data/lib/puma/io_buffer.rb +34 -5
- data/lib/puma/jruby_restart.rb +4 -59
- data/lib/puma/json_serialization.rb +96 -0
- data/lib/puma/launcher/bundle_pruner.rb +104 -0
- data/lib/puma/launcher.rb +197 -130
- data/lib/puma/log_writer.rb +137 -0
- data/lib/puma/minissl/context_builder.rb +92 -0
- data/lib/puma/minissl.rb +256 -70
- data/lib/puma/null_io.rb +20 -1
- data/lib/puma/plugin/tmp_restart.rb +3 -1
- data/lib/puma/plugin.rb +9 -13
- data/lib/puma/rack/builder.rb +8 -9
- data/lib/puma/rack/urlmap.rb +2 -0
- data/lib/puma/rack_default.rb +3 -1
- data/lib/puma/reactor.rb +90 -187
- data/lib/puma/request.rb +607 -0
- data/lib/puma/runner.rb +94 -71
- data/lib/puma/server.rb +336 -703
- data/lib/puma/single.rb +27 -72
- data/lib/puma/state_file.rb +46 -7
- data/lib/puma/systemd.rb +47 -0
- data/lib/puma/thread_pool.rb +185 -91
- data/lib/puma/util.rb +23 -10
- data/lib/puma.rb +68 -3
- data/lib/rack/handler/puma.rb +17 -14
- data/tools/Dockerfile +16 -0
- data/tools/trickletest.rb +0 -1
- metadata +53 -30
- 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 -13
- data/tools/jungle/init.d/README.md +0 -59
- 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,68 +185,241 @@ 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
|
145
235
|
|
146
|
-
|
236
|
+
key = rb_funcall(mini_ssl_ctx, rb_intern_const("key"), 0);
|
147
237
|
|
148
|
-
|
149
|
-
VALUE key = rb_funcall(mini_ssl_ctx, sym_key, 0);
|
238
|
+
cert = rb_funcall(mini_ssl_ctx, rb_intern_const("cert"), 0);
|
150
239
|
|
151
|
-
|
240
|
+
ca = rb_funcall(mini_ssl_ctx, rb_intern_const("ca"), 0);
|
152
241
|
|
153
|
-
|
154
|
-
VALUE cert = rb_funcall(mini_ssl_ctx, sym_cert, 0);
|
242
|
+
cert_pem = rb_funcall(mini_ssl_ctx, rb_intern_const("cert_pem"), 0);
|
155
243
|
|
156
|
-
|
244
|
+
key_pem = rb_funcall(mini_ssl_ctx, rb_intern_const("key_pem"), 0);
|
157
245
|
|
158
|
-
|
159
|
-
VALUE ca = rb_funcall(mini_ssl_ctx, sym_ca, 0);
|
246
|
+
verify_mode = rb_funcall(mini_ssl_ctx, rb_intern_const("verify_mode"), 0);
|
160
247
|
|
161
|
-
|
162
|
-
VALUE verify_mode = rb_funcall(mini_ssl_ctx, sym_verify_mode, 0);
|
248
|
+
ssl_cipher_filter = rb_funcall(mini_ssl_ctx, rb_intern_const("ssl_cipher_filter"), 0);
|
163
249
|
|
164
|
-
|
165
|
-
conn->ctx = ctx;
|
250
|
+
no_tlsv1 = rb_funcall(mini_ssl_ctx, rb_intern_const("no_tlsv1"), 0);
|
166
251
|
|
167
|
-
|
168
|
-
|
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
|
+
}
|
284
|
+
|
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);
|
289
|
+
|
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
|
+
}
|
297
|
+
|
298
|
+
verification_flags = rb_funcall(mini_ssl_ctx, rb_intern_const("verification_flags"), 0);
|
299
|
+
|
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
|
+
}
|
169
305
|
|
170
306
|
if (!NIL_P(ca)) {
|
171
307
|
StringValue(ca);
|
172
|
-
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;
|
173
324
|
}
|
174
325
|
|
175
|
-
|
176
|
-
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
|
326
|
+
SSL_CTX_set_min_proto_version(ctx, min);
|
177
327
|
|
178
|
-
|
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;
|
179
331
|
|
180
|
-
|
181
|
-
|
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);
|
351
|
+
}
|
352
|
+
#endif
|
182
353
|
|
183
|
-
|
184
|
-
|
354
|
+
SSL_CTX_set_options(ctx, ssl_options);
|
355
|
+
|
356
|
+
if (!NIL_P(ssl_cipher_filter)) {
|
357
|
+
StringValue(ssl_cipher_filter);
|
358
|
+
SSL_CTX_set_cipher_list(ctx, RSTRING_PTR(ssl_cipher_filter));
|
359
|
+
}
|
360
|
+
else {
|
361
|
+
SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL@STRENGTH");
|
362
|
+
}
|
363
|
+
|
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);
|
185
367
|
if (ecdh) {
|
186
368
|
SSL_CTX_set_tmp_ecdh(ctx, ecdh);
|
187
369
|
EC_KEY_free(ecdh);
|
188
370
|
}
|
371
|
+
#elif OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
372
|
+
SSL_CTX_set_ecdh_auto(ctx, 1);
|
189
373
|
#endif
|
190
374
|
|
191
|
-
ssl = SSL_new(ctx);
|
192
|
-
conn->ssl = ssl;
|
193
|
-
SSL_set_app_data(ssl, NULL);
|
194
|
-
|
195
375
|
if (NIL_P(verify_mode)) {
|
196
|
-
/*
|
376
|
+
/* SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); */
|
197
377
|
} else {
|
198
|
-
|
378
|
+
SSL_CTX_set_verify(ctx, NUM2INT(verify_mode), engine_verify_callback);
|
199
379
|
}
|
200
380
|
|
201
|
-
|
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
|
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);
|
202
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);
|
203
423
|
SSL_set_accept_state(ssl);
|
204
424
|
return obj;
|
205
425
|
}
|
@@ -207,8 +427,11 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
|
|
207
427
|
VALUE engine_init_client(VALUE klass) {
|
208
428
|
VALUE obj;
|
209
429
|
ms_conn* conn = engine_alloc(klass, &obj);
|
210
|
-
|
430
|
+
#ifdef HAVE_DTLS_METHOD
|
431
|
+
conn->ctx = SSL_CTX_new(DTLS_method());
|
432
|
+
#else
|
211
433
|
conn->ctx = SSL_CTX_new(DTLSv1_method());
|
434
|
+
#endif
|
212
435
|
conn->ssl = SSL_new(conn->ctx);
|
213
436
|
SSL_set_app_data(conn->ssl, NULL);
|
214
437
|
SSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL);
|
@@ -223,7 +446,7 @@ VALUE engine_inject(VALUE self, VALUE str) {
|
|
223
446
|
ms_conn* conn;
|
224
447
|
long used;
|
225
448
|
|
226
|
-
|
449
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
227
450
|
|
228
451
|
StringValue(str);
|
229
452
|
|
@@ -236,13 +459,14 @@ VALUE engine_inject(VALUE self, VALUE str) {
|
|
236
459
|
return INT2FIX(used);
|
237
460
|
}
|
238
461
|
|
239
|
-
|
462
|
+
NORETURN(void raise_error(SSL* ssl, int result));
|
240
463
|
|
241
464
|
void raise_error(SSL* ssl, int result) {
|
242
465
|
char buf[512];
|
243
466
|
char msg[512];
|
244
467
|
const char* err_str;
|
245
468
|
int err = errno;
|
469
|
+
int mask = 4095;
|
246
470
|
int ssl_err = SSL_get_error(ssl, result);
|
247
471
|
int verify_err = (int) SSL_get_verify_result(ssl);
|
248
472
|
|
@@ -259,8 +483,7 @@ void raise_error(SSL* ssl, int result) {
|
|
259
483
|
} else {
|
260
484
|
err = (int) ERR_get_error();
|
261
485
|
ERR_error_string_n(err, buf, sizeof(buf));
|
262
|
-
snprintf(msg, sizeof(msg), "OpenSSL error: %s - %d", buf, err);
|
263
|
-
|
486
|
+
snprintf(msg, sizeof(msg), "OpenSSL error: %s - %d", buf, err & mask);
|
264
487
|
}
|
265
488
|
} else {
|
266
489
|
snprintf(msg, sizeof(msg), "Unknown OpenSSL error: %d", ssl_err);
|
@@ -275,7 +498,7 @@ VALUE engine_read(VALUE self) {
|
|
275
498
|
char buf[512];
|
276
499
|
int bytes, error;
|
277
500
|
|
278
|
-
|
501
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
279
502
|
|
280
503
|
ERR_clear_error();
|
281
504
|
|
@@ -302,7 +525,7 @@ VALUE engine_write(VALUE self, VALUE str) {
|
|
302
525
|
ms_conn* conn;
|
303
526
|
int bytes;
|
304
527
|
|
305
|
-
|
528
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
306
529
|
|
307
530
|
StringValue(str);
|
308
531
|
|
@@ -324,9 +547,11 @@ VALUE engine_extract(VALUE self) {
|
|
324
547
|
ms_conn* conn;
|
325
548
|
int bytes;
|
326
549
|
size_t pending;
|
327
|
-
|
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];
|
328
553
|
|
329
|
-
|
554
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
330
555
|
|
331
556
|
pending = BIO_pending(conn->write);
|
332
557
|
if(pending > 0) {
|
@@ -345,7 +570,7 @@ VALUE engine_shutdown(VALUE self) {
|
|
345
570
|
ms_conn* conn;
|
346
571
|
int ok;
|
347
572
|
|
348
|
-
|
573
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
349
574
|
|
350
575
|
ERR_clear_error();
|
351
576
|
|
@@ -360,7 +585,7 @@ VALUE engine_shutdown(VALUE self) {
|
|
360
585
|
VALUE engine_init(VALUE self) {
|
361
586
|
ms_conn* conn;
|
362
587
|
|
363
|
-
|
588
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
364
589
|
|
365
590
|
return SSL_in_init(conn->ssl) ? Qtrue : Qfalse;
|
366
591
|
}
|
@@ -373,9 +598,13 @@ VALUE engine_peercert(VALUE self) {
|
|
373
598
|
ms_cert_buf* cert_buf = NULL;
|
374
599
|
VALUE rb_cert_buf;
|
375
600
|
|
376
|
-
|
601
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
377
602
|
|
603
|
+
#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
|
604
|
+
cert = SSL_get1_peer_certificate(conn->ssl);
|
605
|
+
#else
|
378
606
|
cert = SSL_get_peer_certificate(conn->ssl);
|
607
|
+
#endif
|
379
608
|
if(!cert) {
|
380
609
|
/*
|
381
610
|
* See if there was a failed certificate associated with this client.
|
@@ -404,12 +633,22 @@ VALUE engine_peercert(VALUE self) {
|
|
404
633
|
return rb_cert_buf;
|
405
634
|
}
|
406
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
|
+
|
407
646
|
VALUE noop(VALUE self) {
|
408
647
|
return Qnil;
|
409
648
|
}
|
410
649
|
|
411
650
|
void Init_mini_ssl(VALUE puma) {
|
412
|
-
VALUE mod, eng;
|
651
|
+
VALUE mod, eng, sslctx;
|
413
652
|
|
414
653
|
/* Fake operation for documentation (RDoc, YARD) */
|
415
654
|
#if 0 == 1
|
@@ -422,7 +661,48 @@ void Init_mini_ssl(VALUE puma) {
|
|
422
661
|
ERR_load_crypto_strings();
|
423
662
|
|
424
663
|
mod = rb_define_module_under(puma, "MiniSSL");
|
664
|
+
|
425
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
|
+
|
673
|
+
|
674
|
+
// OpenSSL Build / Runtime/Load versions
|
675
|
+
|
676
|
+
/* Version of OpenSSL that Puma was compiled with */
|
677
|
+
rb_define_const(mod, "OPENSSL_VERSION", rb_str_new2(OPENSSL_VERSION_TEXT));
|
678
|
+
|
679
|
+
#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000
|
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);
|
689
|
+
#else
|
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);
|
705
|
+
#endif
|
426
706
|
|
427
707
|
rb_define_singleton_method(mod, "check", noop, 0);
|
428
708
|
|
@@ -442,13 +722,16 @@ void Init_mini_ssl(VALUE puma) {
|
|
442
722
|
rb_define_method(eng, "init?", engine_init, 0);
|
443
723
|
|
444
724
|
rb_define_method(eng, "peercert", engine_peercert, 0);
|
725
|
+
|
726
|
+
rb_define_method(eng, "ssl_vers_st", engine_ssl_vers_st, 0);
|
445
727
|
}
|
446
728
|
|
447
729
|
#else
|
448
730
|
|
731
|
+
NORETURN(VALUE raise_error(VALUE self));
|
732
|
+
|
449
733
|
VALUE raise_error(VALUE self) {
|
450
734
|
rb_raise(rb_eStandardError, "SSL not available in this build");
|
451
|
-
return Qnil;
|
452
735
|
}
|
453
736
|
|
454
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
|
+
}
|