如何在稍后将socat tcp4连接更改为SSL连接(使用XMPP协议)

时间:2016-01-13 04:55:36

标签: ssl xmpp socat

我正在考虑创建一个非常简单的XMPP代理。 XMPP协议以纯文本开头,然后在支持的情况下将套接字转换为SSL并继续。

以下是一个示例XMPP会话,我将其修剪为基本部分: 检查功能:

(11:49:48) jabber: Sending (chris@localhost): <?xml version='1.0' ?>
(11:49:48) jabber: Sending (chris@localhost): <stream:stream to='localhost' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>
(11:49:48) jabber: Recv (358): <?xml version='1.0'?><stream:stream xmlns:stream='http://etherx.jabber.org/streams' version='1.0' from='localhost' id='5dea6b36-2da5-485a-8bed-16884e56d6f3' xml:lang='en' xmlns='jabber:client'><stream:features><starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'><required/></starttls><register xmlns='http://jabber.org/features/iq-register'/></stream:features>

告诉服务器开始使用SSL进行通信并交换密钥:

(11:49:48) jabber: Sending (chris@localhost): <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
(11:49:48) jabber: Recv (50): <proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
(11:49:48) nss: SSL version 3.3 using 256-bit AES with 256-bit SHA256 MAC
Server Auth: 2048-bit RSA, Key Exchange: 2048-bit RSA, Compression: NULL
Cipher Suite Name: TLS_RSA_WITH_AES_256_CBC_SHA256
(11:49:48) certificate: Successfully verified certificate for localhost

我们现在处于SSL会话中:

(11:49:48) jabber: Sending (ssl) (chris@localhost): <stream:stream to='localhost' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>
(11:49:48) jabber: Recv (ssl)(447): <?xml version='1.0'?><stream:stream xmlns:stream='http://etherx.jabber.org/streams' version='1.0' from='localhost' id='74a00818-e037-4405-ada1-02bb3dbfe023' xml:lang='en' xmlns='jabber:client'>

当我尝试创建socat SSL&#34;服务器&#34;并使用Pidgin连接到它我得到了未知的协议:

$ socat openssl-listen:5222,reuseaddr,cert=$HOME/server.pem,cafile=$HOME/client.crt,fork -
2016/01/13 14:00:59 socat[28586] E SSL_accept(): error:140760FC:SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol

我尝试使用socat非SSL&#34;服务器&#34;并且它一直工作直到需要更改为SSL(我已添加&#34;客户端:&#34;和#34;服务器:&#34;此输出以便于阅读。所有&#34 ;服务器:&#34;线被我粘贴到终端中):

$ socat tcp4-listen:5222,reuseaddr,fork -
Client: <?xml version='1.0' ?><stream:stream to='localhost' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>
Server: <?xml version='1.0'?><stream:stream xmlns:stream='http://etherx.jabber.org/streams' version='1.0' from='localhost' id='5dea6b36-2da5-485a-8bed-16884e56d6f3' xml:lang='en' xmlns='jabber:client'><stream:features><starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'><required/></starttls><register xmlns='http://jabber.org/features/iq-register'/></stream:features>
Client: <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
Server: <proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
Client: tp�C?�f�Q��|_pV��j���=�^(�32g98kf�/<5=

在最后一行,客户端现在正试图通过SSL与我们交谈,所以我需要一种方法告诉socat在那时切换到SSL。 Socat显然对XMPP协议一无所知,因此它不知道何时切换。可以告诉socat像这样动态切换,还是应该考虑其他方法来做到这一点?

编辑:我做了更多的研究 许多协议,例如HTTPS使用&#34;总是加密&#34;连接。
XMPP使用starttls,它基本上意味着未加密的连接,直到客户端和服务器同意将连接升级为加密。

编辑:我只是看了一下openssl,它有一个s_client的-starttls,但不是s_server,它告诉我这是一个架构问题,知道或被告知时很棘手以及如何将连接升级为加密。

所以我想我真正的问题是,socat可以处理使用starttls的协议,无论是否有一些人工干预来告诉它何时切换?我不认为openssl可以。是否有其他工具可以做到这一点,或者我当然应该使用SSL库编写自己的工具?

1 个答案:

答案 0 :(得分:0)

使用SSL / TLS有两种方法:
XMPP使用STARTTLS,客户端和服务器讨论其安全功能,然后客户端请求在通信中的任意点将套接字转换为TLS。 HTTPS和其他人使用两个套接字,一个用于讨论安全功能,然后通信切换到纯粹用于加密通信的第二个套接字设置。

socat:
不支持STARTTLS。

的OpenSSL:
支持客户端的STARTTLS:

@if (User.IsInRole("intern"))

在服务器端,据我所知,每种情况都需要自定义代码。我找到了XML Base有用的Python脚本。