# HG changeset patch # User Igor Sysoev # Date 1089579827 0 # Node ID fa72605e70895b10458f8d87418c2d0b706fba75 # Parent 79050a10aacbb25972c54461fa83bf9170c64491 nginx-0.0.7-2004-07-12-01:03:47 import diff --git a/auto/modules b/auto/modules --- a/auto/modules +++ b/auto/modules @@ -61,6 +61,7 @@ fi if [ $HTTP_SSL = YES ]; then have=NGX_HTTP_SSL . auto/have HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_SSL_FILTER_MODULE" + HTTP_DEPS="$HTTP_DEPS $HTTP_SSL_DEPS" HTTP_SRCS="$HTTP_SRCS $HTTP_SSL_SRCS" # STUB: move to auto/libs/ssl CORE_LIBS="$CORE_LIBS -lssl -lcrypto" diff --git a/auto/sources b/auto/sources --- a/auto/sources +++ b/auto/sources @@ -250,6 +250,7 @@ HTTP_GZIP_SRCS=src/http/modules/ngx_http HTTP_SSL_FILTER_MODULE=ngx_http_ssl_filter_module +HTTP_SSL_DEPS=src/http/modules/ngx_http_ssl_filter.h HTTP_SSL_SRCS=src/http/modules/ngx_http_ssl_filter.c diff --git a/src/http/modules/ngx_http_ssl_filter.c b/src/http/modules/ngx_http_ssl_filter.c --- a/src/http/modules/ngx_http_ssl_filter.c +++ b/src/http/modules/ngx_http_ssl_filter.c @@ -15,12 +15,13 @@ typedef struct { ngx_flag_t enable; ngx_str_t certificate; ngx_str_t certificate_key; + + SSL_CTX *ssl_ctx; } ngx_http_ssl_srv_conf_t; typedef struct { SSL *ssl; - SSL_CTX *ssl_ctx; unsigned accepted; } ngx_http_ssl_ctx_t; @@ -86,10 +87,11 @@ ngx_module_t ngx_http_ssl_filter_module }; -ngx_int_t ngx_http_ssl_read(ngx_http_request_t *r) +ngx_int_t ngx_http_ssl_read(ngx_http_request_t *r, u_char *buf, size_t n) { int rc; ngx_http_ssl_ctx_t *ctx; + ngx_http_log_ctx_t *log_ctx; ctx = ngx_http_get_module_ctx(r, ngx_http_ssl_filter_module); @@ -101,44 +103,108 @@ ngx_int_t ngx_http_ssl_read(ngx_http_req } } - if (!ctx->accepted) { - rc = SSL_accept(ctx->ssl); + rc = SSL_read(ctx->ssl, buf, n); + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "SSL_read: %d", rc); - if (rc != 1) { - rc = SSL_get_error(ctx->ssl, rc); + if (rc > 0) { + return rc; + } + + rc = SSL_get_error(ctx->ssl, rc); + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "SSL_get_error: %d", rc); - if (rc == SSL_ERROR_WANT_READ || rc == SSL_ERROR_WANT_WRITE) { - return NGX_AGAIN; - } + if (rc == SSL_ERROR_WANT_READ) { + return NGX_AGAIN; + } + +#if 0 + if (rc == SSL_ERROR_WANT_WRITE) { + return NGX_AGAIN; + } +#endif - if (rc == SSL_ERROR_ZERO_RETURN) { - ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, - "client closed connection while SSL handshake"); + if (!SSL_is_init_finished(ctx->ssl)) { + log_ctx = (ngx_http_log_ctx_t *) r->connection->log->data; + log_ctx->action = "SSL handshake"; + } - ngx_http_ssl_close_request(ctx->ssl, SSL_RECEIVED_SHUTDOWN); + if (rc == SSL_ERROR_ZERO_RETURN) { + ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, + "client closed connection"); + + SSL_set_shutdown(ctx->ssl, SSL_RECEIVED_SHUTDOWN); - return NGX_ERROR; - } + return NGX_SSL_ERROR; + } + + if (ERR_GET_REASON(ERR_peek_error()) == SSL_R_HTTP_REQUEST) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "client sent plain HTTP request to HTTPS port"); - if (ERR_GET_REASON(ERR_peek_error()) == SSL_R_HTTP_REQUEST) { - ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, - "client sent HTTP request to HTTPS port"); + SSL_set_shutdown(ctx->ssl, + SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN); - ngx_http_ssl_close_request(ctx->ssl, - SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); + return NGX_SSL_HTTP_ERROR; + } + + ngx_http_ssl_error(NGX_LOG_ALERT, r->connection->log, rc, + "SSL_accept() failed"); + + SSL_set_shutdown(ctx->ssl, SSL_RECEIVED_SHUTDOWN); - return NGX_OK; - } + return NGX_SSL_ERROR; +} + + +ngx_int_t ngx_http_ssl_write(ngx_http_request_t *r, ngx_chain_t *in, + off_t limit) +{ + int rc; + size_t send, size; + ngx_http_ssl_ctx_t *ctx; - ngx_http_ssl_error(NGX_LOG_ALERT, r->connection->log, rc, - "SSL_accept() failed"); + ctx = ngx_http_get_module_ctx(r, ngx_http_ssl_filter_module); + + if (in == NULL) { + rc = SSL_shutdown(ctx->ssl); - ngx_http_ssl_close_request(ctx->ssl, SSL_RECEIVED_SHUTDOWN); + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "SSL_shutdown: %d", rc); - return NGX_ERROR; + if (rc == 1) { + return NGX_OK; } - ctx->accepted = 1; + rc = SSL_get_error(ctx->ssl, rc); + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "SSL_get_error: %d", rc); + + if (rc == SSL_ERROR_WANT_WRITE) { + return NGX_AGAIN; + } + + return NGX_ERROR; + } + + send = 0; + + for (/* void */; in; in = in->next) { + if (ngx_buf_special(in->buf)) { + continue; + } + + size = in->buf->last - in->buf->pos; + + if (send + size > limit) { + size = limit - send; + } + + rc = SSL_write(ctx->ssl, in->buf->pos, size); } return NGX_OK; @@ -153,32 +219,9 @@ static ngx_http_ssl_ctx_t *ngx_http_ssl_ ngx_http_create_ctx(r, ctx, ngx_http_ssl_filter_module, sizeof(ngx_http_ssl_ctx_t), NULL); - /* TODO: configure methods */ - ctx->ssl_ctx = SSL_CTX_new(SSLv23_server_method()); - - if (ctx->ssl_ctx == NULL) { - ngx_http_ssl_error(NGX_LOG_ALERT, r->connection->log, 0, - "SSL_CTX_new() failed"); - return NULL; - } - scf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_filter_module); - if (SSL_CTX_use_certificate_file(ctx->ssl_ctx, scf->certificate.data, - SSL_FILETYPE_PEM) == 0) { - ngx_http_ssl_error(NGX_LOG_ALERT, r->connection->log, 0, - "SSL_CTX_use_certificate_file() failed"); - return NULL; - } - - if (SSL_CTX_use_PrivateKey_file(ctx->ssl_ctx, scf->certificate_key.data, - SSL_FILETYPE_PEM) == 0) { - ngx_http_ssl_error(NGX_LOG_ALERT, r->connection->log, 0, - "SSL_CTX_use_PrivateKey_file() failed"); - return NULL; - } - - ctx->ssl = SSL_new(ctx->ssl_ctx); + ctx->ssl = SSL_new(scf->ssl_ctx); if (ctx->ssl == NULL) { ngx_http_ssl_error(NGX_LOG_ALERT, r->connection->log, 0, @@ -192,14 +235,16 @@ static ngx_http_ssl_ctx_t *ngx_http_ssl_ return NULL; } + SSL_set_accept_state(ctx->ssl); + return ctx; } -void ngx_http_ssl_close_request(SSL *ssl, int mode) +void ngx_http_ssl_close_connection(SSL *ssl, ngx_log_t *log) { - SSL_set_shutdown(ssl, mode); - SSL_shutdown(ssl); + int rc; + SSL_free(ssl); } @@ -257,15 +302,41 @@ static char *ngx_http_ssl_merge_srv_conf ngx_conf_merge_str_value(conf->certificate_key, prev->certificate_key, NGX_DEFLAUT_CERTIFICATE_KEY); + /* STUB: where to move ??? */ + SSL_library_init(); + SSL_load_error_strings(); + + /* TODO: inherit ssl_ctx */ + + /* TODO: configure methods */ + + conf->ssl_ctx = SSL_CTX_new(SSLv23_server_method()); + + if (conf->ssl_ctx == NULL) { + ngx_http_ssl_error(NGX_LOG_EMERG, cf->log, 0, "SSL_CTX_new() failed"); + return NGX_CONF_ERROR; + } + + if (SSL_CTX_use_certificate_file(conf->ssl_ctx, conf->certificate.data, + SSL_FILETYPE_PEM) == 0) { + ngx_http_ssl_error(NGX_LOG_EMERG, cf->log, 0, + "SSL_CTX_use_certificate_file() failed"); + return NGX_CONF_ERROR; + } + + if (SSL_CTX_use_PrivateKey_file(conf->ssl_ctx, conf->certificate_key.data, + SSL_FILETYPE_PEM) == 0) { + ngx_http_ssl_error(NGX_LOG_EMERG, cf->log, 0, + "SSL_CTX_use_PrivateKey_file() failed"); + return NGX_CONF_ERROR; + } + return NGX_CONF_OK; } static ngx_int_t ngx_http_ssl_filter_init(ngx_cycle_t *cycle) { - SSL_library_init(); - SSL_load_error_strings(); - #if 0 ngx_http_next_header_filter = ngx_http_top_header_filter; ngx_http_top_header_filter = ngx_http_ssl_header_filter; diff --git a/src/http/modules/ngx_http_ssl_filter.h b/src/http/modules/ngx_http_ssl_filter.h --- a/src/http/modules/ngx_http_ssl_filter.h +++ b/src/http/modules/ngx_http_ssl_filter.h @@ -9,8 +9,12 @@ #include -ngx_int_t ngx_http_ssl_read(ngx_http_request_t *r); -void ngx_http_ssl_close_request(SSL *ssl, int mode); +#define NGX_SSL_ERROR -10 +#define NGX_SSL_HTTP_ERROR -11 + + +ngx_int_t ngx_http_ssl_read(ngx_http_request_t *r, u_char *buf, size_t n); +void ngx_http_ssl_close_connection(SSL *ssl, ngx_log_t *log); #endif /* _NGX_HTTP_SSL_FILTER_H_INCLUDED_ */ diff --git a/src/http/ngx_http_copy_filter.c b/src/http/ngx_http_copy_filter.c --- a/src/http/ngx_http_copy_filter.c +++ b/src/http/ngx_http_copy_filter.c @@ -87,7 +87,7 @@ ngx_int_t ngx_http_copy_filter(ngx_http_ } - return ngx_output_chain(ctx, in); + return ngx_output_chain(ctx, in); } diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -815,8 +815,9 @@ static ssize_t ngx_http_read_request_hea return NGX_AGAIN; } -#if 0 - ngx_http_ssl_read(r); +#if 1 + n = ngx_http_ssl_read(r, r->header_in->last, + r->header_in->end - r->header_in->last); #else n = ngx_recv(r->connection, r->header_in->last, r->header_in->end - r->header_in->last);