From Gray Pintail, 4 Years ago, written in PHP.
Embed
  1. <?php
  2. /**
  3.  * Created by JetBrains PhpStorm.
  4.  * User: RDeWeese
  5.  * Date: 10/22/13
  6.  * Time: 10:29 AM
  7.  * Library to interact with NW2 OTP API
  8.  */
  9. class NW2OTP
  10. {
  11.  
  12.  
  13.     /**
  14.      * Generate a new secret for token generation
  15.      */
  16.     static function NewSecret()
  17.     {
  18.         $curl = new Curl();
  19.         $curl->get('http://a.nw2.us/new');
  20.         $response = json_decode($curl->response);
  21.         return $response->{'Secret'};
  22.     }
  23.     static function GetToken($secret)
  24.     {
  25.         $curl = new Curl();
  26.         $curl->get('http://a.nw2.us/auth/'.$secret);
  27.         $response = json_decode($curl->response);
  28.         return $response->{'token'};
  29.     }
  30.  
  31.     /**
  32.      * @param $secret
  33.      * @return string
  34.      * Generate a QR code for importing to android devices
  35.      * returns html image with base64 encoded QR code
  36.      */
  37.     static function QRCode($secret) {
  38.         $curl = new Curl();
  39.         $curl->get("http://a.nw2.us/qr/".$secret);
  40.         $response = json_decode($curl->response);
  41.         return '<img src="'.$response->{'QR'}.'">';
  42.     }
  43.  
  44.     /**
  45.      * @param $secret
  46.      * @param $code
  47.      * @return bool
  48.      * Verify a token, encrypts secret and token with public key before submitting for processing
  49.      */
  50.     static function postVerify($secret, $code)
  51.     {
  52.         $curl = new Curl();
  53.         $secret = NW2OTP::encrypt($secret);
  54.         $code = NW2OTP::encrypt($code);
  55.         $data = array('secret'=>NW2OTP::base64_url_encode($secret),
  56.                       'code'=>NW2OTP::base64_url_encode($code));
  57.         $curl->post("http://a.nw2.us/auth/",$data);
  58.         $response = json_decode($curl->response);
  59.         if ($response->{'authenticated'} == "True") {
  60.             return true;
  61.         }
  62.         return false;
  63.     }
  64.  
  65.  
  66.     /**
  67.      * Verify a token, pass secret and token. Returns true if valid. GET method, no encryption
  68.      */
  69.     static function Verify($secret, $token)
  70.     {
  71.         $curl = new Curl();
  72.         $curl->get("http://a.nw2.us/auth/" . $secret . "/" . $token);
  73.         $response = json_decode($curl->response);
  74.         if ($response->{'authenticated'} == "True") {
  75.  
  76.             return true;
  77.         }
  78.         return false;
  79.     }
  80.  
  81.  
  82.     /*
  83.      * Various functions used by class
  84.      */
  85.  
  86.     /**
  87.      * @param $string
  88.      * @return string
  89.      * returns encrypted string
  90.      *
  91.      */
  92.     protected function encrypt($string)
  93.     {
  94.         //Public key for encryption
  95.         $publicKey = "-----BEGIN PUBLIC KEY-----
  96. MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDiLd8eFAoicm+Aw/eSiPRw1c+J
  97. ma14wd7hZCudYeXBXIpqn0b+wWhGc6mO768Rxgobc+QRgoVIlXeDJbLOG1rv7doQ
  98. jEjLyH8qQAM6RKguZ9fKfwxXtQ3r5BJWCOiSucrMegbuT45Ma/r5ffpsE5qqNeJW
  99. BGOilo/3Rhryl5sMSwIDAQAB
  100. -----END PUBLIC KEY-----";
  101.         openssl_public_encrypt($string, $encrypted, $publicKey);
  102.         return $encrypted;
  103.     }
  104.  
  105.     /**
  106.      * @param $input
  107.      * @return string
  108.      * returns URL Friendly base64
  109.      */
  110.     protected function base64_url_encode($input)
  111.     {
  112.         return strtr(base64_encode($input), '+/=', '-_,');
  113.     }
  114.  
  115.     protected function base64_url_decode($input)
  116.     {
  117.         return base64_decode(strtr($input, '-_,', '+/='));
  118.     }
  119.  
  120. }
  121.  
  122. /**
  123.  * Class Curl
  124.  * Borrowed from GitHub
  125.  * PHP-Curl-Class/1.0 (+https://github.com/php-curl-class/php-curl-class
  126.  */
  127. class Curl {
  128.     const USER_AGENT = 'NW2Auth System';
  129.  
  130.     function __construct() {
  131.         if (!extension_loaded('curl')) {
  132.             throw new ErrorException('cURL library is not loaded');
  133.         }
  134.  
  135.         $this->curl = curl_init();
  136.         $this->setUserAgent(self::USER_AGENT);
  137.         $this->setopt(CURLINFO_HEADER_OUT, TRUE);
  138.         $this->setopt(CURLOPT_HEADER, TRUE);
  139.         $this->setopt(CURLOPT_RETURNTRANSFER, TRUE);
  140.     }
  141.  
  142.     function get($url, $data=array()) {
  143.         $this->setopt(CURLOPT_URL, $url . '?' . http_build_query($data));
  144.         $this->setopt(CURLOPT_HTTPGET, TRUE);
  145.         $this->_exec();
  146.     }
  147.  
  148.     function post($url, $data=array()) {
  149.         $this->setopt(CURLOPT_URL, $url);
  150.         $this->setopt(CURLOPT_POST, TRUE);
  151.         $this->setopt(CURLOPT_POSTFIELDS, $this->_postfields($data));
  152.         $this->_exec();
  153.     }
  154.  
  155.     function put($url, $data=array()) {
  156.         $this->setopt(CURLOPT_URL, $url . '?' . http_build_query($data));
  157.         $this->setopt(CURLOPT_CUSTOMREQUEST, 'PUT');
  158.         $this->_exec();
  159.     }
  160.  
  161.     function patch($url, $data=array()) {
  162.         $this->setopt(CURLOPT_URL, $url);
  163.         $this->setopt(CURLOPT_CUSTOMREQUEST, 'PATCH');
  164.         $this->setopt(CURLOPT_POSTFIELDS, $data);
  165.         $this->_exec();
  166.     }
  167.  
  168.     function delete($url, $data=array()) {
  169.         $this->setopt(CURLOPT_URL, $url . '?' . http_build_query($data));
  170.         $this->setopt(CURLOPT_CUSTOMREQUEST, 'DELETE');
  171.         $this->_exec();
  172.     }
  173.  
  174.     function setBasicAuthentication($username, $password) {
  175.         $this->setopt(CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
  176.         $this->setopt(CURLOPT_USERPWD, $username . ':' . $password);
  177.     }
  178.  
  179.     function setHeader($key, $value) {
  180.         $this->_headers[$key] = $key . ': ' . $value;
  181.         $this->setopt(CURLOPT_HTTPHEADER, array_values($this->_headers));
  182.     }
  183.  
  184.     function setUserAgent($user_agent) {
  185.         $this->setopt(CURLOPT_USERAGENT, $user_agent);
  186.     }
  187.  
  188.     function setReferrer($referrer) {
  189.         $this->setopt(CURLOPT_REFERER, $referrer);
  190.     }
  191.  
  192.     function setCookie($key, $value) {
  193.         $this->_cookies[$key] = $value;
  194.         $this->setopt(CURLOPT_COOKIE, http_build_query($this->_cookies, '', '; '));
  195.     }
  196.  
  197.     function setOpt($option, $value) {
  198.         return curl_setopt($this->curl, $option, $value);
  199.     }
  200.  
  201.     function verbose($on=TRUE) {
  202.         $this->setopt(CURLOPT_VERBOSE, $on);
  203.     }
  204.  
  205.     function close() {
  206.         curl_close($this->curl);
  207.     }
  208.  
  209.     function http_build_multi_query($data, $key=NULL) {
  210.         $query = array();
  211.  
  212.         foreach ($data as $k => $value) {
  213.             if (is_string($value)) {
  214.                 $query[] = urlencode(is_null($key) ? $k : $key) . '=' . rawurlencode($value);
  215.             }
  216.             else if (is_array($value)) {
  217.                 $query[] = $this->http_build_multi_query($value, $k . '[]');
  218.             }
  219.         }
  220.  
  221.         return implode('&', $query);
  222.     }
  223.  
  224.     function _postfields($data) {
  225.         if (is_array($data)) {
  226.             if (is_array_multidim($data)) {
  227.                 $data = $this->http_build_multi_query($data);
  228.             }
  229.             else {
  230.                 // Fix "Notice: Array to string conversion" when $value in
  231.                 // curl_setopt($ch, CURLOPT_POSTFIELDS, $value) is an array
  232.                 // that contains an empty array.
  233.                 foreach ($data as &$value) {
  234.                     if (is_array($value) && empty($value)) {
  235.                         $value = '';
  236.                     }
  237.                 }
  238.             }
  239.         }
  240.  
  241.         return $data;
  242.     }
  243.  
  244.     function _exec() {
  245.         $this->response = curl_exec($this->curl);
  246.         $this->curl_error_code = curl_errno($this->curl);
  247.         $this->curl_error_message = curl_error($this->curl);
  248.         $this->curl_error = !($this->curl_error_code === 0);
  249.         $this->http_status_code = curl_getinfo($this->curl, CURLINFO_HTTP_CODE);
  250.         $this->http_error = in_array(floor($this->http_status_code / 100), array(4, 5));
  251.         $this->error = $this->curl_error || $this->http_error;
  252.         $this->error_code = $this->error ? ($this->curl_error ? $this->curl_error_code : $this->http_status_code) : 0;
  253.  
  254.         $this->request_headers = preg_split('/\r\n/', curl_getinfo($this->curl, CURLINFO_HEADER_OUT), NULL, PREG_SPLIT_NO_EMPTY);
  255.         $this->response_headers = '';
  256.         if (!(strpos($this->response, "\r\n\r\n") === FALSE)) {
  257.             list($response_header, $this->response) = explode("\r\n\r\n", $this->response, 2);
  258.             if ($response_header === 'HTTP/1.1 100 Continue') {
  259.                 list($response_header, $this->response) = explode("\r\n\r\n", $this->response, 2);
  260.             }
  261.             $this->response_headers = preg_split('/\r\n/', $response_header, NULL, PREG_SPLIT_NO_EMPTY);
  262.         }
  263.  
  264.         $this->http_error_message = $this->error ? (isset($this->response_headers['0']) ? $this->response_headers['0'] : '') : '';
  265.         $this->error_message = $this->curl_error ? $this->curl_error_message : $this->http_error_message;
  266.  
  267.         return $this->error_code;
  268.     }
  269.  
  270.     function __destruct() {
  271.         $this->close();
  272.     }
  273.  
  274.     private $_cookies = array();
  275.     private $_headers = array();
  276.  
  277.     public $curl;
  278.  
  279.     public $error = FALSE;
  280.     public $error_code = 0;
  281.     public $error_message = NULL;
  282.  
  283.     public $curl_error = FALSE;
  284.     public $curl_error_code = 0;
  285.     public $curl_error_message = NULL;
  286.  
  287.     public $http_error = FALSE;
  288.     public $http_status_code = 0;
  289.     public $http_error_message = NULL;
  290.  
  291.     public $request_headers = NULL;
  292.     public $response_headers = NULL;
  293.     public $response = NULL;
  294. }
  295.  
  296. function is_array_multidim($array) {
  297.     if (!is_array($array)) {
  298.         return FALSE;
  299.     }
  300.  
  301.     return !(count($array) === count($array, COUNT_RECURSIVE));
  302. }
  303. ?>