dongpao5127 2015-03-31 13:48
浏览 59
已采纳

ejabberd外部认证php sql server

I have a ejabberd 15.03 server in a centOS virtual machine and i need to implement an external authentification method with php against SQL server. The official documentation shows a php/mysql example php/mysql external authentification

Are there a method to change this example to php/sqlserver and functions such as mysql_ping.

Here is an example i wrote and put it under /opt/auth/ and configured ejabberd.yml to execute is as external authentification.

$auth = new JabberAuth();
$auth->dbhost = "hostIP";
$auth->dbuser = "user";
$auth->dbpass = "pass";
$auth->dbbase = "databaseName";



$auth->play(); // We simply start process !

class JabberAuth {
    var $dbhost; 
    var $dbuser; 
    var $dbpass;
    var $dbbase; 

    var $debug      = false;                      /* Debug mode */
    var $debugfile  = "/opt/auth/log/pipe-debug.log";  /* Debug output */
    var $logging    = false;                      /* Do we log requests ? */
    var $logfile    = "/opt/auth/log/pipe-log.log" ;   /* Log file ... */
    /*
     * For both debug and logging, ejabberd have to be able to write.
     */

    var $jabber_user;   /* This is the jabber user passed to the script. filled by $this->command() */
    var $jabber_pass;   /* This is the jabber user password passed to the script. filled by $this->command() */
    var $jabber_server; /* This is the jabber server passed to the script. filled by $this->command(). Useful for VirtualHosts */
    var $jid;           /* Simply the JID, if you need it, you have to fill. */
    var $data;          /* This is what SM component send to us. */

    var $dateformat = "M d H:i:s"; /* Check date() for string format. */
    var $command; /* This is the command sent ... */
    var $mysock;  /* MySQL connection ressource */
    var $stdin;   /* stdin file pointer */
    var $stdout;  /* stdout file pointer */

    function JabberAuth()
    {
        @define_syslog_variables();
        @openlog("pipe-auth", LOG_NDELAY, LOG_SYSLOG);

        if($this->debug) {
            @error_reporting(E_ALL);
            @ini_set("log_errors", "1");
            @ini_set("error_log", $this->debugfile);
        }
        $this->logg("Starting pipe-auth ..."); // We notice that it's starting ...
        $this->openstd();
    }

    function stop()
    {
        $this->logg("Shutting down ..."); // Sorry, have to go ...
        closelog();
        $this->closestd(); // Simply close files
        exit(0); // and exit cleanly
    }

    function openstd()
    {
        $this->stdout = @fopen("php://stdout", "w"); // We open STDOUT so we can read
        $this->stdin  = @fopen("php://stdin", "r"); // and STDIN so we can talk !
    }

    function readstdin()
    {
        $l      = @fgets($this->stdin, 3); // We take the length of string
        $length = @unpack("n", $l); // ejabberd give us something to play with ...
        $len    = $length["1"]; // and we now know how long to read.
        if($len > 0) { // if not, we'll fill logfile ... and disk full is just funny once
            $this->logg("Reading $len bytes ... "); // We notice ...
            $data   = @fgets($this->stdin, $len+1);
            // $data = iconv("UTF-8", "ISO-8859-15", $data); // To be tested, not sure if still needed.
            $this->data = $data; // We set what we got.
            $this->logg("IN: ".$data);
        }
    }

    function closestd()
    {
        @fclose($this->stdin); // We close everything ...
        @fclose($this->stdout);
    }

    function out($message)
    {
        @fwrite($this->stdout, $message); // We reply ...
        $dump = @unpack("nn", $message);
        $dump = $dump["n"];
        $this->logg("OUT: ". $dump);
    }

    function myalive()
    {
        if(!is_resource($this->mysock) || !@mysql_ping($this->mysock)) { // check if we have a MySQL connection and if it's valid.
            $this->mysql(); // We try to reconnect if MySQL gone away ...
            return @mysql_ping($this->mysock); // we simply try again, to be sure ...
        } else {
            return true; // so good !
        }
    }

    function play()
    {
        do {
            $this->readstdin(); // get data
            $length = strlen($this->data); // compute data length
            if($length > 0 ) { // for debug mainly ...
                $this->logg("GO: ".$this->data);
                $this->logg("data length is : ".$length);
            }
            $ret = $this->command(); // play with data !
            $this->logg("RE: " . $ret); // this is what WE send.
            $this->out($ret); // send what we reply.
            $this->data = NULL; // more clean. ...
        } while (true);
    }

    function command()
    {
        $data = $this->splitcomm(); // This is an array, where each node is part of what SM sent to us :
        // 0 => the command,
        // and the others are arguments .. e.g. : user, server, password ...

        if($this->myalive()) { // Check we can play with MySQL
            if(strlen($data[0]) > 0 ) {
                $this->logg("Command was : ".$data[0]);
            }
            switch($data[0]) {
                case "isuser": // this is the "isuser" command, used to check for user existance
                        $this->jabber_user = $data[1];
                        $parms = $data[1];  // only for logging purpose
                        $return = $this->checkuser();
                    break;

                case "auth": // check login, password
                        $this->jabber_user = $data[1];
                        $this->jabber_pass = $data[3];
                        $parms = $data[1].":".$data[2].":".md5($data[3]); // only for logging purpose
                        $return = $this->checkpass();
                    break;

                case "setpass":
                        $return = false; // We do not want jabber to be able to change password
                    break;

                default:
                        $this->stop(); // if it's not something known, we have to leave.
                        // never had a problem with this using ejabberd, but might lead to problem ?
                    break;
            }

            $return = ($return) ? 1 : 0;

            if(strlen($data[0]) > 0 && strlen($parms) > 0) {
                $this->logg("Command : ".$data[0].":".$parms." ==> ".$return." ");
            }
            return @pack("nn", 2, $return);
        } else {
            // $this->prevenir(); // Maybe useful to tell somewhere there's a problem ...
            return @pack("nn", 2, 0); // it's so bad.
        }
    }

    function checkpass()
    {


$hash=sha1($this->jabber_pass);
$query = mssql_query("SELECT [attribute] FROM [DatabaseName].[dbo].[table] where (S_USERNAME='$this->jabber_user') AND  (SUBSTRING(S_PASSWORD,1,(LEN(S_PASSWORD)-3)))='$hash'");


// Check if there were any records
if (!mssql_num_rows($query)) {
    return false;
} else {
    return true;
}
    }

    function checkuser()
    {

$query = mssql_query("SELECT [attribute] FROM [DatabaseName].[dbo].[table] where S_USERNAME='$this->jabber_user'");

// Check if there were any records
if (!mssql_num_rows($query)) {
    return false;
} else {
    return true;
}

    }

    function splitcomm() // simply split command and arugments into an array.
    {
        return explode(":", $this->data);
    }

    function mysql() // "MySQL abstraction", this opens a permanent MySQL connection, and fill the ressource
    {

        $this->mysock = @mssql_pconnect($this->dbhost, $this->dbuser, $this->dbpass);
        echo '1';
        var_dump($this->mysock);
        @mssql_select_db($this->dbbase, $this->mysock);
        $this->logg("MsSql :: ". (is_resource($this->mysock) ? "Connecté" : "Déconnecté"));
    }

    function logg($message) // pretty simple, using syslog.
    // some says it doesn't work ? perhaps, but AFAIR, it was working.
    {
        if($this->logging) {
            @syslog(LOG_INFO, $message);
        }
    }
}

This did not make any php error. But in ejabberd.log i'm always getting 'extauth script has exitted abruptly with reason 'normal' '

This is the crash report in crash.log

2015-04-01 17:44:12 =CRASH REPORT==== crasher: initial call: ejabberd_http:init/2 pid: <0.8779.0> registered_name: [] exception error: bad argument: [{extauth,call_port,2,[{file,"src/extauth.erl"},{line,99}]},{ejabberd_auth_external,check_password_extauth,3,[{file,"src/ejabberd_auth_external.erl"},{line,182}]},{ejabberd_auth_external,check_password_external_cache,3,[{file,"src/ejabberd_auth_external.erl"},{line,244}]},{ejabberd_auth,check_password_loop,2,[{file,"src/ejabberd_auth.erl"},{line,158}]},{ejabberd_auth,check_password,3,[{file,"src/ejabberd_auth.erl"},{line,106}]},{ejabberd_web_admin,get_auth_account,5,[{file,"src/ejabberd_web_admin.erl"},{line,266}]},{ejabberd_web_admin,process,2,[{file,"src/ejabberd_web_admin.erl"},{line,221}]},{ejabberd_http,process,5,[{file,"src/ejabberd_http.erl"},{line,359}]}] ancestors: [ejabberd_http_sup,ejabberd_sup,<0.37.0>] messages: [] links: [<0.327.0>,#Port<0.12042>] dictionary: [{random_seed,{2036,6729,29501}}] trap_exit: false status: running heap_size: 2586 stack_size: 27 reductions: 1244 neighbours: 2015-04-01 17:44:12 =SUPERVISOR REPORT==== Supervisor: {local,ejabberd_http_sup} Context: child_terminated Reason: badarg Offender: [{pid,<0.8779.0>},{name,undefined},{mfargs,{ejabberd_http,start_link,undefined}},{restart_type,temporary},{shutdown,1000},{child_type,worker}]

It seem to be a misconfiguration error. This is what i added to ejabberd.yml

auth_method: external
extauth_program: "php -f /etc/ejabberd-15.03/auth_script.php"
extauth_cache: 600
extauth_instances: 3
  • 写回答

1条回答 默认 最新

  • dongshou9343 2015-04-20 12:33
    关注

    I think that recent version of ejabberd do not support SQL-server. So i finally moved to openfire with support many databases.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 安装svn网络有问题怎么办
  • ¥15 Python爬取指定微博话题下的内容,保存为txt
  • ¥15 vue2登录调用后端接口如何实现
  • ¥65 永磁型步进电机PID算法
  • ¥15 sqlite 附加(attach database)加密数据库时,返回26是什么原因呢?
  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥15 latex怎么处理论文引理引用参考文献