From ead4cf2a0e9d41b5874dfcb6c753b18ed675cc0c Mon Sep 17 00:00:00 2001 From: Paul Arthur Date: Mon, 28 Jan 2013 17:39:04 -0500 Subject: Rename vauth to Auth --- config/ampache.cfg.php.dist | 7 +- lib/class/auth.class.php | 328 ++++++++++++++++++++++++++++++++++++ lib/class/vauth.class.php | 330 ------------------------------------- lib/init.php | 8 +- login.php | 2 +- logout.php | 2 +- templates/show_test_config.inc.php | 2 +- 7 files changed, 338 insertions(+), 341 deletions(-) create mode 100644 lib/class/auth.class.php delete mode 100644 lib/class/vauth.class.php diff --git a/config/ampache.cfg.php.dist b/config/ampache.cfg.php.dist index 4e677594..d46b9514 100644 --- a/config/ampache.cfg.php.dist +++ b/config/ampache.cfg.php.dist @@ -78,11 +78,10 @@ session_cookielife = 0 session_cookiesecure = 0 ; Auth Methods -; This defines which auth methods vauth will attempt -; to use and in which order, if auto_create isn't enabled -; The user must exist locally. Local method uses PHP's PAM Auth module +; This defines which auth methods Auth will attempt to use and in which order. +; If auto_create isn't enabled the user must exist locally. ; DEFAULT: mysql -; VALUES: mysql,ldap,http,local +; VALUES: mysql,ldap,http,pam auth_methods = "mysql" ; Automatic local password updating diff --git a/lib/class/auth.class.php b/lib/class/auth.class.php new file mode 100644 index 00000000..8d231f0a --- /dev/null +++ b/lib/class/auth.class.php @@ -0,0 +1,328 @@ +reloadRedirect("' . $target . '")'; + echo xml_from_array($results); + } + else { + /* Redirect them to the login page */ + header('Location: ' . $target); + } + + exit; + + } // logout + + /** + * login + * + * This takes a username and password and then returns the results + * based on what happens when we try to do the auth. + */ + public static function login($username, $password) { + + // Foreach the auth methods + foreach (Config::get('auth_methods') as $method) { + + // Build the function name and call it + $function_name = $method . '_auth'; + + if (!method_exists('Auth', $function_name)) { + continue; + } + + $results = self::$function_name($username, $password); + + // If we achieve victory return + if ($results['success']) { break; } + + } // end foreach + + return $results; + + } + + /** + * mysql_auth + * + * This is the core function of our built-in authentication. + */ + private static function mysql_auth($username, $password) { + + $username = Dba::escape($username); + + if (strlen($password) && strlen($username)) { + $sql = "SELECT `password` FROM `user` WHERE " . + "`username`='$username'"; + $db_results = Dba::read($sql); + if ($row = Dba::fetch_assoc($db_results)) { + + // Use SHA2 now... cooking with fire. + // For backwards compatibility, we hash a couple + // of different variations of the password. + // Increases collision chances, but doesn't + // break things. + $hashed_password[] = hash('sha256', $password); + $hashed_password[] = hash('sha256', + Dba::escape(scrub_in($password))); + + // Automagically update the password if it's + // old and busted. + if($row['password'] == $hashed_password[1] && + $hashed_password[0] != $hashed_password[1]) { + $user = User::get_from_username($username); + $user->update_password($password); + } + + if(in_array($row['password'], $hashed_password)) { + $results['success'] = true; + $results['type'] = 'mysql'; + $results['username'] = $username; + return $results; + } + } + } + + // Default to failure + $results['success'] = false; + $results['error'] = 'MySQL login attempt failed'; + return $results; + + } + + /** + * local_auth + * Check to make sure the pam_auth function is implemented (module is + * installed), then check the credentials. + */ + private static function local_auth($username, $password) { + if (!function_exists('pam_auth')) { + $results['success'] = false; + $results['error'] = 'The PAM PHP module is not installed'; + return $results; + } + + $password = scrub_in($password); + + if (pam_auth($username, $password)) { + $results['success'] = true; + $results['type'] = 'local'; + $results['username'] = $username; + } + else { + $results['success'] = false; + $results['error'] = 'PAM login attempt failed'; + } + + return $results; + } // local_auth + + /** + * ldap_auth + * Step one, connect to the LDAP server and perform a search for the + * username provided. + * Step two, attempt to bind using that username and the password + * provided. + * Step three, figure out if they are authorized to use ampache: + * TODO: in config but unimplemented: + * * require-dn "Grant access if the DN in the directive matches + * the DN fetched from the LDAP directory" + * * require-attribute "an attribute fetched from the LDAP + * directory matches the given value" + */ + private static function ldap_auth($username, $password) { + + $ldap_username = Config::get('ldap_username'); + $ldap_password = Config::get('ldap_password'); + + $require_group = Config::get('ldap_require_group'); + + // This is the DN for the users (required) + $ldap_dn = Config::get('ldap_search_dn'); + + // This is the server url (required) + $ldap_url = Config::get('ldap_url'); + + // This is the ldap filter string (required) + $ldap_filter = Config::get('ldap_filter'); + + //This is the ldap objectclass (required) + $ldap_class = Config::get('ldap_objectclass'); + + if (!($ldap_dn && $ldap_url && $ldap_filter && $ldap_class)) { + debug_event('ldap_auth', 'Required config value missing', 1); + $results['success'] = false; + $results['error'] = 'Incomplete LDAP config'; + return $results; + } + + $ldap_name_field = Config::get('ldap_name_field'); + $ldap_email_field = Config::get('ldap_email_field'); + + if ($ldap_link = ldap_connect($ldap_url) ) { + + /* Set to Protocol 3 */ + ldap_set_option($ldap_link, LDAP_OPT_PROTOCOL_VERSION, 3); + + // bind using our auth if we need to for initial search + if (!ldap_bind($ldap_link, $ldap_username, $ldap_password)) { + $results['success'] = false; + $results['error'] = 'Could not bind to LDAP server.'; + return $results; + } // If bind fails + + $sr = ldap_search($ldap_link, $ldap_dn, "(&(objectclass=$ldap_class)($ldap_filter=$username))"); + $info = ldap_get_entries($ldap_link, $sr); + + if ($info["count"] == 1) { + $user_entry = ldap_first_entry($ldap_link, $sr); + $user_dn = ldap_get_dn($ldap_link, $user_entry); + $password = scrub_in($password); + // bind using the user.. + $retval = ldap_bind($ldap_link, $user_dn, $password); + + if ($retval) { + // When the current user needs to be in + // a specific group to access Ampache, + // check whether the 'member' list of + // the group contains the DN + if ($require_group) { + $group_result = ldap_read($ldap_link, $require_group, 'objectclass=*', array('member')); + if (!$group_result) { + debug_event('ldap_auth', "Failure reading $require_group", 1); + $results['success'] = false; + $results['error'] = 'The LDAP group could not be read'; + return $results; + } + + $group_info = ldap_get_entries($ldap_link, $group_result); + + if ($group_info['count'] < 1) { + debug_event('ldap_auth', "No members found in $require_group", 1); + $results['success'] = false; + $results['error'] = 'Empty LDAP group'; + return $results; + } + + $group_match = preg_grep("/^$user_dn\$/i", $group_info[0]['member']); + if (!$group_match) { + debug_event('ldap_auth', "$user_dn is not a member of $require_group",1); + $results['success'] = false; + $results['error'] = 'LDAP login attempt failed'; + return $results; + } + } + ldap_close($ldap_link); + $results['success'] = true; + $results['type'] = "ldap"; + $results['username'] = $username; + $results['name'] = $info[0][$ldap_name_field][0]; + $results['email'] = $info[0][$ldap_email_field][0]; + + return $results; + + } // if we get something good back + + } // if something was sent back + + } // if failed connect + + /* Default to bad news */ + $results['success'] = false; + $results['error'] = 'LDAP login attempt failed'; + + return $results; + + } // ldap_auth + + /** + * http_auth + * This auth method relies on HTTP auth from the webserver + */ + private static function http_auth($username, $password) { + if (($_SERVER['REMOTE_USER'] == $username) || + ($_SERVER['HTTP_REMOTE_USER'] == $username)) { + $results['success'] = true; + $results['type'] = 'http'; + $results['username'] = $username; + $results['name'] = $username; + $results['email'] = ''; + } + else { + $results['success'] = false; + $results['error'] = 'HTTP auth login attempt failed'; + } + return $results; + } // http_auth + +} +?> diff --git a/lib/class/vauth.class.php b/lib/class/vauth.class.php deleted file mode 100644 index 3d435d4c..00000000 --- a/lib/class/vauth.class.php +++ /dev/null @@ -1,330 +0,0 @@ -reloadRedirect("' . $target . '")'; - echo xml_from_array($results); - } - else { - /* Redirect them to the login page */ - header('Location: ' . $target); - } - - exit; - - } // logout - - /** - * authenticate - * This takes a username and password and then returns the results - * based on what happens when we try to do the auth. - */ - public static function authenticate($username, $password) { - - // Foreach the auth methods - foreach (Config::get('auth_methods') as $method) { - - // Build the function name and call it - $function_name = $method . '_auth'; - - if (!method_exists('vauth', $function_name)) { - continue; - } - - $results = self::$function_name($username, $password); - - // If we achieve victory return - if ($results['success']) { break; } - - } // end foreach - - return $results; - - } // authenticate - - /** - * mysql_auth - * - * This is the core function of our built-in authentication. - */ - private static function mysql_auth($username, $password) { - - $username = Dba::escape($username); - - if (strlen($password) && strlen($username)) { - $sql = "SELECT `password` FROM `user` WHERE " . - "`username`='$username'"; - $db_results = Dba::read($sql); - if ($row = Dba::fetch_assoc($db_results)) { - - // Use SHA2 now... cooking with fire. - // For backwards compatibility, we hash a couple - // of different variations of the password. - // Increases collision chances, but doesn't - // break things. - $hashed_password[] = hash('sha256', $password); - $hashed_password[] = hash('sha256', - Dba::escape(scrub_in($password))); - - // Automagically update the password if it's - // old and busted. - if($row['password'] == $hashed_password[1] && - $hashed_password[0] != $hashed_password[1]) { - $user = User::get_from_username($username); - $user->update_password($password); - } - - if(in_array($row['password'], $hashed_password)) { - $results['success'] = true; - $results['type'] = 'mysql'; - $results['username'] = $username; - return $results; - } - } - } - - // Default to failure - $results['success'] = false; - $results['error'] = 'MySQL login attempt failed'; - return $results; - - } // mysql_auth - - /** - * local_auth - * Check to make sure the pam_auth function is implemented (module is - * installed), then check the credentials. - */ - private static function local_auth($username, $password) { - if (!function_exists('pam_auth')) { - $results['success'] = false; - $results['error'] = 'The PAM PHP module is not installed'; - return $results; - } - - $password = scrub_in($password); - - if (pam_auth($username, $password)) { - $results['success'] = true; - $results['type'] = 'local'; - $results['username'] = $username; - } - else { - $results['success'] = false; - $results['error'] = 'PAM login attempt failed'; - } - - return $results; - } // local_auth - - /** - * ldap_auth - * Step one, connect to the LDAP server and perform a search for the - * username provided. - * Step two, attempt to bind using that username and the password - * provided. - * Step three, figure out if they are authorized to use ampache: - * TODO: in config but unimplemented: - * * require-dn "Grant access if the DN in the directive matches - * the DN fetched from the LDAP directory" - * * require-attribute "an attribute fetched from the LDAP - * directory matches the given value" - */ - private static function ldap_auth($username, $password) { - - $ldap_username = Config::get('ldap_username'); - $ldap_password = Config::get('ldap_password'); - - $require_group = Config::get('ldap_require_group'); - - // This is the DN for the users (required) - $ldap_dn = Config::get('ldap_search_dn'); - - // This is the server url (required) - $ldap_url = Config::get('ldap_url'); - - // This is the ldap filter string (required) - $ldap_filter = Config::get('ldap_filter'); - - //This is the ldap objectclass (required) - $ldap_class = Config::get('ldap_objectclass'); - - if (!($ldap_dn && $ldap_url && $ldap_filter && $ldap_class)) { - debug_event('ldap_auth', 'Required config value missing', 1); - $results['success'] = false; - $results['error'] = 'Incomplete LDAP config'; - return $results; - } - - $ldap_name_field = Config::get('ldap_name_field'); - $ldap_email_field = Config::get('ldap_email_field'); - - if ($ldap_link = ldap_connect($ldap_url) ) { - - /* Set to Protocol 3 */ - ldap_set_option($ldap_link, LDAP_OPT_PROTOCOL_VERSION, 3); - - // bind using our auth if we need to for initial search - if (!ldap_bind($ldap_link, $ldap_username, $ldap_password)) { - $results['success'] = false; - $results['error'] = 'Could not bind to LDAP server.'; - return $results; - } // If bind fails - - $sr = ldap_search($ldap_link, $ldap_dn, "(&(objectclass=$ldap_class)($ldap_filter=$username))"); - $info = ldap_get_entries($ldap_link, $sr); - - if ($info["count"] == 1) { - $user_entry = ldap_first_entry($ldap_link, $sr); - $user_dn = ldap_get_dn($ldap_link, $user_entry); - $password = scrub_in($password); - // bind using the user.. - $retval = ldap_bind($ldap_link, $user_dn, $password); - - if ($retval) { - // When the current user needs to be in - // a specific group to access Ampache, - // check whether the 'member' list of - // the group contains the DN - if ($require_group) { - $group_result = ldap_read($ldap_link, $require_group, 'objectclass=*', array('member')); - if (!$group_result) { - debug_event('ldap_auth', "Failure reading $require_group", 1); - $results['success'] = false; - $results['error'] = 'The LDAP group could not be read'; - return $results; - } - - $group_info = ldap_get_entries($ldap_link, $group_result); - - if ($group_info['count'] < 1) { - debug_event('ldap_auth', "No members found in $require_group", 1); - $results['success'] = false; - $results['error'] = 'Empty LDAP group'; - return $results; - } - - $group_match = preg_grep("/^$user_dn\$/i", $group_info[0]['member']); - if (!$group_match) { - debug_event('ldap_auth', "$user_dn is not a member of $require_group",1); - $results['success'] = false; - $results['error'] = 'LDAP login attempt failed'; - return $results; - } - } - ldap_close($ldap_link); - $results['success'] = true; - $results['type'] = "ldap"; - $results['username'] = $username; - $results['name'] = $info[0][$ldap_name_field][0]; - $results['email'] = $info[0][$ldap_email_field][0]; - - return $results; - - } // if we get something good back - - } // if something was sent back - - } // if failed connect - - /* Default to bad news */ - $results['success'] = false; - $results['error'] = 'LDAP login attempt failed'; - - return $results; - - } // ldap_auth - - /** - * http_auth - * This auth method relies on HTTP auth from the webserver - */ - private static function http_auth($username, $password) { - if (($_SERVER['REMOTE_USER'] == $username) || - ($_SERVER['HTTP_REMOTE_USER'] == $username)) { - $results['success'] = true; - $results['type'] = 'http'; - $results['username'] = $username; - $results['name'] = $username; - $results['email'] = ''; - } - else { - $results['success'] = false; - $results['error'] = 'HTTP auth login attempt failed'; - } - return $results; - } // http_auth - -} // end of vauth class - -?> diff --git a/lib/init.php b/lib/init.php index 7a9b3dc1..9955c088 100644 --- a/lib/init.php +++ b/lib/init.php @@ -82,7 +82,7 @@ if (isset($results['user_ip_cardinality']) && !$results['user_ip_cardinality']) $results['user_ip_cardinality'] = 42; } -/* Variables needed for vauth class */ +/* Variables needed for Auth class */ $results['cookie_path'] = $results['raw_web_path']; $results['cookie_domain'] = $_SERVER['SERVER_NAME']; $results['cookie_life'] = $results['session_cookielife']; @@ -133,7 +133,7 @@ set_memory_limit($results['memory_limit']); if (!defined('NO_SESSION') && Config::get('use_auth')) { /* Verify their session */ if (!Session::exists('interface', $_COOKIE[Config::get('session_name')])) { - vauth::logout($_COOKIE[Config::get('session_name')]); + Auth::logout($_COOKIE[Config::get('session_name')]); exit; } @@ -145,7 +145,7 @@ if (!defined('NO_SESSION') && Config::get('use_auth')) { /* If the user ID doesn't exist deny them */ if (!$GLOBALS['user']->id && !Config::get('demo_mode')) { - vauth::logout(session_id()); + Auth::logout(session_id()); exit; } @@ -181,7 +181,7 @@ elseif (!Config::get('use_auth')) { $GLOBALS['user']->access = $auth['access']; } if (!$GLOBALS['user']->id AND !Config::get('demo_mode')) { - vauth::logout(session_id()); exit; + Auth::logout(session_id()); exit; } $GLOBALS['user']->update_last_seen(); } diff --git a/login.php b/login.php index 2a474342..c3d281ea 100644 --- a/login.php +++ b/login.php @@ -77,7 +77,7 @@ if (($_POST['username'] && $_POST['password']) || $password = ''; } - $auth = vauth::authenticate($username, $password); + $auth = Auth::login($username, $password); if ($auth['success']) { $username = $auth['username']; diff --git a/logout.php b/logout.php index 0599537c..0558eac9 100644 --- a/logout.php +++ b/logout.php @@ -27,5 +27,5 @@ require_once 'lib/init.php'; // To end a legitimate session, just call logout. -vauth::logout('',false); +Auth::logout('',false); ?> diff --git a/templates/show_test_config.inc.php b/templates/show_test_config.inc.php index 3664ff9d..b8714487 100644 --- a/templates/show_test_config.inc.php +++ b/templates/show_test_config.inc.php @@ -54,7 +54,7 @@ new config file.

values from the ampache.cfg.php.dist file will be used.

auth_methods (mysql)
-This defines which auth methods vauth will attempt to use and in which order, if auto_create isn't enabled. +This defines which auth methods Auth will attempt to use and in which order, if auto_create isn't enabled. The user must exist locally as well

tag_order (id3v2,id3v1,vorbiscomment,quicktime,ape,asf)
-- cgit