Mercurial > hg > nginx
comparison src/http/modules/ngx_http_ssl_filter.c @ 392:d1222d46b3f9
nginx-0.0.7-2004-07-15-00:07:58 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Wed, 14 Jul 2004 20:07:58 +0000 |
parents | b670db10cbbd |
children | 5659d773cfa8 |
comparison
equal
deleted
inserted
replaced
391:b670db10cbbd | 392:d1222d46b3f9 |
---|---|
1 | 1 |
2 #include <ngx_config.h> | 2 #include <ngx_config.h> |
3 #include <ngx_core.h> | 3 #include <ngx_core.h> |
4 #include <ngx_http.h> | 4 #include <ngx_http.h> |
5 | |
6 #include <openssl/ssl.h> | |
7 #include <openssl/err.h> | |
8 | 5 |
9 | 6 |
10 #define NGX_DEFLAUT_CERTIFICATE "cert.pem" | 7 #define NGX_DEFLAUT_CERTIFICATE "cert.pem" |
11 #define NGX_DEFLAUT_CERTIFICATE_KEY "cert.pem" | 8 #define NGX_DEFLAUT_CERTIFICATE_KEY "cert.pem" |
12 | 9 |
23 typedef struct { | 20 typedef struct { |
24 SSL *ssl; | 21 SSL *ssl; |
25 } ngx_http_ssl_ctx_t; | 22 } ngx_http_ssl_ctx_t; |
26 | 23 |
27 | 24 |
28 static ngx_http_ssl_ctx_t *ngx_http_ssl_create_ctx(ngx_http_request_t *r); | 25 static ngx_int_t ngx_http_ssl_create_ssl(ngx_http_request_t *r); |
29 static ngx_chain_t *ngx_http_ssl_write(ngx_http_request_t *r, ngx_chain_t *in, | |
30 off_t limit); | |
31 static void ngx_http_ssl_error(ngx_uint_t level, ngx_log_t *log, int err, | 26 static void ngx_http_ssl_error(ngx_uint_t level, ngx_log_t *log, int err, |
32 char *fmt, ...); | 27 char *fmt, ...); |
33 static void *ngx_http_ssl_create_srv_conf(ngx_conf_t *cf); | 28 static void *ngx_http_ssl_create_srv_conf(ngx_conf_t *cf); |
34 static char *ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, | 29 static char *ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, |
35 void *parent, void *child); | 30 void *parent, void *child); |
85 ngx_http_ssl_filter_init, /* init module */ | 80 ngx_http_ssl_filter_init, /* init module */ |
86 NULL /* init process */ | 81 NULL /* init process */ |
87 }; | 82 }; |
88 | 83 |
89 | 84 |
90 ngx_int_t ngx_http_ssl_read(ngx_http_request_t *r, u_char *buf, size_t n) | 85 ngx_int_t ngx_http_ssl_read(ngx_http_request_t *r, u_char *buf, size_t size) |
91 { | 86 { |
92 int rc; | 87 int n; |
88 SSL *ssl; | |
93 ngx_http_ssl_ctx_t *ctx; | 89 ngx_http_ssl_ctx_t *ctx; |
94 ngx_http_log_ctx_t *log_ctx; | 90 ngx_http_log_ctx_t *log_ctx; |
95 | 91 |
96 ctx = ngx_http_get_module_ctx(r, ngx_http_ssl_filter_module); | 92 if (r->connection->ssl == NULL) { |
97 | 93 if (ngx_http_ssl_create_ssl(r) == NGX_ERROR) { |
98 if (ctx == NULL) { | |
99 ctx = ngx_http_ssl_create_ctx(r); | |
100 | |
101 if (ctx == NULL) { | |
102 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 94 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
103 } | 95 } |
104 } | 96 } |
105 | 97 |
106 rc = SSL_read(ctx->ssl, buf, n); | 98 ssl = r->connection->ssl; |
99 | |
100 n = SSL_read(ssl, buf, size); | |
107 | 101 |
108 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 102 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
109 "SSL_read: %d", rc); | 103 "SSL_read: %d", n); |
110 | 104 |
111 if (rc > 0) { | 105 if (n > 0) { |
112 return rc; | 106 return n; |
113 } | 107 } |
114 | 108 |
115 rc = SSL_get_error(ctx->ssl, rc); | 109 n = SSL_get_error(ssl, n); |
116 | 110 |
117 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 111 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
118 "SSL_get_error: %d", rc); | 112 "SSL_get_error: %d", n); |
119 | 113 |
120 if (rc == SSL_ERROR_WANT_READ) { | 114 if (n == SSL_ERROR_WANT_READ) { |
121 return NGX_AGAIN; | 115 return NGX_AGAIN; |
122 } | 116 } |
123 | 117 |
124 #if 0 | 118 #if 0 |
125 if (rc == SSL_ERROR_WANT_WRITE) { | 119 if (n == SSL_ERROR_WANT_WRITE) { |
126 return NGX_AGAIN; | 120 return NGX_AGAIN; |
127 } | 121 } |
128 #endif | 122 #endif |
129 | 123 |
130 if (!SSL_is_init_finished(ctx->ssl)) { | 124 if (!SSL_is_init_finished(ssl)) { |
131 log_ctx = (ngx_http_log_ctx_t *) r->connection->log->data; | 125 log_ctx = (ngx_http_log_ctx_t *) r->connection->log->data; |
132 log_ctx->action = "SSL handshake"; | 126 log_ctx->action = "SSL handshake"; |
133 } | 127 } |
134 | 128 |
135 if (rc == SSL_ERROR_ZERO_RETURN) { | 129 if (n == SSL_ERROR_ZERO_RETURN) { |
136 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, | 130 ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, |
137 "client closed connection"); | 131 "client closed connection"); |
138 | 132 |
139 SSL_set_shutdown(ctx->ssl, SSL_RECEIVED_SHUTDOWN); | 133 SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN); |
140 | 134 |
141 return NGX_SSL_ERROR; | 135 return NGX_SSL_ERROR; |
142 } | 136 } |
143 | 137 |
144 if (ERR_GET_REASON(ERR_peek_error()) == SSL_R_HTTP_REQUEST) { | 138 if (ERR_GET_REASON(ERR_peek_error()) == SSL_R_HTTP_REQUEST) { |
145 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | 139 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
146 "client sent plain HTTP request to HTTPS port"); | 140 "client sent plain HTTP request to HTTPS port"); |
147 | 141 |
148 SSL_set_shutdown(ctx->ssl, | 142 SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN); |
149 SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN); | |
150 | 143 |
151 return NGX_SSL_HTTP_ERROR; | 144 return NGX_SSL_HTTP_ERROR; |
152 } | 145 } |
153 | 146 |
154 ngx_http_ssl_error(NGX_LOG_ALERT, r->connection->log, rc, | 147 ngx_http_ssl_error(NGX_LOG_ALERT, r->connection->log, n, |
155 "SSL_read() failed"); | 148 "SSL_read() failed"); |
156 | 149 |
157 SSL_set_shutdown(ctx->ssl, SSL_RECEIVED_SHUTDOWN); | 150 SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN); |
158 | 151 |
159 return NGX_SSL_ERROR; | 152 return NGX_SSL_ERROR; |
160 } | 153 } |
161 | 154 |
162 | 155 |
163 ngx_int_t ngx_http_ssl_writer(ngx_http_request_t *r, ngx_chain_t *in) | 156 ngx_chain_t *ngx_http_ssl_write(ngx_connection_t *c, ngx_chain_t *in, |
164 { | 157 off_t limit) |
165 ngx_http_ssl_ctx_t *ctx; | 158 { |
166 | 159 int n; |
167 ctx = ngx_http_get_module_ctx(r, ngx_http_ssl_filter_module); | 160 ssize_t send, size; |
168 | |
169 if (in == NULL) { | |
170 rc = SSL_shutdown(ctx->ssl); | |
171 | |
172 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
173 "SSL_shutdown: %d", rc); | |
174 | |
175 if (rc == 0) { | |
176 return NGX_AGAIN; | |
177 } | |
178 | |
179 if (rc == 1) { | |
180 SSL_free(ctx->ssl); | |
181 return NGX_OK; | |
182 } | |
183 | |
184 rc = SSL_get_error(ctx->ssl, rc); | |
185 | |
186 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
187 "SSL_get_error: %d", rc); | |
188 | |
189 if (rc == SSL_ERROR_WANT_WRITE) { | |
190 return NGX_AGAIN; | |
191 } | |
192 | |
193 ngx_http_ssl_error(NGX_LOG_ALERT, r->connection->log, rc, | |
194 "SSL_shutdown() failed"); | |
195 | |
196 return NGX_ERROR; | |
197 } | |
198 | |
199 ch = ngx_http_ssl_write(r, ctx, in, 0); | |
200 | |
201 return NGX_OK; | |
202 } | |
203 | |
204 | |
205 static ngx_chain_t *ngx_http_ssl_write(ngx_http_request_t *r, | |
206 ngx_http_ssl_ctx_t *ctx, | |
207 ngx_chain_t *in, | |
208 off_t limit) | |
209 { | |
210 int rc; | |
211 size_t send, size; | |
212 | |
213 ctx = ngx_http_get_module_ctx(r, ngx_http_ssl_filter_module); | |
214 | 161 |
215 send = 0; | 162 send = 0; |
216 | 163 |
217 for (/* void */; in; in = in->next) { | 164 for (/* void */; in; in = in->next) { |
218 if (ngx_buf_special(in->buf)) { | 165 if (ngx_buf_special(in->buf)) { |
223 | 170 |
224 if (send + size > limit) { | 171 if (send + size > limit) { |
225 size = limit - send; | 172 size = limit - send; |
226 } | 173 } |
227 | 174 |
228 rc = SSL_write(ctx->ssl, in->buf->pos, size); | 175 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "SSL to write: %d", size); |
229 | 176 |
230 if (rc > 0) { | 177 n = SSL_write(c->ssl, in->buf->pos, size); |
231 in->buf->pos += rc; | 178 |
232 | 179 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "SSL_write: %d", n); |
233 if (rc == size) { | 180 |
234 continue; | 181 if (n > 0) { |
182 in->buf->pos += n; | |
183 send += n; | |
184 | |
185 if (n == size) { | |
186 if (send < limit) { | |
187 continue; | |
188 } | |
189 | |
190 return in; | |
235 } | 191 } |
236 | 192 |
237 r->connection->write->ready = 0; | 193 c->write->ready = 0; |
238 return in; | 194 return in; |
239 } | 195 } |
196 | |
197 n = SSL_get_error(c->ssl, n); | |
198 | |
199 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "SSL_get_error: %d", n); | |
200 | |
201 if (n == SSL_ERROR_WANT_WRITE) { | |
202 c->write->ready = 0; | |
203 return in; | |
204 } | |
205 | |
206 ngx_http_ssl_error(NGX_LOG_ALERT, c->log, n, "SSL_write() failed"); | |
207 | |
208 return NGX_CHAIN_ERROR; | |
240 } | 209 } |
241 | 210 |
242 return in; | 211 return in; |
243 } | 212 } |
244 | 213 |
245 | 214 |
246 static ngx_http_ssl_ctx_t *ngx_http_ssl_create_ctx(ngx_http_request_t *r) | 215 ngx_int_t ngx_http_ssl_shutdown(ngx_http_request_t *r) |
247 { | 216 { |
248 ngx_http_ssl_ctx_t *ctx; | 217 int n; |
218 SSL *ssl; | |
219 | |
220 ssl = r->connection->ssl; | |
221 | |
222 n = SSL_shutdown(ssl); | |
223 | |
224 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
225 "SSL_shutdown: %d", n); | |
226 | |
227 if (n == 0) { | |
228 return NGX_AGAIN; | |
229 } | |
230 | |
231 if (n == 1) { | |
232 SSL_free(ssl); | |
233 r->connection->ssl = NULL; | |
234 return NGX_OK; | |
235 } | |
236 | |
237 n = SSL_get_error(ssl, n); | |
238 | |
239 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
240 "SSL_get_error: %d", n); | |
241 | |
242 if (n == SSL_ERROR_WANT_WRITE) { | |
243 return NGX_AGAIN; | |
244 } | |
245 | |
246 ngx_http_ssl_error(NGX_LOG_ALERT, r->connection->log, n, | |
247 "SSL_shutdown() failed"); | |
248 | |
249 return NGX_ERROR; | |
250 } | |
251 | |
252 | |
253 static ngx_int_t ngx_http_ssl_create_ssl(ngx_http_request_t *r) | |
254 { | |
255 SSL *ssl; | |
249 ngx_http_ssl_srv_conf_t *scf; | 256 ngx_http_ssl_srv_conf_t *scf; |
250 | 257 |
251 ngx_http_create_ctx(r, ctx, ngx_http_ssl_filter_module, | |
252 sizeof(ngx_http_ssl_ctx_t), NULL); | |
253 | |
254 scf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_filter_module); | 258 scf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_filter_module); |
255 | 259 |
256 ctx->ssl = SSL_new(scf->ssl_ctx); | 260 ssl = SSL_new(scf->ssl_ctx); |
257 | 261 |
258 if (ctx->ssl == NULL) { | 262 if (ssl == NULL) { |
259 ngx_http_ssl_error(NGX_LOG_ALERT, r->connection->log, 0, | 263 ngx_http_ssl_error(NGX_LOG_ALERT, r->connection->log, 0, |
260 "SSL_new() failed"); | 264 "SSL_new() failed"); |
261 return NULL; | 265 return NGX_ERROR; |
262 } | 266 } |
263 | 267 |
264 if (SSL_set_fd(ctx->ssl, r->connection->fd) == 0) { | 268 if (SSL_set_fd(ssl, r->connection->fd) == 0) { |
265 ngx_http_ssl_error(NGX_LOG_ALERT, r->connection->log, 0, | 269 ngx_http_ssl_error(NGX_LOG_ALERT, r->connection->log, 0, |
266 "SSL_set_fd() failed"); | 270 "SSL_set_fd() failed"); |
267 return NULL; | 271 return NGX_ERROR; |
268 } | 272 } |
269 | 273 |
270 SSL_set_accept_state(ctx->ssl); | 274 SSL_set_accept_state(ssl); |
271 | 275 |
272 return ctx; | 276 r->connection->ssl = ssl; |
277 | |
278 return NGX_OK; | |
273 } | 279 } |
274 | 280 |
275 | 281 |
276 void ngx_http_ssl_close_connection(SSL *ssl, ngx_log_t *log) | 282 void ngx_http_ssl_close_connection(SSL *ssl, ngx_log_t *log) |
277 { | 283 { |