Skip to content

Commit 0208af3

Browse files
committed
Fix generation of X-SSL- headers describing client certificate.
* src/http.c (trimwsl): New function. (get_line): return COPY_EOF only if no data has been stored in the buffer. Otherwise, return COPY_OK. (get_content_length, http_response_validate): Use trimwsl. (set_header_from_bio): New function. (add_ssl_headers): Ensure the BIO returns EOF on end of data. Use set_header_from_bio to generate headers describing client certificate.
1 parent bec9c2e commit 0208af3

File tree

1 file changed

+48
-50
lines changed

1 file changed

+48
-50
lines changed

src/http.c

Lines changed: 48 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,14 @@ isws (int c)
241241
{
242242
return c == ' ' || c == '\t';
243243
}
244+
245+
static char const *
246+
trimwsl (char const *s)
247+
{
248+
while (*s && isws (*s))
249+
s++;
250+
return s;
251+
}
244252

245253
static int
246254
submatch_realloc (struct submatch *sm, GENPAT re)
@@ -1162,7 +1170,7 @@ get_line (BIO *in, char *const buf, int bufsize)
11621170
case 0:
11631171
if (BIO_should_retry (in))
11641172
continue;
1165-
return COPY_EOF;
1173+
return i == 0 ? COPY_EOF : COPY_OK;
11661174
case -1:
11671175
return COPY_READ_ERR;
11681176
default:
@@ -1312,15 +1320,11 @@ get_content_length (char const *arg, int mode)
13121320
CONTENT_LENGTH n;
13131321

13141322
if (mode == CL_HEADER)
1315-
{
1316-
while (isws (*arg))
1317-
arg++;
1318-
}
1323+
arg = trimwsl (arg);
13191324

13201325
if (strtoclen (arg, mode == CL_HEADER ? 10 : 16, &n, &p))
13211326
return NO_CONTENT_LENGTH;
1322-
while (isws (*p))
1323-
p++;
1327+
p = (char*) trimwsl (p);
13241328
if (*p)
13251329
{
13261330
if (!(mode == CL_CHUNK && *p == ';'))
@@ -3218,6 +3222,30 @@ add_forwarded_headers (POUND_HTTP *phttp)
32183222
return 0;
32193223
}
32203224

3225+
static int
3226+
set_header_from_bio (BIO *bio, struct http_request *req,
3227+
char const *hdr, struct stringbuf *sb)
3228+
{
3229+
char buf[MAXBUF];
3230+
int rc;
3231+
char *str;
3232+
3233+
if ((rc = get_line (bio, buf, sizeof (buf))) == COPY_OK)
3234+
{
3235+
stringbuf_reset (sb);
3236+
stringbuf_printf (sb, "%s: %s", hdr, trimwsl (buf));
3237+
if ((str = stringbuf_finish (sb)) == NULL
3238+
|| http_header_list_append (&req->headers, str, H_REPLACE))
3239+
{
3240+
return -1;
3241+
}
3242+
}
3243+
else if (rc != COPY_EOF)
3244+
logmsg (LOG_ERR, "(%"PRItid") error reading data: %s",
3245+
POUND_TID (), copy_status_string (rc));
3246+
return 0;
3247+
}
3248+
32213249
static int
32223250
add_ssl_headers (POUND_HTTP *phttp)
32233251
{
@@ -3248,72 +3276,40 @@ add_ssl_headers (POUND_HTTP *phttp)
32483276
if (phttp->lstn->clnt_check > 0 && phttp->x509 != NULL
32493277
&& (bio = BIO_new (BIO_s_mem ())) != NULL)
32503278
{
3279+
int i;
3280+
3281+
BIO_set_mem_eof_return (bio, 0);
32513282
X509_NAME_print_ex (bio, X509_get_subject_name (phttp->x509), 8,
32523283
XN_FLAG_ONELINE & ~ASN1_STRFLGS_ESC_MSB);
3253-
if (get_line (bio, buf, sizeof (buf)) != COPY_OK)
3284+
if (set_header_from_bio (bio, &phttp->request, "X-SSL-Subject", &sb))
32543285
{
32553286
res = -1;
32563287
goto end;
32573288
}
32583289

3259-
stringbuf_printf (&sb, "X-SSL-Subject: %s", buf);
3260-
if ((str = stringbuf_finish (&sb)) == NULL
3261-
|| http_header_list_append (&phttp->request.headers, str, H_REPLACE))
3262-
{
3263-
res = -1;
3264-
goto end;
3265-
}
3266-
stringbuf_reset (&sb);
3267-
32683290
X509_NAME_print_ex (bio, X509_get_issuer_name (phttp->x509), 8,
32693291
XN_FLAG_ONELINE & ~ASN1_STRFLGS_ESC_MSB);
3270-
if (get_line (bio, buf, sizeof (buf)) != COPY_OK)
3271-
{
3272-
res = -1;
3273-
goto end;
3274-
}
3275-
3276-
stringbuf_printf (&sb, "X-SSL-Issuer: %s", buf);
3277-
if ((str = stringbuf_finish (&sb)) == NULL
3278-
|| http_header_list_append (&phttp->request.headers, str, H_REPLACE))
3292+
if (set_header_from_bio (bio, &phttp->request, "X-SSL-Issuer", &sb))
32793293
{
32803294
res = -1;
32813295
goto end;
32823296
}
3283-
stringbuf_reset (&sb);
32843297

32853298
ASN1_TIME_print (bio, X509_get_notBefore (phttp->x509));
3286-
if (get_line (bio, buf, sizeof (buf)) != COPY_OK)
3299+
if (set_header_from_bio (bio, &phttp->request, "X-SSL-notBefore", &sb))
32873300
{
32883301
res = -1;
32893302
goto end;
32903303
}
32913304

3292-
stringbuf_printf (&sb, "X-SSL-notBefore: %s", buf);
3293-
if ((str = stringbuf_finish (&sb)) == NULL
3294-
|| http_header_list_append (&phttp->request.headers, str, H_REPLACE))
3295-
{
3296-
res = -1;
3297-
goto end;
3298-
}
3299-
stringbuf_reset (&sb);
3300-
33013305
ASN1_TIME_print (bio, X509_get_notAfter (phttp->x509));
3302-
if (get_line (bio, buf, sizeof (buf)) != COPY_OK)
3306+
if (set_header_from_bio (bio, &phttp->request, "X-SSL-notAfter", &sb))
33033307
{
33043308
res = -1;
33053309
goto end;
33063310
}
33073311

3308-
stringbuf_printf (&sb, "X-SSL-notAfter: %s", buf);
3309-
if ((str = stringbuf_finish (&sb)) == NULL
3310-
|| http_header_list_append (&phttp->request.headers, str, H_REPLACE))
3311-
{
3312-
res = -1;
3313-
goto end;
3314-
}
33153312
stringbuf_reset (&sb);
3316-
33173313
stringbuf_printf (&sb, "X-SSL-serial: %ld",
33183314
ASN1_INTEGER_get (X509_get_serialNumber (phttp->x509)));
33193315
if ((str = stringbuf_finish (&sb)) == NULL
@@ -3326,9 +3322,13 @@ add_ssl_headers (POUND_HTTP *phttp)
33263322

33273323
PEM_write_bio_X509 (bio, phttp->x509);
33283324
stringbuf_add_string (&sb, "X-SSL-certificate: ");
3325+
i = 0;
33293326
while (get_line (bio, buf, sizeof (buf)) == COPY_OK)
33303327
{
3328+
if (i > 0)
3329+
stringbuf_add_string (&sb, "\n\t");
33313330
stringbuf_add_string (&sb, buf);
3331+
i++;
33323332
}
33333333
if ((str = stringbuf_finish (&sb)) == NULL
33343334
|| http_header_list_append (&phttp->request.headers, str, H_REPLACE))
@@ -3580,7 +3580,7 @@ log_error (POUND_HTTP *phttp, int code, int en, char const *fmt, ...)
35803580
static int
35813581
http_response_validate (struct http_request *req)
35823582
{
3583-
char *str = req->request;
3583+
char const *str = req->request;
35843584
int http_ver;
35853585

35863586
if (!(strncmp (str, "HTTP/1.", 7) == 0 &&
@@ -3589,9 +3589,7 @@ http_response_validate (struct http_request *req)
35893589
return 0;
35903590
req->version = http_ver - '0';
35913591

3592-
for (str += 8; isws (*str); str++)
3593-
if (!*str)
3594-
return 0;
3592+
str = trimwsl (str + 8);
35953593

35963594
switch (str[0])
35973595
{

0 commit comments

Comments
 (0)