diff --git a/includes/AuthUtility.php b/includes/AuthUtility.php index f57e97e0..59dad869 100644 --- a/includes/AuthUtility.php +++ b/includes/AuthUtility.php @@ -8,6 +8,8 @@ namespace Waca; +use Waca\Helpers\HttpHelper; + class AuthUtility { /** @@ -33,6 +35,10 @@ class AuthUtility // syntax: :1:SALT:HASH // syntax: :2:x:HASH + if ($data[0] == 'Y') { + return self::verifyYubikey($password, $data[1]); + } + // check the version is one of the allowed ones: if ($minimumPasswordVersion > $data[0]) { return false; @@ -56,7 +62,7 @@ class AuthUtility */ public static function isCredentialVersionLatest($credentials) { - return substr($credentials, 0, 3) === ":2:"; + return substr($credentials, 0, 3) === ":2:" || substr($credentials, 0, 3) === ":Y:"; } /** @@ -102,4 +108,32 @@ class AuthUtility { return password_verify($password, $hash); } + + private static function verifyYubikey($provided, $stored) + { + if ($stored !== substr($provided, 0, 12)) { + // different yubikey + return false; + } + + $httpHelper = new HttpHelper('waca/0.0 (+mailto:simon@stwalkerster.co.uk)', true); + + $result = $httpHelper->get('https://api2.yubico.com/wsapi/2.0/verify', array( + 'id' => 31958, + 'otp' => $provided, + 'nonce' => md5(openssl_random_pseudo_bytes(64)) + )); + + $data = array(); + foreach (explode("\r\n", $result) as $line) { + $pos = strpos($line, '='); + if ($pos === false) { + continue; + } + + $data[substr($line, 0, $pos)] = substr($line, $pos + 1); + } + + return $data['status'] == 'OK'; + } }