#include <stdlib.h>
#include <unistd.h>
#include <string.h>
+#include <stdio.h>
#include "NGBufferedDescriptor.h"
// returns the number of bytes which where read from the buffer
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;
}
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 */
}
#if WITH_LOGGING
+#if 0
static void test(void) {
fprintf(stderr,
"%s: called:\n"
_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;