Merge branch 'master' into test test
authorStricted <info@stricted.net>
Sun, 5 Feb 2017 12:26:05 +0000 (13:26 +0100)
committerStricted <info@stricted.net>
Sun, 5 Feb 2017 12:26:05 +0000 (13:26 +0100)
# Conflicts:
# README.md
# SpeedportHybrid.class.php
# Speedportw724v.class.php
# lib/trait/CryptLib.class.php

1  2 
README.md
SpeedportHybrid.class.php
lib/trait/Login.class.php

diff --combined README.md
index 1a6a0fc2675320f25c1dfee0a572fd6d68e6244e,f046add56fdf55085326d1ba0e7dbb6642bb906f..57fadb03947a5f8355a62915f1db3aa13805a018
+++ b/README.md
@@@ -1,16 -1,16 +1,16 @@@
 -### speedport hybrid php api
 +### speedport php api
  
- [![Build Status](https://travis-ci.org/Stricted/speedport-hybrid-php-api.svg?branch=test)](https://travis-ci.org/Stricted/speedport-hybrid-php-api) [![Release](https://img.shields.io/github/release/Stricted/speedport-hybrid-php-api.svg)](https://github.com/Stricted/speedport-hybrid-php-api/releases/latest) [![License](https://img.shields.io/badge/license-LGPLv3-brightgreen.svg)](https://github.com/Stricted/speedport-hybrid-php-api/blob/master/LICENSE)
+ [![Build Status](https://travis-ci.org/Stricted/speedport-hybrid-php-api.svg?branch=master)](https://travis-ci.org/Stricted/speedport-hybrid-php-api) [![Release](https://img.shields.io/github/release/Stricted/speedport-hybrid-php-api.svg)](https://github.com/Stricted/speedport-hybrid-php-api/releases/latest) [![License](https://img.shields.io/badge/license-LGPLv3-brightgreen.svg)](https://github.com/Stricted/speedport-hybrid-php-api/blob/master/LICENSE)
  
 -Access Speedport Hybrid Router through PHP
 +Access Speedport Router through PHP
  
 -**THIS CLASS IS ONLY FOR SPEEDPORT HYBRID**
 +This is an **EXPERIMENTAL** branch to support other speedport router, i dont have them so feel free to test it and report any error
  
  ### License
  ---
  This project is licensed under [GNU LESSER GENERAL PUBLIC LICENSE Version 3](https://github.com/Stricted/speedport-hybrid-php-api/blob/master/LICENSE).
  
 -known endpoints for getData() and sentRequest():
 +known endpoints for getData() and sentRequest() (only for `Speedport Hybrid`):
  
  | Endpoint       |
  | -------------- |
index e5f03a6499cf83de78a7a9f797279f5c7afc2289,c135643cd5163d77b29c03fef5f52a4a9e0d8315..dda8316c09ec459e064fdf54cf03e1d19d02a947
@@@ -1,9 -1,8 +1,10 @@@
  <?php
  require_once('lib/exception/RebootException.class.php');
  require_once('lib/exception/RouterException.class.php');
+ require_once('lib/exception/NotImplementedException.class.php');
  require_once('CryptLib/CryptLib.php');
 +require_once('Speedport.class.php');
 +require_once('ISpeedport.class.php');
  require_once('lib/trait/Connection.class.php');
  require_once('lib/trait/CryptLib.class.php');
  require_once('lib/trait/Login.class.php');
@@@ -15,9 -14,9 +16,9 @@@ require_once('lib/trait/System.class.ph
  /**
   * @author      Jan Altensen (Stricted)
   * @license     GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
-  * @copyright   2015 Jan Altensen (Stricted)
+  * @copyright   2015-2016 Jan Altensen (Stricted)
   */
 -class SpeedportHybrid {
 +class SpeedportHybrid extends Speedport implements ISpeedport {
        use Connection;
        use CryptLib;
        use Firewall;
         * class version
         * @const       string
         */
-       const VERSION = '1.0.4';
+       const VERSION = '1.0.5';
        
 -      /**
 -       * router url
 -       * @var string
 -       */
 -      private $url = '';
 -      
 -      /**
 -       * inititalize this class
 -       *
 -       * @param       string  $url
 -       */
 -      public function __construct ($url = 'http://speedport.ip/') {
 -              $this->url = $url;
 -              $this->checkRequirements();
 -      }
 -      
        /**
         * check php requirements
         */
 -      private function checkRequirements () {
 +      protected function checkRequirements () {
                if (!extension_loaded('curl')) {
                        throw new Exception("The PHP Extension 'curl' is missing.");
                }
        }
        
        /**
 -       * get the values from array
 +       * sends the encrypted request to router
         * 
 -       * @param       array   $array
 +       * @param       string  $path
 +       * @param       mixed   $fields
 +       * @param       string  $cookie
         * @return      array
         */
 -      private function getValues($array) {
 -              $data = array();
 -              foreach ($array as $item) {
 -                      if (!isset($item['vartype']) || !isset($item['varid']) || !isset($item['varvalue'])) continue;
 -                      
 -                      // thank you telekom for this piece of shit
 -                      if ($item['vartype'] == 'template') {
 -                              if (is_array($item['varvalue'])) {
 -                                      $data[$item['varid']][] = $this->getValues($item['varvalue']);
 -                              }
 -                              else {
 -                                      // i dont know if we need this
 -                                      $data[$item['varid']] = $item['varvalue'];
 -                              }
 -                      }
 -                      else {
 -                              if (is_array($item['varvalue'])) {
 -                                      $data[$item['varid']] = $this->getValues($item['varvalue']);
 -                              }
 -                              else {
 -                                      $data[$item['varid']] = $item['varvalue'];
 -                              }
 -                      }
 -              }
 -              
 -              return $data;
 +      protected function sentEncryptedRequest ($path, $fields, $cookie = false) {
 +              $count = count($fields);
 +              $fields = $this->encrypt(http_build_query($fields));
 +              return $this->sentRequest($path, $fields, $cookie, $count);
        }
        
        /**
         * @param       integer $count
         * @return      array
         */
-       protected function sentRequest ($path, $fields, $cookie = false, $count = 0) {
-               $data = parent::sentRequest($path, $fields, $cookie, $count);
-               $header = $data['header'];
-               $body = $data['body'];
+       private function sendRequest ($path, $fields, $cookie = false, $count = 0) {
+               $url = $this->url.$path;
+               $ch = curl_init();
+               curl_setopt($ch, CURLOPT_URL, $url);
+               
+               if (!empty($fields)) {
+                       curl_setopt($ch, CURLOPT_POST, true);
+                       
+                       if (is_array($fields)) {
+                               curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($fields));
+                       }
+                       else {
+                               curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
+                       }
+               }
+               
+               if ($cookie === true) {
+                       curl_setopt($ch, CURLOPT_COOKIE, 'challengev='.$this->challenge.'; '.$this->cookie);
+               }
+               
+               curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+               curl_setopt($ch, CURLOPT_HEADER, true);
+               
+               $result = curl_exec($ch);
+               
+               $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
+               $header = substr($result, 0, $header_size);
+               $body = substr($result, $header_size);
+               curl_close($ch);
+               
+               // check if response is empty
+               if (empty($body)) {
+                       throw new RouterException('empty response');
+               }
+               
                // check if body is encrypted (hex instead of json)
                if (ctype_xdigit($body)) {
                        $body = $this->decrypt($body);
                $body = preg_replace("/},\s+]/", "}\n]", $body);
                
                // decode json
 -              if (strpos($url, '.json') !== false) {
 +              if (strpos($path, '.json') !== false) {
                        $json = json_decode($body, true);
                        
                        if (is_array($json)) {
                        }
                }
                
 -              return array('header' => $this->parse_headers($header), 'body' => $body);
 -      }
 -      
 -      /**
 -       * parse the curl return header into an array
 -       * 
 -       * @param       string  $response
 -       * @return      array
 -       */
 -      private function parse_headers($response) {
 -              $headers = array();
 -              $header_text = substr($response, 0, strpos($response, "\r\n\r\n"));
 -              
 -              $header_text = explode("\r\n", $header_text);
 -              foreach ($header_text as $i => $line) {
 -                      if ($i === 0) {
 -                              $headers['http_code'] = $line;
 -                      }
 -                      else {
 -                              list ($key, $value) = explode(': ', $line);
 -                              $headers[$key] = $value;
 -                      }
 -              }
 -              
 -              return $headers;
 +              return array('header' => $header, 'body' => $body);
        }
  }
index 185a832792f9f4f5065d3c4e4e9f3b444b216696,2e5d029f2475e595476f85f182e9dcb721fc1c82..70a16a1b421bcfb3488f95a7a0d3f870f35b1fd1
@@@ -2,7 -2,7 +2,7 @@@
  /**
   * @author      Jan Altensen (Stricted)
   * @license     GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
-  * @copyright   2015 Jan Altensen (Stricted)
+  * @copyright   2015-2016 Jan Altensen (Stricted)
   */
  trait Login {
        /**
         */
        private $challenge = '';
        
 -      /**
 -       * csrf_token
 -       * @var string
 -       */
 -      private $token = '';
 -      
 -      /**
 -       * hashed password
 -       * @var string
 -       */
 -      private $hash = '';
 -      
 -      /**
 -       * session cookie
 -       * @var string
 -       */
 -      private $cookie = '';
 -      
        /**
         * derivedk cookie
         * @var string
                $path = 'data/Login.json';
                $this->hash = hash('sha256', $this->challenge.':'.$password);
                $fields = array('csrf_token' => 'nulltoken', 'showpw' => 0, 'password' => $this->hash);
-               $data = $this->sentRequest($path, $fields);
+               $data = $this->sendRequest($path, $fields);
                $json = $this->getValues($data['body']);
                
                if (isset($json['login']) && $json['login'] == 'success') {
 -                      $this->cookie = $this->getCookie($data);
 +                      $this->cookie = 'challengev='.$this->challenge.'; ';
 +                      $this->cookie .= $this->getCookie($data);
                        
                        $this->derivedk = $this->getDerviedk($password);
                        
@@@ -55,7 -72,7 +55,7 @@@
        private function getChallenge () {
                $path = 'data/Login.json';
                $fields = array('csrf_token' => 'nulltoken', 'showpw' => 0, 'challengev' => 'null');
-               $data = $this->sentRequest($path, $fields);
+               $data = $this->sendRequest($path, $fields);
                $data = $this->getValues($data['body']);
                
                if (isset($data['challengev']) && !empty($data['challengev'])) {
                
                $path = 'data/SecureStatus.json';
                $fields = array();
-               $data = $this->sentRequest($path, $fields, true);
+               $data = $this->sendRequest($path, $fields, true);
                $data = $this->getValues($data['body']);
                
                if ($data['loginstate'] != 1) {
                
                $path = 'data/Login.json';
                $fields = array('csrf_token' => $this->token, 'logout' => 'byby');
-               $data = $this->sentRequest($path, $fields, true);
+               $data = $this->sendRequest($path, $fields, true);
                $data = $this->getValues($data['body']);
                if ((isset($data['status']) && $data['status'] == 'ok') && $this->checkLogin(false) === false) {
                        // reset challenge and session
         * 
         * @return      string
         */
 -      private function getToken () {
 +      protected function getToken () {
                $this->checkLogin();
                
                $path = 'html/content/overview/index.html';
                $fields = array();
-               $data = $this->sentRequest($path, $fields, true);
+               $data = $this->sendRequest($path, $fields, true);
                
                $a = explode('csrf_token = "', $data['body']);
                $a = explode('";', $a[1]);
                // calculate derivedk
                if (!function_exists('hash_pbkdf2')) {
                        $pbkdf2 = new CryptLib\Key\Derivation\PBKDF\PBKDF2(array('hash' => 'sha1'));
-                       $derivedk = bin2hex($pbkdf2->derive(hash('sha256', $password), substr($this->challenge, 0, 16), 1000, 32));
-                       $derivedk = substr($derivedk, 0, 32);
+                       $derivedk = bin2hex($pbkdf2->derive(hash('sha256', $password), substr($this->challenge, 0, 16), 1000, 16));
                }
                else {
                        $derivedk = hash_pbkdf2('sha1', hash('sha256', $password), substr($this->challenge, 0, 16), 1000, 32);