diff options
author | Christoph Burschka | 2014-01-17 16:10:10 +0100 |
---|---|---|
committer | Christoph Burschka | 2014-01-17 16:10:10 +0100 |
commit | 045012f9b7619d441d8c5b5800519cb7ac6891b6 (patch) | |
tree | 4db383cb85c40b1fdc1b4b8c4413950d9134cedf | |
parent | Apparently that didn't need to be encoded. (diff) | |
download | ejabberd-auth-php-045012f9b7619d441d8c5b5800519cb7ac6891b6.tar.gz |
Okay, the last patch was actually rubbish.
It turns out that you can't hope to bootstrap more
than one PHP-based software without messing stuff
up, particularly because they rely on global variables
without exception. If it is risky and unpredictable for
different systems, it is completely impossible with multiple
instances of the same.
Therefore, the ability to use multiple plugins (and the
accompanying config.php structure) has been removed. The
only plugin that can be used in conjunction with another
is session.
-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; } |