diff options
-rw-r--r-- | README.md | 18 | ||||
-rw-r--r-- | config.sample.php | 68 | ||||
-rw-r--r-- | core/EjabberdAuth.php | 34 | ||||
-rwxr-xr-x | main.php | 29 | ||||
-rw-r--r-- | plugins/session/README.md | 12 | ||||
-rw-r--r-- | plugins/session/install.php | 19 | ||||
-rw-r--r-- | plugins/session/install.sql | 7 | ||||
-rw-r--r-- | plugins/session/main.php | 8 |
8 files changed, 90 insertions, 105 deletions
@@ -1,7 +1,8 @@ ejabberd-auth-php ================= -This is a collection of bridges allowing an ejabberd XMPP server to use a locally installed PHP-based CMS for external authentication. +This is a collection of bridges allowing an ejabberd XMPP server to use a locally +installed PHP-based CMS for external authentication. Features -------- @@ -16,6 +17,21 @@ Currently implemented bridges: Potential candidates for further bridges are WordPress, MediaWiki, Joomla! and Moodle. +Installation +------------ + +Copy the file `config.sample.php` to `config.php` and fill in the appropriate +values. + +If you want to add session authentication, also read [plugins/session/README.md]( +plugins/session/README.md). Otherwise, remove the relevant section of `config.php`. + +Open your ejabberd configuration (`/etc/ejabberd/ejabberd.cfg`) and set the +external authentication script: + + {auth_method, external}. + {extauth_program, ".../ejabberd-auth-php/main.php"}. + Extending --------- diff --git a/config.sample.php b/config.sample.php index 59e0613..9c1746a 100644 --- a/config.sample.php +++ b/config.sample.php @@ -1,54 +1,28 @@ <?php /** - * config.php + * Copy this file to config.php. * - * Configure the Bridge plugins used by this authentication system. - * - * Example 1: Use a Drupal 8 site for all hosts. - * - * $config['*'][0] = [ - * 'plugin' => 'drupal8', - * 'config' => [ - * 'root_path' => '/path/to/drupal8', - * 'site' => 'default', - * ], - * ]; - * - * Example 2: Add a phpBB and MediaWiki subdomain (exact match): - * - * $config['forum.example.com'][0] = [ - * 'plugin' => 'phpbb30', - * 'config => ['root_path' => '/path/to/phpbb'], - * ]; - * $config['wiki.example.com'][0] = [ - * 'plugin' => 'mediawiki', - * 'config' => ['root_path' => '/path/to/mediawiki'], - * ]; - * - * Example 3: Allow session authentication (see plugins/session/README.md) - * - * $config['*'][0] = [ - * 'plugin' => 'phpbb30', - * 'config => ['root_path' => '/path/to/phpbb'], - * ]; - * $config['*'][1] = [ - * 'plugin' => 'session', - * 'config' => [ - * 'mysql' => [ - * 'dsn' => 'mysql:host=localhost;dbname=DATABASE;charset=utf8', - * 'username' => 'USER', - * 'password' => 'PASSWORD', - * 'table' => 'TABLE', - * ], - * 'plugin' => 'phpbb30' - * ], - * ]; + * plugin_conf will always require the `root_path` to the CMS you want to + * authenticate with. Some systems require additional information; Drupal + * needs the site directory (usually `default`). */ -$config['*'][0] = [ - 'plugin' => '', - 'config' => [ - 'root_path' => '', - ], +$config = [ + 'log_path' => 'logs/', + 'plugin' => 'PLUGIN', + 'plugin_conf' => [ + 'root_path' => '</path/to/site>', + ], + + // Remove this section if you are not using session authentication. + 'session' => [ + 'mysql' [ + 'dsn' => 'mysql:host=localhost;dbname=DATABASE;charset=utf8', + 'username' => 'USER', + 'password' => 'PASSWORD', + 'table' => 'TABLE', + ], + 'timeout' => 60, + ], ]; diff --git a/core/EjabberdAuth.php b/core/EjabberdAuth.php index c3cdff8..d88c990 100644 --- a/core/EjabberdAuth.php +++ b/core/EjabberdAuth.php @@ -7,13 +7,13 @@ class EjabberdAuth { var $running; - function __construct($meta, $bridges) { - $this->bridges = $bridges; - foreach ($bridges as $domain) foreach ($domain as $bridge) { - $bridge->parent = $this; - } - if (!empty($meta['log_path']) && is_dir($meta['log_path']) && is_writable($meta['log_path'])) - $this->logfile = fopen($meta['log_path'] . 'activity-' . date('Y-m-d') . '.log', 'a'); + function __construct($config, $bridge, $session) { + $this->bridge = $bridge; + $this->session = $session; + $this->bridge->parent = $this; + $this->session->parent = $this; + if (!empty($config['log_path']) && is_dir($config['log_path']) && is_writable($config['log_path'])) + $this->logfile = fopen($config['log_path'] . 'activity-' . date('Y-m-d') . '.log', 'a'); else $this->logfile = STDERR; $this->log('Initialized.'); } @@ -67,13 +67,13 @@ class EjabberdAuth { // Don't log the password, obviously. $this->log("Executing $command on {$username}@{$server}"); - $domain = array_key_exists($server, $this->bridges) ? $server : '*'; - switch ($command) { case 'isuser': - return $this->isuser($domain, $username, $server); + return $this->session->isuser($username, $server) || + $this->bridge->isuser($username, $server); case 'auth': - return $this->auth($domain, $username, $server, $password); + return $this->session->auth($username, $server, $password) || + $this->bridge->auth($username, $server, $password); case 'setpass': case 'tryregister': case 'removeuser': @@ -83,16 +83,4 @@ class EjabberdAuth { $this->stop(); } } - - function isuser($domain, $username, $server) { - foreach ($this->bridges[$domain] as $bridge) - if ($bridge->isuser($username, $server)) return TRUE; - return FALSE; - } - - function auth($domain, $username, $server, $password) { - foreach ($this->bridges[$domain] as $bridge) - if ($bridge->auth($username, $server, $password)) return TRUE; - return FALSE; - } } @@ -9,20 +9,19 @@ main(); function main() { require_once ROOT . 'config.php'; - $bridges = []; - foreach ($config as $domain => $plugins) { - $bridges[$domain] = []; - foreach ($plugins as $settings) { - $plugin_file = 'plugins/' . $settings['plugin'] . '/' . $settings['plugin'] . '.module'; - if (file_exists(ROOT . $plugin_file)) { - require_once ROOT . $plugin_file; - $function = $settings['plugin'] . '_init'; - $bridges[$domain][] = $function($settings['config']); - } - else { - return fwrite(STDERR, "Plugin <{$plugin_file}> not found.\n"); - } - } + $plugin_file = 'plugins/' . $config['plugin'] . '/' . $config['plugin'] . '.module'; + if (file_exists(ROOT . $plugin_file)) { + require_once ROOT . $plugin_file; + $function = $config['plugin'] . '_init'; + $bridge = $function($config['plugin_conf']); } - (new EjabberdAuth($meta, $bridges))->run(); + else { + return fwrite(STDERR, "Plugin <{$plugin_file}> not found.\n"); + } + if (!empty($config['session'])) { + require_once 'plugins/session/session.module'; + $session = session_init($config['session']); + } + else $session = NULL; + (new EjabberdAuth($config, $bridge, $session))->run(); } diff --git a/plugins/session/README.md b/plugins/session/README.md index 3412f7d..6fccc82 100644 --- a/plugins/session/README.md +++ b/plugins/session/README.md @@ -26,16 +26,12 @@ The control flow is like this: Installation ------------ -This plugin uses a database table, described in the packaged install.sql file. -Install it with this command: +First, configure the database connection in `config.php` by filling in the host, +database, user, password and table name. - cat ./install.sql | replace '{TAB}' '<tablename>' | \ - mysql -h <host> -D <db> -u <user> -p<password> +Then, install the table by running `php plugins/session/install.php`. -Next, you need to configure the database connection both in the main configuration -file and in the local `./config.php` of this plugin. - -Finally, link the `www/rpc.php` file inside your website root somewhere inside +Finally, link the `www/rpc.php` file in your website root somewhere within your forum's cookie domain and path (most forums set the path to `/`, so the domain should be sufficient). diff --git a/plugins/session/install.php b/plugins/session/install.php new file mode 100644 index 0000000..29771b3 --- /dev/null +++ b/plugins/session/install.php @@ -0,0 +1,19 @@ +<?php + +define('ROOT', __DIR__ . '/../../'); + +require_once ROOT . 'plugins/session/session.module'; +require_once ROOT . 'config.php'; + +$db = session_db($config['session']['mysql']); + +$db->exec(sprintf(<<<SQL +CREATE TABLE `%s` ( + username VARCHAR(255), + secret VARCHAR(40), + created INT, + PRIMARY KEY(username, secret), + INDEX(created) +); +SQL +, $config['session']['mysql']['tablename'])); diff --git a/plugins/session/install.sql b/plugins/session/install.sql deleted file mode 100644 index ecf59f9..0000000 --- a/plugins/session/install.sql +++ /dev/null @@ -1,7 +0,0 @@ -CREATE TABLE `{TAB}` ( - username VARCHAR(255), - secret VARCHAR(40), - created INT, - PRIMARY KEY(username, secret), - INDEX(created) -); diff --git a/plugins/session/main.php b/plugins/session/main.php index 18bacd8..49973a7 100644 --- a/plugins/session/main.php +++ b/plugins/session/main.php @@ -5,17 +5,17 @@ define('ROOT', __DIR__ . '/../../'); require_once ROOT . 'plugins/session/session.module'; function create_key($salt) { - require_once __DIR__ . '/config.php'; - $db = session_db($config['mysql']); + require_once ROOT . '/config.php'; + $db = session_db($config['session']['mysql']); $plugin = $config['plugin']; - $plugin_conf = $config['config']; + $plugin_conf = $config['plugin_conf']; require_once ROOT . 'plugins/' . $plugin . '/' . $plugin . '.module'; $function = $plugin . '_session'; $username = function_exists($function) ? $function($plugin_conf) : NULL; if ($username) { $entry = ['user' => $username, 'secret' => sha1($salt . time() . mt_rand()), 'time' => time()]; - $query = $db->prepare(sprintf('INSERT INTO `%s` (`username`, `secret`, `created`) VALUES (:user, :secret, :time);', $config['mysql']['tablename'])); + $query = $db->prepare(sprintf('INSERT INTO `%s` (`username`, `secret`, `created`) VALUES (:user, :secret, :time);', $config['session']['mysql']['tablename'])); $query->execute([':user' => $entry['user'], ':secret' => $entry['secret'], ':time' => $entry['time']]); return $entry; } |