plugins/yubikey/auth.php
author Dan
Thu, 30 Apr 2009 16:11:40 -0400
changeset 17 e04c0f64e972
parent 5 2114640729a5
child 25 2e7ccbdfdc0a
permissions -rw-r--r--
SECURITY (critical): If username provided, any Yubikey could be used to log in.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
     1
<?php
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
     2
3
d0fe7acaf0e8 Maybe we could actually make yubikey_enable in config not ignored!
Dan
parents: 2
diff changeset
     3
if ( getConfig('yubikey_enable', '1') != '1' )
d0fe7acaf0e8 Maybe we could actually make yubikey_enable in config not ignored!
Dan
parents: 2
diff changeset
     4
    return true;
d0fe7acaf0e8 Maybe we could actually make yubikey_enable in config not ignored!
Dan
parents: 2
diff changeset
     5
0
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
     6
// hook into auth
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
     7
$plugins->attachHook('login_process_userdata_json', 'return yubikey_auth_hook_json($userinfo, $req["level"], @$req["remember"]);');
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
     8
// hook into special page init
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
     9
$plugins->attachHook('session_started', 'yubikey_add_special_pages();');
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    10
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    11
function yubikey_auth_hook_json(&$userdata, $level, $remember)
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    12
{
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    13
  global $db, $session, $paths, $template, $plugins; // Common objects
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    14
  global $lang;
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    15
  
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    16
  $do_validate_otp = false;
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    17
  $do_validate_user = false;
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    18
  $do_validate_pass = false;
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    19
  
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    20
  $user_flag = ( $level >= USER_LEVEL_CHPREF ) ? YK_SEC_ELEV_USERNAME : YK_SEC_NORMAL_USERNAME;
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    21
  $pass_flag = ( $level >= USER_LEVEL_CHPREF ) ? YK_SEC_ELEV_PASSWORD : YK_SEC_NORMAL_PASSWORD;
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    22
  
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    23
  $auth_log_prefix = ( $level >= USER_LEVEL_CHPREF ) ? 'admin_' : '';
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    24
  
2
6edc6ebb3b39 Minor: if input OTP is empty and password looks like OTP, now copies password to OTP in memory and treats password field as OTP. Will require patch in Enano trunk to work for html login.
Dan
parents: 0
diff changeset
    25
  // Sort of a hack: if the password looks like an OTP and the OTP field is empty, use the password as the OTP
6edc6ebb3b39 Minor: if input OTP is empty and password looks like OTP, now copies password to OTP in memory and treats password field as OTP. Will require patch in Enano trunk to work for html login.
Dan
parents: 0
diff changeset
    26
  if ( empty($userdata['yubikey_otp']) && preg_match('/^[cbdefghijklnrtuv]{44}$/', $userdata['password'] ) )
6edc6ebb3b39 Minor: if input OTP is empty and password looks like OTP, now copies password to OTP in memory and treats password field as OTP. Will require patch in Enano trunk to work for html login.
Dan
parents: 0
diff changeset
    27
  {
6edc6ebb3b39 Minor: if input OTP is empty and password looks like OTP, now copies password to OTP in memory and treats password field as OTP. Will require patch in Enano trunk to work for html login.
Dan
parents: 0
diff changeset
    28
    $userdata['yubikey_otp'] = $userdata['password'];
6edc6ebb3b39 Minor: if input OTP is empty and password looks like OTP, now copies password to OTP in memory and treats password field as OTP. Will require patch in Enano trunk to work for html login.
Dan
parents: 0
diff changeset
    29
  }
6edc6ebb3b39 Minor: if input OTP is empty and password looks like OTP, now copies password to OTP in memory and treats password field as OTP. Will require patch in Enano trunk to work for html login.
Dan
parents: 0
diff changeset
    30
  
0
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    31
  if ( !empty($userdata['username']) )
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    32
  {
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    33
    // get flags
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    34
    $q = $db->sql_query('SELECT user_id, user_yubikey_flags FROM ' . table_prefix . "users WHERE " . ENANO_SQLFUNC_LOWERCASE . "(username) = '" . $db->escape(strtolower($userdata['username'])) . "';");
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    35
    if ( !$q )
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    36
      $db->die_json();
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    37
    
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    38
    if ( $db->numrows() < 1 )
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    39
    {
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    40
      // Username not found - let the main login function handle it
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    41
      $db->free_result();
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    42
      return null;
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    43
    }
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    44
    list($user_id, $flags) = $db->fetchrow_num();
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    45
    $flags = intval($flags);
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    46
    // At the point the username is validated.
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    47
    $do_validate_user = false;
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    48
    $do_validate_pass = $flags & $pass_flag;
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    49
    if ( empty($userdata['yubikey_otp']) )
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    50
    {
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    51
      // no OTP was provided
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    52
      // make sure the user has allowed logging in with no OTP
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    53
      if ( !($flags & YK_SEC_ALLOW_NO_OTP) )
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    54
      {
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    55
        // We also might have no Yubikeys enrolled.
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    56
        $q = $db->sql_query('SELECT 1 FROM ' . table_prefix . "yubikey WHERE user_id = $user_id;");
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    57
        if ( !$q )
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    58
          $db->die_json();
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    59
        
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    60
        if ( $db->numrows() > 0 )
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    61
        {
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    62
          // Yep at least one key is enrolled.
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    63
          // I don't think these should be logged because they'll usually just be innocent mistakes.
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    64
          $db->free_result();
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    65
          return array(
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    66
              'mode' => 'error',
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    67
              'error' => 'yubiauth_err_must_have_otp'
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    68
            );
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    69
        }
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    70
        // Nope, no keys enrolled, user hasn't enabled Yubikey support
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    71
        $db->free_result();
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    72
      }
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    73
      // we're ok, use normal password auth
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    74
      return null;
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    75
    }
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    76
    else
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    77
    {
17
e04c0f64e972 SECURITY (critical): If username provided, any Yubikey could be used to log in.
Dan
parents: 5
diff changeset
    78
      // user did enter an OTP; make sure it's associated with the username
e04c0f64e972 SECURITY (critical): If username provided, any Yubikey could be used to log in.
Dan
parents: 5
diff changeset
    79
      $yubi_uid = $db->escape(substr($userdata['yubikey_otp'], 0, 12));
e04c0f64e972 SECURITY (critical): If username provided, any Yubikey could be used to log in.
Dan
parents: 5
diff changeset
    80
      $q = $db->sql_query('SELECT 1 FROM ' . table_prefix . 'yubikey WHERE yubi_uid = \'' . $yubi_uid . '\';');
e04c0f64e972 SECURITY (critical): If username provided, any Yubikey could be used to log in.
Dan
parents: 5
diff changeset
    81
      if ( !$q )
e04c0f64e972 SECURITY (critical): If username provided, any Yubikey could be used to log in.
Dan
parents: 5
diff changeset
    82
        $db->die_json();
e04c0f64e972 SECURITY (critical): If username provided, any Yubikey could be used to log in.
Dan
parents: 5
diff changeset
    83
      if ( $db->numrows() < 1 )
e04c0f64e972 SECURITY (critical): If username provided, any Yubikey could be used to log in.
Dan
parents: 5
diff changeset
    84
      {
e04c0f64e972 SECURITY (critical): If username provided, any Yubikey could be used to log in.
Dan
parents: 5
diff changeset
    85
        $db->free_result();
e04c0f64e972 SECURITY (critical): If username provided, any Yubikey could be used to log in.
Dan
parents: 5
diff changeset
    86
        return array(
e04c0f64e972 SECURITY (critical): If username provided, any Yubikey could be used to log in.
Dan
parents: 5
diff changeset
    87
            'mode' => 'error',
e04c0f64e972 SECURITY (critical): If username provided, any Yubikey could be used to log in.
Dan
parents: 5
diff changeset
    88
            'error' => 'yubiauth_err_key_not_authorized'
e04c0f64e972 SECURITY (critical): If username provided, any Yubikey could be used to log in.
Dan
parents: 5
diff changeset
    89
          );
e04c0f64e972 SECURITY (critical): If username provided, any Yubikey could be used to log in.
Dan
parents: 5
diff changeset
    90
      }
e04c0f64e972 SECURITY (critical): If username provided, any Yubikey could be used to log in.
Dan
parents: 5
diff changeset
    91
      $db->free_result();
0
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    92
      $do_validate_otp = true;
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    93
    }
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    94
  }
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    95
  else if ( !empty($userdata['yubikey_otp']) )
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    96
  {
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    97
    // we have an OTP, but no username to work with
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    98
    $yubi_uid = substr($userdata['yubikey_otp'], 0, 12);
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
    99
    if ( !preg_match('/^[cbdefghijklnrtuv]{12}$/', $yubi_uid ) )
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   100
    {
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   101
      return array(
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   102
          'mode' => 'error',
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   103
          'error' => 'yubiauth_err_invalid_otp'
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   104
        );
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   105
    }
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   106
    $q = $db->sql_query('SELECT u.user_id, u.username, u.user_yubikey_flags FROM ' . table_prefix . "users AS u\n"
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   107
                      . "  LEFT JOIN " . table_prefix . "yubikey AS y\n"
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   108
                      . "    ON ( y.user_id = u.user_id )\n"
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   109
                      . "  WHERE y.yubi_uid = '$yubi_uid'\n"
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   110
                      . "  GROUP BY u.user_yubikey_flags;");
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   111
    if ( !$q )
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   112
      $db->_die();
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   113
    
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   114
    if ( $db->numrows() < 1 )
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   115
    {
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   116
      if ( !$do_validate_pass )
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   117
        $session->sql('INSERT INTO ' . table_prefix . "logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES\n"
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   118
                   . '  (\'security\', \'' . $auth_log_prefix . 'auth_bad\', '.time().', \''.enano_date('d M Y h:i a').'\', \'(Yubikey)\', '
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   119
                      . '\''.$db->escape($_SERVER['REMOTE_ADDR']).'\', ' . intval($level) . ')');
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   120
      
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   121
      return array(
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   122
          'mode' => 'error',
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   123
          'error' => 'yubiauth_err_key_not_authorized'
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   124
        );
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   125
    }
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   126
    
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   127
    list($user_id, $username, $flags) = $db->fetchrow_num();
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   128
    $do_validate_otp = true;
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   129
    $do_validate_user = $flags & $user_flag;
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   130
    $do_validate_pass = $flags & $pass_flag;
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   131
  }
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   132
  else
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   133
  {
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   134
    // Nothing - no username or OTP. This request can't be used; throw it out.
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   135
    return array(
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   136
        'mode' => 'error',
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   137
        'error' => 'yubiauth_err_nothing_provided'
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   138
      );
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   139
  }
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   140
  if ( $do_validate_otp )
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   141
  {
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   142
    // We need to validate the OTP.
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   143
    $otp_check = yubikey_validate_otp($userdata['yubikey_otp']);
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   144
    if ( !$otp_check['success'] )
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   145
    {
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   146
      if ( !$do_validate_pass )
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   147
        $session->sql('INSERT INTO ' . table_prefix . "logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES\n"
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   148
                   . '  (\'security\', \'' . $auth_log_prefix . 'auth_bad\', '.time().', \''.enano_date('d M Y h:i a').'\', \'(Yubikey)\', '
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   149
                      . '\''.$db->escape($_SERVER['REMOTE_ADDR']).'\', ' . intval($level) . ')');
17
e04c0f64e972 SECURITY (critical): If username provided, any Yubikey could be used to log in.
Dan
parents: 5
diff changeset
   150
      
e04c0f64e972 SECURITY (critical): If username provided, any Yubikey could be used to log in.
Dan
parents: 5
diff changeset
   151
      if ( $otp_check['error'] === 'http_failed' )
e04c0f64e972 SECURITY (critical): If username provided, any Yubikey could be used to log in.
Dan
parents: 5
diff changeset
   152
      {
e04c0f64e972 SECURITY (critical): If username provided, any Yubikey could be used to log in.
Dan
parents: 5
diff changeset
   153
        return array(
e04c0f64e972 SECURITY (critical): If username provided, any Yubikey could be used to log in.
Dan
parents: 5
diff changeset
   154
            'mode' => 'error',
e04c0f64e972 SECURITY (critical): If username provided, any Yubikey could be used to log in.
Dan
parents: 5
diff changeset
   155
            'error' => 'yubiauth_err_' . $otp_check['error'],
e04c0f64e972 SECURITY (critical): If username provided, any Yubikey could be used to log in.
Dan
parents: 5
diff changeset
   156
            'http_error' => $otp_check['http_error']
e04c0f64e972 SECURITY (critical): If username provided, any Yubikey could be used to log in.
Dan
parents: 5
diff changeset
   157
          );
e04c0f64e972 SECURITY (critical): If username provided, any Yubikey could be used to log in.
Dan
parents: 5
diff changeset
   158
      }
0
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   159
      return array(
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   160
          'mode' => 'error',
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   161
          'error' => 'yubiauth_err_' . $otp_check['error']
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   162
        );
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   163
    }
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   164
  }
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   165
  if ( $do_validate_user )
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   166
  {
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   167
    if ( empty($username) )
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   168
    {
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   169
      return array(
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   170
          'mode' => 'error',
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   171
          'error' => 'yubiauth_err_must_have_username'
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   172
        );
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   173
    }
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   174
    if ( strtolower($username) !== strtolower($userdata['username']) )
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   175
    {
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   176
      // Username incorrect
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   177
      if ( !$do_validate_pass )
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   178
        $session->sql('INSERT INTO ' . table_prefix . "logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES\n"
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   179
                   . '  (\'security\', \'' . $auth_log_prefix . 'auth_bad\', '.time().', \''.enano_date('d M Y h:i a').'\', \'(Yubikey)\', '
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   180
                      . '\''.$db->escape($_SERVER['REMOTE_ADDR']).'\', ' . intval($level) . ')');
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   181
      return array(
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   182
          'mode' => 'error',
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   183
          'error' => 'invalid_credentials'
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   184
        );
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   185
    }
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   186
  }
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   187
  // Do we need to have the password validated?
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   188
  if ( $do_validate_pass )
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   189
  {
5
2114640729a5 Auth: added string for pass required
Dan
parents: 3
diff changeset
   190
    if ( empty($userdata['password']) )
2114640729a5 Auth: added string for pass required
Dan
parents: 3
diff changeset
   191
    {
2114640729a5 Auth: added string for pass required
Dan
parents: 3
diff changeset
   192
      return array(
2114640729a5 Auth: added string for pass required
Dan
parents: 3
diff changeset
   193
          'mode' => 'error',
2114640729a5 Auth: added string for pass required
Dan
parents: 3
diff changeset
   194
          'error' => 'yubiauth_err_must_have_password'
2114640729a5 Auth: added string for pass required
Dan
parents: 3
diff changeset
   195
        );
2114640729a5 Auth: added string for pass required
Dan
parents: 3
diff changeset
   196
    }
0
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   197
    // Yes; return and let the login API continue
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   198
    return null;
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   199
  }
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   200
  else
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   201
  {
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   202
    // No password required; validated, issue session key
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   203
    $session->sql('INSERT INTO ' . table_prefix . "logs(log_type,action,time_id,date_string,author,edit_summary,page_text) VALUES\n"
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   204
                   . '  (\'security\', \'' . $auth_log_prefix . 'auth_good\', '.time().', \''.enano_date('d M Y h:i a').'\', \'' . $db->escape($userdata['username']) . '\', '
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   205
                      . '\''.$db->escape($_SERVER['REMOTE_ADDR']).'\', ' . intval($level) . ')');
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   206
        
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   207
    $q = $db->sql_query('SELECT password FROM ' . table_prefix . "users WHERE user_id = $user_id;");
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   208
    if ( !$q )
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   209
      $db->_die();
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   210
    
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   211
    list($password) = $db->fetchrow_num();
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   212
    $db->free_result();
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   213
    
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   214
    $session->register_session($user_id, $userdata['username'], $password, $level, $remember);
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   215
    return true;
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   216
  }
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   217
}
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   218
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   219
function yubikey_add_special_pages()
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   220
{
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   221
  global $db, $session, $paths, $template, $plugins; // Common objects
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   222
  global $lang;
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   223
  
3
d0fe7acaf0e8 Maybe we could actually make yubikey_enable in config not ignored!
Dan
parents: 2
diff changeset
   224
  if ( getConfig('yubikey_enable', '1') != '1' )
d0fe7acaf0e8 Maybe we could actually make yubikey_enable in config not ignored!
Dan
parents: 2
diff changeset
   225
    return true;
d0fe7acaf0e8 Maybe we could actually make yubikey_enable in config not ignored!
Dan
parents: 2
diff changeset
   226
  
0
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   227
  $paths->add_page(array(
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   228
      'name' => $lang->get('yubiauth_specialpage_yubikey'),
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   229
      'urlname' => 'Yubikey',
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   230
      'namespace' => 'Special',
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   231
      'visible' => 0, 'protected' => 0, 'comments_on' => 0, 'special' => 0
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   232
    ));
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   233
}
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   234
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   235
function page_Special_Yubikey()
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   236
{
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   237
  global $db, $session, $paths, $template, $plugins; // Common objects
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   238
  
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   239
  header('Content-type: text/javascript');
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   240
  /*
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   241
  if ( isset($_GET['validate_otp']) )
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   242
  {
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   243
    echo enano_json_encode(yubikey_validate_otp($_GET['validate_otp']));
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   244
    return true;
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   245
  }
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   246
  */
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   247
  if ( isset($_GET['get_flags']) || isset($_POST['get_flags']) )
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   248
  {
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   249
    $yubi_uid = substr($_REQUEST['get_flags'], 0, 12);
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   250
    if ( !preg_match('/^[cbdefghijklnrtuv]{12}$/', $yubi_uid) )
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   251
    {
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   252
      return print enano_json_encode(array(
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   253
          'mode' => 'error',
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   254
          'error' => 'invalid_otp'
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   255
        ));
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   256
    }
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   257
    $q = $db->sql_query('SELECT u.user_yubikey_flags FROM ' . table_prefix . "users AS u\n"
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   258
                      . "  LEFT JOIN " . table_prefix . "yubikey AS y\n"
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   259
                      . "    ON ( y.user_id = u.user_id )\n"
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   260
                      . "  WHERE y.yubi_uid = '$yubi_uid'\n"
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   261
                      . "  GROUP BY u.user_yubikey_flags;");
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   262
    if ( !$q )
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   263
      $db->_die();
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   264
    
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   265
    if ( $db->numrows() < 1 )
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   266
    {
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   267
      return print enano_json_encode(array(
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   268
          'mode' => 'error',
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   269
          'error' => 'key_not_authorized'
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   270
        ));
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   271
    }
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   272
    
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   273
    list($flags) = $db->fetchrow_num();
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   274
    
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   275
    echo enano_json_encode(array(
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   276
        // We strip YK_SEC_ALLOW_NO_OTP here for security reasons.
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   277
        'flags' => intval($flags & ~YK_SEC_ALLOW_NO_OTP)
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   278
      ));
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   279
    
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   280
    return true;
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   281
  }
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   282
}
9d2c4f04a0d0 First commit! Hoping everything works.
Dan
parents:
diff changeset
   283