Browse Source

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
svn/tags/lighttpd-1.4.12
Jan Kneschke 16 years ago
parent
commit
a85ca5e0ef
  1. 5
      src/base.h
  2. 2
      src/configfile-glue.c
  3. 29
      src/configfile.c
  4. 77
      src/configparser.y
  5. 61
      src/http-header-glue.c
  6. 18
      src/network.c
  7. 24
      src/proc_open.c

5
src/base.h

@ -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;

2
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;
}

29
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,

77
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();

61
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 {
@ -310,6 +310,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;
}

18
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");

24
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) {

Loading…
Cancel
Save