Hi, Problem =======
I'm trying to obtain the certificate of an XMPP server using openssl s_client -connect server.domain.tld:5222 -starttls xmpp However, the name of the server within the XMPP realm is only domain.tld rather than server.domain.tld. The above command tries to start the TLS connection as follows. <stream:stream xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:client' to='server.domain.tld' version='1.0'> But gets rejected with the following message. <stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' id='3729850247' from='domain.tld' xml:lang='en'> <stream:error> <host-unknown xmlns='urn:ietf:params:xml:ns:xmpp-streams'/> </stream:error> Note that the message is sent to server.domain.tld, but the error comes from domain.tld. The solution to this problem seems to be the -servername option to s_client: openssl s_client -connect server.domain.tld:5222 -starttls xmpp -servername domain.tld This however doesn't make any difference, and the stream is started by OpenSSL the same as before: <stream:stream xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:client' to='server.domain.tld' version='1.0'> Cause ===== Looking in apps/s_client.c (line 1181 for openssl-1.0.0e), there is if (starttls_proto == PROTO_XMPP) { int seen = 0; BIO_printf(sbio,"<stream:stream " "xmlns:stream='http://etherx.jabber.org/streams' " "xmlns='jabber:client' to='%s' version='1.0'>", host); [Note: I believe this should be an else if rather than an if statement (or maybe the whole conditionnal should be replaced by a switch statement), though I don't think it would change anything to the behaviour of the program either way.] The string which is sent to the XMPP server uses host, which contains the argument to -connect (from line 494), rather than that to -servername (the aptly named servername variable, line 712). Proposed Solution ================= On line 429, servername is initialised to NULL. The problem could then be solved quickly, but perhaps not very elegantly, by changing the BIO_printf() above with BIO_printf(sbio,"<stream:stream " "xmlns:stream='http://etherx.jabber.org/streams' " "xmlns='jabber:client' to='%s' version='1.0'>", servername?servername:host); (note the servername?servername:host towards the very end). See attached patch. Variable servername is defined within an OPENSSL_NO_TLSEXT conditionnal block, but, logically, so is the full starttls logic, so it shouldn't be a problem. I have compiled and tested a version patched with this proposal. It works as I would expect (i.e., it solves the very problem described above). This is such a trivial change that I don't believe it introduces anything unintended). Hope this helps. -- Olivier Mehani <[email protected]> PGP fingerprint: 4435 CF6A 7C8D DD9B E2DE F5F9 F012 A6E2 98C6 6655
Index: openssl-1.0.0e/apps/s_client.c
===================================================================
--- openssl-1.0.0e.orig/apps/s_client.c
+++ openssl-1.0.0e/apps/s_client.c
@@ -1183,7 +1183,7 @@ SSL_set_tlsext_status_ids(con, ids);
int seen = 0;
BIO_printf(sbio,"<stream:stream "
"xmlns:stream='http://etherx.jabber.org/streams' "
- "xmlns='jabber:client' to='%s' version='1.0'>", host);
+ "xmlns='jabber:client' to='%s' version='1.0'>",
servername?servername:host);
seen = BIO_read(sbio,mbuf,BUFSIZZ);
mbuf[seen] = 0;
while (!strstr(mbuf, "<starttls
xmlns='urn:ietf:params:xml:ns:xmpp-tls'"))
pgpjJT8qmGHVe.pgp
Description: PGP signature
