diff options
Diffstat (limited to 'plugins/htpasswd')
-rw-r--r-- | plugins/htpasswd/BridgeHtpasswd.php | 19 | ||||
-rw-r--r-- | plugins/htpasswd/README.md | 28 | ||||
-rw-r--r-- | plugins/htpasswd/htpasswd.inc | 75 | ||||
-rw-r--r-- | plugins/htpasswd/htpasswd.module | 18 |
4 files changed, 140 insertions, 0 deletions
diff --git a/plugins/htpasswd/BridgeHtpasswd.php b/plugins/htpasswd/BridgeHtpasswd.php new file mode 100644 index 0000000..51b6a94 --- /dev/null +++ b/plugins/htpasswd/BridgeHtpasswd.php @@ -0,0 +1,19 @@ +<?php + +/** + * Implements EjabberdAuthBridge. + */ +class BridgeHtpasswd extends EjabberdAuthBridge { + function __construct($data, $config) { + $this->data = $data; + $this->config = $config; + } + + function isuser($username, $server) { + return array_key_exists($username, $this->data); + } + + function auth($username, $server, $password) { + return $this->isuser($username, $server) && htpasswd_check($password, $this->data[$username], $this->config); + } +} diff --git a/plugins/htpasswd/README.md b/plugins/htpasswd/README.md new file mode 100644 index 0000000..0b78bd6 --- /dev/null +++ b/plugins/htpasswd/README.md @@ -0,0 +1,28 @@ +htpasswd +======== + +This plugin can parse an Apache authentication file +generated by htpasswd. + +The following hash types are supported: + +- APR-MD5 ("htpasswd [-m]", default method) +- SHA1 ("htpasswd -s") +- Blowfish ("htpasswd -B") +- DES ("htpasswd -d") +- Plaintext ("htpasswd -s") + +Note that DES and Plaintext are mutually exclusive, because +the format is not readily distinguishable. Any hash that does +not match the MD5, SHA1 or Blowfish formats will be treated as +a DES hash or a plaintext password depending on configuration. + +Installation +------------ + +This configuration must be entered into plugin_conf in config.php: + + 'plugin_conf' => [ + 'htpasswd_file' => '</path/to/htpasswd/file>', + 'plain' => FALSE, // optional + ] diff --git a/plugins/htpasswd/htpasswd.inc b/plugins/htpasswd/htpasswd.inc new file mode 100644 index 0000000..903940b --- /dev/null +++ b/plugins/htpasswd/htpasswd.inc @@ -0,0 +1,75 @@ +<?php + +function htpasswd_check($clear, $hash, $config) { + /* htpasswd supports the following hashing methods: + * - MD5 (standard) + * - blowfish + * - crypt (DES) + * - sha1 + * - plain + * + * All but the Apache-specific MD5 implementation + * are available in PHP. + */ + + if (preg_match('/^\$apr1\$(.*?)\$.*$/', $hash, $match)) { + $result = htpasswd_apr_md5($clear, $match[1]); + } + elseif (preg_match('/^\$2y\$.*$/', $hash, $match)) { + $result = crypt($clear, $match[0]); + } + elseif (preg_match('/^\{SHA\}.*$/', $hash, $match)) { + $result = '{SHA}' . base64_encode(sha1($clear, TRUE)); + } + + // The crypt and clear formats are not distinguishable. + elseif (empty($config['plain'])) { + $result = crypt($clear, $hash); + } + else { + $result = $clear; + } + + return hash_equals($result, $hash); +} + +/** + * Parts of this APR-MD5 implementation are derived from + * an example at http://php.net/crypt + */ +function htpasswd_apr_md5($clear, $salt) { + $len = strlen($clear); + $text = $clear . '$apr1$' . $salt; + $bin = pack('H32', md5($clear . $salt . $clear)); + for($i = $len; $i > 0; $i -= 16) { + $text .= substr($bin, 0, min(16, $i)); + } + for($i = $len; $i > 0; $i >>= 1) { + $text .= ($i & 1) ? chr(0) : $clear{0}; + } + $bin = pack("H32", md5($text)); + + for($i = 0; $i < 1000; $i++) { + $new = ($i & 1) ? $clear : $bin; + if ($i % 3) $new .= $salt; + if ($i % 7) $new .= $clear; + $new .= ($i & 1) ? $bin : $clear; + $bin = pack("H32", md5($new)); + } + + $tmp = ''; + for ($i = 0; $i < 5; $i++) { + $k = $i + 6; + $j = $i + 12; + if ($j == 16) { + $j = 5; + } + $tmp = $bin[$i] . $bin[$k] . $bin[$j] . $tmp; + } + + $tmp = chr(0) . chr(0) . $bin[11] . $tmp; + $tmp = strtr(strrev(substr(base64_encode($tmp), 2)), + 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', + './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'); + return '$apr1$' . $salt . '$' . $tmp; +} diff --git a/plugins/htpasswd/htpasswd.module b/plugins/htpasswd/htpasswd.module new file mode 100644 index 0000000..b97de52 --- /dev/null +++ b/plugins/htpasswd/htpasswd.module @@ -0,0 +1,18 @@ +<?php + +function htpasswd_init($config) { + $data = array(); + $file = $config['htpasswd_file']; + if (file_exists($file) && is_readable($file)) { + $lines = explode("\n", trim(file_get_contents($file))); + foreach ($lines as $line) { + list($user, $password) = explode(":", trim($line), 2); + $data[$user] = $password; + } + } + + // Load the plugin. + require_once __DIR__ . '/BridgeHtpasswd.php'; + require_once __DIR__ . '/htpasswd.inc'; + return new BridgeHtpasswd($data, $config); +} |