From b29705339a89f15466aa5349ca4499dedcf283ff Mon Sep 17 00:00:00 2001 From: Randall Meyer Date: Sun, 13 Mar 2022 12:32:06 -0700 Subject: [PATCH] Adds user-agent to OCSP requests Uses the proxy.config.http.request_via_str override as the User-Agent Closes #8721 --- iocore/net/OCSPStapling.cc | 41 ++++++++++++++++++++++++++------------ iocore/net/P_SSLConfig.h | 1 + iocore/net/SSLConfig.cc | 2 ++ 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/iocore/net/OCSPStapling.cc b/iocore/net/OCSPStapling.cc index 252fda1e09c..d5721650239 100644 --- a/iocore/net/OCSPStapling.cc +++ b/iocore/net/OCSPStapling.cc @@ -48,6 +48,7 @@ struct certinfo { OCSP_CERTID *cid; // Certificate ID for OCSP requests or nullptr if ID cannot be determined char *uri; // Responder details char *certname; + char *user_agent; ink_mutex stapling_mutex; unsigned char resp_der[MAX_STAPLING_DER]; unsigned int resp_derlen; @@ -72,14 +73,18 @@ certinfo_map_free(void * /*parent*/, void *ptr, CRYPTO_EX_DATA * /*ad*/, int /*i } for (certinfo_map::iterator iter = map->begin(); iter != map->end(); ++iter) { - if (iter->second->uri) { - OPENSSL_free(iter->second->uri); + certinfo *cinf = iter->second; + if (cinf->uri) { + OPENSSL_free(cinf->uri); } - if (iter->second->certname) { - ats_free(iter->second->certname); + if (cinf->certname) { + ats_free(cinf->certname); } - ink_mutex_destroy(&iter->second->stapling_mutex); - OPENSSL_free(iter->second); + if (cinf->user_agent) { + ats_free(cinf->user_agent); + } + ink_mutex_destroy(&cinf->stapling_mutex); + OPENSSL_free(cinf); } delete map; } @@ -211,9 +216,12 @@ ssl_stapling_init_cert(SSL_CTX *ctx, X509 *cert, const char *certname, const cha } // Initialize certinfo - cinf->cid = nullptr; - cinf->uri = nullptr; - cinf->certname = ats_strdup(certname); + cinf->cid = nullptr; + cinf->uri = nullptr; + cinf->certname = ats_strdup(certname); + if (SSLConfigParams::ssl_ocsp_user_agent != nullptr) { + cinf->user_agent = ats_strdup(SSLConfigParams::ssl_ocsp_user_agent); + } cinf->resp_derlen = 0; ink_mutex_init(&cinf->stapling_mutex); cinf->is_prefetched = rsp_file ? true : false; @@ -291,6 +299,10 @@ ssl_stapling_init_cert(SSL_CTX *ctx, X509 *cert, const char *certname, const cha ats_free(cinf->certname); } + if (cinf->user_agent) { + ats_free(cinf->user_agent); + } + if (cinf) { OPENSSL_free(cinf); } @@ -368,7 +380,7 @@ stapling_check_response(certinfo *cinf, OCSP_RESPONSE *rsp) } static OCSP_RESPONSE * -query_responder(BIO *b, char *host, char *path, OCSP_REQUEST *req, int req_timeout) +query_responder(BIO *b, const char *host, const char *path, const char *user_agent, OCSP_REQUEST *req, int req_timeout) { ink_hrtime start, end; OCSP_RESPONSE *resp = nullptr; @@ -380,6 +392,9 @@ query_responder(BIO *b, char *host, char *path, OCSP_REQUEST *req, int req_timeo ctx = OCSP_sendreq_new(b, path, nullptr, -1); OCSP_REQ_CTX_add1_header(ctx, "Host", host); + if (user_agent != nullptr) { + OCSP_REQ_CTX_add1_header(ctx, "User-Agent", user_agent); + } OCSP_REQ_CTX_set1_req(ctx, req); do { @@ -399,7 +414,7 @@ query_responder(BIO *b, char *host, char *path, OCSP_REQUEST *req, int req_timeo } static OCSP_RESPONSE * -process_responder(OCSP_REQUEST *req, char *host, char *path, char *port, int req_timeout) +process_responder(OCSP_REQUEST *req, const char *host, const char *path, const char *port, const char *user_agent, int req_timeout) { BIO *cbio = nullptr; OCSP_RESPONSE *resp = nullptr; @@ -416,7 +431,7 @@ process_responder(OCSP_REQUEST *req, char *host, char *path, char *port, int req Debug("ssl_ocsp", "process_responder: failed to connect to OCSP server; host=%s port=%s path=%s", host, port, path); goto end; } - resp = query_responder(cbio, host, path, req, req_timeout); + resp = query_responder(cbio, host, path, user_agent, req, req_timeout); end: if (cbio) { @@ -456,7 +471,7 @@ stapling_refresh_response(certinfo *cinf, OCSP_RESPONSE **prsp) goto err; } - *prsp = process_responder(req, host, path, port, SSLConfigParams::ssl_ocsp_request_timeout); + *prsp = process_responder(req, host, path, port, cinf->user_agent, SSLConfigParams::ssl_ocsp_request_timeout); if (*prsp == nullptr) { goto done; } diff --git a/iocore/net/P_SSLConfig.h b/iocore/net/P_SSLConfig.h index dcde388983b..99ebf9db77a 100644 --- a/iocore/net/P_SSLConfig.h +++ b/iocore/net/P_SSLConfig.h @@ -124,6 +124,7 @@ struct SSLConfigParams : public ConfigInfo { static int ssl_ocsp_update_period; static int ssl_handshake_timeout_in; char *ssl_ocsp_response_path_only; + static char *ssl_ocsp_user_agent; static int origin_session_cache; static size_t origin_session_cache_size; diff --git a/iocore/net/SSLConfig.cc b/iocore/net/SSLConfig.cc index fb799e3fded..f315c68feed 100644 --- a/iocore/net/SSLConfig.cc +++ b/iocore/net/SSLConfig.cc @@ -67,6 +67,7 @@ bool SSLConfigParams::ssl_ocsp_enabled = false; int SSLConfigParams::ssl_ocsp_cache_timeout = 3600; int SSLConfigParams::ssl_ocsp_request_timeout = 10; int SSLConfigParams::ssl_ocsp_update_period = 60; +char *SSLConfigParams::ssl_ocsp_user_agent = nullptr; int SSLConfigParams::ssl_handshake_timeout_in = 0; int SSLConfigParams::origin_session_cache = 1; size_t SSLConfigParams::origin_session_cache_size = 10240; @@ -363,6 +364,7 @@ SSLConfigParams::initialize() REC_ReadConfigStringAlloc(ssl_ocsp_response_path, "proxy.config.ssl.ocsp.response.path"); set_paths_helper(ssl_ocsp_response_path, nullptr, &ssl_ocsp_response_path_only, nullptr); ats_free(ssl_ocsp_response_path); + REC_ReadConfigStringAlloc(ssl_ocsp_user_agent, "proxy.config.http.request_via_str"); REC_ReadConfigInt32(ssl_handshake_timeout_in, "proxy.config.ssl.handshake_timeout_in");