function auto_create_user($login) { if ($login && defined('AUTH_AUTO_CREATE') && AUTH_AUTO_CREATE) { $user_id = $this->find_user_by_login($login); if (!$user_id) { $login = db_escape_string($login); $salt = substr(bin2hex(get_random_bytes(125)), 0, 250); $pwd_hash = encrypt_password($password, $salt, true); $query = "INSERT INTO ttrss_users\n\t\t\t\t\t\t(login,access_level,last_login,created,pwd_hash,salt)\n\t\t\t\t\t\tVALUES ('{$login}', 0, null, NOW(), '{$pwd_hash}','{$salt}')"; db_query($this->link, $query); return $this->find_user_by_login($login); } else { return $user_id; } } return $this->find_user_by_login($login); }
function auto_create_user($login, $password = false) { if ($login && defined('AUTH_AUTO_CREATE') && AUTH_AUTO_CREATE) { $user_id = $this->find_user_by_login($login); if (!$password) { $password = make_password(); } if (!$user_id) { $login = $this->dbh->escape_string($login); $salt = substr(bin2hex(get_random_bytes(125)), 0, 250); $pwd_hash = hash_password($password); $query = "INSERT INTO ttrss_users\n (login,access_level,last_login,created,pwd_hash,salt)\n VALUES ('{$login}', 0, null, NOW(), '{$pwd_hash}','{$salt}')"; $this->dbh->query($query); return $this->find_user_by_login($login); } return $user_id; } return $this->find_user_by_login($login); }
function changepassword() { $old_pw = $_POST["old_password"]; $new_pw = $_POST["new_password"]; $con_pw = $_POST["confirm_password"]; if ($old_pw == "") { print "ERROR: " . __("Old password cannot be blank."); return; } if ($new_pw == "") { print "ERROR: " . __("New password cannot be blank."); return; } if ($new_pw != $con_pw) { print "ERROR: " . __("Entered passwords do not match."); return; } $result = db_query($this->link, "SELECT salt FROM ttrss_users WHERE\n\t\t\tid = " . $_SESSION['uid']); $salt = db_fetch_result($result, 0, "salt"); if (!$salt) { $old_pw_hash1 = encrypt_password($old_pw); $old_pw_hash2 = encrypt_password($old_pw, $_SESSION["name"]); $query = "SELECT id FROM ttrss_users WHERE\n\t\t\t\tid = " . $_SESSION['uid'] . " AND (pwd_hash = '{$old_pw_hash1}' OR\n\t\t\t\tpwd_hash = '{$old_pw_hash2}')"; } else { $old_pw_hash = encrypt_password($old_pw, $salt, true); $query = "SELECT id FROM ttrss_users WHERE\n\t\t\t\tid = " . $_SESSION['uid'] . " AND pwd_hash = '{$old_pw_hash}'"; } $result = db_query($this->link, $query); if (db_num_rows($result) == 1) { $new_salt = substr(bin2hex(get_random_bytes(125)), 0, 250); $new_pw_hash = encrypt_password($new_pw, $new_salt, true); db_query($this->link, "UPDATE ttrss_users SET\n\t\t\t\tpwd_hash = '{$new_pw_hash}', salt = '{$new_salt}'\n\t\t\t\t\tWHERE id = " . $_SESSION['uid']); $_SESSION["pwd_hash"] = $new_pw_hash; print __("Password has been changed."); } else { print "ERROR: " . __('Old password is incorrect.'); } }
/** * crypt the plaintext password. * * @golbal string $cryptscheme * @param string $clear the cleartext password * @param string $salt optional salt * @return string the properly crypted password */ function crypt_password($clear, $salt = '') { global $cryptscheme; if ($cryptscheme === 'sha') { $hash = sha1($clear); $cryptedpass = '******' . base64_encode(pack('H*', $hash)); } elseif ($cryptscheme === 'clear') { $cryptedpass = $clear; } else { if (empty($salt)) { switch ($cryptscheme) { case 'des': $salt = ''; break; case 'md5': $salt = '$1$'; break; case 'sha512': $salt = '$6$'; break; case 'bcrypt': $salt = '$2a$10$'; break; default: if (preg_match('/\\$[:digit:][:alnum:]?\\$/', $cryptscheme)) { $salt = $cryptscheme; } else { die(_('The value of $cryptscheme is invalid!')); } } $salt .= get_random_bytes(CRYPT_SALT_LENGTH) . '$'; } $cryptedpass = crypt($clear, $salt); } return $cryptedpass; }
static function resetUserPassword($uid, $show_password) { $result = db_query("SELECT login,email\n\t\t\t\tFROM ttrss_users WHERE id = '{$uid}'"); $login = db_fetch_result($result, 0, "login"); $email = db_fetch_result($result, 0, "email"); $salt = db_fetch_result($result, 0, "salt"); $new_salt = substr(bin2hex(get_random_bytes(125)), 0, 250); $tmp_user_pwd = make_password(8); $pwd_hash = encrypt_password($tmp_user_pwd, $new_salt, true); db_query("UPDATE ttrss_users SET pwd_hash = '{$pwd_hash}', salt = '{$new_salt}', otp_enabled = false\n\t\t\t\tWHERE id = '{$uid}'"); if ($show_password) { print T_sprintf("Changed password of user <b>%s</b> to <b>%s</b>", $login, $tmp_user_pwd); } else { print_notice(T_sprintf("Sending new password of user <b>%s</b> to <b>%s</b>", $login, $email)); } require_once 'classes/ttrssmailer.php'; if ($email) { require_once "lib/MiniTemplator.class.php"; $tpl = new MiniTemplator(); $tpl->readTemplateFromFile("templates/resetpass_template.txt"); $tpl->setVariable('LOGIN', $login); $tpl->setVariable('NEWPASS', $tmp_user_pwd); $tpl->addBlock('message'); $message = ""; $tpl->generateOutputToString($message); $mail = new ttrssMailer(); $rc = $mail->quickMail($email, $login, __("[tt-rss] Password change notification"), $message, false); if (!$rc) { print_error($mail->ErrorInfo); } } }
$email = trim(db_escape_string($_REQUEST["email"])); $test = trim(db_escape_string($_REQUEST["turing_test"])); if (!$login || !$email || !$test) { print_error(__("Your registration information is incomplete.")); print "<p><form method=\"GET\" action=\"index.php\">\n\t\t\t\t<input type=\"submit\" value=\"" . __("Return to Tiny Tiny RSS") . "\">\n\t\t\t\t</form>"; return; } if ($test == "four" || $test == "4") { $result = db_query("SELECT id FROM ttrss_users WHERE\n\t\t\t\tlogin = '******'"); $is_registered = db_num_rows($result) > 0; if ($is_registered) { print_error(__('Sorry, this username is already taken.')); print "<p><form method=\"GET\" action=\"index.php\">\n\t\t\t\t<input type=\"submit\" value=\"" . __("Return to Tiny Tiny RSS") . "\">\n\t\t\t\t</form>"; } else { $password = make_password(); $salt = substr(bin2hex(get_random_bytes(125)), 0, 250); $pwd_hash = encrypt_password($password, $salt, true); db_query("INSERT INTO ttrss_users\n\t\t\t\t\t(login,pwd_hash,access_level,last_login, email, created, salt)\n\t\t\t\t\tVALUES ('{$login}', '{$pwd_hash}', 0, null, '{$email}', NOW(), '{$salt}')"); $result = db_query("SELECT id FROM ttrss_users WHERE\n\t\t\t\t\tlogin = '******' AND pwd_hash = '{$pwd_hash}'"); if (db_num_rows($result) != 1) { print_error(__('Registration failed.')); print "<p><form method=\"GET\" action=\"index.php\">\n\t\t\t\t\t<input type=\"submit\" value=\"" . __("Return to Tiny Tiny RSS") . "\">\n\t\t\t\t\t</form>"; } else { $new_uid = db_fetch_result($result, 0, "id"); initialize_user($new_uid); $reg_text = "Hi!\n" . "\n" . "You are receiving this message, because you (or somebody else) have opened\n" . "an account at Tiny Tiny RSS.\n" . "\n" . "Your login information is as follows:\n" . "\n" . "Login: {$login}\n" . "Password: {$password}\n" . "\n" . "Don't forget to login at least once to your new account, otherwise\n" . "it will be deleted in 24 hours.\n" . "\n" . "If that wasn't you, just ignore this message. Thanks."; $mail = new ttrssMailer(); $mail->IsHTML(false); $rc = $mail->quickMail($email, "", "Registration information for Tiny Tiny RSS", $reg_text, false); if (!$rc) { print_error($mail->ErrorInfo);
/** * crypt the plaintext password. * * @golbal string $cryptscheme * @param string $clear the cleartext password * @param string $salt optional salt * @return string the properly crypted password */ function crypt_password($clear, $salt = '') { global $cryptscheme; switch ($cryptscheme) { case 'sha': $hash = sha1($clear); $cryptedpass = '******' . base64_encode(pack('H*', $hash)); break; case 'des': if (!empty($salt)) { $salt = substr($salt, 0, 2); } else { $salt = get_random_bytes(2); } $cryptedpass = crypt($clear, $salt); break; case 'md5': if (!empty($salt)) { $salt = substr($salt, 0, 12); } else { $salt = '$1$' . get_random_bytes(8) . '$'; } $cryptedpass = crypt($clear, $salt); break; case 'clear': $cryptedpass = $clear; break; default: $cryptedpass = crypt($clear, $salt); } return $cryptedpass; }
function authenticate($login, $password) { $pwd_hash0 = hash_password($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() > 96) { if (!defined('AUTH_DISABLE_OTP') || !AUTH_DISABLE_OTP) { $result = db_query("SELECT otp_enabled,salt FROM ttrss_users WHERE\n\t\t\t\t\tlogin = '******'"); 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"]); ?> <html> <head><title>Tiny Tiny RSS</title></head> <?php echo stylesheet_tag("css/utility.css"); ?> <body class="otp"><div class="content"> <form action="public.php?return=<?php echo $return; ?> " method="POST" class="otpform"> <input type="hidden" name="op" value="login"> <input type="hidden" name="login" value="<?php echo htmlspecialchars($login); ?> "> <input type="hidden" name="password" value="<?php echo htmlspecialchars($password); ?> "> <input type="hidden" name="bw_limit" value="<?php echo htmlspecialchars($_POST["bw_limit"]); ?> "> <input type="hidden" name="remember_me" value="<?php echo htmlspecialchars($_POST["remember_me"]); ?> "> <input type="hidden" name="profile" value="<?php echo htmlspecialchars($_POST["profile"]); ?> "> <label><?php echo __("Please enter your one time password:"******"off" size="6" name="otp" value=""/> <input type="submit" value="Continue"/> </form></div> <script type="text/javascript"> document.forms[0].otp.focus(); </script> <?php exit; } } } } } $result = db_query("SELECT id,pwd_hash FROM ttrss_users WHERE\n\t\t\tlogin = '******'"); if (db_num_rows($result) === 1) { if (version_compare(PHP_VERSION, '5.5.0', '<')) { require_once 'vendor/ircmaxell/password-compat/lib/password.php'; } $pwd_hash_dp = db_fetch_result($result, 0, "pwd_hash"); if (password_verify($password, $pwd_hash_dp)) { return db_fetch_result($result, 0, "id"); } } if (get_schema_version() > 87) { $result = db_query("SELECT salt FROM ttrss_users WHERE\n\t\t\t\tlogin = '******'"); if (db_num_rows($result) !== 1) { return false; } $salt = db_fetch_result($result, 0, "salt"); if ($salt == "") { $query = "SELECT id\n\t\t\t\t\tFROM ttrss_users WHERE\n\t\t\t\t\tlogin = '******' AND (pwd_hash = '{$pwd_hash1}' OR\n\t\t\t\t\tpwd_hash = '{$pwd_hash2}')"; // verify and upgrade password to new salt base $result = db_query($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("UPDATE ttrss_users SET\n\t\t\t\t\t\tpwd_hash = '{$pwd_hash}', salt = '{$salt}' WHERE login = '******'"); $query = "SELECT id\n\t\t\t\t\t\tFROM ttrss_users WHERE\n\t\t\t\t\t\tlogin = '******' AND pwd_hash = '{$pwd_hash}'"; } else { return false; } } else { $pwd_hash = encrypt_password($password, $salt, true); $query = "SELECT id\n\t\t\t\t\tFROM ttrss_users WHERE\n\t\t\t\t\tlogin = '******' AND pwd_hash = '{$pwd_hash}'"; } } else { $query = "SELECT id\n\t\t\t\tFROM ttrss_users WHERE\n\t\t\t\tlogin = '******' AND (pwd_hash = '{$pwd_hash1}' OR\n\t\t\t\t\tpwd_hash = '{$pwd_hash2}')"; } $result = db_query($query); if (db_num_rows($result) === 1) { // Authentication was successful, but the hash in the database // is not secure. We need to update it. db_query("UPDATE ttrss_users SET\n\t\t\t\tpwd_hash = '{$pwd_hash0}' WHERE login = '******'"); return db_fetch_result($result, 0, "id"); } return false; }
function srp_test() { $test_phase = 0; //$I = "alice"; //$P = "password123"; $I = "aliceasd"; $P = "passasd98173"; if ($test_phase == 0) { $_GET = array("protocol" => "SRP-6a", "type" => "request", "phase" => 0, "I" => $I, "P" => $P, "hash" => "SHA256", "N_size" => 1024, "enc_client_state" => ""); $json0 = json_encode(srp()); echo "Rep0=", $json0, "\n\n"; $json0 = json_decode($json0, true); } else { $_GET = array("protocol" => "SRP-6a", "type" => "request", "phase" => 1, "I" => $I, "hash" => "SHA256", "N_size" => 1024, "enc_server_state" => "", "enc_client_state" => ""); echo "Req1=", json_encode($_GET), "\n\n"; $json = json_encode(srp()); echo "Rep1=", $json, "\n\n"; $json = json_decode($json, true); if (strlen($json["N_base36"]) < 100) { crit("client: N to small"); } if (strlen($json["s_hex"]) < 32) { crit("client: s_hex to small"); } $Ng_ok = false; if ($json["g_base36"] == "2" && $json["N_base36"] == "16xa82om033wnlk70asiomztdukuffhyjzvfan3p2mx73a3d7m9hws9a6bzc2ln42n93rmtrxi2p22g3xgxrvyryv9petn2256pdt281msxh9e812rhddxq4oo1f35sp7leese5d02obbwmiui7r2ddwfyqu31ctl4959pckt6lbolnlblhf4znrola2vk3wfto3e8z") { $Ng_ok = true; } if ($Ng_ok != true) { crit("client: Ng not whitelisted"); } $N_gmp = gmp_init($json["N_base36"], 36); $N_bin = gmp_bytes($N_gmp); $g_gmp = gmp_init($json["g_base36"], 36); $g_bin = gmp_bytes($g_gmp); // check if N,g are secure: large, N is prime and g is primitive root, and discrate logarithm is hard // because chacking is hard to do in real-time, they should be whitelisted $k_hex = H($N_bin . pad($g_bin)); $k_gmp = gmp_init($k_hex, 16); $s_hex = $json["s_hex"]; $s_bin = hex2bin($s_hex); // client oblicza x = H(s~H(I~P)) $x_bin = H($s_bin . H($I . ":" . $P)); $x_hex = bin2hex($x_bin); $x_gmp = gmp_init($x_hex, 16); // secret $v_gmp = gmp_powm($g_gmp, $x_gmp, $N_gmp); // secret // timing attack // client generuje randomowe a $a_bin = get_random_bytes(128); // rfc 5054: at least 256 bit $a_hex = bin2hex($a_bin); $a_gmp = gmp_init($a_hex, 16); // secret // client oblicza A=g^a, i nam wysyla $A_gmp = gmp_powm($g_gmp, $a_gmp, $N_gmp); // public // timing attack $A_hex = gmp_strval($A_gmp, 16); // debug $A_bin = gmp_bytes($A_gmp); // ponieważ dostalismy B, możemy obliczyc juz S $B_gmp = gmp_init($json["B_base36"], 36); $B_hex = gmp_strval($B_gmp, 16); // debug $B_bin = gmp_bytes($B_gmp); // klient oblicza u = H(A~B) $u_bin = H(pad($A_bin) . pad($B_bin)); $u_hex = bin2hex($u_bin); $u_gmp = gmp_init($u_hex, 16); // klient oblicza S = (B - k*g^x)^(a+u*x) //$S_gmp = gmp_powm(gmp_sub($B_gmp, gmp_mul($k_gmp, gmp_powm($g_gmp, $v_gmp, $N_gmp))), gmp_add($a_gmp, gmp_mul($u_gmp, $x_gmp)), $N_gmp); $S_gmp = gmp_powm(gmp_mod(gmp_sub($B_gmp, gmp_mod(gmp_mul($k_gmp, $v_gmp), $N_gmp)), $N_gmp), gmp_add($a_gmp, gmp_mul($u_gmp, $x_gmp)), $N_gmp); // timing attack $S_bin = gmp_bytes($S_gmp); $S_hex = gmp_strval($S_gmp, 16); // secret // klient oblicza M1 = H(A~B~S) i wysyla do serwera $M1_bin = H($A_bin . $B_bin . $S_bin); $M1_hex = bin2hex($M1_bin); $_GET = array("protocol" => "SRP-6a", "type" => "request", "phase" => 2, "A_base36" => gmp_strval($A_gmp, 36), "M1_hex" => $M1_hex, "enc_server_state" => $json["enc_server_state"], "enc_client_state" => ""); echo "Req2=", json_encode($_GET), "\n\n"; $json2 = json_encode(srp()); echo "Rep2=", $json2, "\n\n"; $json2 = json_decode($json2, true); // klient oblicza M2 = H(A~M1~S) // klient potwierdza poprawnosc otrzymanego M2 // klient oblicza K = H(S) // klient oblicza M = H( (H(N) xor H(g))~H(I)~s~A~B~K ) $M2_bin = H($A_bin . $M1_bin . $S_bin); $M2_hex = bin2hex($M2_bin); if ($M2_hex != $json2["M2_hex"]) { crit("client: M2 are different, don't trust server!"); } $K_bin = H($S_bin); $K_hex = bin2hex($K_bin); // secret $M_bin = HM((H($N_bin) ^ H($g_bin)) . H($I) . $s_bin . $A_bin . $B_bin, $K_bin); $M_hex = bin2hex($M_bin); $_GET = array("protocol" => "SRP-6a", "type" => "request", "phase" => 3, "M_hex" => $M_hex, "enc_server_state" => $json2["enc_server_state"], "enc_client_state" => ""); echo "Req3=", json_encode($_GET), "\n\n"; $json3 = json_encode(srp()); echo "Rep3=", $json3, "\n\n"; $json3 = json_decode($json3, true); $Z_bin = HM($A_bin . $M_bin, $K_bin); $Z_hex = bin2hex($Z_bin); if ($Z_hex != $json3["Z_hex"]) { crit("Z_hex different"); } echo "Logged\n"; } }
function resetPass() { $uid = db_escape_string($_REQUEST["id"]); $result = db_query($this->link, "SELECT login,email\n\t\t\t\tFROM ttrss_users WHERE id = '{$uid}'"); $login = db_fetch_result($result, 0, "login"); $email = db_fetch_result($result, 0, "email"); $salt = db_fetch_result($result, 0, "salt"); $new_salt = substr(bin2hex(get_random_bytes(125)), 0, 250); $tmp_user_pwd = make_password(8); $pwd_hash = encrypt_password($tmp_user_pwd, $new_salt, true); db_query($this->link, "UPDATE ttrss_users SET pwd_hash = '{$pwd_hash}', salt = '{$new_salt}'\n\t\t\t\tWHERE id = '{$uid}'"); print T_sprintf("Changed password of user <b>%s</b>\n\t\t\t\t to <b>%s</b>", $login, $tmp_user_pwd); require_once 'lib/phpmailer/class.phpmailer.php'; if ($email) { print " "; print T_sprintf("Notifying <b>%s</b>.", $email); require_once "lib/MiniTemplator.class.php"; $tpl = new MiniTemplator(); $tpl->readTemplateFromFile("templates/resetpass_template.txt"); $tpl->setVariable('LOGIN', $login); $tpl->setVariable('NEWPASS', $tmp_user_pwd); $tpl->addBlock('message'); $message = ""; $tpl->generateOutputToString($message); $mail = new PHPMailer(); $mail->PluginDir = "lib/phpmailer/"; $mail->SetLanguage("en", "lib/phpmailer/language/"); $mail->CharSet = "UTF-8"; $mail->From = SMTP_FROM_ADDRESS; $mail->FromName = SMTP_FROM_NAME; $mail->AddAddress($email, $login); if (SMTP_HOST) { $mail->Host = SMTP_HOST; $mail->Mailer = "smtp"; $mail->SMTPAuth = SMTP_LOGIN != ''; $mail->Username = SMTP_LOGIN; $mail->Password = SMTP_PASSWORD; } $mail->IsHTML(false); $mail->Subject = __("[tt-rss] Password change notification"); $mail->Body = $message; $rc = $mail->Send(); if (!$rc) { print_error($mail->ErrorInfo); } } print "</div>"; }
/** * Generate a more truly "random" alpha-numeric string. * * @param int $length * * @throws \RuntimeException * * @return string */ function str_random($length = 16) { $string = ''; while (($len = strlen($string)) < $length) { $size = $length - $len; $bytes = get_random_bytes($size); $string .= substr(str_replace(['/', '+', '='], '', base64_encode($bytes)), 0, $size); } return $string; }
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\n\t\t\t\tpwd_hash = '{$new_password_hash}', salt = '{$new_salt}', otp_enabled = false\n\t\t\t\t\tWHERE id = '{$owner_uid}'"); $_SESSION["pwd_hash"] = $new_password_hash; return __("Password has been changed."); } else { return "ERROR: " . __('Old password is incorrect.'); } }
function forgotpass() { startup_gettext(); @($hash = $_REQUEST["hash"]); header('Content-Type: text/html; charset=utf-8'); print "<html><head><title>Tiny Tiny RSS</title>\n\t\t<link rel=\"shortcut icon\" type=\"image/png\" href=\"images/favicon.png\">\n\t\t<link rel=\"icon\" type=\"image/png\" sizes=\"72x72\" href=\"images/favicon-72px.png\">"; echo stylesheet_tag("css/utility.css"); echo javascript_tag("lib/prototype.js"); print "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>\n\t\t\t</head><body id='forgotpass'>"; print '<div class="floatingLogo"><img src="images/logo_small.png"></div>'; print "<h1>" . __("Password recovery") . "</h1>"; print "<div class='content'>"; @($method = $_POST['method']); if ($hash) { $login = $_REQUEST["login"]; if ($login) { $result = $this->dbh->query("SELECT id, resetpass_token FROM ttrss_users\n\t\t\t\t\tWHERE login = '******'"); if ($this->dbh->num_rows($result) != 0) { $id = $this->dbh->fetch_result($result, 0, "id"); $resetpass_token_full = $this->dbh->fetch_result($result, 0, "resetpass_token"); list($timestamp, $resetpass_token) = explode(":", $resetpass_token_full); if ($timestamp && $resetpass_token && $timestamp >= time() - 15 * 60 * 60 && $resetpass_token == $hash) { $result = $this->dbh->query("UPDATE ttrss_users SET resetpass_token = NULL\n\t\t\t\t\t\t\t\tWHERE id = {$id}"); Pref_Users::resetUserPassword($id, true); print "<p>" . "Completed." . "</p>"; } else { print_error("Some of the information provided is missing or incorrect."); } } else { print_error("Some of the information provided is missing or incorrect."); } } else { print_error("Some of the information provided is missing or incorrect."); } print "<form method=\"GET\" action=\"index.php\">\n\t\t\t\t<input type=\"submit\" value=\"" . __("Return to Tiny Tiny RSS") . "\">\n\t\t\t\t</form>"; } else { if (!$method) { print_notice(__("You will need to provide valid account name and email. A password reset link will be sent to your email address.")); print "<form method='POST' action='public.php'>"; print "<input type='hidden' name='method' value='do'>"; print "<input type='hidden' name='op' value='forgotpass'>"; print "<fieldset>"; print "<label>" . __("Login:"******"</label>"; print "<input type='text' name='login' value='' required>"; print "</fieldset>"; print "<fieldset>"; print "<label>" . __("Email:") . "</label>"; print "<input type='email' name='email' value='' required>"; print "</fieldset>"; print "<fieldset>"; print "<label>" . __("How much is two plus two:") . "</label>"; print "<input type='text' name='test' value='' required>"; print "</fieldset>"; print "<p/>"; print "<button type='submit'>" . __("Reset password") . "</button>"; print "</form>"; } else { if ($method == 'do') { $login = $this->dbh->escape_string($_POST["login"]); $email = $this->dbh->escape_string($_POST["email"]); $test = $this->dbh->escape_string($_POST["test"]); if ($test != 4 && $test != 'four' || !$email || !$login) { print_error(__('Some of the required form parameters are missing or incorrect.')); print "<form method=\"GET\" action=\"public.php\">\n\t\t\t\t\t<input type=\"hidden\" name=\"op\" value=\"forgotpass\">\n\t\t\t\t\t<input type=\"submit\" value=\"" . __("Go back") . "\">\n\t\t\t\t\t</form>"; } else { print_notice("Password reset instructions are being sent to your email address."); $result = $this->dbh->query("SELECT id FROM ttrss_users\n\t\t\t\t\tWHERE login = '******' AND email = '{$email}'"); if ($this->dbh->num_rows($result) != 0) { $id = $this->dbh->fetch_result($result, 0, "id"); if ($id) { $resetpass_token = sha1(get_random_bytes(128)); $resetpass_link = get_self_url_prefix() . "/public.php?op=forgotpass&hash=" . $resetpass_token . "&login="******"lib/MiniTemplator.class.php"; $tpl = new MiniTemplator(); $tpl->readTemplateFromFile("templates/resetpass_link_template.txt"); $tpl->setVariable('LOGIN', $login); $tpl->setVariable('RESETPASS_LINK', $resetpass_link); $tpl->addBlock('message'); $message = ""; $tpl->generateOutputToString($message); $mail = new ttrssMailer(); $rc = $mail->quickMail($email, $login, __("[tt-rss] Password reset request"), $message, false); if (!$rc) { print_error($mail->ErrorInfo); } $resetpass_token_full = $this->dbh->escape_string(time() . ":" . $resetpass_token); $result = $this->dbh->query("UPDATE ttrss_users\n\t\t\t\t\t\t\tSET resetpass_token = '{$resetpass_token_full}'\n\t\t\t\t\t\t\tWHERE login = '******' AND email = '{$email}'"); //Pref_Users::resetUserPassword($id, false); print "<p>"; print "<p>" . "Completed." . "</p>"; } else { print_error("User ID not found."); } print "<form method=\"GET\" action=\"index.php\">\n\t\t\t\t\t\t<input type=\"submit\" value=\"" . __("Return to Tiny Tiny RSS") . "\">\n\t\t\t\t\t\t</form>"; } else { print_error(__("Sorry, login and email combination not found.")); print "<form method=\"GET\" action=\"public.php\">\n\t\t\t\t\t\t<input type=\"hidden\" name=\"op\" value=\"forgotpass\">\n\t\t\t\t\t\t<input type=\"submit\" value=\"" . __("Go back") . "\">\n\t\t\t\t\t\t</form>"; } } } } } print "</div>"; print "</body>"; print "</html>"; }
function authenticate_user($link, $login, $password, $force_auth = false) { if (!SINGLE_USER_MODE) { $pwd_hash1 = encrypt_password($password); $pwd_hash2 = encrypt_password($password, $login); $login = db_escape_string($login); $remote_user = get_remote_user($link); if ($remote_user && $remote_user == $login && $login != "admin") { $login = $remote_user; $query = "SELECT id,login,access_level,pwd_hash\n\t FROM ttrss_users WHERE\n\t\t\t\t\tlogin = '******'"; if (defined('AUTO_CREATE_USER') && AUTO_CREATE_USER && $_SERVER["REMOTE_USER"]) { $result = db_query($link, $query); // First login ? if (db_num_rows($result) == 0) { $salt = substr(bin2hex(get_random_bytes(125)), 0, 250); $pwd_hash = encrypt_password($password, $salt, true); $query2 = "INSERT INTO ttrss_users\n\t\t\t\t\t\t\t\t(login,access_level,last_login,created,pwd_hash,salt)\n\t\t\t\t\t\t\t\tVALUES ('{$login}', 0, null, NOW(), '{$pwd_hash}','{$salt}')"; db_query($link, $query2); } } } else { if (get_schema_version($link) > 87) { $result = db_query($link, "SELECT salt FROM ttrss_users WHERE\n\t\t\t\t\tlogin = '******'"); if (db_num_rows($result) != 1) { return false; } $salt = db_fetch_result($result, 0, "salt"); if ($salt == "") { $query = "SELECT id,login,access_level,pwd_hash\n\t\t FROM ttrss_users WHERE\n\t\t\t\t\t\tlogin = '******' AND (pwd_hash = '{$pwd_hash1}' OR\n\t\t\t\t\t\tpwd_hash = '{$pwd_hash2}')"; // verify and upgrade password to new salt base $result = db_query($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($link, "UPDATE ttrss_users SET\n\t\t\t\t\t\t\tpwd_hash = '{$pwd_hash}', salt = '{$salt}' WHERE login = '******'"); $query = "SELECT id,login,access_level,pwd_hash\n\t\t\t FROM ttrss_users WHERE\n\t\t\t\t\t\t\tlogin = '******' AND pwd_hash = '{$pwd_hash}'"; } else { return false; } } else { $pwd_hash = encrypt_password($password, $salt, true); $query = "SELECT id,login,access_level,pwd_hash\n\t\t\t FROM ttrss_users WHERE\n\t\t\t\t\t\tlogin = '******' AND pwd_hash = '{$pwd_hash}'"; } } else { $query = "SELECT id,login,access_level,pwd_hash\n\t\t FROM ttrss_users WHERE\n\t\t\t\t\tlogin = '******' AND (pwd_hash = '{$pwd_hash1}' OR\n\t\t\t\t\t\tpwd_hash = '{$pwd_hash2}')"; } } $result = db_query($link, $query); if (db_num_rows($result) == 1) { $_SESSION["uid"] = db_fetch_result($result, 0, "id"); $_SESSION["name"] = db_fetch_result($result, 0, "login"); $_SESSION["access_level"] = db_fetch_result($result, 0, "access_level"); $_SESSION["csrf_token"] = sha1(uniqid(rand(), true)); db_query($link, "UPDATE ttrss_users SET last_login = NOW() WHERE id = " . $_SESSION["uid"]); // LemonLDAP can send user informations via HTTP HEADER if (defined('AUTO_CREATE_USER') && AUTO_CREATE_USER) { // update user name $fullname = $_SERVER['HTTP_USER_NAME'] ? $_SERVER['HTTP_USER_NAME'] : $_SERVER['AUTHENTICATE_CN']; if ($fullname) { $fullname = db_escape_string($fullname); db_query($link, "UPDATE ttrss_users SET full_name = '{$fullname}' WHERE id = " . $_SESSION["uid"]); } // update user mail $email = $_SERVER['HTTP_USER_MAIL'] ? $_SERVER['HTTP_USER_MAIL'] : $_SERVER['AUTHENTICATE_MAIL']; if ($email) { $email = db_escape_string($email); db_query($link, "UPDATE ttrss_users SET email = '{$email}' WHERE id = " . $_SESSION["uid"]); } } $_SESSION["ip_address"] = $_SERVER["REMOTE_ADDR"]; $_SESSION["pwd_hash"] = db_fetch_result($result, 0, "pwd_hash"); $_SESSION["last_version_check"] = time(); initialize_user_prefs($link, $_SESSION["uid"]); return true; } return false; } else { $_SESSION["uid"] = 1; $_SESSION["name"] = "admin"; $_SESSION["access_level"] = 10; if (!$_SESSION["csrf_token"]) { $_SESSION["csrf_token"] = sha1(uniqid(rand(), true)); } $_SESSION["ip_address"] = $_SERVER["REMOTE_ADDR"]; initialize_user_prefs($link, $_SESSION["uid"]); return true; } }