Multimag  0.2.992
authenticator.php
См. документацию.
1 <?php
2 
3 // MultiMag v0.2 - Complex sales system
4 //
5 // Copyright (C) 2005-2018, BlackLight, TND Team, http://tndproject.org
6 //
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
16 //
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 
26 
31 
36 
39 
40  protected $last_test = '';
41 
42  protected $sql_user_query = "SELECT `id`, `name`, `pass`, `pass_type`, `pass_expired`, `pass_date_change`,
43  `reg_email`, `reg_phone`, `reg_email_confirm`, `reg_phone_confirm`, `reg_email_subscribe`, `reg_phone_subscribe`,
44  `reg_date`, `disabled`, `disabled_reason`, `bifact_auth`, `jid`, `real_name`, `real_address`, `agent_id`,
45  `worker`, `worker_email`, `worker_email`, `worker_phone`, `worker_jid`, `worker_real_name`, `worker_real_address`, `worker_post_name`,
46  `last_session_id`
47  FROM `users`
48  LEFT JOIN `users_worker_info` ON `user_id`=`users`.`id` ";
49 
50  protected $user_info = null; // Кэш для данных подтверждения телефона/email
51 
52  public function __construct() {
53 
54  }
55 
56  protected function regEmailMsg($login, $pass, $conf) {
57  global $CONFIG;
59  $proto = 'http';
60  if (@$CONFIG['site']['force_https_login'] || @$CONFIG['site']['force_https']) {
61  $proto = 'https';
62  }
63  return
64  "Вы получили это письмо потому, что в заявке на регистрацию на сайте http://{$pref->site_name} был указан Ваш адрес электронной почты. ".
65  "Для продолжения регистрации, введите пожалуйста, следующий код подтверждения:\n".
66  "{$conf}\n".
67  "или перейдите по ссылке $proto://{$pref->site_name}/login.php?mode=conf&login={$login}&e={$conf} .\n".
68  "Если не переходить по ссылке (например, если заявка подана не Вами), то регистрационные данные будут автоматически удалены через неделю.\n\n".
69  "Ваш аккаунт:\n".
70  "Логин: $login\n".
71  "Пароль: $pass\n\n".
72  "После подтверждения регистрации Вы сможете получить доступ к расширенным функциям сайта. Неактивные аккаунты удаляются через 6 месяцев.\n\n".
73  "------------------------------------------------------------------------------------------\n\n".
74  "You have received this letter because in the form of registration in a site http://{$pref->site_name} your e-mail address has been entered. ".
75  "For continue of registration, please enter this key:\n".
76  "$conf\n".
77  "or pass under the link $proto://{$pref->site_name}/login.php?mode=conf&login=$login&e=$conf .\n".
78  "If not going under the reference (for example if the form is submitted not by you) registration data will be automatically removed after a week.\n\n".
79  "Your account:\n".
80  "Login: $login\n".
81  "Pass: $pass\n\n".
82  "After confirmatoin of registration you can get access to the expanded functions of a site. Inactive accounts leave in 6 months.\n\n".
83  "------------------------------------------------------------------------------------------\n".
84  "Сообщение сгенерировано автоматически, отвечать на него не нужно!\n".
85  "The message is generated automatically, to answer it is not necessary!";
86  }
87 
88  public function testPassword($password) {
89  if(! @$this->user_info['pass'] ) {
90  return false;
91  }
92  switch($this->user_info['pass_type']) {
93  case 'CRYPT':
94  if(crypt($password, $this->user_info['pass']) === $this->user_info['pass']) {
95  return true;
96  }
97  break;
98  case 'SHA1':
99  if (SHA1($password) === $this->user_info['pass']) {
100  return true;
101  }
102  break;
103  default:
104  if (MD5($password) === $this->user_info['pass']) {
105  return true;
106  }
107  }
108  return false;
109  }
110 
111  public function register($login, $email, $subs_email, $phone, $subs_phone, $captcha) {
112  global $db, $CONFIG;
113  $ret = array();
114  $subs_email = $subs_email?1:0;
115  $subs_phone = $subs_phone?1:0;
116 
117  $db->startTransaction();
118  // Проверка допустимости логина
119  if ($login == '') {
120  $ret['login'] = 'Поле login не заполнено';
121  } elseif (strlen($login) < 3) {
122  $ret['login'] = 'login слишком короткий';
123  } elseif (strlen($login) > 24) {
124  $ret['login'] = 'login слишком длинный';
125  } elseif (!preg_match('/^[a-zA-Z\d]*$/', $login)) {
126  $ret['login'] = 'login должен состоять только из латинских букв и цифр';
127  } else {
128  $sql_login = $db->real_escape_string($login);
129  $res = $db->query("SELECT `id` FROM `users` WHERE `name`='$sql_login'");
130  if ($res->num_rows) {
131  $ret['login'] = 'Такой login занят. Используйте другой.';
132  }
133  }
134  // Проверка наличия телефона или email
135  if (@$CONFIG['site']['allow_phone_regist']) {
136  if ($email == '' && $phone == '') {
137  $ret['email'] = 'Нужно заполнить телефон или email';
138  }
139  }
140  else {
141  if ($email == '') {
142  $ret['email'] = 'Поле email не заполнено';
143  }
144  }
145  // Проверка допустимости email
146  if ($email != '') {
147  if (!preg_match('/^\w+([-\.\w]+)*\w@\w(([-\.\w])*\w+)*\.\w{2,8}$/', $email)) {
148  $ret['email'] = 'Неверный формат адреса e-mail. Адрес должен быть в формате user@host.zone';
149  } else {
150  $res = $db->query("SELECT `id` FROM `users` WHERE `reg_email`='$email'");
151  if ($res->num_rows) {
152  // TODO: предложить восстановить доступ
153  $ret['email'] = 'Пользователь с таким email уже зарегистрирован. Используйте другой.';
154  }
155  }
156  }
157  // Проверка допустимости номера телефона
158  if ($phone != '') {
159  $phone = '+7' . $phone;
160  if (!preg_match('/^\+79\d{9}$/', $phone)) {
161  $phone = normalizePhone($phone);
162  if ($phone === false) {
163  $ret['phone'] = 'Неверный формат телефона. Номер должен быть в федеральном формате +79XXXXXXXXX ';
164  } else {
165  $res = $db->query("SELECT `id` FROM `users` WHERE `reg_phone`='$phone'");
166  if ($res->num_rows) {
167  // TODO: предложить восстановить доступ
168  $ret['phone'] = 'Пользователь с таким телефоном уже зарегистрирован. Используйте другой.';
169  }
170  }
171  } else {
172  $res = $db->query("SELECT `id` FROM `users` WHERE `reg_phone`='$phone'");
173  if ($res->num_rows) {
174  // TODO: предложить восстановить доступ
175  $ret['phone'] = 'Пользователь с таким телефоном уже зарегистрирован. Используйте другой.';
176  }
177  }
178  }
179  // Проверка капчи
180  if ($captcha == '') {
181  $ret['captcha'] = 'Код подтверждения не введён';
182  }
183  if (strtoupper($_SESSION['captcha_keystring']) != strtoupper($captcha)) {
184  $ret['captcha'] = 'Код подтверждения введён неверно';
185  }
186 
187  // Были ли ошибки
188  if(count($ret)) {
189  return $ret;
190  }
191 
192  // Подготовка к созданию учётной записи
193  $email_conf = $email ? substr(MD5(time() + rand(0, 1000000)), 0, 8) : '';
194  $phone_conf = $phone ? rand(1000, 99999) : '';
195 
196  $sql_login = $db->real_escape_string($login);
197  $sql_email = $db->real_escape_string($email);
198  $sql_phone = $db->real_escape_string($phone);
199  list($pass_type, $pass, $pass_hash) = $this->generatePasswordData();
200 
201  $user_data = array(
202  'name' => $sql_login,
203  'pass' => $pass_hash,
204  'pass_type' => $pass_type,
205  'pass_date_change' => date("Y-m-d H:i:s"),
206  'reg_email' => $sql_email,
207  'reg_email_confirm' => $email_conf,
208  'reg_email_subscribe' => $subs_email,
209  'reg_phone' => $phone,
210  'reg_phone_confirm' => $phone_conf,
211  'reg_date' => date("Y-m-d H:i:s")
212  );
213 
214  $user_id = $db->insertA('users', $user_data);
215  $this->loadDataForID($user_id);
216  if ($email) {
217  $msg = $this->regEmailMsg($login, $pass, $email_conf);
219  mailto($email, "Регистрация на {$pref->site_name}", $msg);
220  }
221 
222  if ($phone) {
223  $this->sendConfirmSMS($phone_conf, "\r\nЛогин:$login\r\nПароль:$pass");
224  }
225  $db->commit();
226  return false;
227  }
228 
229  public function createUser($login, $email, $is_verifed_email, $phone, $confirm_phone, $real_name='') {
230  global $db;
231  list($pass_type, $pass, $pass_hash) = $this->generatePasswordData();
232  $sql_login = $db->real_escape_string($login);
233  $sql_email = $db->real_escape_string($email);
234  $sql_phone = $db->real_escape_string($phone);
235  $sql_real_name = $db->real_escape_string($real_name);
236  $user_data = array(
237  'name' => $sql_login,
238  'pass' => $pass_hash,
239  'pass_type' => $pass_type,
240  'pass_date_change' => date("Y-m-d H:i:s"),
241  'reg_email' => $sql_email,
242  'reg_email_confirm' => ($email&&$is_verifed_email)?1:'',
243  'reg_email_subscribe' => $email?1:0,
244  'reg_phone' => $sql_phone,
245  'reg_phone_confirm' => ($phone&&$confirm_phone)?1:'',
246  'reg_date' => date("Y-m-d H:i:s"),
247  'real_name' => $sql_real_name
248  );
249  $user_id = $db->insertA('users', $user_data);
250 
251 
252  if($email) {
253  if($is_verifed_email) {
254  $this->sendRegInfoEmail($login, $pass, $email);
255  } else {
256  $code = $this->getNewConfirmEmailCode();
257  $this->sendConfirmEmail($code);
258  }
259  }
260  return $user_id;
261  }
262 
263  public function generatePasswordData() {
264  global $CONFIG;
265  $pass = keygen_unique(0, 8, 11);
266  if (@$CONFIG['site']['pass_type'] == 'MD5') {
267  $pass_hash = MD5($pass);
268  $pass_type = 'MD5';
269  } else if (@$CONFIG['site']['pass_type'] == 'SHA1') {
270  $pass_hash = SHA1($pass);
271  $pass_type = 'SHA1';
272  } else {
273  if (CRYPT_SHA256 == 1) {
274  $salt = '';
275  for($i=0;$i<16;$i++) {
276  $salt .= chr(rand(0, 255));
277  }
278  $salt = substr(base64_encode($salt), 16);
279  $pass_hash = crypt($pass, '$5$' . $salt . '$');
280  } else {
281  $pass_hash = crypt($pass);
282  }
283  $pass_type = 'CRYPT';
284  }
285  return array($pass_type, $pass, $pass_hash);
286  }
287 
288  public function getNewConfirmPhoneCode() {
289  global $db;
290  $code = rand(1000, 99999);
291  $db->update('users', $this->user_info['id'], 'reg_phone_confirm', $code);
292  $this->user_info['reg_phone_confirm'] = $code;
293  return $code;
294  }
295 
296  public function getNewConfirmEmailCode() {
297  global $db;
298  $code = substr(MD5(time() + rand(0, 1000000)), 0, 8);
299  $db->update('users', $this->user_info['id'], 'reg_email_confirm', $code);
300  $this->user_info['reg_email_confirm'] = $code;
301  return $code;
302  }
303 
304  public function sendConfirmSMS($code, $ext_text = 'Никому не сообщайте.') {
305  global $CONFIG;
307  require_once('include/sendsms.php');
308  $sender = new SMSSender();
309  $sender->setNumber($this->user_info['reg_phone']);
310  $sender->setContent("Код подтверждения: $code\r\n$ext_text\r\n{$pref->site_name}");
311  $sender->send();
312  }
313 
314  public function sendConfirmEmail($code) {
315  global $CONFIG;
317  $proto = 'http';
318  if ($CONFIG['site']['force_https_login'] || $CONFIG['site']['force_https']) {
319  $proto = 'https';
320  }
321  $msg = "Поступил запрос на установку email адреса на сайте {$pref->site_name} для аккаунта {$this->user_info['name']}."
322  . "\nЕсли аккаунт Ваш, и вы действительно хотите установить адрес, перейдите по ссылке:"
323  . "\n$proto://{$pref->site_name}/login.php?mode=conf&login={$this->user_info['name']}&e={$code} ,"
324  . "\nлибо введите код подтверждения:"
325  . "\n{$code}"
326  . "\nЕсли аккаунт Вам не принадлежит, проигнорируйте письмо."
327  . "\n----------------------------------------"
328  . "\nСообщение сгенерировано автоматически, отвечать на него не нужно!";
329  mailto($this->user_info['reg_email'], "Смена регистрационного email адреса", $msg);
330  }
331 
332  protected function sendRegInfoEmail($login, $pass, $email) {
333  global $CONFIG;
335  $proto = 'http';
336  if (@$CONFIG['site']['force_https_login'] || @$CONFIG['site']['force_https']) {
337  $proto = 'https';
338  }
339  $msg =
340  "Вы успешно зарегистрировались на сайте http://{$pref->site_name} !\n".
341  "Ваш аккаунт:\n".
342  "Логин: $login\n".
343  "Пароль: $pass\n\n".
344  "------------------------------------------------------------------------------------------\n\n".
345  "You register in a site http://{$pref->site_name} !\n".
346  "Your account:\n".
347  "Login: $login\n".
348  "Pass: $pass\n\n".
349  "------------------------------------------------------------------------------------------\n".
350  "Сообщение сгенерировано автоматически, отвечать на него не нужно!\n".
351  "The message is generated automatically, to answer it is not necessary!";
352  mailto($email, "Успешная регистрация на сайте", $msg);
353  }
354 
355  public function sendPassChangeEmail($user_id, $login, $session_key, $email) {
356  global $db, $CONFIG;
358  settype($user_id, 'int');
359  $db->query("START TRANSACTION");
360  $key = substr(md5($user_id . $email . time() . rand(0, 1000000)), 8);
361  $proto = 'http';
362  if ($CONFIG['site']['force_https_login'] || $CONFIG['site']['force_https']) {
363  $proto = 'https';
364  }
365  $res = $db->query("UPDATE `users` SET `pass_change`='$key' WHERE `id`='$user_id'");
366  $msg = "Поступил запрос на смену забытого пароля доступа к сайту {$pref->site_name} для аккаунта $login.\nЕсли Вы действительно хотите сменить пароль, перейдите по ссылке\n$proto://{$pref->site_name}/login.php?mode=rem&step=3&key=$session_key&s=$key ,\nлибо введите код подтверждения:\n$key\n----------------------------------------\nСообщение сгенерировано автоматически, отвечать на него не нужно!";
367  mailto($email, "Смена забытого пароля", $msg);
368  $db->query("COMMIT");
369  }
370 
371  public function sendPassChangeSms($user_id, $login, $session_key, $phone) {
372  global $db, $CONFIG;
374  settype($user_id, 'int');
375  require_once('include/sendsms.php');
376  $db->query("START TRANSACTION");
377  $key = rand(10000, 99999999);
378  $res = $db->query("UPDATE `users` SET `pass_change`='$key' WHERE `id`='$user_id'");
379 
380  $sender = new SMSSender();
381  $sender->setNumber($phone);
382  $sender->setContent("$login, Ваш код: $key\n{$pref->site_name}");
383  $sender->send();
384  $db->query("COMMIT");
385  }
386 
387  public function loadDataForLogin($login) {
388  global $db;
389  if(is_array($this->user_info)) {
390  if($this->user_info['name'] === $login) {
391  return true;
392  }
393  }
394  $sql_login = $db->real_escape_string($login);
395  $res = $db->query($this->sql_user_query . " WHERE `name`='$sql_login'");
396  if($res->num_rows) {
397  $this->user_info = $res->fetch_assoc();
398  return true;
399  }
400  return false;
401  }
402 
403  public function loadDataForID($user_id) {
404  global $db;
405  if(is_array($this->user_info)) {
406  if($this->user_info['id'] == $user_id) {
407  return true;
408  }
409  }
410  settype($user_id, 'int');
411  $res = $db->query($this->sql_user_query . " WHERE `id`='$user_id'");
412  if($res->num_rows) {
413  $this->user_info = $res->fetch_assoc();
414  return true;
415  }
416  return false;
417  }
418 
419  public function tryConfirmEmail($confirm_key) {
420  global $db;
421  if($this->isNeedConfirmEmail() && $confirm_key && $confirm_key == $this->user_info['reg_email_confirm']) {
422  $db->update('users', $this->user_info['id'], 'reg_email_confirm', 1);
423  $this->user_info['reg_email_confirm'] = 1;
424  return true;
425  }
426  return false;
427  }
428 
429  public function tryConfirmPhone($confirm_key) {
430  global $db;
431  if($this->isNeedConfirmPhone() && $confirm_key && $confirm_key == $this->user_info['reg_phone_confirm']) {
432  $db->update('users', $this->user_info['id'], 'reg_phone_confirm', 1);
433  $this->user_info['reg_phone_confirm'] = 1;
434  return true;
435  }
436  return false;
437  }
438 
439  public function isNeedConfirmEmail() {
440  if($this->user_info['reg_email'] && $this->user_info['reg_email_confirm']!=1) {
441  return true;
442  }
443  return false;
444  }
445 
446  public function isNeedConfirmPhone() {
447  if($this->user_info['reg_phone'] && $this->user_info['reg_phone_confirm']!=1) {
448  return true;
449  }
450  return false;
451  }
452 
454  public function isConfirmed() {
455  if($this->user_info['reg_email'] && $this->user_info['reg_email_confirm']==1) {
456  return true;
457  }
458  if($this->user_info['reg_phone'] && $this->user_info['reg_phone_confirm']==1) {
459  return true;
460  }
461  return false;
462  }
463 
465  public function isDisabled() {
466  return $this->user_info['disabled'] ? true : false;
467  }
468 
469  // Просрочен ли пароль у пользователя
470  public function isExpired() {
471  global $CONFIG;
472  if($this->user_info['pass_expired']) {
473  return true;
474  }
475  if(isset($CONFIG['site']['user_pass_period'])) {
476  if($CONFIG['site']['user_pass_period']) {
477  $pc_time = strtotime($this->user_info['pass_date_change']);
478  if( $pc_time < time()-$CONFIG['site']['user_pass_period']*60*60*24 ) {
479  return true;
480  }
481  }
482  }
483  if($this->user_info['worker']) {
484  if(isset($CONFIG['site']['worker_pass_period'])) {
485  if($CONFIG['site']['worker_pass_period']) {
486  $pc_time = strtotime($this->user_info['pass_date_change']);
487  if( $pc_time < time()-$CONFIG['site']['worker_pass_period']*60*60*24 ) {
488  return true;
489  }
490  }
491  } else {
492  $pc_time = strtotime($this->user_info['pass_date_change']);
493  if( $pc_time < time()-90*60*60*24 ) {
494  return true;
495  }
496  }
497  }
498  return false;
499  }
500 
501  // Определение кол-ва дней до окончания срока действия пароля
502  public function getDaysExpiredAfter() {
503  global $CONFIG;
504  if($this->user_info['pass_expired']) {
505  return 0;
506  }
507  if(isset($CONFIG['site']['user_pass_period'])) {
508  if($CONFIG['site']['user_pass_period']) {
509  $pc_time = strtotime($this->user_info['pass_date_change']);
510  $exp_time = floor($CONFIG['site']['user_pass_period'] - (time() - $pc_time)/60/60/24);
511  if($exp_time < 0) {
512  $exp_time = 0;
513  }
514  return $exp_time;
515  }
516  }
517  if($this->user_info['worker']) {
518  if(isset($CONFIG['site']['worker_pass_period'])) {
519  if($CONFIG['site']['worker_pass_period']) {
520  $pc_time = strtotime($this->user_info['pass_date_change']);
521  $exp_time = floor($CONFIG['site']['worker_pass_period'] - (time() - $pc_time)/60/60/24);
522  if($exp_time < 0) {
523  $exp_time = 0;
524  }
525  return $exp_time;
526  }
527  } else {
528  $pc_time = strtotime($this->user_info['pass_date_change']);
529  $exp_time = floor(90 - (time() - $pc_time)/60/60/24);
530  if($exp_time < 0) {
531  $exp_time = 0;
532  }
533  return $exp_time;
534  }
535  }
536  return 999999;
537  }
538 
539  public function getDisabledReason() {
540  return $this->user_info['disabled_reason'];
541  }
542 
543  public function getRegEmail() {
544  return $this->user_info['reg_email'];
545  }
546 
547  public function getRegPhone() {
548  return $this->user_info['reg_phone'];
549  }
550 
551  public function getUserInfo() {
552  return $this->user_info;
553  }
554 
555  public function authenticate($type) {
556  global $db;
557  $this->addHistoryLine($type);
558  $db->update('users', $this->user_info['id'], 'last_session_id', session_id());
559  unset($_SESSION['another_device']);
560  $_SESSION['uid'] = $this->user_info['id'];
561  $_SESSION['name'] = $this->user_info['name'];
562  }
563 
564  public function addHistoryLine($auth_method) {
565  global $db;
566  $user_id = intval($this->user_info['id']);
567  $ip = $db->real_escape_string(getenv("REMOTE_ADDR"));
568  $ua = $db->real_escape_string($_SERVER['HTTP_USER_AGENT']);
569  $m = $db->real_escape_string($auth_method);
570  $db->query("INSERT INTO `users_login_history` (`user_id`, `date`, `ip`, `useragent`, `method`)
571  VALUES ($user_id, NOW(), '$ip', '$ua', '$m')");
572  }
573 
574  // Проверяет пароль на наличие недопустимых (с кодом > 127 или < 32) символов, и длину
575  public function isCorrectPassword($pass) {
576  $len = strlen($pass);
577  if($len<8) {
578  return false;
579  }
580  for($i=0;$i<$len;$i++) {
581  if( ord($pass[$i])>127 || ord($pass[$i])<32 ) {
582  return false;
583  }
584  }
585  return true;
586  }
587 
588  public function setPassword($password) {
589  global $CONFIG, $db;
590  if(!@$this->user_info['id']) {
591  throw new \Exception("Не загружен профиль пользователя");
592  }
593  if (@$CONFIG['site']['pass_type'] == 'MD5') {
594  $pass_hash = MD5($password);
595  $sql_pass_type = 'MD5';
596  } else if (@$CONFIG['site']['pass_type'] == 'SHA1') {
597  $pass_hash = SHA1($password);
598  $sql_pass_type = 'SHA1';
599  } else {
600  if (CRYPT_SHA256 == 1) {
601  $salt = '';
602  for ($i = 0; $i < 16; $i++) {
603  $salt .= chr(rand(48, 122));
604  }
605  $pass_hash = crypt($password, '$5$' . $salt . '$');
606  } else {
607  $pass_hash = crypt($password);
608  }
609  $sql_pass_type = 'CRYPT';
610  }
611  $sql_pass_hash = $db->real_escape_string($pass_hash);
612  $db->query("UPDATE `users` SET `pass`='$sql_pass_hash', `pass_type`='$sql_pass_type', `pass_change`='', `pass_date_change`=NOW(), `pass_expired`=0
613  WHERE `id`='{$this->user_info['id']}'");
614  $this->addHistoryLine('chpwd');
615  }
616 
617  public function setRegEmail($email) {
618  global $db;
619  if(!@$this->user_info['id']) {
620  throw new \Exception("Не загружен профиль пользователя");
621  }
622  $sql_email = $db->real_escape_string($email);
623  $db->query("UPDATE `users` SET `reg_email`='$sql_email', `reg_email_confirm`='0'
624  WHERE `id`='{$this->user_info['id']}'");
625  $this->user_info['reg_email'] = $email;
626  $this->user_info['reg_email_confirm'] = 0;
627  $this->addHistoryLine('chemail');
628  }
629 
630  public function setRegPhone($phone) {
631  global $db;
632  if(!@$this->user_info['id']) {
633  throw new \Exception("Не загружен профиль пользователя");
634  }
635  $sql_phone = $db->real_escape_string($phone);
636  $db->query("UPDATE `users` SET `reg_phone`='$sql_phone', `reg_phone_confirm`='0'
637  WHERE `id`='{$this->user_info['id']}'");
638  $this->user_info['reg_phone'] = $phone;
639  $this->user_info['reg_phone_confirm'] = 0;
640  $this->addHistoryLine('chphone');
641  }
642 
643  public function attackTest($ip) {
644  global $db;
645  $need_captcha = 0;
646 
647  $sql = 'SELECT `id` FROM `users_bad_auth`';
648  $ip_sql = $db->real_escape_string($ip);
649 
650  $tm = time() - 60 * 60 * $this->ip_ban_attemps_interval;
651  $res = $db->query("$sql WHERE `ip`='$ip_sql' AND `time`>'$tm'");
652  if ($res->num_rows >= $this->ip_ban_attemps_limit) { // Более ip_ban_attemps_limit ошибок вводе пароля c данного IP за последние 3 часа. Блокируем аутентификацию.
653  return 'ban_ip';
654  }
655  $tm = time() - 60 * 60 * $this->ip_captcha_attemps_interval;
656  $res = $db->query("$sql WHERE `ip`='$ip_sql' AND `time`>'$tm'");
657  if ($res->num_rows >= $this->ip_captcha_attemps_limit) { // Более двух ошибок ввода пароля c данного IP за последние 30 минут. Планируем запрос captcha.
658  $need_captcha = 1;
659  }
660 
661  $ip_a = explode(".", $ip);
662  if (!is_array($ip_a)) { // Если IP не удаётся разделить на элементы - завершаем тест
663  if($need_captcha) {
664  return $this->last_test = 'captcha';
665  } else {
666  return $this->last_test = 'ok';
667  }
668  }
669  if (count($ip_a) < 2) { // Если IP не удаётся разделить на элементы - завершаем тест
670  if($need_captcha) {
671  return $this->last_test = 'captcha';
672  } else {
673  return $this->last_test = 'ok';
674  }
675  }
676 
677  $net24 = intval($ip_a[0]).'.'.intval($ip_a[1]).'.'.intval($ip_a[2]).'.%';
678  $net16 = intval($ip_a[0]).'.'.intval($ip_a[1]).'.%';
679 
680  $tm = time() - 60 * 60 * $this->net24_ban_attemps_interval;
681  $res = $db->query("$sql WHERE `ip` LIKE '$net24' AND `time`>'$tm'");
682  if ($res->num_rows > $this->net24_ban_attemps_limit) { // Более 100 ошибок вводе пароля c подсети /24 за последние 3 часа. Блокируем аутентификацию.
683  return 'ban_net';
684  }
685  $tm = time() - 60 * 60 * $this->net24_captcha_attemps_interval;
686  $res = $db->query("$sql WHERE `ip` LIKE '$net24' AND `time`>'$tm'");
687  if ($res->num_rows > $this->net24_captcha_attemps_limit) { // Более 6 ошибок ввода пароля c подсети /24 за последние 30 минут. Планируем запрос captcha.
688  $need_captcha = 1;
689  }
690 
691  $tm = time() - 60 * 60 * $this->net16_ban_attemps_interval;
692  $res = $db->query("$sql WHERE `ip` LIKE '$net16' AND `time`>'$tm'");
693  if ($res->num_rows > $this->net16_ban_attemps_limit) { // Более 500 ошибок вводе пароля c подсети /16 за последние 3 часа. Блокируем аутентификацию.
694  return 'ban_net';
695  }
696  $tm = time() - 60 * 60 * $this->net16_captcha_attemps_interval;
697  $res = $db->query("$sql WHERE `ip` LIKE '$net16' AND `time`>'$tm'");
698  if ($res->num_rows > $this->net16_captcha_attemps_limit) { // Более 30 ошибок ввода пароля c подсети /16 за последние 30 минут. Планируем запрос captcha.
699  $need_captcha = 1;
700  }
701 
702  $tm = time() - 60 * 60 * $this->all_captcha_attemps_interval;
703  $res = $db->query("$sql WHERE `time`>'$tm'");
704  if ($res->num_rows > $this->all_captcha_attemps_limit) { // Более 100 ошибок ввода пароля со всей сети за последние 15 минут. Планируем запрос captcha.
705  $need_captcha = 1;
706  }
707 
708  if($need_captcha) {
709  return $this->last_test = 'captcha';
710  } else {
711  return $this->last_test = 'ok';
712  }
713  }
714 
715 }
tryConfirmPhone($confirm_key)
$res
Definition: fixer.php:178
sendConfirmSMS($code, $ext_text= 'Никому не сообщайте.')
$i
Definition: images.php:25
$password
Definition: 1c_sync.php:32
Класс аутентификации и регистрации
static getInstance()
Definition: pref.php:70
setPassword($password)
$captcha
Definition: c_img.php:62
$pref
Definition: counter.php:49
regEmailMsg($login, $pass, $conf)
mailto($email, $subject, $msg, $from="")
isCorrectPassword($pass)
createUser($login, $email, $is_verifed_email, $phone, $confirm_phone, $real_name='')
testPassword($password)
isConfirmed()
Подтверждён ли аккаунт хотя бы одним способом
$tm
Definition: backup.php:52
setRegPhone($phone)
keygen_unique($num=0, $minlen=5, $maxlen=12)
Генератор псевдоуникального кода.
Definition: core.php:148
$_SESSION['uid']
Definition: 1c_sync.php:65
sendPassChangeSms($user_id, $login, $session_key, $phone)
$db
setRegEmail($email)
loadDataForLogin($login)
$ip
Definition: 1c_sync.php:38
normalizePhone($phone)
Нормализация номера телефона
Definition: core.php:99
sendPassChangeEmail($user_id, $login, $session_key, $email)
addHistoryLine($auth_method)
tryConfirmEmail($confirm_key)
sendRegInfoEmail($login, $pass, $email)
sendConfirmEmail($code)
isDisabled()
Заблокирован ли аккаунт
$CONFIG['site']['admin_name']
loadDataForID($user_id)