Когда стало решительно нехрен делать - решил написать жаббероклиент. Слегка задрался с открытием сокета и форматированием xml, но вроде выжил.
Косяк такой получился: открываю поток клиентом, сервер отсылает ответ типа «ты кто такой», отсылаю PLAIN для base64, получаю в ответ bad-protocol. Сервер такой вариант предлагает сам, так что тут все ок.
Как оно все выглядит с точки зрения сервера:
=INFO REPORT==== 2015-05-05 14:41:10 ===
D(<0.458.0>:ejabberd_receiver:320) : Received XML on stream = "<?xml version='1.0'?><stream:stream xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:client' xml:lang='en' version='1.0' to='192.168.42.54' from='test@192.168.42.54'>"
=INFO REPORT==== 2015-05-05 14:41:10 ===
D(<0.459.0>:ejabberd_c2s:1553) : Send XML on stream = <<"<stream:features><mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><mechanism>SCRAM-SHA-1</mechanism><mechanism>DIGEST-MD5</mechanism><mechanism>PLAIN</mechanism></mechanisms><c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='http://www.process-one.net/en/ejabberd/' ver='TQ2JFyRoSa70h2G1bpgjzuXb2sU='/><register xmlns='http://jabber.org/features/iq-register'/></stream:features>">>
=INFO REPORT==== 2015-05-05 14:41:21 ===
D(<0.458.0>:ejabberd_receiver:320) : Received XML on stream = "<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'>XDB0ZXN0XDB0ZXN0</auth>"
=INFO REPORT==== 2015-05-05 14:41:21 ===
D(<0.459.0>:ejabberd_c2s:1553) : Send XML on stream = <<"<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><bad-protocol/></failure>">>
сервер ejabberd