[ejabberd] ejabberd starts external auth script but doesn't use it to auth users

Coiby Xu coiby.xu at gmail.com
Fri Apr 27 07:15:05 MSK 2012


Can anybody give any suggestion?

Supplements: I called the external auth script from bash and it's OK.

2012/4/23 Coiby Xu <coiby.xu at gmail.com>

> Hi all,
>
> I met a weird problem(My post at forum is not approved. So I resend this
> question to this mailing list): ejabberd already starts external auth
> script but doesn't use it to auth users.
>
> Here are my configs(key part) and auth script:
>
> 1. in /etc/ejabberd/ejabberd.cfg
> %%{auth_method, internal}.
> %%
> %% Store the plain passwords or hashed for SCRAM:
> %%{auth_password_format, plain}.
> %%{auth_password_format, scram}.
>
> %%
> %% Authentication using external script
> %% Make sure the script is executable by ejabberd.
> %%
> {auth_method, external}.
> {extauth_program, "/usr/share/gforge/src/plugins/ejabberd/auth/
> gforge-auth.pl"}.
> %%{extauth_cache, 600}.
> %%{extauth_instances, 3}.
>
> 2. in /usr/share/gforge/src/plugins/ejabberd/auth/gforge-auth.pl
>  #!/usr/bin/perl
>
> # Postgresql-gforge external auth script
> # Features: auth works. isUser works, and setPass works, with MD5
> encryption.
> # Restrictions: Username or passwords may not contain some special
> characters: $'"` nor line breaks
>
> # Security considerations:
> #  - character filtering may not be perfect, but the most important '$"`
> are filtered out by this script
>
> # CHANGELOG:
> #
> # Based on check_postgresql.pl
> # which can be found here:
> http://www.ejabberd.im/files/efiles/check_postgresql.pl.txt
>
> my $dbUser="gforge";  # The username to connect to postgresql
> my $dbName="gforge"; # The name of the database inside postgresql
> my $dbTable="users"; # The name of the table inside the database
> my $fieldUser="user_name";   # The name of the field that holds jabber
> user names
> my $fieldPass="user_pw";   # The name of the field that holds jabber
> passwords
> my $fieldUnixPass="unix_pw";
>
> use Unix::Syslog qw(:macros :subs);
> use Digest::MD5 "md5_hex";
> use Crypt::PasswdMD5 "unix_md5_crypt";
>
> sub gensalt
> {
>     my @salt = ( '.', '/', 0 .. 9, 'A' .. 'Z', 'a' .. 'z' );
>     my $salt;
>     $salt .= (@salt)[rand @salt];
>     $salt .= (@salt)[rand @salt];
>     return $salt;
> }
>
> while(1)
>   {
>
>     my $buf = "";
>     syslog LOG_INFO,"waiting for packet, hello";
>     my $nread = sysread STDIN,$buf,2;
>     do { syslog LOG_INFO,"port closed"; exit; } unless $nread == 2;
>     my $len = unpack "n",$buf;
>     my $nread = sysread STDIN,$buf,$len;
>
>     my ($op,$user,$domain,$password) = split /:/,$buf;
>
>     # Filter dangerous characters
>     $user =~ s/[."\n\r'\$`]//g;
>     $password =~ s/[."\n\r'\$`]//g;
>
>     $unix_password = unix_md5_crypt( $password, gensalt() );
>     $password = md5_hex($password);
>
>     #$user =~ s/\./\//og;
>     #my $jid = "$user\@$domain";
>     my $result;
>     syslog LOG_INFO,"nice, very nice";
>     syslog(LOG_INFO,"request (%s)", $op);
>     syslog(LOG_INFO,"buffer (%s)", $buf);
>   SWITCH:
>       {
> $op eq 'auth' and do
>   {
>         $orden = "psql -U $dbUser $dbName --command \"select count(*) from
> $dbTable where $fieldUser='$user' and $fieldPass='$password';\" |
> grep '^ *[1-9][0-9]* *\$' &> /dev/null";
>      syslog(LOG_INFO,"Executing: %s",$orden);
>
>      # if command returned 0 we return 1
>      $result = !system($orden);
>   },last SWITCH;
>
> $op eq 'setpass' and do
>   {
>             $unix_password =~ s/\$/\\\$/g;
>             $orden = "psql -U $dbUser $dbName --command \"UPDATE $dbTable
> SET $fieldPass='$password', $fieldUnixPass='$unix_password' where
> $fieldUser='$user';\" | grep '^.*[1-9][0-9]* *\$' &> /dev/null";
>             syslog(LOG_INFO,"Executing: %s",$orden);
>
>             # if command returned 0 we return 1
>             $result = !system($orden);
>
>   },last SWITCH;
>
>         $op eq 'isuser' and do
>           {
>              # password is null. Return 1 if the user $user exists.
>      $result = 0;
>              $orden = "psql -U $dbUser $dbName --command \"select count(*)
> from $dbTable where $fieldUser='$user';\" | grep '^ *[1-9][0-9]* *\$' &>
> /dev/null";
>      syslog(LOG_INFO,"auth: Executing is_user: %s",$orden);
>
>      # if command returned 0 we return 1
>      $result = !system($orden);
>           },last SWITCH;
>       };
>     my $out = pack "nn",2,$result ? 1 : 0;
>     syswrite STDOUT,$out;
>   }
>
> closelog;
>
> In /var/log/message, there are logs and we only have these:
>
> Apr 23 10:41:45 innov perl: waiting for packet, hello
>
> and /var/log/ejabberd/ejabber.log
>
> I(<0.500.0>:ejabberd_c2s:775) :
> ({socket_state,gen_tcp,#Port<0.3374>,<0.499.0>}) Accepted authentication
> for coibyt by ejabberd_auth_internal
> ...
> I(<0.485.0>:ejabberd_c2s:810) :
> ({socket_state,gen_tcp,#Port<0.3351>,<0.484.0>}) Failed authentication for
> coibyt at innov.zjustu.org
>
> According to the logs, ejabberd is starting the auth script but doesn't
> use that script to auth user, why?
>
> Btw, who's the user that runs the external auth script?
>
> Thanks!
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.jabber.ru/pipermail/ejabberd/attachments/20120427/c86e6fc7/attachment.html>


More information about the ejabberd mailing list