From c27a6417906477778046a6824fdba57d845421be Mon Sep 17 00:00:00 2001 From: helge Date: Fri, 15 Apr 2005 14:17:39 +0000 Subject: [PATCH] improved SSL support git-svn-id: http://svn.opengroupware.org/SOPE/trunk@738 e4a50df8-12e2-0310-a44c-efbce7f8a7e3 --- sope-appserver/mod_ngobjweb/ChangeLog | 7 ++ .../mod_ngobjweb/NGBufferedDescriptor.c | 48 ++++++++++-- sope-appserver/mod_ngobjweb/handler.c | 78 +++++++++++++++++-- 3 files changed, 118 insertions(+), 15 deletions(-) diff --git a/sope-appserver/mod_ngobjweb/ChangeLog b/sope-appserver/mod_ngobjweb/ChangeLog index 76b92f30..65224387 100644 --- a/sope-appserver/mod_ngobjweb/ChangeLog +++ b/sope-appserver/mod_ngobjweb/ChangeLog @@ -1,5 +1,12 @@ 2005-04-15 Helge Hess + * handler.c: deliver Apache SSL environment as HTTP headers, either + using x-webobjects- headers or using SSL_CLIENT_xxx headers (when no + proper x-webobjects- header is known) + + * NGBufferedDescriptor.c: escape headers containing '\r' or '\n' (using + %10, %13), required for transporting the certificate header ... + * GNUmakefile: autolocate apxs2 (tested on SuSE 9.1) * handler.c: minor code cleanups diff --git a/sope-appserver/mod_ngobjweb/NGBufferedDescriptor.c b/sope-appserver/mod_ngobjweb/NGBufferedDescriptor.c index c4ccf0a5..6f54cf36 100644 --- a/sope-appserver/mod_ngobjweb/NGBufferedDescriptor.c +++ b/sope-appserver/mod_ngobjweb/NGBufferedDescriptor.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "NGBufferedDescriptor.h" // returns the number of bytes which where read from the buffer @@ -306,14 +307,47 @@ char NGBufferedDescriptor_writeHttpHeader(NGBufferedDescriptor *self, const unsigned char *_key, const unsigned char *_value) { - if (NGBufferedDescriptor_safeWrite(self, _key, strlen(_key))) { - if (NGBufferedDescriptor_safeWrite(self, ": ", 2)) { - if (NGBufferedDescriptor_safeWrite(self, _value, strlen(_value))) { - if (NGBufferedDescriptor_safeWrite(self, "\r\n", 2)) { - return 1; - } + register unsigned int len; + + if (!NGBufferedDescriptor_safeWrite(self, _key, strlen(_key))) + return 0; + + if (!NGBufferedDescriptor_safeWrite(self, ": ", 2)) + return 0; + + len = strlen(_value); + + /* + Required for deliverying certificates, we encode \n and \r as %10 and %13 + assuming that the certficiate is in base64. To safeguard, we also encode + % as %25. + */ + if (len > 0 && (index(_value, '\n') != NULL || index(_value, '\r') !=NULL)) { + for (len = 0; _value[len] != '\0'; len++) { + switch (_value[len]) { + case '%': + case '\r': + case '\n': { + char buf[4]; + sprintf(buf, "%%%02i", _value[len]); + if (NGBufferedDescriptor_write(self, buf, 3) <= 0) + return 0; + break; + } + default: + if (NGBufferedDescriptor_write(self, &(_value[len]), 1) <= 0) + return 0; + break; } } } - return 0; + else { + if (!NGBufferedDescriptor_safeWrite(self, _value, len)) + return 0; + } + + if (!NGBufferedDescriptor_safeWrite(self, "\r\n", 2)) + return 0; + + return 1; } diff --git a/sope-appserver/mod_ngobjweb/handler.c b/sope-appserver/mod_ngobjweb/handler.c index db16345a..a1e7928a 100644 --- a/sope-appserver/mod_ngobjweb/handler.c +++ b/sope-appserver/mod_ngobjweb/handler.c @@ -541,14 +541,74 @@ int ngobjweb_handler(request_rec *r) { writeError = 1; goto writeErrorHandler; } + + /* SSL environment */ + + if (r->subprocess_env != NULL) { + apr_table_t *env = r->subprocess_env; + const char *s; + + s = apr_table_get(env, "HTTPS"); + if (s != NULL && strncasecmp(s, "on", 2) == 0) { // SSL is one + if (!NGBufferedDescriptor_writeHttpHeader(toApp, + "x-webobjects-https-enabled", + "1")) { + writeError = 1; + goto writeErrorHandler; + } + } + + s = apr_table_get(env, "SSL_CLIENT_CERT"); + if (s != NULL) { + const apr_array_header_t *array; + apr_table_entry_t *entries; + int i; + + if (!NGBufferedDescriptor_writeHttpHeader(toApp, + "x-webobjects-clients-cert", + s)) { + writeError = 1; + goto writeErrorHandler; + } + + /* deliver all SSL_CLIENT_ env-vars as headers */ + array = apr_table_elts(env); + entries = (apr_table_entry_t *)array->elts; + for (i = 0; i < array->nelts; i++) { + apr_table_entry_t *entry = &(entries[i]); + + if (strncmp(entry->key, "SSL_CLIENT_", 11) != 0) + continue; + if (strncmp(entry->key, "SSL_CLIENT_CERT", 15) == 0) + continue; /* already avail as x-webobjects-clients-cert" */ + + if (!NGBufferedDescriptor_writeHttpHeader(toApp, + entry->key, + entry->val)) { + writeError = 1; + goto writeErrorHandler; + } + } + } - /* - SSL stuff: - x-webobjects-clients-cert - x-webobjects-https-enabled - x-webobjects-https-keysize - x-webobjects-https-secret-keysize - */ + /* keysize, don't know whether mapping is correct? */ + if ((s = apr_table_get(env, "SSL_CIPHER_ALGKEYSIZE")) != NULL) { + if (!NGBufferedDescriptor_writeHttpHeader(toApp, + "x-webobjects-https-secret-keysize", + s)) { + writeError = 1; + goto writeErrorHandler; + } + } + if ((s = apr_table_get(env, "SSL_CIPHER_USEKEYSIZE")) != NULL) { + if (!NGBufferedDescriptor_writeHttpHeader(toApp, + "x-webobjects-https-keysize", + s)) { + writeError = 1; + goto writeErrorHandler; + } + } + } } /* http headers */ @@ -682,6 +742,7 @@ int ngobjweb_handler(request_rec *r) { } #if WITH_LOGGING +#if 0 static void test(void) { fprintf(stderr, "%s: called:\n" @@ -711,9 +772,10 @@ static void test(void) { _logTable(" env", r->subprocess_env); _logTable(" in", r->headers_in); } +#endif static void _logTable(const char *text, apr_table_t *table) { - apr_array_header_t *array; + const apr_array_header_t *array; apr_table_entry_t *entries; int i; -- 2.39.5