]> git.wh0rd.org - tt-rss.git/commitdiff
move OTPHP to vendor/; additionally move Base32 class to OTPHP namespace
authorAndrew Dolgov <noreply@fakecake.org>
Wed, 20 Jun 2018 15:27:34 +0000 (18:27 +0300)
committerAndrew Dolgov <noreply@fakecake.org>
Wed, 20 Jun 2018 15:27:34 +0000 (18:27 +0300)
14 files changed:
classes/pref/prefs.php
lib/otphp/LICENCE [deleted file]
lib/otphp/lib/hotp.php [deleted file]
lib/otphp/lib/otp.php [deleted file]
lib/otphp/lib/otphp.php [deleted file]
lib/otphp/lib/totp.php [deleted file]
lib/otphp/vendor/base32.php [deleted file]
lib/otphp/vendor/libs.php [deleted file]
vendor/OTPHP/Base32.php [new file with mode: 0644]
vendor/OTPHP/HOTP.php [new file with mode: 0644]
vendor/OTPHP/LICENCE [new file with mode: 0644]
vendor/OTPHP/OTP.php [new file with mode: 0644]
vendor/OTPHP/OTPHP.php [new file with mode: 0644]
vendor/OTPHP/TOTP.php [new file with mode: 0644]

index f56048b2f4f2a8965595c1df208e266fd0efe066..da62ea70cbd950619510df2a09da32a897271403 100644 (file)
@@ -147,7 +147,7 @@ class Pref_Prefs extends Handler_Protected {
                $_SESSION["prefs_op_result"] = "reset-to-defaults";
 
                $sth = $this->pdo->prepare("DELETE FROM ttrss_user_prefs
-                       WHERE (profile = :profile OR (:profile IS NULL AND profile IS NULL)) 
+                       WHERE (profile = :profile OR (:profile IS NULL AND profile IS NULL))
                                AND owner_uid = :uid");
                $sth->execute([":profile" => $_SESSION['profile'], ":uid" => $_SESSION['uid']]);
 
@@ -848,9 +848,6 @@ class Pref_Prefs extends Handler_Protected {
        }
 
        function otpqrcode() {
-               require_once "lib/otphp/vendor/base32.php";
-               require_once "lib/otphp/lib/otp.php";
-               require_once "lib/otphp/lib/totp.php";
                require_once "lib/phpqrcode/phpqrcode.php";
 
                $sth = $this->pdo->prepare("SELECT login,salt,otp_enabled
@@ -860,7 +857,7 @@ class Pref_Prefs extends Handler_Protected {
 
                if ($row = $sth->fetch()) {
 
-                       $base32 = new Base32();
+                       $base32 = new \OTPHP\Base32();
 
                        $login = $row["login"];
                        $otp_enabled = sql_bool_to_bool($row["otp_enabled"]);
@@ -876,9 +873,6 @@ class Pref_Prefs extends Handler_Protected {
        }
 
        function otpenable() {
-               require_once "lib/otphp/vendor/base32.php";
-               require_once "lib/otphp/lib/otp.php";
-               require_once "lib/otphp/lib/totp.php";
 
                $password = clean($_REQUEST["password"]);
                $otp = clean($_REQUEST["otp"]);
@@ -894,7 +888,7 @@ class Pref_Prefs extends Handler_Protected {
 
                        if ($row = $sth->fetch()) {
 
-                               $base32 = new Base32();
+                               $base32 = new \OTPHP\Base32();
 
                                $secret = $base32->encode(sha1($row["salt"]));
                                $topt = new \OTPHP\TOTP($secret);
@@ -902,7 +896,7 @@ class Pref_Prefs extends Handler_Protected {
                                $otp_check = $topt->now();
 
                                if ($otp == $otp_check) {
-                                       $sth = $this->pdo->prepare("UPDATE ttrss_users 
+                                       $sth = $this->pdo->prepare("UPDATE ttrss_users
                                        SET otp_enabled = true WHERE id = ?");
 
                                        $sth->execute([$_SESSION['uid']]);
diff --git a/lib/otphp/LICENCE b/lib/otphp/LICENCE
deleted file mode 100644 (file)
index d14cbc2..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-Copyright (c) 2011 Le Lag 
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
diff --git a/lib/otphp/lib/hotp.php b/lib/otphp/lib/hotp.php
deleted file mode 100644 (file)
index 7092fd9..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-<?php
-/*
- * Copyright (c) 2011 Le Lag 
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
-
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-namespace OTPHP {
-  /**
-   * HOTP - One time password generator 
-   * 
-   * The HOTP class allow for the generation 
-   * and verification of one-time password using 
-   * the HOTP specified algorithm.
-   *
-   * This class is meant to be compatible with 
-   * Google Authenticator
-   *
-   * This class was originally ported from the rotp
-   * ruby library available at https://github.com/mdp/rotp
-   */
-  class HOTP extends OTP {
-    /**
-     *  Get the password for a specific counter value
-     *  @param integer $count the counter which is used to
-     *  seed the hmac hash function.
-     *  @return integer the One Time Password
-     */
-    public function at($count) {
-      return $this->generateOTP($count);
-    }
-
-
-    /**
-     * Verify if a password is valid for a specific counter value
-     *
-     * @param integer $otp the one-time password 
-     * @param integer $counter the counter value
-     * @return  bool true if the counter is valid, false otherwise
-     */
-    public function verify($otp, $counter) {
-      return ($otp == $this->at($counter));
-    }
-
-    /**
-     * Returns the uri for a specific secret for hotp method.
-     * Can be encoded as a image for simple configuration in 
-     * Google Authenticator.
-     *
-     * @param string $name the name of the account / profile
-     * @param integer $initial_count the initial counter 
-     * @return string the uri for the hmac secret
-     */
-    public function provisioning_uri($name, $initial_count) {
-      return "otpauth://hotp/".urlencode($name)."?secret={$this->secret}&counter=$initial_count";
-    }
-  }
-
-}
diff --git a/lib/otphp/lib/otp.php b/lib/otphp/lib/otp.php
deleted file mode 100644 (file)
index 77bcfe9..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-<?php
-/*
- * Copyright (c) 2011 Le Lag 
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
-
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-namespace OTPHP {
-/**
- * One Time Password Generator 
- * 
- * The OTP class allow the generation of one-time
- * password that is described in rfc 4xxx.
- * 
- * This is class is meant to be compatible with 
- * Google Authenticator.
- *
- * This class was originally ported from the rotp
- * ruby library available at https://github.com/mdp/rotp
- */
-class OTP {
-    /**
-     * The base32 encoded secret key
-     * @var string
-     */
-    public $secret;
-
-    /**
-     * The algorithm used for the hmac hash function
-     * @var string
-     */
-    public $digest;
-
-    /**
-     * The number of digits in the one-time password
-     * @var integer
-     */ 
-    public $digits;
-
-    /**
-     * Constructor for the OTP class
-     * @param string $secret the secret key
-     * @param array $opt options array can contain the
-     * following keys :
-     *   @param integer digits : the number of digits in the one time password
-     *   Currently Google Authenticator only support 6. Defaults to 6.
-     *   @param string digest : the algorithm used for the hmac hash function
-     *   Google Authenticator only support sha1. Defaults to sha1
-     *
-     * @return new OTP class.
-     */
-    public function __construct($secret, $opt = Array()) {
-      $this->digits = isset($opt['digits']) ? $opt['digits'] : 6;
-      $this->digest = isset($opt['digest']) ? $opt['digest'] : 'sha1';
-      $this->secret = $secret;
-    }
-
-    /**
-     * Generate a one-time password
-     *
-     * @param integer $input : number used to seed the hmac hash function.
-     * This number is usually a counter (HOTP) or calculated based on the current
-     * timestamp (see TOTP class).
-     * @return integer the one-time password 
-     */
-    public function generateOTP($input) {
-      $hash = hash_hmac($this->digest, $this->intToBytestring($input), $this->byteSecret());
-      foreach(str_split($hash, 2) as $hex) { // stupid PHP has bin2hex but no hex2bin WTF
-        $hmac[] = hexdec($hex);
-      }
-      $offset = $hmac[19] & 0xf;
-      $code = ($hmac[$offset+0] & 0x7F) << 24 |
-        ($hmac[$offset + 1] & 0xFF) << 16 |
-        ($hmac[$offset + 2] & 0xFF) << 8 |
-        ($hmac[$offset + 3] & 0xFF);
-      return $code % pow(10, $this->digits);
-    }
-
-    /**
-     * Returns the binary value of the base32 encoded secret
-     * @access private
-     * This method should be private but was left public for
-     * phpunit tests to work.
-     * @return binary secret key
-     */
-    public function byteSecret() {
-      return \Base32::decode($this->secret);
-    }
-
-    /**
-     * Turns an integer in a OATH bytestring
-     * @param integer $int
-     * @access private
-     * @return string bytestring
-     */
-    public function intToBytestring($int) {
-      $result = Array();
-      while($int != 0) {
-        $result[] = chr($int & 0xFF);
-        $int >>= 8;
-      }
-      return str_pad(join(array_reverse($result)), 8, "\000", STR_PAD_LEFT);
-    }
-  }
-}
diff --git a/lib/otphp/lib/otphp.php b/lib/otphp/lib/otphp.php
deleted file mode 100644 (file)
index a6c6f8d..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-<?php
-/*
- * Copyright (c) 2011 Le Lag 
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
-
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-require_once dirname(__FILE__).'/../vendor/libs.php';
-require_once dirname(__FILE__).'/otp.php';
-require_once dirname(__FILE__).'/hotp.php';
-require_once dirname(__FILE__).'/totp.php';
-
diff --git a/lib/otphp/lib/totp.php b/lib/otphp/lib/totp.php
deleted file mode 100644 (file)
index 10a1f42..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-<?php
-/*
- * Copyright (c) 2011 Le Lag 
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
-
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-namespace OTPHP {
-  /**
-   * TOTP - One time password generator 
-   * 
-   * The TOTP class allow for the generation 
-   * and verification of one-time password using 
-   * the TOTP specified algorithm.
-   *
-   * This class is meant to be compatible with 
-   * Google Authenticator
-   *
-   * This class was originally ported from the rotp
-   * ruby library available at https://github.com/mdp/rotp
-   */
-  class TOTP extends OTP {
-    /**
-     * The interval in seconds for a one-time password timeframe
-     * Defaults to 30
-     * @var integer
-     */
-    public $interval;
-
-    public function __construct($s, $opt = Array()) {
-      $this->interval = isset($opt['interval']) ? $opt['interval'] : 30;
-      parent::__construct($s, $opt);
-    }
-
-    /**
-     *  Get the password for a specific timestamp value 
-     *
-     *  @param integer $timestamp the timestamp which is timecoded and 
-     *  used to seed the hmac hash function.
-     *  @return integer the One Time Password
-     */
-    public function at($timestamp) {
-      return $this->generateOTP($this->timecode($timestamp));
-    }
-
-    /**
-     *  Get the password for the current timestamp value 
-     *
-     *  @return integer the current One Time Password
-     */
-    public function now() {
-      return $this->generateOTP($this->timecode(time()));
-    }
-
-    /**
-     * Verify if a password is valid for a specific counter value
-     *
-     * @param integer $otp the one-time password 
-     * @param integer $timestamp the timestamp for the a given time, defaults to current time.
-     * @return  bool true if the counter is valid, false otherwise
-     */
-    public function verify($otp, $timestamp = null) {
-      if($timestamp === null)
-        $timestamp = time();
-      return ($otp == $this->at($timestamp));
-    }
-
-    /**
-     * Returns the uri for a specific secret for totp method.
-     * Can be encoded as a image for simple configuration in 
-     * Google Authenticator.
-     *
-     * @param string $name the name of the account / profile
-     * @return string the uri for the hmac secret
-     */
-    public function provisioning_uri($name) {
-      return "otpauth://totp/".urlencode($name)."?secret={$this->secret}";
-    }
-
-    /**
-     * Transform a timestamp in a counter based on specified internal
-     *
-     * @param integer $timestamp
-     * @return integer the timecode
-     */
-    protected function timecode($timestamp) {
-      return (int)( (((int)$timestamp * 1000) / ($this->interval * 1000)));
-    }
-  }
-
-}
diff --git a/lib/otphp/vendor/base32.php b/lib/otphp/vendor/base32.php
deleted file mode 100644 (file)
index 99c3f1b..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-<?php
-
-/**
- * Encode in Base32 based on RFC 4648.
- * Requires 20% more space than base64  
- * Great for case-insensitive filesystems like Windows and URL's  (except for = char which can be excluded using the pad option for urls)
- *
- * @package default
- * @author Bryan Ruiz
- **/
-class Base32 {
-
-   private static $map = array(
-        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', //  7
-        'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 15
-        'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 23
-        'Y', 'Z', '2', '3', '4', '5', '6', '7', // 31
-        '='  // padding char
-    );
-    
-   private static $flippedMap = array(
-        'A'=>'0', 'B'=>'1', 'C'=>'2', 'D'=>'3', 'E'=>'4', 'F'=>'5', 'G'=>'6', 'H'=>'7',
-        'I'=>'8', 'J'=>'9', 'K'=>'10', 'L'=>'11', 'M'=>'12', 'N'=>'13', 'O'=>'14', 'P'=>'15',
-        'Q'=>'16', 'R'=>'17', 'S'=>'18', 'T'=>'19', 'U'=>'20', 'V'=>'21', 'W'=>'22', 'X'=>'23',
-        'Y'=>'24', 'Z'=>'25', '2'=>'26', '3'=>'27', '4'=>'28', '5'=>'29', '6'=>'30', '7'=>'31'
-    );
-    
-    /**
-     *    Use padding false when encoding for urls
-     *
-     * @return base32 encoded string
-     * @author Bryan Ruiz
-     **/
-    public static function encode($input, $padding = true) {
-        if(empty($input)) return "";
-        $input = str_split($input);
-        $binaryString = "";
-        for($i = 0; $i < count($input); $i++) {
-            $binaryString .= str_pad(base_convert(ord($input[$i]), 10, 2), 8, '0', STR_PAD_LEFT);
-        }
-        $fiveBitBinaryArray = str_split($binaryString, 5);
-        $base32 = "";
-        $i=0;
-        while($i < count($fiveBitBinaryArray)) {    
-            $base32 .= self::$map[base_convert(str_pad($fiveBitBinaryArray[$i], 5,'0'), 2, 10)];
-            $i++;
-        }
-        if($padding && ($x = strlen($binaryString) % 40) != 0) {
-            if($x == 8) $base32 .= str_repeat(self::$map[32], 6);
-            else if($x == 16) $base32 .= str_repeat(self::$map[32], 4);
-            else if($x == 24) $base32 .= str_repeat(self::$map[32], 3);
-            else if($x == 32) $base32 .= self::$map[32];
-        }
-        return $base32;
-    }
-    
-    public static function decode($input) {
-        if(empty($input)) return;
-        $paddingCharCount = substr_count($input, self::$map[32]);
-        $allowedValues = array(6,4,3,1,0);
-        if(!in_array($paddingCharCount, $allowedValues)) return false;
-        for($i=0; $i<4; $i++){ 
-            if($paddingCharCount == $allowedValues[$i] && 
-                substr($input, -($allowedValues[$i])) != str_repeat(self::$map[32], $allowedValues[$i])) return false;
-        }
-        $input = str_replace('=','', $input);
-        $input = str_split($input);
-        $binaryString = "";
-        for($i=0; $i < count($input); $i = $i+8) {
-            $x = "";
-            if(!in_array($input[$i], self::$map)) return false;
-            for($j=0; $j < 8; $j++) {
-                $x .= str_pad(base_convert(@self::$flippedMap[@$input[$i + $j]], 10, 2), 5, '0', STR_PAD_LEFT);
-            }
-            $eightBits = str_split($x, 8);
-            for($z = 0; $z < count($eightBits); $z++) {
-                $binaryString .= ( ($y = chr(base_convert($eightBits[$z], 2, 10))) || ord($y) == 48 ) ? $y:"";
-            }
-        }
-        return $binaryString;
-    }
-}
-
diff --git a/lib/otphp/vendor/libs.php b/lib/otphp/vendor/libs.php
deleted file mode 100644 (file)
index 742c7b9..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php
-/*
- * Copyright (c) 2011 Le Lag 
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
-
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-// Add any needed third party library to this directory
-
-//require_once dirname(__FILE__).'/some_lib/lib.php';
-require_once dirname(__FILE__).'/base32.php';
diff --git a/vendor/OTPHP/Base32.php b/vendor/OTPHP/Base32.php
new file mode 100644 (file)
index 0000000..f0dc2f1
--- /dev/null
@@ -0,0 +1,85 @@
+<?php
+
+namespace OTPHP;
+
+/**
+ * Encode in Base32 based on RFC 4648.
+ * Requires 20% more space than base64
+ * Great for case-insensitive filesystems like Windows and URL's  (except for = char which can be excluded using the pad option for urls)
+ *
+ * @package default
+ * @author Bryan Ruiz
+ **/
+class Base32 {
+
+   private static $map = array(
+        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', //  7
+        'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 15
+        'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 23
+        'Y', 'Z', '2', '3', '4', '5', '6', '7', // 31
+        '='  // padding char
+    );
+
+   private static $flippedMap = array(
+        'A'=>'0', 'B'=>'1', 'C'=>'2', 'D'=>'3', 'E'=>'4', 'F'=>'5', 'G'=>'6', 'H'=>'7',
+        'I'=>'8', 'J'=>'9', 'K'=>'10', 'L'=>'11', 'M'=>'12', 'N'=>'13', 'O'=>'14', 'P'=>'15',
+        'Q'=>'16', 'R'=>'17', 'S'=>'18', 'T'=>'19', 'U'=>'20', 'V'=>'21', 'W'=>'22', 'X'=>'23',
+        'Y'=>'24', 'Z'=>'25', '2'=>'26', '3'=>'27', '4'=>'28', '5'=>'29', '6'=>'30', '7'=>'31'
+    );
+
+    /**
+     *    Use padding false when encoding for urls
+     *
+     * @return base32 encoded string
+     * @author Bryan Ruiz
+     **/
+    public static function encode($input, $padding = true) {
+        if(empty($input)) return "";
+        $input = str_split($input);
+        $binaryString = "";
+        for($i = 0; $i < count($input); $i++) {
+            $binaryString .= str_pad(base_convert(ord($input[$i]), 10, 2), 8, '0', STR_PAD_LEFT);
+        }
+        $fiveBitBinaryArray = str_split($binaryString, 5);
+        $base32 = "";
+        $i=0;
+        while($i < count($fiveBitBinaryArray)) {
+            $base32 .= self::$map[base_convert(str_pad($fiveBitBinaryArray[$i], 5,'0'), 2, 10)];
+            $i++;
+        }
+        if($padding && ($x = strlen($binaryString) % 40) != 0) {
+            if($x == 8) $base32 .= str_repeat(self::$map[32], 6);
+            else if($x == 16) $base32 .= str_repeat(self::$map[32], 4);
+            else if($x == 24) $base32 .= str_repeat(self::$map[32], 3);
+            else if($x == 32) $base32 .= self::$map[32];
+        }
+        return $base32;
+    }
+
+    public static function decode($input) {
+        if(empty($input)) return;
+        $paddingCharCount = substr_count($input, self::$map[32]);
+        $allowedValues = array(6,4,3,1,0);
+        if(!in_array($paddingCharCount, $allowedValues)) return false;
+        for($i=0; $i<4; $i++){
+            if($paddingCharCount == $allowedValues[$i] &&
+                substr($input, -($allowedValues[$i])) != str_repeat(self::$map[32], $allowedValues[$i])) return false;
+        }
+        $input = str_replace('=','', $input);
+        $input = str_split($input);
+        $binaryString = "";
+        for($i=0; $i < count($input); $i = $i+8) {
+            $x = "";
+            if(!in_array($input[$i], self::$map)) return false;
+            for($j=0; $j < 8; $j++) {
+                $x .= str_pad(base_convert(@self::$flippedMap[@$input[$i + $j]], 10, 2), 5, '0', STR_PAD_LEFT);
+            }
+            $eightBits = str_split($x, 8);
+            for($z = 0; $z < count($eightBits); $z++) {
+                $binaryString .= ( ($y = chr(base_convert($eightBits[$z], 2, 10))) || ord($y) == 48 ) ? $y:"";
+            }
+        }
+        return $binaryString;
+    }
+}
+
diff --git a/vendor/OTPHP/HOTP.php b/vendor/OTPHP/HOTP.php
new file mode 100644 (file)
index 0000000..7092fd9
--- /dev/null
@@ -0,0 +1,74 @@
+<?php
+/*
+ * Copyright (c) 2011 Le Lag 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+namespace OTPHP {
+  /**
+   * HOTP - One time password generator 
+   * 
+   * The HOTP class allow for the generation 
+   * and verification of one-time password using 
+   * the HOTP specified algorithm.
+   *
+   * This class is meant to be compatible with 
+   * Google Authenticator
+   *
+   * This class was originally ported from the rotp
+   * ruby library available at https://github.com/mdp/rotp
+   */
+  class HOTP extends OTP {
+    /**
+     *  Get the password for a specific counter value
+     *  @param integer $count the counter which is used to
+     *  seed the hmac hash function.
+     *  @return integer the One Time Password
+     */
+    public function at($count) {
+      return $this->generateOTP($count);
+    }
+
+
+    /**
+     * Verify if a password is valid for a specific counter value
+     *
+     * @param integer $otp the one-time password 
+     * @param integer $counter the counter value
+     * @return  bool true if the counter is valid, false otherwise
+     */
+    public function verify($otp, $counter) {
+      return ($otp == $this->at($counter));
+    }
+
+    /**
+     * Returns the uri for a specific secret for hotp method.
+     * Can be encoded as a image for simple configuration in 
+     * Google Authenticator.
+     *
+     * @param string $name the name of the account / profile
+     * @param integer $initial_count the initial counter 
+     * @return string the uri for the hmac secret
+     */
+    public function provisioning_uri($name, $initial_count) {
+      return "otpauth://hotp/".urlencode($name)."?secret={$this->secret}&counter=$initial_count";
+    }
+  }
+
+}
diff --git a/vendor/OTPHP/LICENCE b/vendor/OTPHP/LICENCE
new file mode 100644 (file)
index 0000000..d14cbc2
--- /dev/null
@@ -0,0 +1,20 @@
+Copyright (c) 2011 Le Lag 
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
diff --git a/vendor/OTPHP/OTP.php b/vendor/OTPHP/OTP.php
new file mode 100644 (file)
index 0000000..d1995ef
--- /dev/null
@@ -0,0 +1,120 @@
+<?php
+/*
+ * Copyright (c) 2011 Le Lag
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+namespace OTPHP {
+/**
+ * One Time Password Generator
+ *
+ * The OTP class allow the generation of one-time
+ * password that is described in rfc 4xxx.
+ *
+ * This is class is meant to be compatible with
+ * Google Authenticator.
+ *
+ * This class was originally ported from the rotp
+ * ruby library available at https://github.com/mdp/rotp
+ */
+class OTP {
+    /**
+     * The base32 encoded secret key
+     * @var string
+     */
+    public $secret;
+
+    /**
+     * The algorithm used for the hmac hash function
+     * @var string
+     */
+    public $digest;
+
+    /**
+     * The number of digits in the one-time password
+     * @var integer
+     */
+    public $digits;
+
+    /**
+     * Constructor for the OTP class
+     * @param string $secret the secret key
+     * @param array $opt options array can contain the
+     * following keys :
+     *   @param integer digits : the number of digits in the one time password
+     *   Currently Google Authenticator only support 6. Defaults to 6.
+     *   @param string digest : the algorithm used for the hmac hash function
+     *   Google Authenticator only support sha1. Defaults to sha1
+     *
+     * @return new OTP class.
+     */
+    public function __construct($secret, $opt = Array()) {
+      $this->digits = isset($opt['digits']) ? $opt['digits'] : 6;
+      $this->digest = isset($opt['digest']) ? $opt['digest'] : 'sha1';
+      $this->secret = $secret;
+    }
+
+    /**
+     * Generate a one-time password
+     *
+     * @param integer $input : number used to seed the hmac hash function.
+     * This number is usually a counter (HOTP) or calculated based on the current
+     * timestamp (see TOTP class).
+     * @return integer the one-time password
+     */
+    public function generateOTP($input) {
+      $hash = hash_hmac($this->digest, $this->intToBytestring($input), $this->byteSecret());
+      foreach(str_split($hash, 2) as $hex) { // stupid PHP has bin2hex but no hex2bin WTF
+        $hmac[] = hexdec($hex);
+      }
+      $offset = $hmac[19] & 0xf;
+      $code = ($hmac[$offset+0] & 0x7F) << 24 |
+        ($hmac[$offset + 1] & 0xFF) << 16 |
+        ($hmac[$offset + 2] & 0xFF) << 8 |
+        ($hmac[$offset + 3] & 0xFF);
+      return $code % pow(10, $this->digits);
+    }
+
+    /**
+     * Returns the binary value of the base32 encoded secret
+     * @access private
+     * This method should be private but was left public for
+     * phpunit tests to work.
+     * @return binary secret key
+     */
+    public function byteSecret() {
+      return Base32::decode($this->secret);
+    }
+
+    /**
+     * Turns an integer in a OATH bytestring
+     * @param integer $int
+     * @access private
+     * @return string bytestring
+     */
+    public function intToBytestring($int) {
+      $result = Array();
+      while($int != 0) {
+        $result[] = chr($int & 0xFF);
+        $int >>= 8;
+      }
+      return str_pad(join(array_reverse($result)), 8, "\000", STR_PAD_LEFT);
+    }
+  }
+}
diff --git a/vendor/OTPHP/OTPHP.php b/vendor/OTPHP/OTPHP.php
new file mode 100644 (file)
index 0000000..a6c6f8d
--- /dev/null
@@ -0,0 +1,27 @@
+<?php
+/*
+ * Copyright (c) 2011 Le Lag 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+require_once dirname(__FILE__).'/../vendor/libs.php';
+require_once dirname(__FILE__).'/otp.php';
+require_once dirname(__FILE__).'/hotp.php';
+require_once dirname(__FILE__).'/totp.php';
+
diff --git a/vendor/OTPHP/TOTP.php b/vendor/OTPHP/TOTP.php
new file mode 100644 (file)
index 0000000..10a1f42
--- /dev/null
@@ -0,0 +1,106 @@
+<?php
+/*
+ * Copyright (c) 2011 Le Lag 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+namespace OTPHP {
+  /**
+   * TOTP - One time password generator 
+   * 
+   * The TOTP class allow for the generation 
+   * and verification of one-time password using 
+   * the TOTP specified algorithm.
+   *
+   * This class is meant to be compatible with 
+   * Google Authenticator
+   *
+   * This class was originally ported from the rotp
+   * ruby library available at https://github.com/mdp/rotp
+   */
+  class TOTP extends OTP {
+    /**
+     * The interval in seconds for a one-time password timeframe
+     * Defaults to 30
+     * @var integer
+     */
+    public $interval;
+
+    public function __construct($s, $opt = Array()) {
+      $this->interval = isset($opt['interval']) ? $opt['interval'] : 30;
+      parent::__construct($s, $opt);
+    }
+
+    /**
+     *  Get the password for a specific timestamp value 
+     *
+     *  @param integer $timestamp the timestamp which is timecoded and 
+     *  used to seed the hmac hash function.
+     *  @return integer the One Time Password
+     */
+    public function at($timestamp) {
+      return $this->generateOTP($this->timecode($timestamp));
+    }
+
+    /**
+     *  Get the password for the current timestamp value 
+     *
+     *  @return integer the current One Time Password
+     */
+    public function now() {
+      return $this->generateOTP($this->timecode(time()));
+    }
+
+    /**
+     * Verify if a password is valid for a specific counter value
+     *
+     * @param integer $otp the one-time password 
+     * @param integer $timestamp the timestamp for the a given time, defaults to current time.
+     * @return  bool true if the counter is valid, false otherwise
+     */
+    public function verify($otp, $timestamp = null) {
+      if($timestamp === null)
+        $timestamp = time();
+      return ($otp == $this->at($timestamp));
+    }
+
+    /**
+     * Returns the uri for a specific secret for totp method.
+     * Can be encoded as a image for simple configuration in 
+     * Google Authenticator.
+     *
+     * @param string $name the name of the account / profile
+     * @return string the uri for the hmac secret
+     */
+    public function provisioning_uri($name) {
+      return "otpauth://totp/".urlencode($name)."?secret={$this->secret}";
+    }
+
+    /**
+     * Transform a timestamp in a counter based on specified internal
+     *
+     * @param integer $timestamp
+     * @return integer the timecode
+     */
+    protected function timecode($timestamp) {
+      return (int)( (((int)$timestamp * 1000) / ($this->interval * 1000)));
+    }
+  }
+
+}