Browse Source

[multiple] http_header APIs to reduce str copies

master
Glenn Strauss 9 months ago
parent
commit
26f354cb37
  1. 51
      src/http-header-glue.c
  2. 24
      src/http_header.c
  3. 6
      src/http_header.h
  4. 10
      src/http_range.c
  5. 48
      src/mod_auth.c
  6. 7
      src/mod_deflate.c
  7. 12
      src/mod_dirlisting.c
  8. 28
      src/mod_expire.c
  9. 6
      src/mod_extforward.c
  10. 15
      src/mod_geoip.c
  11. 38
      src/mod_gnutls.c
  12. 99
      src/mod_mbedtls.c
  13. 41
      src/mod_nss.c
  14. 76
      src/mod_openssl.c
  15. 53
      src/mod_proxy.c
  16. 86
      src/mod_wolfssl.c
  17. 15
      src/mod_wstunnel.c
  18. 17
      src/response.c

51
src/http-header-glue.c

@ -110,24 +110,24 @@ int http_response_redirect_to_directory(request_st * const r, int status) {
return -1;
}
}
buffer_append_string_encoded(o, CONST_BUF_LEN(&r->uri.path), ENCODING_REL_URI);
buffer_append_string_len(o, CONST_STR_LEN("/"));
if (!buffer_string_is_empty(&r->uri.query)) {
buffer_append_string_len(o, CONST_STR_LEN("?"));
buffer_append_string_buffer(o, &r->uri.query);
}
buffer *vb;
if (status >= 300) {
http_header_response_set(r, HTTP_HEADER_LOCATION,
CONST_STR_LEN("Location"),
CONST_BUF_LEN(o));
r->http_status = status;
r->resp_body_finished = 1;
vb = http_header_response_set_ptr(r, HTTP_HEADER_LOCATION,
CONST_STR_LEN("Location"));
}
else {
http_header_response_set(r, HTTP_HEADER_CONTENT_LOCATION,
CONST_STR_LEN("Content-Location"),
CONST_BUF_LEN(o));
vb = http_header_response_set_ptr(r, HTTP_HEADER_CONTENT_LOCATION,
CONST_STR_LEN("Content-Location"));
}
buffer_copy_buffer(vb, o);
buffer_append_string_encoded(vb, CONST_BUF_LEN(&r->uri.path),
ENCODING_REL_URI);
buffer_append_string_len(vb, CONST_STR_LEN("/"));
if (!buffer_string_is_empty(&r->uri.query)) {
buffer_append_string_len(o, CONST_STR_LEN("?"));
buffer_append_string_buffer(o, &r->uri.query);
}
return 0;
@ -170,16 +170,11 @@ static const buffer * strftime_cache_get(const time_t last_mod) {
const buffer * http_response_set_last_modified(request_st * const r, const time_t lmtime) {
const buffer * const mtime = strftime_cache_get(lmtime);
http_header_response_set(r, HTTP_HEADER_LAST_MODIFIED,
CONST_STR_LEN("Last-Modified"),
CONST_BUF_LEN(mtime));
#if 0
return http_header_response_get(r, HTTP_HEADER_LAST_MODIFIED,
CONST_STR_LEN("Last-Modified"));
#else
return mtime;
#endif
buffer * const vb =
http_header_response_set_ptr(r, HTTP_HEADER_LAST_MODIFIED,
CONST_STR_LEN("Last-Modified"));
buffer_copy_buffer(vb, strftime_cache_get(lmtime));
return vb;
}
@ -423,12 +418,10 @@ void http_response_send_file (request_st * const r, buffer * const path) {
r->http_status = 200;
r->resp_body_finished = 1;
/*(Transfer-Encoding should not have been set at this point)*/
buffer * const tb = r->tmp_buf;
buffer_clear(tb);
buffer_append_int(tb, sce->st.st_size);
http_header_response_set(r, HTTP_HEADER_CONTENT_LENGTH,
CONST_STR_LEN("Content-Length"),
CONST_BUF_LEN(tb));
buffer_append_int(
http_header_response_set_ptr(r, HTTP_HEADER_CONTENT_LENGTH,
CONST_STR_LEN("Content-Length")),
sce->st.st_size);
}
else {
r->http_status = 500;

24
src/http_header.c

@ -209,6 +209,15 @@ buffer * http_header_response_get(const request_st * const r, enum http_header_e
: NULL;
}
buffer * http_header_response_set_ptr(request_st * const r, enum http_header_e id, const char *k, uint32_t klen) {
/* note: caller must not leave buffer empty
* or must call http_header_response_unset() */
light_bset(r->resp_htags, id);
buffer * const vb = array_get_buf_ptr_ext(&r->resp_headers, id, k, klen);
buffer_clear(vb);
return vb;
}
void http_header_response_unset(request_st * const r, enum http_header_e id, const char *k, uint32_t klen) {
if (light_btst(r->resp_htags, id)) {
/* (do not clear bit for HTTP_HEADER_OTHER,
@ -269,6 +278,15 @@ buffer * http_header_request_get(const request_st * const r, enum http_header_e
: NULL;
}
buffer * http_header_request_set_ptr(request_st * const r, enum http_header_e id, const char *k, uint32_t klen) {
/* note: caller must not leave buffer empty
* or must call http_header_request_unset() */
light_bset(r->rqst_htags, id);
buffer * const vb = array_get_buf_ptr_ext(&r->rqst_headers, id, k, klen);
buffer_clear(vb);
return vb;
}
void http_header_request_unset(request_st * const r, enum http_header_e id, const char *k, uint32_t klen) {
if (light_btst(r->rqst_htags, id)) {
/* (do not clear bit for HTTP_HEADER_OTHER,
@ -308,6 +326,12 @@ buffer * http_header_env_get(const request_st * const r, const char *k, uint32_t
return ds && !buffer_string_is_empty(&ds->value) ? &ds->value : NULL;
}
buffer * http_header_env_set_ptr(request_st *r, const char *k, uint32_t klen) {
buffer * const vb = array_get_buf_ptr(&r->env, k, klen);
buffer_clear(vb);
return vb;
}
void http_header_env_set(request_st * const r, const char *k, uint32_t klen, const char *v, uint32_t vlen) {
array_set_key_value(&r->env, k, klen, v, vlen);
}

6
src/http_header.h

@ -102,6 +102,8 @@ int http_header_remove_token (buffer * const b, const char * const m, const uint
__attribute_pure__
buffer * http_header_response_get(const request_st *r, enum http_header_e id, const char *k, uint32_t klen);
__attribute_returns_nonnull__
buffer * http_header_response_set_ptr(request_st *r, enum http_header_e id, const char *k, uint32_t klen);
void http_header_response_unset(request_st *r, enum http_header_e id, const char *k, uint32_t klen);
void http_header_response_set(request_st *r, enum http_header_e id, const char *k, uint32_t klen, const char *v, uint32_t vlen);
void http_header_response_append(request_st *r, enum http_header_e id, const char *k, uint32_t klen, const char *v, uint32_t vlen);
@ -109,12 +111,16 @@ void http_header_response_insert(request_st *r, enum http_header_e id, const cha
__attribute_pure__
buffer * http_header_request_get(const request_st *r, enum http_header_e id, const char *k, uint32_t klen);
__attribute_returns_nonnull__
buffer * http_header_request_set_ptr(request_st *r, enum http_header_e id, const char *k, uint32_t klen);
void http_header_request_unset(request_st *r, enum http_header_e id, const char *k, uint32_t klen);
void http_header_request_set(request_st *r, enum http_header_e id, const char *k, uint32_t klen, const char *v, uint32_t vlen);
void http_header_request_append(request_st *r, enum http_header_e id, const char *k, uint32_t klen, const char *v, uint32_t vlen);
__attribute_pure__
buffer * http_header_env_get(const request_st *r, const char *k, uint32_t klen);
__attribute_returns_nonnull__
buffer * http_header_env_set_ptr(request_st *r, const char *k, uint32_t klen);
void http_header_env_set(request_st *r, const char *k, uint32_t klen, const char *v, uint32_t vlen);
void http_header_env_append(request_st *r, const char *k, uint32_t klen, const char *v, uint32_t vlen);

10
src/http_range.c

@ -309,12 +309,10 @@ http_range_process (request_st * const r, const buffer * const http_range)
http_range_multi(r, ranges, n);
/*(must either set Content-Length or unset prior value, if any)*/
buffer * const tb = r->tmp_buf;
buffer_clear(tb);
buffer_append_int(tb, chunkqueue_length(&r->write_queue));
http_header_response_set(r, HTTP_HEADER_CONTENT_LENGTH,
CONST_STR_LEN("Content-Length"),
CONST_BUF_LEN(tb));
buffer_append_int(
http_header_response_set_ptr(r, HTTP_HEADER_CONTENT_LENGTH,
CONST_STR_LEN("Content-Length")),
chunkqueue_length(&r->write_queue));
return (r->http_status = 206); /* 206 Partial Content */
}

48
src/mod_auth.c

@ -718,19 +718,15 @@ static handler_t mod_auth_send_400_bad_request(request_st * const r) {
}
static handler_t mod_auth_send_401_unauthorized_basic(request_st * const r, const buffer * const realm) {
r->http_status = 401;
r->handler_module = NULL;
buffer * const tb = r->tmp_buf;
buffer_copy_string_len(tb, CONST_STR_LEN("Basic realm=\""));
buffer_append_string_buffer(tb, realm);
buffer_append_string_len(tb, CONST_STR_LEN("\", charset=\"UTF-8\""));
http_header_response_set(r, HTTP_HEADER_WWW_AUTHENTICATE,
CONST_STR_LEN("WWW-Authenticate"),
CONST_BUF_LEN(tb));
return HANDLER_FINISHED;
r->http_status = 401;
r->handler_module = NULL;
buffer * const vb =
http_header_response_set_ptr(r, HTTP_HEADER_WWW_AUTHENTICATE,
CONST_STR_LEN("WWW-Authenticate"));
buffer_copy_string_len(vb, CONST_STR_LEN("Basic realm=\""));
buffer_append_string_buffer(vb, realm);
buffer_append_string_len(vb, CONST_STR_LEN("\", charset=\"UTF-8\""));
return HANDLER_FINISHED;
}
static handler_t mod_auth_check_basic(request_st * const r, void *p_d, const struct http_auth_require_t * const require, const struct http_auth_backend_t * const backend) {
@ -1381,7 +1377,7 @@ static handler_t mod_auth_check_digest(request_st * const r, void *p_d, const st
* data value (included for unique nonces) will be exposed in the nonce
* along with the timestamp, and the additional secret will be used to
* validate that the server generated the nonce using that secret. */
int send_nextnonce;
time_t send_nextnonce;
{
time_t ts = 0;
const unsigned char * const nonce_uns = (unsigned char *)nonce;
@ -1396,7 +1392,7 @@ static handler_t mod_auth_check_digest(request_st * const r, void *p_d, const st
return mod_auth_send_401_unauthorized_digest(r, require, ai.dalgo);
}
send_nextnonce = (cur_ts - ts > 540); /*(9 mins)*/
send_nextnonce = (cur_ts - ts > 540) ? cur_ts : 0; /*(9 mins)*/
if (require->nonce_secret) {
unsigned int rnd = 0;
@ -1495,13 +1491,11 @@ static handler_t mod_auth_check_digest(request_st * const r, void *p_d, const st
}
if (send_nextnonce) {
/*(send nextnonce when expiration is approaching)*/
buffer * const tb = r->tmp_buf;
const time_t cur_ts = log_epoch_secs;
mod_auth_digest_authentication_info(tb, cur_ts, require, ai.dalgo);
http_header_response_set(r, HTTP_HEADER_OTHER,
CONST_STR_LEN("Authentication-Info"),
CONST_BUF_LEN(tb));
/*(send nextnonce when expiration is approaching)*/
mod_auth_digest_authentication_info(
http_header_response_set_ptr(r, HTTP_HEADER_OTHER,
CONST_STR_LEN("Authentication-Info")),
send_nextnonce /*(cur_ts)*/, require, ai.dalgo);
}
http_auth_setenv(r, ai.username, ai.ulen, CONST_STR_LEN("Digest"));
@ -1512,14 +1506,12 @@ static handler_t mod_auth_check_digest(request_st * const r, void *p_d, const st
}
static handler_t mod_auth_send_401_unauthorized_digest(request_st * const r, const struct http_auth_require_t * const require, int nonce_stale) {
buffer * const tb = r->tmp_buf;
mod_auth_digest_www_authenticate(tb, log_epoch_secs, require, nonce_stale);
http_header_response_set(r, HTTP_HEADER_WWW_AUTHENTICATE,
CONST_STR_LEN("WWW-Authenticate"),
CONST_BUF_LEN(tb));
r->http_status = 401;
r->handler_module = NULL;
mod_auth_digest_www_authenticate(
http_header_response_set_ptr(r, HTTP_HEADER_WWW_AUTHENTICATE,
CONST_STR_LEN("WWW-Authenticate")),
log_epoch_secs, require, nonce_stale);
return HANDLER_FINISHED;
}

7
src/mod_deflate.c

@ -1119,11 +1119,10 @@ static void mod_deflate_note_ratio(request_st * const r, const off_t bytes_out,
* for possible logging by mod_accesslog
* (late in response handling, so not seen by most other modules) */
/*(should be called only at end of successful response compression)*/
char ratio[LI_ITOSTRING_LENGTH];
if (0 == bytes_in) return;
size_t len =
li_itostrn(ratio, sizeof(ratio), bytes_out * 100 / bytes_in);
http_header_env_set(r, CONST_STR_LEN("ratio"), ratio, len);
buffer_append_int(
http_header_env_set_ptr(r, CONST_STR_LEN("ratio")),
bytes_out * 100 / bytes_in);
}
static int mod_deflate_stream_end(handler_ctx *hctx) {

12
src/mod_dirlisting.c

@ -1083,14 +1083,14 @@ URIHANDLER_FUNC(mod_dirlisting_subrequest) {
r->resp_body_finished = 1;
buffer * const vb =
http_header_response_set_ptr(r, HTTP_HEADER_CONTENT_TYPE,
CONST_STR_LEN("Content-Type"));
if (buffer_string_is_empty(p->conf.encoding)) {
http_header_response_set(r, HTTP_HEADER_CONTENT_TYPE,
CONST_STR_LEN("Content-Type"),
CONST_STR_LEN("text/html"));
buffer_copy_string_len(vb, CONST_STR_LEN("text/html"));
} else {
buffer_copy_string_len(r->tmp_buf, CONST_STR_LEN("text/html; charset="));
buffer_append_string_buffer(r->tmp_buf, p->conf.encoding);
http_header_response_set(r, HTTP_HEADER_CONTENT_TYPE, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(r->tmp_buf));
buffer_copy_string_len(vb, CONST_STR_LEN("text/html; charset="));
buffer_append_string_buffer(vb, p->conf.encoding);
}
return HANDLER_FINISHED;

28
src/mod_expire.c

@ -270,7 +270,7 @@ SETDEFAULTS_FUNC(mod_expire_set_defaults) {
REQUEST_FUNC(mod_expire_handler) {
plugin_data *p = p_d;
const buffer *vb;
buffer *vb;
const data_string *ds;
/* Add caching headers only to http_status 200 OK or 206 Partial Content */
@ -310,23 +310,21 @@ REQUEST_FUNC(mod_expire_handler) {
expires += st->st_mtime;
}
/* expires should be at least cur_ts */
if (expires < cur_ts) expires = cur_ts;
/* expires should be at least cur_ts */
if (expires < cur_ts) expires = cur_ts;
buffer * const tb = r->tmp_buf;
struct tm tm;
struct tm tm;
/* HTTP/1.0 */
buffer_clear(tb);
buffer_append_strftime(tb, "%a, %d %b %Y %H:%M:%S GMT", gmtime_r(&expires, &tm));
http_header_response_set(r, HTTP_HEADER_EXPIRES,
CONST_STR_LEN("Expires"),
CONST_BUF_LEN(tb));
/* HTTP/1.0 */
vb = http_header_response_set_ptr(r, HTTP_HEADER_EXPIRES,
CONST_STR_LEN("Expires"));
buffer_append_strftime(vb, "%a, %d %b %Y %H:%M:%S GMT", gmtime_r(&expires,&tm));
/* HTTP/1.1 */
buffer_copy_string_len(tb, CONST_STR_LEN("max-age="));
buffer_append_int(tb, expires - cur_ts); /* as expires >= cur_ts the difference is >= 0 */
http_header_response_set(r, HTTP_HEADER_CACHE_CONTROL, CONST_STR_LEN("Cache-Control"), CONST_BUF_LEN(tb));
/* HTTP/1.1 */
vb = http_header_response_set_ptr(r, HTTP_HEADER_CACHE_CONTROL,
CONST_STR_LEN("Cache-Control"));
buffer_append_string_len(vb, CONST_STR_LEN("max-age="));
buffer_append_int(vb, expires - cur_ts);
return HANDLER_GO_ON;
}

6
src/mod_extforward.c

@ -1018,8 +1018,9 @@ static handler_t mod_extforward_Forwarded (request_st * const r, plugin_data * c
&& !light_btst(r->rqst_htags, HTTP_HEADER_X_FORWARDED_FOR)) {
/* create X-Forwarded-For if not present
* (and at least original connecting IP is a trusted proxy) */
buffer *xff = r->tmp_buf;
buffer_clear(xff);
buffer * const xff =
http_header_request_set_ptr(r, HTTP_HEADER_X_FORWARDED_FOR,
CONST_STR_LEN("X-Forwarded-For"));
for (j = 0; j < used; ) {
if (-1 == offsets[j]) { ++j; continue; }
if (3 == offsets[j+1]
@ -1050,7 +1051,6 @@ static handler_t mod_extforward_Forwarded (request_st * const r, plugin_data * c
}
j += 4; /*(k, klen, v, vlen come in sets of 4)*/
}
http_header_request_set(r, HTTP_HEADER_X_FORWARDED_FOR, CONST_STR_LEN("X-Forwarded-For"), CONST_BUF_LEN(xff));
}
#endif

15
src/mod_geoip.c

@ -243,6 +243,9 @@ static handler_t mod_geoip_query (request_st * const r, plugin_data * const p) {
http_header_env_set(r, CONST_STR_LEN("GEOIP_CITY_NAME"), gir->city, strlen(gir->city));
http_header_env_set(r, CONST_STR_LEN("GEOIP_CITY_POSTAL_CODE"), gir->postal_code, strlen(gir->postal_code));
buffer_append_int(http_header_env_set_ptr(r, CONST_STR_LEN("GEOIP_CITY_DMA_CODE")), (intmax_t)gir->dma_code);
buffer_append_int(http_header_env_set_ptr(r, CONST_STR_LEN("GEOIP_CITY_AREA_CODE")), (intmax_t)gir->area_code);
{
char latitude[32];
snprintf(latitude, sizeof(latitude), "%f", gir->latitude);
@ -255,18 +258,6 @@ static handler_t mod_geoip_query (request_st * const r, plugin_data * const p) {
http_header_env_set(r, CONST_STR_LEN("GEOIP_CITY_LONG_LATITUDE"), long_latitude, strlen(long_latitude));
}
{
char dc[LI_ITOSTRING_LENGTH];
http_header_env_set(r, CONST_STR_LEN("GEOIP_CITY_DMA_CODE"),
dc, li_utostrn(dc, sizeof(dc), gir->dma_code));
}
{
char ac[LI_ITOSTRING_LENGTH];
http_header_env_set(r, CONST_STR_LEN("GEOIP_CITY_AREA_CODE"),
ac, li_utostrn(ac, sizeof(ac), gir->area_code));
}
GeoIPRecord_delete(gir);
}

38
src/mod_gnutls.c

@ -2713,22 +2713,17 @@ https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx)
gnutls_session_t ssl = hctx->ssl;
unsigned int crt_size = 0;
const gnutls_datum_t *crts;
gnutls_x509_crt_t crt;
buffer * const tb = r->tmp_buf;
char buf[513]; /*(512+1 for li_tohex_uc())*/
size_t sz;
buffer *vb = http_header_env_set_ptr(r, CONST_STR_LEN("SSL_CLIENT_VERIFY"));
if (hctx->verify_status != ~0u)
crts = gnutls_certificate_get_peers(ssl, &crt_size);
if (0 == crt_size) { /* || hctx->verify_status == ~0u) */
/*(e.g. no cert, or verify result not available)*/
http_header_env_set(r,
CONST_STR_LEN("SSL_CLIENT_VERIFY"),
CONST_STR_LEN("NONE"));
buffer_copy_string_len(vb, CONST_STR_LEN("NONE"));
return;
}
else if (0 != hctx->verify_status) {
buffer_copy_string_len(tb, CONST_STR_LEN("FAILED:"));
buffer_copy_string_len(vb, CONST_STR_LEN("FAILED:"));
#if GNUTLS_VERSION_NUMBER >= 0x030104
/* get failure string and translate newline to ':', removing last one */
/* (preserving behavior from mod_openssl) */
@ -2736,24 +2731,20 @@ https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx)
if (gnutls_certificate_verification_status_print(hctx->verify_status,
GNUTLS_CRT_X509,
&msg, 0) >= 0) {
sz = msg.size-1; /* '\0'-terminated string */
size_t sz = msg.size-1; /* '\0'-terminated string */
for (char *nl=(char *)msg.data; NULL != (nl=strchr(nl, '\n')); ++nl)
nl[0] = ('\0' == nl[1] ? (--sz, '\0') : ':');
buffer_append_string_len(tb, (char *)msg.data, sz);
buffer_append_string_len(vb, (char *)msg.data, sz);
}
if (msg.data) gnutls_free(msg.data);
#endif
http_header_env_set(r,
CONST_STR_LEN("SSL_CLIENT_VERIFY"),
CONST_BUF_LEN(tb));
return;
}
else {
http_header_env_set(r,
CONST_STR_LEN("SSL_CLIENT_VERIFY"),
CONST_STR_LEN("SUCCESS"));
buffer_copy_string_len(vb, CONST_STR_LEN("SUCCESS"));
}
gnutls_x509_crt_t crt;
if (gnutls_x509_crt_init(&crt) < 0)
return;
if (gnutls_x509_crt_import(crt, &crts[0], GNUTLS_X509_FMT_DER) < 0) {
@ -2763,6 +2754,7 @@ https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx)
int rc;
gnutls_datum_t d = { NULL, 0 };
char buf[512];
/*rc = gnutls_x509_crt_print(cert, GNUTLS_CRT_PRINT_ONELINE, &d);*//* ??? */
#if GNUTLS_VERSION_NUMBER < 0x030507
d.data = buf;
@ -2782,13 +2774,11 @@ https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx)
if (rc >= 0)
https_add_ssl_client_subject(r, dn);
sz = sizeof(buf)/2;
if (gnutls_x509_crt_get_serial(crt, buf+sz, &sz) >= 0) {
li_tohex_uc(buf, sizeof(buf), buf+(sizeof(buf)/2), sz);
http_header_env_set(r,
CONST_STR_LEN("SSL_CLIENT_M_SERIAL"),
buf, sz*2);
}
size_t sz = sizeof(buf);
if (gnutls_x509_crt_get_serial(crt, buf, &sz) >= 0)
buffer_append_string_encoded_hex_uc(
http_header_env_set_ptr(r, CONST_STR_LEN("SSL_CLIENT_M_SERIAL")),
buf, sz);
if (!buffer_string_is_empty(hctx->conf.ssl_verifyclient_username)) {
/* pick one of the exported values as "REMOTE_USER", for example
@ -2797,7 +2787,7 @@ https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx)
* ssl.verifyclient.username = "SSL_CLIENT_S_DN_emailAddress"
*/
const buffer *varname = hctx->conf.ssl_verifyclient_username;
const buffer *vb = http_header_env_get(r, CONST_BUF_LEN(varname));
vb = http_header_env_get(r, CONST_BUF_LEN(varname));
if (vb) { /* same as http_auth.c:http_auth_setenv() */
http_header_env_set(r,
CONST_STR_LEN("REMOTE_USER"),

99
src/mod_mbedtls.c

@ -2319,6 +2319,49 @@ https_add_ssl_client_cert (request_st * const r, const mbedtls_x509_crt * const
#endif
static void
https_add_ssl_client_subject (request_st * const r, const mbedtls_x509_name *name)
{
/* add components of client Subject DN */
/* code block is similar to mbedtls_x509_dn_gets() */
buffer * const tb = r->tmp_buf;
char buf[MBEDTLS_X509_MAX_DN_NAME_SIZE]; /*(256)*/
buffer_copy_string_len(tb, CONST_STR_LEN("SSL_CLIENT_S_DN_"));
while (name != NULL) {
if (!name->oid.p) {
name = name->next;
continue;
}
const char *short_name = NULL;
if (0 != mbedtls_oid_get_attr_short_name(&name->oid, &short_name))
continue;
buffer_string_set_length(tb, sizeof("SSL_CLIENT_S_DN_")-1);
buffer_append_string(tb, short_name);
const mbedtls_x509_name *nm = name;
int n = 0;
do {
if (nm != name && n < (int)sizeof(buf)-1)
buf[n++] = ',';
for (size_t i = 0; i < nm->val.len && n < (int)sizeof(buf)-1; ++n) {
unsigned char c = nm->val.p[i];
buf[n] = (c < 32 || c == 127 || (c > 128 && c < 160)) ? '?' : c;
}
buf[n] = '\0';
} while (nm->next_merged && nm->next && (nm = nm->next));
if (n == sizeof(buf)-1)
while (nm->next_merged && nm->next) nm = nm->next;
name = nm->next;
http_header_env_set(r,
CONST_BUF_LEN(tb),
buf, n);
}
}
static void
https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx)
{
@ -2328,7 +2371,7 @@ https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx)
* versions do keep the cert, but not set this define, attempt to retrieve
* the peer cert and check for NULL before using it. */
const mbedtls_x509_crt *crt = mbedtls_ssl_get_peer_cert(&hctx->ssl);
buffer * const tb = r->tmp_buf;
buffer *vb = http_header_env_set_ptr(r, CONST_STR_LEN("SSL_CLIENT_VERIFY"));
char buf[512];
int n;
@ -2336,29 +2379,22 @@ https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx)
? mbedtls_ssl_get_verify_result(&hctx->ssl)
: 0xFFFFFFFF;
if (0xFFFFFFFF == rc) { /*(e.g. no cert, or verify result not available)*/
http_header_env_set(r,
CONST_STR_LEN("SSL_CLIENT_VERIFY"),
CONST_STR_LEN("NONE"));
buffer_copy_string_len(vb, CONST_STR_LEN("NONE"));
return;
}
else if (0 != rc) {
/* get failure string and translate newline to ':', removing last one */
n = mbedtls_x509_crt_verify_info(buf, sizeof(buf), "", rc);
buffer_copy_string_len(tb, CONST_STR_LEN("FAILED:"));
buffer_copy_string_len(vb, CONST_STR_LEN("FAILED:"));
if (n > 0) {
for (char *nl = buf; NULL != (nl = strchr(nl, '\n')); ++nl)
nl[0] = ('\0' == nl[1] ? (--n, '\0') : ':');
buffer_append_string_len(tb, buf, n);
buffer_append_string_len(vb, buf, n);
}
http_header_env_set(r,
CONST_STR_LEN("SSL_CLIENT_VERIFY"),
CONST_BUF_LEN(tb));
return;
}
else {
http_header_env_set(r,
CONST_STR_LEN("SSL_CLIENT_VERIFY"),
CONST_STR_LEN("SUCCESS"));
buffer_copy_string_len(vb, CONST_STR_LEN("SUCCESS"));
}
n = mbedtls_x509_dn_gets(buf, sizeof(buf), &crt->subject);
@ -2368,42 +2404,7 @@ https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx)
buf, n);
}
/* add components of client Subject DN */
/* code block is similar to mbedtls_x509_dn_gets() */
/*(reuse buf; sizeof(buf) > MBEDTLS_X509_MAX_DN_NAME_SIZE, which is 256)*/
buffer_copy_string_len(tb, CONST_STR_LEN("SSL_CLIENT_S_DN_"));
const mbedtls_x509_name *name = &crt->subject;
while (name != NULL) {
if (!name->oid.p) {
name = name->next;
continue;
}
const char *short_name = NULL;
if (0 != mbedtls_oid_get_attr_short_name(&name->oid, &short_name))
continue;
buffer_string_set_length(tb, sizeof("SSL_CLIENT_S_DN_")-1);
buffer_append_string(tb, short_name);
const mbedtls_x509_name *nm = name;
n = 0;
do {
if (nm != name && n < (int)sizeof(buf)-1)
buf[n++] = ',';
for (size_t i = 0; i < nm->val.len && n < (int)sizeof(buf)-1; ++n) {
unsigned char c = nm->val.p[i];
buf[n] = (c < 32 || c == 127 || (c > 128 && c < 160)) ? '?' : c;
}
buf[n] = '\0';
} while (nm->next_merged && nm->next && (nm = nm->next));
if (n == sizeof(buf)-1)
while (nm->next_merged && nm->next) nm = nm->next;
name = nm->next;
http_header_env_set(r,
CONST_BUF_LEN(tb),
buf, n);
}
https_add_ssl_client_subject(r, &crt->subject);
n = mbedtls_x509_serial_gets(buf, sizeof(buf), &crt->serial);
if (n > 0 && n < (int)sizeof(buf)) {
@ -2419,7 +2420,7 @@ https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx)
* ssl.verifyclient.username = "SSL_CLIENT_S_DN_emailAddress"
*/
const buffer *varname = hctx->conf.ssl_verifyclient_username;
const buffer *vb = http_header_env_get(r, CONST_BUF_LEN(varname));
vb = http_header_env_get(r, CONST_BUF_LEN(varname));
if (vb) { /* same as http_auth.c:http_auth_setenv() */
http_header_env_set(r,
CONST_STR_LEN("REMOTE_USER"),

41
src/mod_nss.c

@ -2423,11 +2423,11 @@ https_add_ssl_client_cert (request_st * const r, CERTCertificate *peer)
for (uint32_t i = 0; pem[i]; ++i) {
if (pem[i] != '\r') pem[len++] = pem[i]; /*(translate \r\n to \n)*/
}
buffer * const tb = r->tmp_buf;
buffer_copy_string_len(tb, CONST_STR_LEN(PEM_BEGIN_CERT"\n"));
buffer_append_string_len(tb, pem, len);
buffer_append_string_len(tb,CONST_STR_LEN("\n"PEM_END_CERT"\n"));
http_header_env_set(r, CONST_STR_LEN("SSL_CLIENT_CERT"), CONST_BUF_LEN(tb));
buffer * const vb =
http_header_env_set_ptr(r, CONST_STR_LEN("SSL_CLIENT_CERT"));
buffer_copy_string_len(vb, CONST_STR_LEN(PEM_BEGIN_CERT"\n"));
buffer_append_string_len(vb, pem, len);
buffer_append_string_len(vb,CONST_STR_LEN("\n"PEM_END_CERT"\n"));
PORT_Free(pem);
}
@ -2477,35 +2477,28 @@ https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx)
{
PRFileDesc *ssl = hctx->ssl;
CERTCertificate *crt = NULL;
buffer * const tb = r->tmp_buf;
buffer *vb = http_header_env_set_ptr(r, CONST_STR_LEN("SSL_CLIENT_VERIFY"));
if (hctx->verify_status != -1)
crt = SSL_PeerCertificate(ssl);
if (NULL == crt) { /* || hctx->verify_status == -1) */
/*(e.g. no cert, or verify result not available)*/
http_header_env_set(r,
CONST_STR_LEN("SSL_CLIENT_VERIFY"),
CONST_STR_LEN("NONE"));
buffer_copy_string_len(vb, CONST_STR_LEN("NONE"));
return;
}
else if (0 != hctx->verify_status) {
buffer_copy_string_len(tb, CONST_STR_LEN("FAILED:"));
buffer_copy_string_len(vb, CONST_STR_LEN("FAILED:"));
const char *s = PR_ErrorToName(hctx->verify_status);
if (s)
buffer_append_string_len(tb, s, strlen(s));
buffer_append_string_len(tb, CONST_STR_LEN(":"));
buffer_append_string_len(vb, s, strlen(s));
buffer_append_string_len(vb, CONST_STR_LEN(":"));
s = PR_ErrorToString(hctx->verify_status, PR_LANGUAGE_I_DEFAULT);
buffer_append_string_len(tb, s, strlen(s));
http_header_env_set(r,
CONST_STR_LEN("SSL_CLIENT_VERIFY"),
CONST_BUF_LEN(tb));
buffer_append_string_len(vb, s, strlen(s));
CERT_DestroyCertificate(crt);
return;
}
else {
http_header_env_set(r,
CONST_STR_LEN("SSL_CLIENT_VERIFY"),
CONST_STR_LEN("SUCCESS"));
buffer_copy_string_len(vb, CONST_STR_LEN("SUCCESS"));
}
char *s = CERT_NameToAsciiInvertible(&crt->subject, CERT_N2A_STRICT);
@ -2518,11 +2511,9 @@ https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx)
https_add_ssl_client_subject(r, &crt->subject);
buffer_string_set_length(tb, 0);
buffer_append_uint_hex_lc(tb, DER_GetInteger(&crt->serialNumber));
http_header_env_set(r,
CONST_STR_LEN("SSL_CLIENT_M_SERIAL"),
CONST_BUF_LEN(tb));
buffer_append_uint_hex_lc(
http_header_env_set_ptr(r, CONST_STR_LEN("SSL_CLIENT_M_SERIAL")),
DER_GetInteger(&crt->serialNumber));
if (!buffer_string_is_empty(hctx->conf.ssl_verifyclient_username)) {
/* pick one of the exported values as "REMOTE_USER", for example
@ -2531,7 +2522,7 @@ https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx)
* ssl.verifyclient.username = "SSL_CLIENT_S_DN_emailAddress"
*/
const buffer *varname = hctx->conf.ssl_verifyclient_username;
const buffer *vb = http_header_env_get(r, CONST_BUF_LEN(varname));
vb = http_header_env_get(r, CONST_BUF_LEN(varname));
if (vb) { /* same as http_auth.c:http_auth_setenv() */
http_header_env_set(r,
CONST_STR_LEN("REMOTE_USER"),

76
src/mod_openssl.c

@ -3348,32 +3348,51 @@ CONNECTION_FUNC(mod_openssl_handle_con_close)
static void
https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx)
https_add_ssl_client_subject (request_st * const r, X509_NAME *xn)
{
buffer * const tb = r->tmp_buf;
buffer_copy_string_len(tb, CONST_STR_LEN("SSL_CLIENT_S_DN_"));
for (int i = 0, nentries = X509_NAME_entry_count(xn); i < nentries; ++i) {
int xobjnid;
const char * xobjsn;
X509_NAME_ENTRY *xe;
if (!(xe = X509_NAME_get_entry(xn, i))) {
continue;
}
xobjnid = OBJ_obj2nid((ASN1_OBJECT*)X509_NAME_ENTRY_get_object(xe));
xobjsn = OBJ_nid2sn(xobjnid);
if (xobjsn) {
buffer_string_set_length(tb, sizeof("SSL_CLIENT_S_DN_")-1);
buffer_append_string(tb, xobjsn);
http_header_env_set(r,
CONST_BUF_LEN(tb),
(const char*)X509_NAME_ENTRY_get_data(xe)->data,
X509_NAME_ENTRY_get_data(xe)->length);
}
}
}
static void
https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx)
{
X509 *xs;
X509_NAME *xn;
int i, nentries;
buffer *vb = http_header_env_set_ptr(r, CONST_STR_LEN("SSL_CLIENT_VERIFY"));
long vr = SSL_get_verify_result(hctx->ssl);
if (vr != X509_V_OK) {
char errstr[256];
ERR_error_string_n(vr, errstr, sizeof(errstr));
buffer_copy_string_len(tb, CONST_STR_LEN("FAILED:"));
buffer_append_string(tb, errstr);
http_header_env_set(r,
CONST_STR_LEN("SSL_CLIENT_VERIFY"),
CONST_BUF_LEN(tb));
buffer_copy_string_len(vb, CONST_STR_LEN("FAILED:"));
buffer_append_string(vb, errstr);
return;
} else if (!(xs = SSL_get_peer_certificate(hctx->ssl))) {
http_header_env_set(r,
CONST_STR_LEN("SSL_CLIENT_VERIFY"),
CONST_STR_LEN("NONE"));
buffer_copy_string_len(vb, CONST_STR_LEN("NONE"));
return;
} else {
http_header_env_set(r,
CONST_STR_LEN("SSL_CLIENT_VERIFY"),
CONST_STR_LEN("SUCCESS"));
buffer_copy_string_len(vb, CONST_STR_LEN("SUCCESS"));
}
xn = X509_get_subject_name(xs);
@ -3387,26 +3406,8 @@ https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx)
buf, (size_t)len);
}
}
buffer_copy_string_len(tb, CONST_STR_LEN("SSL_CLIENT_S_DN_"));
for (i = 0, nentries = X509_NAME_entry_count(xn); i < nentries; ++i) {
int xobjnid;
const char * xobjsn;
X509_NAME_ENTRY *xe;
if (!(xe = X509_NAME_get_entry(xn, i))) {
continue;
}
xobjnid = OBJ_obj2nid((ASN1_OBJECT*)X509_NAME_ENTRY_get_object(xe));
xobjsn = OBJ_nid2sn(xobjnid);
if (xobjsn) {
buffer_string_set_length(tb, sizeof("SSL_CLIENT_S_DN_")-1);
buffer_append_string(tb, xobjsn);
http_header_env_set(r,
CONST_BUF_LEN(tb),
(const char*)X509_NAME_ENTRY_get_data(xe)->data,
X509_NAME_ENTRY_get_data(xe)->length);
}
}
https_add_ssl_client_subject(r, xn);
{
ASN1_INTEGER *xsn = X509_get_serialNumber(xs);
@ -3426,7 +3427,7 @@ https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx)
* ssl.verifyclient.username = "SSL_CLIENT_S_DN_emailAddress"
*/
const buffer *varname = hctx->conf.ssl_verifyclient_username;
const buffer *vb = http_header_env_get(r, CONST_BUF_LEN(varname));
vb = http_header_env_get(r, CONST_BUF_LEN(varname));
if (vb) { /* same as http_auth.c:http_auth_setenv() */
http_header_env_set(r,
CONST_STR_LEN("REMOTE_USER"),
@ -3443,13 +3444,10 @@ https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx)
PEM_write_bio_X509(bio, xs);
const int n = BIO_pending(bio);
buffer_string_prepare_copy(tb, n);
BIO_read(bio, tb->ptr, n);
vb = http_header_env_set_ptr(r, CONST_STR_LEN("SSL_CLIENT_CERT"));
buffer_extend(vb, (uint32_t)n);
BIO_read(bio, vb->ptr, n);
BIO_free(bio);
buffer_commit(tb, n);
http_header_env_set(r,
CONST_STR_LEN("SSL_CLIENT_CERT"),
CONST_BUF_LEN(tb));
}
}
X509_free(xs);

53
src/mod_proxy.c

@ -638,14 +638,8 @@ static void proxy_set_Forwarded(connection * const con, request_st * const r, co
if (flags && NULL == b) {
const buffer *xff =
http_header_request_get(r, HTTP_HEADER_X_FORWARDED_FOR, CONST_STR_LEN("X-Forwarded-For"));
http_header_request_set(r, HTTP_HEADER_FORWARDED,
CONST_STR_LEN("Forwarded"),
CONST_STR_LEN("x")); /*(must not be blank for _get below)*/
#ifdef __COVERITY__
force_assert(NULL != b); /*(not NULL because created directly above)*/
#endif
b = http_header_request_get(r, HTTP_HEADER_FORWARDED, CONST_STR_LEN("Forwarded"));
buffer_clear(b);
b = http_header_request_set_ptr(r, HTTP_HEADER_FORWARDED,
CONST_STR_LEN("Forwarded"));
if (NULL != xff) {
/* use X-Forwarded-For contents to seed Forwarded */
char *s = xff->ptr;
@ -657,20 +651,18 @@ static void proxy_set_Forwarded(connection * const con, request_st * const r, co
do {
++i;
} while (s[i]!=' ' && s[i]!='\t' && s[i]!=',' && s[i]!='\0');
buffer_append_string_len(b, CONST_STR_LEN("for="));
/* over-simplified test expecting only IPv4 or IPv6 addresses,
* (not expecting :port, so treat existence of colon as IPv6,
* and not expecting unix paths, especially not containing ':')
* quote all strings, backslash-escape since IPs not validated*/
ipv6 = (NULL != memchr(s+j, ':', i-j)); /*(over-simplified) */
buffer_append_string_len(b, CONST_STR_LEN("\""));
if (ipv6)
buffer_append_string_len(b, CONST_STR_LEN("["));
ipv6
? buffer_append_string_len(b, CONST_STR_LEN("for=\"["))
: buffer_append_string_len(b, CONST_STR_LEN("for=\""));
buffer_append_string_backslash_escaped(b, s+j, i-j);
if (ipv6)
buffer_append_string_len(b, CONST_STR_LEN("]"));
buffer_append_string_len(b, CONST_STR_LEN("\""));
buffer_append_string_len(b, CONST_STR_LEN(", "));
ipv6
? buffer_append_string_len(b, CONST_STR_LEN("]\", "))
: buffer_append_string_len(b, CONST_STR_LEN("\", "));
}
}
} else if (flags) { /*(NULL != b)*/
@ -688,12 +680,13 @@ static void proxy_set_Forwarded(connection * const con, request_st * const r, co
* (should be IP from original con->dst_addr_buf,
* so trustable and without :port) */
int ipv6 = (NULL != strchr(efor->ptr, ':'));
buffer_append_string_len(b, CONST_STR_LEN("\""));
if (ipv6) buffer_append_string_len(b, CONST_STR_LEN("["));
buffer_append_string_backslash_escaped(
b, CONST_BUF_LEN(efor));
if (ipv6) buffer_append_string_len(b, CONST_STR_LEN("]"));
buffer_append_string_len(b, CONST_STR_LEN("\""));
ipv6
? buffer_append_string_len(b, CONST_STR_LEN("\"["))
: buffer_append_string_len(b, CONST_STR_LEN("\""));
buffer_append_string_backslash_escaped(b, CONST_BUF_LEN(efor));
ipv6
? buffer_append_string_len(b, CONST_STR_LEN("]\""))
: buffer_append_string_len(b, CONST_STR_LEN("\""));
} else if (family == AF_INET) {
/*(Note: if :port is added, then must be quoted-string:
* e.g. for="...:port")*/
@ -720,8 +713,7 @@ static void proxy_set_Forwarded(connection * const con, request_st * const r, co
* from con->srv_socket->srv_token for consistency */
if (semicolon) buffer_append_string_len(b, CONST_STR_LEN(";"));
buffer_append_string_len(b, CONST_STR_LEN("by="));
buffer_append_string_len(b, CONST_STR_LEN("\""));
buffer_append_string_len(b, CONST_STR_LEN("by=\""));
#ifdef HAVE_SYS_UN_H
/* special-case: might need to encode unix domain socket path */
if (family == AF_UNIX) {
@ -745,13 +737,13 @@ static void proxy_set_Forwarded(connection * const con, request_st * const r, co
/* expecting "http" or "https"
* (not checking if quoted-string and encoding needed) */
if (semicolon) buffer_append_string_len(b, CONST_STR_LEN(";"));
buffer_append_string_len(b, CONST_STR_LEN("proto="));
if (NULL != eproto) {
buffer_append_string_len(b, CONST_STR_LEN("proto="));
buffer_append_string_buffer(b, eproto);
} else if (con->srv_socket->is_ssl) {
buffer_append_string_len(b, CONST_STR_LEN("https"));
buffer_append_string_len(b, CONST_STR_LEN("proto=https"));
} else {
buffer_append_string_len(b, CONST_STR_LEN("http"));
buffer_append_string_len(b, CONST_STR_LEN("proto=http"));
}
semicolon = 1;
}
@ -899,9 +891,10 @@ static handler_t proxy_create_env(gw_handler_ctx *gwhctx) {
* and not streaming to backend (request body has been fully received) */
const buffer *vb = http_header_request_get(r, HTTP_HEADER_CONTENT_LENGTH, CONST_STR_LEN("Content-Length"));
if (NULL == vb) {
char buf[LI_ITOSTRING_LENGTH];
http_header_request_set(r, HTTP_HEADER_CONTENT_LENGTH, CONST_STR_LEN("Content-Length"),
buf, li_itostrn(buf, sizeof(buf), r->reqbody_length));
buffer_append_int(
http_header_request_set_ptr(r, HTTP_HEADER_CONTENT_LENGTH,
CONST_STR_LEN("Content-Length")),
r->reqbody_length);
}
}
else if (!hctx->conf.header.force_http10

86
src/mod_wolfssl.c

@ -3131,32 +3131,51 @@ CONNECTION_FUNC(mod_openssl_handle_con_close)
static void
https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx)
https_add_ssl_client_subject (request_st * const r, X509_NAME *xn)
{
buffer * const tb = r->tmp_buf;
buffer_copy_string_len(tb, CONST_STR_LEN("SSL_CLIENT_S_DN_"));
for (int i = 0, nentries = X509_NAME_entry_count(xn); i < nentries; ++i) {
int xobjnid;
const char * xobjsn;
X509_NAME_ENTRY *xe;
if (!(xe = wolfSSL_X509_NAME_get_entry(xn, i))) {
continue;
}
xobjnid = OBJ_obj2nid((ASN1_OBJECT*)X509_NAME_ENTRY_get_object(xe));
xobjsn = OBJ_nid2sn(xobjnid);
if (xobjsn) {
buffer_string_set_length(tb, sizeof("SSL_CLIENT_S_DN_")-1);
buffer_append_string(tb, xobjsn);
http_header_env_set(r,
CONST_BUF_LEN(tb),
(const char*)X509_NAME_ENTRY_get_data(xe)->data,
X509_NAME_ENTRY_get_data(xe)->length);
}
}
}
static void
https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx)
{
X509 *xs;
X509_NAME *xn;
int i, nentries;
buffer *vb = http_header_env_set_ptr(r, CONST_STR_LEN("SSL_CLIENT_VERIFY"));
long vr = SSL_get_verify_result(hctx->ssl);
if (vr != X509_V_OK) {
char errstr[256];
ERR_error_string_n(vr, errstr, sizeof(errstr));
buffer_copy_string_len(tb, CONST_STR_LEN("FAILED:"));
buffer_append_string(tb, errstr);
http_header_env_set(r,
CONST_STR_LEN("SSL_CLIENT_VERIFY"),
CONST_BUF_LEN(tb));
buffer_copy_string_len(vb, CONST_STR_LEN("FAILED:"));
buffer_append_string(vb, errstr);
return;
} else if (!(xs = SSL_get_peer_certificate(hctx->ssl))) {
http_header_env_set(r,
CONST_STR_LEN("SSL_CLIENT_VERIFY"),
CONST_STR_LEN("NONE"));
buffer_copy_string_len(vb, CONST_STR_LEN("NONE"));
return;
} else {
http_header_env_set(r,
CONST_STR_LEN("SSL_CLIENT_VERIFY"),
CONST_STR_LEN("SUCCESS"));
buffer_copy_string_len(vb, CONST_STR_LEN("SUCCESS"));
}
xn = X509_get_subject_name(xs);
@ -3170,36 +3189,16 @@ https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx)
buf, (size_t)len);
}
}
buffer_copy_string_len(tb, CONST_STR_LEN("SSL_CLIENT_S_DN_"));
for (i = 0, nentries = X509_NAME_entry_count(xn); i < nentries; ++i) {
int xobjnid;
const char * xobjsn;
X509_NAME_ENTRY *xe;
if (!(xe = wolfSSL_X509_NAME_get_entry(xn, i))) {
continue;
}
xobjnid = OBJ_obj2nid((ASN1_OBJECT*)X509_NAME_ENTRY_get_object(xe));
xobjsn = OBJ_nid2sn(xobjnid);
if (xobjsn) {
buffer_string_set_length(tb, sizeof("SSL_CLIENT_S_DN_")-1);
buffer_append_string(tb, xobjsn);
http_header_env_set(r,
CONST_BUF_LEN(tb),
(const char*)X509_NAME_ENTRY_get_data(xe)->data,
X509_NAME_ENTRY_get_data(xe)->length);
}
}
https_add_ssl_client_subject(r, xn);
{
byte buf[64];
int bsz = (int)sizeof(buf);
if (wolfSSL_X509_get_serial_number(xs, buf, &bsz) == WOLFSSL_SUCCESS) {
char serialHex[128+1];
li_tohex_uc(serialHex, sizeof(serialHex), (char *)buf, (size_t)bsz);
http_header_env_set(r,
CONST_STR_LEN("SSL_CLIENT_M_SERIAL"),
serialHex, strlen(serialHex));
buffer_append_string_encoded_hex_uc(
http_header_env_set_ptr(r, CONST_STR_LEN("SSL_CLIENT_M_SERIAL")),
(char *)buf, (size_t)bsz);
}
}
@ -3210,7 +3209,7 @@ https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx)
* ssl.verifyclient.username = "SSL_CLIENT_S_DN_emailAddress"
*/
const buffer *varname = hctx->conf.ssl_verifyclient_username;
const buffer *vb = http_header_env_get(r, CONST_BUF_LEN(varname));
vb = http_header_env_get(r, CONST_BUF_LEN(varname));
if (vb) { /* same as http_auth.c:http_auth_setenv() */
http_header_env_set(r,
CONST_STR_LEN("REMOTE_USER"),
@ -3226,12 +3225,11 @@ https_add_ssl_client_entries (request_st * const r, handler_ctx * const hctx)
const unsigned char *der = wolfSSL_X509_get_der(xs, &dersz);
pemsz = der ? wc_DerToPemEx(der, dersz, NULL, 0, NULL, CERT_TYPE) : 0;
if (pemsz > 0) {
buffer_string_prepare_copy(tb, pemsz);
if (0 == wc_DerToPemEx(der, dersz, (byte *)tb->ptr, pemsz,
NULL, CERT_TYPE))
http_header_env_set(r,
CONST_STR_LEN("SSL_CLIENT_CERT"),
tb->ptr, (uint32_t)pemsz);
vb = http_header_env_set_ptr(r, CONST_STR_LEN("SSL_CLIENT_CERT"));
if (0 == wc_DerToPemEx(der, dersz,
(byte *)buffer_string_prepare_copy(vb,pemsz),
pemsz, NULL, CERT_TYPE))
buffer_commit(vb, (uint32_t)pemsz);
}
}
X509_free(xs);

15
src/mod_wstunnel.c

@ -716,7 +716,6 @@ static int create_MD5_sum(request_st * const r) {
static int create_response_ietf_00(handler_ctx *hctx) {
request_st * const r = hctx->gw.r;
buffer *value = r->tmp_buf;
/* "Origin" header is preferred
* ("Sec-WebSocket-Origin" is from older drafts of websocket spec) */
@ -757,15 +756,15 @@ static int create_response_ietf_00(handler_ctx *hctx) {
CONST_BUF_LEN(origin));
#endif
buffer * const value =
http_header_response_set_ptr(r, HTTP_HEADER_OTHER,
CONST_STR_LEN("Sec-WebSocket-Location"));
if (buffer_is_equal_string(&r->uri.scheme, CONST_STR_LEN("https")))
buffer_copy_string_len(value, CONST_STR_LEN("wss://"));
else
buffer_copy_string_len(value, CONST_STR_LEN("ws://"));
buffer_append_string_buffer(value, r->http_host);
buffer_append_string_buffer(value, &r->uri.path);
http_header_response_set(r, HTTP_HEADER_OTHER,
CONST_STR_LEN("Sec-WebSocket-Location"),
CONST_BUF_LEN(value));
return 0;
}
@ -806,12 +805,10 @@ static int create_response_rfc_6455(handler_ctx *hctx) {
CONST_STR_LEN("upgrade"));
#endif
buffer *value = r->tmp_buf;
buffer_clear(value);
buffer * const value =
http_header_response_set_ptr(r, HTTP_HEADER_OTHER,
CONST_STR_LEN("Sec-WebSocket-Accept"));
buffer_append_base64_encode(value, sha_digest, SHA_DIGEST_LENGTH, BASE64_STANDARD);
http_header_response_set(r, HTTP_HEADER_OTHER,
CONST_STR_LEN("Sec-WebSocket-Accept"),
CONST_BUF_LEN(value));
if (hctx->frame.type == MOD_WEBSOCKET_FRAME_TYPE_BIN)
http_header_response_set(r, HTTP_HEADER_OTHER,

17
src/response.c

@ -867,12 +867,10 @@ http_response_write_prepare(request_st * const r)
* (should not reach here if 1xx (r->http_status < 200))
*/
if (qlen > 0) {
buffer * const tb = r->tmp_buf;
buffer_clear(tb);
buffer_append_int(tb, qlen);
http_header_response_set(r, HTTP_HEADER_CONTENT_LENGTH,
CONST_STR_LEN("Content-Length"),
CONST_BUF_LEN(tb));
buffer_append_int(
http_header_response_set_ptr(r, HTTP_HEADER_CONTENT_LENGTH,
CONST_STR_LEN("Content-Length")),
qlen);
}
else if (r->http_method != HTTP_METHOD_HEAD
&& r->http_status != 204 && r->http_status != 304) {
@ -958,10 +956,9 @@ http_response_call_error_handler (request_st * const r, const buffer * const err
/* set REDIRECT_STATUS to save current HTTP status code
* for access by dynamic handlers
* https://redmine.lighttpd.net/issues/1828 */
buffer * const tb = r->tmp_buf;
buffer_clear(tb);
buffer_append_int(tb, r->http_status);
http_header_env_set(r, CONST_STR_LEN("REDIRECT_STATUS"), CONST_BUF_LEN(tb));
buffer_append_int(
http_header_env_set_ptr(r, CONST_STR_LEN("REDIRECT_STATUS")),
r->http_status);
if (error_handler == r->conf.error_handler) {
plugins_call_handle_request_reset(r);

Loading…
Cancel
Save