Mercurial > hg > nginx
annotate src/stream/ngx_stream_ssl_module.c @ 6791:cb4a4e9bba8e
Perl: fixed optimization in SSI command handler.
As the pointer to the first argument was tested instead of the argument
itself, array of arguments was always created, even if there were no
arguments. Fix is to test args[0] instead of args.
Found by Coverity (CID 1356862).
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Tue, 01 Nov 2016 20:39:21 +0300 |
parents | 3908156a51fa |
children | ea93c7d8752a |
rev | line source |
---|---|
6115 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4 * Copyright (C) Nginx, Inc. | |
5 */ | |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_stream.h> | |
11 | |
12 | |
6611
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
13 typedef ngx_int_t (*ngx_ssl_variable_handler_pt)(ngx_connection_t *c, |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
14 ngx_pool_t *pool, ngx_str_t *s); |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
15 |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
16 |
6115 | 17 #define NGX_DEFAULT_CIPHERS "HIGH:!aNULL:!MD5" |
6553
2014ed60f17f
SSL: support for multiple curves (ticket #885).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6550
diff
changeset
|
18 #define NGX_DEFAULT_ECDH_CURVE "auto" |
6115 | 19 |
20 | |
6693 | 21 static ngx_int_t ngx_stream_ssl_handler(ngx_stream_session_t *s); |
22 static ngx_int_t ngx_stream_ssl_init_connection(ngx_ssl_t *ssl, | |
23 ngx_connection_t *c); | |
24 static void ngx_stream_ssl_handshake_handler(ngx_connection_t *c); | |
6611
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
25 static ngx_int_t ngx_stream_ssl_static_variable(ngx_stream_session_t *s, |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
26 ngx_stream_variable_value_t *v, uintptr_t data); |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
27 static ngx_int_t ngx_stream_ssl_variable(ngx_stream_session_t *s, |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
28 ngx_stream_variable_value_t *v, uintptr_t data); |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
29 |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
30 static ngx_int_t ngx_stream_ssl_add_variables(ngx_conf_t *cf); |
6115 | 31 static void *ngx_stream_ssl_create_conf(ngx_conf_t *cf); |
32 static char *ngx_stream_ssl_merge_conf(ngx_conf_t *cf, void *parent, | |
33 void *child); | |
34 | |
35 static char *ngx_stream_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, | |
36 void *conf); | |
37 static char *ngx_stream_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, | |
38 void *conf); | |
6693 | 39 static ngx_int_t ngx_stream_ssl_init(ngx_conf_t *cf); |
6115 | 40 |
41 | |
42 static ngx_conf_bitmask_t ngx_stream_ssl_protocols[] = { | |
43 { ngx_string("SSLv2"), NGX_SSL_SSLv2 }, | |
44 { ngx_string("SSLv3"), NGX_SSL_SSLv3 }, | |
45 { ngx_string("TLSv1"), NGX_SSL_TLSv1 }, | |
46 { ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 }, | |
47 { ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 }, | |
48 { ngx_null_string, 0 } | |
49 }; | |
50 | |
51 | |
52 static ngx_command_t ngx_stream_ssl_commands[] = { | |
53 | |
54 { ngx_string("ssl_handshake_timeout"), | |
55 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, | |
56 ngx_conf_set_msec_slot, | |
57 NGX_STREAM_SRV_CONF_OFFSET, | |
58 offsetof(ngx_stream_ssl_conf_t, handshake_timeout), | |
59 NULL }, | |
60 | |
61 { ngx_string("ssl_certificate"), | |
62 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, | |
6550
51e1f047d15d
SSL: support for multiple certificates (ticket #814).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6489
diff
changeset
|
63 ngx_conf_set_str_array_slot, |
6115 | 64 NGX_STREAM_SRV_CONF_OFFSET, |
6550
51e1f047d15d
SSL: support for multiple certificates (ticket #814).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6489
diff
changeset
|
65 offsetof(ngx_stream_ssl_conf_t, certificates), |
6115 | 66 NULL }, |
67 | |
68 { ngx_string("ssl_certificate_key"), | |
69 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, | |
6550
51e1f047d15d
SSL: support for multiple certificates (ticket #814).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6489
diff
changeset
|
70 ngx_conf_set_str_array_slot, |
6115 | 71 NGX_STREAM_SRV_CONF_OFFSET, |
6550
51e1f047d15d
SSL: support for multiple certificates (ticket #814).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6489
diff
changeset
|
72 offsetof(ngx_stream_ssl_conf_t, certificate_keys), |
6115 | 73 NULL }, |
74 | |
75 { ngx_string("ssl_password_file"), | |
76 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, | |
77 ngx_stream_ssl_password_file, | |
78 NGX_STREAM_SRV_CONF_OFFSET, | |
79 0, | |
80 NULL }, | |
81 | |
82 { ngx_string("ssl_dhparam"), | |
83 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, | |
84 ngx_conf_set_str_slot, | |
85 NGX_STREAM_SRV_CONF_OFFSET, | |
86 offsetof(ngx_stream_ssl_conf_t, dhparam), | |
87 NULL }, | |
88 | |
89 { ngx_string("ssl_ecdh_curve"), | |
90 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, | |
91 ngx_conf_set_str_slot, | |
92 NGX_STREAM_SRV_CONF_OFFSET, | |
93 offsetof(ngx_stream_ssl_conf_t, ecdh_curve), | |
94 NULL }, | |
95 | |
96 { ngx_string("ssl_protocols"), | |
97 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_1MORE, | |
98 ngx_conf_set_bitmask_slot, | |
99 NGX_STREAM_SRV_CONF_OFFSET, | |
100 offsetof(ngx_stream_ssl_conf_t, protocols), | |
101 &ngx_stream_ssl_protocols }, | |
102 | |
103 { ngx_string("ssl_ciphers"), | |
104 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, | |
105 ngx_conf_set_str_slot, | |
106 NGX_STREAM_SRV_CONF_OFFSET, | |
107 offsetof(ngx_stream_ssl_conf_t, ciphers), | |
108 NULL }, | |
109 | |
110 { ngx_string("ssl_prefer_server_ciphers"), | |
111 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG, | |
112 ngx_conf_set_flag_slot, | |
113 NGX_STREAM_SRV_CONF_OFFSET, | |
114 offsetof(ngx_stream_ssl_conf_t, prefer_server_ciphers), | |
115 NULL }, | |
116 | |
117 { ngx_string("ssl_session_cache"), | |
118 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE12, | |
119 ngx_stream_ssl_session_cache, | |
120 NGX_STREAM_SRV_CONF_OFFSET, | |
121 0, | |
122 NULL }, | |
123 | |
124 { ngx_string("ssl_session_tickets"), | |
125 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG, | |
126 ngx_conf_set_flag_slot, | |
127 NGX_STREAM_SRV_CONF_OFFSET, | |
128 offsetof(ngx_stream_ssl_conf_t, session_tickets), | |
129 NULL }, | |
130 | |
131 { ngx_string("ssl_session_ticket_key"), | |
132 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, | |
133 ngx_conf_set_str_array_slot, | |
134 NGX_STREAM_SRV_CONF_OFFSET, | |
135 offsetof(ngx_stream_ssl_conf_t, session_ticket_keys), | |
136 NULL }, | |
137 | |
138 { ngx_string("ssl_session_timeout"), | |
139 NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, | |
140 ngx_conf_set_sec_slot, | |
141 NGX_STREAM_SRV_CONF_OFFSET, | |
142 offsetof(ngx_stream_ssl_conf_t, session_timeout), | |
143 NULL }, | |
144 | |
145 ngx_null_command | |
146 }; | |
147 | |
148 | |
149 static ngx_stream_module_t ngx_stream_ssl_module_ctx = { | |
6611
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
150 ngx_stream_ssl_add_variables, /* preconfiguration */ |
6693 | 151 ngx_stream_ssl_init, /* postconfiguration */ |
6174
68c106e6fa0a
Stream: added postconfiguration method to stream modules.
Vladimir Homutov <vl@nginx.com>
parents:
6157
diff
changeset
|
152 |
6115 | 153 NULL, /* create main configuration */ |
154 NULL, /* init main configuration */ | |
155 | |
156 ngx_stream_ssl_create_conf, /* create server configuration */ | |
157 ngx_stream_ssl_merge_conf /* merge server configuration */ | |
158 }; | |
159 | |
160 | |
161 ngx_module_t ngx_stream_ssl_module = { | |
162 NGX_MODULE_V1, | |
163 &ngx_stream_ssl_module_ctx, /* module context */ | |
164 ngx_stream_ssl_commands, /* module directives */ | |
165 NGX_STREAM_MODULE, /* module type */ | |
166 NULL, /* init master */ | |
167 NULL, /* init module */ | |
168 NULL, /* init process */ | |
169 NULL, /* init thread */ | |
170 NULL, /* exit thread */ | |
171 NULL, /* exit process */ | |
172 NULL, /* exit master */ | |
173 NGX_MODULE_V1_PADDING | |
174 }; | |
175 | |
176 | |
6611
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
177 static ngx_stream_variable_t ngx_stream_ssl_vars[] = { |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
178 |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
179 { ngx_string("ssl_protocol"), NULL, ngx_stream_ssl_static_variable, |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
180 (uintptr_t) ngx_ssl_get_protocol, NGX_STREAM_VAR_CHANGEABLE, 0 }, |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
181 |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
182 { ngx_string("ssl_cipher"), NULL, ngx_stream_ssl_static_variable, |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
183 (uintptr_t) ngx_ssl_get_cipher_name, NGX_STREAM_VAR_CHANGEABLE, 0 }, |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
184 |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
185 { ngx_string("ssl_session_id"), NULL, ngx_stream_ssl_variable, |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
186 (uintptr_t) ngx_ssl_get_session_id, NGX_STREAM_VAR_CHANGEABLE, 0 }, |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
187 |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
188 { ngx_string("ssl_session_reused"), NULL, ngx_stream_ssl_variable, |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
189 (uintptr_t) ngx_ssl_get_session_reused, NGX_STREAM_VAR_CHANGEABLE, 0 }, |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
190 |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
191 { ngx_string("ssl_server_name"), NULL, ngx_stream_ssl_variable, |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
192 (uintptr_t) ngx_ssl_get_server_name, NGX_STREAM_VAR_CHANGEABLE, 0 }, |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
193 |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
194 { ngx_null_string, NULL, NULL, 0, 0, 0 } |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
195 }; |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
196 |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
197 |
6115 | 198 static ngx_str_t ngx_stream_ssl_sess_id_ctx = ngx_string("STREAM"); |
199 | |
200 | |
6611
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
201 static ngx_int_t |
6693 | 202 ngx_stream_ssl_handler(ngx_stream_session_t *s) |
203 { | |
204 ngx_connection_t *c; | |
205 ngx_stream_ssl_conf_t *sslcf; | |
206 | |
207 c = s->connection; | |
208 | |
209 sslcf = ngx_stream_get_module_srv_conf(s, ngx_stream_ssl_module); | |
210 | |
211 if (s->ssl && c->ssl == NULL) { | |
212 c->log->action = "SSL handshaking"; | |
213 | |
214 if (sslcf->ssl.ctx == NULL) { | |
215 ngx_log_error(NGX_LOG_ERR, c->log, 0, | |
216 "no \"ssl_certificate\" is defined " | |
217 "in server listening on SSL port"); | |
218 return NGX_ERROR; | |
219 } | |
220 | |
221 return ngx_stream_ssl_init_connection(&sslcf->ssl, c); | |
222 } | |
223 | |
224 return NGX_OK; | |
225 } | |
226 | |
227 | |
228 static ngx_int_t | |
229 ngx_stream_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c) | |
230 { | |
231 ngx_int_t rc; | |
232 ngx_stream_session_t *s; | |
233 ngx_stream_ssl_conf_t *sslcf; | |
234 | |
235 s = c->data; | |
236 | |
237 if (ngx_ssl_create_connection(ssl, c, 0) == NGX_ERROR) { | |
238 return NGX_ERROR; | |
239 } | |
240 | |
241 rc = ngx_ssl_handshake(c); | |
242 | |
243 if (rc == NGX_ERROR) { | |
244 return NGX_ERROR; | |
245 } | |
246 | |
247 if (rc == NGX_AGAIN) { | |
248 sslcf = ngx_stream_get_module_srv_conf(s, ngx_stream_ssl_module); | |
249 | |
250 ngx_add_timer(c->read, sslcf->handshake_timeout); | |
251 | |
252 c->ssl->handler = ngx_stream_ssl_handshake_handler; | |
253 | |
254 return NGX_AGAIN; | |
255 } | |
256 | |
257 /* rc == NGX_OK */ | |
258 | |
259 return NGX_OK; | |
260 } | |
261 | |
262 | |
263 static void | |
264 ngx_stream_ssl_handshake_handler(ngx_connection_t *c) | |
265 { | |
266 ngx_stream_session_t *s; | |
267 | |
268 s = c->data; | |
269 | |
270 if (!c->ssl->handshaked) { | |
271 ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR); | |
272 return; | |
273 } | |
274 | |
275 if (c->read->timer_set) { | |
276 ngx_del_timer(c->read); | |
277 } | |
278 | |
279 ngx_stream_core_run_phases(s); | |
280 } | |
281 | |
282 | |
283 static ngx_int_t | |
6611
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
284 ngx_stream_ssl_static_variable(ngx_stream_session_t *s, |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
285 ngx_stream_variable_value_t *v, uintptr_t data) |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
286 { |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
287 ngx_ssl_variable_handler_pt handler = (ngx_ssl_variable_handler_pt) data; |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
288 |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
289 size_t len; |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
290 ngx_str_t str; |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
291 |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
292 if (s->connection->ssl) { |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
293 |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
294 (void) handler(s->connection, NULL, &str); |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
295 |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
296 v->data = str.data; |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
297 |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
298 for (len = 0; v->data[len]; len++) { /* void */ } |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
299 |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
300 v->len = len; |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
301 v->valid = 1; |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
302 v->no_cacheable = 0; |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
303 v->not_found = 0; |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
304 |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
305 return NGX_OK; |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
306 } |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
307 |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
308 v->not_found = 1; |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
309 |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
310 return NGX_OK; |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
311 } |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
312 |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
313 |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
314 static ngx_int_t |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
315 ngx_stream_ssl_variable(ngx_stream_session_t *s, |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
316 ngx_stream_variable_value_t *v, uintptr_t data) |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
317 { |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
318 ngx_ssl_variable_handler_pt handler = (ngx_ssl_variable_handler_pt) data; |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
319 |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
320 ngx_str_t str; |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
321 |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
322 if (s->connection->ssl) { |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
323 |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
324 if (handler(s->connection, s->connection->pool, &str) != NGX_OK) { |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
325 return NGX_ERROR; |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
326 } |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
327 |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
328 v->len = str.len; |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
329 v->data = str.data; |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
330 |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
331 if (v->len) { |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
332 v->valid = 1; |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
333 v->no_cacheable = 0; |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
334 v->not_found = 0; |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
335 |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
336 return NGX_OK; |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
337 } |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
338 } |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
339 |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
340 v->not_found = 1; |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
341 |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
342 return NGX_OK; |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
343 } |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
344 |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
345 |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
346 static ngx_int_t |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
347 ngx_stream_ssl_add_variables(ngx_conf_t *cf) |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
348 { |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
349 ngx_stream_variable_t *var, *v; |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
350 |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
351 for (v = ngx_stream_ssl_vars; v->name.len; v++) { |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
352 var = ngx_stream_add_variable(cf, &v->name, v->flags); |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
353 if (var == NULL) { |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
354 return NGX_ERROR; |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
355 } |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
356 |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
357 var->get_handler = v->get_handler; |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
358 var->data = v->data; |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
359 } |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
360 |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
361 return NGX_OK; |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
362 } |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
363 |
85e7bcb37d6b
Stream: SSL-related variables.
Vladimir Homutov <vl@nginx.com>
parents:
6606
diff
changeset
|
364 |
6115 | 365 static void * |
366 ngx_stream_ssl_create_conf(ngx_conf_t *cf) | |
367 { | |
368 ngx_stream_ssl_conf_t *scf; | |
369 | |
370 scf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_ssl_conf_t)); | |
371 if (scf == NULL) { | |
372 return NULL; | |
373 } | |
374 | |
375 /* | |
376 * set by ngx_pcalloc(): | |
377 * | |
378 * scf->protocols = 0; | |
379 * scf->dhparam = { 0, NULL }; | |
380 * scf->ecdh_curve = { 0, NULL }; | |
381 * scf->ciphers = { 0, NULL }; | |
382 * scf->shm_zone = NULL; | |
383 */ | |
384 | |
385 scf->handshake_timeout = NGX_CONF_UNSET_MSEC; | |
6550
51e1f047d15d
SSL: support for multiple certificates (ticket #814).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6489
diff
changeset
|
386 scf->certificates = NGX_CONF_UNSET_PTR; |
51e1f047d15d
SSL: support for multiple certificates (ticket #814).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6489
diff
changeset
|
387 scf->certificate_keys = NGX_CONF_UNSET_PTR; |
6115 | 388 scf->passwords = NGX_CONF_UNSET_PTR; |
389 scf->prefer_server_ciphers = NGX_CONF_UNSET; | |
390 scf->builtin_session_cache = NGX_CONF_UNSET; | |
391 scf->session_timeout = NGX_CONF_UNSET; | |
392 scf->session_tickets = NGX_CONF_UNSET; | |
393 scf->session_ticket_keys = NGX_CONF_UNSET_PTR; | |
394 | |
395 return scf; | |
396 } | |
397 | |
398 | |
399 static char * | |
400 ngx_stream_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child) | |
401 { | |
402 ngx_stream_ssl_conf_t *prev = parent; | |
403 ngx_stream_ssl_conf_t *conf = child; | |
404 | |
405 ngx_pool_cleanup_t *cln; | |
406 | |
407 ngx_conf_merge_msec_value(conf->handshake_timeout, | |
408 prev->handshake_timeout, 60000); | |
409 | |
410 ngx_conf_merge_value(conf->session_timeout, | |
411 prev->session_timeout, 300); | |
412 | |
413 ngx_conf_merge_value(conf->prefer_server_ciphers, | |
414 prev->prefer_server_ciphers, 0); | |
415 | |
416 ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols, | |
6157
b2899e7d0ef8
Disabled SSLv3 by default (ticket #653).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6115
diff
changeset
|
417 (NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1 |
6115 | 418 |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2)); |
419 | |
6550
51e1f047d15d
SSL: support for multiple certificates (ticket #814).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6489
diff
changeset
|
420 ngx_conf_merge_ptr_value(conf->certificates, prev->certificates, NULL); |
51e1f047d15d
SSL: support for multiple certificates (ticket #814).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6489
diff
changeset
|
421 ngx_conf_merge_ptr_value(conf->certificate_keys, prev->certificate_keys, |
51e1f047d15d
SSL: support for multiple certificates (ticket #814).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6489
diff
changeset
|
422 NULL); |
6115 | 423 |
424 ngx_conf_merge_ptr_value(conf->passwords, prev->passwords, NULL); | |
425 | |
426 ngx_conf_merge_str_value(conf->dhparam, prev->dhparam, ""); | |
427 | |
428 ngx_conf_merge_str_value(conf->ecdh_curve, prev->ecdh_curve, | |
429 NGX_DEFAULT_ECDH_CURVE); | |
430 | |
431 ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, NGX_DEFAULT_CIPHERS); | |
432 | |
433 | |
434 conf->ssl.log = cf->log; | |
435 | |
6550
51e1f047d15d
SSL: support for multiple certificates (ticket #814).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6489
diff
changeset
|
436 if (conf->certificates == NULL) { |
6115 | 437 return NGX_CONF_OK; |
438 } | |
439 | |
6550
51e1f047d15d
SSL: support for multiple certificates (ticket #814).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6489
diff
changeset
|
440 if (conf->certificate_keys == NULL |
51e1f047d15d
SSL: support for multiple certificates (ticket #814).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6489
diff
changeset
|
441 || conf->certificate_keys->nelts < conf->certificates->nelts) |
51e1f047d15d
SSL: support for multiple certificates (ticket #814).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6489
diff
changeset
|
442 { |
6115 | 443 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, |
444 "no \"ssl_certificate_key\" is defined " | |
445 "for certificate \"%V\"", | |
6550
51e1f047d15d
SSL: support for multiple certificates (ticket #814).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6489
diff
changeset
|
446 ((ngx_str_t *) conf->certificates->elts) |
51e1f047d15d
SSL: support for multiple certificates (ticket #814).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6489
diff
changeset
|
447 + conf->certificates->nelts - 1); |
6115 | 448 return NGX_CONF_ERROR; |
449 } | |
450 | |
451 if (ngx_ssl_create(&conf->ssl, conf->protocols, NULL) != NGX_OK) { | |
452 return NGX_CONF_ERROR; | |
453 } | |
454 | |
455 cln = ngx_pool_cleanup_add(cf->pool, 0); | |
456 if (cln == NULL) { | |
457 return NGX_CONF_ERROR; | |
458 } | |
459 | |
460 cln->handler = ngx_ssl_cleanup_ctx; | |
461 cln->data = &conf->ssl; | |
462 | |
6550
51e1f047d15d
SSL: support for multiple certificates (ticket #814).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6489
diff
changeset
|
463 if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates, |
51e1f047d15d
SSL: support for multiple certificates (ticket #814).
Maxim Dounin <mdounin@mdounin.ru>
parents:
6489
diff
changeset
|
464 conf->certificate_keys, conf->passwords) |
6115 | 465 != NGX_OK) |
466 { | |
467 return NGX_CONF_ERROR; | |
468 } | |
469 | |
6591
04d8d1f85649
SSL: ngx_ssl_ciphers() to set list of ciphers.
Tim Taubert <tim@timtaubert.de>
parents:
6553
diff
changeset
|
470 if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers, |
04d8d1f85649
SSL: ngx_ssl_ciphers() to set list of ciphers.
Tim Taubert <tim@timtaubert.de>
parents:
6553
diff
changeset
|
471 conf->prefer_server_ciphers) |
04d8d1f85649
SSL: ngx_ssl_ciphers() to set list of ciphers.
Tim Taubert <tim@timtaubert.de>
parents:
6553
diff
changeset
|
472 != NGX_OK) |
6115 | 473 { |
474 return NGX_CONF_ERROR; | |
475 } | |
476 | |
477 if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) { | |
478 return NGX_CONF_ERROR; | |
479 } | |
480 | |
481 if (ngx_ssl_ecdh_curve(cf, &conf->ssl, &conf->ecdh_curve) != NGX_OK) { | |
482 return NGX_CONF_ERROR; | |
483 } | |
484 | |
485 ngx_conf_merge_value(conf->builtin_session_cache, | |
486 prev->builtin_session_cache, NGX_SSL_NONE_SCACHE); | |
487 | |
488 if (conf->shm_zone == NULL) { | |
489 conf->shm_zone = prev->shm_zone; | |
490 } | |
491 | |
492 if (ngx_ssl_session_cache(&conf->ssl, &ngx_stream_ssl_sess_id_ctx, | |
493 conf->builtin_session_cache, | |
494 conf->shm_zone, conf->session_timeout) | |
495 != NGX_OK) | |
496 { | |
497 return NGX_CONF_ERROR; | |
498 } | |
499 | |
500 ngx_conf_merge_value(conf->session_tickets, | |
501 prev->session_tickets, 1); | |
502 | |
503 #ifdef SSL_OP_NO_TICKET | |
504 if (!conf->session_tickets) { | |
505 SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_NO_TICKET); | |
506 } | |
507 #endif | |
508 | |
509 ngx_conf_merge_ptr_value(conf->session_ticket_keys, | |
510 prev->session_ticket_keys, NULL); | |
511 | |
512 if (ngx_ssl_session_ticket_keys(cf, &conf->ssl, conf->session_ticket_keys) | |
513 != NGX_OK) | |
514 { | |
515 return NGX_CONF_ERROR; | |
516 } | |
517 | |
518 return NGX_CONF_OK; | |
519 } | |
520 | |
521 | |
522 static char * | |
523 ngx_stream_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
524 { | |
525 ngx_stream_ssl_conf_t *scf = conf; | |
526 | |
527 ngx_str_t *value; | |
528 | |
529 if (scf->passwords != NGX_CONF_UNSET_PTR) { | |
530 return "is duplicate"; | |
531 } | |
532 | |
533 value = cf->args->elts; | |
534 | |
535 scf->passwords = ngx_ssl_read_password_file(cf, &value[1]); | |
536 | |
537 if (scf->passwords == NULL) { | |
538 return NGX_CONF_ERROR; | |
539 } | |
540 | |
541 return NGX_CONF_OK; | |
542 } | |
543 | |
544 | |
545 static char * | |
546 ngx_stream_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
547 { | |
548 ngx_stream_ssl_conf_t *scf = conf; | |
549 | |
550 size_t len; | |
551 ngx_str_t *value, name, size; | |
552 ngx_int_t n; | |
553 ngx_uint_t i, j; | |
554 | |
555 value = cf->args->elts; | |
556 | |
557 for (i = 1; i < cf->args->nelts; i++) { | |
558 | |
559 if (ngx_strcmp(value[i].data, "off") == 0) { | |
560 scf->builtin_session_cache = NGX_SSL_NO_SCACHE; | |
561 continue; | |
562 } | |
563 | |
564 if (ngx_strcmp(value[i].data, "none") == 0) { | |
565 scf->builtin_session_cache = NGX_SSL_NONE_SCACHE; | |
566 continue; | |
567 } | |
568 | |
569 if (ngx_strcmp(value[i].data, "builtin") == 0) { | |
570 scf->builtin_session_cache = NGX_SSL_DFLT_BUILTIN_SCACHE; | |
571 continue; | |
572 } | |
573 | |
574 if (value[i].len > sizeof("builtin:") - 1 | |
575 && ngx_strncmp(value[i].data, "builtin:", sizeof("builtin:") - 1) | |
576 == 0) | |
577 { | |
578 n = ngx_atoi(value[i].data + sizeof("builtin:") - 1, | |
579 value[i].len - (sizeof("builtin:") - 1)); | |
580 | |
581 if (n == NGX_ERROR) { | |
582 goto invalid; | |
583 } | |
584 | |
585 scf->builtin_session_cache = n; | |
586 | |
587 continue; | |
588 } | |
589 | |
590 if (value[i].len > sizeof("shared:") - 1 | |
591 && ngx_strncmp(value[i].data, "shared:", sizeof("shared:") - 1) | |
592 == 0) | |
593 { | |
594 len = 0; | |
595 | |
596 for (j = sizeof("shared:") - 1; j < value[i].len; j++) { | |
597 if (value[i].data[j] == ':') { | |
598 break; | |
599 } | |
600 | |
601 len++; | |
602 } | |
603 | |
604 if (len == 0) { | |
605 goto invalid; | |
606 } | |
607 | |
608 name.len = len; | |
609 name.data = value[i].data + sizeof("shared:") - 1; | |
610 | |
611 size.len = value[i].len - j - 1; | |
612 size.data = name.data + len + 1; | |
613 | |
614 n = ngx_parse_size(&size); | |
615 | |
616 if (n == NGX_ERROR) { | |
617 goto invalid; | |
618 } | |
619 | |
620 if (n < (ngx_int_t) (8 * ngx_pagesize)) { | |
621 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
622 "session cache \"%V\" is too small", | |
623 &value[i]); | |
624 | |
625 return NGX_CONF_ERROR; | |
626 } | |
627 | |
628 scf->shm_zone = ngx_shared_memory_add(cf, &name, n, | |
629 &ngx_stream_ssl_module); | |
630 if (scf->shm_zone == NULL) { | |
631 return NGX_CONF_ERROR; | |
632 } | |
633 | |
634 scf->shm_zone->init = ngx_ssl_session_cache_init; | |
635 | |
636 continue; | |
637 } | |
638 | |
639 goto invalid; | |
640 } | |
641 | |
642 if (scf->shm_zone && scf->builtin_session_cache == NGX_CONF_UNSET) { | |
643 scf->builtin_session_cache = NGX_SSL_NO_BUILTIN_SCACHE; | |
644 } | |
645 | |
646 return NGX_CONF_OK; | |
647 | |
648 invalid: | |
649 | |
650 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
651 "invalid session cache \"%V\"", &value[i]); | |
652 | |
653 return NGX_CONF_ERROR; | |
654 } | |
6693 | 655 |
656 | |
657 static ngx_int_t | |
658 ngx_stream_ssl_init(ngx_conf_t *cf) | |
659 { | |
660 ngx_stream_handler_pt *h; | |
661 ngx_stream_core_main_conf_t *cmcf; | |
662 | |
663 cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module); | |
664 | |
665 h = ngx_array_push(&cmcf->phases[NGX_STREAM_SSL_PHASE].handlers); | |
666 if (h == NULL) { | |
667 return NGX_ERROR; | |
668 } | |
669 | |
670 *h = ngx_stream_ssl_handler; | |
671 | |
672 return NGX_OK; | |
673 } |