#!/usr/bin/php * published under GPL * * Latest version of this script is available at: * http://87.230.15.86/~dado/ejabberd/joomla-login * * Installation: * - create a new mysql user which only needs to select your joomla user table * $ mysql -u root -p joomla * Enter password: ******* * mysql> grant select on jos_users to ejabberd identified by 'p4ssw0rd'; * * (if your Joomla DB name or table prefix differs, change above lines) * * - Place this script somewhere on your filesystem, ie. /var/lib/ejabberd * (the full path would then be /var/lib/ejabberd/joomla-login) * * - Change variables below to fit your setup * * - Change it's owner to whichever user is running the server, ie. ejabberd * $ chown ejabberd:ejabberd /var/lib/ejabberd/joomla-login * * - Change the access mode so it is readable only to the user ejabberd and has exec * $ chmod 700 /var/lib/ejabberd/joomla-login * * - Edit your ejabberd.cfg file, comment out your auth_method and add: * {auth_method, external}. * {extauth_program, "/var/lib/ejabberd/joomla-login"}. * * - Restart your ejabberd service, you should be able to login with your Joomla auth info * * Other hints: * - if your users have a space or a @ in their username, they'll run into trouble * registering with any client so they should be instructed to replace these chars * " " (space) is replaced with "%20" * "@" is replaced with "(a)" * * - if your users have special chars and you're not using UTF-8 for Joomla, set * sJoomlaCharset below to match your Joomla encoding * */ // MySQL user which is used to connect to DB server $sDBUser = "ejabberd"; // MySQL password for the above user $sDBPassword = "p4ssw0rd"; // MySQL location, in 99% this is correct $sDBHost = "localhost"; // MySQL DB name in which your Joomla CMS is installed $sDBName = "joomla"; // Joomla table name prefix, this is the default, there should exist a {$PREFIX}users table $sJoomlaPrefix = "jos_"; // if you're running in some other charset then UTF-8, set it here so that usernames can contain // special chars. If you're running in UTF-8, set this to "" ie. // $sJoomlaCharset = ""; $sJoomlaCharset = "iso-8859-2"; // the logfile to which to write, should be writeable by the user which is running the server $sLogFile = "/var/log/ejabberd/exauth.log"; // set true to debug if needed $bDebug = false; $oAuth = new exAuth($sDBUser, $sDBPassword, $sDBHost, $sDBName, $sJoomlaPrefix, $sJoomlaCharset, $sLogFile, $bDebug); class exAuth { private $sDBUser; private $sDBPassword; private $sDBHost; private $sDBName; private $sJoomlaPrefix; private $sJoomlaCharset; private $sLogFile; private $bDebug; private $oMySQL; private $rLogFile; public function __construct($sDBUser, $sDBPassword, $sDBHost, $sDBName, $sJoomlaPrefix, $sJoomlaCharset, $sLogFile, $bDebug) { // setter $this->sDBUser = $sDBUser; $this->sDBPassword = $sDBPassword; $this->sDBHost = $sDBHost; $this->sDBName = $sDBName; $this->sJoomlaPrefix = $sJoomlaPrefix; $this->sJoomlaCharset = $sJoomlaCharset; $this->sLogFile = $sLogFile; $this->bDebug = $bDebug; // ovo ne provjeravamo jer ako ne mozes kreirati log file, onda si u kvascu :) $this->rLogFile = fopen($this->sLogFile, "a") or die("Error opening log file: ". $this->sLogFile); $this->writeLog("[exAuth] start"); $this->dbconnect(); // ovdje bi trebali biti spojeni na MySQL, imati otvoren log i zavrtit cekalicu do { $iHeader = fgets(STDIN, 3); $aLength = unpack("n", $iHeader); $iLength = $aLength["1"]; if($iLength > 0) { // ovo znaci da smo nesto dobili $sData = fgets(STDIN, $iLength + 1); if (isset($this->sJoomlaCharset) and !empty($this->sJoomlaCharset) and (strtoupper($this->sJoomlaCharset) != "UTF-8")) { $sData = iconv("UTF-8", $this->sJoomlaCharset, $sData); } $this->writeDebugLog("[debug] received data: ". $sData); $aCommand = explode(":", $sData); if (is_array($aCommand)){ switch ($aCommand[0]){ case "isuser": // provjeravamo je li korisnik dobar if (!isset($aCommand[1])){ $this->writeLog("[exAuth] invalid isuser command, no username given"); fwrite(STDOUT, pack("nn", 2, 0)); } else { // ovdje provjeri je li korisnik OK $this->dbverify(); $sUser = str_replace(array("%20", "(a)"), array(" ", "@"), $aCommand[1]); $this->writeDebugLog("[debug] checking isuser for ". $sUser); $sQuery = "select * from ". $this->sJoomlaPrefix ."users where username='". $this->oMySQL->escape_string($sUser) ."'"; $this->writeDebugLog("[debug] using query ". $sQuery); if ($oResult = $this->oMySQL->query($sQuery)){ if ($oResult->num_rows) { // korisnik OK $this->writeLog("[exAuth] valid user: ". $sUser); fwrite(STDOUT, pack("nn", 2, 1)); } else { // korisnik nije OK $this->writeLog("[exAuth] invalid user: ". $sUser); fwrite(STDOUT, pack("nn", 2, 0)); } $oResult->close(); } else { $this->writeLog("[MySQL] invalid query: ". $sQuery); fwrite(STDOUT, pack("nn", 2, 0)); } } break; case "auth": // provjeravamo autentifikaciju korisnika if (sizeof($aCommand) != 4){ $this->writeLog("[exAuth] invalid auth command, data missing"); fwrite(STDOUT, pack("nn", 2, 0)); } else { // ovdje provjeri prijavu $this->dbverify(); $sUser = str_replace(array("%20", "(a)"), array(" ", "@"), $aCommand[1]); $this->writeDebugLog("[debug] doing auth for ". $sUser); $sQuery = "select * from ". $this->sJoomlaPrefix ."users where password=md5('". $this->oMySQL->escape_string($aCommand[3]) ."') and username='". $this->oMySQL->escape_string($sUser) ."'"; $this->writeDebugLog("[debug] using query ". $sQuery); if ($oResult = $this->oMySQL->query($sQuery)){ if ($oResult->num_rows) { // korisnik OK $this->writeLog("[exAuth] authentificated user ". $sUser ."@". $aCommand[2]); fwrite(STDOUT, pack("nn", 2, 1)); } else { // korisnik nije OK $this->writeLog("[exAuth] authentification failed for user ". $sUser ."@". $aCommand[2]); fwrite(STDOUT, pack("nn", 2, 0)); } $oResult->close(); } else { $this->writeLog("[MySQL] invalid query: ". $sQuery); fwrite(STDOUT, pack("nn", 2, 0)); } } break; case "setpass": // postavljanje zaporke, onemoguceno $this->writeLog("[exAuth] setpass command disabled"); fwrite(STDOUT, pack("nn", 2, 0)); break; default: // ako je uhvaceno ista drugo $this->writeLog("[exAuth] unknown command ". $aCommand[0]); fwrite(STDOUT, pack("nn", 2, 0)); break; } } else { $this->writeDebugLog("[debug] invalid command string"); fwrite(STDOUT, pack("nn", 2, 0)); } } unset ($iHeader); unset ($aLength); unset ($iLength); unset($aCommand); } while (true); } public function __destruct() { // zatvori log file $this->writeLog("[exAuth] stop"); if (is_resource($this->rLogFile)){ fclose($this->rLogFile); } // zatvori MySQLi vezu if (is_object($this->oMySQL)){ $this->oMySQL->close(); } } private function writeLog($sMessage) { if (is_resource($this->rLogFile)) { fwrite($this->rLogFile, date("r") ." ". $sMessage ."\n"); } } private function writeDebugLog($sMessage) { if ($this->bDebug){ $this->writeLog($sMessage); } } private function dbconnect(){ if (!is_object($this->oMySQL)){ $this->oMySQL = new mysqli($this->sDBHost, $this->sDBUser, $this->sDBPassword, $this->sDBName); if (mysqli_connect_errno()) { $this->writeLog(sprintf("[MySQL] connection failed: %s\n", mysqli_connect_error())); $this->writeLog("[exAuth] killing"); exit(); } else { $this->writeLog("[MySQL] connected"); } } } private function dbverify(){ if (!is_object($this->oMySQL)){ $this->dbconnect(); } else { if (!$this->oMySQL->ping()){ unset($this->oMySQL); // ubijamo nekoristan objekt $this->writeLog("[MySQL] connection died, reconnecting"); $this->dbconnect(); } } } } ?>