I am using the docker-ejabberd/ecs container as a XMPP server and the Net::XMPP perl client My ejabberd.yml looks like this:
hosts:
- jabber-gw.foobar.me
loglevel: debug
ca_file: /etc/ssl/certs/ca-certificates.crt
acme:
ca_url: https://ca.foobar.local:8000/acme/acme/directory
auto: false
cert_type: rsa
listen:
-
port: 5222
ip: "0.0.0.0"
module: ejabberd_c2s
max_stanza_size: 65536
shaper: c2s_shaper
access: c2s
starttls_required: true
-
port: 5223
ip: "0.0.0.0"
tls: true
module: ejabberd_c2s
shaper: c2s_shaper
access: c2s
starttls_required: true
-
port: 5269
ip: "0.0.0.0"
module: ejabberd_s2s_in
max_stanza_size: 65536
-
port: 5443
ip: "0.0.0.0"
module: ejabberd_http
tls: true
request_handlers:
/admin: ejabberd_web_admin
/api: mod_http_api
/bosh: mod_bosh
/captcha: ejabberd_captcha
/upload: mod_http_upload
/ws: ejabberd_http_ws
-
port: 5280
ip: "0.0.0.0"
module: ejabberd_http
request_handlers:
/admin: ejabberd_web_admin
/.well-known/acme-challenge: ejabberd_acme
-
port: 3478
ip: "0.0.0.0"
transport: udp
module: ejabberd_stun
use_turn: true
## The server's public IPv4 address:
# turn_ipv4_address: "203.0.113.3"
## The server's public IPv6 address:
# turn_ipv6_address: "2001:db8::3"
-
port: 1883
ip: "0.0.0.0"
module: mod_mqtt
backlog: 1000
s2s_use_starttls: optional
acl:
local:
user_regexp: ""
loopback:
ip:
- 127.0.0.0/8
- ::1/128
My ejabberd client perl code looks like this:
#!/usr/bin/perl
use strict;
use warnings;
use Net::XMPP qw( Client );
if ($#ARGV < 4)
{
print "\nperl client.pl <server> <port> <username> <password> <resource> \n\n";
exit(0);
}
my $server = $ARGV[0];
my $port = $ARGV[1];
my $username = $ARGV[2];
my $password = $ARGV[3];
my $resource = $ARGV[4];
$SIG{HUP} = \&Stop;
$SIG{KILL} = \&Stop;
$SIG{TERM} = \&Stop;
$SIG{INT} = \&Stop;
my $Connection = new Net::XMPP::Client(
debug => "stdout",
debuglevel => 2
);
$Connection->SetCallBacks(message=>\&InMessage,
presence=>\&InPresence,
iq=>\&InIQ);
my $status = $Connection->Connect(hostname=>$server,
port=>$port,
tls=>1,
srv=>"jabber-gw.foobar.me",
ssl_ca_path=>"/etc/ssl/certs/"
);
if (!(defined($status)))
{
print "ERROR: Jabber server is down or connection was not allowed.\n";
print " ($!)\n";
exit(0);
}
my @result = $Connection->AuthSend(username=>$username,
password=>$password,
resource=>$resource);
if ($result[0] ne "ok")
{
print "ERROR: Authorization failed: $result[0] - $result[1]\n";
exit(0);
}
print "Logged in to $server:$port...\n";
$Connection->RosterGet();
print "Getting Roster to tell server to send presence info...\n";
$Connection->PresenceSend();
print "Sending presence to tell world that we are logged in...\n";
while(defined($Connection->Process())) { }
print "ERROR: The connection was killed...\n";
exit(0);
sub Stop
{
print "Exiting...\n";
$Connection->Disconnect();
exit(0);
}
I can successfully obtain an ACME cert for my host, then add the ca root cert to the clients ssl_ca_path. I then register the client on the server with ejabberdclt instructions. When i try to connect the client to the server, i see **Nodeprep failed **in the server logs:
2022-11-28 05:35:44.211915 00:00 [info] (<0.974.0>) Accepted connection 192.168.11.19:44198 -> 192.168.32.4:5222
2022-11-28 05:35:44.212589 00:00 [notice] (tcp|<0.974.0>) Received XML on stream = <<"<?xml version='1.0'?><stream:stream version='1.0' xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:client' to='jabber-gw.foobar.me' from='OMVonHP.foobar.me' xml:lang='en' >">>
..
omitted
..
2022-11-28 05:35:44.310551 00:00 [notice] (tls|<0.974.0>) Received XML on stream = <<"<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'></response>">>
2022-11-28 05:35:44.310855 00:00 [debug] Running hook c2s_handle_recv: mod_stream_mgmt:c2s_handle_recv/3
2022-11-28 05:35:44.311055 00:00 [debug] Running hook c2s_auth_result: ejabberd_c2s:process_auth_result/3
2022-11-28 05:35:44.311249 00:00 [warning] (tls|<0.974.0>) Failed c2s DIGEST-MD5 authentication from 192.168.11.19: Nodeprep failed
2022-11-28 05:35:44.311422 00:00 [debug] Running hook c2s_auth_result: mod_fail2ban:c2s_auth_result/3
2022-11-28 05:35:44.311667 00:00 [notice] (tls|<0.974.0>) Send XML on stream = <<"<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><not-authorized/><text xml:lang='en'>Nodeprep failed</text></failure>">>
2022-11-28 05:35:44.311953 00:00 [debug] Running hook c2s_handle_send: mod_push:c2s_stanza/3
2022-11-28 05:35:44.314781 00:00 [debug] Running hook c2s_terminated: mod_pubsub:on_user_offline/2
2022-11-28 05:35:44.315136 00:00 [debug] Running hook c2s_terminated: ejabberd_c2s:process_terminated/2
2022-11-28 05:35:44.315395 00:00 [notice] (tls|<0.974.0>) Send XML on stream = <<"</stream:stream>">>
and in the client logs:
DMyODMwZg==)
XML::Stream: Node: _handle_close: sid(6607014926489030516) sax(XML::Stream::Parser=HASH(0x55e0c0b3e700)) tag(challenge)
XML::Stream: Node: _handle_close: check( 0 )
XML::Stream: Node: _handle_close: check2( -1 )
XML::Stream: Send: (<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'></response>)
XML::Stream: Process: block(0)
XMPP::Conn: AuthSASL: haven't authed yet... let's wait.
XMPP::Conn: Process: timeout(1)
XML::Stream: Read: buff(<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><not-authorized/><text xml:lang='en'>Nodeprep failed</text></failure>)
XMPP::Conn: AuthSASL: Authentication failed.
ERROR: Authorization failed: error - not-authorized
I cant find anywhere what Nodeprep failed means? Would appreciate some help thanks.
CodePudding user response:
nodeprep, node preparation, it parses the username to see if it satisfies the characters requirements by XMPP: not using invalid characters like " & ' / : < > @
Did you try to register an account with latin characters like "admin" or "lukewarms", or did it include more complex or uncommon characters?
I installed ejabberd 21.12 from souce, disabled starttls because I don't have a valid certificate, and your script works correctly:
ejabberdctl register admin localhost asd
...
./client.perl localhost 5222 admin asd Perr
...
ejabberd log file shows:
2022-11-28 16:47:15.776517 01:00 [info] (<0.1263.0>)
Accepted connection [::ffff:127.0.0.1]:60816 -> [::ffff:127.0.0.1]:5222
2022-11-28 16:47:15.847908 01:00 [info] (tcp|<0.1263.0>)
Accepted c2s PLAIN authentication for admin@localhost
by mnesia backend from ::ffff:127.0.0.1
2022-11-28 16:47:15.878782 01:00 [info] (tcp|<0.1263.0>)
Opened c2s session for admin@localhost/Perr
2022-11-28 16:47:15.928367 01:00 [info] (tcp|<0.1263.0>)
Closing c2s session for admin@localhost/Perr:
Connection failed: connection closed
Some ideas for you to try:
A) Try registering and logging in an account with simple username, like "abcd"
B) Try logging in with a well-known and tested XMPP client, like Gajim, Psi, Conversations, ...
C) Try disabling starttls in the 5222 port, to check if there's some problem there.
CodePudding user response:
OK, it's taken me two and a half days but i have a workaround. I've worked out it's failing whilst the client is using DIGEST-MD5 sasl authentication mechanism (likely cos the NET::XMPP library hasn't been refreshed in many years). I discovered here that you can force the server to disable sasl mechanisms offered to the client, so i added:
disable_sasl_mechanisms: DIGEST-MD5
to my ejabberd.yml file which forced plain auth - not ideal but in my case i am using TLS and certs so i can live with it. With plain auth my client connects fine without Nodeprep failures.