# HG changeset patch # User Igor Sysoev # Date 1128024000 -14400 # Node ID ca4f70b3ccc69ca8333d07bfee0dc6a8b0185719 # Parent 2f95911bc4b48306dce92d44b60823708052ea6a nginx 0.2.2 *) Feature: the "config errmsg" command of the ngx_http_ssi_module. *) Change: the ngx_http_geo_module variables can be overridden by the "set" directive. *) Feature: the "ssl_protocols" and "ssl_prefer_server_ciphers" directives of the ngx_http_ssl_module and ngx_imap_ssl_module. *) Bugfix: the ngx_http_autoindex_module did not show correctly the long file names; *) Bugfix: the ngx_http_autoindex_module now do not show the files starting by dot. *) Bugfix: if the SSL handshake failed then another connection may be closed too. Thanks to Rob Mueller. *) Bugfix: the export versions of MSIE 5.x could not connect via HTTPS. diff --git a/CHANGES b/CHANGES --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,25 @@ + +Changes with nginx 0.2.2 30 Sep 2005 + + *) Feature: the "config errmsg" command of the ngx_http_ssi_module. + + *) Change: the ngx_http_geo_module variables can be overridden by the + "set" directive. + + *) Feature: the "ssl_protocols" and "ssl_prefer_server_ciphers" + directives of the ngx_http_ssl_module and ngx_imap_ssl_module. + + *) Bugfix: the ngx_http_autoindex_module did not show correctly the + long file names; + + *) Bugfix: the ngx_http_autoindex_module now do not show the files + starting by dot. + + *) Bugfix: if the SSL handshake failed then another connection may be + closed too. Thanks to Rob Mueller. + + *) Bugfix: the export versions of MSIE 5.x could not connect via HTTPS. + Changes with nginx 0.2.1 23 Sep 2005 @@ -33,7 +55,7 @@ Changes with nginx 0.2.0 *) Bugfix: if all backend using in load-balancing failed after one error, then nginx did not try do connect to them during 60 seconds. - *) Bugfix: in IMAP/POP3 command argument parsing. + *) Bugfix: in IMAP/POP3 command argument parsing. Thanks to Rob Mueller. *) Bugfix: errors while using SSL in IMAP/POP3 proxy. diff --git a/CHANGES.ru b/CHANGES.ru --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,3 +1,26 @@ + +Изменения в nginx 0.2.2 30.09.2005 + + *) Добавление: команда config errmsg в модуле ngx_http_ssi_module. + + *) Изменение: переменные модуля ngx_http_geo_module можно + переопределять директивой set. + + *) Добавление: директивы ssl_protocols и ssl_prefer_server_ciphers + модулей ngx_http_ssl_module и ngx_imap_ssl_module. + + *) Исправление: ошибка в модуле ngx_http_autoindex_module при показе + длинных имён файлов; + + *) Исправление: модуль ngx_http_autoindex_module теперь не показывает + файлы, начинающиеся на точку. + + *) Исправление: если SSL handshake завершался с ошибкой, то это могло + привести также в закрытию другого соединения. Спасибо Rob Mueller. + + *) Исправление: экспортные версии MSIE 5.x не могли соединиться по + HTTPS. + Изменения в nginx 0.2.1 23.09.2005 @@ -15,8 +38,8 @@ обычный pid-файл без суффикса ".newbin". Если новый основной процесс выходит, то старый процесс переименовывает свой pid-файл c суффиксом ".oldbin" в pid-файл без суффикса. При обновлении с версии 0.1.х до - 0.2.0 нужно учитывать, что старый процесс 0.1.x и новый процесс - 0.2.0 оба используют pid-файл без суффиксов. + 0.2.0 нужно учитывать, что оба процесса - старый 0.1.x и новый + 0.2.0 - используют pid-файл без суффиксов. *) Изменение: директива worker_connections, новое название директивы connections; директива теперь задаёт максимальное число соединений, diff --git a/src/core/nginx.h b/src/core/nginx.h --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -8,7 +8,7 @@ #define _NGINX_H_INCLUDED_ -#define NGINX_VER "nginx/0.2.1" +#define NGINX_VER "nginx/0.2.2" #define NGINX_VAR "NGINX" #define NGX_OLDPID_EXT ".oldbin" diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h --- a/src/core/ngx_connection.h +++ b/src/core/ngx_connection.h @@ -28,7 +28,7 @@ struct ngx_listening_s { int backlog; /* handler of accepted connection */ - void (*handler)(ngx_connection_t *c); + ngx_connection_handler_pt handler; void *ctx; /* ngx_http_conf_ctx_t, for example */ void *servers; /* array of ngx_http_in_addr_t, for example */ @@ -118,7 +118,7 @@ struct ngx_connection_s { ngx_str_t addr_text; #if (NGX_OPENSSL) - ngx_ssl_t *ssl; + ngx_ssl_connection_t *ssl; #endif #if (NGX_HAVE_IOCP) diff --git a/src/core/ngx_core.h b/src/core/ngx_core.h --- a/src/core/ngx_core.h +++ b/src/core/ngx_core.h @@ -23,7 +23,7 @@ typedef struct ngx_peers_s ngx_pee typedef struct ngx_connection_s ngx_connection_t; typedef void (*ngx_event_handler_pt)(ngx_event_t *ev); - +typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c); #define NGX_OK 0 diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -14,9 +14,12 @@ typedef struct { } ngx_openssl_conf_t; +static void ngx_ssl_handshake_handler(ngx_event_t *ev); static ngx_int_t ngx_ssl_handle_recv(ngx_connection_t *c, int n); static void ngx_ssl_write_handler(ngx_event_t *wev); static void ngx_ssl_read_handler(ngx_event_t *rev); +static void ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, + ngx_err_t err, char *text); static void *ngx_openssl_create_conf(ngx_cycle_t *cycle); static char *ngx_openssl_init_conf(ngx_cycle_t *cycle, void *conf); @@ -63,7 +66,19 @@ ngx_module_t ngx_openssl_module = { NULL, /* exit process */ NULL, /* exit master */ NGX_MODULE_V1_PADDING -}; +}; + + +static long ngx_ssl_protocols[] = { + SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1, + SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1, + SSL_OP_NO_SSLv2|SSL_OP_NO_TLSv1, + SSL_OP_NO_TLSv1, + SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3, + SSL_OP_NO_SSLv3, + SSL_OP_NO_SSLv2, + 0, +}; ngx_int_t @@ -81,45 +96,241 @@ ngx_ssl_init(ngx_log_t *log) ngx_int_t -ngx_ssl_create_connection(ngx_ssl_ctx_t *ssl_ctx, ngx_connection_t *c, - ngx_uint_t flags) +ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols) +{ + ssl->ctx = SSL_CTX_new(SSLv23_server_method()); + + if (ssl->ctx == NULL) { + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "SSL_CTX_new() failed"); + return NGX_ERROR; + } + + SSL_CTX_set_options(ssl->ctx, SSL_OP_ALL); + + if (ngx_ssl_protocols[protocols >> 1] != 0) { + SSL_CTX_set_options(ssl->ctx, ngx_ssl_protocols[protocols >> 1]); + } + + SSL_CTX_set_mode(ssl->ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); + + SSL_CTX_set_read_ahead(ssl->ctx, 1); + + return NGX_OK; +} + + +ngx_int_t +ngx_ssl_certificate(ngx_ssl_t *ssl, u_char *cert, u_char *key) +{ + if (SSL_CTX_use_certificate_chain_file(ssl->ctx, (char *) cert) == 0) { + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, + "SSL_CTX_use_certificate_chain_file(\"%s\") failed", + cert); + return NGX_ERROR; + } + + if (SSL_CTX_use_PrivateKey_file(ssl->ctx, (char *) key, SSL_FILETYPE_PEM) + == 0) + { + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, + "SSL_CTX_use_PrivateKey_file(\"%s\") failed", key); + return NGX_ERROR; + } + + return NGX_OK; +} + + +ngx_int_t +ngx_ssl_generate_rsa512_key(ngx_ssl_t *ssl) +{ + ssl->rsa512_key = RSA_generate_key(512, RSA_F4, NULL, NULL); + + if (ssl->rsa512_key) { + SSL_CTX_set_tmp_rsa(ssl->ctx, ssl->rsa512_key); + return NGX_OK; + } + + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "RSA_generate_key(512) failed"); + + return NGX_ERROR; +} + + +ngx_int_t +ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c, ngx_uint_t flags) { - ngx_ssl_t *ssl; + ngx_ssl_connection_t *sc; - ssl = ngx_pcalloc(c->pool, sizeof(ngx_ssl_t)); - if (ssl == NULL) { + sc = ngx_pcalloc(c->pool, sizeof(ngx_ssl_connection_t)); + if (sc == NULL) { return NGX_ERROR; } if (flags & NGX_SSL_BUFFER) { - ssl->buffer = 1; + sc->buffer = 1; - ssl->buf = ngx_create_temp_buf(c->pool, NGX_SSL_BUFSIZE); - if (ssl->buf == NULL) { + sc->buf = ngx_create_temp_buf(c->pool, NGX_SSL_BUFSIZE); + if (sc->buf == NULL) { return NGX_ERROR; } } - ssl->connection = SSL_new(ssl_ctx); + sc->connection = SSL_new(ssl->ctx); - if (ssl->connection == NULL) { + if (sc->connection == NULL) { ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_new() failed"); return NGX_ERROR; } - if (SSL_set_fd(ssl->connection, c->fd) == 0) { + if (SSL_set_fd(sc->connection, c->fd) == 0) { ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_set_fd() failed"); return NGX_ERROR; } - SSL_set_accept_state(ssl->connection); + SSL_set_accept_state(sc->connection); - c->ssl = ssl; + c->ssl = sc; return NGX_OK; } +ngx_int_t +ngx_ssl_handshake(ngx_connection_t *c) +{ + int n, sslerr; + ngx_err_t err; + + n = SSL_do_handshake(c->ssl->connection); + + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_do_handshake: %d", n); + + if (n == 1) { + + if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) { + return NGX_ERROR; + } + + if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) { + return NGX_ERROR; + } + +#if (NGX_DEBUG) + { + char buf[129], *s, *d; + SSL_CIPHER *cipher; + + cipher = SSL_get_current_cipher(c->ssl->connection); + + if (cipher) { + SSL_CIPHER_description(cipher, &buf[1], 128); + + for (s = &buf[1], d = buf; *s; s++) { + if (*s == ' ' && *d == ' ') { + continue; + } + + if (*s == LF || *s == CR) { + continue; + } + + *++d = *s; + } + + if (*d != ' ') { + d++; + } + + *d = '\0'; + + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, + "SSL: %s, cipher: \"%s\"", + SSL_get_version(c->ssl->connection), &buf[1]); + + if (SSL_session_reused(c->ssl->connection)) { + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, + "SSL reused session"); + } + + } else { + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, + "SSL no shared ciphers"); + } + } +#endif + + c->ssl->handshaked = 1; + + c->recv = ngx_ssl_recv; + c->send = ngx_ssl_write; + c->send_chain = ngx_ssl_send_chain; + + return NGX_OK; + } + + sslerr = SSL_get_error(c->ssl->connection, n); + + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr); + + if (sslerr == SSL_ERROR_WANT_READ) { + c->read->ready = 0; + c->read->handler = ngx_ssl_handshake_handler; + + if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) { + return NGX_ERROR; + } + + return NGX_AGAIN; + } + + if (sslerr == SSL_ERROR_WANT_WRITE) { + c->write->ready = 0; + c->write->handler = ngx_ssl_handshake_handler; + + if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) { + return NGX_ERROR; + } + + return NGX_AGAIN; + } + + err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0; + + c->ssl->no_wait_shutdown = 1; + c->ssl->no_send_shutdown = 1; + + if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) { + ngx_log_error(NGX_LOG_INFO, c->log, err, + "client closed connection in SSL handshake"); + + return NGX_ERROR; + } + + ngx_ssl_connection_error(c, sslerr, err, "SSL_do_handshake() failed"); + + return NGX_ERROR; +} + + +static void +ngx_ssl_handshake_handler(ngx_event_t *ev) +{ + ngx_connection_t *c; + + c = ev->data; + + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, + "ssl handshake handler: %d", ev->write); + + if (ngx_ssl_handshake(c) == NGX_AGAIN) { + return; + } + + c->ssl->handler(c); +} + + ssize_t ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size) { @@ -143,56 +354,7 @@ ngx_ssl_recv(ngx_connection_t *c, u_char ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_read: %d", n); if (n > 0) { - bytes += n; - -#if (NGX_DEBUG) - - if (!c->ssl->handshaked && SSL_is_init_finished(c->ssl->connection)) - { - char buf[129], *s, *d; - SSL_CIPHER *cipher; - - c->ssl->handshaked = 1; - - cipher = SSL_get_current_cipher(c->ssl->connection); - - if (cipher) { - SSL_CIPHER_description(cipher, &buf[1], 128); - - for (s = &buf[1], d = buf; *s; s++) { - if (*s == ' ' && *d == ' ') { - continue; - } - - if (*s == LF || *s == CR) { - continue; - } - - *++d = *s; - } - - if (*d != ' ') { - d++; - } - - *d = '\0'; - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, - "SSL cipher: \"%s\"", &buf[1]); - - if (SSL_session_reused(c->ssl->connection)) { - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, - "SSL reused session"); - } - - } else { - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, - "SSL no shared ciphers"); - } - } -#endif - } c->ssl->last = ngx_ssl_handle_recv(c, n); @@ -221,10 +383,8 @@ ngx_ssl_recv(ngx_connection_t *c, u_char static ngx_int_t ngx_ssl_handle_recv(ngx_connection_t *c, int n) { - int sslerr; - char *handshake; - ngx_err_t err; - ngx_uint_t level; + int sslerr; + ngx_err_t err; if (n > 0) { @@ -250,13 +410,6 @@ ngx_ssl_handle_recv(ngx_connection_t *c, return NGX_OK; } - if (!SSL_is_init_finished(c->ssl->connection)) { - handshake = " in SSL handshake"; - - } else { - handshake = ""; - } - sslerr = SSL_get_error(c->ssl->connection, n); err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0; @@ -270,9 +423,8 @@ ngx_ssl_handle_recv(ngx_connection_t *c, if (sslerr == SSL_ERROR_WANT_WRITE) { - ngx_log_error(NGX_LOG_INFO, c->log, err, - "client does SSL %shandshake", - SSL_is_init_finished(c->ssl->connection) ? "re" : ""); + ngx_log_error(NGX_LOG_INFO, c->log, 0, + "client started SSL renegotiation"); c->write->ready = 0; @@ -292,44 +444,16 @@ ngx_ssl_handle_recv(ngx_connection_t *c, return NGX_AGAIN; } - c->ssl->no_rcv_shut = 1; - c->ssl->no_send_shut = 1; + c->ssl->no_wait_shutdown = 1; + c->ssl->no_send_shutdown = 1; if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) { - ngx_log_error(NGX_LOG_INFO, c->log, err, - "client closed connection%s", handshake); + ngx_log_error(NGX_LOG_INFO, c->log, err, "client closed connection"); return NGX_ERROR; } - level = NGX_LOG_CRIT; - - if (sslerr == SSL_ERROR_SYSCALL) { - - if (err == NGX_ECONNRESET - || err == NGX_EPIPE - || err == NGX_ENOTCONN - || err == NGX_ECONNREFUSED - || err == NGX_EHOSTUNREACH) - { - switch (c->log_error) { - - case NGX_ERROR_IGNORE_ECONNRESET: - case NGX_ERROR_INFO: - level = NGX_LOG_INFO; - break; - - case NGX_ERROR_ERR: - level = NGX_LOG_ERR; - break; - - default: - break; - } - } - } - - ngx_ssl_error(level, c->log, err, "SSL_read() failed%s", handshake); + ngx_ssl_connection_error(c, sslerr, err, "SSL_read() failed"); return NGX_ERROR; } @@ -341,6 +465,7 @@ ngx_ssl_write_handler(ngx_event_t *wev) ngx_connection_t *c; c = wev->data; + c->read->handler(c->read); } @@ -482,9 +607,8 @@ ngx_ssl_send_chain(ngx_connection_t *c, ssize_t ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size) { - int n, sslerr; - ngx_err_t err; - ngx_uint_t level; + int n, sslerr; + ngx_err_t err; ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL to write: %d", size); @@ -494,52 +618,6 @@ ngx_ssl_write(ngx_connection_t *c, u_cha if (n > 0) { -#if (NGX_DEBUG) - - if (!c->ssl->handshaked && SSL_is_init_finished(c->ssl->connection)) { - char buf[129], *s, *d; - SSL_CIPHER *cipher; - - c->ssl->handshaked = 1; - - cipher = SSL_get_current_cipher(c->ssl->connection); - - if (cipher) { - SSL_CIPHER_description(cipher, &buf[1], 128); - - for (s = &buf[1], d = buf; *s; s++) { - if (*s == ' ' && *d == ' ') { - continue; - } - - if (*s == LF || *s == CR) { - continue; - } - - *++d = *s; - } - - if (*d != ' ') { - d++; - } - - *d = '\0'; - - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, - "SSL cipher: \"%s\"", &buf[1]); - - if (SSL_session_reused(c->ssl->connection)) { - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, - "SSL reused session"); - } - - } else { - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, - "SSL no shared ciphers"); - } - } -#endif - if (c->ssl->saved_read_handler) { c->read->handler = c->ssl->saved_read_handler; @@ -575,9 +653,8 @@ ngx_ssl_write(ngx_connection_t *c, u_cha if (sslerr == SSL_ERROR_WANT_READ) { - ngx_log_error(NGX_LOG_INFO, c->log, err, - "client does SSL %shandshake", - SSL_is_init_finished(c->ssl->connection) ? "re" : ""); + ngx_log_error(NGX_LOG_INFO, c->log, 0, + "client started SSL renegotiation"); c->read->ready = 0; @@ -598,37 +675,10 @@ ngx_ssl_write(ngx_connection_t *c, u_cha return NGX_AGAIN; } - c->ssl->no_rcv_shut = 1; - c->ssl->no_send_shut = 1; - - level = NGX_LOG_CRIT; - - if (sslerr == SSL_ERROR_SYSCALL) { - - if (err == NGX_ECONNRESET - || err == NGX_EPIPE - || err == NGX_ENOTCONN - || err == NGX_ECONNREFUSED - || err == NGX_EHOSTUNREACH) - { - switch (c->log_error) { + c->ssl->no_wait_shutdown = 1; + c->ssl->no_send_shutdown = 1; - case NGX_ERROR_IGNORE_ECONNRESET: - case NGX_ERROR_INFO: - level = NGX_LOG_INFO; - break; - - case NGX_ERROR_ERR: - level = NGX_LOG_ERR; - break; - - default: - break; - } - } - } - - ngx_ssl_error(level, c->log, err, "SSL_write() failed"); + ngx_ssl_connection_error(c, sslerr, err, "SSL_write() failed"); return NGX_ERROR; } @@ -640,6 +690,7 @@ ngx_ssl_read_handler(ngx_event_t *rev) ngx_connection_t *c; c = rev->data; + c->write->handler(c->write); } @@ -650,31 +701,23 @@ ngx_ssl_shutdown(ngx_connection_t *c) int n, sslerr, mode; ngx_uint_t again; - if (!c->ssl->shutdown_set) { - - /* it seems that SSL_set_shutdown() could be called once only */ - - if (c->read->timedout) { - mode = SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN; + if (c->read->timedout) { + mode = SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN; - } else { - mode = 0; + } else { + mode = SSL_get_shutdown(c->ssl->connection); - if (c->ssl->no_rcv_shut) { - mode = SSL_RECEIVED_SHUTDOWN; - } - - if (c->ssl->no_send_shut) { - mode |= SSL_SENT_SHUTDOWN; - } + if (c->ssl->no_wait_shutdown) { + mode |= SSL_RECEIVED_SHUTDOWN; } - if (mode) { - SSL_set_shutdown(c->ssl->connection, mode); - c->ssl->shutdown_set = 1; + if (c->ssl->no_send_shutdown) { + mode |= SSL_SENT_SHUTDOWN; } } + SSL_set_shutdown(c->ssl->connection, mode); + again = 0; #if (NGX_SUPPRESS_WARN) sslerr = 0; @@ -736,11 +779,49 @@ ngx_ssl_shutdown(ngx_connection_t *c) } +static void +ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err, + char *text) +{ + ngx_uint_t level; + + level = NGX_LOG_CRIT; + + if (sslerr == SSL_ERROR_SYSCALL) { + + if (err == NGX_ECONNRESET + || err == NGX_EPIPE + || err == NGX_ENOTCONN + || err == NGX_ECONNREFUSED + || err == NGX_EHOSTUNREACH) + { + switch (c->log_error) { + + case NGX_ERROR_IGNORE_ECONNRESET: + case NGX_ERROR_INFO: + level = NGX_LOG_INFO; + break; + + case NGX_ERROR_ERR: + level = NGX_LOG_ERR; + break; + + default: + break; + } + } + } + + ngx_ssl_error(level, c->log, err, text); +} + + void ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...) { + u_long n; + va_list args; u_char errstr[NGX_MAX_CONF_ERRSTR], *p, *last; - va_list args; last = errstr + NGX_MAX_CONF_ERRSTR; @@ -748,9 +829,18 @@ ngx_ssl_error(ngx_uint_t level, ngx_log_ p = ngx_vsnprintf(errstr, sizeof(errstr) - 1, fmt, args); va_end(args); - p = ngx_cpystrn(p, (u_char *) " (SSL: ", last - p); + p = ngx_cpystrn(p, (u_char *) " (SSL:", last - p); + + while (p < last && (n = ERR_get_error())) { + + *p++ = ' '; - ERR_error_string_n(ERR_get_error(), (char *) p, last - p); + ERR_error_string_n(n, (char *) p, last - p); + + while (p < last && *p) { + p++; + } + } ngx_log_error(level, log, err, "%s)", errstr); } @@ -759,9 +849,10 @@ ngx_ssl_error(ngx_uint_t level, ngx_log_ void ngx_ssl_cleanup_ctx(void *data) { - SSL_CTX *ctx = data; + ngx_ssl_t *ssl = data; - SSL_CTX_free(ctx); + RSA_free(ssl->rsa512_key); + SSL_CTX_free(ssl->ctx); } diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h --- a/src/event/ngx_event_openssl.h +++ b/src/event/ngx_event_openssl.h @@ -16,44 +16,53 @@ #if OPENSSL_VERSION_NUMBER >= 0x00907000 #include -#define NGX_SSL_ENGINE 1 +#define NGX_SSL_ENGINE 1 #endif -#define NGX_SSL_NAME "OpenSSL" +#define NGX_SSL_NAME "OpenSSL" + + +typedef struct { + SSL_CTX *ctx; + RSA *rsa512_key; + ngx_log_t *log; +} ngx_ssl_t; typedef struct { - SSL *connection; - ngx_int_t last; - ngx_buf_t *buf; - ngx_event_handler_pt saved_read_handler; - ngx_event_handler_pt saved_write_handler; + SSL *connection; + ngx_int_t last; + ngx_buf_t *buf; + + ngx_connection_handler_pt handler; - unsigned buffer:1; - unsigned no_rcv_shut:1; - unsigned no_send_shut:1; - unsigned shutdown_set:1; + ngx_event_handler_pt saved_read_handler; + ngx_event_handler_pt saved_write_handler; -#if (NGX_DEBUG) - unsigned handshaked:1; -#endif -} ngx_ssl_t; + unsigned handshaked:1; + unsigned buffer:1; + unsigned no_wait_shutdown:1; + unsigned no_send_shutdown:1; +} ngx_ssl_connection_t; -typedef SSL_CTX ngx_ssl_ctx_t; +#define NGX_SSL_SSLv2 2 +#define NGX_SSL_SSLv3 4 +#define NGX_SSL_TLSv1 8 -#define NGX_SSL_BUFFER 1 +#define NGX_SSL_BUFFER 1 -#define NGX_SSL_BUFSIZE 16384 +#define NGX_SSL_BUFSIZE 16384 ngx_int_t ngx_ssl_init(ngx_log_t *log); -ngx_int_t ngx_ssl_create_connection(ngx_ssl_ctx_t *ctx, ngx_connection_t *c, +ngx_int_t ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols); +ngx_int_t ngx_ssl_certificate(ngx_ssl_t *ssl, u_char *cert, u_char *key); +ngx_int_t ngx_ssl_generate_rsa512_key(ngx_ssl_t *ssl); +ngx_int_t ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c, ngx_uint_t flags); - -#define ngx_ssl_handshake(c) NGX_OK - +ngx_int_t ngx_ssl_handshake(ngx_connection_t *c); ssize_t ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size); ssize_t ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size); ngx_chain_t *ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, diff --git a/src/http/modules/ngx_http_autoindex_module.c b/src/http/modules/ngx_http_autoindex_module.c --- a/src/http/modules/ngx_http_autoindex_module.c +++ b/src/http/modules/ngx_http_autoindex_module.c @@ -271,21 +271,14 @@ ngx_http_autoindex_handler(ngx_http_requ len = ngx_de_namelen(&dir); - if (len == 1 && ngx_de_name(&dir)[0] == '.') { - continue; - } - - if (len == 2 - && ngx_de_name(&dir)[0] == '.' - && ngx_de_name(&dir)[1] == '.') - { + if (ngx_de_name(&dir)[0] == '.') { continue; } if (!dir.valid_info) { - if (dname.len + 1 + len > fname.len) { - fname.len = dname.len + 1 + len + 32; + if (dname.len + 1 + len + 1 > fname.len) { + fname.len = dname.len + 1 + len + 1 + 32; fname.data = ngx_palloc(pool, fname.len); if (fname.data == NULL) { @@ -468,7 +461,8 @@ ngx_http_autoindex_handler(ngx_http_requ } else { if (entry[i].dir) { - b->last = ngx_cpymem(b->last, " -", sizeof(" -") - 1); + b->last = ngx_cpymem(b->last, " -", + sizeof(" -") - 1); } else { length = entry[i].size; @@ -498,13 +492,14 @@ ngx_http_autoindex_handler(ngx_http_requ } else { size = (ngx_int_t) length; - scale = ' '; + scale = '\0'; } - b->last = ngx_sprintf(b->last, "%6i", size); + if (scale) { + b->last = ngx_sprintf(b->last, "%6i%c", size, scale); - if (scale != ' ') { - *b->last++ = scale; + } else { + b->last = ngx_sprintf(b->last, " %6i", size); } } } diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c --- a/src/http/modules/ngx_http_fastcgi_module.c +++ b/src/http/modules/ngx_http_fastcgi_module.c @@ -293,7 +293,7 @@ static ngx_command_t ngx_http_fastcgi_c NULL }, { ngx_string("fastcgi_next_upstream"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_ANY, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, ngx_conf_set_bitmask_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_fastcgi_loc_conf_t, upstream.next_upstream), diff --git a/src/http/modules/ngx_http_geo_module.c b/src/http/modules/ngx_http_geo_module.c --- a/src/http/modules/ngx_http_geo_module.c +++ b/src/http/modules/ngx_http_geo_module.c @@ -117,7 +117,7 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_c name.data++; } - var = ngx_http_add_variable(cf, &name, 0); + var = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGABLE); if (var == NULL) { return NGX_CONF_ERROR; } diff --git a/src/http/modules/ngx_http_gzip_filter_module.c b/src/http/modules/ngx_http_gzip_filter_module.c --- a/src/http/modules/ngx_http_gzip_filter_module.c +++ b/src/http/modules/ngx_http_gzip_filter_module.c @@ -181,7 +181,7 @@ static ngx_command_t ngx_http_gzip_filt &ngx_http_gzip_http_version }, { ngx_string("gzip_proxied"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_ANY, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, ngx_conf_set_bitmask_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_gzip_conf_t, proxied), diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -244,7 +244,7 @@ static ngx_command_t ngx_http_proxy_com NULL }, { ngx_string("proxy_next_upstream"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_ANY, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, ngx_conf_set_bitmask_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_proxy_loc_conf_t, upstream.next_upstream), diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c --- a/src/http/modules/ngx_http_ssi_filter_module.c +++ b/src/http/modules/ngx_http_ssi_filter_module.c @@ -59,6 +59,7 @@ typedef struct { ngx_uint_t output; /* unsigned output:1; */ ngx_str_t timefmt; + ngx_str_t errmsg; } ngx_http_ssi_ctx_t; @@ -217,8 +218,6 @@ static ngx_int_t (*ngx_http_next_body_fi static u_char ngx_http_ssi_string[] = "