diff options
author | jan <jan@152afb58-edef-0310-8abb-c4023f1b3aa9> | 2006-09-07 10:19:29 +0000 |
---|---|---|
committer | jan <jan@152afb58-edef-0310-8abb-c4023f1b3aa9> | 2006-09-07 10:19:29 +0000 |
commit | fa2b3c4b3de591f83307aba3ff24e9c235b89d4d (patch) | |
tree | 2770b47dd8f20bde62e58e2042c3c06d3748711c | |
parent | dc24de4b51b85957bd5bb1ebbd971d196730bb0f (diff) | |
download | lighttpd-fa2b3c4b3de591f83307aba3ff24e9c235b89d4d.tar.gz |
merged [1051], [1052], [1053], [1054], [1057], [1060], [1061], [1062]
added ssl.use-sslv2 and ssl.cipher-list
git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.11-ssl-fixes@1279 152afb58-edef-0310-8abb-c4023f1b3aa9
-rw-r--r-- | src/base.h | 5 | ||||
-rw-r--r-- | src/configfile-glue.c | 2 | ||||
-rw-r--r-- | src/configfile.c | 29 | ||||
-rw-r--r-- | src/configparser.y | 77 | ||||
-rw-r--r-- | src/http-header-glue.c | 61 | ||||
-rw-r--r-- | src/network.c | 18 | ||||
-rw-r--r-- | src/proc_open.c | 24 |
7 files changed, 141 insertions, 75 deletions
@@ -257,6 +257,9 @@ typedef struct { /* server wide */ buffer *ssl_pemfile; buffer *ssl_ca_file; + buffer *ssl_cipher_list; + unsigned short ssl_use_sslv2; + unsigned short use_ipv6; unsigned short is_ssl; unsigned short allow_http11; @@ -484,6 +487,8 @@ typedef struct { buffer *ssl_pemfile; buffer *ssl_ca_file; + buffer *ssl_cipher_list; + unsigned short ssl_use_sslv2; unsigned short use_ipv6; unsigned short is_ssl; diff --git a/src/configfile-glue.c b/src/configfile-glue.c index 64018549..6471686e 100644 --- a/src/configfile-glue.c +++ b/src/configfile-glue.c @@ -230,7 +230,7 @@ static cond_result_t config_check_cond_nocache(server *srv, connection *con, dat break; } } else { - l = NULL; + l = srv->empty_string; } break; } diff --git a/src/configfile.c b/src/configfile.c index acb1e0a4..4d9946d3 100644 --- a/src/configfile.c +++ b/src/configfile.c @@ -80,6 +80,8 @@ static int config_insert(server *srv) { { "server.network-backend", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 43 */ { "server.upload-dirs", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 44 */ { "server.core-files", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 45 */ + { "ssl.cipher-list", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 46 */ + { "ssl.use-sslv2", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 47 */ { "server.host", "use server.bind instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, { "server.docroot", "use server.document-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, @@ -138,6 +140,7 @@ static int config_insert(server *srv) { s->ssl_ca_file = buffer_init(); s->error_handler = buffer_init(); s->server_tag = buffer_init(); + s->ssl_cipher_list = buffer_init(); s->errorfile_prefix = buffer_init(); s->max_keep_alive_requests = 16; s->max_keep_alive_idle = 5; @@ -145,6 +148,7 @@ static int config_insert(server *srv) { s->max_write_idle = 360; s->use_xattr = 0; s->is_ssl = 0; + s->ssl_use_sslv2 = 1; s->use_ipv6 = 0; s->follow_symlink = 1; s->kbytes_per_second = 0; @@ -189,6 +193,9 @@ static int config_insert(server *srv) { cv[38].destination = s->ssl_ca_file; cv[40].destination = &(s->range_requests); + cv[46].destination = s->ssl_cipher_list; + cv[47].destination = &(s->ssl_use_sslv2); + srv->config_storage[i] = s; if (0 != (ret = config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv))) { @@ -252,6 +259,10 @@ int config_setup_connection(server *srv, connection *con) { PATCH(ssl_pemfile); PATCH(ssl_ca_file); + PATCH(ssl_cipher_list); + PATCH(ssl_use_sslv2); + + return 0; } @@ -297,6 +308,10 @@ int config_patch_connection(server *srv, connection *con, comp_key_t comp) { PATCH(ssl_pemfile); } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.ca-file"))) { PATCH(ssl_ca_file); + } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.use-sslv2"))) { + PATCH(ssl_use_sslv2); + } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.cipher-list"))) { + PATCH(ssl_cipher_list); } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.engine"))) { PATCH(is_ssl); } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.follow-symlink"))) { @@ -540,7 +555,7 @@ static int config_tokenizer(server *srv, tokenizer_t *t, int *token_id, buffer * } else { config_skip_newline(t); t->line_pos = 1; - t->line++; + t->line++; } break; case ',': @@ -699,21 +714,13 @@ static int config_tokenizer(server *srv, tokenizer_t *t, int *token_id, buffer * for (i = 0; t->input[t->offset + i] && isdigit((unsigned char)t->input[t->offset + i]); i++); /* was there it least a digit ? */ - if (i && t->input[t->offset + i]) { + if (i) { tid = TK_INTEGER; buffer_copy_string_len(token, t->input + t->offset, i); t->offset += i; t->line_pos += i; - } else { - /* ERROR */ - log_error_write(srv, __FILE__, __LINE__, "sbsdsds", - "source:", t->source, - "line:", t->line, "pos:", t->line_pos, - "unexpected EOF"); - - return -1; } } else { /* the key might consist of [-.0-9a-z] */ @@ -800,7 +807,7 @@ static int config_parse(server *srv, config_t *context, tokenizer_t *t) { if (ret == -1) { log_error_write(srv, __FILE__, __LINE__, "sb", - "configfile parser failed:", lasttoken); + "configfile parser failed at:", lasttoken); } else if (context->ok == 0) { log_error_write(srv, __FILE__, __LINE__, "sbsdsdsb", "source:", t->source, diff --git a/src/configparser.y b/src/configparser.y index ef65061d..d386ff67 100644 --- a/src/configparser.y +++ b/src/configparser.y @@ -33,40 +33,22 @@ static data_config *configparser_pop(config_t *ctx) { /* return a copied variable */ static data_unset *configparser_get_variable(config_t *ctx, const buffer *key) { - if (strncmp(key->ptr, "env.", sizeof("env.") - 1) == 0) { - char *env; - - if (NULL != (env = getenv(key->ptr + 4))) { - data_string *ds; - ds = data_string_init(); - buffer_append_string(ds->value, env); - return (data_unset *)ds; - } - - fprintf(stderr, "Undefined env variable: %s\n", key->ptr + 4); - ctx->ok = 0; - - return NULL; - } else { - data_unset *du; - data_config *dc; + data_unset *du; + data_config *dc; #if 0 - fprintf(stderr, "get var %s\n", key->ptr); + fprintf(stderr, "get var %s\n", key->ptr); #endif - for (dc = ctx->current; dc; dc = dc->parent) { + for (dc = ctx->current; dc; dc = dc->parent) { #if 0 - fprintf(stderr, "get var on block: %s\n", dc->key->ptr); - array_print(dc->value, 0); + fprintf(stderr, "get var on block: %s\n", dc->key->ptr); + array_print(dc->value, 0); #endif - if (NULL != (du = array_get_element(dc->value, key->ptr))) { - return du->copy(du); - } + if (NULL != (du = array_get_element(dc->value, key->ptr))) { + return du->copy(du); } - fprintf(stderr, "Undefined config variable: %s\n", key->ptr); - ctx->ok = 0; - return NULL; } + return NULL; } /* op1 is to be eat/return by this function, op1->key is not cared @@ -161,7 +143,12 @@ metaline ::= EOL. varline ::= key(A) ASSIGN expression(B). { buffer_copy_string_buffer(B->key, A); - if (NULL == array_get_element(ctx->current->value, B->key->ptr)) { + if (strncmp(A->ptr, "env.", sizeof("env.") - 1) == 0) { + fprintf(stderr, "Setting env variable is not supported in conditional %d %s: %s\n", + ctx->current->context_ndx, + ctx->current->key->ptr, A->ptr); + ctx->ok = 0; + } else if (NULL == array_get_element(ctx->current->value, B->key->ptr)) { array_insert_unique(ctx->current->value, B); B = NULL; } else { @@ -180,7 +167,12 @@ varline ::= key(A) APPEND expression(B). { array *vars = ctx->current->value; data_unset *du; - if (NULL != (du = array_get_element(vars, A->ptr))) { + if (strncmp(A->ptr, "env.", sizeof("env.") - 1) == 0) { + fprintf(stderr, "Appending env variable is not supported in conditional %d %s: %s\n", + ctx->current->context_ndx, + ctx->current->key->ptr, A->ptr); + ctx->ok = 0; + } else if (NULL != (du = array_get_element(vars, A->ptr))) { /* exists in current block */ du = configparser_merge_data(du, B); if (NULL == du) { @@ -190,6 +182,7 @@ varline ::= key(A) APPEND expression(B). { buffer_copy_string_buffer(du->key, A); array_replace(vars, du); } + B->free(B); } else if (NULL != (du = configparser_get_variable(ctx, A))) { du = configparser_merge_data(du, B); if (NULL == du) { @@ -199,15 +192,13 @@ varline ::= key(A) APPEND expression(B). { buffer_copy_string_buffer(du->key, A); array_insert_unique(ctx->current->value, du); } + B->free(B); } else { - fprintf(stderr, "Undefined config variable in conditional %d %s: %s\n", - ctx->current->context_ndx, - ctx->current->key->ptr, A->ptr); - ctx->ok = 0; + buffer_copy_string_buffer(B->key, A); + array_insert_unique(ctx->current->value, B); } buffer_free(A); A = NULL; - B->free(B); B = NULL; } @@ -239,7 +230,23 @@ expression(A) ::= value(B). { } value(A) ::= key(B). { - A = configparser_get_variable(ctx, B); + if (strncmp(B->ptr, "env.", sizeof("env.") - 1) == 0) { + char *env; + + if (NULL != (env = getenv(B->ptr + 4))) { + data_string *ds; + ds = data_string_init(); + buffer_append_string(ds->value, env); + A = (data_unset *)ds; + } + else { + fprintf(stderr, "Undefined env variable: %s\n", B->ptr + 4); + ctx->ok = 0; + } + } else if (NULL == (A = configparser_get_variable(ctx, B))) { + fprintf(stderr, "Undefined config variable: %s\n", B->ptr); + ctx->ok = 0; + } if (!A) { /* make a dummy so it won't crash */ A = (data_unset *)data_string_init(); diff --git a/src/http-header-glue.c b/src/http-header-glue.c index 4771a5ee..b40f3746 100644 --- a/src/http-header-glue.c +++ b/src/http-header-glue.c @@ -262,26 +262,11 @@ int http_response_handle_cachable(server *srv, connection *con, buffer *mtime) { return HANDLER_FINISHED; } else { char buf[sizeof("Sat, 23 Jul 2005 21:20:01 GMT")]; + time_t t_header, t_file; + struct tm tm; - /* convert to timestamp */ - if (used_len < sizeof(buf)) { - time_t t_header, t_file; - struct tm tm; - - strncpy(buf, con->request.http_if_modified_since, used_len); - buf[used_len] = '\0'; - - strptime(buf, "%a, %d %b %Y %H:%M:%S GMT", &tm); - t_header = mktime(&tm); - - strptime(mtime->ptr, "%a, %d %b %Y %H:%M:%S GMT", &tm); - t_file = mktime(&tm); - - if (t_file > t_header) { - con->http_status = 304; - return HANDLER_FINISHED; - } - } else { + /* check if we can safely copy the string */ + if (used_len >= sizeof(buf)) { log_error_write(srv, __FILE__, __LINE__, "ssdd", "DEBUG: Last-Modified check failed as the received timestamp was too long:", con->request.http_if_modified_since, used_len, sizeof(buf) - 1); @@ -289,6 +274,21 @@ int http_response_handle_cachable(server *srv, connection *con, buffer *mtime) { con->http_status = 412; return HANDLER_FINISHED; } + + + strncpy(buf, con->request.http_if_modified_since, used_len); + buf[used_len] = '\0'; + + strptime(buf, "%a, %d %b %Y %H:%M:%S GMT", &tm); + t_header = mktime(&tm); + + strptime(mtime->ptr, "%a, %d %b %Y %H:%M:%S GMT", &tm); + t_file = mktime(&tm); + + if (t_file > t_header) return HANDLER_GO_ON; + + con->http_status = 304; + return HANDLER_FINISHED; } } else { con->http_status = 304; @@ -302,7 +302,7 @@ int http_response_handle_cachable(server *srv, connection *con, buffer *mtime) { } else if (con->request.http_if_modified_since) { size_t used_len; char *semicolon; - + if (NULL == (semicolon = strchr(con->request.http_if_modified_since, ';'))) { used_len = strlen(con->request.http_if_modified_since); } else { @@ -312,6 +312,27 @@ int http_response_handle_cachable(server *srv, connection *con, buffer *mtime) { if (0 == strncmp(con->request.http_if_modified_since, mtime->ptr, used_len)) { con->http_status = 304; return HANDLER_FINISHED; + } else { + char buf[sizeof("Sat, 23 Jul 2005 21:20:01 GMT")]; + time_t t_header, t_file; + struct tm tm; + + /* convert to timestamp */ + if (used_len >= sizeof(buf)) return HANDLER_GO_ON; + + strncpy(buf, con->request.http_if_modified_since, used_len); + buf[used_len] = '\0'; + + strptime(buf, "%a, %d %b %Y %H:%M:%S GMT", &tm); + t_header = mktime(&tm); + + strptime(mtime->ptr, "%a, %d %b %Y %H:%M:%S GMT", &tm); + t_file = mktime(&tm); + + if (t_file > t_header) return HANDLER_GO_ON; + + con->http_status = 304; + return HANDLER_FINISHED; } } diff --git a/src/network.c b/src/network.c index c7abf904..6ba27435 100644 --- a/src/network.c +++ b/src/network.c @@ -329,6 +329,24 @@ int network_server_init(server *srv, buffer *host_token, specific_config *s) { ERR_error_string(ERR_get_error(), NULL)); return -1; } + + if (!s->ssl_use_sslv2) { + /* disable SSLv2 */ + if (SSL_OP_NO_SSLv2 != SSL_CTX_set_options(s->ssl_ctx, SSL_OP_NO_SSLv2)) { + log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", + ERR_error_string(ERR_get_error(), NULL)); + return -1; + } + } + + if (!buffer_is_empty(s->ssl_cipher_list)) { + /* Disable support for low encryption ciphers */ + if (SSL_CTX_set_cipher_list(s->ssl_ctx, s->ssl_cipher_list->ptr) != 1) { + log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", + ERR_error_string(ERR_get_error(), NULL)); + return -1; + } + } if (buffer_is_empty(s->ssl_pemfile)) { log_error_write(srv, __FILE__, __LINE__, "s", "ssl.pemfile has to be set"); diff --git a/src/proc_open.c b/src/proc_open.c index ecea815a..ad2650d2 100644 --- a/src/proc_open.c +++ b/src/proc_open.c @@ -148,11 +148,14 @@ int proc_open(proc_handler_t *proc, const char *command) { STARTUPINFO si; BOOL procok; SECURITY_ATTRIBUTES security; - const char *shell; + const char *shell = NULL; + const char *windir = NULL; buffer *cmdline; - if (NULL == (shell = getenv(SHELLENV))) { - fprintf(stderr, "env %s is required", SHELLENV); + if (NULL == (shell = getenv(SHELLENV)) && + NULL == (windir = getenv("SystemRoot")) && + NULL == (windir = getenv("windir"))) { + fprintf(stderr, "One of %s,%%SystemRoot,%%windir is required", SHELLENV); return -1; } @@ -177,17 +180,23 @@ int proc_open(proc_handler_t *proc, const char *command) { memset(&pi, 0, sizeof(pi)); cmdline = buffer_init(); - buffer_append_string(cmdline, shell); + if (shell) { + buffer_append_string(cmdline, shell); + } else { + buffer_append_string(cmdline, windir); + buffer_append_string(cmdline, "\\system32\\cmd.exe"); + } buffer_append_string_len(cmdline, CONST_STR_LEN(" /c ")); buffer_append_string(cmdline, command); procok = CreateProcess(NULL, cmdline->ptr, &security, &security, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi); - buffer_free(cmdline); if (FALSE == procok) { - fprintf(stderr, "failed to CreateProcess"); + fprintf(stderr, "failed to CreateProcess: %s", cmdline->ptr); + buffer_free(cmdline); return -1; } + buffer_free(cmdline); proc->child = pi.hProcess; CloseHandle(pi.hThread); @@ -226,8 +235,7 @@ int proc_open(proc_handler_t *proc, const char *command) { const char *shell; if (NULL == (shell = getenv(SHELLENV))) { - fprintf(stderr, "env %s is required", SHELLENV); - return -1; + shell = "/bin/sh"; } if (proc_open_pipes(proc) != 0) { |