2015-03-31 49 views
3

我有一個centos虛擬機中的ejabberd 15.03服務器,我需要用php對SQL服務器實現外部認證方法。 官方文檔顯示了一個php/mysql示例 php/mysql external authentificationejabberd外部認證php sqlserver

是否有一種方法可以將此示例更改爲php/sqlserver和函數,如mysql_ping。

這裏是我編寫的一個例子,並將其放在/ opt/auth /下並配置ejabberd.yml來執行,作爲外部認證。

$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) || [email protected]_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); 
     } 
    } 
} 

這並沒有使任何PHP錯誤。但在ejabberd.log我一直都想與 正常‘ 'extauth腳本已與原因突然exitted’

這是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}]

崩潰報告,這一點似乎是一個錯誤配置錯誤。 這是我加入什麼ejabberd.yml

auth_method: external 
extauth_program: "php -f /etc/ejabberd-15.03/auth_script.php" 
extauth_cache: 600 
extauth_instances: 3 
+1

您需要將調試添加到您的腳本中,以知道它爲何退出。 – 2015-04-02 08:44:01

+0

我存在'error_reporting(E_ALL);'我沒有在代碼中添加它。 – 2015-04-02 08:50:25

+0

那麼,你爲什麼退出,在哪裏? – 2015-04-02 08:52:57

回答

0

我認爲最近ejabberd的版本不支持SQL服務器。 所以我終於搬到了支持許多數據庫的openfire。