Mercurial > hg > nginx-quic
comparison src/http/modules/ngx_http_ssl_filter.c @ 386:fa72605e7089
nginx-0.0.7-2004-07-12-01:03:47 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Sun, 11 Jul 2004 21:03:47 +0000 |
parents | 79050a10aacb |
children | b670db10cbbd |
comparison
equal
deleted
inserted
replaced
385:79050a10aacb | 386:fa72605e7089 |
---|---|
13 | 13 |
14 typedef struct { | 14 typedef struct { |
15 ngx_flag_t enable; | 15 ngx_flag_t enable; |
16 ngx_str_t certificate; | 16 ngx_str_t certificate; |
17 ngx_str_t certificate_key; | 17 ngx_str_t certificate_key; |
18 | |
19 SSL_CTX *ssl_ctx; | |
18 } ngx_http_ssl_srv_conf_t; | 20 } ngx_http_ssl_srv_conf_t; |
19 | 21 |
20 | 22 |
21 typedef struct { | 23 typedef struct { |
22 SSL *ssl; | 24 SSL *ssl; |
23 SSL_CTX *ssl_ctx; | |
24 | 25 |
25 unsigned accepted; | 26 unsigned accepted; |
26 } ngx_http_ssl_ctx_t; | 27 } ngx_http_ssl_ctx_t; |
27 | 28 |
28 | 29 |
84 ngx_http_ssl_filter_init, /* init module */ | 85 ngx_http_ssl_filter_init, /* init module */ |
85 NULL /* init process */ | 86 NULL /* init process */ |
86 }; | 87 }; |
87 | 88 |
88 | 89 |
89 ngx_int_t ngx_http_ssl_read(ngx_http_request_t *r) | 90 ngx_int_t ngx_http_ssl_read(ngx_http_request_t *r, u_char *buf, size_t n) |
90 { | 91 { |
91 int rc; | 92 int rc; |
92 ngx_http_ssl_ctx_t *ctx; | 93 ngx_http_ssl_ctx_t *ctx; |
94 ngx_http_log_ctx_t *log_ctx; | |
93 | 95 |
94 ctx = ngx_http_get_module_ctx(r, ngx_http_ssl_filter_module); | 96 ctx = ngx_http_get_module_ctx(r, ngx_http_ssl_filter_module); |
95 | 97 |
96 if (ctx == NULL) { | 98 if (ctx == NULL) { |
97 ctx = ngx_http_ssl_create_ctx(r); | 99 ctx = ngx_http_ssl_create_ctx(r); |
99 if (ctx == NULL) { | 101 if (ctx == NULL) { |
100 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 102 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
101 } | 103 } |
102 } | 104 } |
103 | 105 |
104 if (!ctx->accepted) { | 106 rc = SSL_read(ctx->ssl, buf, n); |
105 rc = SSL_accept(ctx->ssl); | 107 |
106 | 108 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
107 if (rc != 1) { | 109 "SSL_read: %d", rc); |
108 rc = SSL_get_error(ctx->ssl, rc); | 110 |
109 | 111 if (rc > 0) { |
110 if (rc == SSL_ERROR_WANT_READ || rc == SSL_ERROR_WANT_WRITE) { | 112 return rc; |
111 return NGX_AGAIN; | 113 } |
112 } | 114 |
113 | 115 rc = SSL_get_error(ctx->ssl, rc); |
114 if (rc == SSL_ERROR_ZERO_RETURN) { | 116 |
115 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, | 117 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
116 "client closed connection while SSL handshake"); | 118 "SSL_get_error: %d", rc); |
117 | 119 |
118 ngx_http_ssl_close_request(ctx->ssl, SSL_RECEIVED_SHUTDOWN); | 120 if (rc == SSL_ERROR_WANT_READ) { |
119 | 121 return NGX_AGAIN; |
120 return NGX_ERROR; | 122 } |
121 } | 123 |
122 | 124 #if 0 |
123 if (ERR_GET_REASON(ERR_peek_error()) == SSL_R_HTTP_REQUEST) { | 125 if (rc == SSL_ERROR_WANT_WRITE) { |
124 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | 126 return NGX_AGAIN; |
125 "client sent HTTP request to HTTPS port"); | 127 } |
126 | 128 #endif |
127 ngx_http_ssl_close_request(ctx->ssl, | 129 |
128 SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); | 130 if (!SSL_is_init_finished(ctx->ssl)) { |
129 | 131 log_ctx = (ngx_http_log_ctx_t *) r->connection->log->data; |
130 return NGX_OK; | 132 log_ctx->action = "SSL handshake"; |
131 } | 133 } |
132 | 134 |
133 ngx_http_ssl_error(NGX_LOG_ALERT, r->connection->log, rc, | 135 if (rc == SSL_ERROR_ZERO_RETURN) { |
134 "SSL_accept() failed"); | 136 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, |
135 | 137 "client closed connection"); |
136 ngx_http_ssl_close_request(ctx->ssl, SSL_RECEIVED_SHUTDOWN); | 138 |
137 | 139 SSL_set_shutdown(ctx->ssl, SSL_RECEIVED_SHUTDOWN); |
138 return NGX_ERROR; | 140 |
139 } | 141 return NGX_SSL_ERROR; |
140 | 142 } |
141 ctx->accepted = 1; | 143 |
144 if (ERR_GET_REASON(ERR_peek_error()) == SSL_R_HTTP_REQUEST) { | |
145 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
146 "client sent plain HTTP request to HTTPS port"); | |
147 | |
148 SSL_set_shutdown(ctx->ssl, | |
149 SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN); | |
150 | |
151 return NGX_SSL_HTTP_ERROR; | |
152 } | |
153 | |
154 ngx_http_ssl_error(NGX_LOG_ALERT, r->connection->log, rc, | |
155 "SSL_accept() failed"); | |
156 | |
157 SSL_set_shutdown(ctx->ssl, SSL_RECEIVED_SHUTDOWN); | |
158 | |
159 return NGX_SSL_ERROR; | |
160 } | |
161 | |
162 | |
163 ngx_int_t ngx_http_ssl_write(ngx_http_request_t *r, ngx_chain_t *in, | |
164 off_t limit) | |
165 { | |
166 int rc; | |
167 size_t send, size; | |
168 ngx_http_ssl_ctx_t *ctx; | |
169 | |
170 ctx = ngx_http_get_module_ctx(r, ngx_http_ssl_filter_module); | |
171 | |
172 if (in == NULL) { | |
173 rc = SSL_shutdown(ctx->ssl); | |
174 | |
175 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
176 "SSL_shutdown: %d", rc); | |
177 | |
178 if (rc == 1) { | |
179 return NGX_OK; | |
180 } | |
181 | |
182 rc = SSL_get_error(ctx->ssl, rc); | |
183 | |
184 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
185 "SSL_get_error: %d", rc); | |
186 | |
187 if (rc == SSL_ERROR_WANT_WRITE) { | |
188 return NGX_AGAIN; | |
189 } | |
190 | |
191 return NGX_ERROR; | |
192 } | |
193 | |
194 send = 0; | |
195 | |
196 for (/* void */; in; in = in->next) { | |
197 if (ngx_buf_special(in->buf)) { | |
198 continue; | |
199 } | |
200 | |
201 size = in->buf->last - in->buf->pos; | |
202 | |
203 if (send + size > limit) { | |
204 size = limit - send; | |
205 } | |
206 | |
207 rc = SSL_write(ctx->ssl, in->buf->pos, size); | |
142 } | 208 } |
143 | 209 |
144 return NGX_OK; | 210 return NGX_OK; |
145 } | 211 } |
146 | 212 |
151 ngx_http_ssl_srv_conf_t *scf; | 217 ngx_http_ssl_srv_conf_t *scf; |
152 | 218 |
153 ngx_http_create_ctx(r, ctx, ngx_http_ssl_filter_module, | 219 ngx_http_create_ctx(r, ctx, ngx_http_ssl_filter_module, |
154 sizeof(ngx_http_ssl_ctx_t), NULL); | 220 sizeof(ngx_http_ssl_ctx_t), NULL); |
155 | 221 |
156 /* TODO: configure methods */ | |
157 ctx->ssl_ctx = SSL_CTX_new(SSLv23_server_method()); | |
158 | |
159 if (ctx->ssl_ctx == NULL) { | |
160 ngx_http_ssl_error(NGX_LOG_ALERT, r->connection->log, 0, | |
161 "SSL_CTX_new() failed"); | |
162 return NULL; | |
163 } | |
164 | |
165 scf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_filter_module); | 222 scf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_filter_module); |
166 | 223 |
167 if (SSL_CTX_use_certificate_file(ctx->ssl_ctx, scf->certificate.data, | 224 ctx->ssl = SSL_new(scf->ssl_ctx); |
168 SSL_FILETYPE_PEM) == 0) { | |
169 ngx_http_ssl_error(NGX_LOG_ALERT, r->connection->log, 0, | |
170 "SSL_CTX_use_certificate_file() failed"); | |
171 return NULL; | |
172 } | |
173 | |
174 if (SSL_CTX_use_PrivateKey_file(ctx->ssl_ctx, scf->certificate_key.data, | |
175 SSL_FILETYPE_PEM) == 0) { | |
176 ngx_http_ssl_error(NGX_LOG_ALERT, r->connection->log, 0, | |
177 "SSL_CTX_use_PrivateKey_file() failed"); | |
178 return NULL; | |
179 } | |
180 | |
181 ctx->ssl = SSL_new(ctx->ssl_ctx); | |
182 | 225 |
183 if (ctx->ssl == NULL) { | 226 if (ctx->ssl == NULL) { |
184 ngx_http_ssl_error(NGX_LOG_ALERT, r->connection->log, 0, | 227 ngx_http_ssl_error(NGX_LOG_ALERT, r->connection->log, 0, |
185 "SSL_new() failed"); | 228 "SSL_new() failed"); |
186 return NULL; | 229 return NULL; |
190 ngx_http_ssl_error(NGX_LOG_ALERT, r->connection->log, 0, | 233 ngx_http_ssl_error(NGX_LOG_ALERT, r->connection->log, 0, |
191 "SSL_set_fd() failed"); | 234 "SSL_set_fd() failed"); |
192 return NULL; | 235 return NULL; |
193 } | 236 } |
194 | 237 |
238 SSL_set_accept_state(ctx->ssl); | |
239 | |
195 return ctx; | 240 return ctx; |
196 } | 241 } |
197 | 242 |
198 | 243 |
199 void ngx_http_ssl_close_request(SSL *ssl, int mode) | 244 void ngx_http_ssl_close_connection(SSL *ssl, ngx_log_t *log) |
200 { | 245 { |
201 SSL_set_shutdown(ssl, mode); | 246 int rc; |
202 SSL_shutdown(ssl); | 247 |
203 SSL_free(ssl); | 248 SSL_free(ssl); |
204 } | 249 } |
205 | 250 |
206 | 251 |
207 static void ngx_http_ssl_error(ngx_uint_t level, ngx_log_t *log, int err, | 252 static void ngx_http_ssl_error(ngx_uint_t level, ngx_log_t *log, int err, |
255 NGX_DEFLAUT_CERTIFICATE); | 300 NGX_DEFLAUT_CERTIFICATE); |
256 | 301 |
257 ngx_conf_merge_str_value(conf->certificate_key, prev->certificate_key, | 302 ngx_conf_merge_str_value(conf->certificate_key, prev->certificate_key, |
258 NGX_DEFLAUT_CERTIFICATE_KEY); | 303 NGX_DEFLAUT_CERTIFICATE_KEY); |
259 | 304 |
260 return NGX_CONF_OK; | 305 /* STUB: where to move ??? */ |
261 } | |
262 | |
263 | |
264 static ngx_int_t ngx_http_ssl_filter_init(ngx_cycle_t *cycle) | |
265 { | |
266 SSL_library_init(); | 306 SSL_library_init(); |
267 SSL_load_error_strings(); | 307 SSL_load_error_strings(); |
268 | 308 |
309 /* TODO: inherit ssl_ctx */ | |
310 | |
311 /* TODO: configure methods */ | |
312 | |
313 conf->ssl_ctx = SSL_CTX_new(SSLv23_server_method()); | |
314 | |
315 if (conf->ssl_ctx == NULL) { | |
316 ngx_http_ssl_error(NGX_LOG_EMERG, cf->log, 0, "SSL_CTX_new() failed"); | |
317 return NGX_CONF_ERROR; | |
318 } | |
319 | |
320 if (SSL_CTX_use_certificate_file(conf->ssl_ctx, conf->certificate.data, | |
321 SSL_FILETYPE_PEM) == 0) { | |
322 ngx_http_ssl_error(NGX_LOG_EMERG, cf->log, 0, | |
323 "SSL_CTX_use_certificate_file() failed"); | |
324 return NGX_CONF_ERROR; | |
325 } | |
326 | |
327 if (SSL_CTX_use_PrivateKey_file(conf->ssl_ctx, conf->certificate_key.data, | |
328 SSL_FILETYPE_PEM) == 0) { | |
329 ngx_http_ssl_error(NGX_LOG_EMERG, cf->log, 0, | |
330 "SSL_CTX_use_PrivateKey_file() failed"); | |
331 return NGX_CONF_ERROR; | |
332 } | |
333 | |
334 return NGX_CONF_OK; | |
335 } | |
336 | |
337 | |
338 static ngx_int_t ngx_http_ssl_filter_init(ngx_cycle_t *cycle) | |
339 { | |
269 #if 0 | 340 #if 0 |
270 ngx_http_next_header_filter = ngx_http_top_header_filter; | 341 ngx_http_next_header_filter = ngx_http_top_header_filter; |
271 ngx_http_top_header_filter = ngx_http_ssl_header_filter; | 342 ngx_http_top_header_filter = ngx_http_ssl_header_filter; |
272 | 343 |
273 ngx_http_next_body_filter = ngx_http_top_body_filter; | 344 ngx_http_next_body_filter = ngx_http_top_body_filter; |