| 1 | 
        
            2
         | 
        
            Manuela
         | 
        <?php
  | 
      
      
        | 2 | 
        
         | 
        
         | 
        
  | 
      
      
        | 3 | 
        
         | 
        
         | 
        /*
  | 
      
      
        | 4 | 
        
         | 
        
         | 
         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  | 
      
      
        | 5 | 
        
         | 
        
         | 
         *
  | 
      
      
        | 6 | 
        
         | 
        
         | 
         * This program is free software: you can redistribute it and/or modify
  | 
      
      
        | 7 | 
        
         | 
        
         | 
         * it under the terms of the GNU General Public License as published by
  | 
      
      
        | 8 | 
        
         | 
        
         | 
         * the Free Software Foundation, either version 3 of the License, or
  | 
      
      
        | 9 | 
        
         | 
        
         | 
         * (at your option) any later version.
  | 
      
      
        | 10 | 
        
         | 
        
         | 
         *
  | 
      
      
        | 11 | 
        
         | 
        
         | 
         * This program is distributed in the hope that it will be useful,
  | 
      
      
        | 12 | 
        
         | 
        
         | 
         * but WITHOUT ANY WARRANTY; without even the implied warranty of
  | 
      
      
        | 13 | 
        
         | 
        
         | 
         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  | 
      
      
        | 14 | 
        
         | 
        
         | 
         * GNU General Public License for more details.
  | 
      
      
        | 15 | 
        
         | 
        
         | 
         *
  | 
      
      
        | 16 | 
        
         | 
        
         | 
         * You should have received a copy of the GNU General Public License
  | 
      
      
        | 17 | 
        
         | 
        
         | 
         * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  | 
      
      
        | 18 | 
        
         | 
        
         | 
         */
  | 
      
      
        | 19 | 
        
         | 
        
         | 
        
  | 
      
      
        | 20 | 
        
         | 
        
         | 
        /**
  | 
      
      
        | 21 | 
        
         | 
        
         | 
         * SecureTokens.php
  | 
      
      
        | 22 | 
        
         | 
        
         | 
         *
  | 
      
      
        | 23 | 
        
         | 
        
         | 
         * @category      Core
  | 
      
      
        | 24 | 
        
         | 
        
         | 
         * @package       Core_Security
  | 
      
      
        | 25 | 
        
         | 
        
         | 
         * @subpackage    WB-2.8.4 and up
  | 
      
      
        | 26 | 
        
         | 
        
         | 
         * @copyright     Manuela v.d.Decken <manuela@isteam.de>
  | 
      
      
        | 27 | 
        
         | 
        
         | 
         * @author        Manuela v.d.Decken <manuela@isteam.de>
  | 
      
      
        | 28 | 
        
         | 
        
         | 
         * @license       http://www.gnu.org/licenses/gpl.html   GPL License
  | 
      
      
        | 29 | 
        
         | 
        
         | 
         * @
  | 
      
      
        | 30 | 
        
         | 
        
         | 
         * @version       0.1.2
  | 
      
      
        | 31 | 
        
         | 
        
         | 
         * @revision      $Revision$
  | 
      
      
        | 32 | 
        
         | 
        
         | 
         * @link          $HeadURL$
  | 
      
      
        | 33 | 
        
         | 
        
         | 
         * @lastmodified $Date$
  | 
      
      
        | 34 | 
        
         | 
        
         | 
         * @since         File available since 12.09.2015
  | 
      
      
        | 35 | 
        
         | 
        
         | 
         * @description
  | 
      
      
        | 36 | 
        
         | 
        
         | 
         * This class is a replacement for the former class SecureForm using the SecureTokensInterface
  | 
      
      
        | 37 | 
        
         | 
        
         | 
         *
  | 
      
      
        | 38 | 
        
         | 
        
         | 
         * Settings for this class
  | 
      
      
        | 39 | 
        
         | 
        
         | 
         * TYPE    KONSTANTE                    REGISTY-VAR                       DEFAULTWERT
  | 
      
      
        | 40 | 
        
         | 
        
         | 
         * boolean SEC_TOKEN_FINGERPRINT        ($oReg->SecTokenFingerprint)      [default=true]
  | 
      
      
        | 41 | 
        
         | 
        
         | 
         * integer SEC_TOKEN_IPV4_NETMASK       ($oReg->SecTokenIpv4Netmask)      0-255 [default=24]
  | 
      
      
        | 42 | 
        
         | 
        
         | 
         * integer SEC_TOKEN_IPV6_PREFIX_LENGTH ($oReg->SecTokenIpv6PrefixLength) 0-128 [default=64]
  | 
      
      
        | 43 | 
        
         | 
        
         | 
         * integer SEC_TOKEN_LIFE_TIME          ($oReg->SecTokenLifeTime)         1800 | 2700 | 3600[default] | 7200
  | 
      
      
        | 44 | 
        
         | 
        
         | 
        */
  | 
      
      
        | 45 | 
        
         | 
        
         | 
        
  | 
      
      
        | 46 | 
        
         | 
        
         | 
        class SecureTokens
  | 
      
      
        | 47 | 
        
         | 
        
         | 
        {
 | 
      
      
        | 48 | 
        
         | 
        
         | 
        /**
  | 
      
      
        | 49 | 
        
         | 
        
         | 
         * possible settings for TokenLifeTime in seconds
  | 
      
      
        | 50 | 
        
         | 
        
         | 
         * @description seconds for 30min / 45min / 1h / 75min / 90min / 105min / 2h
  | 
      
      
        | 51 | 
        
         | 
        
         | 
         */
  | 
      
      
        | 52 | 
        
         | 
        
         | 
        /** minimum lifetime in seconds */
  | 
      
      
        | 53 | 
        
         | 
        
         | 
            const LIFETIME_MIN  = 1800; // 30min
  | 
      
      
        | 54 | 
        
         | 
        
         | 
        /** maximum lifetime in seconds */
  | 
      
      
        | 55 | 
        
         | 
        
         | 
            const LIFETIME_MAX  = 7200; // 120min (2h)
  | 
      
      
        | 56 | 
        
         | 
        
         | 
        /** stepwidth between min and max */
  | 
      
      
        | 57 | 
        
         | 
        
         | 
            const LIFETIME_STEP =  900; // 15min
  | 
      
      
        | 58 | 
        
         | 
        
         | 
        /** lifetime in seconds to use in DEBUG mode if negative value is given (-1) */
  | 
      
      
        | 59 | 
        
         | 
        
         | 
            const DEBUG_LIFETIME = 300; // 5
  | 
      
      
        | 60 | 
        
         | 
        
         | 
        /** array to hold all tokens from the session */
  | 
      
      
        | 61 | 
        
         | 
        
         | 
            private $aTokens = array(
  | 
      
      
        | 62 | 
        
         | 
        
         | 
                'default' => array('value' => 0, 'expire' => 0, 'instance' => 0)
 | 
      
      
        | 63 | 
        
         | 
        
         | 
            );
  | 
      
      
        | 64 | 
        
         | 
        
         | 
        /** the salt for this instance */
  | 
      
      
        | 65 | 
        
         | 
        
         | 
            private $sSalt             = '';
  | 
      
      
        | 66 | 
        
         | 
        
         | 
        /** fingerprint of the current connection */
  | 
      
      
        | 67 | 
        
         | 
        
         | 
            private $sFingerprint      = '';
  | 
      
      
        | 68 | 
        
         | 
        
         | 
        /** the FTAN token which is valid for this instance */
  | 
      
      
        | 69 | 
        
         | 
        
         | 
            private $aLastCreatedFtan  = null;
  | 
      
      
        | 70 | 
        
         | 
        
         | 
        /** the time when tokens expired if they created in this instance */
  | 
      
      
        | 71 | 
        
         | 
        
         | 
            private $iExpireTime       = 0;
  | 
      
      
        | 72 | 
        
         | 
        
         | 
        /** remove selected tokens only and update all others */
  | 
      
      
        | 73 | 
        
         | 
        
         | 
            private $bPreserveAllOtherTokens = false;
  | 
      
      
        | 74 | 
        
         | 
        
         | 
        /** id of the current instance */
  | 
      
      
        | 75 | 
        
         | 
        
         | 
            private $sCurrentInstance  = null;
  | 
      
      
        | 76 | 
        
         | 
        
         | 
        /** id of the instance to remove */
  | 
      
      
        | 77 | 
        
         | 
        
         | 
            private $sInstanceToDelete = null;
  | 
      
      
        | 78 | 
        
         | 
        
         | 
        /** id of the instance to update expire time */
  | 
      
      
        | 79 | 
        
         | 
        
         | 
            private $sInstanceToUpdate = null;
  | 
      
      
        | 80 | 
        
         | 
        
         | 
        /* --- settings for SecureTokens ------------------------------------------------------ */
  | 
      
      
        | 81 | 
        
         | 
        
         | 
        /** use fingerprinting to encode */
  | 
      
      
        | 82 | 
        
         | 
        
         | 
            private $bUseFingerprint   = true;
  | 
      
      
        | 83 | 
        
         | 
        
         | 
        /** maximum lifetime of a token in seconds */
  | 
      
      
        | 84 | 
        
         | 
        
         | 
            private $iTokenLifeTime    = 1800; // between LIFETIME_MIN and LIFETIME_MAX (default = 30min)
  | 
      
      
        | 85 | 
        
         | 
        
         | 
        /** bit length of the IPv4 Netmask (0-32 // 0 = off  default = 24) */
  | 
      
      
        | 86 | 
        
         | 
        
         | 
            private $iNetmaskLengthV4  = 0;
  | 
      
      
        | 87 | 
        
         | 
        
         | 
        /** bit length of the IPv6 Netmask (0-128 // 0 = off  default = 64) */
  | 
      
      
        | 88 | 
        
         | 
        
         | 
            private $iNetmaskLengthV6  = 0;
  | 
      
      
        | 89 | 
        
         | 
        
         | 
        
  | 
      
      
        | 90 | 
        
         | 
        
         | 
            private static $oInstance = null;
  | 
      
      
        | 91 | 
        
         | 
        
         | 
        /**
  | 
      
      
        | 92 | 
        
         | 
        
         | 
         * constructor
  | 
      
      
        | 93 | 
        
         | 
        
         | 
         * @param (void)
  | 
      
      
        | 94 | 
        
         | 
        
         | 
         */
  | 
      
      
        | 95 | 
        
         | 
        
         | 
            protected function __construct()
  | 
      
      
        | 96 | 
        
         | 
        
         | 
            {
 | 
      
      
        | 97 | 
        
         | 
        
         | 
            // load settings if available
  | 
      
      
        | 98 | 
        
         | 
        
         | 
                $this->getSettings();
  | 
      
      
        | 99 | 
        
         | 
        
         | 
            // generate salt for calculations in this instance
  | 
      
      
        | 100 | 
        
         | 
        
         | 
                $this->sSalt            = $this->generateSalt();
  | 
      
      
        | 101 | 
        
         | 
        
         | 
            // generate fingerprint for the current connection
  | 
      
      
        | 102 | 
        
         | 
        
         | 
                $this->sFingerprint     = $this->buildFingerprint();
  | 
      
      
        | 103 | 
        
         | 
        
         | 
            // define the expiretime for this instance
  | 
      
      
        | 104 | 
        
         | 
        
         | 
                $this->iExpireTime      = time() + $this->iTokenLifeTime;
  | 
      
      
        | 105 | 
        
         | 
        
         | 
            // calculate the instance id for this instance
  | 
      
      
        | 106 | 
        
         | 
        
         | 
                $this->sCurrentInstance = $this->encodeHash(md5($this->iExpireTime.$this->sSalt));
  | 
      
      
        | 107 | 
        
         | 
        
         | 
            // load array of tokens from session
  | 
      
      
        | 108 | 
        
         | 
        
         | 
                $this->loadTokens();
  | 
      
      
        | 109 | 
        
         | 
        
         | 
            // at first of all remove expired tokens
  | 
      
      
        | 110 | 
        
         | 
        
         | 
                $this->removeExpiredTokens();
  | 
      
      
        | 111 | 
        
         | 
        
         | 
            }
  | 
      
      
        | 112 | 
        
         | 
        
         | 
        
  | 
      
      
        | 113 | 
        
         | 
        
         | 
            public static function getInstance()
  | 
      
      
        | 114 | 
        
         | 
        
         | 
            {
 | 
      
      
        | 115 | 
        
         | 
        
         | 
                if (self::$oInstance == null) {
 | 
      
      
        | 116 | 
        
         | 
        
         | 
                    $sClass = __CLASS__;
  | 
      
      
        | 117 | 
        
         | 
        
         | 
                    self::$oInstance = new $sClass();
  | 
      
      
        | 118 | 
        
         | 
        
         | 
                }
  | 
      
      
        | 119 | 
        
         | 
        
         | 
                return self::$oInstance;
  | 
      
      
        | 120 | 
        
         | 
        
         | 
            }
  | 
      
      
        | 121 | 
        
         | 
        
         | 
        
  | 
      
      
        | 122 | 
        
         | 
        
         | 
            private function __clone() {}
 | 
      
      
        | 123 | 
        
         | 
        
         | 
        
  | 
      
      
        | 124 | 
        
         | 
        
         | 
        /**
  | 
      
      
        | 125 | 
        
         | 
        
         | 
         * destructor
  | 
      
      
        | 126 | 
        
         | 
        
         | 
         */
  | 
      
      
        | 127 | 
        
         | 
        
         | 
            final public function __destruct()
  | 
      
      
        | 128 | 
        
         | 
        
         | 
            {
 | 
      
      
        | 129 | 
        
         | 
        
         | 
                foreach ($this->aTokens as $sKey => $aToken) {
 | 
      
      
        | 130 | 
        
         | 
        
         | 
                    if ($aToken['instance'] == $this->sInstanceToUpdate) {
 | 
      
      
        | 131 | 
        
         | 
        
         | 
                        $this->aTokens[$sKey]['instance'] = $this->sCurrentInstance;
  | 
      
      
        | 132 | 
        
         | 
        
         | 
                        $this->aTokens[$sKey]['expire']   = $this->iExpireTime;
  | 
      
      
        | 133 | 
        
         | 
        
         | 
                    } elseif ($aToken['instance'] == $this->sInstanceToDelete) {
 | 
      
      
        | 134 | 
        
         | 
        
         | 
                        unset($this->aTokens[$sKey]);
  | 
      
      
        | 135 | 
        
         | 
        
         | 
                    }
  | 
      
      
        | 136 | 
        
         | 
        
         | 
                }
  | 
      
      
        | 137 | 
        
         | 
        
         | 
                $this->saveTokens();
  | 
      
      
        | 138 | 
        
         | 
        
         | 
            }
  | 
      
      
        | 139 | 
        
         | 
        
         | 
        
  | 
      
      
        | 140 | 
        
         | 
        
         | 
        /**
  | 
      
      
        | 141 | 
        
         | 
        
         | 
         * returns the current FTAN
  | 
      
      
        | 142 | 
        
         | 
        
         | 
         * @param bool $mode: true or POST returns a complete prepared, hidden HTML-Input-Tag (default)
  | 
      
      
        | 143 | 
        
         | 
        
         | 
         *                     false or GET returns an GET argument 'key=value'
  | 
      
      
        | 144 | 
        
         | 
        
         | 
         * @return mixed:     array or string
  | 
      
      
        | 145 | 
        
         | 
        
         | 
         * @deprecated the param $mMode is set deprecated
  | 
      
      
        | 146 | 
        
         | 
        
         | 
         *              string retvals are set deprecated. From versions after 2.8.4 retval will be array only
  | 
      
      
        | 147 | 
        
         | 
        
         | 
         */
  | 
      
      
        | 148 | 
        
         | 
        
         | 
            final public function getFTAN($mMode = 'POST')
  | 
      
      
        | 149 | 
        
         | 
        
         | 
            {
 | 
      
      
        | 150 | 
        
         | 
        
         | 
                if (is_null($this->aLastCreatedFtan)) {
 | 
      
      
        | 151 | 
        
         | 
        
         | 
                    $sFtan = md5($this->sSalt);
  | 
      
      
        | 152 | 
        
         | 
        
         | 
                    $this->aLastCreatedFtan = $this->addToken(
  | 
      
      
        | 153 | 
        
         | 
        
         | 
                        substr($sFtan, rand(0,15), 16),
  | 
      
      
        | 154 | 
        
         | 
        
         | 
                        substr($sFtan, rand(0,15), 16)
  | 
      
      
        | 155 | 
        
         | 
        
         | 
                    );
  | 
      
      
        | 156 | 
        
         | 
        
         | 
                }
  | 
      
      
        | 157 | 
        
         | 
        
         | 
                $aFtan = $this->aTokens[$this->aLastCreatedFtan];
  | 
      
      
        | 158 | 
        
         | 
        
         | 
                $aFtan['name']  = $this->aLastCreatedFtan;
  | 
      
      
        | 159 | 
        
         | 
        
         | 
                $aFtan['value'] = $this->encodeHash(md5($aFtan['value'].$this->sFingerprint));
  | 
      
      
        | 160 | 
        
         | 
        
         | 
                if (is_string($mMode)) {
 | 
      
      
        | 161 | 
        
         | 
        
         | 
                    $mMode = strtoupper($mMode);
  | 
      
      
        | 162 | 
        
         | 
        
         | 
                } else {
 | 
      
      
        | 163 | 
        
         | 
        
         | 
                    $mMode = $mMode === true ? 'POST' : 'GET';
  | 
      
      
        | 164 | 
        
         | 
        
         | 
                }
  | 
      
      
        | 165 | 
        
         | 
        
         | 
                switch ($mMode):
  | 
      
      
        | 166 | 
        
         | 
        
         | 
                    case 'POST':
  | 
      
      
        | 167 | 
        
         | 
        
         | 
                        return '<input type="hidden" name="'.$aFtan['name'].'" value="'
  | 
      
      
        | 168 | 
        
         | 
        
         | 
                              .$aFtan['value'].'" title="">';
  | 
      
      
        | 169 | 
        
         | 
        
         | 
                        break;
  | 
      
      
        | 170 | 
        
         | 
        
         | 
                    case 'GET':
  | 
      
      
        | 171 | 
        
         | 
        
         | 
                        return $aFtan['name'].'='.$aFtan['value'];
  | 
      
      
        | 172 | 
        
         | 
        
         | 
                        break;
  | 
      
      
        | 173 | 
        
         | 
        
         | 
                    default:
  | 
      
      
        | 174 | 
        
         | 
        
         | 
                        return array('name' => $aFtan['name'], 'value' => $aFtan['value']);
 | 
      
      
        | 175 | 
        
         | 
        
         | 
                endswitch;
  | 
      
      
        | 176 | 
        
         | 
        
         | 
            }
  | 
      
      
        | 177 | 
        
         | 
        
         | 
        
  | 
      
      
        | 178 | 
        
         | 
        
         | 
        /**
  | 
      
      
        | 179 | 
        
         | 
        
         | 
         * checks received form-transactionnumbers against session-stored one
  | 
      
      
        | 180 | 
        
         | 
        
         | 
         * @param string $mode: requestmethode POST(default) or GET
  | 
      
      
        | 181 | 
        
         | 
        
         | 
         * @param bool $bPreserve (default=false)
  | 
      
      
        | 182 | 
        
         | 
        
         | 
         * @return bool:    true if numbers matches against stored ones
  | 
      
      
        | 183 | 
        
         | 
        
         | 
         *
  | 
      
      
        | 184 | 
        
         | 
        
         | 
         * requirements: an active session must be available
  | 
      
      
        | 185 | 
        
         | 
        
         | 
         * this check will prevent from multiple sending a form. history.back() also will never work
  | 
      
      
        | 186 | 
        
         | 
        
         | 
         */
  | 
      
      
        | 187 | 
        
         | 
        
         | 
            final public function checkFTAN($mMode = 'POST')
  | 
      
      
        | 188 | 
        
         | 
        
         | 
            {
 | 
      
      
        | 189 | 
        
         | 
        
         | 
                $bRetval = false;
  | 
      
      
        | 190 | 
        
         | 
        
         | 
                // get the POST/GET arguments
  | 
      
      
        | 191 | 
        
         | 
        
         | 
                $aArguments = (strtoupper($mMode) == 'POST' ? $_POST : $_GET);
  | 
      
      
        | 192 | 
        
         | 
        
         | 
                // encode the value of all matching tokens
  | 
      
      
        | 193 | 
        
         | 
        
         | 
                $aMatchingTokens = array_map(
  | 
      
      
        | 194 | 
        
         | 
        
         | 
                    array($this, 'checkFtanCallback'),
  | 
      
      
        | 195 | 
        
         | 
        
         | 
            //            function ($aToken) {
 | 
      
      
        | 196 | 
        
         | 
        
         | 
            //                return $this->encode64(md5($aToken['value'].$this->sFingerprint));
  | 
      
      
        | 197 | 
        
         | 
        
         | 
            //            },
  | 
      
      
        | 198 | 
        
         | 
        
         | 
                        // extract all matching tokens from $this->aTokens
  | 
      
      
        | 199 | 
        
         | 
        
         | 
                        array_intersect_key($this->aTokens, $aArguments)
  | 
      
      
        | 200 | 
        
         | 
        
         | 
                );
  | 
      
      
        | 201 | 
        
         | 
        
         | 
        //echo "<pre>".print_r(debug_backtrace(0),true)."</pre>";
  | 
      
      
        | 202 | 
        
         | 
        
         | 
                // extract all matching arguments from $aArguments
  | 
      
      
        | 203 | 
        
         | 
        
         | 
                $aMatchingArguments = array_intersect_key($aArguments, $this->aTokens);
  | 
      
      
        | 204 | 
        
         | 
        
         | 
                // get all tokens with matching values from match lists
  | 
      
      
        | 205 | 
        
         | 
        
         | 
                $aHits = array_intersect($aMatchingTokens, $aMatchingArguments);
  | 
      
      
        | 206 | 
        
         | 
        
         | 
                foreach ($aHits as $sTokenName => $sValue) {
 | 
      
      
        | 207 | 
        
         | 
        
         | 
                    $bRetval = true;
  | 
      
      
        | 208 | 
        
         | 
        
         | 
                    $this->removeToken($sTokenName);
  | 
      
      
        | 209 | 
        
         | 
        
         | 
                }
  | 
      
      
        | 210 | 
        
         | 
        
         | 
                return $bRetval;
  | 
      
      
        | 211 | 
        
         | 
        
         | 
            }
  | 
      
      
        | 212 | 
        
         | 
        
         | 
        /**
  | 
      
      
        | 213 | 
        
         | 
        
         | 
         * store value in session and returns an accesskey to it
  | 
      
      
        | 214 | 
        
         | 
        
         | 
         * @param mixed $mValue can be numeric, string or array
  | 
      
      
        | 215 | 
        
         | 
        
         | 
         * @return string
  | 
      
      
        | 216 | 
        
         | 
        
         | 
         */
  | 
      
      
        | 217 | 
        
         | 
        
         | 
            final public function getIDKEY($mValue)
  | 
      
      
        | 218 | 
        
         | 
        
         | 
            {
 | 
      
      
        | 219 | 
        
         | 
        
         | 
                if (is_array($mValue) == true) {
 | 
      
      
        | 220 | 
        
         | 
        
         | 
                    // serialize value, if it's an array
  | 
      
      
        | 221 | 
        
         | 
        
         | 
                    $mValue = serialize($mValue);
  | 
      
      
        | 222 | 
        
         | 
        
         | 
                }
  | 
      
      
        | 223 | 
        
         | 
        
         | 
                // crypt value with salt into md5-hash and return a 16-digit block from random start position
  | 
      
      
        | 224 | 
        
         | 
        
         | 
                $sTokenName = $this->addToken(
  | 
      
      
        | 225 | 
        
         | 
        
         | 
                    substr(md5($this->sSalt.(string)$mValue), rand(0,15), 16),
  | 
      
      
        | 226 | 
        
         | 
        
         | 
                    $mValue
  | 
      
      
        | 227 | 
        
         | 
        
         | 
                );
  | 
      
      
        | 228 | 
        
         | 
        
         | 
                return $sTokenName;
  | 
      
      
        | 229 | 
        
         | 
        
         | 
            }
  | 
      
      
        | 230 | 
        
         | 
        
         | 
        
  | 
      
      
        | 231 | 
        
         | 
        
         | 
        /*
  | 
      
      
        | 232 | 
        
         | 
        
         | 
         * search for key in session and returns the original value
  | 
      
      
        | 233 | 
        
         | 
        
         | 
         * @param string $sFieldname: name of the POST/GET-Field containing the key or hex-key itself
  | 
      
      
        | 234 | 
        
         | 
        
         | 
         * @param mixed $mDefault: returnvalue if key not exist (default 0)
  | 
      
      
        | 235 | 
        
         | 
        
         | 
         * @param string $sRequest: requestmethode can be POST or GET or '' (default POST)
  | 
      
      
        | 236 | 
        
         | 
        
         | 
         * @param bool $bPreserve (default=false)
  | 
      
      
        | 237 | 
        
         | 
        
         | 
         * @return mixed: the original value (string, numeric, array) or DEFAULT if request fails
  | 
      
      
        | 238 | 
        
         | 
        
         | 
         * @description: each IDKEY can be checked only once. Unused Keys stay in list until they expire
  | 
      
      
        | 239 | 
        
         | 
        
         | 
         */
  | 
      
      
        | 240 | 
        
         | 
        
         | 
            final public function checkIDKEY($sFieldname, $mDefault = 0, $sRequest = 'POST', $bPreserve = false)
  | 
      
      
        | 241 | 
        
         | 
        
         | 
            {
 | 
      
      
        | 242 | 
        
         | 
        
         | 
                $mReturnValue = $mDefault; // set returnvalue to default
  | 
      
      
        | 243 | 
        
         | 
        
         | 
                $this->bPreserveAllOtherTokens = $bPreserve ?: $this->bPreserveAllOtherTokens;
  | 
      
      
        | 244 | 
        
         | 
        
         | 
                $sRequest = strtoupper($sRequest);
  | 
      
      
        | 245 | 
        
         | 
        
         | 
                switch ($sRequest) {
 | 
      
      
        | 246 | 
        
         | 
        
         | 
                    case 'POST':
  | 
      
      
        | 247 | 
        
         | 
        
         | 
                        $sTokenName = $_POST[$sFieldname] ?: $sFieldname;
  | 
      
      
        | 248 | 
        
         | 
        
         | 
                        break;
  | 
      
      
        | 249 | 
        
         | 
        
         | 
                    case 'GET':
  | 
      
      
        | 250 | 
        
         | 
        
         | 
                        $sTokenName = $_GET[$sFieldname] ?: $sFieldname;
  | 
      
      
        | 251 | 
        
         | 
        
         | 
                        break;
  | 
      
      
        | 252 | 
        
         | 
        
         | 
                    default:
  | 
      
      
        | 253 | 
        
         | 
        
         | 
                        $sTokenName = $sFieldname;
  | 
      
      
        | 254 | 
        
         | 
        
         | 
                }
  | 
      
      
        | 255 | 
        
         | 
        
         | 
                if (preg_match('/^[0-9a-f]{16}$/i', $sTokenName)) {
 | 
      
      
        | 256 | 
        
         | 
        
         | 
                // key must be a 16-digit hexvalue
  | 
      
      
        | 257 | 
        
         | 
        
         | 
                    if (array_key_exists($sTokenName, $this->aTokens)) {
 | 
      
      
        | 258 | 
        
         | 
        
         | 
                    // check if key is stored in IDKEYs-list
  | 
      
      
        | 259 | 
        
         | 
        
         | 
                        $mReturnValue = $this->aTokens[$sTokenName]['value']; // get stored value
  | 
      
      
        | 260 | 
        
         | 
        
         | 
                        $this->removeToken($sTokenName);   // remove from list to prevent multiuse
  | 
      
      
        | 261 | 
        
         | 
        
         | 
                        if (preg_match('/.*(?<!\{).*(\d:\{.*;\}).*(?!\}).*/', $mReturnValue)) {
 | 
      
      
        | 262 | 
        
         | 
        
         | 
                        // if value is a serialized array, then deserialize it
  | 
      
      
        | 263 | 
        
         | 
        
         | 
                            $mReturnValue = unserialize($mReturnValue);
  | 
      
      
        | 264 | 
        
         | 
        
         | 
                        }
  | 
      
      
        | 265 | 
        
         | 
        
         | 
                    }
  | 
      
      
        | 266 | 
        
         | 
        
         | 
                }
  | 
      
      
        | 267 | 
        
         | 
        
         | 
                return $mReturnValue;
  | 
      
      
        | 268 | 
        
         | 
        
         | 
            }
  | 
      
      
        | 269 | 
        
         | 
        
         | 
        
  | 
      
      
        | 270 | 
        
         | 
        
         | 
        /**
  | 
      
      
        | 271 | 
        
         | 
        
         | 
         * make a valid LifeTime value from given integer on the rules of class SecureTokens
  | 
      
      
        | 272 | 
        
         | 
        
         | 
         * @param integer  $iLifeTime
  | 
      
      
        | 273 | 
        
         | 
        
         | 
         * @return integer
  | 
      
      
        | 274 | 
        
         | 
        
         | 
         */
  | 
      
      
        | 275 | 
        
         | 
        
         | 
            final public function sanitizeLifeTime($iLifeTime)
  | 
      
      
        | 276 | 
        
         | 
        
         | 
            {
 | 
      
      
        | 277 | 
        
         | 
        
         | 
                $iLifeTime = intval($iLifeTime);
  | 
      
      
        | 278 | 
        
         | 
        
         | 
                for ($i = self::LIFETIME_MIN; $i <= self::LIFETIME_MAX; $i += self::LIFETIME_STEP) {
 | 
      
      
        | 279 | 
        
         | 
        
         | 
                    $aLifeTimes[] = $i;
  | 
      
      
        | 280 | 
        
         | 
        
         | 
                }
  | 
      
      
        | 281 | 
        
         | 
        
         | 
                $iRetval = array_pop($aLifeTimes);
  | 
      
      
        | 282 | 
        
         | 
        
         | 
                foreach ($aLifeTimes as $iValue) {
 | 
      
      
        | 283 | 
        
         | 
        
         | 
                    if ($iLifeTime <= $iValue) {
 | 
      
      
        | 284 | 
        
         | 
        
         | 
                        $iRetval = $iValue;
  | 
      
      
        | 285 | 
        
         | 
        
         | 
                        break;
  | 
      
      
        | 286 | 
        
         | 
        
         | 
                    }
  | 
      
      
        | 287 | 
        
         | 
        
         | 
                }
  | 
      
      
        | 288 | 
        
         | 
        
         | 
                return $iRetval;
  | 
      
      
        | 289 | 
        
         | 
        
         | 
            }
  | 
      
      
        | 290 | 
        
         | 
        
         | 
        
  | 
      
      
        | 291 | 
        
         | 
        
         | 
        /**
  | 
      
      
        | 292 | 
        
         | 
        
         | 
         * returns all TokenLifeTime values
  | 
      
      
        | 293 | 
        
         | 
        
         | 
         * @return array
  | 
      
      
        | 294 | 
        
         | 
        
         | 
         */
  | 
      
      
        | 295 | 
        
         | 
        
         | 
            final public function getTokenLifeTime()
  | 
      
      
        | 296 | 
        
         | 
        
         | 
            {
 | 
      
      
        | 297 | 
        
         | 
        
         | 
                return array(
  | 
      
      
        | 298 | 
        
         | 
        
         | 
                    'min'   => self::LIFETIME_MIN,
  | 
      
      
        | 299 | 
        
         | 
        
         | 
                    'max'   => self::LIFETIME_MAX,
  | 
      
      
        | 300 | 
        
         | 
        
         | 
                    'step'  => self::LIFETIME_STEP,
  | 
      
      
        | 301 | 
        
         | 
        
         | 
                    'value' => $this->iTokenLifeTime
  | 
      
      
        | 302 | 
        
         | 
        
         | 
                );
  | 
      
      
        | 303 | 
        
         | 
        
         | 
            }
  | 
      
      
        | 304 | 
        
         | 
        
         | 
        
  | 
      
      
        | 305 | 
        
         | 
        
         | 
        /* ************************************************************************************ */
  | 
      
      
        | 306 | 
        
         | 
        
         | 
        /* *** from here private methods only                                               *** */
  | 
      
      
        | 307 | 
        
         | 
        
         | 
        /* ************************************************************************************ */
  | 
      
      
        | 308 | 
        
         | 
        
         | 
        /**
  | 
      
      
        | 309 | 
        
         | 
        
         | 
         * load all tokens from session
  | 
      
      
        | 310 | 
        
         | 
        
         | 
         */
  | 
      
      
        | 311 | 
        
         | 
        
         | 
            private function loadTokens()
  | 
      
      
        | 312 | 
        
         | 
        
         | 
            {
 | 
      
      
        | 313 | 
        
         | 
        
         | 
                if (isset($_SESSION['TOKENS'])) {
 | 
      
      
        | 314 | 
        
         | 
        
         | 
                    $this->aTokens = unserialize($_SESSION['TOKENS']);
  | 
      
      
        | 315 | 
        
         | 
        
         | 
                } else {
 | 
      
      
        | 316 | 
        
         | 
        
         | 
                    $this->saveTokens();
  | 
      
      
        | 317 | 
        
         | 
        
         | 
                }
  | 
      
      
        | 318 | 
        
         | 
        
         | 
            }
  | 
      
      
        | 319 | 
        
         | 
        
         | 
        
  | 
      
      
        | 320 | 
        
         | 
        
         | 
        /**
  | 
      
      
        | 321 | 
        
         | 
        
         | 
         * save all tokens into session
  | 
      
      
        | 322 | 
        
         | 
        
         | 
         */
  | 
      
      
        | 323 | 
        
         | 
        
         | 
            private function saveTokens()
  | 
      
      
        | 324 | 
        
         | 
        
         | 
            {
 | 
      
      
        | 325 | 
        
         | 
        
         | 
                $_SESSION['TOKENS'] = serialize($this->aTokens);
  | 
      
      
        | 326 | 
        
         | 
        
         | 
            }
  | 
      
      
        | 327 | 
        
         | 
        
         | 
        
  | 
      
      
        | 328 | 
        
         | 
        
         | 
        /**
  | 
      
      
        | 329 | 
        
         | 
        
         | 
         * add new token to the list
  | 
      
      
        | 330 | 
        
         | 
        
         | 
         * @param string $sTokenName
  | 
      
      
        | 331 | 
        
         | 
        
         | 
         * @param string $sValue
  | 
      
      
        | 332 | 
        
         | 
        
         | 
         * @return string  name(index) of the token
  | 
      
      
        | 333 | 
        
         | 
        
         | 
         */
  | 
      
      
        | 334 | 
        
         | 
        
         | 
            private function addToken($sTokenName, $sValue)
  | 
      
      
        | 335 | 
        
         | 
        
         | 
            {
 | 
      
      
        | 336 | 
        
         | 
        
         | 
                // limit TokenName to 16 digits
  | 
      
      
        | 337 | 
        
         | 
        
         | 
                $sTokenName = substr(str_pad($sTokenName, 16, '0', STR_PAD_LEFT), -16);
  | 
      
      
        | 338 | 
        
         | 
        
         | 
                // make sure, first digit is a alpha char [a-f]
  | 
      
      
        | 339 | 
        
         | 
        
         | 
                $sTokenName[0] = dechex(10 + (hexdec($sTokenName[0]) % 5));
  | 
      
      
        | 340 | 
        
         | 
        
         | 
                // loop as long the generated TokenName already exists in list
  | 
      
      
        | 341 | 
        
         | 
        
         | 
                while (isset($this->aTokens[$sTokenName])) {
 | 
      
      
        | 342 | 
        
         | 
        
         | 
                    // split TokenName into 4 words
  | 
      
      
        | 343 | 
        
         | 
        
         | 
                    $aWords = str_split($sTokenName, 4);
  | 
      
      
        | 344 | 
        
         | 
        
         | 
                    // get lowest word and increment it
  | 
      
      
        | 345 | 
        
         | 
        
         | 
                    $iWord = hexdec($aWords[3]) + 1;
  | 
      
      
        | 346 | 
        
         | 
        
         | 
                    // reformat integer into a 4 digit hex string
  | 
      
      
        | 347 | 
        
         | 
        
         | 
                    $aWords[3] = sprintf('%04x', ($iWord > 0xffff ? 1 : $iWord));
 | 
      
      
        | 348 | 
        
         | 
        
         | 
                    // rebuild the TokenName
  | 
      
      
        | 349 | 
        
         | 
        
         | 
                    $sTokenName = implode('', $aWords);
 | 
      
      
        | 350 | 
        
         | 
        
         | 
                }
  | 
      
      
        | 351 | 
        
         | 
        
         | 
                // store Token in list
  | 
      
      
        | 352 | 
        
         | 
        
         | 
                $this->aTokens[$sTokenName] = array(
  | 
      
      
        | 353 | 
        
         | 
        
         | 
                    'value'    => $sValue,
  | 
      
      
        | 354 | 
        
         | 
        
         | 
                    'expire'   => $this->iExpireTime,
  | 
      
      
        | 355 | 
        
         | 
        
         | 
                    'instance' => $this->sCurrentInstance
  | 
      
      
        | 356 | 
        
         | 
        
         | 
                );
  | 
      
      
        | 357 | 
        
         | 
        
         | 
                return $sTokenName;
  | 
      
      
        | 358 | 
        
         | 
        
         | 
            }
  | 
      
      
        | 359 | 
        
         | 
        
         | 
        
  | 
      
      
        | 360 | 
        
         | 
        
         | 
        /**
  | 
      
      
        | 361 | 
        
         | 
        
         | 
         * remove the token, called sTokenName from list
  | 
      
      
        | 362 | 
        
         | 
        
         | 
         * @param type $sTokenName
  | 
      
      
        | 363 | 
        
         | 
        
         | 
         */
  | 
      
      
        | 364 | 
        
         | 
        
         | 
            private function removeToken($sTokenName)
  | 
      
      
        | 365 | 
        
         | 
        
         | 
            {
 | 
      
      
        | 366 | 
        
         | 
        
         | 
                if (isset($this->aTokens[$sTokenName])) {
 | 
      
      
        | 367 | 
        
         | 
        
         | 
                    if ($this->bPreserveAllOtherTokens) {
 | 
      
      
        | 368 | 
        
         | 
        
         | 
                        if ($this->sInstanceToDelete) {
 | 
      
      
        | 369 | 
        
         | 
        
         | 
                            $this->sInstanceToUpdate = $this->sInstanceToDelete;
  | 
      
      
        | 370 | 
        
         | 
        
         | 
                            $this->sInstanceToDelete = null;
  | 
      
      
        | 371 | 
        
         | 
        
         | 
                        } else {
 | 
      
      
        | 372 | 
        
         | 
        
         | 
                            $this->sInstanceToUpdate = $this->aTokens[$sTokenName]['instance'];
  | 
      
      
        | 373 | 
        
         | 
        
         | 
                        }
  | 
      
      
        | 374 | 
        
         | 
        
         | 
                    } else {
 | 
      
      
        | 375 | 
        
         | 
        
         | 
                        $this->sInstanceToDelete = $this->aTokens[$sTokenName]['instance'];
  | 
      
      
        | 376 | 
        
         | 
        
         | 
                    }
  | 
      
      
        | 377 | 
        
         | 
        
         | 
                    unset($this->aTokens[$sTokenName]);
  | 
      
      
        | 378 | 
        
         | 
        
         | 
                }
  | 
      
      
        | 379 | 
        
         | 
        
         | 
            }
  | 
      
      
        | 380 | 
        
         | 
        
         | 
        
  | 
      
      
        | 381 | 
        
         | 
        
         | 
        /**
  | 
      
      
        | 382 | 
        
         | 
        
         | 
         * remove all expired tokens from list
  | 
      
      
        | 383 | 
        
         | 
        
         | 
         */
  | 
      
      
        | 384 | 
        
         | 
        
         | 
            private function removeExpiredTokens()
  | 
      
      
        | 385 | 
        
         | 
        
         | 
            {
 | 
      
      
        | 386 | 
        
         | 
        
         | 
                $iTimestamp = time();
  | 
      
      
        | 387 | 
        
         | 
        
         | 
                foreach ($this->aTokens as $sTokenName => $aToken) {
 | 
      
      
        | 388 | 
        
         | 
        
         | 
                    if ($aToken['expire'] <= $iTimestamp && $aToken['expire'] != 0){
 | 
      
      
        | 389 | 
        
         | 
        
         | 
                        unset($this->aTokens[$sTokenName]);
  | 
      
      
        | 390 | 
        
         | 
        
         | 
                    }
  | 
      
      
        | 391 | 
        
         | 
        
         | 
                }
  | 
      
      
        | 392 | 
        
         | 
        
         | 
            }
  | 
      
      
        | 393 | 
        
         | 
        
         | 
        
  | 
      
      
        | 394 | 
        
         | 
        
         | 
        /**
  | 
      
      
        | 395 | 
        
         | 
        
         | 
         * generate a runtime depended hash
  | 
      
      
        | 396 | 
        
         | 
        
         | 
         * @return string  md5 hash
  | 
      
      
        | 397 | 
        
         | 
        
         | 
         */
  | 
      
      
        | 398 | 
        
         | 
        
         | 
            private function generateSalt()
  | 
      
      
        | 399 | 
        
         | 
        
         | 
            {
 | 
      
      
        | 400 | 
        
         | 
        
         | 
                list($fUsec, $fSec) = explode(" ", microtime());
 | 
      
      
        | 401 | 
        
         | 
        
         | 
                $sSalt = (string)rand(10000, 99999)
  | 
      
      
        | 402 | 
        
         | 
        
         | 
                       . (string)((float)$fUsec + (float)$fSec)
  | 
      
      
        | 403 | 
        
         | 
        
         | 
                       . (string)rand(10000, 99999);
  | 
      
      
        | 404 | 
        
         | 
        
         | 
                return md5($sSalt);
  | 
      
      
        | 405 | 
        
         | 
        
         | 
            }
  | 
      
      
        | 406 | 
        
         | 
        
         | 
        
  | 
      
      
        | 407 | 
        
         | 
        
         | 
        /**
  | 
      
      
        | 408 | 
        
         | 
        
         | 
         * build a simple fingerprint
  | 
      
      
        | 409 | 
        
         | 
        
         | 
         * @return string
  | 
      
      
        | 410 | 
        
         | 
        
         | 
         */
  | 
      
      
        | 411 | 
        
         | 
        
         | 
            private function buildFingerprint()
  | 
      
      
        | 412 | 
        
         | 
        
         | 
            {
 | 
      
      
        | 413 | 
        
         | 
        
         | 
                if (!$this->bUseFingerprint) { return md5('this_is_a_dummy_only'); }
 | 
      
      
        | 414 | 
        
         | 
        
         | 
                $sClientIp = '127.0.0.1';
  | 
      
      
        | 415 | 
        
         | 
        
         | 
                if (array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER)){
 | 
      
      
        | 416 | 
        
         | 
        
         | 
                    $aTmp = preg_split('/\s*,\s*/', $_SERVER['HTTP_X_FORWARDED_FOR'], null, PREG_SPLIT_NO_EMPTY);
 | 
      
      
        | 417 | 
        
         | 
        
         | 
                    $sClientIp = array_pop($aTmp);
  | 
      
      
        | 418 | 
        
         | 
        
         | 
                }else if (array_key_exists('REMOTE_ADDR', $_SERVER)) {
 | 
      
      
        | 419 | 
        
         | 
        
         | 
                    $sClientIp = $_SERVER['REMOTE_ADDR'];
  | 
      
      
        | 420 | 
        
         | 
        
         | 
                }else if (array_key_exists('HTTP_CLIENT_IP', $_SERVER)) {
 | 
      
      
        | 421 | 
        
         | 
        
         | 
                    $sClientIp = $_SERVER['HTTP_CLIENT_IP'];
  | 
      
      
        | 422 | 
        
         | 
        
         | 
                }
  | 
      
      
        | 423 | 
        
         | 
        
         | 
                $aTmp = array_chunk(stat(__FILE__), 11);
  | 
      
      
        | 424 | 
        
         | 
        
         | 
                unset($aTmp[0][8]);
  | 
      
      
        | 425 | 
        
         | 
        
         | 
                return md5(
  | 
      
      
        | 426 | 
        
         | 
        
         | 
                    __FILE__ . PHP_VERSION . implode('', $aTmp[0])
 | 
      
      
        | 427 | 
        
         | 
        
         | 
                    . (array_key_exists('HTTP_USER_AGENT', $_SERVER) ? $_SERVER['HTTP_USER_AGENT'] : 'AGENT')
 | 
      
      
        | 428 | 
        
         | 
        
         | 
                    . $this->calcClientIpHash($sClientIp)
  | 
      
      
        | 429 | 
        
         | 
        
         | 
                );
  | 
      
      
        | 430 | 
        
         | 
        
         | 
            }
  | 
      
      
        | 431 | 
        
         | 
        
         | 
        
  | 
      
      
        | 432 | 
        
         | 
        
         | 
        /**
  | 
      
      
        | 433 | 
        
         | 
        
         | 
         * mask IPv4 as well IPv6 addresses with netmask and make a md5 hash from
  | 
      
      
        | 434 | 
        
         | 
        
         | 
         * @param string $sClientIp IP as string from $_SERVER['REMOTE_ADDR']
  | 
      
      
        | 435 | 
        
         | 
        
         | 
         * @return md5 value of masked ip
  | 
      
      
        | 436 | 
        
         | 
        
         | 
         * @description this method does not accept the IPv6/IPv4 mixed format
  | 
      
      
        | 437 | 
        
         | 
        
         | 
         *               like "2222:3333:4444:5555:6666:7777:192.168.1.200"
  | 
      
      
        | 438 | 
        
         | 
        
         | 
         */
  | 
      
      
        | 439 | 
        
         | 
        
         | 
            private function calcClientIpHash($sRawIp)
  | 
      
      
        | 440 | 
        
         | 
        
         | 
            {
 | 
      
      
        | 441 | 
        
         | 
        
         | 
                // clean address from netmask/prefix and port
  | 
      
      
        | 442 | 
        
         | 
        
         | 
                $sPattern = '/^\[?([.:a-f0-9]*)(?:\/[0-1]*)?(?:\]?.*)$/im';
  | 
      
      
        | 443 | 
        
         | 
        
         | 
                $sRawIp = preg_replace($sPattern, '$1', $sRawIp);
  | 
      
      
        | 444 | 
        
         | 
        
         | 
                if (strpos($sRawIp, ':') === false) {
 | 
      
      
        | 445 | 
        
         | 
        
         | 
        // sanitize IPv4 ---------------------------------------------------------------------- //
  | 
      
      
        | 446 | 
        
         | 
        
         | 
                    $iIpV4 = ip2long($sRawIp);
  | 
      
      
        | 447 | 
        
         | 
        
         | 
                    // calculate netmask
  | 
      
      
        | 448 | 
        
         | 
        
         | 
                    $iMask = ($this->iNetmaskLengthV4 < 1)
  | 
      
      
        | 449 | 
        
         | 
        
         | 
                        ? 0
  | 
      
      
        | 450 | 
        
         | 
        
         | 
                        : bindec(
  | 
      
      
        | 451 | 
        
         | 
        
         | 
                            str_repeat('1', $this->iNetmaskLengthV4).
 | 
      
      
        | 452 | 
        
         | 
        
         | 
                            str_repeat('0', 32 - $this->iNetmaskLengthV4)
 | 
      
      
        | 453 | 
        
         | 
        
         | 
                        );
  | 
      
      
        | 454 | 
        
         | 
        
         | 
                    // apply mask and reformat to IPv4 string notation.
  | 
      
      
        | 455 | 
        
         | 
        
         | 
                    $sIp = long2ip($iIpV4 & $iMask);
  | 
      
      
        | 456 | 
        
         | 
        
         | 
                } else {
 | 
      
      
        | 457 | 
        
         | 
        
         | 
        // sanitize IPv6 ---------------------------------------------------------------------- //
  | 
      
      
        | 458 | 
        
         | 
        
         | 
                    // check if IP includes a IPv4 part and convert this into IPv6 format
  | 
      
      
        | 459 | 
        
         | 
        
         | 
                    $sPattern = '/^([:a-f0-9]*?)\:([0-9]{1,3}(?:\.[0-9]{1,3}){3})$/is';
 | 
      
      
        | 460 | 
        
         | 
        
         | 
                    if (preg_match($sPattern, $sRawIp, $aMatches)) {
 | 
      
      
        | 461 | 
        
         | 
        
         | 
                        // convert IPv4 into full size 32bit binary string
  | 
      
      
        | 462 | 
        
         | 
        
         | 
                        $sIpV4Bin = str_pad((string)decbin(ip2long($aMatches[2])), 32, '0', STR_PAD_LEFT) ;
  | 
      
      
        | 463 | 
        
         | 
        
         | 
                        // split into 2 parts of 16bit
  | 
      
      
        | 464 | 
        
         | 
        
         | 
                        $aIpV6Hex = str_split($sIpV4Bin, 16);
  | 
      
      
        | 465 | 
        
         | 
        
         | 
                        // concate the IPv6/96 part and hex of both IPv4 parts
  | 
      
      
        | 466 | 
        
         | 
        
         | 
                        $sRawIp = $aMatches[1].':'.dechex(bindec($aIpV6Hex[0])).':'.dechex(bindec($aIpV6Hex[1]));
  | 
      
      
        | 467 | 
        
         | 
        
         | 
                    }
  | 
      
      
        | 468 | 
        
         | 
        
         | 
                    // calculate number of missing IPv6 words
  | 
      
      
        | 469 | 
        
         | 
        
         | 
                    $iWords = 8 - count(preg_split('/:/', $sRawIp, null, PREG_SPLIT_NO_EMPTY));
 | 
      
      
        | 470 | 
        
         | 
        
         | 
                    // build multiple ':0000:' replacements for '::'
  | 
      
      
        | 471 | 
        
         | 
        
         | 
                    $sReplacement = $iWords ? implode(':', array_fill(0, $iWords, '0000')) : '';
 | 
      
      
        | 472 | 
        
         | 
        
         | 
                    // insert replacements and remove trailing/leading ':'
  | 
      
      
        | 473 | 
        
         | 
        
         | 
                    $sClientIp = trim(preg_replace('/\:\:/', ':'.$sReplacement.':', $sRawIp), ':');
 | 
      
      
        | 474 | 
        
         | 
        
         | 
                    // split all 8 parts from IP into an array
  | 
      
      
        | 475 | 
        
         | 
        
         | 
                    $aIpV6 = array_map(
  | 
      
      
        | 476 | 
        
         | 
        
         | 
                        function($sPart) {
 | 
      
      
        | 477 | 
        
         | 
        
         | 
                            // expand all parts to 4 hex digits using leading '0'
  | 
      
      
        | 478 | 
        
         | 
        
         | 
                            return str_pad($sPart, 4, '0', STR_PAD_LEFT);
  | 
      
      
        | 479 | 
        
         | 
        
         | 
                        },
  | 
      
      
        | 480 | 
        
         | 
        
         | 
                        preg_split('/:/', $sClientIp)
 | 
      
      
        | 481 | 
        
         | 
        
         | 
                    );
  | 
      
      
        | 482 | 
        
         | 
        
         | 
                    // build binary netmask from iNetmaskLengthV6
  | 
      
      
        | 483 | 
        
         | 
        
         | 
                    // and split all 8 parts into an array
  | 
      
      
        | 484 | 
        
         | 
        
         | 
                    if ($this->iNetmaskLengthV6 < 1) {
 | 
      
      
        | 485 | 
        
         | 
        
         | 
                        $aMask = array_fill(0, 8, str_repeat('0', 16));
 | 
      
      
        | 486 | 
        
         | 
        
         | 
                    } else {
 | 
      
      
        | 487 | 
        
         | 
        
         | 
                        $aMask = str_split(
  | 
      
      
        | 488 | 
        
         | 
        
         | 
                            str_repeat('1', $this->iNetmaskLengthV6).
 | 
      
      
        | 489 | 
        
         | 
        
         | 
                            str_repeat('0', 128 - $this->iNetmaskLengthV6),
 | 
      
      
        | 490 | 
        
         | 
        
         | 
                            16
  | 
      
      
        | 491 | 
        
         | 
        
         | 
                        );
  | 
      
      
        | 492 | 
        
         | 
        
         | 
                    }
  | 
      
      
        | 493 | 
        
         | 
        
         | 
                    // iterate all IP parts, apply its mask and reformat to IPv6 string notation.
  | 
      
      
        | 494 | 
        
         | 
        
         | 
                    array_walk(
  | 
      
      
        | 495 | 
        
         | 
        
         | 
                        $aIpV6,
  | 
      
      
        | 496 | 
        
         | 
        
         | 
                        function(&$sWord, $iIndex) use ($aMask) {
 | 
      
      
        | 497 | 
        
         | 
        
         | 
                            $sWord = sprintf('%04x', hexdec($sWord) & bindec($aMask[$iIndex]));
 | 
      
      
        | 498 | 
        
         | 
        
         | 
                        }
  | 
      
      
        | 499 | 
        
         | 
        
         | 
                    );
  | 
      
      
        | 500 | 
        
         | 
        
         | 
                    // reformat to IPv6 string notation.
  | 
      
      
        | 501 | 
        
         | 
        
         | 
                    $sIp = implode(':', $aIpV6);
 | 
      
      
        | 502 | 
        
         | 
        
         | 
        // ------------------------------------------------------------------------------------ //
  | 
      
      
        | 503 | 
        
         | 
        
         | 
                }
  | 
      
      
        | 504 | 
        
         | 
        
         | 
                return md5($sIp); // return the hashed IP string
  | 
      
      
        | 505 | 
        
         | 
        
         | 
            }
  | 
      
      
        | 506 | 
        
         | 
        
         | 
        
  | 
      
      
        | 507 | 
        
         | 
        
         | 
        /**
  | 
      
      
        | 508 | 
        
         | 
        
         | 
         * encode a hex string into a 64char based string
  | 
      
      
        | 509 | 
        
         | 
        
         | 
         * @param string $sMd5Hash
  | 
      
      
        | 510 | 
        
         | 
        
         | 
         * @return string
  | 
      
      
        | 511 | 
        
         | 
        
         | 
         * @description reduce the 32char length of a MD5 to 22 chars
  | 
      
      
        | 512 | 
        
         | 
        
         | 
         */
  | 
      
      
        | 513 | 
        
         | 
        
         | 
            private function encodeHash($sMd5Hash)
  | 
      
      
        | 514 | 
        
         | 
        
         | 
            {
 | 
      
      
        | 515 | 
        
         | 
        
         | 
                 return preg_replace('/[^a-zA-Z0-9]/', '_', rtrim(base64_encode(pack('h*',$sMd5Hash)), '='));
 | 
      
      
        | 516 | 
        
         | 
        
         | 
        //        return rtrim(base64_encode(pack('h*',$sMd5Hash)), '+-= ');
 | 
      
      
        | 517 | 
        
         | 
        
         | 
            }
  | 
      
      
        | 518 | 
        
         | 
        
         | 
        
  | 
      
      
        | 519 | 
        
         | 
        
         | 
        // callback method, needed for PHP-5.3.x only
  | 
      
      
        | 520 | 
        
         | 
        
         | 
            private function checkFtanCallback($aToken)
  | 
      
      
        | 521 | 
        
         | 
        
         | 
            {
 | 
      
      
        | 522 | 
        
         | 
        
         | 
                return $this->encodeHash(md5($aToken['value'].$this->sFingerprint));
  | 
      
      
        | 523 | 
        
         | 
        
         | 
            }
  | 
      
      
        | 524 | 
        
         | 
        
         | 
        
  | 
      
      
        | 525 | 
        
         | 
        
         | 
        /**
  | 
      
      
        | 526 | 
        
         | 
        
         | 
         * read settings if available
  | 
      
      
        | 527 | 
        
         | 
        
         | 
         */
  | 
      
      
        | 528 | 
        
         | 
        
         | 
            private function getSettings()
  | 
      
      
        | 529 | 
        
         | 
        
         | 
            {
 | 
      
      
        | 530 | 
        
         | 
        
         | 
                if (!class_exists('WbAdaptor', false)) {
 | 
      
      
        | 531 | 
        
         | 
        
         | 
                // for WB before 2.8.4
  | 
      
      
        | 532 | 
        
         | 
        
         | 
                    $this->bUseFingerprint  = defined('SEC_TOKEN_FINGERPRINT')
 | 
      
      
        | 533 | 
        
         | 
        
         | 
                                              ? SEC_TOKEN_FINGERPRINT
  | 
      
      
        | 534 | 
        
         | 
        
         | 
                                              : $this->bUseFingerprint;
  | 
      
      
        | 535 | 
        
         | 
        
         | 
                    $this->iNetmaskLengthV4 = defined('SEC_TOKEN_NETMASK4')
 | 
      
      
        | 536 | 
        
         | 
        
         | 
                                              ? SEC_TOKEN_NETMASK4
  | 
      
      
        | 537 | 
        
         | 
        
         | 
                                              : $this->iNetmaskLengthV4;
  | 
      
      
        | 538 | 
        
         | 
        
         | 
                    $this->iNetmaskLengthV6 = defined('SEC_TOKEN_NETMASK6')
 | 
      
      
        | 539 | 
        
         | 
        
         | 
                                              ? SEC_TOKEN_NETMASK6
  | 
      
      
        | 540 | 
        
         | 
        
         | 
                                              : $this->iNetmaskLengthV6;
  | 
      
      
        | 541 | 
        
         | 
        
         | 
                    $this->iTokenLifeTime   = defined('SEC_TOKEN_LIFE_TIME')
 | 
      
      
        | 542 | 
        
         | 
        
         | 
                                              ? SEC_TOKEN_LIFE_TIME
  | 
      
      
        | 543 | 
        
         | 
        
         | 
                                              : $this->iTokenLifeTime;
  | 
      
      
        | 544 | 
        
         | 
        
         | 
                } else {
 | 
      
      
        | 545 | 
        
         | 
        
         | 
                // for WB from 2.8.4 and up
  | 
      
      
        | 546 | 
        
         | 
        
         | 
                    $oReg = WbAdaptor::getInstance();
  | 
      
      
        | 547 | 
        
         | 
        
         | 
                    $this->bUseFingerprint  = isset($oReg->SecTokenFingerprint)
  | 
      
      
        | 548 | 
        
         | 
        
         | 
                                              ? $oReg->SecTokenFingerprint
  | 
      
      
        | 549 | 
        
         | 
        
         | 
                                              : $this->bUseFingerprint;
  | 
      
      
        | 550 | 
        
         | 
        
         | 
                    $this->iNetmaskLengthV4 = isset($oReg->SecTokenIpv4Netmask)
  | 
      
      
        | 551 | 
        
         | 
        
         | 
                                              ? $oReg->SecTokenIpv4Netmask
  | 
      
      
        | 552 | 
        
         | 
        
         | 
                                              : $this->iNetmaskLengthV4;
  | 
      
      
        | 553 | 
        
         | 
        
         | 
                    $this->iNetmaskLengthV6 = isset($oReg->SecTokenIpv6PrefixLength)
  | 
      
      
        | 554 | 
        
         | 
        
         | 
                                              ? $oReg->SecTokenIpv6PrefixLength
  | 
      
      
        | 555 | 
        
         | 
        
         | 
                                              : $this->iNetmaskLengthV6;
  | 
      
      
        | 556 | 
        
         | 
        
         | 
                    $this->iTokenLifeTime   = isset($oReg->SecTokenLifeTime)
  | 
      
      
        | 557 | 
        
         | 
        
         | 
                                              ? $oReg->SecTokenLifeTime
  | 
      
      
        | 558 | 
        
         | 
        
         | 
                                              : $this->iTokenLifeTime;
  | 
      
      
        | 559 | 
        
         | 
        
         | 
                }
  | 
      
      
        | 560 | 
        
         | 
        
         | 
                $this->iNetmaskLengthV4 = ($this->iNetmaskLengthV4 < 1 || $this->iNetmaskLengthV4 > 32)
  | 
      
      
        | 561 | 
        
         | 
        
         | 
                                          ? 0 :$this->iNetmaskLengthV4;
  | 
      
      
        | 562 | 
        
         | 
        
         | 
                $this->iNetmaskLengthV6 = ($this->iNetmaskLengthV6 < 1 || $this->iNetmaskLengthV6 > 128)
  | 
      
      
        | 563 | 
        
         | 
        
         | 
                                          ? 0 :$this->iNetmaskLengthV6;
  | 
      
      
        | 564 | 
        
         | 
        
         | 
                $this->iTokenLifeTime   = $this->sanitizeLifeTime($this->iTokenLifeTime);
  | 
      
      
        | 565 | 
        
         | 
        
         | 
                if ($this->iTokenLifeTime <= self::LIFETIME_MIN && DEBUG) {
 | 
      
      
        | 566 | 
        
         | 
        
         | 
                    $this->iTokenLifeTime = self::DEBUG_LIFETIME;
  | 
      
      
        | 567 | 
        
         | 
        
         | 
                }
  | 
      
      
        | 568 | 
        
         | 
        
         | 
            }
  | 
      
      
        | 569 | 
        
         | 
        
         | 
        
  | 
      
      
        | 570 | 
        
         | 
        
         | 
        
  | 
      
      
        | 571 | 
        
         | 
        
         | 
        } // end of class SecureTokens
  |