Challenge-Response Authentication

This commit is contained in:
xiaomlove
2025-04-05 15:38:40 +07:00
parent bd9b4d7e1d
commit 97dc956c20
28 changed files with 538 additions and 329 deletions
+13 -12
View File
@@ -9,7 +9,7 @@ if (!$id)
dbconn();
$res = sql_query("SELECT passhash, secret, editsecret, status FROM users WHERE id = ".sqlesc($id)) or sqlerr(__FILE__, __LINE__);
$res = sql_query("SELECT passhash, secret, auth_key, editsecret, status FROM users WHERE id = ".sqlesc($id)) or sqlerr(__FILE__, __LINE__);
$row = mysql_fetch_assoc($res);
if (!$row)
@@ -30,17 +30,18 @@ if (!mysql_affected_rows())
httperr();
if ($securelogin == "yes")
{
$securelogin_indentity_cookie = true;
$passh = md5($row["passhash"].$_SERVER["REMOTE_ADDR"]);
}
else // when it's op, default is not use secure login
{
$securelogin_indentity_cookie = false;
$passh = md5($row["passhash"]);
}
logincookie($id, $passh,1,get_setting('system.cookie_valid_days', 365) * 86400,$securelogin_indentity_cookie);
//if ($securelogin == "yes")
//{
// $securelogin_indentity_cookie = true;
// $passh = md5($row["passhash"].$_SERVER["REMOTE_ADDR"]);
//}
//else // when it's op, default is not use secure login
//{
// $securelogin_indentity_cookie = false;
// $passh = md5($row["passhash"]);
//}
//logincookie($id, $passh,1,get_setting('system.cookie_valid_days', 365) * 86400,$securelogin_indentity_cookie);
logincookie($id, $row["auth_key"]);
//sessioncookie($row["id"], $passh,false);
header("Location: ok.php?type=confirm");
+23
View File
@@ -404,3 +404,26 @@ function NewRow(anchor,up){
function DelRow(anchor){
anchor.parentNode.parentNode.parentNode.parentNode.deleteRow(anchor.parentNode.parentNode.rowIndex);
}
// 工具函数:SHA-256哈希
async function sha256(message) {
const msgBuffer = new TextEncoder().encode(message);
const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer);
const hashArray = Array.from(new Uint8Array(hashBuffer));
return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
}
// 工具函数:HMAC-SHA256
async function hmacSha256(key, message) {
const encoder = new TextEncoder();
const keyData = encoder.encode(key);
const messageData = encoder.encode(message);
const cryptoKey = await crypto.subtle.importKey(
'raw', keyData, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']
);
const signature = await crypto.subtle.sign('HMAC', cryptoKey, messageData);
const hashArray = Array.from(new Uint8Array(signature));
return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
}
+21 -9
View File
@@ -48,14 +48,19 @@ if (!empty($_GET["returnto"])) {
print("<p><b>" . $lang_login['p_error']. "</b> " . $lang_login['p_after_logged_in']. "</p>\n");
}
}
$useChallengeResponseAuthentication = \App\Models\Setting::getIsUseChallengeResponseAuthentication();
$passwordName = 'class="password"';
if (!$useChallengeResponseAuthentication) {
$passwordName .= ' name="password"';
}
?>
<form method="post" action="takelogin.php">
<form id="login-form" method="post" action="takelogin.php">
<input type="hidden" name="secret" value="<?php echo $secret?>">
<p><?php echo $lang_login['p_need_cookies_enables']?><br /> [<b><?php echo $maxloginattempts;?></b>] <?php echo $lang_login['p_fail_ban']?></p>
<p><?php echo $lang_login['p_you_have']?> <b><?php echo remaining ();?></b> <?php echo $lang_login['p_remaining_tries']?></p>
<table border="0" cellpadding="5">
<tr><td class="rowhead"><?php echo $lang_login['rowhead_username']?></td><td class="rowfollow" align="left"><input type="text" name="username" style="width: 180px; border: 1px solid gray" /></td></tr>
<tr><td class="rowhead"><?php echo $lang_login['rowhead_password']?></td><td class="rowfollow" align="left"><input type="password" name="password" style="width: 180px; border: 1px solid gray"/></td></tr>
<tr><td class="rowhead"><?php echo $lang_login['rowhead_username']?></td><td class="rowfollow" align="left"><input type="text" class="username" name="username" style="width: 180px; border: 1px solid gray" /></td></tr>
<tr><td class="rowhead"><?php echo $lang_login['rowhead_password']?></td><td class="rowfollow" align="left"><input type="password" <?php echo $passwordName ?> style="width: 180px; border: 1px solid gray"/></td></tr>
<tr><td class="rowhead"><?php echo $lang_login['rowhead_two_step_code']?></td><td class="rowfollow" align="left"><input type="text" name="two_step_code" placeholder="<?php echo $lang_login['two_step_code_tooltip'] ?>" style="width: 180px; border: 1px solid gray"/></td></tr>
<?php
show_image_code ();
@@ -75,16 +80,20 @@ elseif ($securetracker == "op")
?>
<tr><td class="toolbox" colspan="2" align="left"><?php echo $lang_login['text_advanced_options']?></td></tr>
<tr><td class="rowhead"><?php echo $lang_login['text_auto_logout']?></td><td class="rowfollow" align="left"><input class="checkbox" type="checkbox" name="logout" value="yes" /><?php echo $lang_login['checkbox_auto_logout']?></td></tr>
<tr><td class="rowhead"><?php echo $lang_login['text_restrict_ip']?></td><td class="rowfollow" align="left"><input class="checkbox" type="checkbox" name="securelogin" value="yes" /><?php echo $lang_login['checkbox_restrict_ip']?></td></tr>
<tr><td class="rowhead"><?php echo $lang_login['text_ssl']?></td><td class="rowfollow" align="left"><input class="checkbox" type="checkbox" name="ssl" value="yes" <?php echo $sec?> /><?php echo $lang_login['checkbox_ssl']?><br /><input class="checkbox" type="checkbox" name="trackerssl" value="yes" <?php echo $sectra?> /><?php echo $lang_login['checkbox_ssl_tracker']?></td></tr>
<tr><td class="toolbox" colspan="2" align="right"><input type="submit" value="<?php echo $lang_login['button_login']?>" class="btn" /> <input type="reset" value="<?php echo $lang_login['button_reset']?>" class="btn" /></td></tr>
<!--<tr><td class="rowhead">--><?php //echo $lang_login['text_restrict_ip']?><!--</td><td class="rowfollow" align="left"><input class="checkbox" type="checkbox" name="securelogin" value="yes" />--><?php //echo $lang_login['checkbox_restrict_ip']?><!--</td></tr>-->
<!--<tr><td class="rowhead">--><?php //echo $lang_login['text_ssl']?><!--</td><td class="rowfollow" align="left"><input class="checkbox" type="checkbox" name="ssl" value="yes" --><?php //echo $sec?><!-- />--><?php //echo $lang_login['checkbox_ssl']?><!--<br /><input class="checkbox" type="checkbox" name="trackerssl" value="yes" --><?php //echo $sectra?><!-- />--><?php //echo $lang_login['checkbox_ssl_tracker']?><!--</td></tr>-->
<tr><td class="toolbox" colspan="2" align="right"><input id="submit-btn" type="button" value="<?php echo $lang_login['button_login']?>" class="btn" /> <input type="reset" value="<?php echo $lang_login['button_reset']?>" class="btn" /></td></tr>
</table>
<?php
if (isset($returnto))
print("<input type=\"hidden\" name=\"returnto\" value=\"" . htmlspecialchars($returnto) . "\" />\n");
if (isset($returnto)) {
print("<input type=\"hidden\" name=\"returnto\" value=\"" . htmlspecialchars($returnto) . "\" />\n");
}
if ($useChallengeResponseAuthentication) {
print('<input type="hidden" name="response" />');
}
?>
</form>
<p>[<b><a href="complains.php"><?= $lang_login['text_complain'] ?></a></b>]</p>
<p><?php echo $lang_login['p_no_account_signup']?></p>
@@ -108,4 +117,7 @@ print("<div id=sbword style=\"display: none\">".$lang_login['sumbit_shout']."</d
print(smile_row("shbox","shbox_text"));
print("</td></tr></table></form></td></tr></table>");
}
?>
<?php
render_password_challenge_js("login-form", "username", "password");
stdfoot();
+3 -1
View File
@@ -85,7 +85,9 @@ elseif($_SERVER["REQUEST_METHOD"] == "GET" && $take_recover && isset($_GET["id"]
$sec = mksecret();
$newpasshash = md5($sec . $newpassword . $sec);
// $newpasshash = md5($sec . $newpassword . $sec);
$newpasshash = hash('sha256', $newpassword);
$newpasshash = hash('sha256', $sec.$newpasshash);
sql_query("UPDATE users SET secret=" . sqlesc($sec) . ", editsecret='', passhash=" . sqlesc($newpasshash) . " WHERE id=" . sqlesc($id)." AND editsecret=" . sqlesc($arr["editsecret"])) or sqlerr(__FILE__, __LINE__);
+2 -1
View File
@@ -199,7 +199,7 @@ elseif ($action == 'savesettings_security') // save security
$validConfig = array(
'securelogin', 'securetracker', 'https_announce_url','iv','maxip','maxloginattempts','changeemail','cheaterdet','nodetect',
'guest_visit_type', 'guest_visit_value_static_page', 'guest_visit_value_custom_content', 'guest_visit_value_redirect',
'login_type', 'login_secret_lifetime',
'login_type', 'login_secret_lifetime', 'use_challenge_response_authentication'
);
GetVar($validConfig);
$SECURITY = [];
@@ -376,6 +376,7 @@ elseif ($action == 'securitysettings') //security settings
tr($lang_settings['row_max_ips'],"<input type='text' style=\"width: 300px\" name=maxip value='" . ($SECURITY["maxip"] ? $SECURITY["maxip"] : "1")."'> ".$lang_settings['text_max_ips_note'], 1);
tr($lang_settings['row_max_login_attemps'],"<input type='text' style=\"width: 300px\" name=maxloginattempts value='" . ($SECURITY["maxloginattempts"] ? $SECURITY["maxloginattempts"] : "7")."'> ".$lang_settings['text_max_login_attemps_note'], 1);
yesorno($lang_settings['row_use_challenge_response_authentication'], 'use_challenge_response_authentication', $SECURITY["use_challenge_response_authentication"], $lang_settings['text_use_challenge_response_authentication_note']);
$guestVisitTypeRadio = '<label><input type="radio" name="guest_visit_type" value="normal"' . (empty($SECURITY['guest_visit_type']) || $SECURITY['guest_visit_type'] == 'normal' ? ' checked' : '') . ' onclick="document.getElementById(\'tbody_static_page\').style.display=\'none\';document.getElementById(\'tbody_custom_content\').style.display=\'none\';document.getElementById(\'tbody_redirect\').style.display=\'none\';">' . $lang_settings['text_guest_visit_type_normal'] . '</label>';
$guestVisitTypeRadio .= '<br/><label><input type="radio" name="guest_visit_type" value="static_page"' . ($SECURITY['guest_visit_type'] == 'static_page' ? ' checked' : '') . ' onclick="document.getElementById(\'tbody_static_page\').style.display=\'table-row-group\';document.getElementById(\'tbody_custom_content\').style.display=\'none\';document.getElementById(\'tbody_redirect\').style.display=\'none\';">' . $lang_settings['text_guest_visit_type_static_page'] . '</label>';
$guestVisitTypeRadio .= '<br/><label><input type="radio" name="guest_visit_type" value="custom_content"' . ($SECURITY['guest_visit_type'] == 'custom_content' ? ' checked' : '') . ' onclick="document.getElementById(\'tbody_static_page\').style.display=\'none\';document.getElementById(\'tbody_custom_content\').style.display=\'table-row-group\';document.getElementById(\'tbody_redirect\').style.display=\'none\';">' . $lang_settings['text_guest_visit_type_custom_content'] . '</label>';
+8 -4
View File
@@ -17,6 +17,7 @@ if ($langid)
}
}
require_once(get_langfile_path("", false, $CURLANGDIR));
require_once(get_langfile_path("takesignup.php", false, $CURLANGDIR));
cur_user_check ();
$type = $_GET['type'] ?? '';
$isPreRegisterEmailAndUsername = get_setting("system.is_invite_pre_email_and_username") == "yes";
@@ -73,7 +74,7 @@ print("<div align=right valign=top>".$lang_signup['text_select_lang']. $s . "</d
?>
</form>
<p>
<form method="post" action="takesignup.php">
<form method="post" action="takesignup.php" id="signup-form">
<?php if ($type == 'invite') print("<input type=\"hidden\" name=\"inviter\" value=\"".$inviter."\"><input type=hidden name=type value='invite'>");?>
<table border="1" cellspacing="0" cellpadding="10">
<?php
@@ -93,9 +94,9 @@ if ($isPreRegisterEmailAndUsername && !empty($inv["pre_register_email"])) {
?>
<tr><td class=rowhead><?php echo $lang_signup['row_desired_username'] ?></td><td class=rowfollow align=left><?php echo $usernameInput?><br />
<font class=small><?php echo $lang_signup['text_allowed_characters'] ?></font></td></tr>
<tr><td class=rowhead><?php echo $lang_signup['row_pick_a_password'] ?></td><td class=rowfollow align=left><input type="password" style="width: 200px" name="wantpassword" /><br />
<tr><td class=rowhead><?php echo $lang_signup['row_pick_a_password'] ?></td><td class=rowfollow align=left><input type="password" style="width: 200px" class="wantpassword" data-too-short="<?php echo $lang_takesignup['std_password_too_short']?>" data-too-long="<?php echo $lang_takesignup['std_password_too_long']?>" data-equals-username="<?php echo $lang_takesignup['std_password_equals_username']?>"/><br />
<font class=small><?php echo $lang_signup['text_minimum_six_characters'] ?></font></td></tr>
<tr><td class=rowhead><?php echo $lang_signup['row_enter_password_again'] ?></td><td class=rowfollow align=left><input type="password" style="width: 200px" name="passagain" /></td></tr>
<tr><td class=rowhead><?php echo $lang_signup['row_enter_password_again'] ?></td><td class=rowfollow align=left><input type="password" style="width: 200px" class="passagain" data-tip="<?php echo $lang_takesignup['std_passwords_unmatched']?>"/></td></tr>
<?php
show_image_code ();
?>
@@ -123,8 +124,11 @@ tr($lang_signup['row_school'], "<select name=school>$schools</select>", 1);
<input type=checkbox name=faqverify value=yes><?php echo $lang_signup['checkbox_read_faq'] ?> <br />
<input type=checkbox name=ageverify value=yes><?php echo $lang_signup['checkbox_age'] ?></td></tr>
<input type=hidden name=hash value=<?php echo $code?>>
<tr><td class=toolbox colspan="2" align="center"><font color=red><b><?php echo $lang_signup['text_all_fields_required'] ?></b><p></font><input type=submit value=<?php echo $lang_signup['submit_sign_up'] ?> style='height: 25px'></td></tr>
<input type="hidden" name="wantpassword" />
<tr><td class=toolbox colspan="2" align="center"><font color=red><b><?php echo $lang_signup['text_all_fields_required'] ?></b><p></font><input id="submit-btn" type=button value=<?php echo $lang_signup['submit_sign_up'] ?> style='height: 25px'></td></tr>
</table>
</form>
<?php
render_password_hash_js("signup-form", "wantpassword", "wantpassword", true,"passagain", "wantusername");
stdfoot();
+60 -53
View File
@@ -1,7 +1,7 @@
<?php
require_once("../include/bittorrent.php");
header("Content-Type: text/html; charset=utf-8");
if (!mkglobal("username:password"))
if (!mkglobal("username"))
die();
dbconn();
require_once(get_langfile_path("", false, get_langfolder_cookie()));
@@ -14,15 +14,30 @@ function bark($text = "")
$text = ($text == "" ? $lang_takelogin['std_login_fail_note'] : $text);
stderr($lang_takelogin['std_login_fail'], $text,false);
}
if ($iv == "yes")
check_code ($_POST['imagehash'], $_POST['imagestring'],'login.php',true);
$res = sql_query("SELECT id, passhash, secret, enabled, status, two_step_secret, lang FROM users WHERE username = " . sqlesc($username));
if ($iv == "yes") {
check_code ($_POST['imagehash'], $_POST['imagestring'],'login.php',true);
}
//同时支持新旧两种登录方式
$useChallengeResponse = \App\Models\Setting::getIsUseChallengeResponseAuthentication();
if ($useChallengeResponse) {
if (empty($_POST['response'])) {
failedlogins("Require response parameter.");
}
} else {
if (empty($_POST['password'])) {
failedlogins("Require password parameter.");
}
}
$res = sql_query("SELECT id, passhash, secret, auth_key, enabled, status, two_step_secret, lang FROM users WHERE username = " . sqlesc($username));
$row = mysql_fetch_array($res);
if (!$row)
failedlogins();
if ($row['status'] == 'pending')
failedlogins($lang_takelogin['std_user_account_unconfirmed']);
if ($row["enabled"] == "no")
bark($lang_takelogin['std_account_disabled']);
if (!empty($row['two_step_secret'])) {
if (empty($_POST['two_step_code'])) {
@@ -34,72 +49,64 @@ if (!empty($row['two_step_secret'])) {
}
}
$log = "user: {$row['id']}, ip: $ip";
if ($row["passhash"] != md5($row["secret"] . $password . $row["secret"])) {
$update = [];
if ($useChallengeResponse) {
$challenge = \Nexus\Database\NexusDB::cache_get(get_challenge_key($username));
if (empty($challenge)) {
failedlogins("expired");
}
$log .= ", useChallengeResponse, client response: " . $_POST['response'];
} else {
$passwordHash = hash('sha256', $row['secret'] . hash('sha256', $_POST['password']));
$log .= ", !useChallengeResponse, passwordHash: $passwordHash";
if (empty($row['auth_key'])) {
//先使用旧的验证方式验证
if ($row["passhash"] != md5($row["secret"] . $_POST['password'] . $row["secret"])) {
do_log("$log, md5 not equal");
login_failedlogins();
}
$log .= ", no auth_key, upgrade to challenge response";
//自动升级为新的验证方式
$update['passhash'] = $row['passhash'] = $passwordHash;
}
//后端自动生成挑战响应
$challenge = mksecret();
$_POST['response'] = hash_hmac('sha256', $passwordHash, $challenge);
$log .= ", server generate response: " . $_POST['response'];
}
$expectedResponse = hash_hmac('sha256', $row['passhash'], $challenge);
$log .= ", expectedResponse: $expectedResponse";
if (!hash_equals($expectedResponse, $_POST["response"])) {
do_log("$log, !hash_equals");
login_failedlogins();
}
\Nexus\Database\NexusDB::cache_del(get_challenge_key($username));
do_log("$log, login successful");
$userRep = new \App\Repositories\UserRepository();
$userRep->saveLoginLog($row['id'], $ip, 'Web', true);
if ($row["enabled"] == "no")
bark($lang_takelogin['std_account_disabled']);
if (isset($_POST["securelogin"]) && $_POST["securelogin"] == "yes")
{
$securelogin_indentity_cookie = true;
/**
* Not IP related
* @since 1.8.0
*/
// $passh = md5($row["passhash"].$ip);
$passh = md5($row["passhash"]);
$log .= ", secure login == yeah, passhash: {$row['passhash']}, ip: $ip, md5: $passh";
}
else
{
$securelogin_indentity_cookie = false;
$passh = md5($row["passhash"]);
$log .= ", passhash: {$row['passhash']}, md5: $passh";
}
if ($securelogin=='yes' || (isset($_POST["ssl"]) && $_POST["ssl"] == "yes"))
{
$pprefix = "https://";
$ssl = true;
}
else
{
$pprefix = "http://";
$ssl = false;
}
if ($securetracker=='yes' || (isset($_POST["trackerssl"] ) && $_POST["trackerssl"] == "yes"))
{
$trackerssl = true;
}
else
{
$trackerssl = false;
}
do_log($log);
//update user lang
$language = \App\Models\Language::query()->where("site_lang_folder", get_langfolder_cookie())->first();
if ($language && $language->id != $row["lang"]) {
do_log(sprintf("update user: %s lang: %s => %s", $row["id"], $row["lang"], $language->id));
\App\Models\User::query()->where("id", $row["id"])->update(["lang" => $language->id]);
$update["lang"] = $language->id;
}
if (empty($row['auth_key'])) {
$row['auth_key'] = $update['auth_key'] = hash('sha256', mksecret(32));
}
if (!empty($update)) {
\App\Models\User::query()->where("id", $row["id"])->update($update);
clear_user_cache($row["id"]);
}
if (isset($_POST["logout"]) && $_POST["logout"] == "yes")
{
logincookie($row["id"], $passh,1,900,$securelogin_indentity_cookie, $ssl, $trackerssl);
//sessioncookie($row["id"], $passh,true);
logincookie($row["id"], $row['auth_key'],900);
}
else
{
logincookie($row["id"], $passh,1,get_setting('system.cookie_valid_days', 365) * 86400,$securelogin_indentity_cookie, $ssl, $trackerssl);
//sessioncookie($row["id"], $passh,false);
logincookie($row["id"], $row['auth_key']);
}
if (!empty($_POST["returnto"]))
+15 -14
View File
@@ -73,7 +73,7 @@ $res = sql_query("SELECT username FROM users WHERE id = $inviter") or sqlerr(__F
$arr = mysql_fetch_assoc($res);
$invusername = $arr['username'];
}
if (!mkglobal("wantusername:wantpassword:passagain:email")) {
if (!mkglobal("wantusername:wantpassword:email")) {
die();
}
if ($isPreRegisterEmailAndUsername && $type == 'invite' && !empty($inv["pre_register_username"]) && !empty($inv["pre_register_email"])) {
@@ -111,17 +111,17 @@ if (empty($wantusername) || empty($wantpassword) || empty($email) || empty($coun
if (strlen($wantusername) > 12)
bark($lang_takesignup['std_username_too_long']);
if ($wantpassword != $passagain)
bark($lang_takesignup['std_passwords_unmatched']);
//if ($wantpassword != $passagain)
// bark($lang_takesignup['std_passwords_unmatched']);
if (strlen($wantpassword) < 6)
bark($lang_takesignup['std_password_too_short']);
if (strlen($wantpassword) > 40)
bark($lang_takesignup['std_password_too_long']);
if ($wantpassword == $wantusername)
bark($lang_takesignup['std_password_equals_username']);
//if (strlen($wantpassword) < 6)
// bark($lang_takesignup['std_password_too_short']);
//
//if (strlen($wantpassword) > 40)
// bark($lang_takesignup['std_password_too_long']);
//
//if ($wantpassword == $wantusername)
// bark($lang_takesignup['std_password_equals_username']);
if (!validemail($email))
bark($lang_takesignup['std_wrong_email_address_format']);
@@ -148,7 +148,8 @@ $arr = mysql_fetch_row($res);
*/
$secret = mksecret();
$wantpasshash = md5($secret . $wantpassword . $secret);
//$wantpasshash = md5($secret . $wantpassword . $secret);
$wantpasshash = hash('sha256', $secret . $wantpassword);
$editsecret = ($verification == 'admin' ? '' : $secret);
$invite_count = (int) $invite_count;
$passkey = md5($wantusername.date("Y-m-d H:i:s").$wantpasshash);
@@ -162,13 +163,13 @@ $email = sqlesc($email);
$country = sqlesc($country);
$gender = sqlesc($gender);
$sitelangid = sqlesc(get_langid_from_langcookie());
$authKey = sqlesc(mksecret());
$res_check_user = sql_query("SELECT * FROM users WHERE username = " . $wantusername);
if(mysql_num_rows($res_check_user) == 1)
bark($lang_takesignup['std_username_exists']);
$ret = sql_query("INSERT INTO users (username, passhash, passkey, secret, editsecret, email, country, gender, status, class, invites, ".($type == 'invite' ? "invited_by," : "")." added, last_access, lang, stylesheet".($showschool == 'yes' ? ", school" : "").", uploaded) VALUES (" . $wantusername . "," . $wantpasshash . "," . sqlesc($passkey) . "," . $secret . "," . $editsecret . "," . $email . "," . $country . "," . $gender . ", 'pending', ".$defaultclass_class.",". $invite_count .", ".($type == 'invite' ? "'$inviter'," : "") ." '". date("Y-m-d H:i:s") ."' , " . " '". date("Y-m-d H:i:s") ."' , ".$sitelangid . ",".$defcss.($showschool == 'yes' ? ",".$school : "").",".($iniupload_main > 0 ? $iniupload_main : 0).")") or sqlerr(__FILE__, __LINE__);
$ret = sql_query("INSERT INTO users (username, passhash, passkey, secret, auth_key, editsecret, email, country, gender, status, class, invites, ".($type == 'invite' ? "invited_by," : "")." added, last_access, lang, stylesheet".($showschool == 'yes' ? ", school" : "").", uploaded) VALUES (" . $wantusername . "," . $wantpasshash . "," . sqlesc($passkey) . "," . $secret . "," . $authKey. "," . $editsecret . "," . $email . "," . $country . "," . $gender . ", 'pending', ".$defaultclass_class.",". $invite_count .", ".($type == 'invite' ? "'$inviter'," : "") ." '". date("Y-m-d H:i:s") ."' , " . " '". date("Y-m-d H:i:s") ."' , ".$sitelangid . ",".$defcss.($showschool == 'yes' ? ",".$school : "").",".($iniupload_main > 0 ? $iniupload_main : 0).")") or sqlerr(__FILE__, __LINE__);
$id = mysql_insert_id();
fire_event("user_created", \App\Models\User::query()->find($id, \App\Models\User::$commonFields));
$tmpInviteCount = get_setting('main.tmp_invite_count');
+66 -66
View File
@@ -3,7 +3,7 @@ require "../include/bittorrent.php";
dbconn();
require_once(get_langfile_path());
loggedinorreturn();
$userInfo = \App\Models\User::query()->findOrFail($CURUSER["id"], \App\Models\User::$commonFields);
$userInfo = \App\Models\User::query()->findOrFail($CURUSER["id"]);
function bark($msg) {
stdhead();
global $lang_usercp;
@@ -41,12 +41,15 @@ function getimageheight ($imagewidth, $imageheight)
}
return $imageheight;
}
function form($name) {
return print("<form method=post action=usercp.php><input type=hidden name=action value=".htmlspecialchars($name)."><input type=hidden name=type value=save>");
function form($name, $type = "save", $id = "") {
if ($id == "") {
$id = "form" . random_str();
}
return print("<form method=post action=usercp.php id=\"".$id."\"><input type=hidden name=action value=".htmlspecialchars($name)."><input type=hidden name=type value={$type}>");
}
function submit() {
function submit($type = "submit") {
global $lang_usercp;
print("<tr><td class=\"rowhead\" valign=\"top\" align=\"right\">".$lang_usercp['row_save_settings']."</td><td class=\"rowfollow\" valign=\"top\" align=left><input type=submit value=\"".$lang_usercp['submit_save_settings']."\"></td></tr>"."</form>");
print("<tr><td class=\"rowhead\" valign=\"top\" align=\"right\">".$lang_usercp['row_save_settings']."</td><td class=\"rowfollow\" valign=\"top\" align=left><input type=".$type." value=\"".$lang_usercp['submit_save_settings']."\"></td></tr>");
}
function format_tz($a)
{
@@ -174,11 +177,11 @@ if ($action){
}
usercpmenu ("personal");
form ("personal");
print ("<table border=0 cellspacing=0 cellpadding=5 width=".CONTENT_WIDTH.">");
if ($type == 'saved')
print("<tr><td colspan=2 class=\"heading\" valign=\"top\" align=\"center\"><font color=red>".$lang_usercp['text_saved']."</font></td></tr>\n");
form ("personal");
tr_small($lang_usercp['row_account_parked'],
"<input type=checkbox name=parked" . ($CURUSER["parked"] == "yes" ? " checked" : "") . " value=yes>".$lang_usercp['checkbox_pack_my_account']."<br /><font class=small size=1>".$lang_usercp['text_account_pack_note']."</font>"
,1);
@@ -214,7 +217,7 @@ tr($lang_usercp['row_school'], "<select name=school>$schools</select>", 1);
"\"><br />\n".$lang_usercp['text_avatar_note'].($enablebitbucket_main == 'yes' ? $lang_usercp['text_bitbucket_note'] : ""),1);
tr($lang_usercp['row_info'], "<textarea name=\"info\" style=\"width:700px\" rows=\"10\" >" . htmlspecialchars($CURUSER["info"]) . "</textarea><br />".$lang_usercp['text_info_note'], 1);
submit();
print("</table>");
print("</table></form>");
stdfoot();
die;
break;
@@ -398,6 +401,7 @@ tr($lang_usercp['row_school'], "<select name=school>$schools</select>", 1);
}
stdhead($lang_usercp['head_control_panel'].$lang_usercp['head_tracker_settings']);
usercpmenu ("tracker");
form ("tracker");
$brsectiontype = $browsecatmode;
$spsectiontype = $specialcatmode;
if ($enablespecial == 'yes' && get_user_class() >= get_setting('authority.view_special_torrent'))
@@ -451,7 +455,6 @@ if ($showaudiocodec) $audiocodecs = searchbox_item_list("audiocodecs");
}
*/
print ("<table border=0 cellspacing=0 cellpadding=5 width=".CONTENT_WIDTH.">");
form ("tracker");
if ($type == 'saved')
print("<tr><td colspan=2 class=\"heading\" valign=\"top\" align=\"center\"><font color=red>".$lang_usercp['text_saved']."</font></td></tr>\n");
if ($emailnotify_smtp=='yes' && $smtptype != 'none')
@@ -654,7 +657,7 @@ tr_small($lang_usercp['row_funbox'],"<input type=checkbox name=showfb".($CURUSER
<b>".$lang_usercp['text_comments_reviews'].": </b><br /><input type=checkbox name=showcomnum ".($CURUSER['showcomnum'] == 'yes' ? " checked" : "")." value=yes>".$lang_usercp['text_show_comment_number'].($showtooltipsetting ? "<select name=\"showlastcom\" style=\"width: 70px;\"><option value=\"yes\" ".($CURUSER['showlastcom'] != 'no' ? " selected" : "").">".$lang_usercp['select_with']."</option><option value=\"no\" ".($CURUSER['showlastcom'] == 'no' ? " selected" : "").">".$lang_usercp['select_without']."</option></select>".$lang_usercp['text_last_comment_on_tooltip'] : ""), 1);
submit();
print("</table>");
print("</table></form>");
stdfoot();
die;
break;
@@ -689,8 +692,8 @@ tr_small($lang_usercp['row_funbox'],"<input type=checkbox name=showfb".($CURUSER
}
stdhead($lang_usercp['head_control_panel'].$lang_usercp['head_forum_settings'],true);
usercpmenu ("forum");
form ("forum");
print ("<table border=0 cellspacing=0 cellpadding=5 width=".CONTENT_WIDTH.">");
form ("forum");
if ($type == 'saved')
print("<tr><td colspan=2 class=\"heading\" valign=\"top\" align=\"center\"><font color=red>".$lang_usercp['text_saved']."</font></td></tr>\n");
@@ -703,20 +706,26 @@ tr_small($lang_usercp['row_funbox'],"<input type=checkbox name=showfb".($CURUSER
tr_small($lang_usercp['row_click_on_topic'], "<input type=radio name=clicktopic" . ($CURUSER["clicktopic"] == "firstpage" ? " checked" : "") . " value=\"firstpage\">".$lang_usercp['text_go_to_first_page']."<input type=radio name=clicktopic" . ($CURUSER["clicktopic"] == "lastpage" ? " checked" : "") . " value=\"lastpage\">".$lang_usercp['text_go_to_last_page'],1);
tr_small($lang_usercp['row_forum_signature'], "<textarea name=signature style=\"width:700px\" rows=10>" . $CURUSER['signature'] . "</textarea><br />".$lang_usercp['text_signature_note'],1);
submit();
print("</table>");
print("</table></form>");
stdfoot();
die;
break;
case "security":
if ($type == 'confirm') {
$oldpassword = $_POST['oldpassword'];
if (!$oldpassword){
$response = $_POST['response'];
if (!$response){
stderr($lang_usercp['std_error'], $lang_usercp['std_enter_old_password'].goback(), 0);
die;
}elseif ($CURUSER["passhash"] != md5($CURUSER["secret"] . $oldpassword . $CURUSER["secret"])){
stderr($lang_usercp['std_error'], $lang_usercp['std_wrong_password_note'].goback(), 0);
die;
}else
}
//验证旧密码
$challenge = \Nexus\Database\NexusDB::cache_get(get_challenge_key($userInfo->username));
if (empty($challenge)) {
stderr($lang_usercp['std_error'], "expired!".goback(), 0);
}
$expectedResponse = hash_hmac('sha256', $userInfo->passhash, $challenge);
if (!hash_equals($expectedResponse, $response)) {
stderr($lang_usercp['std_error'], $lang_usercp['std_wrong_password_note'].goback(), 0);
}
$updateset = array();
$changedemail = 0;
$passupdated = 0;
@@ -724,7 +733,7 @@ tr_small($lang_usercp['row_funbox'],"<input type=checkbox name=showfb".($CURUSER
$resetpasskey = $_POST["resetpasskey"];
$email = mysql_real_escape_string( htmlspecialchars( trim($_POST["email"]) ));
$chpassword = $_POST["chpassword"];
$passagain = $_POST["passagain"];
// $passagain = $_POST["passagain"];
$privacy = $_POST["privacy"];
$twoStepSecret = $_POST['two_step_secret'] ?? '';
$twoStepSecretHash = $_POST['two_step_code'];
@@ -747,47 +756,30 @@ tr_small($lang_usercp['row_funbox'],"<input type=checkbox name=showfb".($CURUSER
}
if ($chpassword != "") {
if ($chpassword == $CURUSER["username"]) {
stderr($lang_usercp['std_error'], $lang_usercp['std_password_equals_username'].goback("-2"), 0);
die;
}
if (strlen($chpassword) > 40) {
stderr($lang_usercp['std_error'], $lang_usercp['std_password_too_long'].goback("-2"), 0);
die;
}
if (strlen($chpassword) < 6) {
stderr($lang_usercp['std_error'], $lang_usercp['std_password_too_short'].goback("-2"), 0);
die;
}
if ($chpassword != $passagain) {
stderr($lang_usercp['std_error'], $lang_usercp['std_passwords_unmatched'].goback("-2"), 0);
die;
}
// if ($chpassword == $CURUSER["username"]) {
// stderr($lang_usercp['std_error'], $lang_usercp['std_password_equals_username'].goback("-2"), 0);
// die;
// }
// if (strlen($chpassword) > 40) {
// stderr($lang_usercp['std_error'], $lang_usercp['std_password_too_long'].goback("-2"), 0);
// die;
// }
// if (strlen($chpassword) < 6) {
// stderr($lang_usercp['std_error'], $lang_usercp['std_password_too_short'].goback("-2"), 0);
// die;
// }
// if ($chpassword != $passagain) {
// stderr($lang_usercp['std_error'], $lang_usercp['std_passwords_unmatched'].goback("-2"), 0);
// die;
// }
$sec = mksecret();
$passhash = md5($sec . $chpassword . $sec);
// $passhash = md5($sec . $chpassword . $sec);
$passhash = hash('sha256', $sec . $chpassword);
$updateset[] = "secret = " . sqlesc($sec);
$updateset[] = "passhash = " . sqlesc($passhash);
//die($securelogin . base64_decode($_COOKIE["c_secure_login"]));
if ($_COOKIE["c_secure_login"] == base64("yeah"))
{
$passh = md5($passhash . $_SERVER["REMOTE_ADDR"]);
$securelogin_indentity_cookie = true;
}
else
{
$passh = md5($passhash);
$securelogin_indentity_cookie = false;
}
if($_COOKIE["c_secure_ssl"] == base64("yeah"))
$ssl = true;
else
$ssl = false;
logincookie($CURUSER["id"], $passh ,1,get_setting('system.cookie_valid_days', 365) * 86400,$securelogin_indentity_cookie,$ssl);
//sessioncookie($CURUSER["id"], $passh);
logincookie($CURUSER["id"], $userInfo->auth_key);
$passupdated = 1;
}
@@ -864,13 +856,15 @@ EOD;
if ($privacyupdated == 1)
$to .= "&privacy=1";
clear_user_cache($CURUSER["id"]);
\Nexus\Database\NexusDB::cache_get(get_challenge_key($userInfo->username));
header("Location: $to");
}
stdhead($lang_usercp['head_control_panel'].$lang_usercp['head_security_settings']);
usercpmenu ("security");
form ("security", $type == "save" ? "confirm" : "save","security");
print ("<table border=0 cellspacing=0 cellpadding=5 width=".CONTENT_WIDTH.">");
if ($type == 'save') {
print("<form method=post action=usercp.php><input type=hidden name=action value=security><input type=hidden name=type value=confirm>");
// print("<form method=post action=usercp.php><input type=hidden name=action value=security><input type=hidden name=type value=confirm>");
$resetpasskey = $_POST["resetpasskey"];
$resetauthkey = $_POST["resetauthkey"];
$email = mysql_real_escape_string( htmlspecialchars( trim($_POST["email"]) ));
@@ -885,20 +879,23 @@ EOD;
print("<input type=\"hidden\" name=\"resetauthkey\" value=\"1\">");
print("<input type=\"hidden\" name=\"email\" value=\"$email\">");
print("<input type=\"hidden\" name=\"chpassword\" value=\"$chpassword\">");
print("<input type=\"hidden\" name=\"passagain\" value=\"$passagain\">");
// print("<input type=\"hidden\" name=\"passagain\" value=\"$passagain\">");
print("<input type=\"hidden\" name=\"privacy\" value=\"$privacy\">");
print("<input type=\"hidden\" name=\"two_step_secret\" value=\"$two_step_secret\">");
print("<input type=\"hidden\" name=\"two_step_code\" value=\"$two_step_code\">");
Print("<tr><td class=\"rowhead nowrap\" valign=\"top\" align=\"right\" width=1%>".$lang_usercp['row_security_check']."</td><td valign=\"top\" align=\"left\" width=\"99%\"><input type=password name=oldpassword style=\"width: 200px\"><br /><font class=small>".$lang_usercp['text_security_check_note']."</font></td></tr>\n");
do_action("usercp_security_update_confirm", $_POST);
submit();
print("</table>");
Print("<tr><td class=\"rowhead nowrap\" valign=\"top\" align=\"right\" width=1%>".$lang_usercp['row_security_check']."</td><td valign=\"top\" align=\"left\" width=\"99%\"><input type=password class=oldpassword style=\"width: 200px\"><br /><font class=small>".$lang_usercp['text_security_check_note']."</font></td></tr>\n");
print('<input type=hidden name=username value="'.$CURUSER["username"].'">');
print('<input type=hidden name=response>');
do_action("usercp_security_update_confirm", $_POST);
submit("button");
print("</table></form>");
render_password_challenge_js("security", "username", "oldpassword");
stdfoot();
die;
}
if ($type == 'saved')
print("<tr><td colspan=2 class=\"heading\" valign=\"top\" align=\"center\"><font color=red>".$lang_usercp['text_saved'].($_GET["mail"] == "1" ? $lang_usercp['std_confirmation_email_sent'] : "")." ".($_GET["passkey"] == "1" ? $lang_usercp['std_passkey_reset'] : "")." ".($_GET["password"] == "1" ? $lang_usercp['std_password_changed'] : "")." ".($_GET["privacy"] == "1" ? $lang_usercp['std_privacy_level_updated'] : "")."</font></td></tr>\n");
form ("security");
tr_small($lang_usercp['row_reset_passkey'],"<input type=checkbox name=resetpasskey value=1 />".$lang_usercp['checkbox_reset_my_passkey']."<br /><font class=small>".$lang_usercp['text_reset_passkey_note']."</font>", 1);
// tr_small($lang_usercp['row_reset_authkey'],"<input type=checkbox name=resetauthkey value=1 />".$lang_usercp['checkbox_reset_my_authkey']."<br /><font class=small>".$lang_usercp['text_reset_authkey_note']."</font>", 1);
@@ -927,11 +924,14 @@ EOD;
if ($disableemailchange != 'no' && $smtptype != 'none') //system-wide setting
tr_small($lang_usercp['row_email_address'], "<input type=\"text\" name=\"email\" style=\"width: 200px\" value=\"" . htmlspecialchars($CURUSER["email"]) . "\" /> <br /><font class=small>".$lang_usercp['text_email_address_note']."</font>", 1);
do_action("usercp_security_setting_form");
tr_small($lang_usercp['row_change_password'], "<input type=\"password\" name=\"chpassword\" style=\"width: 200px\" />", 1);
tr_small($lang_usercp['row_type_password_again'], "<input type=\"password\" name=\"passagain\" style=\"width: 200px\" />", 1);
tr_small($lang_usercp['row_change_password'], "<input type=\"password\" class=\"password\" style=\"width: 200px\" />", 1);
print('<input type="hidden" name="chpassword" />');
tr_small($lang_usercp['row_type_password_again'], "<input type=\"password\" class=\"passagain\" style=\"width: 200px\" />", 1);
tr_small($lang_usercp['row_privacy_level'], priv("normal", $lang_usercp['radio_normal']) . " " . priv("low", $lang_usercp['radio_low']) . " " . priv("strong", $lang_usercp['radio_strong']), 1);
submit();
print("</table>");
submit("button");
print("</table></form>");
render_password_hash_js("security", "password", "chpassword", false,"passagain");
stdfoot();
die;
break;