# LightTPD v1.4.16 Client SSL Authentication Patch
# with environment variables for CGI/FastCGI/SCGI modules
#
# v0.3 - 2007/07/26
#
# by Joe Presbrey <presbrey@mit.edu>
# original posting at <http://trac.lighttpd.net/trac/ticket/921>
#
diff -ur lighttpd-1.4.16.orig/src/base.h lighttpd-1.4.16/src/base.h
|
old
|
new
|
|
| 266 | 266 | buffer *ssl_ca_file; |
| 267 | 267 | buffer *ssl_cipher_list; |
| 268 | 268 | unsigned short ssl_use_sslv2; |
| | 269 | unsigned short ssl_verify_peer; |
| | 270 | unsigned short ssl_verify_depth; |
| 269 | 271 | |
| 270 | 272 | unsigned short use_ipv6; |
| 271 | 273 | unsigned short is_ssl; |
diff -ur lighttpd-1.4.16.orig/src/configfile.c lighttpd-1.4.16/src/configfile.c
|
old
|
new
|
|
| 92 | 92 | { "etag.use-inode", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 48 */ |
| 93 | 93 | { "etag.use-mtime", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 49 */ |
| 94 | 94 | { "etag.use-size", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 50 */ |
| | 95 | { "ssl.verify-peer", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, |
| | 96 | { "ssl.verify-depth", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_SERVER }, |
| 95 | 97 | { "server.host", "use server.bind instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, |
| 96 | 98 | { "server.docroot", "use server.document-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, |
| 97 | 99 | { "server.virtual-root", "load mod_simple_vhost and use simple-vhost.server-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, |
| … |
… |
|
| 157 | 159 | s->max_write_idle = 360; |
| 158 | 160 | s->use_xattr = 0; |
| 159 | 161 | s->is_ssl = 0; |
| | 162 | s->ssl_verify_peer = 0; |
| | 163 | s->ssl_verify_depth = 9; |
| 160 | 164 | s->ssl_use_sslv2 = 1; |
| 161 | 165 | s->use_ipv6 = 0; |
| 162 | 166 | #ifdef HAVE_LSTAT |
| … |
… |
|
| 214 | 218 | cv[48].destination = &(s->etag_use_inode); |
| 215 | 219 | cv[49].destination = &(s->etag_use_mtime); |
| 216 | 220 | cv[50].destination = &(s->etag_use_size); |
| | 221 | cv[51].destination = &(s->ssl_verify_peer); |
| | 222 | cv[52].destination = &(s->ssl_verify_depth); |
| 217 | 223 | |
| 218 | 224 | srv->config_storage[i] = s; |
| 219 | 225 | |
| … |
… |
|
| 284 | 290 | PATCH(force_lowercase_filenames); |
| 285 | 291 | PATCH(is_ssl); |
| 286 | 292 | |
| | 293 | PATCH(ssl_verify_peer); |
| 287 | 294 | PATCH(ssl_pemfile); |
| 288 | 295 | PATCH(ssl_ca_file); |
| 289 | 296 | PATCH(ssl_cipher_list); |
| … |
… |
|
| 349 | 356 | PATCH(ssl_cipher_list); |
| 350 | 357 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.engine"))) { |
| 351 | 358 | PATCH(is_ssl); |
| | 359 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.verify-peer"))) { |
| | 360 | PATCH(ssl_verify_peer); |
| | 361 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.verify-depth"))) { |
| | 362 | PATCH(ssl_verify_depth); |
| 352 | 363 | #ifdef HAVE_LSTAT |
| 353 | 364 | } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.follow-symlink"))) { |
| 354 | 365 | PATCH(follow_symlink); |
diff -ur lighttpd-1.4.16.orig/src/connections.c lighttpd-1.4.16/src/connections.c
|
old
|
new
|
|
| 1332 | 1332 | ERR_error_string(ERR_get_error(), NULL)); |
| 1333 | 1333 | return NULL; |
| 1334 | 1334 | } |
| | 1335 | if (con->conf.ssl_verify_peer) |
| | 1336 | { |
| | 1337 | if(SSL_get_verify_result(con->ssl) != X509_V_OK) |
| | 1338 | { |
| | 1339 | log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", |
| | 1340 | ERR_error_string(ERR_get_error(), NULL)); |
| | 1341 | return NULL; |
| | 1342 | } |
| | 1343 | |
| | 1344 | } |
| 1335 | 1345 | } |
| 1336 | 1346 | #endif |
| 1337 | 1347 | return con; |
diff -ur lighttpd-1.4.16.orig/src/mod_cgi.c lighttpd-1.4.16/src/mod_cgi.c
|
old
|
new
|
|
| 845 | 845 | #ifdef USE_OPENSSL |
| 846 | 846 | if (srv_sock->is_ssl) { |
| 847 | 847 | cgi_env_add(&env, CONST_STR_LEN("HTTPS"), CONST_STR_LEN("on")); |
| | 848 | if (con->conf.ssl_verify_peer) { |
| | 849 | X509 *xs = SSL_get_peer_certificate(con->ssl); |
| | 850 | if (NULL != xs) { |
| | 851 | X509_NAME *xn = X509_get_subject_name(xs); |
| | 852 | X509_NAME_ENTRY *xe; |
| | 853 | |
| | 854 | char *xc = X509_NAME_oneline(xn, NULL, 0); |
| | 855 | cgi_env_add(&env, CONST_STR_LEN("SSL_CLIENT_S_DN"), xc, strlen(xc)); |
| | 856 | OPENSSL_free(xc); |
| | 857 | |
| | 858 | for (i = 0; i < X509_NAME_entry_count(xn); i++) { |
| | 859 | xe = X509_NAME_get_entry(xn, i); |
| | 860 | buffer *xobjname = buffer_init(); |
| | 861 | buffer_copy_string(xobjname, "SSL_CLIENT_S_DN_"); |
| | 862 | int xobjnid = OBJ_obj2nid((ASN1_OBJECT *)X509_NAME_ENTRY_get_object(xe)); |
| | 863 | const char *xobjsn = OBJ_nid2sn(xobjnid); |
| | 864 | buffer_append_string(xobjname, xobjsn); |
| | 865 | cgi_env_add(&env, CONST_BUF_LEN(xobjname), xe->value->data, strlen((char *)xe->value->data)); |
| | 866 | buffer_free(xobjname); |
| | 867 | } |
| | 868 | X509_free(xs); |
| | 869 | } |
| | 870 | } |
| 848 | 871 | } |
| 849 | 872 | #endif |
| 850 | 873 | |
diff -ur lighttpd-1.4.16.orig/src/mod_fastcgi.c lighttpd-1.4.16/src/mod_fastcgi.c
|
old
|
new
|
|
| 2029 | 2029 | #ifdef USE_OPENSSL |
| 2030 | 2030 | if (srv_sock->is_ssl) { |
| 2031 | 2031 | fcgi_env_add(p->fcgi_env, CONST_STR_LEN("HTTPS"), CONST_STR_LEN("on")); |
| | 2032 | if (con->conf.ssl_verify_peer) { |
| | 2033 | X509 *xs = SSL_get_peer_certificate(con->ssl); |
| | 2034 | if (NULL != xs) { |
| | 2035 | X509_NAME *xn = X509_get_subject_name(xs); |
| | 2036 | X509_NAME_ENTRY *xe; |
| | 2037 | |
| | 2038 | char *xc = X509_NAME_oneline(xn, NULL, 0); |
| | 2039 | fcgi_env_add(p->fcgi_env, CONST_STR_LEN("SSL_CLIENT_S_DN"), xc, strlen(xc)); |
| | 2040 | OPENSSL_free(xc); |
| | 2041 | |
| | 2042 | for (int i = 0; i < X509_NAME_entry_count(xn); i++) { |
| | 2043 | xe = X509_NAME_get_entry(xn, i); |
| | 2044 | buffer *xobjname = buffer_init(); |
| | 2045 | buffer_copy_string(xobjname, "SSL_CLIENT_S_DN_"); |
| | 2046 | int xobjnid = OBJ_obj2nid((ASN1_OBJECT *)X509_NAME_ENTRY_get_object(xe)); |
| | 2047 | const char *xobjsn = OBJ_nid2sn(xobjnid); |
| | 2048 | buffer_append_string(xobjname, xobjsn); |
| | 2049 | fcgi_env_add(p->fcgi_env, CONST_BUF_LEN(xobjname), xe->value->data, strlen((char *)xe->value->data)); |
| | 2050 | buffer_free(xobjname); |
| | 2051 | } |
| | 2052 | X509_free(xs); |
| | 2053 | } |
| | 2054 | } |
| 2032 | 2055 | } |
| 2033 | 2056 | #endif |
| 2034 | 2057 | |
diff -ur lighttpd-1.4.16.orig/src/mod_scgi.c lighttpd-1.4.16/src/mod_scgi.c
|
old
|
new
|
|
| 1561 | 1561 | #ifdef USE_OPENSSL |
| 1562 | 1562 | if (srv_sock->is_ssl) { |
| 1563 | 1563 | scgi_env_add(p->scgi_env, CONST_STR_LEN("HTTPS"), CONST_STR_LEN("on")); |
| | 1564 | if (con->conf.ssl_verify_peer) { |
| | 1565 | X509 *xs = SSL_get_peer_certificate(con->ssl); |
| | 1566 | if (NULL != xs) { |
| | 1567 | X509_NAME *xn = X509_get_subject_name(xs); |
| | 1568 | X509_NAME_ENTRY *xe; |
| | 1569 | |
| | 1570 | char *xc = X509_NAME_oneline(xn, NULL, 0); |
| | 1571 | scgi_env_add(p->scgi_env, CONST_STR_LEN("SSL_CLIENT_S_DN"), xc, strlen(xc)); |
| | 1572 | OPENSSL_free(xc); |
| | 1573 | |
| | 1574 | for (int i = 0; i < X509_NAME_entry_count(xn); i++) { |
| | 1575 | xe = X509_NAME_get_entry(xn, i); |
| | 1576 | buffer *xobjname = buffer_init(); |
| | 1577 | buffer_copy_string(xobjname, "SSL_CLIENT_S_DN_"); |
| | 1578 | int xobjnid = OBJ_obj2nid((ASN1_OBJECT *)X509_NAME_ENTRY_get_object(xe)); |
| | 1579 | const char *xobjsn = OBJ_nid2sn(xobjnid); |
| | 1580 | buffer_append_string(xobjname, xobjsn); |
| | 1581 | scgi_env_add(p->scgi_env, CONST_BUF_LEN(xobjname), xe->value->data, strlen((char *)xe->value->data)); |
| | 1582 | buffer_free(xobjname); |
| | 1583 | } |
| | 1584 | X509_free(xs); |
| | 1585 | } |
| | 1586 | } |
| 1564 | 1587 | } |
| 1565 | 1588 | #endif |
| 1566 | 1589 | |
diff -ur lighttpd-1.4.16.orig/src/network.c lighttpd-1.4.16/src/network.c
|
old
|
new
|
|
| 72 | 72 | buffer *b; |
| 73 | 73 | int is_unix_domain_socket = 0; |
| 74 | 74 | int fd; |
| | 75 | #ifdef USE_OPENSSL |
| | 76 | pid_t pid; |
| | 77 | #endif |
| 75 | 78 | |
| 76 | 79 | #ifdef SO_ACCEPTFILTER |
| 77 | 80 | struct accept_filter_arg afa; |
| … |
… |
|
| 359 | 362 | ERR_error_string(ERR_get_error(), NULL), s->ssl_ca_file); |
| 360 | 363 | return -1; |
| 361 | 364 | } |
| | 365 | if (s->ssl_verify_peer) { |
| | 366 | SSL_CTX_set_client_CA_list( |
| | 367 | s->ssl_ctx, SSL_load_client_CA_file(s->ssl_ca_file->ptr)); |
| | 368 | } |
| 362 | 369 | } |
| 363 | 370 | |
| 364 | 371 | if (SSL_CTX_use_certificate_file(s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) { |
| … |
… |
|
| 380 | 387 | s->ssl_pemfile); |
| 381 | 388 | return -1; |
| 382 | 389 | } |
| | 390 | |
| | 391 | if (s->ssl_verify_peer) { |
| | 392 | SSL_CTX_set_verify(s->ssl_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); |
| | 393 | SSL_CTX_set_verify_depth(s->ssl_ctx, s->ssl_verify_depth); |
| | 394 | } |
| | 395 | |
| | 396 | pid = getpid(); |
| | 397 | if (SSL_CTX_set_session_id_context(s->ssl_ctx, (void*)&pid, sizeof(pid)) != 1) { |
| | 398 | log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", |
| | 399 | ERR_error_string(ERR_get_error(), NULL)); |
| | 400 | return -1; |
| | 401 | } |
| | 402 | |
| 383 | 403 | SSL_CTX_set_default_read_ahead(s->ssl_ctx, 1); |
| 384 | 404 | SSL_CTX_set_mode(s->ssl_ctx, SSL_CTX_get_mode(s->ssl_ctx) | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); |
| 385 | 405 | |