From: Andrew Dolgov Date: Thu, 27 Dec 2012 11:14:44 +0000 (+0400) Subject: move authentication modules to plugins/ X-Git-Tag: 1.7.0~101 X-Git-Url: https://git.wh0rd.org/?a=commitdiff_plain;h=0f28f81f8911e432ae4bf50da7ed2c334618fd95;p=tt-rss.git move authentication modules to plugins/ --- diff --git a/classes/auth/imap.php b/classes/auth/imap.php deleted file mode 100644 index 52664eb3..00000000 --- a/classes/auth/imap.php +++ /dev/null @@ -1,32 +0,0 @@ -auto_create_user($login); - } - } - - return false; - } - -} -?> diff --git a/classes/auth/internal.php b/classes/auth/internal.php deleted file mode 100644 index 37014ce4..00000000 --- a/classes/auth/internal.php +++ /dev/null @@ -1,174 +0,0 @@ -link) > 96) { - if (!defined('AUTH_DISABLE_OTP') || !AUTH_DISABLE_OTP) { - $result = db_query($this->link, "SELECT otp_enabled,salt FROM ttrss_users WHERE - login = '$login'"); - - if (db_num_rows($result) > 0) { - require_once "lib/otphp/vendor/base32.php"; - require_once "lib/otphp/lib/otp.php"; - require_once "lib/otphp/lib/totp.php"; - - $base32 = new Base32(); - - $otp_enabled = sql_bool_to_bool(db_fetch_result($result, 0, "otp_enabled")); - $secret = $base32->encode(sha1(db_fetch_result($result, 0, "salt"))); - - $topt = new \OTPHP\TOTP($secret); - $otp_check = $topt->now(); - - if ($otp_enabled) { - if ($otp) { - if ($otp != $otp_check) { - return false; - } - } else { - $return = urlencode($_REQUEST["return"]); - ?> - Tiny Tiny RSS - -
- - - - - - - -
- - link) > 87) { - - $result = db_query($this->link, "SELECT salt FROM ttrss_users WHERE - login = '$login'"); - - if (db_num_rows($result) != 1) { - return false; - } - - $salt = db_fetch_result($result, 0, "salt"); - - if ($salt == "") { - - $query = "SELECT id - FROM ttrss_users WHERE - login = '$login' AND (pwd_hash = '$pwd_hash1' OR - pwd_hash = '$pwd_hash2')"; - - // verify and upgrade password to new salt base - - $result = db_query($this->link, $query); - - if (db_num_rows($result) == 1) { - // upgrade password to MODE2 - - $salt = substr(bin2hex(get_random_bytes(125)), 0, 250); - $pwd_hash = encrypt_password($password, $salt, true); - - db_query($this->link, "UPDATE ttrss_users SET - pwd_hash = '$pwd_hash', salt = '$salt' WHERE login = '$login'"); - - $query = "SELECT id - FROM ttrss_users WHERE - login = '$login' AND pwd_hash = '$pwd_hash'"; - - } else { - return false; - } - - } else { - - $pwd_hash = encrypt_password($password, $salt, true); - - $query = "SELECT id - FROM ttrss_users WHERE - login = '$login' AND pwd_hash = '$pwd_hash'"; - - } - - } else { - $query = "SELECT id - FROM ttrss_users WHERE - login = '$login' AND (pwd_hash = '$pwd_hash1' OR - pwd_hash = '$pwd_hash2')"; - } - - $result = db_query($this->link, $query); - - if (db_num_rows($result) == 1) { - return db_fetch_result($result, 0, "id"); - } - - return false; - } - - function check_password($owner_uid, $password) { - $owner_uid = db_escape_string($owner_uid); - - $result = db_query($this->link, "SELECT salt,login FROM ttrss_users WHERE - id = '$owner_uid'"); - - $salt = db_fetch_result($result, 0, "salt"); - $login = db_fetch_result($result, 0, "login"); - - if (!$salt) { - $password_hash1 = encrypt_password($password); - $password_hash2 = encrypt_password($password, $login); - - $query = "SELECT id FROM ttrss_users WHERE - id = '$owner_uid' AND (pwd_hash = '$password_hash1' OR - pwd_hash = '$password_hash2')"; - - } else { - $password_hash = encrypt_password($password, $salt, true); - - $query = "SELECT id FROM ttrss_users WHERE - id = '$owner_uid' AND pwd_hash = '$password_hash'"; - } - - $result = db_query($this->link, $query); - - return db_num_rows($result) != 0; - } - - function change_password($owner_uid, $old_password, $new_password) { - $owner_uid = db_escape_string($owner_uid); - - if ($this->check_password($owner_uid, $old_password)) { - - $new_salt = substr(bin2hex(get_random_bytes(125)), 0, 250); - $new_password_hash = encrypt_password($new_password, $new_salt, true); - - db_query($this->link, "UPDATE ttrss_users SET - pwd_hash = '$new_password_hash', salt = '$new_salt', otp_enabled = false - WHERE id = '$owner_uid'"); - - $_SESSION["pwd_hash"] = $new_password_hash; - - return __("Password has been changed."); - } else { - return "ERROR: ".__('Old password is incorrect.'); - } - } -} -?> diff --git a/classes/auth/remote.php b/classes/auth/remote.php deleted file mode 100644 index 6892a352..00000000 --- a/classes/auth/remote.php +++ /dev/null @@ -1,61 +0,0 @@ -link, "SELECT login FROM ttrss_user_prefs, ttrss_users - WHERE pref_name = 'SSL_CERT_SERIAL' AND value = '$cert_serial' AND - owner_uid = ttrss_users.id"); - - if (db_num_rows($result) != 0) { - return db_escape_string(db_fetch_result($result, 0, "login")); - } - } - - return ""; - } - - - function authenticate($login, $password) { - $try_login = db_escape_string($_SERVER["REMOTE_USER"]); - - if (!$try_login) $try_login = $this->get_login_by_ssl_certificate(); -# if (!$try_login) $try_login = "test_qqq"; - - if ($try_login) { - $user_id = $this->auto_create_user($try_login); - - if ($user_id) { - $_SESSION["fake_login"] = $try_login; - $_SESSION["fake_password"] = "******"; - $_SESSION["hide_hello"] = true; - $_SESSION["hide_logout"] = true; - - // LemonLDAP can send user informations via HTTP HEADER - if (defined('AUTH_AUTO_CREATE') && AUTH_AUTO_CREATE){ - // update user name - $fullname = $_SERVER['HTTP_USER_NAME'] ? $_SERVER['HTTP_USER_NAME'] : $_SERVER['AUTHENTICATE_CN']; - if ($fullname){ - $fullname = db_escape_string($fullname); - db_query($this->link, "UPDATE ttrss_users SET full_name = '$fullname' WHERE id = " . - $user_id); - } - // update user mail - $email = $_SERVER['HTTP_USER_MAIL'] ? $_SERVER['HTTP_USER_MAIL'] : $_SERVER['AUTHENTICATE_MAIL']; - if ($email){ - $email = db_escape_string($email); - db_query($this->link, "UPDATE ttrss_users SET email = '$email' WHERE id = " . - $user_id); - } - } - - return $user_id; - } - } - - return false; - } -} - -?> diff --git a/classes/iauthmodule.php b/classes/iauthmodule.php new file mode 100644 index 00000000..d47dbacf --- /dev/null +++ b/classes/iauthmodule.php @@ -0,0 +1,5 @@ + diff --git a/classes/pluginhost.php b/classes/pluginhost.php index 545e62e0..d97dfa66 100644 --- a/classes/pluginhost.php +++ b/classes/pluginhost.php @@ -13,6 +13,7 @@ class PluginHost { const HOOK_PREFS_TABS = 5; const HOOK_FEED_PARSED = 6; const HOOK_UPDATE_TASK = 7; + const HOOK_AUTH_USER = 8; const KIND_ALL = 1; const KIND_SYSTEM = 2; diff --git a/classes/pref/prefs.php b/classes/pref/prefs.php index e8926194..0922e43a 100644 --- a/classes/pref/prefs.php +++ b/classes/pref/prefs.php @@ -28,8 +28,8 @@ class Pref_Prefs extends Handler_Protected { return; } - $module_class = "auth_" . $_SESSION["auth_module"]; - $authenticator = new $module_class($this->link); + global $pluginhost; + $authenticator = $pluginhost->get_plugin($_SESSION["auth_module"]); if (method_exists($authenticator, "change_password")) { print $authenticator->change_password($_SESSION["uid"], $old_pw, $new_pw); @@ -188,9 +188,11 @@ class Pref_Prefs extends Handler_Protected { print ""; - if ($_SESSION["auth_module"]) { - $module_class = "auth_" . $_SESSION["auth_module"]; - $authenticator = new $module_class($this->link); + if ($_SESSION["auth_module"]) { + global $pluginhost; + + $authenticator = $pluginhost->get_plugin($_SESSION["auth_module"]); + } else { $authenticator = false; } @@ -258,7 +260,7 @@ class Pref_Prefs extends Handler_Protected { print ""; - if ($_SESSION["auth_module"] == "internal") { + if ($_SESSION["auth_module"] == "auth_internal") { print "

" . __("One time passwords / Authenticator") . "

"; @@ -802,11 +804,11 @@ class Pref_Prefs extends Handler_Protected { function otpenable() { $password = db_escape_string($_REQUEST["password"]); - - $module_class = "auth_" . $_SESSION["auth_module"]; - $authenticator = new $module_class($this->link); $enable_otp = $_REQUEST["enable_otp"] == "on"; + global $pluginhost; + $authenticator = $pluginhost->get_plugin($_SESSION["auth_module"]); + if ($authenticator->check_password($_SESSION["uid"], $password)) { if ($enable_otp) { @@ -824,8 +826,8 @@ class Pref_Prefs extends Handler_Protected { function otpdisable() { $password = db_escape_string($_REQUEST["password"]); - $module_class = "auth_" . $_SESSION["auth_module"]; - $authenticator = new $module_class($this->link); + global $pluginhost; + $authenticator = $pluginhost->get_plugin($_SESSION["auth_module"]); if ($authenticator->check_password($_SESSION["uid"], $password)) { diff --git a/config.php-dist b/config.php-dist index cd7a29be..e0949c61 100644 --- a/config.php-dist +++ b/config.php-dist @@ -52,15 +52,7 @@ // *** Authentication *** // ********************** - define('AUTH_MODULES', 'internal'); - // Comma-separated list of authentication modules to use. - // Available modules are: - // internal - tt-rss internal user DB - // remote - use server REMOTE_USER variable or client SSL certificate if enabled - // imap - authenticates using an IMAP server (check classes/auth/imap.php for some - // stuff you need to put into config.php) - // in preferences - // + // Please see PLUGINS below to configure various authentication modules. define('AUTH_AUTO_CREATE', true); // Allow authentication modules to auto-create users in tt-rss internal @@ -173,12 +165,13 @@ // if you experience weird errors and tt-rss failing to start, blank pages // after login, or content encoding errors, disable it. - define('PLUGINS', 'note'); - // Comma-separated list of plugins to load automatically for all users. - // System plugins have to be specified here. + define('PLUGINS', 'auth_remote, auth_internal, note'); + // Comma-separated list of plugins to load automatically for all users. + // System plugins have to be specified here. Please enable at least one + // authentication plugin here (auth_*). // Users may enable other user plugins from Preferences/Plugins but may not // disable plugins specified in this list. - + define('FEEDBACK_URL', ''); // Displays an URL for users to provide feedback or comments regarding // this instance of tt-rss. Can lead to a forum, contact email, etc. diff --git a/include/functions.php b/include/functions.php index d03fcfb1..f6ef7c2b 100644 --- a/include/functions.php +++ b/include/functions.php @@ -547,7 +547,7 @@ if (!SINGLE_USER_MODE) { $user_id = false; - $modules = explode(",", AUTH_MODULES); + /* $modules = explode(",", AUTH_MODULES); foreach ($modules as $module) { $module_class = "auth_$module"; @@ -565,6 +565,17 @@ print T_sprintf("Fatal: authentication module %s not found.", $module); die; } + } */ + + global $pluginhost; + foreach ($pluginhost->get_hooks($pluginhost::HOOK_AUTH_USER) as $plugin) { + + $user_id = (int) $plugin->authenticate($login, $password); + + if ($user_id) { + $_SESSION["auth_module"] = strtolower(get_class($plugin)); + break; + } } if ($user_id && !$check_only) { diff --git a/include/sanity_config.php b/include/sanity_config.php index f5436b6b..04058560 100644 --- a/include/sanity_config.php +++ b/include/sanity_config.php @@ -1,3 +1,3 @@ - +$requred_defines = array( 'DB_TYPE', 'DB_HOST', 'DB_USER', 'DB_NAME', 'DB_PASS', 'MYSQL_CHARSET', 'SELF_URL_PATH', 'SINGLE_USER_MODE', 'PHP_EXECUTABLE', 'LOCK_DIRECTORY', 'CACHE_DIR', 'ICONS_DIR', 'ICONS_URL', 'AUTH_AUTO_CREATE', 'AUTH_AUTO_LOGIN', 'FORCE_ARTICLE_PURGE', 'PUBSUBHUBBUB_HUB', 'PUBSUBHUBBUB_ENABLED', 'SPHINX_ENABLED', 'SPHINX_INDEX', 'ENABLE_REGISTRATION', 'REG_NOTIFY_ADDRESS', 'REG_MAX_USERS', 'SESSION_COOKIE_LIFETIME', 'SESSION_EXPIRE_TIME', 'SESSION_CHECK_ADDRESS', 'SMTP_FROM_NAME', 'SMTP_FROM_ADDRESS', 'DIGEST_SUBJECT', 'SMTP_HOST', 'SMTP_LOGIN', 'SMTP_PASSWORD', 'CHECK_FOR_NEW_VERSION', 'ENABLE_GZIP_OUTPUT', 'PLUGINS', 'FEEDBACK_URL', 'CONFIG_VERSION'); ?> diff --git a/plugins/auth_imap/auth_imap.php b/plugins/auth_imap/auth_imap.php new file mode 100644 index 00000000..cca279cb --- /dev/null +++ b/plugins/auth_imap/auth_imap.php @@ -0,0 +1,51 @@ +link = $host->get_link(); + $this->host = $host; + $this->base = new Auth_Base($this->link); + + $host->add_hook($host::HOOK_AUTH_USER, $this); + } + + function authenticate($login, $password) { + + if ($login && $password) { + $imap = imap_open( + "{".IMAP_AUTH_SERVER.IMAP_AUTH_OPTIONS."}INBOX", + $login, + $password); + + if ($imap) { + imap_close($imap); + + return $this->base->auto_create_user($login); + } + } + + return false; + } + +} + +?> diff --git a/plugins/auth_internal/auth_internal.php b/plugins/auth_internal/auth_internal.php new file mode 100644 index 00000000..cf6c1378 --- /dev/null +++ b/plugins/auth_internal/auth_internal.php @@ -0,0 +1,191 @@ +link = $host->get_link(); + $this->host = $host; + + $host->add_hook($host::HOOK_AUTH_USER, $this); + } + + function authenticate($login, $password) { + + $pwd_hash1 = encrypt_password($password); + $pwd_hash2 = encrypt_password($password, $login); + $login = db_escape_string($login); + $otp = db_escape_string($_REQUEST["otp"]); + + if (get_schema_version($this->link) > 96) { + if (!defined('AUTH_DISABLE_OTP') || !AUTH_DISABLE_OTP) { + $result = db_query($this->link, "SELECT otp_enabled,salt FROM ttrss_users WHERE + login = '$login'"); + + if (db_num_rows($result) > 0) { + require_once "lib/otphp/vendor/base32.php"; + require_once "lib/otphp/lib/otp.php"; + require_once "lib/otphp/lib/totp.php"; + + $base32 = new Base32(); + + $otp_enabled = sql_bool_to_bool(db_fetch_result($result, 0, "otp_enabled")); + $secret = $base32->encode(sha1(db_fetch_result($result, 0, "salt"))); + + $topt = new \OTPHP\TOTP($secret); + $otp_check = $topt->now(); + + if ($otp_enabled) { + if ($otp) { + if ($otp != $otp_check) { + return false; + } + } else { + $return = urlencode($_REQUEST["return"]); + ?> + Tiny Tiny RSS + +
+ + + + + + + +
+ + link) > 87) { + + $result = db_query($this->link, "SELECT salt FROM ttrss_users WHERE + login = '$login'"); + + if (db_num_rows($result) != 1) { + return false; + } + + $salt = db_fetch_result($result, 0, "salt"); + + if ($salt == "") { + + $query = "SELECT id + FROM ttrss_users WHERE + login = '$login' AND (pwd_hash = '$pwd_hash1' OR + pwd_hash = '$pwd_hash2')"; + + // verify and upgrade password to new salt base + + $result = db_query($this->link, $query); + + if (db_num_rows($result) == 1) { + // upgrade password to MODE2 + + $salt = substr(bin2hex(get_random_bytes(125)), 0, 250); + $pwd_hash = encrypt_password($password, $salt, true); + + db_query($this->link, "UPDATE ttrss_users SET + pwd_hash = '$pwd_hash', salt = '$salt' WHERE login = '$login'"); + + $query = "SELECT id + FROM ttrss_users WHERE + login = '$login' AND pwd_hash = '$pwd_hash'"; + + } else { + return false; + } + + } else { + + $pwd_hash = encrypt_password($password, $salt, true); + + $query = "SELECT id + FROM ttrss_users WHERE + login = '$login' AND pwd_hash = '$pwd_hash'"; + + } + + } else { + $query = "SELECT id + FROM ttrss_users WHERE + login = '$login' AND (pwd_hash = '$pwd_hash1' OR + pwd_hash = '$pwd_hash2')"; + } + + $result = db_query($this->link, $query); + + if (db_num_rows($result) == 1) { + return db_fetch_result($result, 0, "id"); + } + + return false; + } + + function check_password($owner_uid, $password) { + $owner_uid = db_escape_string($owner_uid); + + $result = db_query($this->link, "SELECT salt,login FROM ttrss_users WHERE + id = '$owner_uid'"); + + $salt = db_fetch_result($result, 0, "salt"); + $login = db_fetch_result($result, 0, "login"); + + if (!$salt) { + $password_hash1 = encrypt_password($password); + $password_hash2 = encrypt_password($password, $login); + + $query = "SELECT id FROM ttrss_users WHERE + id = '$owner_uid' AND (pwd_hash = '$password_hash1' OR + pwd_hash = '$password_hash2')"; + + } else { + $password_hash = encrypt_password($password, $salt, true); + + $query = "SELECT id FROM ttrss_users WHERE + id = '$owner_uid' AND pwd_hash = '$password_hash'"; + } + + $result = db_query($this->link, $query); + + return db_num_rows($result) != 0; + } + + function change_password($owner_uid, $old_password, $new_password) { + $owner_uid = db_escape_string($owner_uid); + + if ($this->check_password($owner_uid, $old_password)) { + + $new_salt = substr(bin2hex(get_random_bytes(125)), 0, 250); + $new_password_hash = encrypt_password($new_password, $new_salt, true); + + db_query($this->link, "UPDATE ttrss_users SET + pwd_hash = '$new_password_hash', salt = '$new_salt', otp_enabled = false + WHERE id = '$owner_uid'"); + + $_SESSION["pwd_hash"] = $new_password_hash; + + return __("Password has been changed."); + } else { + return "ERROR: ".__('Old password is incorrect.'); + } + } +} +?> diff --git a/plugins/auth_remote/auth_remote.php b/plugins/auth_remote/auth_remote.php new file mode 100644 index 00000000..65f188b8 --- /dev/null +++ b/plugins/auth_remote/auth_remote.php @@ -0,0 +1,81 @@ +link = $host->get_link(); + $this->host = $host; + $this->base = new Auth_Base($this->link); + + $host->add_hook($host::HOOK_AUTH_USER, $this); + } + + function get_login_by_ssl_certificate() { + $cert_serial = db_escape_string(get_ssl_certificate_id()); + + if ($cert_serial) { + $result = db_query($this->link, "SELECT login FROM ttrss_user_prefs, ttrss_users + WHERE pref_name = 'SSL_CERT_SERIAL' AND value = '$cert_serial' AND + owner_uid = ttrss_users.id"); + + if (db_num_rows($result) != 0) { + return db_escape_string(db_fetch_result($result, 0, "login")); + } + } + + return ""; + } + + + function authenticate($login, $password) { + $try_login = db_escape_string($_SERVER["REMOTE_USER"]); + + if (!$try_login) $try_login = $this->get_login_by_ssl_certificate(); +# if (!$try_login) $try_login = "test_qqq"; + + if ($try_login) { + $user_id = $this->base->auto_create_user($try_login); + + if ($user_id) { + $_SESSION["fake_login"] = $try_login; + $_SESSION["fake_password"] = "******"; + $_SESSION["hide_hello"] = true; + $_SESSION["hide_logout"] = true; + + // LemonLDAP can send user informations via HTTP HEADER + if (defined('AUTH_AUTO_CREATE') && AUTH_AUTO_CREATE){ + // update user name + $fullname = $_SERVER['HTTP_USER_NAME'] ? $_SERVER['HTTP_USER_NAME'] : $_SERVER['AUTHENTICATE_CN']; + if ($fullname){ + $fullname = db_escape_string($fullname); + db_query($this->link, "UPDATE ttrss_users SET full_name = '$fullname' WHERE id = " . + $user_id); + } + // update user mail + $email = $_SERVER['HTTP_USER_MAIL'] ? $_SERVER['HTTP_USER_MAIL'] : $_SERVER['AUTHENTICATE_MAIL']; + if ($email){ + $email = db_escape_string($email); + db_query($this->link, "UPDATE ttrss_users SET email = '$email' WHERE id = " . + $user_id); + } + } + + return $user_id; + } + } + + return false; + } +} + +?>