plugins/SpecialUserFuncs.php
changeset 179 36b287f1d85c
parent 133 af0f6ec48de3
child 182 c69730750be3
equal deleted inserted replaced
178:4c19952406db 179:36b287f1d85c
   102   global $__login_status;
   102   global $__login_status;
   103   
   103   
   104   $pubkey = $session->rijndael_genkey();
   104   $pubkey = $session->rijndael_genkey();
   105   $challenge = $session->dss_rand();
   105   $challenge = $session->dss_rand();
   106   
   106   
       
   107   $locked_out = false;
       
   108   // are we locked out?
       
   109   $threshold = ( $_ = getConfig('lockout_threshold') ) ? intval($_) : 5;
       
   110   $duration  = ( $_ = getConfig('lockout_duration') ) ? intval($_) : 15;
       
   111   // convert to minutes
       
   112   $duration  = $duration * 60;
       
   113   $policy = ( $x = getConfig('lockout_policy') && in_array(getConfig('lockout_policy'), array('lockout', 'disable', 'captcha')) ) ? getConfig('lockout_policy') : 'lockout';
       
   114   if ( $policy != 'disable' )
       
   115   {
       
   116     $ipaddr = $db->escape($_SERVER['REMOTE_ADDR']);
       
   117     $timestamp_cutoff = time() - $duration;
       
   118     $q = $session->sql('SELECT timestamp FROM '.table_prefix.'lockout WHERE timestamp > ' . $timestamp_cutoff . ' AND ipaddr = \'' . $ipaddr . '\' ORDER BY timestamp DESC;');
       
   119     $fails = $db->numrows();
       
   120     if ( $fails >= $threshold )
       
   121     {
       
   122       $row = $db->fetchrow();
       
   123       $locked_out = true;
       
   124       $lockdata = array(
       
   125           'locked_out' => true,
       
   126           'lockout_threshold' => $threshold,
       
   127           'lockout_duration' => ( $duration / 60 ),
       
   128           'lockout_fails' => $fails,
       
   129           'lockout_policy' => $policy,
       
   130           'lockout_last_time' => $row['timestamp'],
       
   131           'server_time' => time(),
       
   132           'captcha' => ''
       
   133         );
       
   134       if ( $policy == 'captcha' )
       
   135       {
       
   136         $lockdata['captcha'] = $session->make_captcha();
       
   137       }
       
   138     }
       
   139     $db->free_result();
       
   140   }
       
   141   
   107   if ( isset($_GET['act']) && $_GET['act'] == 'getkey' )
   142   if ( isset($_GET['act']) && $_GET['act'] == 'getkey' )
   108   {
   143   {
   109     $username = ( $session->user_logged_in ) ? $session->username : false;
   144     $username = ( $session->user_logged_in ) ? $session->username : false;
   110     $response = Array(
   145     $response = Array(
   111       'username' => $username,
   146       'username' => $username,
   112       'key' => $pubkey,
   147       'key' => $pubkey,
   113       'challenge' => $challenge
   148       'challenge' => $challenge,
       
   149       'locked_out' => false
   114       );
   150       );
       
   151     
       
   152     if ( $locked_out )
       
   153     {
       
   154       foreach ( $lockdata as $x => $y )
       
   155       {
       
   156         $response[$x] = $y;
       
   157       }
       
   158       unset($x, $y);
       
   159     }
       
   160     
   115     $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE);
   161     $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE);
   116     $response = $json->encode($response);
   162     $response = $json->encode($response);
   117     echo $response;
   163     echo $response;
   118     return null;
   164     return null;
   119   }
   165   }
   136   $template->header();
   182   $template->header();
   137   echo '<form action="'.makeUrl($paths->nslist['Special'].'Login').'" method="post" name="loginform" onsubmit="runEncryption();">';
   183   echo '<form action="'.makeUrl($paths->nslist['Special'].'Login').'" method="post" name="loginform" onsubmit="runEncryption();">';
   138   $header = ( $level > USER_LEVEL_MEMBER ) ? 'Please re-enter your login details' : 'Please enter your username and password to log in.';
   184   $header = ( $level > USER_LEVEL_MEMBER ) ? 'Please re-enter your login details' : 'Please enter your username and password to log in.';
   139   if ( isset($_POST['login']) )
   185   if ( isset($_POST['login']) )
   140   {
   186   {
   141     echo '<p>'.$__login_status.'</p>';
   187     $errstring = $__login_status['error'];
       
   188     switch($__login_status['error'])
       
   189     {
       
   190       case 'key_not_found':
       
   191         $errstring = 'Enano couldn\'t look up the encryption key used to encrypt your password. This most often happens if a cache rotation occurred during your login attempt, or if you refreshed the login page.';
       
   192         break;
       
   193       case 'key_wrong_length':
       
   194         $errstring = 'The encryption key was the wrong length.';
       
   195         break;
       
   196       case 'too_big_for_britches':
       
   197         $errstring = 'You are trying to authenticate at a level that your user account does not permit.';
       
   198         break;
       
   199       case 'invalid_credentials':
       
   200         $errstring = 'You have entered an invalid username or password. Please enter your login details again.';
       
   201         if ( $__login_status['lockout_policy'] == 'lockout' )
       
   202         {
       
   203           $errstring .= ' You have used up '.$__login_status['lockout_fails'].' out of '.$__login_status['lockout_threshold'].' login attempts. After you have used up all '.$data['lockout_threshold'].' login attempts, you will be locked out from logging in for '.$__login_status['lockout_duration'].' minutes.';
       
   204         }
       
   205         else if ( $__login_status['lockout_policy'] == 'captcha' )
       
   206         {
       
   207           $errstring .= ' You have used up '.$__login_status['lockout_fails'].' out of '.$__login_status['lockout_threshold'].' login attempts. After you have used up all '.$data['lockout_threshold'].' login attempts, you will have to enter a visual confirmation code before logging in, effective for '.$__login_status['lockout_duration'].' minutes.';
       
   208         }
       
   209         break;
       
   210       case 'backend_fail':
       
   211         $errstring = 'You entered the right credentials and everything was validated, but for some reason Enano couldn\'t register your session. This is an internal problem with the site and you are encouraged to contact site administration.';
       
   212         break;
       
   213       case 'locked_out':
       
   214         $attempts = intval($__login_status['lockout_fails']);
       
   215         if ( $attempts > $__login_status['lockout_threshold'])
       
   216           $attempts = $__login_status['lockout_threshold'];
       
   217         $time_rem = ( $__login_status['lockout_last_time'] % ( $__login_status['lockout_duration'] * 60 ) );
       
   218         $time_rem = $__login_status['lockout_duration'] - round($time_rem / 60);
       
   219         $s = ( $time_rem == 1 ) ? '' : 's';
       
   220         $errstring = "You have used up all {$__login_status['lockout_threshold']} allowed login attempts. Please wait {$time_rem} minute$s before attempting to log in again";
       
   221         if ( $__login_status['lockout_policy'] == 'captcha' )
       
   222         $errstring .= ', or enter the visual confirmation code shown above in the appropriate box';
       
   223         $errstring .= '.';
       
   224         break;
       
   225     }
       
   226     echo '<div class="error-box-mini">'.$errstring.'</div>';
   142   }
   227   }
   143   if ( $p = $paths->getAllParams() )
   228   if ( $p = $paths->getAllParams() )
   144   {
   229   {
   145     echo '<input type="hidden" name="return_to" value="'.$p.'" />';
   230     echo '<input type="hidden" name="return_to" value="'.$p.'" />';
   146   }
   231   }
   187                 echo 'value="' . $session->username . '"';
   272                 echo 'value="' . $session->username . '"';
   188               }
   273               }
   189               ?> />
   274               ?> />
   190           </td>
   275           </td>
   191           <?php if ( $level <= USER_LEVEL_MEMBER ) { ?>
   276           <?php if ( $level <= USER_LEVEL_MEMBER ) { ?>
   192           <td rowspan="2" class="row3">
   277           <td rowspan="<?php echo ( ( $locked_out && $lockdata['lockout_policy'] == 'captcha' ) ) ? '4' : '2'; ?>" class="row3">
   193             <small>Forgot your password? <a href="<?php echo makeUrlNS('Special', 'PasswordReset'); ?>">No problem.</a><br />
   278             <small>Forgot your password? <a href="<?php echo makeUrlNS('Special', 'PasswordReset'); ?>">No problem.</a><br />
   194             Maybe you need to <a href="<?php echo makeUrlNS('Special', 'Register'); ?>">create an account</a>.</small>
   279             Maybe you need to <a href="<?php echo makeUrlNS('Special', 'Register'); ?>">create an account</a>.</small>
   195           </td>
   280           </td>
   196           <?php } ?>
   281           <?php } ?>
   197         </tr>
   282         </tr>
   198         <tr>
   283         <tr>
   199           <td class="row2">Password:<br /></td><td class="row1"><input name="pass" size="25" type="password" tabindex="<?php echo ( $level <= USER_LEVEL_MEMBER ) ? '2' : '1'; ?>" /></td>
   284           <td class="row2">Password:<br /></td><td class="row1"><input name="pass" size="25" type="password" tabindex="<?php echo ( $level <= USER_LEVEL_MEMBER ) ? '2' : '1'; ?>" /></td>
   200          </tr>
   285          </tr>
       
   286          <?php
       
   287          if ( $locked_out && $lockdata['lockout_policy'] == 'captcha' )
       
   288          {
       
   289            ?>
       
   290            <tr>
       
   291              <td class="row2" rowspan="2">Code in image:<br /></td><td class="row1"><input type="hidden" name="captcha_hash" value="<?php echo $lockdata['captcha']; ?>" /><input name="captcha_code" size="25" type="text" tabindex="<?php echo ( $level <= USER_LEVEL_MEMBER ) ? '3' : '4'; ?>" /></td>
       
   292            </tr>
       
   293            <tr>
       
   294              <td class="row3">
       
   295                <img src="<?php echo makeUrlNS('Special', 'Captcha/' . $lockdata['captcha']) ?>" onclick="this.src=this.src+'/a';" style="cursor: pointer;" />
       
   296              </td>
       
   297            </tr>
       
   298            <?php
       
   299          }
       
   300          ?>
   201          <?php if ( $level <= USER_LEVEL_MEMBER ) { ?>
   301          <?php if ( $level <= USER_LEVEL_MEMBER ) { ?>
   202          <tr>
   302          <tr>
   203            <td class="row3" colspan="3">
   303            <td class="row3" colspan="3">
   204              <p><b>Important note regarding cryptography:</b> Some countries do not allow the import or use of cryptographic technology. If you live in one of the countries listed below, you should <a href="<?php if($p=$paths->getParam(0))$u='/'.$p;else $u='';echo makeUrl($paths->page.$u, 'level='.$level.'&use_crypt=0', true); ?>">log in without using encryption</a>.</p>
   304              <p><b>Important note regarding cryptography:</b> Some countries do not allow the import or use of cryptographic technology. If you live in one of the countries listed below, you should <a href="<?php if($p=$paths->getParam(0))$u='/'.$p;else $u='';echo makeUrl($paths->page.$u, 'level='.$level.'&use_crypt=0', true); ?>">log in without using encryption</a>.</p>
   205              <p>This restriction applies to the following countries: Belarus, China, India, Israel, Kazakhstan, Mongolia, Pakistan, Russia, Saudi Arabia, Singapore, Tunisia, Venezuela, and Vietnam.</p>
   305              <p>This restriction applies to the following countries: Belarus, China, India, Israel, Kazakhstan, Mongolia, Pakistan, Russia, Saudi Arabia, Singapore, Tunisia, Venezuela, and Vietnam.</p>
   240   if ( isset($_GET['act']) && $_GET['act'] == 'ajaxlogin' )
   340   if ( isset($_GET['act']) && $_GET['act'] == 'ajaxlogin' )
   241   {
   341   {
   242     $plugins->attachHook('login_password_reset', 'SpecialLogin_SendResponse_PasswordReset($row[\'user_id\'], $row[\'temp_password\']);');
   342     $plugins->attachHook('login_password_reset', 'SpecialLogin_SendResponse_PasswordReset($row[\'user_id\'], $row[\'temp_password\']);');
   243     $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE);
   343     $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE);
   244     $data = $json->decode($_POST['params']);
   344     $data = $json->decode($_POST['params']);
       
   345     $captcha_hash = ( isset($data['captcha_hash']) ) ? $data['captcha_hash'] : false;
       
   346     $captcha_code = ( isset($data['captcha_code']) ) ? $data['captcha_code'] : false;
   245     $level = ( isset($data['level']) ) ? intval($data['level']) : USER_LEVEL_MEMBER;
   347     $level = ( isset($data['level']) ) ? intval($data['level']) : USER_LEVEL_MEMBER;
   246     $result = $session->login_with_crypto($data['username'], $data['crypt_data'], $data['crypt_key'], $data['challenge'], $level);
   348     $result = $session->login_with_crypto($data['username'], $data['crypt_data'], $data['crypt_key'], $data['challenge'], $level, $captcha_hash, $captcha_code);
   247     $session->start();
   349     $session->start();
   248     //echo "$result\n$session->sid_super";
   350     if ( $result['success'] )
   249     //exit;
       
   250     if ( $result == 'success' )
       
   251     {
   351     {
   252       $response = Array(
   352       $response = Array(
   253           'result' => 'success',
   353           'result' => 'success',
   254           'key' => $session->sid_super // ( ( $session->sid_super ) ? $session->sid_super : $session->sid )
   354           'key' => $session->sid_super // ( ( $session->sid_super ) ? $session->sid_super : $session->sid )
   255         );
   355         );
   256     }
   356     }
   257     else
   357     else
   258     {
   358     {
       
   359       $captcha = '';
       
   360       if ( $result['error'] == 'locked_out' && $result['lockout_policy'] == 'captcha' )
       
   361       {
       
   362         $session->kill_captcha();
       
   363         $captcha = $session->make_captcha();
       
   364       }
   259       $response = Array(
   365       $response = Array(
   260           'result' => 'error',
   366           'result' => 'error',
   261           'error' => $result
   367           'data' => $result,
       
   368           'captcha' => $captcha
   262         );
   369         );
   263     }
   370     }
   264     $response = $json->encode($response);
   371     $response = $json->encode($response);
   265     echo $response;
   372     echo $response;
   266     $db->close();
   373     $db->close();
   267     exit;
   374     exit;
   268   }
   375   }
   269   if(isset($_POST['login'])) {
   376   if(isset($_POST['login'])) {
       
   377     $captcha_hash = ( isset($_POST['captcha_hash']) ) ? $_POST['captcha_hash'] : false;
       
   378     $captcha_code = ( isset($_POST['captcha_code']) ) ? $_POST['captcha_code'] : false;
   270     if($_POST['use_crypt'] == 'yes')
   379     if($_POST['use_crypt'] == 'yes')
   271     {
   380     {
   272       $result = $session->login_with_crypto($_POST['username'], $_POST['crypt_data'], $_POST['crypt_key'], $_POST['challenge_data'], intval($_POST['auth_level']));
   381       $result = $session->login_with_crypto($_POST['username'], $_POST['crypt_data'], $_POST['crypt_key'], $_POST['challenge_data'], intval($_POST['auth_level']), $captcha_hash, $captcha_code);
   273     }
   382     }
   274     else
   383     else
   275     {
   384     {
   276       $result = $session->login_without_crypto($_POST['username'], $_POST['pass'], false, intval($_POST['auth_level']));
   385       $result = $session->login_without_crypto($_POST['username'], $_POST['pass'], false, intval($_POST['auth_level']), $captcha_hash, $captcha_code);
   277     }
   386     }
   278     $session->start();
   387     $session->start();
   279     $paths->init();
   388     $paths->init();
   280     if($result == 'success')
   389     if($result['success'])
   281     {
   390     {
   282       $template->load_theme($session->theme, $session->style);
   391       $template->load_theme($session->theme, $session->style);
   283       if(isset($_POST['return_to']))
   392       if(isset($_POST['return_to']))
   284       {
   393       {
   285         $name = ( isset($paths->pages[$_POST['return_to']]['name']) ) ? $paths->pages[$_POST['return_to']]['name'] : $_POST['return_to'];
   394         $name = ( isset($paths->pages[$_POST['return_to']]['name']) ) ? $paths->pages[$_POST['return_to']]['name'] : $_POST['return_to'];