diff options
author | stbuehler <stbuehler@152afb58-edef-0310-8abb-c4023f1b3aa9> | 2009-10-14 18:19:54 +0000 |
---|---|---|
committer | stbuehler <stbuehler@152afb58-edef-0310-8abb-c4023f1b3aa9> | 2009-10-14 18:19:54 +0000 |
commit | 20eab04d57337075f6d7b03b184c68a88ff3576c (patch) | |
tree | 3e3f548ecde3466f49b1186173864fa8113243b5 | |
parent | 9b794792b8c02c29c2e4b4e495aa27022bfb3e22 (diff) | |
download | lighttpd-20eab04d57337075f6d7b03b184c68a88ff3576c.tar.gz |
Add SSL Client Certificate verification (#1288)
git-svn-id: svn://svn.lighttpd.net/lighttpd/trunk@2655 152afb58-edef-0310-8abb-c4023f1b3aa9
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | src/base.h | 5 | ||||
-rw-r--r-- | src/configfile.c | 27 | ||||
-rw-r--r-- | src/network.c | 24 | ||||
-rw-r--r-- | src/server.c | 1 |
5 files changed, 58 insertions, 0 deletions
@@ -144,6 +144,7 @@ NEWS * Allow chunkqueue_skip to skip all types of chunks * Use linux-epoll by default if available (fixes #2021) * Add TLS servername indication (SNI) support (fixes #386, thx Peter Colberg <peter@colberg.org>) + * Add SSL Client Certificate verification (#1288) - 1.5.0-r19.. - * -F option added for spawn-fcgi @@ -310,6 +310,11 @@ typedef struct { buffer *ssl_ca_file; buffer *ssl_cipher_list; unsigned short ssl_use_sslv2; + unsigned short ssl_verifyclient; + unsigned short ssl_verifyclient_enforce; + unsigned short ssl_verifyclient_depth; + buffer *ssl_verifyclient_username; + unsigned short use_ipv6; unsigned short is_ssl; unsigned short allow_http11; diff --git a/src/configfile.c b/src/configfile.c index fe4a0a9a..0aa5778e 100644 --- a/src/configfile.c +++ b/src/configfile.c @@ -105,6 +105,10 @@ static int config_insert(server *srv) { { "server.breakagelog", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 57 */ { "debug.log-timeouts", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 58 */ { "debug.log-ssl-noise", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 59 */ + { "ssl.verifyclient.activate", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 60 */ + { "ssl.verifyclient.enforce", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 61 */ + { "ssl.verifyclient.depth", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_SERVER }, /* 62 */ + { "ssl.verifyclient.username", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 63 */ { "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 }, @@ -173,6 +177,10 @@ static int config_insert(server *srv) { s->errorfile_prefix = buffer_init(); s->ssl_cipher_list = buffer_init(); s->ssl_use_sslv2 = 1; + s->ssl_verifyclient = 0; + s->ssl_verifyclient_enforce = 1; + s->ssl_verifyclient_username = buffer_init(); + s->ssl_verifyclient_depth = 9; s->max_keep_alive_requests = 16; s->max_keep_alive_idle = 5; s->max_read_idle = 60; @@ -242,6 +250,12 @@ static int config_insert(server *srv) { cv[58].destination = &(s->log_timeouts); cv[59].destination = &(s->log_ssl_noise); + /* ssl.verify */ + cv[60].destination = &(s->ssl_verifyclient); + cv[61].destination = &(s->ssl_verifyclient_enforce); + cv[62].destination = &(s->ssl_verifyclient_depth); + cv[63].destination = s->ssl_verifyclient_username; + srv->config_storage[i] = s; if (0 != (ret = config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv))) { @@ -320,6 +334,11 @@ int config_setup_connection(server *srv, connection *con) { PATCH(etag_use_mtime); PATCH(etag_use_size); + PATCH(ssl_verifyclient); + PATCH(ssl_verifyclient_enforce); + PATCH(ssl_verifyclient_depth); + PATCH(ssl_verifyclient_username); + return 0; } @@ -416,6 +435,14 @@ int config_patch_connection(server *srv, connection *con, comp_key_t comp) { PATCH(global_kbytes_per_second); PATCH(global_bytes_per_second_cnt); con->conf.global_bytes_per_second_cnt_ptr = &s->global_bytes_per_second_cnt; + } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.verifyclient.activate"))) { + PATCH(ssl_verifyclient); + } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.verifyclient.enforce"))) { + PATCH(ssl_verifyclient_enforce); + } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.verifyclient.depth"))) { + PATCH(ssl_verifyclient_depth); + } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.verifyclient.username"))) { + PATCH(ssl_verifyclient_username); } } } diff --git a/src/network.c b/src/network.c index e2a06b68..9671c27e 100644 --- a/src/network.c +++ b/src/network.c @@ -670,6 +670,30 @@ int network_init(server *srv) { ERR_error_string(ERR_get_error(), NULL), s->ssl_ca_file); return -1; } + if (s->ssl_verifyclient) { + STACK_OF(X509_NAME) *certs = SSL_load_client_CA_file(s->ssl_ca_file->ptr); + if (!certs) { + log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", + ERR_error_string(ERR_get_error(), NULL), s->ssl_ca_file); + } + if (SSL_CTX_set_session_id_context(s->ssl_ctx, (void*) &srv, sizeof(srv)) != 1) { + log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", + ERR_error_string(ERR_get_error(), NULL)); + return -1; + } + SSL_CTX_set_client_CA_list(s->ssl_ctx, certs); + SSL_CTX_set_verify( + s->ssl_ctx, + SSL_VERIFY_PEER | (s->ssl_verifyclient_enforce ? SSL_VERIFY_FAIL_IF_NO_PEER_CERT : 0), + NULL + ); + SSL_CTX_set_verify_depth(s->ssl_ctx, s->ssl_verifyclient_depth); + } + } else if (s->ssl_verifyclient) { + log_error_write( + srv, __FILE__, __LINE__, "s", + "SSL: You specified ssl.verifyclient.activate but no ca_file" + ); } if (SSL_CTX_use_certificate_file(s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) { diff --git a/src/server.c b/src/server.c index 262f222f..c95dc2c9 100644 --- a/src/server.c +++ b/src/server.c @@ -338,6 +338,7 @@ static void server_free(server *srv) { buffer_free(s->errorfile_prefix); array_free(s->mimetypes); buffer_free(s->ssl_cipher_list); + buffer_free(s->ssl_verifyclient_username); #ifdef USE_OPENSSL SSL_CTX_free(s->ssl_ctx); #endif |