forked from photogabble/blacknova
-
Notifications
You must be signed in to change notification settings - Fork 0
/
pwreset2.php
137 lines (114 loc) · 6.18 KB
/
pwreset2.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
<?php
// Blacknova Traders - A web-based massively multiplayer space combat and trading game
// Copyright (C) 2001-2014 Ron Harwood and the BNT development team
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// File: pwreset2.php
require_once './common.php';
$title = $langvars['l_pwr_title'];
$body_class = 'options';
Bnt\Header::display($pdo_db, $lang, $template, $title, $body_class);
// Database driven language entries
$langvars = Bnt\Translate::load($pdo_db, $lang, array('mail', 'common', 'global_funcs', 'global_includes', 'global_funcs', 'combat', 'footer', 'news', 'options', 'pwreset', 'option2'));
echo "<h1>" . $title . "</h1>\n";
$reset_code = filter_input(INPUT_POST, 'code', FILTER_SANITIZE_STRING);
$newpass1 = filter_input(INPUT_POST, 'newpass1', FILTER_SANITIZE_STRING);
$newpass2 = filter_input(INPUT_POST, 'newpass2', FILTER_SANITIZE_STRING);
// It is important to note that SQL (both MySQL and PostgreSQL) index differently (one longer)
// than php does, which is why the substr (6/8 instead of 5/8) has a start index one "larger" here than in the php calls
// Also, we start at the 5th digit (plus one for SQL) because the first four characterts (before md5) are always going to be $2a$, from phpass/blowfish
// In most cases, even after hashing, the 5th character and beyond are unique.
// We chose 8 characters of uniqueness because its reasonable if you have to type it in, and
// because 8 characters is 4,294,967,296 combinations, and that should be sufficiently secure
$result = $db->SelectLimit("SELECT ship_id, email, recovery_time FROM {$db->prefix}ships WHERE substr(MD5(password),6,8) = ?", 1, -1, array('password' => $reset_code));
Bnt\Db::logDbErrors($db, $result, __LINE__, __FILE__);
if (!$result->EOF && $result != false)
{
$playerinfo = $result->fields;
$recovery_time = $result->fields['recovery_time'];
$expiration = $recovery_time + (90 * 60); // 90 minutes expiration for e-mailed password resets
// If time is within reset passowrd period (less than expiration), prompt user for new password
if (time() > $expiration)
{
echo $langvars['l_pwr_timeout'];
}
else
{
// Do it all here
// Check to see if newpass1 and newpass2 is empty.
if (empty($newpass1) && empty($newpass2))
{
// Yes both newpass1 and newpass2 are empty.
echo $langvars['l_opt2_passunchanged'] . "<br><br>";
// Redirect back to login page
header('Refresh: 10;url=index.php');
}
// Chack to see if newpass1 and newpass2 do not match.
elseif ($newpass1 !== $newpass2)
{
// Newpass1 and newpass2 do not match.
echo $langvars['l_opt2_newpassnomatch'] . "<br><br>";
// Redirect back to login page
header('Refresh: 10;url=index.php');
}
// So newpass1 and newpass2 are not null and they do match.
else
{
// Hash the password. $hashedPassword will be a 60-character string.
$hashed_pass = password_hash($newpass1, PASSWORD_DEFAULT);
// They have changed their password successfully, so update their session ID as well
session_regenerate_id();
// Now update the players password.
$rs = $db->Execute("UPDATE {$db->prefix}ships SET password = ? WHERE ship_id = ?;", array($hashed_pass, $playerinfo['ship_id']));
Bnt\Db::logDbErrors($db, $rs, __LINE__, __FILE__);
// Now check to see if we have a valid update and have ONLY 1 changed record.
if ((is_bool($rs) && $rs == false) || $db->Affected_Rows() != 1)
{
// Either we got an error in the SQL Query or <> 1 records was changed.
echo $langvars['l_opt2_passchangeerr'] . "<br><br>";
}
else
{
// Log user in
$_SESSION['password'] = $newpass1;
$_SESSION['logged_in'] = true;
$_SESSION['username'] = $playerinfo['email'];
}
// Send email to user & admin notifying of password change
$langvars['l_mail_message'] = str_replace("[ip]", $_SERVER['REMOTE_ADDR'], $langvars['l_mail_message']);
$langvars['l_mail_message'] = str_replace("[game_name]", $bntreg->game_name, $langvars['l_mail_message']);
// Some reason \r\n is broken, so replace them now.
$langvars['l_mail_message'] = str_replace('\r\n', "\r\n", $langvars['l_mail_message']);
// Need to set the topic with the game name.
$langvars['l_mail_topic'] = str_replace("[game_name]", $bntreg->game_name, $langvars['l_mail_topic']);
mail($playerinfo['email'], $langvars['l_mail_topic'], $langvars['l_mail_message'], "From: {$bntreg->admin_mail}\r\nReply-To: {$bntreg->admin_mail}\r\nX-Mailer: PHP/" . phpversion());
// Reset recovery_time to zero
$recovery_update_result = $db->Execute("UPDATE {$db->prefix}ships SET recovery_time = null WHERE email = ?;", array($playerinfo['email']));
Bnt\Db::logDbErrors($db, $recovery_update_result, __LINE__, __FILE__);
echo $langvars['l_pwr_success'] . "<br><br>";
echo str_replace("[here]", "<a href='main.php'>" . $langvars['l_here'] . "</a>", $langvars['l_global_mmenu']);
// Redirect to game
header('Refresh: 5;url=main.php');
}
}
}
else
{
// This reset code is not valid.
echo $langvars['l_pwr_invalid'];
// Admin log this attempt to use an invalid code
}
Bnt\Footer::display($pdo_db, $lang, $bntreg, $template);
?>