Index | Thread | Search

From:
Martijn van Duren <openbsd+tech@list.imperialat.at>
Subject:
openssl: implement -starttls sieve for s_client
To:
tech@openbsd.org
Date:
Fri, 30 Jan 2026 10:44:27 +0100

Download raw body.

Thread
Hello tech@,

I had to do some sieve debugging, and wrote this snippet to allow me to
connect. Is this worth having? Sieve STARTTLS is defined in RFC5804
section 2.2.

martijn@

diff dfcd5193b8f011e09ff8283f2d01c2fbbbab30a6 e113694d2551fc272d4bed2b56c8bf9155d6c66e
commit - dfcd5193b8f011e09ff8283f2d01c2fbbbab30a6
commit + e113694d2551fc272d4bed2b56c8bf9155d6c66e
blob - f3e0be15ede77ad406c0b9d098ce8a83b5172400
blob + fdc198d2c77ca79fbcf059409eb33fc6b170606a
--- usr.bin/openssl/openssl.1
+++ usr.bin/openssl/openssl.1
@@ -4416,6 +4416,7 @@ is a keyword for the intended protocol.
 Currently, the supported keywords are
 .Qq ftp ,
 .Qq imap ,
+.Qq sieve ,
 .Qq smtp ,
 .Qq pop3 ,
 and
blob - 84718c19fd2dc8e965d60fd08a46d013e24b9e02
blob + d3106809f80d462a08180c21db813cd706b39c13
--- usr.bin/openssl/s_client.c
+++ usr.bin/openssl/s_client.c
@@ -174,6 +174,7 @@ enum {
 	PROTO_LMTP,
 	PROTO_POP3,
 	PROTO_IMAP,
+	PROTO_SIEVE,
 	PROTO_FTP,
 	PROTO_XMPP,
 };
@@ -335,6 +336,8 @@ s_client_opt_starttls(char *arg)
 		cfg.starttls_proto = PROTO_POP3;
 	else if (strcmp(arg, "imap") == 0)
 		cfg.starttls_proto = PROTO_IMAP;
+	else if (strcmp(arg, "sieve") == 0)
+		cfg.starttls_proto = PROTO_SIEVE;
 	else if (strcmp(arg, "ftp") == 0)
 		cfg.starttls_proto = PROTO_FTP;
 	else if (strcmp(arg, "xmpp") == 0)
@@ -729,7 +732,8 @@ static const struct option s_client_options[] = {
 		.name = "starttls",
 		.argname = "protocol",
 		.desc = "Use the STARTTLS command before starting TLS,\n"
-		        "smtp, lmtp, pop3, imap, ftp and xmpp are supported.",
+		        "smtp, lmtp, pop3, imap, sieve, ftp and xmpp "
+			"are supported.",
 		.type = OPTION_ARG_FUNC,
 		.opt.argfunc = s_client_opt_starttls,
 	},
@@ -1220,6 +1224,28 @@ s_client_main(int argc, char **argv)
 			    " try anyway...\n");
 		BIO_printf(sbio, ". STARTTLS\r\n");
 		BIO_read(sbio, sbuf, BUFSIZZ);
+	} else if (cfg.starttls_proto == PROTO_SIEVE) {
+		int foundit = 0;
+		BIO *fbio = BIO_new(BIO_f_buffer());
+		BIO_push(fbio, sbio);
+		/* wait for multi-line CAPABILITY response */
+		do {
+			BIO_gets(fbio, mbuf, BUFSIZZ);
+			if (strcmp(mbuf, "\"STARTTLS\"\r\n") == 0)
+				foundit = 1;
+		}
+		while (strncmp(mbuf, "OK", 2) != 0);
+		if (!foundit)
+			BIO_printf(bio_err,
+			    "didn't find STARTTLS in server response,"
+			    " try anyway...\n");
+		BIO_printf(sbio, "STARTTLS\r\n");
+		BIO_gets(fbio, mbuf, BUFSIZZ);
+		(void) BIO_flush(fbio);
+		BIO_pop(fbio);
+		BIO_free(fbio);
+		if (strncmp(mbuf, "OK", 2) != 0)
+			goto shut;
 	} else if (cfg.starttls_proto == PROTO_FTP) {
 		BIO *fbio = BIO_new(BIO_f_buffer());
 		BIO_push(fbio, sbio);