Peter Saint-Andre wrote:
Because we want to do this:
openssl s_client -connect example.com:5223 -CAfile ca.crt
AFAIK there is no good way to do something similar for STARTTLS
connections. If you know of a way, please do let us know.
adding a xmpp-starttls to s_client is not that difficult...
A patch (diff against good old openssl 0.9.8d) is attached.
Beware, detection of the starttls stream feature is not perfectly
reliable. Usage:
`openssl s_client -connect example.com:5222 -starttls xmpp -starttls_to
example.com`
--- openssl-0.9.8d/apps/s_client.c 2005-11-25 14:46:41.000000000 +0100
+++ openssl-0.9.8d-patched/apps/s_client.c 2007-02-22 21:39:04.000000000
+0100
@@ -187,6 +187,8 @@
BIO_printf(bio_err," -host host - use -connect instead\n");
BIO_printf(bio_err," -port port - use -connect instead\n");
BIO_printf(bio_err," -connect host:port - who to connect to (default is
%s:%s)\n",SSL_HOST_NAME,PORT_STR);
+ BIO_printf(bio_err, " -starttls_to name - use name as 'to' in xmpp
starttls mode, default is host from -connect\n");
+ BIO_printf(bio_err, " -starttls_from name - use name as 'from' in xmpp
s2s starttls mode\n");
BIO_printf(bio_err," -verify depth - turn on peer certificate
verification\n");
BIO_printf(bio_err," -cert arg - certificate file to use, PEM
format assumed\n");
@@ -249,6 +251,8 @@
short port=PORT;
int full_log=1;
char *host=SSL_HOST_NAME;
+ char *starttls_tohost=NULL;
+ char *starttls_fromhost=NULL;
char *cert_file=NULL,*key_file=NULL;
int cert_format = FORMAT_PEM, key_format = FORMAT_PEM;
char *passarg = NULL, *pass = NULL;
@@ -327,6 +331,16 @@
if (--argc < 1) goto bad;
host= *(++argv);
}
+ else if (strcmp(*argv,"-starttls_to") == 0)
+ {
+ if (--argc < 1) goto bad;
+ starttls_tohost= *(++argv);
+ }
+ else if (strcmp(*argv,"-starttls_from") == 0)
+ {
+ if (--argc < 1) goto bad;
+ starttls_fromhost= *(++argv);
+ }
else if (strcmp(*argv,"-port") == 0)
{
if (--argc < 1) goto bad;
@@ -469,6 +483,10 @@
starttls_proto = 1;
else if (strcmp(*argv,"pop3") == 0)
starttls_proto = 2;
+ else if (strcmp(*argv, "xmpp") == 0)
+ starttls_proto = 3;
+ else if (strcmp(*argv, "xmpp-server") == 0)
+ starttls_proto = 4;
else
goto bad;
}
@@ -731,6 +749,60 @@
BIO_printf(sbio,"STLS\r\n");
BIO_read(sbio,sbuf,BUFSIZZ);
}
+ if (starttls_proto == 3 || starttls_proto == 4)
+ {
+ int r;
+ if (starttls_proto == 3)
+ {
+ BIO_printf(bio_c_out, "using XMPP c2s protocol\n");
+ BIO_printf(sbio,"<stream:stream "
+
"xmlns:stream='http://etherx.jabber.org/streams' "
+ "xmlns='jabber:client' "
+ "to='%s' version='1.0'>", starttls_tohost);
+ }
+ else
+ {
+ BIO_printf(bio_c_out, "using XMPP s2s protocol\n");
+ BIO_printf(sbio,"<stream:stream "
+
"xmlns:stream='http://etherx.jabber.org/streams' "
+ "xmlns='jabber:server' "
+ "xmlns:db='jabber:server:dialback' "
+ "to='%s' from='%s' version='1.0'>",
+ starttls_tohost, starttls_fromhost);
+ }
+ BIO_printf(bio_c_out, "sent opening stream header\n");
+ BIO_printf(bio_c_out, "expecting for stream:features\n");
+ r = BIO_read(sbio,mbuf,BUFSIZZ);
+ mbuf[r] = 0;
+ BIO_printf(bio_c_out, "READ: %s\n", mbuf);
+ while(!strstr(mbuf, "<starttls
xmlns='urn:ietf:params:xml:ns:xmpp-tls'"))
+ {
+ if (strstr(mbuf, "/stream:features>"))
+ {
+ BIO_printf(bio_c_out, "error: no starttls stream
feature\n");
+ goto shut;
+ }
+ r = BIO_read(sbio,mbuf,BUFSIZZ);
+ mbuf[r] = 0;
+ BIO_printf(bio_c_out, "READ: %s\n", mbuf);
+ }
+ BIO_printf(sbio, "<starttls
xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
+ BIO_printf(bio_c_out, "sent: starttls\n");
+ r = BIO_read(sbio,sbuf,BUFSIZZ);
+ sbuf[r] = 0;
+ BIO_printf(bio_c_out, "READ: %s\n", sbuf);
+ if (strstr(sbuf, "<proceed"))
+ BIO_printf(bio_c_out, "proceeding\n");
+ else if (strstr(sbuf, "<failure"))
+ {
+ BIO_printf(bio_c_out, "got failure. bailing out\n");
+ goto shut;
+ }
+ else
+ BIO_printf(bio_c_out, "probably there was an error\n");
+ BIO_flush(bio_c_out);
+ mbuf[0] = 0;
+ }
for (;;)
{