Greetings OpenCA developers!
We have recently been looking into utilizing the OpenCA ocsp daemon for
our own CA and have found it most useful.
We did run into some issues with both bugs and features.
After running the daemon under a small bit of load we found that the
daemon would crash at random intervals - after a quick glance at the
source it seems that OpenSSL was not being initialized in a thread safe
manner. This fix is included within the patch.
We also needed the ability for the code to handle GET style methods for
ocsp requests. After looking over the current http handling code it was
determined that cleaning up and re-factoring the http processing
functionality may be in order. This was also included within the patch.
In order to facilitate the GET requests I had to add a new flag "-u"
where an administrator can specify the root URI (e.g., -u /ocsp/) so the
code knows to read the encoded data found afterwards.
I hope that you find these changes useful, and I thank you for the great
project!
~Mark
diff -Naur ../openca-ocspd-1.5.1-rc1/src/Makefile.in ./src/Makefile.in
--- ../openca-ocspd-1.5.1-rc1/src/Makefile.in 2006-10-14 10:34:53.000000000
-0400
+++ ./src/Makefile.in 2009-06-05 16:03:44.000000000 -0400
@@ -63,9 +63,9 @@
configuration.c configuration.h crl.h crl.c support.c \
support.h crypto.c crypto.h http_client.c http_client.h core.h \
threads.h sock.h structs.h core.c sock.c threads.c ocsp_db.h \
- hash-db.c ocspd_engine.c ocspd_engine.h
+ hash-db.c ocspd_engine.c ocspd_engine.h ocsp_http.c ocsp_http.h
@have_engine_t...@am__objects_1 = ocspd_engine.$(OBJEXT)
-am_ocspd_OBJECTS = ocspd.$(OBJEXT) ocsp_response.$(OBJEXT) \
+am_ocspd_OBJECTS = ocspd.$(OBJEXT) ocsp_http.$(OBJEXT) ocsp_response.$(OBJEXT)
\
ocsp_request.$(OBJEXT) configuration.$(OBJEXT) crl.$(OBJEXT) \
support.$(OBJEXT) crypto.$(OBJEXT) http_client.$(OBJEXT) \
core.$(OBJEXT) sock.$(OBJEXT) threads.$(OBJEXT) \
@@ -288,6 +288,7 @@
#
ocspd_SOURCES = \
ocspd.c ocspd.h general.h ocsp_codes.h \
+ ocsp_http.c ocsp_http.h \
ocsp_response.c ocsp_response.h \
ocsp_request.c ocsp_request.h \
configuration.c configuration.h \
@@ -402,6 +403,7 @@
@AMDEP_TRUE@@am__include@ @am__qu...@./$(DEPDIR)/hash-db...@am__quote@
@AMDEP_TRUE@@am__include@ @am__qu...@./$(DEPDIR)/http_client...@am__quote@
@AMDEP_TRUE@@am__include@ @am__qu...@./$(DEPDIR)/ocsp_request...@am__quote@
+...@amdep_true@@am__include@ @am__qu...@./$(DEPDIR)/ocsp_http...@am__quote@
@AMDEP_TRUE@@am__include@ @am__qu...@./$(DEPDIR)/ocsp_response...@am__quote@
@AMDEP_TRUE@@am__include@ @am__qu...@./$(DEPDIR)/ocspd...@am__quote@
@AMDEP_TRUE@@am__include@ @am__qu...@./$(DEPDIR)/ocspd_engine...@am__quote@
diff -Naur ../openca-ocspd-1.5.1-rc1/src/core.c ./src/core.c
--- ../openca-ocspd-1.5.1-rc1/src/core.c 2006-10-21 10:50:32.000000000
-0400
+++ ./src/core.c 2009-06-05 16:03:44.000000000 -0400
@@ -13,10 +13,20 @@
extern OCSPD_CONFIG *ocspd_conf;
pthread_mutex_t crl_lock = PTHREAD_MUTEX_INITIALIZER;
-
pthread_mutex_t clifd_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t clifd_cond;
+pthread_mutex_t *thread_locks;
+
+unsigned long openssl_thread_id() {
+ return (unsigned long) pthread_self();
+}
+void openssl_thread_lock( int mode, int lock_id, const char* file, int line ) {
+ if ( mode & CRYPTO_LOCK )
+ pthread_mutex_lock( &thread_locks[lock_id] );
+ else
+ pthread_mutex_unlock( &thread_locks[lock_id] );
+}
int start_threaded_server ( char * bind_s, char * port_s, int nthreads,
OCSPD_CONFIG * ocspd_conf ) {
@@ -77,6 +87,23 @@
ocspd_conf->iget = ocspd_conf->iput = 0;
+ int num_thread_locks = CRYPTO_num_locks();
+ thread_locks = calloc( sizeof( pthread_mutex_t ),
+ num_thread_locks );
+
+ for (i = 0; i < num_thread_locks; i++)
+ {
+ if ( pthread_mutex_init( &thread_locks[i], NULL ) )
+ {
+ fprintf(stderr, "Unable to create mutex\n");
+ exit(80);
+ }
+ }
+
+ CRYPTO_set_locking_callback( &openssl_thread_lock );
+ CRYPTO_set_id_callback( &openssl_thread_id );
+
+
for( i = 0; i < ocspd_conf->nthreads; i++ ) {
if(thread_make(i) != 0 ) {
syslog(LOG_ERR,
@@ -86,6 +113,7 @@
}
}
+
/* Register the alarm handler */
set_alrm_handler();
@@ -178,6 +206,8 @@
return 1;
}
+
+
void handle_sighup ( int i ) {
syslog( LOG_ERR,
diff -Naur ../openca-ocspd-1.5.1-rc1/src/general.h ./src/general.h
--- ../openca-ocspd-1.5.1-rc1/src/general.h 2006-10-21 08:53:55.000000000
-0400
+++ ./src/general.h 2009-06-05 16:03:44.000000000 -0400
@@ -381,6 +381,7 @@
STACK *pre_cmds;
STACK *post_cmds;
#endif
+ char *base_uri;
} OCSPD_CONFIG;
#define CRL_REASON_UNSPECIFIED 0
diff -Naur ../openca-ocspd-1.5.1-rc1/src/ocsp_http.c ./src/ocsp_http.c
--- ../openca-ocspd-1.5.1-rc1/src/ocsp_http.c 1969-12-31 19:00:00.000000000
-0500
+++ ./src/ocsp_http.c 2009-06-08 12:13:43.000000000 -0400
@@ -0,0 +1,573 @@
+#include <strings.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+
+#include "core.h"
+#include "threads.h"
+#include "sock.h"
+
+#include "ocsp_request.h"
+#include "ocsp_http.h"
+
+extern OCSPD_CONFIG *ocspd_conf;
+
+http_method_t
+decode_http_method(const char *str, int len, int *error)
+{
+ http_method_t method;
+
+ switch (*str) {
+ case 'p':
+ case 'P':
+ if (len < 5) {
+ *error = HTTP_HEADER_TRUNCATED;
+ return METHOD_ERROR;
+ }
+
+ if (strncasecmp(str, "POST ", 5)) {
+ *error = HTTP_INVALID_METHOD;
+ return METHOD_ERROR;
+ }
+
+ method = METHOD_POST;
+ break;
+ case 'g':
+ case 'G':
+ if (len < 4) {
+ *error = HTTP_HEADER_TRUNCATED;
+ return METHOD_ERROR;
+ }
+
+ if (strncasecmp(str, "GET ", 4)) {
+ *error = HTTP_INVALID_METHOD;
+ return METHOD_ERROR;
+ }
+
+ method = METHOD_GET;
+ break;
+ default:
+ *error = HTTP_INVALID_METHOD;
+ return METHOD_ERROR;
+ }
+
+ return method;
+}
+
+char *
+http_expand_hex(const char *hexstr)
+{
+ switch (strtol(hexstr, NULL, 16)) {
+ case 0x24:
+ return "$";
+ case 0x26:
+ return "&";
+ case 0x2B:
+ return "+";
+ case 0x2C:
+ return ",";
+ case 0x2F:
+ return "/";
+ case 0x3A:
+ return ":";
+ case 0x3B:
+ return ";";
+ case 0x3D:
+ return "=";
+ case 0x3F:
+ return "?";
+ case 0x40:
+ return "@";
+ case 0x20:
+ return " ";
+ case 0x22:
+ return "\"";
+ case 0x3C:
+ return "<";
+ case 0x3E:
+ return ">";
+ case 0x23:
+ return "#";
+ case 0x25:
+ return "%";
+ case 0x7b:
+ return "{";
+ case 0x7d:
+ return "}";
+ case 0x7c:
+ return "|";
+ case 0x5c:
+ return "\\";
+ case 0x5e:
+ return "^";
+ case 0x7e:
+ return "~";
+ case 0x5B:
+ return "[";
+ case 0x5D:
+ return "]";
+ case 0x60:
+ return "`";
+ default:
+ return NULL;
+ }
+ return NULL;
+}
+
+char *
+http_decode_base64(char *input, int len, int *tlen)
+{
+ BIO *bio,
+ *b64;
+ char *outbuf;
+ int inlen;
+
+ if (!(outbuf = malloc(4096))) {
+ *tlen = -1;
+ return NULL;
+ }
+
+ memset(outbuf, 0, 4096);
+
+ b64 = BIO_new(BIO_f_base64());
+ bio = BIO_new_mem_buf(input, len);
+ bio = BIO_push(b64, bio);
+
+ while ((inlen = BIO_read(bio, outbuf, 4096)) > 0)
+ *tlen += inlen;
+
+ BIO_free_all(bio);
+
+ return outbuf;
+}
+
+char *
+decode_uri(char *in_uri, int len)
+{
+ int i;
+ int current_byte;
+ int characters_written;
+ int outstring_len;
+ char *outstring;
+
+ if (!in_uri || len <= 0)
+ return NULL;
+
+ /*
+ * (len / 64) is the number of newline characters that will need to
+ * be added.
+ *
+ * We also add 2 more bytes to the end for the last \n, and a \0
+ * terminator.
+ */
+
+ outstring_len = (len / 64) + len + 2;
+ characters_written = 0;
+
+ if (!(outstring = malloc(outstring_len)))
+ return NULL;
+
+ memset(outstring, 0, outstring_len);
+
+ current_byte = 0;
+
+ for (i = 0; i < len; i++) {
+ char *data;
+ char *hexstr;
+ char *expanded;
+
+ data = &in_uri[i];
+
+ /*
+ * openssl base64 decoding requires our encoded string to include
+ * newlines after every 64 bytes
+ */
+ if (i > 0 && !(characters_written % 63)) {
+ outstring[current_byte++] = '\n';
+ }
+
+ if (*data != '%') {
+ outstring[current_byte++] = *data;
+ characters_written++;
+ continue;
+ }
+
+ if (i + 2 >= outstring_len) {
+ /*
+ * we can't actually fit a hex set here
+ */
+ outstring[current_byte++] = *data;
+ characters_written++;
+ continue;
+ }
+
+ hexstr = malloc(3);
+ hexstr[0] = data[1];
+ hexstr[1] = data[2];
+ hexstr[2] = '\0';
+
+ expanded = http_expand_hex(hexstr);
+
+ if (expanded) {
+ outstring[current_byte++] = *expanded;
+ i += 2;
+ } else
+ outstring[current_byte++] = *data;
+
+ characters_written++;
+ free(hexstr);
+ }
+
+ outstring[current_byte] = '\n';
+
+ return outstring;
+}
+
+http_rec_t *
+create_http_rec(void)
+{
+ http_rec_t *rec;
+
+ if (!(rec = malloc(sizeof(http_rec_t))))
+ return NULL;
+
+ memset(rec, 0, sizeof(http_rec_t));
+ return rec;
+}
+
+void
+free_http_rec(http_rec_t * rec)
+{
+ if (!rec)
+ return;
+
+ if (rec->http_raw_rec)
+ free(rec->http_raw_rec);
+
+ if (rec->http_data)
+ free(rec->http_data);
+
+ free(rec);
+}
+
+int
+decode_http_content_len(char *input_buf, int input_len)
+{
+ /*
+ * return values: -1 error occurred 0 not enough data >0 the length to
+ * read
+ */
+ char *content_sz_raw;
+ char *content_sz_val_raw;
+ char *content_sz_val;
+ char *content_sz_end;
+ int content_sz_val_len;
+ int content_len;
+
+ /*
+ * first find the content-length header
+ */
+ content_sz_raw = strstr(input_buf, "Content-Length: ");
+
+ if (!content_sz_raw)
+ return 0;
+
+ /*
+ * paranoid overflow check
+ */
+ if (content_sz_raw > (char *) (input_buf + input_len))
+ return 0;
+
+ content_sz_val_raw = &content_sz_raw[16];
+
+ if (!content_sz_val_raw)
+ return 0;
+
+ if (content_sz_val_raw > (char *) (input_buf + input_len))
+ return 0;
+
+ /*
+ * find the end of the content-length line
+ */
+ content_sz_end = strstr(content_sz_val_raw, "\r\n");
+
+ if (!content_sz_end)
+ return 0;
+
+ /*
+ * get a general number of bytes to alloc
+ */
+ content_sz_val_len = content_sz_end - content_sz_val_raw;
+
+ if (content_sz_val_len <= 0)
+ return -1;
+
+ if (!(content_sz_val = malloc(content_sz_val_len)))
+ return -1;
+
+ memset(content_sz_val, 0, content_sz_val_len + 1);
+ strncpy(content_sz_val, content_sz_val_raw, content_sz_val_len);
+
+ content_len = atoi(content_sz_val);
+
+ free(content_sz_val);
+
+ if (content_len >= INT_LEAST32_MAX)
+ return -1;
+
+ return content_len;
+}
+
+char *
+decode_http_post_data(char *input_buf, int input_len,
+ int content_len, int *error)
+{
+ char *headers_end;
+ char *payload_start;
+ char *input_buf_end;
+ int current_content_len;
+
+
+ input_buf_end = (char *) (input_buf + input_len);
+
+ /*
+ * find the end of all the headers
+ */
+ headers_end = strstr(input_buf, "\r\n\r\n");
+
+ if (!headers_end)
+ headers_end = strstr(input_buf, "\n\n");
+
+ if (!headers_end) {
+ /*
+ * not enough data? continue on
+ */
+ *error = HTTP_CONTINUE;
+ return NULL;
+ }
+
+ payload_start = headers_end;
+
+ while ((*payload_start == '\n') || (*payload_start == '\r')) {
+ if (payload_start > input_buf_end)
+ break;
+
+ payload_start++;
+ }
+
+ if (payload_start > input_buf_end) {
+ *error = HTTP_OVERFLOW;
+ return NULL;
+ }
+
+ /*
+ * check to see if we have the entire payload as determined by the
+ * content_len
+ */
+ current_content_len = input_buf_end - payload_start;
+
+ if (current_content_len < content_len) {
+ *error = HTTP_CONTINUE;
+ return NULL;
+ }
+
+ if (current_content_len > content_len) {
+ *error = HTTP_OVERFLOW;
+ return NULL;
+ }
+
+ return payload_start;
+}
+
+
+http_rec_t *
+decode_http_post(char *input_buf, int input_len, int *error)
+{
+ int content_len;
+ char *post_data;
+ http_rec_t *rec;
+
+ content_len = decode_http_content_len(input_buf, input_len);
+
+ if (content_len == 0) {
+ *error = HTTP_CONTINUE;
+ return NULL;
+ }
+
+ if (content_len < 0) {
+ *error = HTTP_INVALID_CONTENTLEN;
+ return NULL;
+ }
+
+ post_data = decode_http_post_data(input_buf,
+ input_len, content_len, error);
+
+ if (!post_data)
+ return NULL;
+
+ if (!(rec = create_http_rec())) {
+ *error = HTTP_ALLOC_ERROR;
+ return NULL;
+ }
+
+ rec->method = METHOD_POST;
+ rec->request_len = input_len;
+ rec->content_len = content_len;
+
+ rec->http_raw_rec = malloc(input_len);
+ memcpy(rec->http_raw_rec, input_buf, input_len);
+
+ rec->http_data = malloc(content_len);
+ memcpy(rec->http_data, post_data, content_len);
+
+ return rec;
+}
+
+http_rec_t *
+decode_http_get(char *input_buf, int input_len, int *error)
+{
+ /*
+ * decoding a ocsp GET request is a trivial task. Simply read the
+ * URI, hop past the base_uri, swap reserved characters with the real
+ * values, and base64 decode the string
+ */
+ http_rec_t *rec;
+ char *uri_start;
+ char *uri_end;
+ char *uri;
+ char *decoded_uri;
+ char *unbased_uri;
+ int uri_len;
+ int tlen;
+
+ rec = NULL;
+ tlen = 0;
+
+ /*
+ * lets first find the base URI
+ */
+ uri_start = strstr(input_buf, ocspd_conf->base_uri);
+
+ if (!uri_start) {
+ *error = HTTP_BASEURI_ERROR;
+ return NULL;
+ }
+
+ if (uri_start > (input_buf + input_len)) {
+ *error = HTTP_OVERFLOW;
+ return NULL;
+ }
+
+ /*
+ * increment past the base_uri
+ */
+ uri_start += strlen(ocspd_conf->base_uri);
+
+ /*
+ * find the end of the GET request by looking for the protocol
+ */
+ uri_end = strstr(uri_start, " HTTP/1");
+
+ if (!uri_end) {
+ *error = HTTP_HEADER_TRUNCATED;
+ return NULL;
+ }
+
+ if (uri_end > (input_buf + input_len)) {
+ *error = HTTP_OVERFLOW;
+ return NULL;
+ }
+
+ uri_len = uri_end - uri_start;
+
+ if (!(uri = malloc(uri_len + 1))) {
+ *error = HTTP_ALLOC_ERROR;
+ return NULL;
+ }
+
+ memset(uri, 0, uri_len + 1);
+ memcpy(uri, uri_start, uri_len);
+
+ /*
+ * do our reserved hex encoded swapping with the real thing
+ */
+ decoded_uri = decode_uri(uri, uri_len);
+ free(uri);
+
+ if (!decoded_uri) {
+ *error = HTTP_URI_DECODE;
+ return NULL;
+ }
+
+ /*
+ * now take the input uri and base64 decode
+ */
+ unbased_uri = http_decode_base64(decoded_uri,
+ strlen(decoded_uri), &tlen);
+
+ if (!unbased_uri || tlen <= 0) {
+ *error = HTTP_BASE64_DECODE;
+
+#if 0
+ printf("DECODED %p tlen %d\n", unbased_uri, tlen);
+
+ printf("IN BASE64\n=================\n%s\n=================\n",
+ decoded_uri);
+#endif
+
+ if (unbased_uri)
+ free(unbased_uri);
+
+ if (decoded_uri)
+ free(decoded_uri);
+
+ return NULL;
+ }
+
+ if (!(rec = create_http_rec())) {
+ if (decoded_uri)
+ free(decoded_uri);
+
+ if (unbased_uri)
+ free(unbased_uri);
+
+ *error = HTTP_HEADER_TRUNCATED;
+ return NULL;
+ }
+
+ rec->method = METHOD_GET;
+ rec->request_len = input_len;
+ rec->content_len = tlen;
+ rec->http_raw_rec = strdup(input_buf);
+ rec->http_data = unbased_uri;
+
+ if (decoded_uri)
+ free(decoded_uri);
+
+ return rec;
+}
+
+http_rec_t *
+decode_http_request(char *input_buf, int input_len, int *error)
+{
+ http_method_t method;
+ http_rec_t *rec;
+
+ rec = NULL;
+
+ method = decode_http_method(input_buf, input_len, error);
+
+ switch (method) {
+ case METHOD_POST:
+ rec = decode_http_post(input_buf, input_len, error);
+ break;
+ case METHOD_GET:
+ rec = decode_http_get(input_buf, input_len, error);
+ break;
+ default:
+ return NULL;
+ }
+
+ return rec;
+}
diff -Naur ../openca-ocspd-1.5.1-rc1/src/ocsp_http.h ./src/ocsp_http.h
--- ../openca-ocspd-1.5.1-rc1/src/ocsp_http.h 1969-12-31 19:00:00.000000000
-0500
+++ ./src/ocsp_http.h 2009-06-05 16:03:44.000000000 -0400
@@ -0,0 +1,40 @@
+#ifndef __OCSP_HTTP_H
+#define __OCSP_HTTP_H
+
+#define HTTP_CONTINUE 0
+#define HTTP_HEADER_TRUNCATED -1
+#define HTTP_OVERFLOW -2
+#define HTTP_INVALID_CONTENTLEN -3
+#define HTTP_ALLOC_ERROR -4
+#define HTTP_BASEURI_ERROR -5
+#define HTTP_URI_DECODE -6
+#define HTTP_BASE64_DECODE -7
+#define HTTP_INVALID_METHOD -8
+
+typedef enum http_method {
+ METHOD_POST,
+ METHOD_GET,
+ METHOD_ERROR
+} http_method_t;
+
+typedef struct http_rec {
+ http_method_t method;
+ int request_len;
+ int content_len;
+
+ char *http_raw_rec;
+ char *http_data;
+} http_rec_t;
+
+http_method_t decode_http_method(const char *, int, int *);
+char *http_expand_hex(const char *);
+char *http_decode_base64(char *input, int len, int *tlen);
+char *http_decode_uri(char *in_uri, int len);
+http_rec_t *create_http_rec(void);
+void free_http_rec(http_rec_t *rec);
+int decode_http_content_len(char *input_buf, int input_len);
+char *decode_http_post_data(char *input_buf, int input_len, int content_len,
int *error);
+http_rec_t *decode_http_post (char *input_buf, int input_len, int *error);
+http_rec_t *decode_http_get (char *input_buf, int input_len, int *error);
+http_rec_t *decode_http_request(char *input_buf, int input_len, int *error);
+#endif
diff -Naur ../openca-ocspd-1.5.1-rc1/src/ocsp_request.c ./src/ocsp_request.c
--- ../openca-ocspd-1.5.1-rc1/src/ocsp_request.c 2006-10-21
12:39:24.000000000 -0400
+++ ./src/ocsp_request.c 2009-06-05 16:03:44.000000000 -0400
@@ -8,6 +8,7 @@
#include "threads.h"
#include "sock.h"
+#include "ocsp_http.h"
#include "ocsp_request.h"
#define OCSPD_DEF_MAX_SIZE 65535
@@ -18,29 +19,17 @@
extern OCSPD_CONFIG *ocspd_conf;
OCSP_REQUEST * ocspd_req_get_socket ( int connfd, OCSPD_CONFIG *ocspd_conf) {
-
ssize_t fullsize = 0;
ssize_t newsize = 0;
ssize_t maxsize = 0;
- ssize_t cont_len = 0;
- ssize_t full_req_size = 0;
-
char* buf = NULL;
-
- int post = 0;
- int headers = 0;
int sel_ret = 0;
- int cont = 0;
-
- char *pnt = NULL;
- char *pnt_end = NULL;
- char *req_st = NULL;
-
BIO *mem = NULL;
OCSP_REQUEST * req = NULL;
-
struct timeval time_out;
fd_set readset;
+ http_rec_t *http_rec = NULL;
+ int error;
if( !ocspd_conf ) {
return (NULL);
@@ -54,6 +43,8 @@
maxsize = OCSPD_DEF_MAX_SIZE - OCSPD_DEF_MAX_READ;
}
+ error = 0;
+
/* Add the socket to the read set */
FD_ZERO( &readset );
FD_SET (connfd, &readset);
@@ -67,14 +58,7 @@
return(NULL);
}
- cont = 0;
- /*
- while((sel_ret = Select(connfd+1, &readset,
- NULL, NULL, &time_out)) >= 0) {
- */
- full_req_size = 0;
for(;;) {
-
FD_ZERO( &readset );
FD_SET (connfd, &readset);
@@ -106,21 +90,15 @@
return(NULL);
}
- /*
- if( ocspd_conf->debug ) {
- syslog(LOG_ERR, "DEBUG::NETWORK::Select "
- "%d (cont = %d)!", sel_ret, cont);
- }
-
- if( ocspd_conf->debug ) {
- syslog(LOG_ERR, "DEBUG::NETWORK::FD_ISSET "
- "%d", FD_ISSET(connfd, &readset) );
- }
- */
-
- // cont += WAIT_USEC;
-
if (FD_ISSET (connfd, &readset)) {
+ if(fullsize + OCSPD_DEF_MAX_READ >= maxsize)
+ {
+ syslog(LOG_ERR, "ERROR::NET::Socket recv buffer
overflow");
+
+ free(buf);
+ return NULL;
+ }
+
if((newsize = recv(connfd, &(buf[fullsize]),
OCSPD_DEF_MAX_READ, 0 )) == 0 ) {
break;
@@ -139,106 +117,78 @@
break;
}
+
if( ocspd_conf->debug ) {
syslog(LOG_ERR, "DEBUG::NETWORK::recv "
"received %d (conn = %d)!", newsize,
connfd);
}
-
- /*
- if( sel_ret == 0 ) {
- if( (cont/1000) >= ocspd_conf->max_timeout_secs ) {
- if( ocspd_conf->verbose ) {
- syslog(LOG_ERR,
"ERROR::NETWORK::Timeout "
- "reached while reading REQUEST (%d >=
%d)!",
- cont/1000,
ocspd_conf->max_timeout_secs);
- }
-
- break;
- } else {
- continue;
- }
- }
- */
-
- /* Check for headers */
- if( (!cont_len) &&
- ((pnt = strstr(buf, "Content-Length: " )) !=
NULL) ) {
- if((pnt_end = strstr(pnt, "\r\n")) != NULL )
- sscanf((char *) (pnt+16), "%d",
&cont_len );
- if(ocspd_conf->debug) {
- syslog(LOG_ERR, "DEBUG::Got Content Len
[%d]",
- cont_len);
- }
- }
fullsize += newsize;
- if( (!headers) &&
- (((pnt = strstr(buf, "\r\n\r\n")) != NULL) ||
- ((pnt = strstr(buf, "\n\n")) != NULL))
) {
-
- while( (*pnt == '\n') || (*pnt == '\r')) {
- *pnt = '\x0';
- pnt++;
- }
-
- if( !cont_len ) {
- if(ocspd_conf->verbose)
- syslog(LOG_ERR, "ERROR::No "
- "Content-Length"
- " in REQ Headers");
- if(ocspd_conf->debug) {
- fprintf( stderr,"---BEGIN
HEADERS---\n"
- "%s\n"
- "---END HEADERS---\n\n",
- buf );
- }
- free(buf);
- return(NULL);
- }
- req_st = pnt;
- headers = (int) (req_st - buf);
- full_req_size = headers+cont_len;
- }
-
- if( (!post) && (fullsize >= 5 ) &&
- ( strncmp( buf, "POST ", 5) != 0 )) {
-
- /* Got an error - probably not found (?) */
- if( ocspd_conf->verbose) {
- syslog( LOG_ERR, "ERROR::Request::HTTP
method "
- "is not POST");
- }
- free(buf);
- return(NULL);
- }
-
- if( fullsize >= maxsize ) {
- /* Max Reading size exceeded */
- syslog( LOG_ERR,
- "ERROR::Max REQUEST size exceeded [ %d
]",
- maxsize );
- free( buf );
- return(NULL);
- }
-
- if( (full_req_size > 0) &&
- (full_req_size - fullsize < 1 )) {
-
- break;
+ if( fullsize >= maxsize ) {
+ /* Max Reading size exceeded */
+ syslog( LOG_ERR,
+ "ERROR::Max REQUEST size exceeded [ %d
]",
+ maxsize );
+ free( buf );
+ return(NULL);
+ }
+
+ http_rec = decode_http_request(buf, fullsize, &error);
+
+ if(!http_rec)
+ {
+ switch(error)
+ {
+ case HTTP_CONTINUE:
+ continue;
+ case HTTP_HEADER_TRUNCATED:
+ syslog(LOG_ERR, "ERROR::HTTP Header
truncated");
+ free(buf);
+ return NULL;
+ case HTTP_OVERFLOW:
+ syslog(LOG_ERR,
+ "ERROR::HTTP overflow detected");
+ free(buf);
+ return NULL;
+ case HTTP_INVALID_CONTENTLEN:
+ syslog(LOG_ERR,
+ "ERROR::HTTP::POST Invalid
Content-Length");
+ free(buf);
+ return NULL;
+ case HTTP_ALLOC_ERROR:
+ syslog(LOG_ERR,
+ "CRIT::Alloc Could not allocate
memory!!");
+ free(buf);
+ return NULL;
+ case HTTP_BASEURI_ERROR:
+ syslog(LOG_ERR,
+ "ERROR::HTTP::GET Invalid base
URI!!");
+ free(buf);
+ return NULL;
+ case HTTP_URI_DECODE:
+ syslog(LOG_ERR,
+ "ERROR::HTTP::GET Could not decode
the base64 encoded URI");
+ free(buf);
+ return NULL;
+ case HTTP_BASE64_DECODE:
+ syslog(LOG_ERR,
+ "ERROR::HTTP::GET Could not decode
base64 URI");
+ free(buf);
+ return NULL;
+ case HTTP_INVALID_METHOD:
+ syslog(LOG_ERR,
+ "ERROR::HTTP Invalid method in
request");
+ free(buf);
+ return NULL;
+ }
}
+ break;
}
}
- if(ocspd_conf->debug) {
- fprintf( stderr,"---BEGIN HEADERS---\n"
- "%s\n"
- "---END HEADERS---\n\n",
- buf );
- }
-
- if(!(mem = BIO_new_mem_buf(req_st, cont_len) )) {
+ if(!(mem = BIO_new_mem_buf(http_rec->http_data, http_rec->content_len)
)) {
BIO *err = NULL;
if((err = BIO_new(BIO_s_file())) != NULL) {
@@ -247,10 +197,10 @@
BIO_free(err);
}
- syslog( LOG_ERR, "ERROR: Internal memory allocation error!");
+ syslog(LOG_ERR, "ERROR: Internal memory allocation error!");
if(ocspd_conf->debug) {
fprintf(stderr, "ERROR::req_st=%p [len %d]\n",
- req_st, cont_len);
+ http_rec->http_data, http_rec->content_len);
}
} else {
if((req = d2i_OCSP_REQUEST_bio(mem, NULL)) == NULL ) {
@@ -260,16 +210,19 @@
fprintf(stderr, "[len %d] buf=%p -- req_st=%p "
"(fullsize %d - hd_size = %d - "
"rq_size = %d)\n",
- cont_len, buf,
- req_st, fullsize,
- req_st - buf,
- fullsize - (req_st - buf) );
+ http_rec->content_len, buf,
+ http_rec->http_data, fullsize,
+ http_rec->http_data - buf,
+ fullsize - (http_rec->http_data
- buf));
}
}
if(mem) BIO_free (mem);
}
- if( buf ) free (buf);
+ if(buf)
+ free (buf);
+
+ free_http_rec(http_rec);
return (req);
}
diff -Naur ../openca-ocspd-1.5.1-rc1/src/ocspd.c ./src/ocspd.c
--- ../openca-ocspd-1.5.1-rc1/src/ocspd.c 2006-10-21 08:58:10.000000000
-0400
+++ ./src/ocspd.c 2009-06-05 16:03:44.000000000 -0400
@@ -63,6 +63,7 @@
" -md digest - Set digest to be used [md5]\n",
" -k pwd - Password protecting the private key (if any)\n",
" -i passin - Passin arg\n",
+" -u baseuri - Base URI for GET requests (defaults to /)\n",
#ifdef _OLD_HAVE_ENGINE
" -e engine - use engine e, possibly a hardware device.\n",
#endif
@@ -113,6 +114,7 @@
char *pidfile = NULL;
char *chroot_dir = NULL;
char *tmp_s = NULL;
+ char *base_uri = "/";
int keyform = FORMAT_PEM;
/* ADD ENGINE SUPPORT */
@@ -195,6 +197,12 @@
debug=1;
else if (strcmp(*argv,"-d") == 0)
daemon=1;
+ else if (strcmp(*argv,"-u") == 0)
+ {
+ if (--argc < 1) goto bad;
+ base_uri = *(++argv);
+ }
+
else badops = 1;
argc--;
argv++;
@@ -255,6 +263,9 @@
/* Set the CRL checking variables */
ocspd_conf->crl_check_validity = 0;
+
+ /* set the base URI for GET requests */
+ ocspd_conf->base_uri = base_uri;
/* ENGINE support added */
#ifdef HAVE_ENGINE
------------------------------------------------------------------------------
Crystal Reports - New Free Runtime and 30 Day Trial
Check out the new simplified licensing option that enables unlimited
royalty-free distribution of the report engine for externally facing
server and web deployment.
http://p.sf.net/sfu/businessobjects
_______________________________________________
OpenCA-Devel mailing list
OpenCA-Devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openca-devel