diff options
author | Jakob Schlyter <jakob@cvs.openbsd.org> | 1999-09-30 19:46:11 +0000 |
---|---|---|
committer | Jakob Schlyter <jakob@cvs.openbsd.org> | 1999-09-30 19:46:11 +0000 |
commit | 39c9c04a41c796121b7b8682e589dd4e7e488d2d (patch) | |
tree | 6a06ad5877f7ab0002f23843ca72540dec42447a /usr.sbin | |
parent | f3fd8f672242a9c598438fd69845818db1d2c511 (diff) |
Sync with mod_ssl v2.4.4. ok beck@.
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/httpd/src/CHANGES.SSL | 43 | ||||
-rw-r--r-- | usr.sbin/httpd/src/modules/ssl/mod_ssl.h | 30 | ||||
-rw-r--r-- | usr.sbin/httpd/src/modules/ssl/ssl_engine_kernel.c | 32 | ||||
-rw-r--r-- | usr.sbin/httpd/src/modules/ssl/ssl_engine_mutex.c | 25 | ||||
-rw-r--r-- | usr.sbin/httpd/src/modules/ssl/ssl_engine_vars.c | 37 |
5 files changed, 150 insertions, 17 deletions
diff --git a/usr.sbin/httpd/src/CHANGES.SSL b/usr.sbin/httpd/src/CHANGES.SSL index 00b298731c5..5d1ba553ea3 100644 --- a/usr.sbin/httpd/src/CHANGES.SSL +++ b/usr.sbin/httpd/src/CHANGES.SSL @@ -23,6 +23,49 @@ / __/ |__ _| __ |_____(_) |_| ___________________________________________ + Changes with mod_ssl 2.4.4 (27-Sep-1999 to 28-Sep-1999) + + *) Fixed the `union semun' situation for SSLMutex which was broken in 2.4.3 + because Apache's internal NEED_UNION_SEMUN define is horrible + inconsistent (it was defined only for Solaris although it should be for + a lot more platforms). The correct solution actually is this: Some + platforms have a `union semun' pre-defined but Single Unix Specification + (SUSv2) says in semctl(2): `If required, it is of type union semun, + which the application program must explicitly declare'. So we have to + define it always ourself to avoid problems (but under a different name + to avoid a namespace clash, of course). + + *) Fixed `make certificate VIEW=1': nested quotes are + disliked by strict(er) Bourne shell flavors. + + Changes with mod_ssl 2.4.3 (06-Sep-1999 to 27-Sep-1999) + + *) Upgraded pkg.contrib/gid-mkcert.sh to use OpenSSL + instead of SSLeay+cafix+pkcs12. + + *) Enabled SSL_USE_SEM (Semaphore based SSLMutex) now explicitly + for FreeBSD, NetBSD, OpenBSD, Linux and Solaris. + + *) Fixed ``SSL_CLIENT_CERT_CHAIN<n>'' variable generation under + ``SSLOptions +ExportOptions''. + + *) Added new ``SSL_CLIENT_VERIFY'' variable which can be used with + SSLRequire to manually check the verify results under ``SSLVerifyClient + optional'' in order to redirect to an enrollment page. + + *) Fixed documentation related to SSL_XXX variables. + + *) Fixed timeout handling of internal OpenSSL cache. + + *) Make sure server.key/ca.key files are stored with explicit + permissions 600 also in conf/ssl.key/ inside the source tree. + + *) Added hint about "Connection refused" problem to FAQ. + + *) Fixed semaphore based SSLMutex variant: the IPC_CREAT fallback was wrong + and the return code semantics were treated incorrectly. Additionally the + ownership of the semaphore is now set, too. + Changes with mod_ssl 2.4.2 (30-Aug-1999 to 06-Sep-1999) *) Added hint about -fPIC vs. -fpic to INSTALL document. diff --git a/usr.sbin/httpd/src/modules/ssl/mod_ssl.h b/usr.sbin/httpd/src/modules/ssl/mod_ssl.h index 812bf6f3c46..5dac8c81ec7 100644 --- a/usr.sbin/httpd/src/modules/ssl/mod_ssl.h +++ b/usr.sbin/httpd/src/modules/ssl/mod_ssl.h @@ -66,6 +66,13 @@ #ifndef MOD_SSL_H #define MOD_SSL_H 1 +/* + * Check whether Extended API (EAPI) is enabled + */ +#ifndef EAPI +#error "mod_ssl requires Extended API (EAPI)" +#endif + /* * Power up our brain... */ @@ -248,12 +255,27 @@ #else #define SSL_MUTEX_LOCK_MODE (_S_IREAD|_S_IWRITE ) #endif -#ifdef USE_SYSVSEM_SERIALIZED_ACCEPT +#if defined(USE_SYSVSEM_SERIALIZED_ACCEPT) ||\ + defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) ||\ + (defined(LINUX) && LINUX >= 2) ||\ + defined(SOLARIS2) #define SSL_CAN_USE_SEM #define SSL_HAVE_IPCSEM #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> +/* + * Some platforms have a `union semun' pre-defined but Single Unix + * Specification (SUSv2) says in semctl(2): `If required, it is of + * type union semun, which the application program must explicitly + * declare'. So we define it always ourself to avoid problems (but under + * a different name to avoid a namespace clash). + */ +union ssl_ipc_semun { + long val; + struct semid_ds *buf; + unsigned short int *array; +}; #endif #ifdef WIN32 #define SSL_CAN_USE_SEM @@ -321,15 +343,11 @@ #endif /* !SSL_USE_SDBM */ /* - * Check for OpenSSL version and whether - * Extended API (EAPI) is enabled + * Check for OpenSSL version */ #if SSL_LIBRARY_VERSION < 0x00903100 #error "mod_ssl requires OpenSSL 0.9.3 or higher" #endif -#ifndef EAPI -#error "mod_ssl requires Extended API (EAPI)" -#endif /* * The own data structures diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_engine_kernel.c b/usr.sbin/httpd/src/modules/ssl/ssl_engine_kernel.c index 3addfce1275..152a61b1a8e 100644 --- a/usr.sbin/httpd/src/modules/ssl/ssl_engine_kernel.c +++ b/usr.sbin/httpd/src/modules/ssl/ssl_engine_kernel.c @@ -209,6 +209,8 @@ void ssl_hook_NewConnection(conn_rec *conn) */ ap_ctx_set(fb->ctx, "ssl::client::dn", NULL); ap_ctx_set(fb->ctx, "ssl::verify::error", NULL); + ap_ctx_set(fb->ctx, "ssl::verify::info", NULL); + SSL_set_verify_result(ssl, X509_V_OK); /* * We have to manage a I/O timeout ourself, because Apache @@ -343,9 +345,12 @@ void ssl_hook_NewConnection(conn_rec *conn) /* * Check for failed client authentication */ - if ((cp = (char *)ap_ctx_get(fb->ctx, "ssl::verify::error")) != NULL) { + if ( SSL_get_verify_result(ssl) != X509_V_OK + || ap_ctx_get(fb->ctx, "ssl::verify::error") != NULL) { + cp = (char *)ap_ctx_get(fb->ctx, "ssl::verify::error"); ssl_log(srvr, SSL_LOG_ERROR|SSL_ADD_SSLERR, - "SSL client authentication failed: %s", cp); + "SSL client authentication failed: %s", + cp != NULL ? cp : "unknown reason"); SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN); SSL_smart_shutdown(ssl); SSL_free(ssl); @@ -1155,6 +1160,7 @@ static const char *ssl_hook_Fixup_vars[] = { "SSL_CIPHER_EXPORT", "SSL_CIPHER_USEKEYSIZE", "SSL_CIPHER_ALGKEYSIZE", + "SSL_CLIENT_VERIFY", "SSL_CLIENT_M_VERSION", "SSL_CLIENT_M_SERIAL", "SSL_CLIENT_V_START", @@ -1210,6 +1216,8 @@ int ssl_hook_Fixup(request_rec *r) table *e = r->subprocess_env; char *var; char *val; + STACK_OF(X509) *sk; + SSL *ssl; int i; /* @@ -1217,7 +1225,7 @@ int ssl_hook_Fixup(request_rec *r) */ if (!sc->bEnabled) return DECLINED; - if (ap_ctx_get(r->connection->client->ctx, "ssl") == NULL) + if ((ssl = ap_ctx_get(r->connection->client->ctx, "ssl")) == NULL) return DECLINED; /* @@ -1235,10 +1243,17 @@ int ssl_hook_Fixup(request_rec *r) * On-demand bloat up the SSI/CGI environment with certificate data */ if (dc->nOptions & SSL_OPT_EXPORTCERTDATA) { - val = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CLIENT_CERT"); - ap_table_set(e, "SSL_CLIENT_CERT", val); val = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_SERVER_CERT"); ap_table_set(e, "SSL_SERVER_CERT", val); + val = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CLIENT_CERT"); + ap_table_set(e, "SSL_CLIENT_CERT", val); + sk = SSL_get_peer_cert_chain(ssl); + for (i = 0; i < sk_X509_num(sk); i++) { + var = ap_psprintf(r->pool, "SSL_CLIENT_CERT_CHAIN_%d", i); + val = ssl_var_lookup(r->pool, r->server, r->connection, r, var); + if (val != NULL) + ap_table_set(e, var, val); + } } /* @@ -1409,6 +1424,7 @@ int ssl_callback_SSLVerify(int ok, X509_STORE_CTX *ctx) ssl_log(s, SSL_LOG_TRACE, "Certificate Verification: Verifiable Issuer is configured as " "optional, therefore we're accepting the certificate"); + ap_ctx_set(conn->client->ctx, "ssl::verify::info", "GENEROUS"); ok = TRUE; } @@ -1417,7 +1433,8 @@ int ssl_callback_SSLVerify(int ok, X509_STORE_CTX *ctx) */ if (ok) { ok = ssl_callback_SSLVerify_CRL(ok, ctx, s); - errnum = X509_STORE_CTX_get_error(ctx); + if (!ok) + errnum = X509_STORE_CTX_get_error(ctx); } /* @@ -1643,13 +1660,14 @@ int ssl_callback_NewSessionCacheEntry(SSL *ssl, SSL_SESSION *pNew) * Set the timeout also for the internal OpenSSL cache, because this way * our inter-process cache is consulted only when it's really necessary. */ - t = (SSL_get_time(pNew) + sc->nSessionCacheTimeout); + t = sc->nSessionCacheTimeout; SSL_set_timeout(pNew, t); /* * Store the SSL_SESSION in the inter-process cache with the * same expire time, so it expires automatically there, too. */ + t = (SSL_get_time(pNew) + sc->nSessionCacheTimeout); rc = ssl_scache_store(s, pNew, t); /* diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_engine_mutex.c b/usr.sbin/httpd/src/modules/ssl/ssl_engine_mutex.c index 266c797649b..2f5eca251e7 100644 --- a/usr.sbin/httpd/src/modules/ssl/ssl_engine_mutex.c +++ b/usr.sbin/httpd/src/modules/ssl/ssl_engine_mutex.c @@ -275,16 +275,35 @@ void ssl_mutex_sem_create(server_rec *s, pool *p) #ifdef SSL_CAN_USE_SEM int semid; SSLModConfigRec *mc = myModConfig(); +#ifdef SSL_HAVE_IPCSEM + union ssl_ipc_semun semctlarg; + struct semid_ds semctlbuf; +#endif #ifdef SSL_HAVE_IPCSEM semid = semget(IPC_PRIVATE, 1, IPC_CREAT|IPC_EXCL|S_IRUSR|S_IWUSR); if (semid == -1 && errno == EEXIST) - semid = semget(IPC_PRIVATE, 1, IPC_CREAT|IPC_EXCL|S_IRUSR|S_IWUSR); + semid = semget(IPC_PRIVATE, 1, IPC_EXCL|S_IRUSR|S_IWUSR); if (semid == -1) { ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO, "Parent process could not create private SSLMutex semaphore"); ssl_die(); } + semctlarg.val = 0; + if (semctl(semid, 0, SETVAL, semctlarg) < 0) { + ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO, + "Parent process could not initialize SSLMutex semaphore value"); + ssl_die(); + } + semctlbuf.sem_perm.uid = ap_user_id; + semctlbuf.sem_perm.gid = ap_group_id; + semctlbuf.sem_perm.mode = 0660; + semctlarg.buf = &semctlbuf; + if (semctl(semid, 0, IPC_SET, semctlarg) < 0) { + ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO, + "Parent process could not set permissions for SSLMutex semaphore"); + ssl_die(); + } #endif #ifdef SSL_HAVE_W32SEM semid = (int)ap_create_mutex("mod_ssl_mutex"); @@ -333,7 +352,7 @@ BOOL ssl_mutex_sem_acquire(void) { 0, 1, SEM_UNDO } /* increment semaphore */ }; - rc = semop(mc->nMutexSEMID, sb, 2); + rc = (semop(mc->nMutexSEMID, sb, 2) == 0); #endif #ifdef SSL_HAVE_W32SEM rc = (ap_acquire_mutex((mutex *)mc->nMutexSEMID) == 0); @@ -353,7 +372,7 @@ BOOL ssl_mutex_sem_release(void) { 0, -1, SEM_UNDO } /* decrements semaphore */ }; - rc = semop(mc->nMutexSEMID, sb, 1); + rc = (semop(mc->nMutexSEMID, sb, 1) == 0); #endif #ifdef SSL_HAVE_W32SEM rc = ap_release_mutex((mutex *)mc->nMutexSEMID); diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_engine_vars.c b/usr.sbin/httpd/src/modules/ssl/ssl_engine_vars.c index e0c2c817c89..b5d84ae6e15 100644 --- a/usr.sbin/httpd/src/modules/ssl/ssl_engine_vars.c +++ b/usr.sbin/httpd/src/modules/ssl/ssl_engine_vars.c @@ -79,6 +79,7 @@ static char *ssl_var_lookup_ssl_cert_valid(pool *p, ASN1_UTCTIME *tm); static char *ssl_var_lookup_ssl_cert_serial(pool *p, X509 *xs); static char *ssl_var_lookup_ssl_cert_chain(pool *p, STACK_OF(X509) *sk, char *var); static char *ssl_var_lookup_ssl_cert_PEM(pool *p, X509 *xs); +static char *ssl_var_lookup_ssl_cert_verify(pool *p, conn_rec *c); static char *ssl_var_lookup_ssl_cipher(pool *p, conn_rec *c, char *var); static void ssl_var_lookup_ssl_cipher_bits(char *cipher, int *usekeysize, int *algkeysize); static char *ssl_var_lookup_ssl_version(pool *p, char *var); @@ -303,6 +304,9 @@ static char *ssl_var_lookup_ssl(pool *p, conn_rec *c, char *var) sk = SSL_get_peer_cert_chain(ssl); result = ssl_var_lookup_ssl_cert_chain(p, sk, var+17); } + else if (ssl != NULL && strcEQ(var, "CLIENT_VERIFY")) { + result = ssl_var_lookup_ssl_cert_verify(p, c); + } else if (ssl != NULL && strlen(var) > 7 && strcEQn(var, "CLIENT_", 7)) { if ((xs = SSL_get_peer_certificate(ssl)) != NULL) result = ssl_var_lookup_ssl_cert(p, xs, var+7); @@ -468,7 +472,7 @@ static char *ssl_var_lookup_ssl_cert_chain(pool *p, STACK_OF(X509) *sk, char *va if (strspn(var, "0123456789") == strlen(var)) { n = atoi(var); - if (sk_X509_num(sk) >= n) { + if (n < sk_X509_num(sk)) { xs = sk_X509_value(sk, n); result = ssl_var_lookup_ssl_cert_PEM(p, xs); } @@ -494,6 +498,37 @@ static char *ssl_var_lookup_ssl_cert_PEM(pool *p, X509 *xs) return result; } +static char *ssl_var_lookup_ssl_cert_verify(pool *p, conn_rec *c) +{ + char *result; + long vrc; + char *verr; + char *vinfo; + SSL *ssl; + X509 *xs; + + result = NULL; + ssl = ap_ctx_get(c->client->ctx, "ssl"); + verr = ap_ctx_get(c->client->ctx, "ssl::verify::error"); + vinfo = ap_ctx_get(c->client->ctx, "ssl::verify::info"); + vrc = SSL_get_verify_result(ssl); + xs = SSL_get_peer_certificate(ssl); + + if (vrc == X509_V_OK && verr == NULL && vinfo == NULL && xs == NULL) + /* no client verification done at all */ + result = "NONE"; + else if (vrc == X509_V_OK && verr == NULL && vinfo == NULL && xs != NULL) + /* client verification done successful */ + result = "SUCCESS"; + else if (vrc == X509_V_OK && vinfo != NULL && strEQ(vinfo, "GENEROUS")) + /* client verification done in generous way */ + result = "GENEROUS"; + else + /* client verification failed */ + result = ap_psprintf(p, "FAILED:%s", verr); + return result; +} + static char *ssl_var_lookup_ssl_cipher(pool *p, conn_rec *c, char *var) { char *result; |