]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
cli: add --starttls-name option
authorDaiki Ueno <ueno@gnu.org>
Fri, 13 Oct 2023 08:36:57 +0000 (17:36 +0900)
committerDaiki Ueno <ueno@gnu.org>
Fri, 13 Oct 2023 08:47:27 +0000 (17:47 +0900)
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 <ueno@gnu.org>
NEWS
src/cli.c
src/gnutls-cli-options.json
src/socket.c
src/socket.h

diff --git a/NEWS b/NEWS
index 2e6486ab7d37d230f6b6eca0af0d34060b1b4476..16afabaf286563ebba731e25bf4870a874bcd580 100644 (file)
--- 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
index e8a54900e25616536f9b97192e84cd5c93bc3d7b..ca29a849f28c45d606eee2e6d3d4718f2d325989 100644 (file)
--- 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;
 
index e321aac3fca4406df621c6c89a146ef6083bf1c6..c8bfef7eb8f1255d6cdaba6be4c333965b2c2723 100644 (file)
           ],
           "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",
index 3962c550df17b455ee22ac4782c0b6c391902a05..48784b67fa4bffb212678577428b3716c5094989 100644 (file)
@@ -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),
                        "<stream:stream xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:client' to='%s' version='1.0'>\n",
-                       socket->hostname);
+                       socket->app_hostname ? socket->app_hostname :
+                                              socket->hostname);
                send_line(socket, buf);
                wait_for_text(socket, "<?", 2);
                send_line(
@@ -268,7 +271,9 @@ static void socket_starttls(socket_st *socket)
                        log_msg(stdout, "Negotiating LMTP STARTTLS\n");
 
                wait_for_text(socket, "220 ", 4);
-               snprintf(buf, sizeof(buf), "LHLO %s\r\n", 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;
                }
index 7b88c4847ab7eb815f22ecada1dd1484d0a1653b..680ca16ade1b68e7f540998e7d5edca93b2f6c9c 100644 (file)
@@ -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);