From a0f7cde9daa7ed463beee00fb5fe75e8d90fa1d4 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 8 Jul 2025 09:56:37 +0200 Subject: dirmngr: Add option--user-agent and always use a User-Agent header. * dirmngr/dirmngr.h (opt): Add user_agent. * dirmngr/dirmngr.c (oUserAgent): New. (opts): Add "user-agent". (parse_rereadable_options): Set option. * dirmngr/ks-engine-hkp.c (send_request): Send User-Agent. * dirmngr/ks-engine-http.c (ks_http_fetch): Ditto. * dirmngr/ocsp.c (do_ocsp_request): Ditto. -- Note that the http_open_document function is not used by dirmngr. If it ever gets used we may want to add a way to configure the http.c module with a user-agent string, so that it is send by the send_request function and we do not need to explictly do that in the caller. GnuPG-bug-id: 7715 --- NEWS | 2 ++ dirmngr/dirmngr.c | 12 ++++++++++++ dirmngr/dirmngr.h | 2 ++ dirmngr/ks-engine-hkp.c | 2 ++ dirmngr/ks-engine-http.c | 2 ++ dirmngr/ocsp.c | 3 +++ doc/dirmngr.texi | 6 ++++++ 7 files changed, 29 insertions(+) diff --git a/NEWS b/NEWS index a43fe024f..90644271d 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,8 @@ Noteworthy changes in version 2.5.9 (unreleased) * gpg: Do not show the non-standard secp256k1 curve in the menu to select the curve. It can however be specified using its name. + * dirmngr: New option --user-agent and send a default User-Agent of + "GnuPG/2.6" for all HTTP requests. [T7715] Release-info: https://dev.gnupg.org/T7695 diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c index 08f313879..d418d09e2 100644 --- a/dirmngr/dirmngr.c +++ b/dirmngr/dirmngr.c @@ -161,6 +161,7 @@ enum cmd_and_opt_values { oListenBacklog, oFakeCRL, oCompatibilityFlags, + oUserAgent, aTest }; @@ -251,6 +252,7 @@ static gpgrt_opt_t opts[] = { N_("|URL|redirect all HTTP requests to URL")), ARGPARSE_s_n (oHonorHTTPProxy, "honor-http-proxy", N_("use system's HTTP proxy setting")), + ARGPARSE_s_s (oUserAgent, "user-agent", "@"), ARGPARSE_s_s (oLDAPWrapperProgram, "ldap-wrapper-program", "@"), ARGPARSE_header ("Keyserver", N_("Configuration for OpenPGP servers")), @@ -695,6 +697,7 @@ parse_rereadable_options (gpgrt_argparse_t *pargs, int reread) opt.ocsp_max_period = 90 * 86400; /* 90 days. */ opt.ocsp_current_period = 3 * 60 * 60; /* 3 hours. */ opt.max_replies = DEFAULT_MAX_REPLIES; + opt.user_agent = "GnuPG/2.6"; while (opt.ocsp_signer) { fingerprint_list_t tmp = opt.ocsp_signer->next; @@ -906,6 +909,15 @@ parse_rereadable_options (gpgrt_argparse_t *pargs, int reread) } break; + case oUserAgent: + if (strpbrk (pargs->r.ret_str, "\r\n")) + ; /* Ignore if the caller tried to insert CR or LF. */ + else if (!strcmp (pargs->r.ret_str, "none")) + opt.user_agent = ""; + else + opt.user_agent = pargs->r.ret_str; + break; + default: return 0; /* Not handled. */ } diff --git a/dirmngr/dirmngr.h b/dirmngr/dirmngr.h index ace40e6d5..5de66721b 100644 --- a/dirmngr/dirmngr.h +++ b/dirmngr/dirmngr.h @@ -160,6 +160,8 @@ struct strlist_t keyserver; /* List of default keyservers. */ + const char *user_agent; /* The HTTP Use-Agent (never NULL). */ + /* Compatibility flags (COMPAT_FLAG_xxxx). */ unsigned int compat_flags; } opt; diff --git a/dirmngr/ks-engine-hkp.c b/dirmngr/ks-engine-hkp.c index 75fe19987..617b01a9f 100644 --- a/dirmngr/ks-engine-hkp.c +++ b/dirmngr/ks-engine-hkp.c @@ -1278,6 +1278,8 @@ send_request (ctrl_t ctrl, const char *request, const char *hostportstr, we're good with both HTTP 1.0 and 1.1. */ es_fputs ("Pragma: no-cache\r\n" "Cache-Control: no-cache\r\n", fp); + if (*opt.user_agent) + es_fprintf (fp, "User-Agent: %s\r\n", opt.user_agent); if (post_cb) err = post_cb (post_cb_value, http); if (!err) diff --git a/dirmngr/ks-engine-http.c b/dirmngr/ks-engine-http.c index 5091ddf27..3fbadc913 100644 --- a/dirmngr/ks-engine-http.c +++ b/dirmngr/ks-engine-http.c @@ -130,6 +130,8 @@ ks_http_fetch (ctrl_t ctrl, const char *url, unsigned int flags, if ((flags & KS_HTTP_FETCH_NOCACHE)) es_fputs ("Pragma: no-cache\r\n" "Cache-Control: no-cache\r\n", fp); + if (*opt.user_agent) + es_fprintf (fp, "User-Agent: %s\r\n", opt.user_agent); http_start_data (http); if (es_ferror (fp)) err = gpg_error_from_syserror (); diff --git a/dirmngr/ocsp.c b/dirmngr/ocsp.c index 7de8b10e4..aee921e9a 100644 --- a/dirmngr/ocsp.c +++ b/dirmngr/ocsp.c @@ -197,6 +197,9 @@ do_ocsp_request (ctrl_t ctrl, ksba_ocsp_t ocsp, return err; } + if (*opt.user_agent) + es_fprintf (http_get_write_ptr (http), + "User-Agent: %s\r\n", opt.user_agent); es_fprintf (http_get_write_ptr (http), "Content-Type: application/ocsp-request\r\n" "Content-Length: %lu\r\n", diff --git a/doc/dirmngr.texi b/doc/dirmngr.texi index 20ea18d08..eda33064e 100644 --- a/doc/dirmngr.texi +++ b/doc/dirmngr.texi @@ -429,6 +429,12 @@ ignoring DPs entirely. Ignore all OCSP URLs contained in the certificate. The effect is to force the use of the default responder. +@item --user-agent @var{string} +@opindex user-agent +Change the default User-Agent for HTTP requests to @var{string}. If +@var{string} is empty or has the value ``none'' no User-Agent header +will be used. + @item --honor-http-proxy @opindex honor-http-proxy If the environment variable @env{http_proxy} has been set, use its -- cgit v1.2.3