Mercurial > hg > nginx
comparison src/event/ngx_event_openssl.c @ 395:f8f0f1834266
nginx-0.0.7-2004-07-16-21:11:43 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Fri, 16 Jul 2004 17:11:43 +0000 |
parents | e7a68e14ccd3 |
children | 6f3b20c1ac50 |
comparison
equal
deleted
inserted
replaced
394:e7a68e14ccd3 | 395:f8f0f1834266 |
---|---|
11 | 11 |
12 return NGX_OK; | 12 return NGX_OK; |
13 } | 13 } |
14 | 14 |
15 | 15 |
16 ngx_int_t ngx_ssl_create_session(ngx_ssl_ctx_t *ssl_ctx, ngx_connection_t *c) | 16 ngx_int_t ngx_ssl_create_session(ngx_ssl_ctx_t *ssl_ctx, ngx_connection_t *c, |
17 ngx_uint_t flags) | |
17 { | 18 { |
18 ngx_ssl_t *ssl; | 19 ngx_ssl_t *ssl; |
19 | 20 |
20 ssl = SSL_new(ssl_ctx); | 21 if (!(ssl = ngx_pcalloc(c->pool, sizeof(ngx_ssl_t)))) { |
21 | |
22 if (ssl == NULL) { | |
23 ngx_ssl_error(NGX_LOG_ALERT, c->log, "SSL_new() failed"); | |
24 return NGX_ERROR; | 22 return NGX_ERROR; |
25 } | 23 } |
26 | 24 |
27 if (SSL_set_fd(ssl, c->fd) == 0) { | 25 if (flags & NGX_SSL_BUFFER) { |
28 ngx_ssl_error(NGX_LOG_ALERT, c->log, "SSL_set_fd() failed"); | 26 if (!(ssl->buf = ngx_create_temp_buf(c->pool, NGX_SSL_BUFSIZE))) { |
27 return NGX_ERROR; | |
28 } | |
29 } | |
30 | |
31 ssl->ssl = SSL_new(ssl_ctx); | |
32 | |
33 if (ssl->ssl == NULL) { | |
34 ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_new() failed"); | |
29 return NGX_ERROR; | 35 return NGX_ERROR; |
30 } | 36 } |
31 | 37 |
32 SSL_set_accept_state(ssl); | 38 if (SSL_set_fd(ssl->ssl, c->fd) == 0) { |
39 ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_set_fd() failed"); | |
40 return NGX_ERROR; | |
41 } | |
42 | |
43 SSL_set_accept_state(ssl->ssl); | |
33 | 44 |
34 c->ssl = ssl; | 45 c->ssl = ssl; |
35 | 46 |
36 return NGX_OK; | 47 return NGX_OK; |
37 } | 48 } |
38 | 49 |
39 | 50 |
40 ngx_int_t ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size) | 51 ngx_int_t ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size) |
41 { | 52 { |
42 int n; | 53 int n, sslerr; |
54 ngx_err_t err; | |
43 char *handshake; | 55 char *handshake; |
44 | 56 |
45 n = SSL_read(c->ssl, buf, size); | 57 n = SSL_read(c->ssl->ssl, buf, size); |
46 | 58 |
47 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_read: %d", n); | 59 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_read: %d", n); |
48 | 60 |
49 if (n > 0) { | 61 if (n > 0) { |
50 return n; | 62 return n; |
51 } | 63 } |
52 | 64 |
53 n = SSL_get_error(c->ssl, n); | 65 sslerr = SSL_get_error(c->ssl->ssl, n); |
54 | 66 |
55 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", n); | 67 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr); |
56 | 68 |
57 if (n == SSL_ERROR_WANT_READ) { | 69 err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0; |
70 | |
71 if (sslerr == SSL_ERROR_WANT_READ) { | |
58 return NGX_AGAIN; | 72 return NGX_AGAIN; |
59 } | 73 } |
60 | 74 |
61 #if 0 | 75 #if 0 |
62 if (n == SSL_ERROR_WANT_WRITE) { | 76 if (sslerr == SSL_ERROR_WANT_WRITE) { |
63 return NGX_AGAIN; | 77 return NGX_AGAIN; |
64 } | 78 } |
65 #endif | 79 #endif |
66 | 80 |
67 if (!SSL_is_init_finished(c->ssl)) { | 81 if (!SSL_is_init_finished(c->ssl->ssl)) { |
68 handshake = "in SSL handshake"; | 82 handshake = "in SSL handshake"; |
69 | 83 |
70 } else { | 84 } else { |
71 handshake = ""; | 85 handshake = ""; |
72 } | 86 } |
73 | 87 |
74 if (n == SSL_ERROR_ZERO_RETURN) { | 88 if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) { |
75 ngx_log_error(NGX_LOG_INFO, c->log, 0, | 89 ngx_log_error(NGX_LOG_INFO, c->log, err, |
76 "client closed connection%s", handshake); | 90 "client closed connection%s", handshake); |
77 | 91 |
78 SSL_set_shutdown(c->ssl, SSL_RECEIVED_SHUTDOWN); | 92 SSL_set_shutdown(c->ssl->ssl, SSL_RECEIVED_SHUTDOWN); |
79 | 93 |
80 return NGX_ERROR; | 94 return NGX_ERROR; |
81 } | 95 } |
82 | 96 |
83 if (ERR_GET_REASON(ERR_peek_error()) == SSL_R_HTTP_REQUEST) { | 97 ngx_ssl_error(NGX_LOG_ALERT, c->log, err, |
84 ngx_log_error(NGX_LOG_ERR, c->log, 0, | 98 "SSL_read() failed%s", handshake); |
85 "client sent plain HTTP request to HTTPS port"); | 99 |
86 | 100 SSL_set_shutdown(c->ssl->ssl, SSL_RECEIVED_SHUTDOWN); |
87 SSL_set_shutdown(c->ssl, SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN); | |
88 | |
89 return NGX_SSL_HTTP_ERROR; | |
90 } | |
91 | |
92 ngx_ssl_error(NGX_LOG_ALERT, c->log, "SSL_read() failed%s", handshake); | |
93 | |
94 SSL_set_shutdown(c->ssl, SSL_RECEIVED_SHUTDOWN); | |
95 | 101 |
96 return NGX_ERROR; | 102 return NGX_ERROR; |
97 } | 103 } |
98 | 104 |
99 | 105 |
100 ngx_chain_t *ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, | 106 ngx_chain_t *ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, |
101 off_t limit) | 107 off_t limit) |
102 { | 108 { |
103 int n; | 109 int n; |
104 ssize_t send, size; | 110 ssize_t send, size; |
111 ngx_buf_t *buf; | |
105 | 112 |
106 send = 0; | 113 send = 0; |
114 | |
115 buf = c->ssl->buf; | |
116 | |
117 #if 0 | |
118 | |
119 if (buf) { | |
120 | |
121 for ( ;; ) { | |
122 | |
123 for ( /* void */ ; in && buf->last < buf->end; in = in->next) { | |
124 if (ngx_buf_special(in->buf)) { | |
125 continue; | |
126 } | |
127 | |
128 size = in->buf->last - in->buf->pos; | |
129 | |
130 if (size > buf->end - buf->last) { | |
131 size = buf->end - buf->last; | |
132 } | |
133 | |
134 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
135 "SSL buf copy: %d", size); | |
136 | |
137 ngx_memcpy(buf->last, in->buf->pos, size); | |
138 | |
139 buf->last += size; | |
140 in->buf->pos += size; | |
141 } | |
142 | |
143 size = buf->last - buf->pos; | |
144 | |
145 if (send + size > limit) { | |
146 size = limit - send; | |
147 } | |
148 | |
149 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
150 "SSL to write: %d", size); | |
151 | |
152 n = SSL_write(c->ssl->ssl, buf->pos, size); | |
153 | |
154 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
155 "SSL_write: %d", n); | |
156 | |
157 if (n > 0) { | |
158 buf->pos += n; | |
159 send += n; | |
160 | |
161 if (n < size) { | |
162 break; | |
163 } | |
164 | |
165 if (send < limit) { | |
166 if (buf->pos == buf->last) { | |
167 buf->pos = buf->start; | |
168 buf->last = buf->start; | |
169 } | |
170 | |
171 if (in == NULL) { | |
172 break; | |
173 } | |
174 | |
175 continue; | |
176 } | |
177 } | |
178 | |
179 n = SSL_get_error(c->ssl->ssl, n); | |
180 | |
181 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
182 "SSL_get_error: %d", n); | |
183 | |
184 if (n == SSL_ERROR_WANT_WRITE) { | |
185 break; | |
186 } | |
187 | |
188 #if 0 | |
189 if (n == SSL_ERROR_WANT_READ) { | |
190 break; | |
191 } | |
192 #endif | |
193 | |
194 ngx_ssl_error(NGX_LOG_ALERT, c->log, "SSL_write() failed"); | |
195 | |
196 return NGX_CHAIN_ERROR; | |
197 } | |
198 | |
199 if (in) { | |
200 c->write->ready = 0; | |
201 return in; | |
202 } | |
203 | |
204 if (buf->pos == buf->last) { | |
205 return NULL; | |
206 | |
207 } else { | |
208 c->write->ready = 0; | |
209 return NGX_CHAIN_AGAIN; | |
210 } | |
211 } | |
212 | |
213 #endif | |
107 | 214 |
108 for (/* void */; in; in = in->next) { | 215 for (/* void */; in; in = in->next) { |
109 if (ngx_buf_special(in->buf)) { | 216 if (ngx_buf_special(in->buf)) { |
110 continue; | 217 continue; |
111 } | 218 } |
117 } | 224 } |
118 | 225 |
119 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, | 226 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, |
120 "SSL to write: %d", size); | 227 "SSL to write: %d", size); |
121 | 228 |
122 n = SSL_write(c->ssl, in->buf->pos, size); | 229 n = SSL_write(c->ssl->ssl, in->buf->pos, size); |
123 | 230 |
124 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_write: %d", n); | 231 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_write: %d", n); |
125 | 232 |
126 if (n > 0) { | 233 if (n > 0) { |
127 in->buf->pos += n; | 234 in->buf->pos += n; |
137 | 244 |
138 c->write->ready = 0; | 245 c->write->ready = 0; |
139 return in; | 246 return in; |
140 } | 247 } |
141 | 248 |
142 n = SSL_get_error(c->ssl, n); | 249 n = SSL_get_error(c->ssl->ssl, n); |
143 | 250 |
144 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", n); | 251 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", n); |
145 | 252 |
146 if (n == SSL_ERROR_WANT_WRITE) { | 253 if (n == SSL_ERROR_WANT_WRITE) { |
147 c->write->ready = 0; | 254 c->write->ready = 0; |
152 if (n == SSL_ERROR_WANT_READ) { | 259 if (n == SSL_ERROR_WANT_READ) { |
153 return NGX_AGAIN; | 260 return NGX_AGAIN; |
154 } | 261 } |
155 #endif | 262 #endif |
156 | 263 |
157 ngx_ssl_error(NGX_LOG_ALERT, c->log, "SSL_write() failed"); | 264 ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_write() failed"); |
158 | 265 |
159 return NGX_CHAIN_ERROR; | 266 return NGX_CHAIN_ERROR; |
160 } | 267 } |
161 | 268 |
162 return in; | 269 return in; |
174 SSL_set_shutdown(c->ssl, SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN); | 281 SSL_set_shutdown(c->ssl, SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN); |
175 } | 282 } |
176 #endif | 283 #endif |
177 | 284 |
178 #if 0 | 285 #if 0 |
179 SSL_set_shutdown(c->ssl, SSL_RECEIVED_SHUTDOWN); | 286 SSL_set_shutdown(c->ssl->ssl, SSL_RECEIVED_SHUTDOWN); |
180 #endif | 287 #endif |
181 | 288 |
182 again = 0; | 289 again = 0; |
183 | 290 |
184 for ( ;; ) { | 291 for ( ;; ) { |
185 n = SSL_shutdown(c->ssl); | 292 n = SSL_shutdown(c->ssl->ssl); |
186 | 293 |
187 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n); | 294 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n); |
188 | 295 |
189 if (n == 0) { | 296 if (n == 0) { |
190 again = 1; | 297 again = 1; |
191 break; | 298 break; |
192 } | 299 } |
193 | 300 |
194 if (n == 1) { | 301 if (n == 1) { |
195 SSL_free(c->ssl); | 302 SSL_free(c->ssl->ssl); |
196 c->ssl = NULL; | 303 c->ssl = NULL; |
197 return NGX_OK; | 304 return NGX_OK; |
198 } | 305 } |
199 | 306 |
200 break; | 307 break; |
201 } | 308 } |
202 | 309 |
203 if (!again) { | 310 if (!again) { |
204 n = SSL_get_error(c->ssl, n); | 311 n = SSL_get_error(c->ssl->ssl, n); |
205 | 312 |
206 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", n); | 313 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", n); |
207 } | 314 } |
208 | 315 |
209 if (again || n == SSL_ERROR_WANT_READ) { | 316 if (again || n == SSL_ERROR_WANT_READ) { |
224 } | 331 } |
225 | 332 |
226 return NGX_AGAIN; | 333 return NGX_AGAIN; |
227 } | 334 } |
228 | 335 |
229 ngx_ssl_error(NGX_LOG_ALERT, c->log, "SSL_shutdown() failed"); | 336 ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_shutdown() failed"); |
230 | 337 |
231 return NGX_ERROR; | 338 return NGX_ERROR; |
232 } | 339 } |
233 | 340 |
234 | 341 |
235 void ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, char *fmt, ...) | 342 void ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, |
343 char *fmt, ...) | |
236 { | 344 { |
237 int len; | 345 int len; |
238 char errstr[NGX_MAX_CONF_ERRSTR]; | 346 char errstr[NGX_MAX_CONF_ERRSTR]; |
239 va_list args; | 347 va_list args; |
240 | 348 |
241 va_start(args, fmt); | 349 va_start(args, fmt); |
242 len = ngx_vsnprintf(errstr, sizeof(errstr) - 1, fmt, args); | 350 len = ngx_vsnprintf(errstr, sizeof(errstr) - 1, fmt, args); |
243 va_end(args); | 351 va_end(args); |
244 | 352 |
250 errstr[len++] = ':'; | 358 errstr[len++] = ':'; |
251 errstr[len++] = ' '; | 359 errstr[len++] = ' '; |
252 | 360 |
253 ERR_error_string_n(ERR_get_error(), errstr + len, sizeof(errstr) - len - 1); | 361 ERR_error_string_n(ERR_get_error(), errstr + len, sizeof(errstr) - len - 1); |
254 | 362 |
255 ngx_log_error(level, log, 0, "%s)", errstr); | 363 ngx_log_error(level, log, err, "%s)", errstr); |
256 } | 364 } |