1
login.php in trunk/web – MultiMag

source: trunk/web/login.php @ 261

Last change on this file since 261 was 261, checked in by blacklight, 7 years ago
  • Улучшена производительность счётчика посещений
  • Добавлена подсветка отгруженных заявок в журнале документов
File size: 23.3 KB
Line 
1<?php
2
3//      MultiMag v0.1 - Complex sales system
4//
5//      Copyright (C) 2005-2010, 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//
20
21include_once("core.php");
22$login=@htmlentities($_POST['login'],ENT_QUOTES);
23$pass=@htmlentities($_POST['pass'],ENT_QUOTES);
24
25function attack_test()
26{
27        $lock=0;
28        $captcha=0;
29        $ip=getenv("REMOTE_ADDR");
30        $sql='SELECT `id` FROM `users_bad_auth`';
31       
32        $tm=time()-60*60*3;
33        $res=mysql_query("$sql WHERE `ip`='$ip' AND `time`>'$tm'");
34       
35        if(mysql_num_rows($res)>20)     return 2;       // Lock
36        $tm=time()-60*5;
37        $res=mysql_query("$sql WHERE `ip`='$ip' AND `time`>'$tm'");
38        if(mysql_num_rows($res)>2)      $captcha=1;
39       
40        $ip_a=explode(".",$ip);
41       
42        $tm=time()-60*60*3;
43        $res=mysql_query("$sql WHERE `ip`='$ip_a[0].$ip_a[1].$ip_a[2].%' AND `time`>'$tm'");
44        if(mysql_num_rows($res)>100)    return 3;       // Lock
45        $tm=time()-60*5;
46        $res=mysql_query("$sql WHERE `ip`='$ip_a[0].$ip_a[1].$ip_a[2].%' AND `time`>'$tm'");
47        if(mysql_num_rows($res)>6)      $captcha=1;
48       
49        $tm=time()-60*60*3;
50        $res=mysql_query("$sql WHERE `ip`='$ip_a[0].$ip_a[1].%' AND `time`>'$tm'");
51        if(mysql_num_rows($res)>500)    return 3;       // Lock
52        $tm=time()-60*5;
53        $res=mysql_query("$sql WHERE `ip`='$ip_a[0].$ip_a[1].%' AND `time`>'$tm'");
54        if(mysql_num_rows($res)>30)     $captcha=1;
55       
56        $tm=time()-60*5;
57        $res=mysql_query("$sql WHERE `time`>'$tm'");
58        if(mysql_num_rows($res)>100)    $captcha=1;
59       
60        return $captcha;       
61}
62
63function regMsg($login, $pass, $conf)
64{
65        global $CONFIG;
66        $proto='http';
67        if($CONFIG['site']['force_https_login'] || $CONFIG['site']['force_https'])      $proto='https';
68return "Вы получили это письмо потому, что в заявке на регистрацию на сайте http://{$CONFIG['site']['name']} был указан Ваш адрес электронной почты. Для продолжения регистрации введите следующий код подтверждения:
69$conf
70или перейдите по ссылке $proto://{$CONFIG['site']['name']}/login.php?mode=conf&s=$conf .
71Если не переходить по ссылке (например, если заявка подана не Вами), то регистрационные данные будут автоматически удалены через неделю.
72Ваш аккаунт:
73Логин: $login
74Пароль: $pass
75
76После подтверждения регистрации Вы сможете получить доступ к расширенным функциям сайта. Неактивные аккаунты удаляются через 6 месяцев.
77
78------------------------------------------------------------------------------------------
79
80You have received this letter because in the form of registration in a site http://{$CONFIG['site']['name']} your e-mail address has been entered. For continuation of registration enter this key:
81$conf
82or pass under the link $proto://{$CONFIG['site']['name']}/login.php?mode=conf&s=$conf .  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.
83Your account:
84login: $login
85pass: $pass
86
87After confirmatoin of registration you can get access to the expanded functions of a site. Inactive accounts leave in 6 months.
88
89------------------------------------------------------------------------------------------
90Сообщение сгенерировано автоматически, отвечать на него не нужно!
91The message is generated automatically, to answer it is not necessary!";
92}
93
94class RegException extends Exception
95{
96        var $target;
97        function __construct($text='', $target='')
98        {
99                parent::__construct($text);     
100                $this->target=$target;
101        }
102
103}
104
105function RegForm($err_target='', $err_msg='')
106{
107        global $CONFIG, $tmpl;
108        $login=rcv('login');
109        $email=rcv('email');
110       
111        $err_msgs=array('login'=>'', 'email'=>'','img'=>'');
112        $err_msgs[$err_target]="<div style='color: #c00'>$err_msg</div>";
113       
114        $form_action='/login.php';
115        if($CONFIG['site']['force_https_login'])
116        {
117                $host=$_SERVER['HTTP_HOST'];
118                $qs=explode('/',$query);
119                $form_action='https://'.$host.'/login.php';
120        }
121
122        $tmpl->AddText("<p id='text'>
123        Для использования всех возможностей этого сайта, необходимо пройти процедуру регистрации. Регистрация не сложная,
124        и займёт всего несколько минут. Все зарегистрированные пользователи автоматически получают возможность приобретать товар по специальным ценам!</p>
125        <p>Регистрируясь, Вы даёте согласие на хранение, обработку и публикацию своей персональной информации, в соответствии с законом &quot;О персональных данных&quot;.</p>
126        <form action='$form_action' method='post' id='reg-form'>
127        <h2>Для регистрации заполните следующую форму:</h2>
128        <input type='hidden' name='mode' value='regs'>
129        <table>
130        <tr><td width='50%'>
131        Ваш login
132        <div class='mini'>
133        имя, которое Вы будете использовать для входа на сайт:
134        <br>должен состоять из латинских букв и цифр, начинаться с буквы, иметь длину от 3 до 24 символов
135        </div>
136        <td>
137        <input type='text' name='login' value='$login'>{$err_msgs['login']}
138        <tr><td>
139        Адрес электронной почты e-mail<br>
140        <div class='mini'>в формате user@host.zone</div>
141        <td><input type='text' name='email' value='$email'>{$err_msgs['email']}
142        <tr><td><td><input type='checkbox' name='subs' value='1' checked>Подписаться на новости и другую информацию
143        <tr><td>
144        Введите код подтверждения, изображенный на картинке:<br>
145        <img src='/kcaptcha/index.php'><br>
146        <td>
147        <input type='text' name='img'>{$err_msgs['img']}
148        <tr><td style='color: #c00;'><td>
149        <button type='submit'>Далее &gt;&gt;</button>
150        </form>
151        </table>");
152}
153
154if($mode=='')
155{
156        $opt=rcv('opt');
157        $img=rcv('img');
158        $login=rcv('login');
159        $pass=rcv('pass');
160        if(@$_SESSION['uid'])
161        {
162                include("user.php");
163                exit();
164        }
165       
166        // Куда переходить после авторизации
167        $from=getenv("HTTP_REFERER");
168        if($from)
169        {
170                $froma=explode("/",$from);
171                $proto=@$_SERVER['HTTPS']?'https':'http';
172                if( ($froma[2]!=$_SERVER['HTTP_HOST']) || ($froma[3]=='login.php') || ($froma[3]=='') ) $from="$proto://".$_SERVER['HTTP_HOST'];               
173        }
174        $_SESSION['redir_to']=$from;   
175       
176        $cont=rcv('cont');
177        $tmpl->AddText("<h1 id='page-title'>Аутентификация</h1>");
178        $tmpl->SetTitle("Аутентификация");
179        if($cont)       $tmpl->AddText("<div id='page-info'>Для доступа в этот раздел Вам необходимо пройти аутентификацию.</div>");
180
181        //$_SESSION['c_str']=strtoupper(keygen_unique(0,5,7));
182        $ip=getenv("REMOTE_ADDR");
183        $time=time()+60;
184        $at=attack_test();
185        if($at>1)       mysql_query("INSERT INTO `users_bad_auth` (`ip`, `time`) VALUES ('$ip', '$time')");
186        if($at>=3)
187        {
188                $tmpl->msg("Из-за попыток подбора паролей к сайту доступ с вашей подсети заблокирован! Вы сможете авторизоваться через несколько часов после прекращения попыток подбора пароля. Если Вы не предпринимали попыток подбора пароля, обратитесь к Вашему поставщику интернет-услуг - возможно, кто-то другой пытается подобрать пароль, используя ваш адрес.","err","Доступ заблокирован");
189        }
190        else if($at==2)
191        {
192                $tmpl->msg("Из-за попыток подбора паролей к сайту доступ с вашего адреса заблокирован! Вы сможете авторизоваться через несколько часов после прекращения попыток подбора пароля. Если Вы не предпринимали попыток подбора пароля, обратитесь к Вашему поставщику интернет-услуг - возможно, кто-то другой пытается подобрать пароль, используя ваш адрес.","err","Доступ заблокирован");
193        }
194        else
195        {
196                if($opt=='login')
197                {
198                        if( ($at==1) && ( (strtoupper($_SESSION['captcha_keystring'])!=strtoupper($img)) || ($_SESSION['captcha_keystring']=='') ) )
199                        {
200                                $tmpl->msg("Введите правильный код подтверждения, изображенный на картинке", "err");
201                                mysql_query("INSERT INTO `users_bad_auth` (`ip`, `time`) VALUES ('$ip', '$time')");
202                        }
203                        else
204                        {
205                                $res=mysql_query("SELECT `users`.`id`, `users`.`name`, `users`.`confirm`, `users_data`.`value` FROM `users`
206                                LEFT JOIN `users_data` ON `users_data`.`uid`=`users`.`id` AND `users_data`.`param`='firm_id'
207                                WHERE `name`='$login' AND `pass`=MD5('$pass')");
208                       
209                                if(@$nxt=mysql_fetch_row($res))
210                                {
211                                        if( ($nxt[2]=='') || ($nxt[2]=='0') )
212                                        {
213                                                mysql_query("UPDATE `users` SET `lastlogin`=NOW(), `passch`='' WHERE `id`='$nxt[0]'");
214                                                $_SESSION['uid']=$nxt[0];
215                                                $_SESSION['name']=$nxt[1];
216                                                if($_SESSION['last_page'])     
217                                                {
218                                                        $lp=$_SESSION['last_page'];
219                                                        unset($_SESSION['last_page']);
220                                                        header("Location: ".$lp);
221                                                }
222                                                else if($_SESSION['redir_to'])  header("Location: ".$_SESSION['redir_to']);
223                                                else                            header("Location: index.php");
224                                                exit();
225                                        }
226                                        else
227                                        {
228                                                $tmpl->msg("Вы не подтвердили свои регистрационные данные! Проверьте свой почтоый ящик!<br>Если Вы ещё не получили письмо, а с момента регистрации прошло более трёх часов - вероятно Ваш сервер не принимает от нас почту. В таком случае Вам нужно повторно выполнить резистрацию, указав при этом адрес электронной почты, зарегистрированный на другом сервере.!");
229                                        }
230                                }
231                                else
232                                {
233                                        mysql_query("INSERT INTO `users_bad_auth` (`ip`, `time`) VALUES ('$ip', '$time')");
234                                        $tmpl->msg("Неверная пара логин / пароль! Попробуйте снова!","err","Авторизоваться не удалось");
235                                }
236               
237               
238                        }
239                }
240                $at=attack_test();
241               
242                if($at>0)
243                        $m="<tr><td>
244                        Введите код подтверждения, изображенный на картинке:<br>
245                        <img src='kcaptcha/index.php' alt='Включите отображение картинок!'><td>
246                        <input type='text' name='img'>";
247                else $m='';
248               
249                $form_action='/login.php';
250                if($CONFIG['site']['force_https_login'])
251                {
252                        $host=$_SERVER['HTTP_HOST'];
253                        $qs=explode('/',$query);
254                        $form_action='https://'.$host.'/login.php';
255                }
256                $tmpl->AddText("
257                <form method='post' action='$form_action' id='login-form'>
258                <input type='hidden' name='opt' value='login'>
259                <table id='login-table'>
260                <tr><th colspan='2'>
261                Введите данные:
262                <tr><td colspan='2'>
263                Если у Вас их нет, вы можете <a class='wiki' href='/login.php?mode=reg'>зарегистрироваться</a>
264                <tr><td>
265                Имя:<td>
266                <input type='text' name='login' class='text' id='input_name' value='$login'><br>
267                <tr><td>Пароль:<td>
268                <input type='password' name='pass' class='text'>(<a class='wiki' href='?mode=rem'>Сменить</a>)<br>$m
269                <tr><td><td>
270                <button type='submit'>Вход!</button> ( <a class='wiki' href='/login.php?mode=rem'>Забыли пароль?</a> )
271                </table></form>
272       
273                <script type=\"text/javascript\">
274               
275                function focusInput()
276                {
277                var input_name = document.getElementById('input_name');
278                if (input_name.value == '')
279                        input_name.focus();
280                return false;
281                }
282               
283                window.setTimeout('focusInput()', 300);
284                </script>");
285        }
286
287}
288else if($mode=='logout')
289{
290    unset($_SESSION['uid']);
291    unset($_SESSION['name']);
292    header("Location: index.php");
293    exit();
294}
295else if($mode=='reg')
296{
297        if(!$uid)
298        {
299                $tmpl->SetTitle("Регистрация");
300                $tmpl->AddText("<h1 id='page-title'>Регистрация</h1>");
301                RegForm();
302        }       else $tmpl->msg("Вы уже являетесь нашим зарегистрированным пользователем. Повторная регистрация не требуется.","info");
303}
304else if($mode=='regs')
305{
306        try
307        {
308                $login=rcv('login');
309                $email=rcv('email');
310                $img=strtoupper(rcv('img'));
311                $subs=rcv('subs');
312                if($subs!='0') $subs=1;
313               
314                if($login=='')
315                        throw new RegException('Поле login не заполнено','login');
316                if(strlen($login)<3)
317                        throw new RegException('login слишком короткий','login');
318                if(strlen($login)>24)
319                        throw new RegException('login слишком длинный','login');
320                if( !preg_match('/^[a-zA-Z][a-zA-Z\d]*$/', $login))
321                        throw new RegException('login должен состоять из английских букв, цифр, начинаться с буквы','login');
322               
323                $res=mysql_query("SELECT `id` FROM `users` WHERE `name`='$login'");
324                if(mysql_num_rows($res))
325                        throw new RegException('Такой login занят. Используйте другой.','login');
326               
327                if($email=='')
328                        throw new RegException('Поле email не заполнено','email');
329                if( !preg_match('/^\w+([-\.\w]+)*\w@\w(([-\.\w])*\w+)*\.\w{2,8}$/', $email))
330                        throw new RegException('Неверный формат адреса e-mail. Адрес должен быть в формате user@host.zone','email');
331                $res=mysql_query("SELECT `id` FROM `users` WHERE `email`='$email'");
332                if(mysql_num_rows($res))
333                        throw new RegException('Пользователь с таким email уже зарегистрирован. Используйте другой.','email');
334               
335                if($img=='')
336                        throw new RegException('Код подтверждения не введён','img');
337                if(strtoupper($_SESSION['captcha_keystring'])!=strtoupper($img))
338                        throw new RegException('Код подтверждения введён неверно','img');
339                       
340                       
341
342//                      header("Location: login.php?mode=reg".$l);
343                $conf=md5(time()+rand(0,1000000));
344                $pass=keygen_unique(0,6,9);
345                $msg=regMsg($login, $pass, $conf);
346
347       
348                if(mailto($email,"Регистрация на ".$CONFIG['site']['name'], $msg))
349                {
350                        $res=mysql_query("INSERT INTO `users` (`name`,`pass`,`email`,`date_reg`,`confirm`,`subscribe`)
351                        VALUES ('$login', MD5('$pass'), '$email', NOW(),'$conf','$subs')  ");
352                        if(mysql_errno())       throw new MysqlException("Не удалось добвать пользователя! Попробуйте позднее!");
353                       
354                        $tmpl->AddText("<h1 id='page-title'>Завершение регистрации</h1>
355                        <form action='/login.php'>
356                        <input type='hidden' name='mode' value='conf'>
357                        Для проверки, что указанный адрес электронной почты принадлежит Вам, на него было выслано сообщение.<br>Для завершения регистрации введите полученный код:<br><br>
358                        <input type='text' name='s'><button type='submit'>Продолжить</button><br><br>
359                        Если Вы не получите письмо в течение трёх часов, возможно ваш сервер не принимает наше сообщение. Сообщите о проблеме администратору своего почтового сервера, или используйте другой!
360                        </form>");     
361                }
362                else throw new Exception('Не удалось отправить сообщение электронной почты. Попытайтесь позднее. Если проблема сохранится - убедительная просьба сообщить об этом администратору.','img');
363        }
364        catch(RegException $e)
365        {
366                mysql_query("ROLLBACK");
367                $tmpl->SetTitle("Регистрация");
368                $tmpl->SetText("<h1 id='page-title'>Регистрация</h1>");
369                $tmpl->msg("Проверьте данные! ".$e->getMessage(),"err","Неверный ввод!");
370                RegForm($e->target, $e->getMessage());
371               
372        }
373        catch(Exception $e)
374        {
375                mysql_query("ROLLBACK");
376                $tmpl->msg($e->getMessage(),"err","Ошибка при регистрации");
377        }
378
379}
380else if($mode=='conf')
381{
382        $tmpl->AddText("<h1 id='page-title'>Подтверждение регистрации</h1>");
383        $s=rcv('s');
384        $res=mysql_query("SELECT `id`, `name` FROM `users` WHERE `confirm`='$s'");
385        if($nxt=mysql_fetch_row($res))
386        {
387                mysql_query("UPDATE `users` SET `confirm`='0' WHERE `id` = '$nxt[0]' ");
388                mysql_query("UPDATE `users` SET `lastlogin`=NOW(), `passch`='' WHERE `id`='$nxt[0]'");
389                $_SESSION['uid']=$nxt[0];
390                $_SESSION['name']=$nxt[1];
391                if($_SESSION['last_page'])     
392                {
393                        $lp=$_SESSION['last_page'];
394                        unset($_SESSION['last_page']);
395                        header("Location: ".$lp);
396                }
397                else $tmpl->msg("Регистрация завершена! Теперь можно войти!","ok");
398        }
399        else $tmpl->msg("Неверный или устаревший код подтверждения!","err");
400}
401else if($mode=='rem')
402{
403        $tmpl->SetText("<h1 id='page-title'>Смена пароля</h1>
404        <p id='text'>Для начала процедуры смены пароля введите логин на сайте или адрес электронной почты:</p>
405        <form method='post'>
406        <input type='text' name='login'><br>
407        <input type='hidden' name='mode' value='rems'>
408        <p id='text'>После нажатия кнопки на адрес электронной почты, указанный при регистрации, будет выслана ссылка для смены пароля.</p>
409        <input type='submit' value='Выслать ссылку'>
410        </form>");
411}
412else if($mode=='rems')
413{
414        $tmpl->SetText("<h1 id='page-title'>Смена пароля</h1>");
415        $res=mysql_query("SELECT `id`,`name`,`email`,`confirm`,`date_reg` FROM `users` WHERE `name`='$login' OR `email`='$login'");
416        if(@$nxt=mysql_fetch_row($res))
417        {
418                $key=md5($nxt[0].$nxt[1].$nxt[2].$nxt[4].time());
419                $proto='http';
420                if($CONFIG['site']['force_https_login'] || $CONFIG['site']['force_https'])      $proto='https';
421
422                mysql_query("UPDATE `users` SET `passch`='$key' WHERE `id`='$nxt[0]'");
423                $msg="Поступил запрос на смену пароля доступа к сайту {$CONFIG['site']['name']} для аккаунта $nxt[1].
424Если Вы действительно хотите сменить пароль, перейдите по ссылке $proto://{$CONFIG['site']['name']}/login.php?mode=remn&s=$key
425Если Вы не давали запрос на смену пароля, обязательно отмените этот запрос, авторизовавшись на сайте!
426----------------------------------------
427Сообщение сгенерировано автоматически, отвечать на него не нужно!";
428                if(mailto($nxt[2],"Восстановление забытого пароля",$msg))
429                        $tmpl->msg("Проверьте почтовый ящик!","ok");
430                else
431                        $tmpl->msg("Сообщение не может быть отправлено в данный момент! Попытайтесь позднее!","err");
432        }
433        else $tmpl->msg("Пользователя с таким именем или адресом электронной почты не найдено! Возможно, он был удален по неактивности.","err");
434}
435else if($mode=='passch')
436{
437        $tmpl->AddText("<h1 id='page-title'>Смена пароля</h1>
438        <div id='page-info'>Если у Вас есть сомнения в конфеденциальности текущено пароля</div>
439        Хороший пароль должен состоять из смеси букв, цифр, и специальных символов (как минимум из смеси букв и цифр), и не являться слованым словом.");
440}
441else if($mode=='remn')
442{
443        $key=rcv('s');
444        if(strlen($key)!=32) $tmpl->logger("PassRecovery: uncorrect key!");
445        else
446        {
447                $res=mysql_query("SELECT `id`,`name`,`email` FROM `users` WHERE `passch`='$key'");
448                if($nxt=mysql_fetch_row($res))
449                {
450                $pass=keygen_unique(0,6,9);
451                mysql_query("UPDATE `users` SET `pass`=md5('$pass'), `passch`='', `confirm`='0' WHERE `id`='$nxt[0]'");
452                $_SESSION['uid']=$nxt[0];
453                $_SESSION['name']=$nxt[1];
454                $msg="Сайт {$CONFIG['site']['name']}\nПароль был успешно изменён! Не забудьте его!\nlogin: $nxt[1]\npass: $pass\n----------------------------------------\nСообщение сгенерировано автоматически, отвечать на него не нужно!";
455                mailto($nxt[2],"Информация о смене пароля",$msg);
456                $tmpl->AddText("<h1>Завершение смены пароля</h1>
457                <p id=text>$nxt[1], ваш новый пароль:<br>
458                $pass<br>Не забудьте его! Письмо с новым паролем отправлено Вам по электронной почте!");
459                }
460                else $tmpl->logger("Ссылка уже не действительна!");
461        }
462}
463else if($mode=='unsubscribe')
464{
465        $tmpl->SetText("<h1 id='page-title'>Отказ от рассылки</h1>");
466        $email=rcv('email');
467        $c=0;
468        $res=mysql_query("UPDATE `users` SET `subscribe`='0' WHERE `email`='$email'");
469        echo mysql_error();
470        if(mysql_affected_rows())
471        {
472                $tmpl->msg("Вы успешно отказались от автоматической рассылки!","ok");
473                $c=1;
474        }
475       
476        $res=mysql_query("UPDATE `doc_agent` SET `no_mail`='1' WHERE `email`='$email'");
477        echo mysql_error();
478        if(mysql_affected_rows())
479        {
480                $tmpl->msg("В нашей клиентской базе Ваш адрес помечен, как нежелательный для рассылки.","ok");
481                $c=1;
482        }
483       
484        if(!$c) $tmpl->msg("Ваш адрес не найден в наших базах рассылки! Возможно, Вы отказались от рассылки ранее, или не являетесь нашим зарегистрированным пользователем. За разяснением обратитесь по телефону или e-mail, указанному на странице <a class='wiki' href='/wiki/ContactInfo'>Контакты</a>, либо в письме, полученном от нас. Спасибо за понимание!","notify");
485}
486else $tmpl->logger("Uncorrect mode!");
487
488
489$tmpl->write();
490
491?>
Note: See TracBrowser for help on using the repository browser.