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;