yms/backend.php
author Dan Fuhry <dan@enanocms.org>
Wed, 11 Jan 2017 13:02:34 +0000
changeset 12 31387f4022e5
parent 4 9fdc988ce46e
child 13 8a8cdc21aa15
permissions -rw-r--r--
Tolerate up to 0.5Hz difference in OTP timestamps I've received complaints of OTP validation failures during the trial rollout at Datto. I dumped a few OTPs along with the times of validation and found that the user's Yubikey was running its oscillator at 8.32Hz. This commit adds tolerance for up to 0.5Hz of variation to the OTP's timestamp field.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
     1
<?php
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
     2
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
     3
function yms_add_yubikey($key, $otp, $client_id = false, $enabled = true, $any_client = false, $notes = false)
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
     4
{
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
     5
  global $db, $session, $paths, $template, $plugins; // Common objects
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
     6
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
     7
  if ( $client_id === false )
4
9fdc988ce46e Added counter and ANY_CLIENT settings to ShowAESKey; Significant improvements to claim system: Added master switch for the whole system; Added ability for administrators to "su" to client ID 0 to manage pooled keys; Added ability for admins to release key when it is added
Dan
parents: 2
diff changeset
     8
    $client_id = $GLOBALS['yms_client_id'];
0
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
     9
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    10
  $key = yms_tobinary($key);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    11
  $otp = yms_tobinary($otp);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    12
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    13
  if ( strlen($key) != 16 )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    14
  {
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    15
    return 'yms_err_addkey_invalid_key';
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    16
  }
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    17
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    18
  if ( strlen($otp) != 22 )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    19
  {
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    20
    return 'yms_err_addkey_invalid_otp';
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    21
  }
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    22
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    23
  $otpdata = yms_decode_otp($otp, $key);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    24
  if ( $otpdata === false )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    25
  {
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    26
    return 'yms_err_addkey_invalid_otp';
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    27
  }
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    28
  if ( !$otpdata['crc_good'] )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    29
  {
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    30
    return 'yms_err_addkey_crc_failed';
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    31
  }
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    32
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    33
  // make sure it's not already in there
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    34
  $q = $db->sql_query('SELECT 1 FROM ' . table_prefix . "yms_yubikeys WHERE public_id = '{$otpdata['publicid']}';");
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    35
  if ( !$q )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    36
    $db->_die();
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    37
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    38
  if ( $db->numrows() > 0 )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    39
  {
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    40
    $db->free_result();
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    41
    return 'yms_err_addkey_key_exists';
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    42
  }
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    43
  $db->free_result();
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    44
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    45
  $now = time();
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    46
  $key = yms_hex_encode($key);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    47
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    48
  $flags = 0;
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    49
  if ( $enabled )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    50
    $flags |= YMS_ENABLED;
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    51
  if ( $any_client )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    52
    $flags |= YMS_ANY_CLIENT;
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    53
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    54
  $notes = $notes ? $db->escape(strval($notes)) : '';
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    55
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    56
  $q = $db->sql_query("INSERT INTO " . table_prefix . "yms_yubikeys(client_id, public_id, private_id, session_count, token_count, create_time, access_time, token_time, aes_secret, flags, notes) VALUES\n"
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    57
         . "  ($client_id, '{$otpdata['publicid']}', '{$otpdata['privateid']}', {$otpdata['session']}, {$otpdata['count']}, $now, $now, {$otpdata['timestamp']}, '$key', $flags, '$notes');");
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    58
  if ( !$q )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    59
    $db->_die();
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    60
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    61
  return true;
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    62
}
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    63
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    64
function yms_chown_yubikey($otp, $client_id = false, $enabled = true, $any_client = false, $notes = false)
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    65
{
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    66
  global $db, $session, $paths, $template, $plugins; // Common objects
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    67
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    68
  if ( $client_id === false )
4
9fdc988ce46e Added counter and ANY_CLIENT settings to ShowAESKey; Significant improvements to claim system: Added master switch for the whole system; Added ability for administrators to "su" to client ID 0 to manage pooled keys; Added ability for admins to release key when it is added
Dan
parents: 2
diff changeset
    69
    $client_id = $GLOBALS['yms_client_id'];
0
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    70
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    71
  $otp = yms_tobinary($otp);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    72
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    73
  if ( strlen($otp) != 22 )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    74
  {
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    75
    return 'yms_err_addkey_invalid_otp';
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    76
  }
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    77
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    78
  $public_id = yms_hex_encode(substr($otp, 0, 6));
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    79
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    80
  // make sure it's already in there
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    81
  $q = $db->sql_query('SELECT id FROM ' . table_prefix . "yms_yubikeys WHERE public_id = '{$public_id}' AND client_id = 0;");
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    82
  if ( !$q )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    83
    $db->_die();
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    84
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    85
  if ( $db->numrows() < 1 )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    86
  {
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    87
    // this should never happen, as the OTP is put through validation before this function is called
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    88
    $db->free_result();
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    89
    return 'yms_err_claimkey_owner_invalid';
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    90
  }
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    91
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    92
  list($key_id) = $db->fetchrow_num();
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    93
  $db->free_result();
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    94
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    95
  $now = time();
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    96
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    97
  $flags = 0;
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    98
  if ( $enabled )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
    99
    $flags |= YMS_ENABLED;
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   100
  if ( $any_client )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   101
    $flags |= YMS_ANY_CLIENT;
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   102
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   103
  $notes = $notes ? $db->escape(strval($notes)) : '';
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   104
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   105
  $q = $db->sql_query("UPDATE " . table_prefix . "yms_yubikeys SET flags = $flags, notes = '$notes', client_id = $client_id WHERE id = $key_id;");
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   106
  if ( !$q )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   107
    $db->_die();
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   108
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   109
  return true;
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   110
}
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   111
2
bbdd428926b9 Added key deletion.
Dan
parents: 0
diff changeset
   112
function yms_delete_key($id, $client_id = false)
bbdd428926b9 Added key deletion.
Dan
parents: 0
diff changeset
   113
{
bbdd428926b9 Added key deletion.
Dan
parents: 0
diff changeset
   114
  global $db, $session, $paths, $template, $plugins; // Common objects
bbdd428926b9 Added key deletion.
Dan
parents: 0
diff changeset
   115
  
bbdd428926b9 Added key deletion.
Dan
parents: 0
diff changeset
   116
  if ( $client_id === false )
4
9fdc988ce46e Added counter and ANY_CLIENT settings to ShowAESKey; Significant improvements to claim system: Added master switch for the whole system; Added ability for administrators to "su" to client ID 0 to manage pooled keys; Added ability for admins to release key when it is added
Dan
parents: 2
diff changeset
   117
    $client_id = $GLOBALS['yms_client_id'];
2
bbdd428926b9 Added key deletion.
Dan
parents: 0
diff changeset
   118
  
bbdd428926b9 Added key deletion.
Dan
parents: 0
diff changeset
   119
  $q = $db->sql_query('SELECT 1 FROM ' . table_prefix . "yms_yubikeys WHERE id = $id AND client_id = $client_id;");
bbdd428926b9 Added key deletion.
Dan
parents: 0
diff changeset
   120
  if ( !$q )
bbdd428926b9 Added key deletion.
Dan
parents: 0
diff changeset
   121
    $db->_die();
bbdd428926b9 Added key deletion.
Dan
parents: 0
diff changeset
   122
  
bbdd428926b9 Added key deletion.
Dan
parents: 0
diff changeset
   123
  if ( $db->numrows() < 1 )
bbdd428926b9 Added key deletion.
Dan
parents: 0
diff changeset
   124
  {
bbdd428926b9 Added key deletion.
Dan
parents: 0
diff changeset
   125
    $db->free_result();
bbdd428926b9 Added key deletion.
Dan
parents: 0
diff changeset
   126
    return 'yms_err_delete_not_found';
bbdd428926b9 Added key deletion.
Dan
parents: 0
diff changeset
   127
  }
bbdd428926b9 Added key deletion.
Dan
parents: 0
diff changeset
   128
  $db->free_result();
bbdd428926b9 Added key deletion.
Dan
parents: 0
diff changeset
   129
  
bbdd428926b9 Added key deletion.
Dan
parents: 0
diff changeset
   130
  $q = $db->sql_query('DELETE FROM ' . table_prefix . "yms_yubikeys WHERE id = $id AND client_id = $client_id;");
bbdd428926b9 Added key deletion.
Dan
parents: 0
diff changeset
   131
  if ( !$q )
bbdd428926b9 Added key deletion.
Dan
parents: 0
diff changeset
   132
    $db->_die();
bbdd428926b9 Added key deletion.
Dan
parents: 0
diff changeset
   133
  
bbdd428926b9 Added key deletion.
Dan
parents: 0
diff changeset
   134
  return true;
bbdd428926b9 Added key deletion.
Dan
parents: 0
diff changeset
   135
}
bbdd428926b9 Added key deletion.
Dan
parents: 0
diff changeset
   136
0
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   137
function yms_validate_custom_field($value, $otp, $url)
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   138
{
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   139
  require_once(ENANO_ROOT . '/includes/http.php');
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   140
  $url = strtr($url, array(
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   141
      '%c' => rawurlencode($value),
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   142
      '%o' => rawurlencode($otp)
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   143
    ));
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   144
  // do we need to sign this?
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   145
  if ( strstr($url, '%h') && ($key = getConfig('yms_claim_auth_key', false)) )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   146
  {
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   147
    list(, $signpart) = explode('?', $url);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   148
    $signpart = preg_replace('/(&h=%h|^h=%h&)/', '', $signpart);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   149
    $signpart = yms_ksort_url($signpart);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   150
    
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   151
    $key = yms_tobinary($key);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   152
    $key = yms_hex_encode($key);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   153
    $hash = hmac_sha1($signpart, $key);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   154
    $hash = yms_hex_decode($hash);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   155
    $hash = base64_encode($hash);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   156
    
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   157
    $url = str_replace('%h', rawurlencode($hash), $url);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   158
  }
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   159
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   160
  // run authentication
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   161
  $result = yms_get_url($url);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   162
  $result = yms_parse_auth_result($result, $key);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   163
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   164
  if ( !$result['sig_valid'] )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   165
    return 'yubiauth_err_response_bad_signature';
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   166
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   167
  if ( $result['status'] !== 'OK' )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   168
  {
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   169
    if ( preg_match('/^[A-Z_]+$/', $result['status']) )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   170
      return 'yubiauth_err_response_' . strtolower($result['status']);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   171
    else
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   172
      return $result['status'];
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   173
  }
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   174
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   175
  // authentication is ok
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   176
  return true;
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   177
}
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   178
4
9fdc988ce46e Added counter and ANY_CLIENT settings to ShowAESKey; Significant improvements to claim system: Added master switch for the whole system; Added ability for administrators to "su" to client ID 0 to manage pooled keys; Added ability for admins to release key when it is added
Dan
parents: 2
diff changeset
   179
function yms_update_counters($id, $scount, $tcount, $client_id = false, $any_client = null)
9fdc988ce46e Added counter and ANY_CLIENT settings to ShowAESKey; Significant improvements to claim system: Added master switch for the whole system; Added ability for administrators to "su" to client ID 0 to manage pooled keys; Added ability for admins to release key when it is added
Dan
parents: 2
diff changeset
   180
{
9fdc988ce46e Added counter and ANY_CLIENT settings to ShowAESKey; Significant improvements to claim system: Added master switch for the whole system; Added ability for administrators to "su" to client ID 0 to manage pooled keys; Added ability for admins to release key when it is added
Dan
parents: 2
diff changeset
   181
  global $db, $session, $paths, $template, $plugins; // Common objects
9fdc988ce46e Added counter and ANY_CLIENT settings to ShowAESKey; Significant improvements to claim system: Added master switch for the whole system; Added ability for administrators to "su" to client ID 0 to manage pooled keys; Added ability for admins to release key when it is added
Dan
parents: 2
diff changeset
   182
  
9fdc988ce46e Added counter and ANY_CLIENT settings to ShowAESKey; Significant improvements to claim system: Added master switch for the whole system; Added ability for administrators to "su" to client ID 0 to manage pooled keys; Added ability for admins to release key when it is added
Dan
parents: 2
diff changeset
   183
  if ( !$client_id )
9fdc988ce46e Added counter and ANY_CLIENT settings to ShowAESKey; Significant improvements to claim system: Added master switch for the whole system; Added ability for administrators to "su" to client ID 0 to manage pooled keys; Added ability for admins to release key when it is added
Dan
parents: 2
diff changeset
   184
    $client_id = intval($GLOBALS['yms_client_id']);
9fdc988ce46e Added counter and ANY_CLIENT settings to ShowAESKey; Significant improvements to claim system: Added master switch for the whole system; Added ability for administrators to "su" to client ID 0 to manage pooled keys; Added ability for admins to release key when it is added
Dan
parents: 2
diff changeset
   185
  
9fdc988ce46e Added counter and ANY_CLIENT settings to ShowAESKey; Significant improvements to claim system: Added master switch for the whole system; Added ability for administrators to "su" to client ID 0 to manage pooled keys; Added ability for admins to release key when it is added
Dan
parents: 2
diff changeset
   186
  foreach ( array($id, $scount, $tcount, $client_id) as $var )
9fdc988ce46e Added counter and ANY_CLIENT settings to ShowAESKey; Significant improvements to claim system: Added master switch for the whole system; Added ability for administrators to "su" to client ID 0 to manage pooled keys; Added ability for admins to release key when it is added
Dan
parents: 2
diff changeset
   187
    if ( (!is_int($var) && !is_string($var)) || (is_string($var) && !ctype_digit($var)) )
9fdc988ce46e Added counter and ANY_CLIENT settings to ShowAESKey; Significant improvements to claim system: Added master switch for the whole system; Added ability for administrators to "su" to client ID 0 to manage pooled keys; Added ability for admins to release key when it is added
Dan
parents: 2
diff changeset
   188
      return "yms_err_expected_int";
9fdc988ce46e Added counter and ANY_CLIENT settings to ShowAESKey; Significant improvements to claim system: Added master switch for the whole system; Added ability for administrators to "su" to client ID 0 to manage pooled keys; Added ability for admins to release key when it is added
Dan
parents: 2
diff changeset
   189
    
9fdc988ce46e Added counter and ANY_CLIENT settings to ShowAESKey; Significant improvements to claim system: Added master switch for the whole system; Added ability for administrators to "su" to client ID 0 to manage pooled keys; Added ability for admins to release key when it is added
Dan
parents: 2
diff changeset
   190
  $any_client_sql = '';
9fdc988ce46e Added counter and ANY_CLIENT settings to ShowAESKey; Significant improvements to claim system: Added master switch for the whole system; Added ability for administrators to "su" to client ID 0 to manage pooled keys; Added ability for admins to release key when it is added
Dan
parents: 2
diff changeset
   191
  if ( is_bool($any_client) )
9fdc988ce46e Added counter and ANY_CLIENT settings to ShowAESKey; Significant improvements to claim system: Added master switch for the whole system; Added ability for administrators to "su" to client ID 0 to manage pooled keys; Added ability for admins to release key when it is added
Dan
parents: 2
diff changeset
   192
  {
9fdc988ce46e Added counter and ANY_CLIENT settings to ShowAESKey; Significant improvements to claim system: Added master switch for the whole system; Added ability for administrators to "su" to client ID 0 to manage pooled keys; Added ability for admins to release key when it is added
Dan
parents: 2
diff changeset
   193
    $operand = $any_client ? "|" : "& ~";
9fdc988ce46e Added counter and ANY_CLIENT settings to ShowAESKey; Significant improvements to claim system: Added master switch for the whole system; Added ability for administrators to "su" to client ID 0 to manage pooled keys; Added ability for admins to release key when it is added
Dan
parents: 2
diff changeset
   194
    $any_client_sql = ", flags = flags " . $operand . YMS_ANY_CLIENT;
9fdc988ce46e Added counter and ANY_CLIENT settings to ShowAESKey; Significant improvements to claim system: Added master switch for the whole system; Added ability for administrators to "su" to client ID 0 to manage pooled keys; Added ability for admins to release key when it is added
Dan
parents: 2
diff changeset
   195
  }
9fdc988ce46e Added counter and ANY_CLIENT settings to ShowAESKey; Significant improvements to claim system: Added master switch for the whole system; Added ability for administrators to "su" to client ID 0 to manage pooled keys; Added ability for admins to release key when it is added
Dan
parents: 2
diff changeset
   196
    
9fdc988ce46e Added counter and ANY_CLIENT settings to ShowAESKey; Significant improvements to claim system: Added master switch for the whole system; Added ability for administrators to "su" to client ID 0 to manage pooled keys; Added ability for admins to release key when it is added
Dan
parents: 2
diff changeset
   197
  $q = $db->sql_query('UPDATE ' . table_prefix . "yms_yubikeys SET session_count = {$scount}, token_count = {$tcount}{$any_client_sql} WHERE id = $id AND client_id = $client_id");
9fdc988ce46e Added counter and ANY_CLIENT settings to ShowAESKey; Significant improvements to claim system: Added master switch for the whole system; Added ability for administrators to "su" to client ID 0 to manage pooled keys; Added ability for admins to release key when it is added
Dan
parents: 2
diff changeset
   198
  if ( !$q )
9fdc988ce46e Added counter and ANY_CLIENT settings to ShowAESKey; Significant improvements to claim system: Added master switch for the whole system; Added ability for administrators to "su" to client ID 0 to manage pooled keys; Added ability for admins to release key when it is added
Dan
parents: 2
diff changeset
   199
    $db->_die();
9fdc988ce46e Added counter and ANY_CLIENT settings to ShowAESKey; Significant improvements to claim system: Added master switch for the whole system; Added ability for administrators to "su" to client ID 0 to manage pooled keys; Added ability for admins to release key when it is added
Dan
parents: 2
diff changeset
   200
  
9fdc988ce46e Added counter and ANY_CLIENT settings to ShowAESKey; Significant improvements to claim system: Added master switch for the whole system; Added ability for administrators to "su" to client ID 0 to manage pooled keys; Added ability for admins to release key when it is added
Dan
parents: 2
diff changeset
   201
  return true;
9fdc988ce46e Added counter and ANY_CLIENT settings to ShowAESKey; Significant improvements to claim system: Added master switch for the whole system; Added ability for administrators to "su" to client ID 0 to manage pooled keys; Added ability for admins to release key when it is added
Dan
parents: 2
diff changeset
   202
}
9fdc988ce46e Added counter and ANY_CLIENT settings to ShowAESKey; Significant improvements to claim system: Added master switch for the whole system; Added ability for administrators to "su" to client ID 0 to manage pooled keys; Added ability for admins to release key when it is added
Dan
parents: 2
diff changeset
   203
0
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   204
function yms_get_url($url)
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   205
{
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   206
  require_once(ENANO_ROOT . '/includes/http.php');
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   207
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   208
  $url = preg_replace('#^https?://#i', '', $url);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   209
  if ( !preg_match('#^(\[?[a-z0-9-:]+(?:\.[a-z0-9-:]+\]?)*)(?::([0-9]+))?(/.*)$#U', $url, $match) )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   210
  {
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   211
    return 'invalid_auth_url';
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   212
  }
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   213
  $server =& $match[1];
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   214
  $port = ( !empty($match[2]) ) ? intval($match[2]) : 80;
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   215
  $uri =& $match[3];
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   216
  try
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   217
  {
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   218
    $req = new Request_HTTP($server, $uri, 'GET', $port);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   219
    $response = $req->get_response_body();
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   220
  }
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   221
  catch ( Exception $e )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   222
  {
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   223
    return 'http_failed:' . $e->getMessage();
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   224
  }
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   225
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   226
  if ( $req->response_code !== HTTP_OK )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   227
    return 'http_failed_status:' . $req->response_code;
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   228
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   229
  return $response;
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   230
}
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   231
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   232
function yms_parse_auth_result($result, $api_key = false)
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   233
{
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   234
  $result = explode("\n", trim($result));
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   235
  $arr = array();
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   236
  foreach ( $result as $line )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   237
  {
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   238
    list($name) = explode('=', $line);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   239
    $value = substr($line, strlen($name) + 1);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   240
    $arr[$name] = $value;
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   241
  }
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   242
  // signature check
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   243
  if ( $api_key )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   244
  {
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   245
    $signarr = $arr;
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   246
    ksort($signarr);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   247
    unset($signarr['h']);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   248
    $signpart = array();
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   249
    foreach ( $signarr as $name => $value )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   250
      $signpart[] = "{$name}={$value}";
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   251
    
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   252
    $signpart = implode('&', $signpart);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   253
    $api_key = yms_hex_encode(yms_tobinary($api_key));
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   254
    $right_sig = base64_encode(yms_hex_decode(
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   255
                   hmac_sha1($signpart, $api_key)
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   256
                 ));
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   257
    $arr['sig_valid'] = ( $arr['h'] === $right_sig );
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   258
  }
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   259
  else
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   260
  {
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   261
    $arr['sig_valid'] = true;
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   262
  }
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   263
  return $arr;
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   264
}
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   265
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   266
function yms_ksort_url($signpart)
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   267
{
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   268
  $arr = array();
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   269
  $values = explode('&', $signpart);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   270
  foreach ( $values as $var )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   271
  {
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   272
    list($name) = explode('=', $var);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   273
    $value = substr($var, strlen($name) + 1);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   274
    $arr[$name] = $value;
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   275
  }
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   276
  ksort($arr);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   277
  $result = array();
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   278
  foreach ( $arr as $name => $value )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   279
  {
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   280
    $result[] = "{$name}={$value}";
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   281
  }
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   282
  return implode('&', $result);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   283
}
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   284
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   285
function yms_validate_otp($otp, $id)
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   286
{
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   287
  global $db, $session, $paths, $template, $plugins; // Common objects
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   288
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   289
  $public_id = yms_modhex_decode(substr($otp, 0, 12));
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   290
  if ( !$public_id )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   291
  {
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   292
    return 'BAD_OTP';
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   293
  }
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   294
  // Just in case
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   295
  $public_id = $db->escape($public_id);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   296
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   297
  $q = $db->sql_query("SELECT id, private_id, session_count, token_count, access_time, token_time, aes_secret, flags, client_id FROM " . table_prefix . "yms_yubikeys WHERE ( client_id = 0 or client_id = $id OR flags & " . YMS_ANY_CLIENT . " ) AND public_id = '$public_id';");
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   298
  if ( !$q )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   299
    $db->_die();
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   300
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   301
  if ( $db->numrows($q) < 1 )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   302
  {
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   303
    return 'NO_SUCH_KEY';
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   304
  }
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   305
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   306
  list($yubikey_id, $private_id, $session_count, $token_count, $access_time, $token_time, $aes_secret, $flags, $client_id) = $db->fetchrow_num($q);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   307
  $session_count = intval($session_count);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   308
  $token_count = intval($token_count);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   309
  $access_time = intval($access_time);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   310
  $token_time = intval($token_time);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   311
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   312
  // check flags
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   313
  if ( $client_id > 0 )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   314
  {
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   315
    if ( !($flags & YMS_ANY_CLIENT) )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   316
    {
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   317
      return 'NO_SUCH_KEY';
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   318
    }
4
9fdc988ce46e Added counter and ANY_CLIENT settings to ShowAESKey; Significant improvements to claim system: Added master switch for the whole system; Added ability for administrators to "su" to client ID 0 to manage pooled keys; Added ability for admins to release key when it is added
Dan
parents: 2
diff changeset
   319
  }
9fdc988ce46e Added counter and ANY_CLIENT settings to ShowAESKey; Significant improvements to claim system: Added master switch for the whole system; Added ability for administrators to "su" to client ID 0 to manage pooled keys; Added ability for admins to release key when it is added
Dan
parents: 2
diff changeset
   320
  if ( !($flags & YMS_ENABLED) )
9fdc988ce46e Added counter and ANY_CLIENT settings to ShowAESKey; Significant improvements to claim system: Added master switch for the whole system; Added ability for administrators to "su" to client ID 0 to manage pooled keys; Added ability for admins to release key when it is added
Dan
parents: 2
diff changeset
   321
  {
9fdc988ce46e Added counter and ANY_CLIENT settings to ShowAESKey; Significant improvements to claim system: Added master switch for the whole system; Added ability for administrators to "su" to client ID 0 to manage pooled keys; Added ability for admins to release key when it is added
Dan
parents: 2
diff changeset
   322
    return 'NO_SUCH_KEY';
0
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   323
  }
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   324
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   325
  // decode the OTP
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   326
  $otp = yms_decode_otp($otp, $aes_secret);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   327
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   328
  // check CRC
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   329
  if ( !$otp['crc_good'] )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   330
  {
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   331
    return 'BAD_OTP';
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   332
  }
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   333
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   334
  // check private UID (avoids combining a whitelisted known public UID with the increment part of a malicious token)
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   335
  if ( $private_id !== $otp['privateid'] )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   336
  {
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   337
    return 'BAD_OTP';
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   338
  }
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   339
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   340
  // check counters
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   341
  if ( $otp['session'] < $session_count )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   342
  {
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   343
    return 'REPLAYED_OTP';
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   344
  }
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   345
  if ( $otp['session'] == $session_count && $otp['count'] <= $token_count )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   346
  {
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   347
    return 'REPLAYED_OTP';
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   348
  }
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   349
  
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   350
  // check timestamp
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   351
  if ( $otp['session'] == $session_count )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   352
  {
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   353
    $expect_delta = time() - $access_time;
12
31387f4022e5 Tolerate up to 0.5Hz difference in OTP timestamps
Dan Fuhry <dan@enanocms.org>
parents: 4
diff changeset
   354
    // Tolerate up to a 0.5Hz deviance from 8Hz. I've observed Yubikey
31387f4022e5 Tolerate up to 0.5Hz difference in OTP timestamps
Dan Fuhry <dan@enanocms.org>
parents: 4
diff changeset
   355
    // clocks running at 8.32Hz
31387f4022e5 Tolerate up to 0.5Hz difference in OTP timestamps
Dan Fuhry <dan@enanocms.org>
parents: 4
diff changeset
   356
    $actual_delta = $otp['timestamp'] - $token_time;
31387f4022e5 Tolerate up to 0.5Hz difference in OTP timestamps
Dan Fuhry <dan@enanocms.org>
parents: 4
diff changeset
   357
    $fuzz = 150 + round(($actual_delta / 7.5) - ($actual_delta / 8.5));
31387f4022e5 Tolerate up to 0.5Hz difference in OTP timestamps
Dan Fuhry <dan@enanocms.org>
parents: 4
diff changeset
   358
    // Now that we've calculated fuzz, convert the actual delta to quasi-seconds
31387f4022e5 Tolerate up to 0.5Hz difference in OTP timestamps
Dan Fuhry <dan@enanocms.org>
parents: 4
diff changeset
   359
    $actual_delta /= 8;
0
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   360
    if ( !yms_within($expect_delta, $actual_delta, $fuzz) )
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   361
    {
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   362
      // if we have a likely wraparound, just pass it
12
31387f4022e5 Tolerate up to 0.5Hz difference in OTP timestamps
Dan Fuhry <dan@enanocms.org>
parents: 4
diff changeset
   363
      if ( !($token_time > 0xe80000 && $otp['timestamp'] < 0x080000) )
0
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   364
      {
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   365
        return 'BAD_OTP';
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   366
      }
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   367
    }
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   368
    // $debug_array = array('ts_debug_delta_expected' => $expect_delta, 'ts_debug_delta_received' => $actual_delta);
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   369
  }
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   370
  
12
31387f4022e5 Tolerate up to 0.5Hz difference in OTP timestamps
Dan Fuhry <dan@enanocms.org>
parents: 4
diff changeset
   371
  // update DB
31387f4022e5 Tolerate up to 0.5Hz difference in OTP timestamps
Dan Fuhry <dan@enanocms.org>
parents: 4
diff changeset
   372
  $q = $db->sql_query("UPDATE " . table_prefix . "yms_yubikeys SET session_count = {$otp['session']}, token_count = {$otp['count']}, access_time = " . time() . ", token_time = {$otp['timestamp']} WHERE id = $yubikey_id;");
31387f4022e5 Tolerate up to 0.5Hz difference in OTP timestamps
Dan Fuhry <dan@enanocms.org>
parents: 4
diff changeset
   373
  if ( !$q )
31387f4022e5 Tolerate up to 0.5Hz difference in OTP timestamps
Dan Fuhry <dan@enanocms.org>
parents: 4
diff changeset
   374
    $db->_die();
31387f4022e5 Tolerate up to 0.5Hz difference in OTP timestamps
Dan Fuhry <dan@enanocms.org>
parents: 4
diff changeset
   375
  
0
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   376
  // looks like we're good
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   377
  return 'OK';
9997bee9ad03 First commit. Lacks key deletion support and an admin CP for controlling options.
Dan
parents:
diff changeset
   378
}