goed-beveiligd-inlogsysteem-met-classen
Gesponsorde koppelingen
PHP script bestanden
class.clsUser.php:
Code (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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
<?php
// Constante definities, spreken voor zich
define('LOGIN_SESSION_EXPIRED',1);
define('LOGIN_NO_USER',2);
define('LOGIN_INCORRECT_PWD',4);
define('LOGIN_SECURITY_BAN',8);
define('LOGIN_SUCCESS',16);
define('REGISTER_INVALID_USERNAME',1);
define('REGISTER_USER_EXISTS',2);
define('REGISTER_INVALID_EMAIL',4);
define('REGISTER_EMAIL_EXISTS',8);
define('REGISTER_SUCCESS',16);
class clsUser {
private $state_loaded; // true als clsUser::load() is aangeroepen
private $id;
private $username;
private $startdate;
private $email;
private $db;
public function __construct(){
$this->db = clsDatabase::getInstance('test.login'); // Laad de database met de gegevens uit 'test.login'
$this->state_loaded = false;
}
public function __destruct(){
}
public function get_logged_in() {
/* pre: -
post: Geeft terug of de gebruiker is ingelogd, kijkt ook of sessie niet gestolen is.
*/
if ( isset ( $_SESSION['ip']) ) {
return (( $_SESSION['ip'] == $_SERVER['REMOTE_ADDR'] ) && (isset($_SESSION['id'])));
} else {
$_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
return isset($_SESSION['id']);
}
}
public function get_id() { return $this->id; }
public function get_username() { return $this->username; }
public function get_startdate() { return $this->startdate; }
public function get_banned() {
/* pre: -
post: Returned true of false. True als persoon gebanned is, false als dit niet het geval is.
Init $_SESSION['bf_security_timer'] als dit nodig is, en unset deze ook als het nodig is.
*/
if ( $this->get_bf_counter() >= 3 ) {
if ( isset ( $_SESSION['bf_security_timer'] ) ) {
if ( $_SESSION['bf_security_timer'] + 5 * 60 <= time() ) {
unset ( $_SESSION['bf_security_timer'] );
set_bf_counter(1,false);
return false;
}
} else {
$_SESSION['bf_security_timer'] = time();
}
} else {
return false;
}
return true;
}
public function get_bf_counter() {
/* pre: -
post: Return hoeveel pogingen er zijn gedaan om in te loggen.
Init $_SESSION['bf_security_counter'] als dit nodig is.
*/
if ( isset ( $_SESSION['bf_security_counter'] ) ) {
return $_SESSION['bf_security_counter'];
} else {
$_SESSION['bf_security_counter'] = 1;
return 1;
}
}
public function set_bf_counter( $arg_plus = 1, $arg_relative = true) {
/* pre: 0 < $arg_plus < MAX_INT, (bool) $arg_relative
post: Update $_SESSION['bf_security_counter'] met $arg_plus
*/
if ( $arg_relative ) {
$_SESSION['bf_security_counter'] += $arg_plus ;
} else {
$_SESSION['bf_security_counter'] = $arg_plus ;
}
}
public function set_username( $arg_username ) {
/* pre: -
post: $this->username geset als $arg_username alleen letters of underscore bevat en 2 < len($arg_username) <= 12
*/
if ( (preg_match('/[A-Z_]+/i',$arg_username)) && (strlen($arg_username) > 2) && (strlen($arg_username) <= 12) ) {
$this->username = $arg_username;
}
}
public function set_email ( $arg_email ) {
/* pre: -
post: $this->email geset als $arg_email valide is
*/
if ( preg_match('/\b[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b/i',$arg_email) ) {
$this->email = $arg_email;
}
}
public function log_in( $arg_username, $arg_response ) {
/* pre: -
post: geeft een waarde terug of de login succesvol is. Alleen succesvol bij LOGIN_SUCCESS
*/
if ( $this->get_banned() ) {
return LOGIN_SECURITY_BAN;
}
// Bepaal of de sessie nog niet verlopen is
if ( isset ( $_SESSION['challenge'] ) ) {
$rs_user = $this->db->query("SELECT * FROM users WHERE username = '" . $this->db->quote_smart($arg_username) . "'");
// Bepaal of user bestaat
if ( $rs_user->CountRows() ) {
$arr_user = $rs_user->fetchRow();
// Password was gehashed verzonden, dus ook nu hashen om te vergelijken
$f = bin2hex(mhash(MHASH_SHA256, $arg_username . '()' . $_SESSION['challenge'] ) );
$f = $arr_user['password'] . $f;
$f = bin2hex(mhash(MHASH_SHA256,$f));
// Vergelijk server met client waarde
if ( $f == $arg_response ) {
$_SESSION['id'] = $arr_user['id'];
$this->logged_in = true;
$this->id = $arr_user['id'];
$this->username = $arr_user['username'];
$this->startdate = $arr_user['startdate'];
$this->email = $arr_user['email'];
// De challenge hebben we niet meer nodig
unset($_SESSION['challenge']);
return LOGIN_SUCCESS;
} else {
$this->set_bf_counter();
return LOGIN_INCORRECT_PWD;
}
} else {
return LOGIN_NO_USER;
}
} else {
return LOGIN_SESSION_EXPIRED;
}
}
public function log_off () {
/* pre: -
post: Gebruiker is uitgelogd
*/
if ( $this->get_logged_in() ) {
unset($_SESSION['id']);
}
}
public function load(){
/* pre: -
post: Laad de huidige instantie van het user object
*/
if (! $this->state_loaded && $this->get_logged_in() ) {
$this->state_loaded = true;
$arr_user = $this->db->query("SELECT * FROM users WHERE id = " . $this->db->quote_smart($_SESSION['id']) )->fetchRow();
$this->id = $arr_user['id'];
$this->username = $arr_user['username'];
$this->startdate = $arr_user['startdate'];
$this->email = $arr_user['email'];
}
}
public function register_user ( ) {
/* pre: -
post: Gebruiker toevoegd in database, en e-mail met wachtwoord verzonden
*/
// Niks doen als het object geladen is
if ( ! $this->state_loaded ) {
// Username en email moeten valide zijn
if ( ($this->username != '') && ($this->email != '') ) {
$rs_u = $this->db->query("SELECT username FROM users WHERE username = '" . $this->db->quote_smart($this->username) . "' OR email = '" . $this->db->quote_smart($this->email) . "'");
// Gebruiker nog emailaddress mag bestaan
if ($rs_u->CountRows() ) {
$arr_u = $rs_u->fetchRow();
// We weten dat of er iemand met deze username of iemand met dit emailadres bestaat, maar we weten nog niet welke van de twee.
if ( $arr_u['username'] == $this->username ) {
return REGISTER_USER_EXISTS;
} else {
return REGISTER_EMAIL_EXISTS;
}
} else {
$pwd = '';
// Maak een nieuw wachtwoord van alleen maar hoofdletters
for ( $i = 1; $i < 9;$i++ ){
$pwd .= chr(rand(65,90));
}
// Voet gebruiker in in de database
$rs_u = $this->db->query("INSERT INTO users VALUES(NULL,'{$this->username}','" . bin2hex(mhash(MHASH_SHA256,$pwd)) . "',NOW(), '{$this->email}')");
$this->id = $rs_u->getInsertId();
$this->startdate = time();
// Header maken voor het verzenden van e-mail
$header = "Content-type: text/html; charset=iso-8859-1\r\n";
$header .= "Return-Path: [email protected]\r\n";
$header .= "X-Sender: [email protected]\r\n";
$header .= "From: Login Test <[email protected]>\r\n";
$header .= "X-Mailer:PHP 5.1\r\n";
$header .= "MIME-Version: 1.0\r\n";
mail($this->email, "Login account", $pwd,$header);
return REGISTER_SUCCESS;
}
} else {
if ( $this->username == '' ) {
return REGISTER_INVALID_USERNAME;
}else{
return REGISTER_INVALID_EMAIL;
}
}
}
}
}
?>
// Constante definities, spreken voor zich
define('LOGIN_SESSION_EXPIRED',1);
define('LOGIN_NO_USER',2);
define('LOGIN_INCORRECT_PWD',4);
define('LOGIN_SECURITY_BAN',8);
define('LOGIN_SUCCESS',16);
define('REGISTER_INVALID_USERNAME',1);
define('REGISTER_USER_EXISTS',2);
define('REGISTER_INVALID_EMAIL',4);
define('REGISTER_EMAIL_EXISTS',8);
define('REGISTER_SUCCESS',16);
class clsUser {
private $state_loaded; // true als clsUser::load() is aangeroepen
private $id;
private $username;
private $startdate;
private $email;
private $db;
public function __construct(){
$this->db = clsDatabase::getInstance('test.login'); // Laad de database met de gegevens uit 'test.login'
$this->state_loaded = false;
}
public function __destruct(){
}
public function get_logged_in() {
/* pre: -
post: Geeft terug of de gebruiker is ingelogd, kijkt ook of sessie niet gestolen is.
*/
if ( isset ( $_SESSION['ip']) ) {
return (( $_SESSION['ip'] == $_SERVER['REMOTE_ADDR'] ) && (isset($_SESSION['id'])));
} else {
$_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
return isset($_SESSION['id']);
}
}
public function get_id() { return $this->id; }
public function get_username() { return $this->username; }
public function get_startdate() { return $this->startdate; }
public function get_banned() {
/* pre: -
post: Returned true of false. True als persoon gebanned is, false als dit niet het geval is.
Init $_SESSION['bf_security_timer'] als dit nodig is, en unset deze ook als het nodig is.
*/
if ( $this->get_bf_counter() >= 3 ) {
if ( isset ( $_SESSION['bf_security_timer'] ) ) {
if ( $_SESSION['bf_security_timer'] + 5 * 60 <= time() ) {
unset ( $_SESSION['bf_security_timer'] );
set_bf_counter(1,false);
return false;
}
} else {
$_SESSION['bf_security_timer'] = time();
}
} else {
return false;
}
return true;
}
public function get_bf_counter() {
/* pre: -
post: Return hoeveel pogingen er zijn gedaan om in te loggen.
Init $_SESSION['bf_security_counter'] als dit nodig is.
*/
if ( isset ( $_SESSION['bf_security_counter'] ) ) {
return $_SESSION['bf_security_counter'];
} else {
$_SESSION['bf_security_counter'] = 1;
return 1;
}
}
public function set_bf_counter( $arg_plus = 1, $arg_relative = true) {
/* pre: 0 < $arg_plus < MAX_INT, (bool) $arg_relative
post: Update $_SESSION['bf_security_counter'] met $arg_plus
*/
if ( $arg_relative ) {
$_SESSION['bf_security_counter'] += $arg_plus ;
} else {
$_SESSION['bf_security_counter'] = $arg_plus ;
}
}
public function set_username( $arg_username ) {
/* pre: -
post: $this->username geset als $arg_username alleen letters of underscore bevat en 2 < len($arg_username) <= 12
*/
if ( (preg_match('/[A-Z_]+/i',$arg_username)) && (strlen($arg_username) > 2) && (strlen($arg_username) <= 12) ) {
$this->username = $arg_username;
}
}
public function set_email ( $arg_email ) {
/* pre: -
post: $this->email geset als $arg_email valide is
*/
if ( preg_match('/\b[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b/i',$arg_email) ) {
$this->email = $arg_email;
}
}
public function log_in( $arg_username, $arg_response ) {
/* pre: -
post: geeft een waarde terug of de login succesvol is. Alleen succesvol bij LOGIN_SUCCESS
*/
if ( $this->get_banned() ) {
return LOGIN_SECURITY_BAN;
}
// Bepaal of de sessie nog niet verlopen is
if ( isset ( $_SESSION['challenge'] ) ) {
$rs_user = $this->db->query("SELECT * FROM users WHERE username = '" . $this->db->quote_smart($arg_username) . "'");
// Bepaal of user bestaat
if ( $rs_user->CountRows() ) {
$arr_user = $rs_user->fetchRow();
// Password was gehashed verzonden, dus ook nu hashen om te vergelijken
$f = bin2hex(mhash(MHASH_SHA256, $arg_username . '()' . $_SESSION['challenge'] ) );
$f = $arr_user['password'] . $f;
$f = bin2hex(mhash(MHASH_SHA256,$f));
// Vergelijk server met client waarde
if ( $f == $arg_response ) {
$_SESSION['id'] = $arr_user['id'];
$this->logged_in = true;
$this->id = $arr_user['id'];
$this->username = $arr_user['username'];
$this->startdate = $arr_user['startdate'];
$this->email = $arr_user['email'];
// De challenge hebben we niet meer nodig
unset($_SESSION['challenge']);
return LOGIN_SUCCESS;
} else {
$this->set_bf_counter();
return LOGIN_INCORRECT_PWD;
}
} else {
return LOGIN_NO_USER;
}
} else {
return LOGIN_SESSION_EXPIRED;
}
}
public function log_off () {
/* pre: -
post: Gebruiker is uitgelogd
*/
if ( $this->get_logged_in() ) {
unset($_SESSION['id']);
}
}
public function load(){
/* pre: -
post: Laad de huidige instantie van het user object
*/
if (! $this->state_loaded && $this->get_logged_in() ) {
$this->state_loaded = true;
$arr_user = $this->db->query("SELECT * FROM users WHERE id = " . $this->db->quote_smart($_SESSION['id']) )->fetchRow();
$this->id = $arr_user['id'];
$this->username = $arr_user['username'];
$this->startdate = $arr_user['startdate'];
$this->email = $arr_user['email'];
}
}
public function register_user ( ) {
/* pre: -
post: Gebruiker toevoegd in database, en e-mail met wachtwoord verzonden
*/
// Niks doen als het object geladen is
if ( ! $this->state_loaded ) {
// Username en email moeten valide zijn
if ( ($this->username != '') && ($this->email != '') ) {
$rs_u = $this->db->query("SELECT username FROM users WHERE username = '" . $this->db->quote_smart($this->username) . "' OR email = '" . $this->db->quote_smart($this->email) . "'");
// Gebruiker nog emailaddress mag bestaan
if ($rs_u->CountRows() ) {
$arr_u = $rs_u->fetchRow();
// We weten dat of er iemand met deze username of iemand met dit emailadres bestaat, maar we weten nog niet welke van de twee.
if ( $arr_u['username'] == $this->username ) {
return REGISTER_USER_EXISTS;
} else {
return REGISTER_EMAIL_EXISTS;
}
} else {
$pwd = '';
// Maak een nieuw wachtwoord van alleen maar hoofdletters
for ( $i = 1; $i < 9;$i++ ){
$pwd .= chr(rand(65,90));
}
// Voet gebruiker in in de database
$rs_u = $this->db->query("INSERT INTO users VALUES(NULL,'{$this->username}','" . bin2hex(mhash(MHASH_SHA256,$pwd)) . "',NOW(), '{$this->email}')");
$this->id = $rs_u->getInsertId();
$this->startdate = time();
// Header maken voor het verzenden van e-mail
$header = "Content-type: text/html; charset=iso-8859-1\r\n";
$header .= "Return-Path: [email protected]\r\n";
$header .= "X-Sender: [email protected]\r\n";
$header .= "From: Login Test <[email protected]>\r\n";
$header .= "X-Mailer:PHP 5.1\r\n";
$header .= "MIME-Version: 1.0\r\n";
mail($this->email, "Login account", $pwd,$header);
return REGISTER_SUCCESS;
}
} else {
if ( $this->username == '' ) {
return REGISTER_INVALID_USERNAME;
}else{
return REGISTER_INVALID_EMAIL;
}
}
}
}
}
?>
class.clsDatabase.php:
Code (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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
<?php
class clsDatabase {
protected $con_id;
protected $host;
protected $user;
protected $password;
protected $database;
private $query_counter;
public function __construct( $arg_param ) {
// Laad de connectie gegevens uit een array
if ( is_array ($arg_param) && count($arg_param) == 4 ) {
foreach ( $arg_param as $parameter => $value ) {
$this->{$parameter} = $value;
}
// Laad de connectie gegevens uit een bestand
// !! LET OP: niet veilig, gebruiker kan dit bestand ook zien. Beveilingen met .htaccess of andere aanpak bedenken
} elseif ( is_file ( $arg_param ) ) {
if (! $handle = file ( $arg_param ) ) {
trigger_error('Invalid path parameter given for connection');
} else {
foreach ($handle as $line) {
$arr = explode('=',$line);
$this->$arr[0] = trim($arr[1]);
}
}
} else {
trigger_error('No connection parameters provided',E_USER_ERROR);
}
// Maak de connectie naar de database
$this->connect();
// Er zijn nog geen queries uitgeoverd
$query_counter = 0;
}
public function __destruct() {
}
public static function getInstance( $arg_param ) {
/* pre: -
post: Geeft instantie van huidig object, altijd maar 1 instantie te gelijk ( SINGLETON )
*/
static $instance;
if( ! isset( $instance ) ){
$object= __CLASS__;
$instance = new $object($arg_param);
}
return $instance;
}
public function get_con_id() { return $this->con_id; }
public function get_host() { return $this->host; }
public function get_user() { return $this->user; }
public function get_password() { return $this->password; }
public function get_database() { return $this->database; }
public function get_query_counter() { return $this->query_counter; }
private function connect() {
/* pre: -
post: Huidige connectie wordt gesloten en nieuwe connectie is aangamaakt
*/
// Sluit huidige connectie als die er is.
if ( $this->con_id ) {
mysql_close($this->con_id);
$this->con_id = NULL;
}
// Alles moet wel zijn ingevuld
if ( ($this->host == '') || ($this->user == '') || ($this->password == '') || ($this->database == '') ){
trigger_error('Insufficient connection parameters given',E_USER_ERROR);
} else {
if ( ! $this->con_id = mysql_connect($this->host,$this->user,$this->password ) ) {
trigger_error('Unable to create connection',E_USER_ERROR);
} else {
if ( ! mysql_select_db($this->database,$this->con_id) ) {
trigger_error('Error selecting database',E_USER_ERROR);
}
}
}
}
public function query($arg_sql) {
/* pre: -
post: Een clsResult wordt geretured met de huidige query
Querycounter is met 1 verhoogd
*/
if ( ! $result = mysql_query($arg_sql, $this->con_id) ) {
trigger_error('Error performing query, error given: ' .mysql_error($this->con_id) . ' on query: ' .$arg_sql,E_USER_ERROR);
}
$this->queries++;
return new clsResult($this, $result);
}
public function quote_smart( $arg_value ) {
/* pre: -
post: $arg_value wordt ge-escaped. Werkt ook met magic_quotes
*/
if (get_magic_quotes_gpc()) {
$arg_value = stripslashes($arg_value);
}
// Quote if not integer
$arg_value = mysql_real_escape_string($arg_value, $this->con_id );
return $arg_value;
}
}
class clsResult {
protected $myparent; // clsDatabase
protected $result;
public function __construct(clsDatabase $arg_parent, $arg_query ) {
$this->myparent = $arg_parent;
$this->result = $arg_query;
}
public function __destruct() {
// Geef resources van query vrij, maar alleen als het een resource is
if ( is_resource($this->result) ) {
mysql_free_result($this->result);
}
}
public function CountRows() {
/* pre: $this->result is resource
post: Het aantal rijen in result, false voor 0 rijen
*/
$rows = mysql_num_rows($this->result);
if ( $rows == 0 ){
return false;
}
return $rows;
}
function fetchRow(){
/* pre: $this->result is resource
post: Geef een array van de huidige rij
*/
return mysql_fetch_array($this->result,MYSQL_ASSOC);
}
public function CountAffectedRows() {
/* pre: $this->result is GEEN resource, maar resultaat van UPDATE of INSERT
post: Geeft het aantal aangepaste rijen weer, false voor 0 rijen
*/
$rows = mysql_affected_rows($this->myparent->get_con_id());
if ($rows == 0) {
return false;
} else {
return $rows;
}
}
public function getInsertId() {
/* pre: $this->result is GEEN resource, maar resultaat van UPDATE of INSERT
post: Geeft het id van de laatst ingevoegde rij
*/
if( ! $id = mysql_insert_id( $this->myparent->get_con_id() ) ){
trigger_error('Error getting ID',E_USER_ERROR);
}
return $id;
}
public function seekRow( $arg_row = 0 ) {
/* pre: $this->result is resource, 0 =< $arg_row =< count($this->result)
post: Zoek een rij in het resultaat
*/
if( ! mysql_data_seek($this->result,$arg_row)){
trigger_error('Error seeking data',E_USER_ERROR);
}
}
}
?>
class clsDatabase {
protected $con_id;
protected $host;
protected $user;
protected $password;
protected $database;
private $query_counter;
public function __construct( $arg_param ) {
// Laad de connectie gegevens uit een array
if ( is_array ($arg_param) && count($arg_param) == 4 ) {
foreach ( $arg_param as $parameter => $value ) {
$this->{$parameter} = $value;
}
// Laad de connectie gegevens uit een bestand
// !! LET OP: niet veilig, gebruiker kan dit bestand ook zien. Beveilingen met .htaccess of andere aanpak bedenken
} elseif ( is_file ( $arg_param ) ) {
if (! $handle = file ( $arg_param ) ) {
trigger_error('Invalid path parameter given for connection');
} else {
foreach ($handle as $line) {
$arr = explode('=',$line);
$this->$arr[0] = trim($arr[1]);
}
}
} else {
trigger_error('No connection parameters provided',E_USER_ERROR);
}
// Maak de connectie naar de database
$this->connect();
// Er zijn nog geen queries uitgeoverd
$query_counter = 0;
}
public function __destruct() {
}
public static function getInstance( $arg_param ) {
/* pre: -
post: Geeft instantie van huidig object, altijd maar 1 instantie te gelijk ( SINGLETON )
*/
static $instance;
if( ! isset( $instance ) ){
$object= __CLASS__;
$instance = new $object($arg_param);
}
return $instance;
}
public function get_con_id() { return $this->con_id; }
public function get_host() { return $this->host; }
public function get_user() { return $this->user; }
public function get_password() { return $this->password; }
public function get_database() { return $this->database; }
public function get_query_counter() { return $this->query_counter; }
private function connect() {
/* pre: -
post: Huidige connectie wordt gesloten en nieuwe connectie is aangamaakt
*/
// Sluit huidige connectie als die er is.
if ( $this->con_id ) {
mysql_close($this->con_id);
$this->con_id = NULL;
}
// Alles moet wel zijn ingevuld
if ( ($this->host == '') || ($this->user == '') || ($this->password == '') || ($this->database == '') ){
trigger_error('Insufficient connection parameters given',E_USER_ERROR);
} else {
if ( ! $this->con_id = mysql_connect($this->host,$this->user,$this->password ) ) {
trigger_error('Unable to create connection',E_USER_ERROR);
} else {
if ( ! mysql_select_db($this->database,$this->con_id) ) {
trigger_error('Error selecting database',E_USER_ERROR);
}
}
}
}
public function query($arg_sql) {
/* pre: -
post: Een clsResult wordt geretured met de huidige query
Querycounter is met 1 verhoogd
*/
if ( ! $result = mysql_query($arg_sql, $this->con_id) ) {
trigger_error('Error performing query, error given: ' .mysql_error($this->con_id) . ' on query: ' .$arg_sql,E_USER_ERROR);
}
$this->queries++;
return new clsResult($this, $result);
}
public function quote_smart( $arg_value ) {
/* pre: -
post: $arg_value wordt ge-escaped. Werkt ook met magic_quotes
*/
if (get_magic_quotes_gpc()) {
$arg_value = stripslashes($arg_value);
}
// Quote if not integer
$arg_value = mysql_real_escape_string($arg_value, $this->con_id );
return $arg_value;
}
}
class clsResult {
protected $myparent; // clsDatabase
protected $result;
public function __construct(clsDatabase $arg_parent, $arg_query ) {
$this->myparent = $arg_parent;
$this->result = $arg_query;
}
public function __destruct() {
// Geef resources van query vrij, maar alleen als het een resource is
if ( is_resource($this->result) ) {
mysql_free_result($this->result);
}
}
public function CountRows() {
/* pre: $this->result is resource
post: Het aantal rijen in result, false voor 0 rijen
*/
$rows = mysql_num_rows($this->result);
if ( $rows == 0 ){
return false;
}
return $rows;
}
function fetchRow(){
/* pre: $this->result is resource
post: Geef een array van de huidige rij
*/
return mysql_fetch_array($this->result,MYSQL_ASSOC);
}
public function CountAffectedRows() {
/* pre: $this->result is GEEN resource, maar resultaat van UPDATE of INSERT
post: Geeft het aantal aangepaste rijen weer, false voor 0 rijen
*/
$rows = mysql_affected_rows($this->myparent->get_con_id());
if ($rows == 0) {
return false;
} else {
return $rows;
}
}
public function getInsertId() {
/* pre: $this->result is GEEN resource, maar resultaat van UPDATE of INSERT
post: Geeft het id van de laatst ingevoegde rij
*/
if( ! $id = mysql_insert_id( $this->myparent->get_con_id() ) ){
trigger_error('Error getting ID',E_USER_ERROR);
}
return $id;
}
public function seekRow( $arg_row = 0 ) {
/* pre: $this->result is resource, 0 =< $arg_row =< count($this->result)
post: Zoek een rij in het resultaat
*/
if( ! mysql_data_seek($this->result,$arg_row)){
trigger_error('Error seeking data',E_USER_ERROR);
}
}
}
?>
class.clsSessionHandler.php:
Code (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
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
<?php
class clsSessionHandler {
protected $session_started; // Is sessie al gestart?
protected $lifetime;
private $db;
public function __construct() {
// Maak een nieuwe connectie naar de database
$this->db = clsDatabase::getInstance('test.login');
// Deze classe moet sessies afhandlen, dus geef dat aan
session_set_save_handler(array($this,'sess_open'),array($this,'sess_close'),array($this,'sess_read'),
array($this,'sess_write'),array($this,'sess_destroy'),array($this,'sess_gc'));
session_start();
$this->session_started = true;
}
public function __destruct() {
}
public static function getInstance() {
/* pre: -
post: Geeft instantie van huidig object, altijd maar 1 instantie te gelijk ( SINGLETON )
*/
static $instance;
if(!isset($instance)){
$object= __CLASS__;
$instance = new $object;
}
return $instance;
}
public function sess_open ( $save_path, $session_name ) {
// Bepaal de max leeftijd van een sessie
$this->lifetime = ini_get("session.gc_maxlifetime");
// Als iemand al een sessie had en deze is nog niet verlopen, geef hem dan opnieuw diezelfde sessie
$rs = $this->db->query( "SELECT session_id FROM sessions WHERE ip = '" . $_SERVER['REMOTE_ADDR'] . "'");
if ( $rs->CountRows() ) {
$rs_arr = $rs->fetchRow();
session_id($rs_arr['session_id']);
}
return true;
}
public function sess_close () {
$this->sess_gc($this->lifetime);
return true;
}
public function sess_read( $id ) {
$rs = $this->db->query( "SELECT data FROM sessions WHERE session_id = '" . $this->db->quote_smart($id) . "'");
if ( $rs->CountRows() ) {
$rs_arr = $rs->fetchRow();
return $rs_arr['data'];
} else {
$rs = $this->db->query("INSERT INTO sessions VALUES ( '', NOW(), '" .$this->db->quote_smart($id) ."', '{$_SERVER['REMOTE_ADDR']}',0)");
return false;
}
}
public function sess_write ( $id, $sess_data ) {
// Als iemand al ingelogd is haal dan het id uit de data, nodig voor users_online bijvoorbeeld
if ( preg_match ( '/id\|s:(\d+?):\"(\d+?)\"/i',$sess_data, $matches) ) {
$user = $matches[2];
} else {
$user = 0;
}
$rs = $this->db->query("INSERT INTO sessions VALUES ( '$sess_data', NOW(), '" . $this->db->quote_smart($id) . "', '{$_SERVER['REMOTE_ADDR']}', '$user') ON DUPLICATE KEY UPDATE data = '" .$this->db->quote_smart($sess_data) . "', user = '$user'");
return true;
}
public function sess_destroy ( $id ) {
$this->db->query("DELETE FROM sessions WHERE session_id = '" .$this->db->quote_smart($id) ."'");
return true;
}
public function sess_gc ( $maxlifetime ) {
// Vernietig alle sessies die verlopen zijn
$rs = $this->db->query("DELETE FROM sessions WHERE time + $maxlifetime < NOW()");
return $rs->CountAffectedRows();
}
}
?>
class clsSessionHandler {
protected $session_started; // Is sessie al gestart?
protected $lifetime;
private $db;
public function __construct() {
// Maak een nieuwe connectie naar de database
$this->db = clsDatabase::getInstance('test.login');
// Deze classe moet sessies afhandlen, dus geef dat aan
session_set_save_handler(array($this,'sess_open'),array($this,'sess_close'),array($this,'sess_read'),
array($this,'sess_write'),array($this,'sess_destroy'),array($this,'sess_gc'));
session_start();
$this->session_started = true;
}
public function __destruct() {
}
public static function getInstance() {
/* pre: -
post: Geeft instantie van huidig object, altijd maar 1 instantie te gelijk ( SINGLETON )
*/
static $instance;
if(!isset($instance)){
$object= __CLASS__;
$instance = new $object;
}
return $instance;
}
public function sess_open ( $save_path, $session_name ) {
// Bepaal de max leeftijd van een sessie
$this->lifetime = ini_get("session.gc_maxlifetime");
// Als iemand al een sessie had en deze is nog niet verlopen, geef hem dan opnieuw diezelfde sessie
$rs = $this->db->query( "SELECT session_id FROM sessions WHERE ip = '" . $_SERVER['REMOTE_ADDR'] . "'");
if ( $rs->CountRows() ) {
$rs_arr = $rs->fetchRow();
session_id($rs_arr['session_id']);
}
return true;
}
public function sess_close () {
$this->sess_gc($this->lifetime);
return true;
}
public function sess_read( $id ) {
$rs = $this->db->query( "SELECT data FROM sessions WHERE session_id = '" . $this->db->quote_smart($id) . "'");
if ( $rs->CountRows() ) {
$rs_arr = $rs->fetchRow();
return $rs_arr['data'];
} else {
$rs = $this->db->query("INSERT INTO sessions VALUES ( '', NOW(), '" .$this->db->quote_smart($id) ."', '{$_SERVER['REMOTE_ADDR']}',0)");
return false;
}
}
public function sess_write ( $id, $sess_data ) {
// Als iemand al ingelogd is haal dan het id uit de data, nodig voor users_online bijvoorbeeld
if ( preg_match ( '/id\|s:(\d+?):\"(\d+?)\"/i',$sess_data, $matches) ) {
$user = $matches[2];
} else {
$user = 0;
}
$rs = $this->db->query("INSERT INTO sessions VALUES ( '$sess_data', NOW(), '" . $this->db->quote_smart($id) . "', '{$_SERVER['REMOTE_ADDR']}', '$user') ON DUPLICATE KEY UPDATE data = '" .$this->db->quote_smart($sess_data) . "', user = '$user'");
return true;
}
public function sess_destroy ( $id ) {
$this->db->query("DELETE FROM sessions WHERE session_id = '" .$this->db->quote_smart($id) ."'");
return true;
}
public function sess_gc ( $maxlifetime ) {
// Vernietig alle sessies die verlopen zijn
$rs = $this->db->query("DELETE FROM sessions WHERE time + $maxlifetime < NOW()");
return $rs->CountAffectedRows();
}
}
?>
Index.php:
Code (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
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
<?php
// Laad alle benodigde classen automatisch
if ( ! function_exists('__autoload') ) {
function __autoload( $arg_class ) {
require_once("class.$arg_class.php");
}
}
// We hebben sessies nodig, dus maak deze aan
$obj_handler = clsSessionHandler::getInstance();
$obj_user = new clsUser();
if ( $obj_user->get_banned() ) {
echo "You got banned for 5 mins";
return;
}
if ( $obj_user->get_logged_in() ) {
$msg = "You already are logged in.";
} else {
if ( isset ( $_POST['username'], $_POST['response'] ) ){
$h = $obj_user->log_in($_POST['username'], $_POST['response'] );
switch ( $h ) {
case LOGIN_SESSION_EXPIRED:
$msg = "Session expired";
break;
case LOGIN_NO_USER:
$msg = "No such user";
break;
case LOGIN_INCORRECT_PWD:
$msg = "Incorrect password";
break;
case LOGIN_SUCCESS:
$msg = "You are now logged in";
break;
case LOGIN_SECURITY_BAN:
$msg = "You got banned for 5 mins";
return;
break;
}
}
}
// Nieuwe challenge nodig voor login
$_SESSION['challenge'] = sha1(pack("H*", sha1(mt_rand())));
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Login</title>
<script type="text/javascript" src="sha.js"></script>
<script type="text/javascript" language="javascript">
function create_response ( ) {
var password = document.getElementById('password');
var challenge = document.getElementById('challenge');
var login = document.forms['login'];
login.response.value = sha256_digest(sha256_digest(password.value) + sha256_digest(login.username.value + '()' + challenge.value));
password.value = '';
challenge.value = '';
return true;
}
</script>
</head>
<body>
<?php
if ( isset ( $msg) ) {
echo $msg;
}
?>
<form method="post" name="login" action="<?php echo basename($_SERVER['PHP_SELF']);?>" onsubmit="return create_response(); ">
<p>Username: <input type="text" name="username" /></p>
<p>Password: <input type="password" id="password" /></p>
<input type="hidden" id="challenge" value="<?php echo $_SESSION['challenge'];?>"/>
<input type="hidden" name="response" />
<input type="submit" value="Login" />
</form>
<p><a href="register.php" title="Create account">Click here for a free account</a></p>
</body>
</html>
// Laad alle benodigde classen automatisch
if ( ! function_exists('__autoload') ) {
function __autoload( $arg_class ) {
require_once("class.$arg_class.php");
}
}
// We hebben sessies nodig, dus maak deze aan
$obj_handler = clsSessionHandler::getInstance();
$obj_user = new clsUser();
if ( $obj_user->get_banned() ) {
echo "You got banned for 5 mins";
return;
}
if ( $obj_user->get_logged_in() ) {
$msg = "You already are logged in.";
} else {
if ( isset ( $_POST['username'], $_POST['response'] ) ){
$h = $obj_user->log_in($_POST['username'], $_POST['response'] );
switch ( $h ) {
case LOGIN_SESSION_EXPIRED:
$msg = "Session expired";
break;
case LOGIN_NO_USER:
$msg = "No such user";
break;
case LOGIN_INCORRECT_PWD:
$msg = "Incorrect password";
break;
case LOGIN_SUCCESS:
$msg = "You are now logged in";
break;
case LOGIN_SECURITY_BAN:
$msg = "You got banned for 5 mins";
return;
break;
}
}
}
// Nieuwe challenge nodig voor login
$_SESSION['challenge'] = sha1(pack("H*", sha1(mt_rand())));
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Login</title>
<script type="text/javascript" src="sha.js"></script>
<script type="text/javascript" language="javascript">
function create_response ( ) {
var password = document.getElementById('password');
var challenge = document.getElementById('challenge');
var login = document.forms['login'];
login.response.value = sha256_digest(sha256_digest(password.value) + sha256_digest(login.username.value + '()' + challenge.value));
password.value = '';
challenge.value = '';
return true;
}
</script>
</head>
<body>
<?php
if ( isset ( $msg) ) {
echo $msg;
}
?>
<form method="post" name="login" action="<?php echo basename($_SERVER['PHP_SELF']);?>" onsubmit="return create_response(); ">
<p>Username: <input type="text" name="username" /></p>
<p>Password: <input type="password" id="password" /></p>
<input type="hidden" id="challenge" value="<?php echo $_SESSION['challenge'];?>"/>
<input type="hidden" name="response" />
<input type="submit" value="Login" />
</form>
<p><a href="register.php" title="Create account">Click here for a free account</a></p>
</body>
</html>
Register.php
Code (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
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
<?php
// Laad alle benodigde classen automatisch
if ( ! function_exists('__autoload') ) {
function __autoload( $arg_class ) {
require_once("class.$arg_class.php");
}
}
// We hebben sessies nodig, dus maak deze aan
$obj_handler = clsSessionHandler::getInstance();
if (isset ($_POST['username'],$_POST['email'])) {
$obj_user = new clsUser();
$obj_user->set_username($_POST['username']);
$obj_user->set_email($_POST['email']);
$ret = $obj_user->register_user();
switch ( $ret ) {
case REGISTER_INVALID_USERNAME:
$msg = "Invalid username";
break;
case REGISTER_INVALID_EMAIL:
$msg = "Invalid email address";
break;
case REGISTER_USER_EXISTS:
$msg = "User already exists";
break;
case REGISTER_EMAIL_EXISTS:
$msg = "Email already taken.";
break;
case REGISTER_SUCCESS:
$msg = "Account created";
include('index.php');
return;
break;
}
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Untitled Document</title>
</head>
<body>
<?php
if ( isset ( $msg) ) {
echo $msg;
}
?>
<form action="<?php echo basename($_SERVER['PHP_SELF']);?>" method="post">
<p>Desired username: <input type="text" name="username" /></p>
<p>Your emailaddress: <input type="text" name="email" /></p>
<input type="submit" value="Register" />
</form>
</body>
</html>
// Laad alle benodigde classen automatisch
if ( ! function_exists('__autoload') ) {
function __autoload( $arg_class ) {
require_once("class.$arg_class.php");
}
}
// We hebben sessies nodig, dus maak deze aan
$obj_handler = clsSessionHandler::getInstance();
if (isset ($_POST['username'],$_POST['email'])) {
$obj_user = new clsUser();
$obj_user->set_username($_POST['username']);
$obj_user->set_email($_POST['email']);
$ret = $obj_user->register_user();
switch ( $ret ) {
case REGISTER_INVALID_USERNAME:
$msg = "Invalid username";
break;
case REGISTER_INVALID_EMAIL:
$msg = "Invalid email address";
break;
case REGISTER_USER_EXISTS:
$msg = "User already exists";
break;
case REGISTER_EMAIL_EXISTS:
$msg = "Email already taken.";
break;
case REGISTER_SUCCESS:
$msg = "Account created";
include('index.php');
return;
break;
}
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Untitled Document</title>
</head>
<body>
<?php
if ( isset ( $msg) ) {
echo $msg;
}
?>
<form action="<?php echo basename($_SERVER['PHP_SELF']);?>" method="post">
<p>Desired username: <input type="text" name="username" /></p>
<p>Your emailaddress: <input type="text" name="email" /></p>
<input type="submit" value="Register" />
</form>
</body>
</html>
sha.js:
Code (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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
/* SHA256 logical functions */
function rotateRight(n,x) {
return ((x >>> n) | (x << (32 - n)));
}
function choice(x,y,z) {
return ((x & y) ^ (~x & z));
}
function majority(x,y,z) {
return ((x & y) ^ (x & z) ^ (y & z));
}
function sha256_Sigma0(x) {
return (rotateRight(2, x) ^ rotateRight(13, x) ^ rotateRight(22, x));
}
function sha256_Sigma1(x) {
return (rotateRight(6, x) ^ rotateRight(11, x) ^ rotateRight(25, x));
}
function sha256_sigma0(x) {
return (rotateRight(7, x) ^ rotateRight(18, x) ^ (x >>> 3));
}
function sha256_sigma1(x) {
return (rotateRight(17, x) ^ rotateRight(19, x) ^ (x >>> 10));
}
function sha256_expand(W, j) {
return (W[j&0x0f] += sha256_sigma1(W[(j+14)&0x0f]) + W[(j+9)&0x0f] +
sha256_sigma0(W[(j+1)&0x0f]));
}
/* Hash constant words K: */
var K256 = new Array(
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
);
/* global arrays */
var ihash, count, buffer;
var sha256_hex_digits = "0123456789abcdef";
/* Add 32-bit integers with 16-bit operations (bug in some JS-interpreters:
overflow) */
function safe_add(x, y)
{
var lsw = (x & 0xffff) + (y & 0xffff);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xffff);
}
/* Initialise the SHA256 computation */
function sha256_init() {
ihash = new Array(8);
count = new Array(2);
buffer = new Array(64);
count[0] = count[1] = 0;
ihash[0] = 0x6a09e667;
ihash[1] = 0xbb67ae85;
ihash[2] = 0x3c6ef372;
ihash[3] = 0xa54ff53a;
ihash[4] = 0x510e527f;
ihash[5] = 0x9b05688c;
ihash[6] = 0x1f83d9ab;
ihash[7] = 0x5be0cd19;
}
/* Transform a 512-bit message block */
function sha256_transform() {
var a, b, c, d, e, f, g, h, T1, T2;
var W = new Array(16);
/* Initialize registers with the previous intermediate value */
a = ihash[0];
b = ihash[1];
c = ihash[2];
d = ihash[3];
e = ihash[4];
f = ihash[5];
g = ihash[6];
h = ihash[7];
/* make 32-bit words */
for(var i=0; i<16; i++)
W[i] = ((buffer[(i<<2)+3]) | (buffer[(i<<2)+2] << 8) | (buffer[(i<<2)+1]
<< 16) | (buffer[i<<2] << 24));
for(var j=0; j<64; j++) {
T1 = h + sha256_Sigma1(e) + choice(e, f, g) + K256[j];
if(j < 16) T1 += W[j];
else T1 += sha256_expand(W, j);
T2 = sha256_Sigma0(a) + majority(a, b, c);
h = g;
g = f;
f = e;
e = safe_add(d, T1);
d = c;
c = b;
b = a;
a = safe_add(T1, T2);
}
/* Compute the current intermediate hash value */
ihash[0] += a;
ihash[1] += b;
ihash[2] += c;
ihash[3] += d;
ihash[4] += e;
ihash[5] += f;
ihash[6] += g;
ihash[7] += h;
}
/* Read the next chunk of data and update the SHA256 computation */
function sha256_update(data, inputLen) {
var i, index, curpos = 0;
/* Compute number of bytes mod 64 */
index = ((count[0] >> 3) & 0x3f);
var remainder = (inputLen & 0x3f);
/* Update number of bits */
if ((count[0] += (inputLen << 3)) < (inputLen << 3)) count[1]++;
count[1] += (inputLen >> 29);
/* Transform as many times as possible */
for(i=0; i+63<inputLen; i+=64) {
for(var j=index; j<64; j++)
buffer[j] = data.charCodeAt(curpos++);
sha256_transform();
index = 0;
}
/* Buffer remaining input */
for(var j=0; j<remainder; j++)
buffer[j] = data.charCodeAt(curpos++);
}
/* Finish the computation by operations such as padding */
function sha256_final() {
var index = ((count[0] >> 3) & 0x3f);
buffer[index++] = 0x80;
if(index <= 56) {
for(var i=index; i<56; i++)
buffer[i] = 0;
} else {
for(var i=index; i<64; i++)
buffer[i] = 0;
sha256_transform();
for(var i=0; i<56; i++)
buffer[i] = 0;
}
buffer[56] = (count[1] >>> 24) & 0xff;
buffer[57] = (count[1] >>> 16) & 0xff;
buffer[58] = (count[1] >>> 8) & 0xff;
buffer[59] = count[1] & 0xff;
buffer[60] = (count[0] >>> 24) & 0xff;
buffer[61] = (count[0] >>> 16) & 0xff;
buffer[62] = (count[0] >>> 8) & 0xff;
buffer[63] = count[0] & 0xff;
sha256_transform();
}
/* Split the internal hash values into an array of bytes */
function sha256_encode_bytes() {
var j=0;
var output = new Array(32);
for(var i=0; i<8; i++) {
output[j++] = ((ihash[i] >>> 24) & 0xff);
output[j++] = ((ihash[i] >>> 16) & 0xff);
output[j++] = ((ihash[i] >>> 8) & 0xff);
output[j++] = (ihash[i] & 0xff);
}
return output;
}
/* Get the internal hash as a hex string */
function sha256_encode_hex() {
var output = new String();
for(var i=0; i<8; i++) {
for(var j=28; j>=0; j-=4)
output += sha256_hex_digits.charAt((ihash[i] >>> j) & 0x0f);
}
return output;
}
/* Main function: returns a hex string representing the SHA256 value of the
given data */
function sha256_digest(data) {
sha256_init();
sha256_update(data, data.length);
sha256_final();
return sha256_encode_hex();
}
/* test if the JS-interpreter is working properly */
function sha256_self_test()
{
return sha256_digest("message digest") ==
"f7846f55cf23e14eebeab5b4e1550cad5b509e3348fbc4efa3a1413d393cb650";
}
function rotateRight(n,x) {
return ((x >>> n) | (x << (32 - n)));
}
function choice(x,y,z) {
return ((x & y) ^ (~x & z));
}
function majority(x,y,z) {
return ((x & y) ^ (x & z) ^ (y & z));
}
function sha256_Sigma0(x) {
return (rotateRight(2, x) ^ rotateRight(13, x) ^ rotateRight(22, x));
}
function sha256_Sigma1(x) {
return (rotateRight(6, x) ^ rotateRight(11, x) ^ rotateRight(25, x));
}
function sha256_sigma0(x) {
return (rotateRight(7, x) ^ rotateRight(18, x) ^ (x >>> 3));
}
function sha256_sigma1(x) {
return (rotateRight(17, x) ^ rotateRight(19, x) ^ (x >>> 10));
}
function sha256_expand(W, j) {
return (W[j&0x0f] += sha256_sigma1(W[(j+14)&0x0f]) + W[(j+9)&0x0f] +
sha256_sigma0(W[(j+1)&0x0f]));
}
/* Hash constant words K: */
var K256 = new Array(
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
);
/* global arrays */
var ihash, count, buffer;
var sha256_hex_digits = "0123456789abcdef";
/* Add 32-bit integers with 16-bit operations (bug in some JS-interpreters:
overflow) */
function safe_add(x, y)
{
var lsw = (x & 0xffff) + (y & 0xffff);
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return (msw << 16) | (lsw & 0xffff);
}
/* Initialise the SHA256 computation */
function sha256_init() {
ihash = new Array(8);
count = new Array(2);
buffer = new Array(64);
count[0] = count[1] = 0;
ihash[0] = 0x6a09e667;
ihash[1] = 0xbb67ae85;
ihash[2] = 0x3c6ef372;
ihash[3] = 0xa54ff53a;
ihash[4] = 0x510e527f;
ihash[5] = 0x9b05688c;
ihash[6] = 0x1f83d9ab;
ihash[7] = 0x5be0cd19;
}
/* Transform a 512-bit message block */
function sha256_transform() {
var a, b, c, d, e, f, g, h, T1, T2;
var W = new Array(16);
/* Initialize registers with the previous intermediate value */
a = ihash[0];
b = ihash[1];
c = ihash[2];
d = ihash[3];
e = ihash[4];
f = ihash[5];
g = ihash[6];
h = ihash[7];
/* make 32-bit words */
for(var i=0; i<16; i++)
W[i] = ((buffer[(i<<2)+3]) | (buffer[(i<<2)+2] << 8) | (buffer[(i<<2)+1]
<< 16) | (buffer[i<<2] << 24));
for(var j=0; j<64; j++) {
T1 = h + sha256_Sigma1(e) + choice(e, f, g) + K256[j];
if(j < 16) T1 += W[j];
else T1 += sha256_expand(W, j);
T2 = sha256_Sigma0(a) + majority(a, b, c);
h = g;
g = f;
f = e;
e = safe_add(d, T1);
d = c;
c = b;
b = a;
a = safe_add(T1, T2);
}
/* Compute the current intermediate hash value */
ihash[0] += a;
ihash[1] += b;
ihash[2] += c;
ihash[3] += d;
ihash[4] += e;
ihash[5] += f;
ihash[6] += g;
ihash[7] += h;
}
/* Read the next chunk of data and update the SHA256 computation */
function sha256_update(data, inputLen) {
var i, index, curpos = 0;
/* Compute number of bytes mod 64 */
index = ((count[0] >> 3) & 0x3f);
var remainder = (inputLen & 0x3f);
/* Update number of bits */
if ((count[0] += (inputLen << 3)) < (inputLen << 3)) count[1]++;
count[1] += (inputLen >> 29);
/* Transform as many times as possible */
for(i=0; i+63<inputLen; i+=64) {
for(var j=index; j<64; j++)
buffer[j] = data.charCodeAt(curpos++);
sha256_transform();
index = 0;
}
/* Buffer remaining input */
for(var j=0; j<remainder; j++)
buffer[j] = data.charCodeAt(curpos++);
}
/* Finish the computation by operations such as padding */
function sha256_final() {
var index = ((count[0] >> 3) & 0x3f);
buffer[index++] = 0x80;
if(index <= 56) {
for(var i=index; i<56; i++)
buffer[i] = 0;
} else {
for(var i=index; i<64; i++)
buffer[i] = 0;
sha256_transform();
for(var i=0; i<56; i++)
buffer[i] = 0;
}
buffer[56] = (count[1] >>> 24) & 0xff;
buffer[57] = (count[1] >>> 16) & 0xff;
buffer[58] = (count[1] >>> 8) & 0xff;
buffer[59] = count[1] & 0xff;
buffer[60] = (count[0] >>> 24) & 0xff;
buffer[61] = (count[0] >>> 16) & 0xff;
buffer[62] = (count[0] >>> 8) & 0xff;
buffer[63] = count[0] & 0xff;
sha256_transform();
}
/* Split the internal hash values into an array of bytes */
function sha256_encode_bytes() {
var j=0;
var output = new Array(32);
for(var i=0; i<8; i++) {
output[j++] = ((ihash[i] >>> 24) & 0xff);
output[j++] = ((ihash[i] >>> 16) & 0xff);
output[j++] = ((ihash[i] >>> 8) & 0xff);
output[j++] = (ihash[i] & 0xff);
}
return output;
}
/* Get the internal hash as a hex string */
function sha256_encode_hex() {
var output = new String();
for(var i=0; i<8; i++) {
for(var j=28; j>=0; j-=4)
output += sha256_hex_digits.charAt((ihash[i] >>> j) & 0x0f);
}
return output;
}
/* Main function: returns a hex string representing the SHA256 value of the
given data */
function sha256_digest(data) {
sha256_init();
sha256_update(data, data.length);
sha256_final();
return sha256_encode_hex();
}
/* test if the JS-interpreter is working properly */
function sha256_self_test()
{
return sha256_digest("message digest") ==
"f7846f55cf23e14eebeab5b4e1550cad5b509e3348fbc4efa3a1413d393cb650";
}
test.login
Database:
Code (php)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
DROP TABLE IF EXISTS `sessions`;
CREATE TABLE `sessions` (
`data` varchar(500) NOT NULL,
`time` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
`session_id` varchar(255) NOT NULL,
`ip` varchar(12) NOT NULL,
`user` mediumint(8) unsigned NOT NULL,
PRIMARY KEY (`session_id`),
KEY `user` (`user`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `sessions` (
`data` varchar(500) NOT NULL,
`time` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
`session_id` varchar(255) NOT NULL,
`ip` varchar(12) NOT NULL,
`user` mediumint(8) unsigned NOT NULL,
PRIMARY KEY (`session_id`),
KEY `user` (`user`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`id` mediumint(8) unsigned NOT NULL auto_increment,
`username` varchar(30) NOT NULL,
`password` varchar(255) NOT NULL,
`startdate` timestamp NOT NULL default CURRENT_TIMESTAMP,
`email` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='InnoDB free: 8192 kB';
CREATE TABLE `users` (
`id` mediumint(8) unsigned NOT NULL auto_increment,
`username` varchar(30) NOT NULL,
`password` varchar(255) NOT NULL,
`startdate` timestamp NOT NULL default CURRENT_TIMESTAMP,
`email` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='InnoDB free: 8192 kB';