From: Daiki Ueno Date: Fri, 13 Oct 2023 08:36:57 +0000 (+0900) Subject: cli: add --starttls-name option X-Git-Tag: 3.8.2~7^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=585ac2bb2cb60f6f7252fbbbab15095bccd996ac;p=thirdparty%2Fgnutls.git cli: add --starttls-name option Some deployment of application protocols, such as XMPP, require a different hostname than the host being connected. This adds a new option, --starttls-name, to gnutls-cli to specify it separately. Signed-off-by: Daiki Ueno --- diff --git a/NEWS b/NEWS index 2e6486ab7d..16afabaf28 100644 --- a/NEWS +++ b/NEWS @@ -20,6 +20,12 @@ See the end for copying conditions. GNUTLS_CIPHER_AES_{128,256}_SIV_GCM, the authentication tag is appended to the ciphertext, not prepended. +** gnutls-cli: New option --starttls-name + Depending on deployment, application protocols such as XMPP may + require a different origin address than the external address to be + presented prior to STARTTLS negotiation. The --starttls-name can + be used to specify specify the addresses separately. + ** API and ABI modifications: gnutls_pubkey_import_dh_raw: New function gnutls_privkey_import_dh_raw: New function diff --git a/src/cli.c b/src/cli.c index e8a54900e2..ca29a849f2 100644 --- a/src/cli.c +++ b/src/cli.c @@ -1050,8 +1050,9 @@ static int try_resume(socket_st *hd) fclose(fp); } - socket_open3(hd, hostname, service, OPT_ARG(STARTTLS_PROTO), - socket_flags, CONNECT_MSG, &rdata, &edata); + socket_open_int(hd, hostname, service, OPT_ARG(STARTTLS_PROTO), + OPT_ARG(STARTTLS_NAME), socket_flags, CONNECT_MSG, + &rdata, &edata, NULL, NULL); log_msg(stdout, "- Resume Handshake was completed\n"); if (gnutls_session_is_resumed(hd->session) != 0) @@ -1362,9 +1363,9 @@ int main(int argc, char **argv) client_fp = fopen(OPT_ARG(SAVE_CLIENT_TRACE), "wb"); } - socket_open2(&hd, hostname, service, OPT_ARG(STARTTLS_PROTO), - socket_flags, CONNECT_MSG, NULL, NULL, server_fp, - client_fp); + socket_open_int(&hd, hostname, service, OPT_ARG(STARTTLS_PROTO), + OPT_ARG(STARTTLS_NAME), socket_flags, CONNECT_MSG, NULL, + NULL, server_fp, client_fp); hd.verbose = verbose; diff --git a/src/gnutls-cli-options.json b/src/gnutls-cli-options.json index e321aac3fc..c8bfef7eb8 100644 --- a/src/gnutls-cli-options.json +++ b/src/gnutls-cli-options.json @@ -113,6 +113,18 @@ ], "argument-type": "string" }, + { + "long-option": "starttls-name", + "description": "The hostname presented to the application protocol for STARTTLS (for smtp, xmpp, lmtp)", + "detail": "Specify the hostname presented to the application protocol for STARTTLS.", + "requires": [ + "starttls-proto" + ], + "conflicts": [ + "starttls" + ], + "argument-type": "string" + }, { "long-option": "udp", "short-option": "u", diff --git a/src/socket.c b/src/socket.c index 3962c550df..48784b67fa 100644 --- a/src/socket.c +++ b/src/socket.c @@ -219,7 +219,9 @@ static void socket_starttls(socket_st *socket) log_msg(stdout, "Negotiating SMTP STARTTLS\n"); wait_for_text(socket, "220 ", 4); - snprintf(buf, sizeof(buf), "EHLO %s\r\n", socket->hostname); + snprintf(buf, sizeof(buf), "EHLO %s\r\n", + socket->app_hostname ? socket->app_hostname : + socket->hostname); send_line(socket, buf); wait_for_text(socket, "250 ", 4); send_line(socket, "STARTTLS\r\n"); @@ -240,7 +242,8 @@ static void socket_starttls(socket_st *socket) snprintf( buf, sizeof(buf), "\n", - socket->hostname); + socket->app_hostname ? socket->app_hostname : + socket->hostname); send_line(socket, buf); wait_for_text(socket, "hostname); + snprintf(buf, sizeof(buf), "LHLO %s\r\n", + socket->app_hostname ? socket->app_hostname : + socket->hostname); send_line(socket, buf); wait_for_text(socket, "250 ", 4); send_line(socket, "STARTTLS\r\n"); @@ -453,10 +458,11 @@ inline static int wrap_pull_timeout_func(gnutls_transport_ptr_t ptr, ms); } -void socket_open2(socket_st *hd, const char *hostname, const char *service, - const char *app_proto, int flags, const char *msg, - gnutls_datum_t *rdata, gnutls_datum_t *edata, - FILE *server_trace, FILE *client_trace) +void socket_open_int(socket_st *hd, const char *hostname, const char *service, + const char *app_proto, const char *app_hostname, int flags, + const char *msg, gnutls_datum_t *rdata, + gnutls_datum_t *edata, FILE *server_trace, + FILE *client_trace) { struct addrinfo hints, *res, *ptr; int sd, err = 0; @@ -559,6 +565,7 @@ void socket_open2(socket_st *hd, const char *hostname, const char *service, hd->fd = sd; if (flags & SOCKET_FLAG_STARTTLS) { hd->app_proto = app_proto; + hd->app_hostname = app_hostname; socket_starttls(hd); hd->app_proto = NULL; } diff --git a/src/socket.h b/src/socket.h index 7b88c4847a..680ca16ade 100644 --- a/src/socket.h +++ b/src/socket.h @@ -18,6 +18,7 @@ typedef struct { int secure; char *hostname; const char *app_proto; + const char *app_hostname; char *ip; char *service; struct addrinfo *ptr; @@ -48,18 +49,20 @@ ssize_t socket_send(const socket_st *socket, const void *buffer, int buffer_size); ssize_t socket_send_range(const socket_st *socket, const void *buffer, int buffer_size, gnutls_range_st *range); -void socket_open2(socket_st *hd, const char *hostname, const char *service, - const char *app_proto, int flags, const char *msg, - gnutls_datum_t *rdata, gnutls_datum_t *edata, - FILE *server_trace, FILE *client_trace); +void socket_open_int(socket_st *hd, const char *hostname, const char *service, + const char *app_proto, const char *app_hostname, int flags, + const char *msg, gnutls_datum_t *rdata, + gnutls_datum_t *edata, FILE *server_trace, + FILE *client_trace); -#define socket_open(hd, host, service, app_proto, flags, msg, rdata) \ - socket_open2(hd, host, service, app_proto, flags, msg, rdata, NULL, \ - NULL, NULL) +#define socket_open(hd, host, service, app_proto, flags, msg, rdata) \ + socket_open_int(hd, host, service, app_proto, NULL, flags, msg, rdata, \ + NULL, NULL, NULL) -#define socket_open3(hd, host, service, app_proto, flags, msg, rdata, edata) \ - socket_open2(hd, host, service, app_proto, flags, msg, rdata, edata, \ - NULL, NULL) +#define socket_open2(hd, host, service, app_proto, flags, msg, rdata, edata, \ + server_trace, client_trace) \ + socket_open_int(hd, host, service, app_proto, NULL, flags, msg, rdata, \ + edata, server_trace, client_trace) void socket_bye(socket_st *socket, unsigned polite);