mirror of
https://github.com/openssl/openssl.git
synced 2024-12-16 13:33:49 +08:00
Add Sieve support (RFC 5804) to s_client ("-starttls sieve")
Reviewed-by: Andy Polyakov <appro@openssl.org> Reviewed-by: Rich Salz <rsalz@openssl.org> (Merged from https://github.com/openssl/openssl/pull/2300)
This commit is contained in:
parent
b08ee30bf4
commit
20967afb7f
@ -2664,3 +2664,11 @@ int set_cert_times(X509 *x, const char *startdate, const char *enddate,
|
|||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void make_uppercase(char *string)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; string[i] != '\0'; i++)
|
||||||
|
string[i] = toupper((unsigned char)string[i]);
|
||||||
|
}
|
||||||
|
@ -559,6 +559,8 @@ int raw_write_stdout(const void *, int);
|
|||||||
# define TM_STOP 1
|
# define TM_STOP 1
|
||||||
double app_tminterval(int stop, int usertime);
|
double app_tminterval(int stop, int usertime);
|
||||||
|
|
||||||
|
void make_uppercase(char *string);
|
||||||
|
|
||||||
typedef struct verify_options_st {
|
typedef struct verify_options_st {
|
||||||
int depth;
|
int depth;
|
||||||
int quiet;
|
int quiet;
|
||||||
|
@ -2141,8 +2141,7 @@ static int get_certificate_status(const char *serial, CA_DB *db)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Make it Upper Case */
|
/* Make it Upper Case */
|
||||||
for (i = 0; row[DB_serial][i] != '\0'; i++)
|
make_uppercase(row[DB_serial]);
|
||||||
row[DB_serial][i] = toupper((unsigned char)row[DB_serial][i]);
|
|
||||||
|
|
||||||
ok = 1;
|
ok = 1;
|
||||||
|
|
||||||
|
@ -749,7 +749,8 @@ typedef enum PROTOCOL_choice {
|
|||||||
PROTO_IRC,
|
PROTO_IRC,
|
||||||
PROTO_POSTGRES,
|
PROTO_POSTGRES,
|
||||||
PROTO_LMTP,
|
PROTO_LMTP,
|
||||||
PROTO_NNTP
|
PROTO_NNTP,
|
||||||
|
PROTO_SIEVE
|
||||||
} PROTOCOL_CHOICE;
|
} PROTOCOL_CHOICE;
|
||||||
|
|
||||||
static const OPT_PAIR services[] = {
|
static const OPT_PAIR services[] = {
|
||||||
@ -764,6 +765,7 @@ static const OPT_PAIR services[] = {
|
|||||||
{"postgres", PROTO_POSTGRES},
|
{"postgres", PROTO_POSTGRES},
|
||||||
{"lmtp", PROTO_LMTP},
|
{"lmtp", PROTO_LMTP},
|
||||||
{"nntp", PROTO_NNTP},
|
{"nntp", PROTO_NNTP},
|
||||||
|
{"sieve", PROTO_SIEVE},
|
||||||
{NULL, 0}
|
{NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1911,12 +1913,12 @@ int s_client_main(int argc, char **argv)
|
|||||||
*/
|
*/
|
||||||
int foundit = 0;
|
int foundit = 0;
|
||||||
BIO *fbio = BIO_new(BIO_f_buffer());
|
BIO *fbio = BIO_new(BIO_f_buffer());
|
||||||
|
|
||||||
BIO_push(fbio, sbio);
|
BIO_push(fbio, sbio);
|
||||||
/* Wait for multi-line response to end from LMTP or SMTP */
|
/* Wait for multi-line response to end from LMTP or SMTP */
|
||||||
do {
|
do {
|
||||||
mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
|
mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
|
||||||
}
|
} while (mbuf_len > 3 && mbuf[3] == '-');
|
||||||
while (mbuf_len > 3 && mbuf[3] == '-');
|
|
||||||
if (starttls_proto == (int)PROTO_LMTP)
|
if (starttls_proto == (int)PROTO_LMTP)
|
||||||
BIO_printf(fbio, "LHLO %s\r\n", ehlo);
|
BIO_printf(fbio, "LHLO %s\r\n", ehlo);
|
||||||
else
|
else
|
||||||
@ -1930,14 +1932,13 @@ int s_client_main(int argc, char **argv)
|
|||||||
mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
|
mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
|
||||||
if (strstr(mbuf, "STARTTLS"))
|
if (strstr(mbuf, "STARTTLS"))
|
||||||
foundit = 1;
|
foundit = 1;
|
||||||
}
|
} while (mbuf_len > 3 && mbuf[3] == '-');
|
||||||
while (mbuf_len > 3 && mbuf[3] == '-');
|
|
||||||
(void)BIO_flush(fbio);
|
(void)BIO_flush(fbio);
|
||||||
BIO_pop(fbio);
|
BIO_pop(fbio);
|
||||||
BIO_free(fbio);
|
BIO_free(fbio);
|
||||||
if (!foundit)
|
if (!foundit)
|
||||||
BIO_printf(bio_err,
|
BIO_printf(bio_err,
|
||||||
"didn't find starttls in server response,"
|
"Didn't find STARTTLS in server response,"
|
||||||
" trying anyway...\n");
|
" trying anyway...\n");
|
||||||
BIO_printf(sbio, "STARTTLS\r\n");
|
BIO_printf(sbio, "STARTTLS\r\n");
|
||||||
BIO_read(sbio, sbuf, BUFSIZZ);
|
BIO_read(sbio, sbuf, BUFSIZZ);
|
||||||
@ -1958,6 +1959,7 @@ int s_client_main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
int foundit = 0;
|
int foundit = 0;
|
||||||
BIO *fbio = BIO_new(BIO_f_buffer());
|
BIO *fbio = BIO_new(BIO_f_buffer());
|
||||||
|
|
||||||
BIO_push(fbio, sbio);
|
BIO_push(fbio, sbio);
|
||||||
BIO_gets(fbio, mbuf, BUFSIZZ);
|
BIO_gets(fbio, mbuf, BUFSIZZ);
|
||||||
/* STARTTLS command requires CAPABILITY... */
|
/* STARTTLS command requires CAPABILITY... */
|
||||||
@ -1975,7 +1977,7 @@ int s_client_main(int argc, char **argv)
|
|||||||
BIO_free(fbio);
|
BIO_free(fbio);
|
||||||
if (!foundit)
|
if (!foundit)
|
||||||
BIO_printf(bio_err,
|
BIO_printf(bio_err,
|
||||||
"didn't find STARTTLS in server response,"
|
"Didn't find STARTTLS in server response,"
|
||||||
" trying anyway...\n");
|
" trying anyway...\n");
|
||||||
BIO_printf(sbio, ". STARTTLS\r\n");
|
BIO_printf(sbio, ". STARTTLS\r\n");
|
||||||
BIO_read(sbio, sbuf, BUFSIZZ);
|
BIO_read(sbio, sbuf, BUFSIZZ);
|
||||||
@ -1984,6 +1986,7 @@ int s_client_main(int argc, char **argv)
|
|||||||
case PROTO_FTP:
|
case PROTO_FTP:
|
||||||
{
|
{
|
||||||
BIO *fbio = BIO_new(BIO_f_buffer());
|
BIO *fbio = BIO_new(BIO_f_buffer());
|
||||||
|
|
||||||
BIO_push(fbio, sbio);
|
BIO_push(fbio, sbio);
|
||||||
/* wait for multi-line response to end from FTP */
|
/* wait for multi-line response to end from FTP */
|
||||||
do {
|
do {
|
||||||
@ -2007,7 +2010,11 @@ int s_client_main(int argc, char **argv)
|
|||||||
starttls_proto == PROTO_XMPP ? "client" : "server",
|
starttls_proto == PROTO_XMPP ? "client" : "server",
|
||||||
xmpphost ? xmpphost : host);
|
xmpphost ? xmpphost : host);
|
||||||
seen = BIO_read(sbio, mbuf, BUFSIZZ);
|
seen = BIO_read(sbio, mbuf, BUFSIZZ);
|
||||||
mbuf[seen] = 0;
|
if (seen < 0) {
|
||||||
|
BIO_printf(bio_err, "BIO_read failed\n");
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
mbuf[seen] = '\0';
|
||||||
while (!strstr
|
while (!strstr
|
||||||
(mbuf, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'")
|
(mbuf, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'")
|
||||||
&& !strstr(mbuf,
|
&& !strstr(mbuf,
|
||||||
@ -2018,15 +2025,19 @@ int s_client_main(int argc, char **argv)
|
|||||||
if (seen <= 0)
|
if (seen <= 0)
|
||||||
goto shut;
|
goto shut;
|
||||||
|
|
||||||
mbuf[seen] = 0;
|
mbuf[seen] = '\0';
|
||||||
}
|
}
|
||||||
BIO_printf(sbio,
|
BIO_printf(sbio,
|
||||||
"<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
|
"<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
|
||||||
seen = BIO_read(sbio, sbuf, BUFSIZZ);
|
seen = BIO_read(sbio, sbuf, BUFSIZZ);
|
||||||
sbuf[seen] = 0;
|
if (seen < 0) {
|
||||||
|
BIO_printf(bio_err, "BIO_read failed\n");
|
||||||
|
goto shut;
|
||||||
|
}
|
||||||
|
sbuf[seen] = '\0';
|
||||||
if (!strstr(sbuf, "<proceed"))
|
if (!strstr(sbuf, "<proceed"))
|
||||||
goto shut;
|
goto shut;
|
||||||
mbuf[0] = 0;
|
mbuf[0] = '\0';
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PROTO_TELNET:
|
case PROTO_TELNET:
|
||||||
@ -2210,6 +2221,54 @@ int s_client_main(int argc, char **argv)
|
|||||||
BIO_read(sbio, sbuf, BUFSIZZ);
|
BIO_read(sbio, sbuf, BUFSIZZ);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case PROTO_SIEVE:
|
||||||
|
{
|
||||||
|
int foundit = 0;
|
||||||
|
BIO *fbio = BIO_new(BIO_f_buffer());
|
||||||
|
|
||||||
|
BIO_push(fbio, sbio);
|
||||||
|
/* wait for multi-line response to end from Sieve */
|
||||||
|
do {
|
||||||
|
mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
|
||||||
|
/*
|
||||||
|
* According to RFC 5804 § 1.7, capability
|
||||||
|
* is case-insensitive, make it uppercase
|
||||||
|
*/
|
||||||
|
if (mbuf_len > 1 && mbuf[0] == '"') {
|
||||||
|
make_uppercase(mbuf);
|
||||||
|
if (strncmp(mbuf, "\"STARTTLS\"", 10) == 0)
|
||||||
|
foundit = 1;
|
||||||
|
}
|
||||||
|
} while (mbuf_len > 1 && mbuf[0] == '"');
|
||||||
|
(void)BIO_flush(fbio);
|
||||||
|
BIO_pop(fbio);
|
||||||
|
BIO_free(fbio);
|
||||||
|
if (!foundit)
|
||||||
|
BIO_printf(bio_err,
|
||||||
|
"Didn't find STARTTLS in server response,"
|
||||||
|
" trying anyway...\n");
|
||||||
|
BIO_printf(sbio, "STARTTLS\r\n");
|
||||||
|
mbuf_len = BIO_read(sbio, mbuf, BUFSIZZ);
|
||||||
|
if (mbuf_len < 0) {
|
||||||
|
BIO_printf(bio_err, "BIO_read failed\n");
|
||||||
|
goto end;
|
||||||
|
} else if (mbuf_len < 2) {
|
||||||
|
BIO_printf(bio_err, "Server does not support STARTTLS.\n");
|
||||||
|
goto shut;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* According to RFC 5804 § 2.2, response codes are case-
|
||||||
|
* insensitive, make it uppercase but preserve the response.
|
||||||
|
*/
|
||||||
|
mbuf[mbuf_len] = '\0';
|
||||||
|
strncpy(sbuf, mbuf, 2);
|
||||||
|
make_uppercase(sbuf);
|
||||||
|
if (strncmp(sbuf, "OK", 2) != 0) {
|
||||||
|
BIO_printf(bio_err, "STARTTLS not supported: %s", mbuf);
|
||||||
|
goto shut;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
@ -437,7 +437,7 @@ command for more information.
|
|||||||
send the protocol-specific message(s) to switch to TLS for communication.
|
send the protocol-specific message(s) to switch to TLS for communication.
|
||||||
B<protocol> is a keyword for the intended protocol. Currently, the only
|
B<protocol> is a keyword for the intended protocol. Currently, the only
|
||||||
supported keywords are "smtp", "pop3", "imap", "ftp", "xmpp", "xmpp-server",
|
supported keywords are "smtp", "pop3", "imap", "ftp", "xmpp", "xmpp-server",
|
||||||
"irc", "postgres", "lmtp" and "nntp".
|
"irc", "postgres", "lmtp", "nntp" and "sieve".
|
||||||
|
|
||||||
=item B<-xmpphost hostname>
|
=item B<-xmpphost hostname>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user