puma 4.3.5 → 6.0.1
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 +1639 -519
- data/LICENSE +23 -20
- data/README.md +130 -42
- data/bin/puma-wild +3 -9
- data/docs/architecture.md +63 -26
- data/docs/compile_options.md +55 -0
- data/docs/deployment.md +60 -69
- 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 +15 -15
- data/docs/rails_dev_mode.md +28 -0
- data/docs/restart.md +46 -23
- data/docs/signals.md +13 -11
- data/docs/stats.md +142 -0
- data/docs/systemd.md +85 -128
- 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 -4
- data/ext/puma_http11/ext_help.h +1 -1
- data/ext/puma_http11/extconf.rb +56 -11
- data/ext/puma_http11/http11_parser.c +69 -58
- data/ext/puma_http11/http11_parser.h +2 -2
- data/ext/puma_http11/http11_parser.java.rl +3 -3
- data/ext/puma_http11/http11_parser.rl +3 -3
- data/ext/puma_http11/http11_parser_common.rl +3 -3
- data/ext/puma_http11/mini_ssl.c +322 -130
- data/ext/puma_http11/no_ssl/PumaHttp11Service.java +15 -0
- data/ext/puma_http11/org/jruby/puma/Http11.java +6 -6
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +52 -52
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +241 -96
- data/ext/puma_http11/puma_http11.c +47 -57
- data/lib/puma/app/status.rb +53 -37
- data/lib/puma/binder.rb +232 -119
- data/lib/puma/cli.rb +33 -33
- data/lib/puma/client.rb +197 -101
- data/lib/puma/cluster/worker.rb +175 -0
- data/lib/puma/cluster/worker_handle.rb +97 -0
- data/lib/puma/cluster.rb +224 -229
- data/lib/puma/commonlogger.rb +2 -2
- data/lib/puma/configuration.rb +112 -87
- data/lib/puma/const.rb +30 -25
- data/lib/puma/control_cli.rb +99 -79
- data/lib/puma/detect.rb +31 -2
- data/lib/puma/dsl.rb +426 -110
- data/lib/puma/error_logger.rb +112 -0
- data/lib/puma/events.rb +16 -115
- data/lib/puma/io_buffer.rb +44 -2
- 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 +170 -148
- data/lib/puma/log_writer.rb +137 -0
- data/lib/puma/minissl/context_builder.rb +35 -19
- data/lib/puma/minissl.rb +213 -55
- data/lib/puma/null_io.rb +18 -1
- data/lib/puma/plugin/tmp_restart.rb +1 -1
- data/lib/puma/plugin.rb +3 -12
- data/lib/puma/rack/builder.rb +5 -9
- data/lib/puma/rack/urlmap.rb +0 -0
- data/lib/puma/rack_default.rb +1 -1
- data/lib/puma/reactor.rb +85 -369
- data/lib/puma/request.rb +644 -0
- data/lib/puma/runner.rb +83 -77
- data/lib/puma/server.rb +303 -773
- data/lib/puma/single.rb +18 -74
- data/lib/puma/state_file.rb +45 -8
- data/lib/puma/systemd.rb +47 -0
- data/lib/puma/thread_pool.rb +136 -68
- data/lib/puma/util.rb +21 -4
- data/lib/puma.rb +54 -5
- data/lib/rack/handler/puma.rb +11 -12
- data/tools/{docker/Dockerfile → Dockerfile} +1 -1
- data/tools/trickletest.rb +0 -0
- metadata +36 -28
- data/docs/tcp_mode.md +0 -96
- data/ext/puma_http11/io_buffer.c +0 -155
- data/ext/puma_http11/org/jruby/puma/IOBuffer.java +0 -72
- data/lib/puma/accept_nonblock.rb +0 -29
- 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;
|
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
|
+
};
|
61
57
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
DH *get_dh1024() {
|
66
|
-
/* `openssl dhparam 1024 -C`
|
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,52 +185,129 @@ 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
|
-
|
145
|
-
|
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;
|
146
230
|
|
147
|
-
|
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
|
148
235
|
|
149
|
-
|
150
|
-
VALUE key = rb_funcall(mini_ssl_ctx, sym_key, 0);
|
236
|
+
key = rb_funcall(mini_ssl_ctx, rb_intern_const("key"), 0);
|
151
237
|
|
152
|
-
|
238
|
+
cert = rb_funcall(mini_ssl_ctx, rb_intern_const("cert"), 0);
|
153
239
|
|
154
|
-
|
155
|
-
VALUE cert = rb_funcall(mini_ssl_ctx, sym_cert, 0);
|
240
|
+
ca = rb_funcall(mini_ssl_ctx, rb_intern_const("ca"), 0);
|
156
241
|
|
157
|
-
|
242
|
+
cert_pem = rb_funcall(mini_ssl_ctx, rb_intern_const("cert_pem"), 0);
|
158
243
|
|
159
|
-
|
160
|
-
VALUE ca = rb_funcall(mini_ssl_ctx, sym_ca, 0);
|
244
|
+
key_pem = rb_funcall(mini_ssl_ctx, rb_intern_const("key_pem"), 0);
|
161
245
|
|
162
|
-
|
163
|
-
VALUE verify_mode = rb_funcall(mini_ssl_ctx, sym_verify_mode, 0);
|
246
|
+
verify_mode = rb_funcall(mini_ssl_ctx, rb_intern_const("verify_mode"), 0);
|
164
247
|
|
165
|
-
|
166
|
-
VALUE ssl_cipher_filter = rb_funcall(mini_ssl_ctx, sym_ssl_cipher_filter, 0);
|
248
|
+
ssl_cipher_filter = rb_funcall(mini_ssl_ctx, rb_intern_const("ssl_cipher_filter"), 0);
|
167
249
|
|
168
|
-
|
169
|
-
VALUE no_tlsv1 = rb_funcall(mini_ssl_ctx, sym_no_tlsv1, 0);
|
250
|
+
no_tlsv1 = rb_funcall(mini_ssl_ctx, rb_intern_const("no_tlsv1"), 0);
|
170
251
|
|
171
|
-
|
172
|
-
VALUE no_tlsv1_1 = rb_funcall(mini_ssl_ctx, sym_no_tlsv1_1, 0);
|
252
|
+
no_tlsv1_1 = rb_funcall(mini_ssl_ctx, rb_intern_const("no_tlsv1_1"), 0);
|
173
253
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
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
|
+
}
|
180
284
|
|
181
|
-
|
182
|
-
|
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
|
+
}
|
183
305
|
|
184
306
|
if (!NIL_P(ca)) {
|
185
307
|
StringValue(ca);
|
186
|
-
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
|
+
}
|
187
311
|
}
|
188
312
|
|
189
313
|
ssl_options = SSL_OP_CIPHER_SERVER_PREFERENCE | SSL_OP_SINGLE_ECDH_USE | SSL_OP_NO_COMPRESSION;
|
@@ -198,10 +322,8 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
|
|
198
322
|
else {
|
199
323
|
min = TLS1_VERSION;
|
200
324
|
}
|
201
|
-
|
202
|
-
SSL_CTX_set_min_proto_version(ctx, min);
|
203
325
|
|
204
|
-
|
326
|
+
SSL_CTX_set_min_proto_version(ctx, min);
|
205
327
|
|
206
328
|
#else
|
207
329
|
/* As of 1.0.2f, SSL_OP_SINGLE_DH_USE key use is always on */
|
@@ -213,10 +335,23 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
|
|
213
335
|
if(RTEST(no_tlsv1_1)) {
|
214
336
|
ssl_options |= SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1;
|
215
337
|
}
|
216
|
-
SSL_CTX_set_options(ctx, ssl_options);
|
217
338
|
#endif
|
218
339
|
|
219
|
-
|
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
|
353
|
+
|
354
|
+
SSL_CTX_set_options(ctx, ssl_options);
|
220
355
|
|
221
356
|
if (!NIL_P(ssl_cipher_filter)) {
|
222
357
|
StringValue(ssl_cipher_filter);
|
@@ -226,35 +361,65 @@ VALUE engine_init_server(VALUE self, VALUE mini_ssl_ctx) {
|
|
226
361
|
SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL@STRENGTH");
|
227
362
|
}
|
228
363
|
|
229
|
-
DH *dh = get_dh1024();
|
230
|
-
SSL_CTX_set_tmp_dh(ctx, dh);
|
231
|
-
|
232
364
|
#if OPENSSL_VERSION_NUMBER < 0x10002000L
|
233
|
-
// Remove this case if OpenSSL 1.0.1 (now EOL) support is no
|
234
|
-
|
235
|
-
EC_KEY *ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
|
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);
|
236
367
|
if (ecdh) {
|
237
368
|
SSL_CTX_set_tmp_ecdh(ctx, ecdh);
|
238
369
|
EC_KEY_free(ecdh);
|
239
370
|
}
|
240
371
|
#elif OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
|
241
|
-
// Prior to OpenSSL 1.1.0, servers must manually enable server-side ECDH
|
242
|
-
// negotiation.
|
243
372
|
SSL_CTX_set_ecdh_auto(ctx, 1);
|
244
373
|
#endif
|
245
374
|
|
246
|
-
ssl = SSL_new(ctx);
|
247
|
-
conn->ssl = ssl;
|
248
|
-
SSL_set_app_data(ssl, NULL);
|
249
|
-
|
250
375
|
if (NIL_P(verify_mode)) {
|
251
|
-
/*
|
376
|
+
/* SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); */
|
252
377
|
} else {
|
253
|
-
|
378
|
+
SSL_CTX_set_verify(ctx, NUM2INT(verify_mode), engine_verify_callback);
|
254
379
|
}
|
255
380
|
|
256
|
-
|
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);
|
257
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);
|
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);
|
258
423
|
SSL_set_accept_state(ssl);
|
259
424
|
return obj;
|
260
425
|
}
|
@@ -281,7 +446,7 @@ VALUE engine_inject(VALUE self, VALUE str) {
|
|
281
446
|
ms_conn* conn;
|
282
447
|
long used;
|
283
448
|
|
284
|
-
|
449
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
285
450
|
|
286
451
|
StringValue(str);
|
287
452
|
|
@@ -294,13 +459,14 @@ VALUE engine_inject(VALUE self, VALUE str) {
|
|
294
459
|
return INT2FIX(used);
|
295
460
|
}
|
296
461
|
|
297
|
-
|
462
|
+
NORETURN(void raise_error(SSL* ssl, int result));
|
298
463
|
|
299
464
|
void raise_error(SSL* ssl, int result) {
|
300
465
|
char buf[512];
|
301
466
|
char msg[512];
|
302
467
|
const char* err_str;
|
303
468
|
int err = errno;
|
469
|
+
int mask = 4095;
|
304
470
|
int ssl_err = SSL_get_error(ssl, result);
|
305
471
|
int verify_err = (int) SSL_get_verify_result(ssl);
|
306
472
|
|
@@ -317,8 +483,7 @@ void raise_error(SSL* ssl, int result) {
|
|
317
483
|
} else {
|
318
484
|
err = (int) ERR_get_error();
|
319
485
|
ERR_error_string_n(err, buf, sizeof(buf));
|
320
|
-
snprintf(msg, sizeof(msg), "OpenSSL error: %s - %d", buf, err);
|
321
|
-
|
486
|
+
snprintf(msg, sizeof(msg), "OpenSSL error: %s - %d", buf, err & mask);
|
322
487
|
}
|
323
488
|
} else {
|
324
489
|
snprintf(msg, sizeof(msg), "Unknown OpenSSL error: %d", ssl_err);
|
@@ -333,7 +498,7 @@ VALUE engine_read(VALUE self) {
|
|
333
498
|
char buf[512];
|
334
499
|
int bytes, error;
|
335
500
|
|
336
|
-
|
501
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
337
502
|
|
338
503
|
ERR_clear_error();
|
339
504
|
|
@@ -360,7 +525,7 @@ VALUE engine_write(VALUE self, VALUE str) {
|
|
360
525
|
ms_conn* conn;
|
361
526
|
int bytes;
|
362
527
|
|
363
|
-
|
528
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
364
529
|
|
365
530
|
StringValue(str);
|
366
531
|
|
@@ -382,9 +547,11 @@ VALUE engine_extract(VALUE self) {
|
|
382
547
|
ms_conn* conn;
|
383
548
|
int bytes;
|
384
549
|
size_t pending;
|
385
|
-
|
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];
|
386
553
|
|
387
|
-
|
554
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
388
555
|
|
389
556
|
pending = BIO_pending(conn->write);
|
390
557
|
if(pending > 0) {
|
@@ -403,7 +570,7 @@ VALUE engine_shutdown(VALUE self) {
|
|
403
570
|
ms_conn* conn;
|
404
571
|
int ok;
|
405
572
|
|
406
|
-
|
573
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
407
574
|
|
408
575
|
ERR_clear_error();
|
409
576
|
|
@@ -418,7 +585,7 @@ VALUE engine_shutdown(VALUE self) {
|
|
418
585
|
VALUE engine_init(VALUE self) {
|
419
586
|
ms_conn* conn;
|
420
587
|
|
421
|
-
|
588
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
422
589
|
|
423
590
|
return SSL_in_init(conn->ssl) ? Qtrue : Qfalse;
|
424
591
|
}
|
@@ -431,9 +598,13 @@ VALUE engine_peercert(VALUE self) {
|
|
431
598
|
ms_cert_buf* cert_buf = NULL;
|
432
599
|
VALUE rb_cert_buf;
|
433
600
|
|
434
|
-
|
601
|
+
TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn);
|
435
602
|
|
603
|
+
#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
|
604
|
+
cert = SSL_get1_peer_certificate(conn->ssl);
|
605
|
+
#else
|
436
606
|
cert = SSL_get_peer_certificate(conn->ssl);
|
607
|
+
#endif
|
437
608
|
if(!cert) {
|
438
609
|
/*
|
439
610
|
* See if there was a failed certificate associated with this client.
|
@@ -462,12 +633,22 @@ VALUE engine_peercert(VALUE self) {
|
|
462
633
|
return rb_cert_buf;
|
463
634
|
}
|
464
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
|
+
|
465
646
|
VALUE noop(VALUE self) {
|
466
647
|
return Qnil;
|
467
648
|
}
|
468
649
|
|
469
650
|
void Init_mini_ssl(VALUE puma) {
|
470
|
-
VALUE mod, eng;
|
651
|
+
VALUE mod, eng, sslctx;
|
471
652
|
|
472
653
|
/* Fake operation for documentation (RDoc, YARD) */
|
473
654
|
#if 0 == 1
|
@@ -480,7 +661,15 @@ void Init_mini_ssl(VALUE puma) {
|
|
480
661
|
ERR_load_crypto_strings();
|
481
662
|
|
482
663
|
mod = rb_define_module_under(puma, "MiniSSL");
|
664
|
+
|
483
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
|
+
|
484
673
|
|
485
674
|
// OpenSSL Build / Runtime/Load versions
|
486
675
|
|
@@ -493,27 +682,27 @@ void Init_mini_ssl(VALUE puma) {
|
|
493
682
|
#else
|
494
683
|
rb_define_const(mod, "OPENSSL_LIBRARY_VERSION", rb_str_new2(SSLeay_version(SSLEAY_VERSION)));
|
495
684
|
#endif
|
496
|
-
|
497
|
-
#if defined(OPENSSL_NO_SSL3) || defined(OPENSSL_NO_SSL3_METHOD)
|
498
|
-
/* True if SSL3 is not available */
|
499
|
-
rb_define_const(mod, "OPENSSL_NO_SSL3", Qtrue);
|
500
|
-
#else
|
501
|
-
rb_define_const(mod, "OPENSSL_NO_SSL3", Qfalse);
|
502
|
-
#endif
|
503
|
-
|
504
|
-
#if defined(OPENSSL_NO_TLS1) || defined(OPENSSL_NO_TLS1_METHOD)
|
505
|
-
/* True if TLS1 is not available */
|
506
|
-
rb_define_const(mod, "OPENSSL_NO_TLS1", Qtrue);
|
507
|
-
#else
|
508
|
-
rb_define_const(mod, "OPENSSL_NO_TLS1", Qfalse);
|
509
|
-
#endif
|
510
|
-
|
511
|
-
#if defined(OPENSSL_NO_TLS1_1) || defined(OPENSSL_NO_TLS1_1_METHOD)
|
512
|
-
/* True if TLS1_1 is not available */
|
513
|
-
rb_define_const(mod, "OPENSSL_NO_TLS1_1", Qtrue);
|
514
|
-
#else
|
515
|
-
rb_define_const(mod, "OPENSSL_NO_TLS1_1", Qfalse);
|
516
|
-
#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
|
517
706
|
|
518
707
|
rb_define_singleton_method(mod, "check", noop, 0);
|
519
708
|
|
@@ -533,13 +722,16 @@ void Init_mini_ssl(VALUE puma) {
|
|
533
722
|
rb_define_method(eng, "init?", engine_init, 0);
|
534
723
|
|
535
724
|
rb_define_method(eng, "peercert", engine_peercert, 0);
|
725
|
+
|
726
|
+
rb_define_method(eng, "ssl_vers_st", engine_ssl_vers_st, 0);
|
536
727
|
}
|
537
728
|
|
538
729
|
#else
|
539
730
|
|
731
|
+
NORETURN(VALUE raise_error(VALUE self));
|
732
|
+
|
540
733
|
VALUE raise_error(VALUE self) {
|
541
734
|
rb_raise(rb_eStandardError, "SSL not available in this build");
|
542
|
-
return Qnil;
|
543
735
|
}
|
544
736
|
|
545
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
|
+
}
|