diff --git a/README.md b/README.md index 75bfd0c..2d9729e 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,9 @@ Optional: * `USERNAME_FORMAT` (default: *{first_name}-{last_name}*): The template used to dynamically generate usernames. See [Username format](#username-format). * `USERNAME_REGEX` (default: *^[a-z][a-zA-Z0-9\._-]{3,32}$*): The regular expression used to ensure a username (and group name) is valid. See [Username format](#username-format). + +* `PASSWORD_HASH` (default: *SSHA*): Select which hashing method which will be used to store passwords in LDAP. Options are `MD5`, `SHA`, `SMD5`, `SSHA` or `CRYPT`. +* `ACCEPT_WEAK_PASSWORDS` (default: *FALSE*): Set this to *TRUE* to prevent a password being rejected for being too weak. The password strength indicators will still gauge the strength of the password. Don't enable this in a production environment. * `LOGIN_TIMEOUT_MINS` (default: 10 minutes): How long before an idle session will be timed out. diff --git a/www/account_manager/new_user.php b/www/account_manager/new_user.php index 36edd61..82a4b19 100644 --- a/www/account_manager/new_user.php +++ b/www/account_manager/new_user.php @@ -46,7 +46,7 @@ if (isset($_POST['create_account'])) { if ($_POST['email']) { $email = stripslashes($_POST['email']); } - if (!is_numeric($_POST['pass_score']) or $_POST['pass_score'] < 3) { $weak_password = TRUE; } + if ((!is_numeric($_POST['pass_score']) or $_POST['pass_score'] < 3) and $ACCEPT_WEAK_PASSWORDS != TRUE) { $weak_password = TRUE; } if (isset($email) and !is_valid_email($email)) { $invalid_email = TRUE; } if (preg_match("/\"|'/",$password)) { $invalid_password = TRUE; } if ($_POST['password'] != $_POST['password_match']) { $mismatched_passwords = TRUE; } diff --git a/www/account_manager/show_user.php b/www/account_manager/show_user.php index 7d55f25..1113a73 100644 --- a/www/account_manager/show_user.php +++ b/www/account_manager/show_user.php @@ -82,7 +82,7 @@ if ($ldap_search) { $password = $_POST['password']; - if (!is_numeric($_POST['pass_score']) or $_POST['pass_score'] < 3) { $weak_password = TRUE; } + if ((!is_numeric($_POST['pass_score']) or $_POST['pass_score'] < 3) and $ACCEPT_WEAK_PASSWORDS != TRUE) { $weak_password = TRUE; } if (preg_match("/\"|'/",$password)) { $invalid_password = TRUE; } if ($_POST['password'] != $_POST['password_match']) { $mismatched_passwords = TRUE; } if (!preg_match("/$USERNAME_REGEX/",$username)) { $invalid_username = TRUE; } diff --git a/www/change_password/index.php b/www/change_password/index.php index 475bb32..5d44493 100644 --- a/www/change_password/index.php +++ b/www/change_password/index.php @@ -9,7 +9,7 @@ set_page_access("user"); if (isset($_POST['change_password'])) { - if (!is_numeric($_POST['pass_score']) or $_POST['pass_score'] < 3) { $not_strong_enough = 1; } + if ((!is_numeric($_POST['pass_score']) or $_POST['pass_score'] < 3) and $ACCEPT_WEAK_PASSWORDS != TRUE) { $not_strong_enough = 1; } if (preg_match("/\"|'/",$_POST['password'])) { $invalid_chars = 1; } if ($_POST['password'] != $_POST['password_match']) { $mismatched = 1; } @@ -32,7 +32,7 @@ if (isset($_POST['change_password'])) { render_header('Change your LDAP password'); -if (isset($not_strong_enough)) { ?> +if (isset($not_strong_enough)) { ?>

The password wasn't strong enough.

diff --git a/www/includes/config.inc.php b/www/includes/config.inc.php index 858b889..0d22d13 100644 --- a/www/includes/config.inc.php +++ b/www/includes/config.inc.php @@ -32,7 +32,8 @@ $LDAP['require_starttls'] = ((strcasecmp(getenv('LDAP_REQUIRE_STARTTLS'),'TRUE') == 0) ? TRUE : FALSE); $DEFAULT_USER_GROUP = (getenv('DEFAULT_USER_GROUP') ? getenv('DEFAULT_USER_GROUP') : 'everybody'); - $DEFAULT_USER_SHELL = (getenv('DEFAULT_USER_SHELL') ? getenv('DEFAULT_SHELL') : '/bin/bash'); + $DEFAULT_USER_SHELL = (getenv('DEFAULT_USER_SHELL') ? getenv('DEFAULT_USER_SHELL') : '/bin/bash'); + $EMAIL_DOMAIN = (getenv('EMAIL_DOMAIN') ? getenv('EMAIL_DOMAIN') : Null); $LOGIN_TIMEOUT_MINS = (getenv('SESSION_TIMEOUT') ? getenv('SESSION_TIMEOUT') : 10); @@ -42,6 +43,11 @@ $USERNAME_REGEX = '^[a-z][a-zA-Z0-9\._-]{3,32}$'; #We'll use the username regex for groups too. + $PASSWORD_HASH = (getenv('PASSWORD_HASH') ? getenv('PASSWORD_HASH') : 'SSHA'); + if ( ! in_array($PASSWORD_HASH, array('MD5','SMD5','SHA','SSHA','CRYPT'))) { $PASSWORD_HASH = 'SSHA'; } + + $ACCEPT_WEAK_PASSWORDS = ((strcasecmp(getenv('ACCEPT_WEAK_PASSWORDS'),'TRUE') == 0) ? TRUE : FALSE); + $LDAP_DEBUG = ((strcasecmp(getenv('LDAP_DEBUG'),'TRUE') == 0) ? TRUE : FALSE); $SESSION_DEBUG = ((strcasecmp(getenv('SESSION_DEBUG'),'TRUE') == 0) ? TRUE : FALSE); diff --git a/www/includes/ldap_functions.inc.php b/www/includes/ldap_functions.inc.php index 3ec35e5..2dd112d 100644 --- a/www/includes/ldap_functions.inc.php +++ b/www/includes/ldap_functions.inc.php @@ -145,7 +145,35 @@ function ldap_setup_auth($ldap_connection, $password) { function ldap_hashed_password($password) { - $hashed_pwd = '{MD5}' . base64_encode(md5($password,TRUE)); + global $PASSWORD_HASH; + + $permitted_chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; + $salt = substr(str_shuffle($permitted_chars), 0, 64); + + switch (strtoupper($PASSWORD_HASH)) { + + case 'MD5': + $hashed_pwd = '{MD5}' . base64_encode(md5($password,TRUE)); + break; + + case 'SMD5': + $hashed_pwd = '{SMD5}' . base64_encode(md5($password.$salt,TRUE) . $salt); + break; + + case 'SHA': + $hashed_pwd = '{SHA}' . base64_encode(sha1($password,TRUE)); + break; + + case 'SSHA': + $hashed_pwd = '{SSHA}' . base64_encode(sha1($password.$salt,TRUE) . $salt); + break; + + case 'CRYPT': + $hashed_pwd = '{crypt}' . crypt($password, $salt); + break; + + } + return $hashed_pwd; } @@ -166,7 +194,7 @@ function ldap_get_user_list($ldap_connection,$start=0,$entries=NULL,$sort="asc", $ldap_search = @ ldap_search($ldap_connection, "${LDAP['user_dn']}", $this_filter, $fields); $result = @ ldap_get_entries($ldap_connection, $ldap_search); - if ($LDAP_DEBUG == TRUE) { error_log("LDAP returned ${result['count']} users for ${LDAP['user_dn']} when using this filter: $this_filter",0); } + if ($LDAP_DEBUG == TRUE) { error_log("$log_prefix: LDAP returned ${result['count']} users for ${LDAP['user_dn']} when using this filter: $this_filter",0); } $records = array(); foreach ($result as $record) { @@ -251,7 +279,7 @@ function ldap_get_group_list($ldap_connection,$start=0,$entries=NULL,$sort="asc" $ldap_search = ldap_search($ldap_connection, "${LDAP['group_dn']}", $this_filter); $result = @ ldap_get_entries($ldap_connection, $ldap_search); - if ($LDAP_DEBUG == TRUE) { error_log("LDAP returned ${result['count']} groups for ${LDAP['group_dn']} when using this filter: $this_filter",0); } + if ($LDAP_DEBUG == TRUE) { error_log("$log_prefix: LDAP returned ${result['count']} groups for ${LDAP['group_dn']} when using this filter: $this_filter",0); } $records = array(); foreach ($result as $record) { @@ -292,13 +320,13 @@ function ldap_get_group_members($ldap_connection,$group_name,$start=0,$entries=N if ($key !== 'count' and !empty($value)) { $this_member = preg_replace("/^.*?=(.*?),.*/", "$1", $value); array_push($records, $this_member); - if ($LDAP_DEBUG == TRUE) { error_log("${value} is a member",0); } + if ($LDAP_DEBUG == TRUE) { error_log("$log_prefix: ${value} is a member",0); } } } $actual_result_count = count($records); - if ($LDAP_DEBUG == TRUE) { error_log("LDAP returned $actual_result_count members of ${group_name} when using this search: $ldap_search_query and this filter: ${LDAP['group_membership_attribute']}",0); } + if ($LDAP_DEBUG == TRUE) { error_log("$log_prefix: LDAP returned $actual_result_count members of ${group_name} when using this search: $ldap_search_query and this filter: ${LDAP['group_membership_attribute']}",0); } if ($actual_result_count > 0) { if ($sort == "asc") { sort($records); } else { rsort($records); } diff --git a/www/includes/web_functions.inc.php b/www/includes/web_functions.inc.php index e811e8f..181ab86 100644 --- a/www/includes/web_functions.inc.php +++ b/www/includes/web_functions.inc.php @@ -52,8 +52,7 @@ function set_passkey_cookie($user_id,$is_admin) { $IS_ADMIN = TRUE; } $filename = preg_replace('/[^a-zA-Z0-9]/','_', $user_id); - file_put_contents("/tmp/$filename","$passkey:$admin_val:$this_time"); -# setcookie('orf_cookie', "$user_id:$passkey", $this_time+(60 * $LOGIN_TIMEOUT_MINS), '/', $_SERVER["HTTP_HOST"]); + @ file_put_contents("/tmp/$filename","$passkey:$admin_val:$this_time"); setcookie('orf_cookie', "$user_id:$passkey", $this_time+(60 * $LOGIN_TIMEOUT_MINS), '/', '', '', TRUE); if ( $SESSION_DEBUG == TRUE) { error_log("$log_prefix Session: user $user_id validated (IS_ADMIN=${IS_ADMIN}), sent orf_cookie to the browser.",0); } $VALIDATED = TRUE; @@ -171,11 +170,10 @@ function log_out($method='normal') { global $USER_ID; -#setcookie('orf_cookie', "", time()-20000 , "/", $_SERVER["HTTP_HOST"], 0); setcookie('orf_cookie', "", time()-20000, '/', '', '', TRUE); $filename = preg_replace('/[^a-zA-Z0-9]/','_', $USER_ID); - unlink("/tmp/$filename"); + @ unlink("/tmp/$filename"); if ($method == 'auto') { $options = "?logged_out"; } else { $options = ""; } header("Location: //${_SERVER["HTTP_HOST"]}/index.php$options\n\n");