├── logo.png ├── screenshot.png ├── views ├── img │ ├── logo.png │ ├── cover.jpg │ └── index.php ├── css │ ├── menuTabIcon.css │ ├── disable-contact-form.css │ └── index.php ├── js │ ├── contextmenu.js │ ├── contextmenu-img.js │ ├── index.php │ ├── menu.js │ └── secure-random-password.js └── index.php ├── vendor ├── robthree │ ├── twofactorauth │ │ ├── lib │ │ │ ├── Providers │ │ │ │ ├── Qr │ │ │ │ │ ├── QRException.php │ │ │ │ │ ├── IQRCodeProvider.php │ │ │ │ │ ├── index.php │ │ │ │ │ ├── BaseHTTPQRCodeProvider.php │ │ │ │ │ ├── ImageChartsQRCodeProvider.php │ │ │ │ │ ├── QRicketProvider.php │ │ │ │ │ └── QRServerProvider.php │ │ │ │ ├── Rng │ │ │ │ │ ├── RNGException.php │ │ │ │ │ ├── IRNGProvider.php │ │ │ │ │ ├── CSRNGProvider.php │ │ │ │ │ ├── MCryptRNGProvider.php │ │ │ │ │ ├── index.php │ │ │ │ │ ├── OpenSSLRNGProvider.php │ │ │ │ │ └── HashRNGProvider.php │ │ │ │ ├── Time │ │ │ │ │ ├── TimeException.php │ │ │ │ │ ├── ITimeProvider.php │ │ │ │ │ ├── LocalMachineTimeProvider.php │ │ │ │ │ ├── index.php │ │ │ │ │ ├── NTPTimeProvider.php │ │ │ │ │ └── HttpTimeProvider.php │ │ │ │ └── index.php │ │ │ ├── TwoFactorAuthException.php │ │ │ ├── index.php │ │ │ └── TwoFactorAuth.php │ │ ├── index.php │ │ └── LICENSE │ └── index.php ├── autoload.php ├── composer │ ├── autoload_namespaces.php │ ├── autoload_psr4.php │ ├── index.php │ ├── LICENSE │ ├── autoload_real.php │ ├── autoload_classmap.php │ ├── autoload_static.php │ ├── installed.json │ └── ClassLoader.php ├── index.php ├── dg │ ├── index.php │ └── composer-cleaner │ │ ├── index.php │ │ └── src │ │ ├── index.php │ │ └── ComposerCleaner │ │ ├── index.php │ │ ├── Plugin.php │ │ └── Cleaner.php └── mlocati │ ├── index.php │ └── ip-lib │ ├── index.php │ ├── src │ ├── index.php │ ├── Address │ │ ├── index.php │ │ ├── Type.php │ │ ├── AddressInterface.php │ │ ├── AssignedRange.php │ │ ├── IPv4.php │ │ └── IPv6.php │ ├── Range │ │ ├── index.php │ │ ├── AbstractRange.php │ │ ├── RangeInterface.php │ │ ├── Type.php │ │ ├── Single.php │ │ ├── Pattern.php │ │ └── Subnet.php │ └── Factory.php │ └── LICENSE.txt ├── index.php ├── upgrade ├── index.php └── upgrade-5.0.0.php ├── controllers ├── index.php ├── admin │ ├── index.php │ └── AdminSecurityLiteController.php └── front │ ├── index.php │ ├── unlock.php │ └── cron.php ├── translations └── index.php ├── LICENSE └── README.md /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathiasReker/Security-Lite/HEAD/logo.png -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathiasReker/Security-Lite/HEAD/screenshot.png -------------------------------------------------------------------------------- /views/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathiasReker/Security-Lite/HEAD/views/img/logo.png -------------------------------------------------------------------------------- /views/img/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathiasReker/Security-Lite/HEAD/views/img/cover.jpg -------------------------------------------------------------------------------- /vendor/robthree/twofactorauth/lib/Providers/Qr/QRException.php: -------------------------------------------------------------------------------- 1 | array($vendorDir . '/robthree/twofactorauth/lib'), 10 | 'IPLib\\' => array($vendorDir . '/mlocati/ip-lib/src'), 11 | ); 12 | -------------------------------------------------------------------------------- /vendor/robthree/twofactorauth/lib/Providers/Rng/CSRNGProvider.php: -------------------------------------------------------------------------------- 1 | registerHook( 25 | [ 26 | 'displayMaintenance', 27 | ] 28 | ); 29 | 30 | return true; 31 | } 32 | -------------------------------------------------------------------------------- /vendor/dg/composer-cleaner/index.php: -------------------------------------------------------------------------------- 1 | source = $source; 11 | } 12 | 13 | public function getRandomBytes($bytecount) { 14 | $result = @mcrypt_create_iv($bytecount, $this->source); 15 | if ($result === false) 16 | throw new \RNGException('mcrypt_create_iv returned an invalid value'); 17 | return $result; 18 | } 19 | 20 | public function isCryptographicallySecure() { 21 | return true; 22 | } 23 | } -------------------------------------------------------------------------------- /vendor/robthree/twofactorauth/lib/index.php: -------------------------------------------------------------------------------- 1 | link->getAdminLink('AdminModules', true) . '&configure=securitylite&tab_reset=1'); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /vendor/mlocati/ip-lib/src/Address/Type.php: -------------------------------------------------------------------------------- 1 | $url, 15 | CURLOPT_RETURNTRANSFER => true, 16 | CURLOPT_CONNECTTIMEOUT => 10, 17 | CURLOPT_DNS_CACHE_TIMEOUT => 10, 18 | CURLOPT_TIMEOUT => 10, 19 | CURLOPT_SSL_VERIFYPEER => $this->verifyssl, 20 | CURLOPT_USERAGENT => 'TwoFactorAuth' 21 | )); 22 | $data = curl_exec($curlhandle); 23 | 24 | curl_close($curlhandle); 25 | return $data; 26 | } 27 | } -------------------------------------------------------------------------------- /vendor/robthree/twofactorauth/lib/Providers/Rng/OpenSSLRNGProvider.php: -------------------------------------------------------------------------------- 1 | requirestrong = $requirestrong; 11 | } 12 | 13 | public function getRandomBytes($bytecount) { 14 | $result = openssl_random_pseudo_bytes($bytecount, $crypto_strong); 15 | if ($this->requirestrong && ($crypto_strong === false)) 16 | throw new \RNGException('openssl_random_pseudo_bytes returned non-cryptographically strong value'); 17 | if ($result === false) 18 | throw new \RNGException('openssl_random_pseudo_bytes returned an invalid value'); 19 | return $result; 20 | } 21 | 22 | public function isCryptographicallySecure() { 23 | return $this->requirestrong; 24 | } 25 | } -------------------------------------------------------------------------------- /vendor/robthree/twofactorauth/lib/Providers/Rng/HashRNGProvider.php: -------------------------------------------------------------------------------- 1 | algorithm = $algorithm; 13 | } 14 | 15 | public function getRandomBytes($bytecount) { 16 | $result = ''; 17 | $hash = mt_rand(); 18 | for ($i = 0; $i < $bytecount; $i++) { 19 | $hash = hash($this->algorithm, $hash.mt_rand(), true); 20 | $result .= $hash[mt_rand(0, strlen($hash)-1)]; 21 | } 22 | return $result; 23 | } 24 | 25 | public function isCryptographicallySecure() { 26 | return false; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /vendor/composer/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Copyright (c) Nils Adermann, Jordi Boggiano 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is furnished 9 | to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | 22 | -------------------------------------------------------------------------------- /vendor/mlocati/ip-lib/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2016 Michele Locati 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is furnished 9 | to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. -------------------------------------------------------------------------------- /vendor/robthree/twofactorauth/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014-2015 Rob Janssen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /vendor/robthree/twofactorauth/lib/Providers/Qr/ImageChartsQRCodeProvider.php: -------------------------------------------------------------------------------- 1 | verifyssl = $verifyssl; 17 | 18 | $this->errorcorrectionlevel = $errorcorrectionlevel; 19 | $this->margin = $margin; 20 | } 21 | 22 | public function getMimeType() 23 | { 24 | return 'image/png'; 25 | } 26 | 27 | public function getQRCodeImage($qrtext, $size) 28 | { 29 | return $this->getContent($this->getUrl($qrtext, $size)); 30 | } 31 | 32 | public function getUrl($qrtext, $size) 33 | { 34 | return 'https://image-charts.com/chart?cht=qr' 35 | . '&chs=' . ceil($size/2) . 'x' . ceil($size/2) 36 | . '&chld=' . $this->errorcorrectionlevel . '|' . $this->margin 37 | . '&chl=' . rawurlencode($qrtext); 38 | } 39 | } -------------------------------------------------------------------------------- /vendor/dg/composer-cleaner/src/ComposerCleaner/Plugin.php: -------------------------------------------------------------------------------- 1 | 'clean', 26 | ScriptEvents::POST_INSTALL_CMD => 'clean', 27 | ]; 28 | } 29 | 30 | 31 | public function clean(Event $event) 32 | { 33 | $vendorDir = $event->getComposer()->getConfig()->get('vendor-dir'); 34 | $extra = $event->getComposer()->getPackage()->getExtra(); 35 | $ignorePaths = isset($extra['cleaner-ignore']) ? $extra['cleaner-ignore'] : (array) $event->getComposer()->getConfig()->get('cleaner-ignore'); 36 | $fileSystem = new Filesystem(new ProcessExecutor($event->getIO())); 37 | $cleaner = new Cleaner($event->getIO(), $fileSystem); 38 | $cleaner->clean($vendorDir, $ignorePaths); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /vendor/composer/autoload_real.php: -------------------------------------------------------------------------------- 1 | = 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); 30 | if ($useStaticLoader) { 31 | require_once __DIR__ . '/autoload_static.php'; 32 | 33 | call_user_func(\Composer\Autoload\ComposerStaticInit6e410ad27b65f7365030aa1ea83fae7f::getInitializer($loader)); 34 | } else { 35 | $classMap = require __DIR__ . '/autoload_classmap.php'; 36 | if ($classMap) { 37 | $loader->addClassMap($classMap); 38 | } 39 | } 40 | 41 | $loader->setClassMapAuthoritative(true); 42 | $loader->register(false); 43 | 44 | return $loader; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /vendor/robthree/twofactorauth/lib/Providers/Qr/QRicketProvider.php: -------------------------------------------------------------------------------- 1 | verifyssl = false; 18 | 19 | $this->errorcorrectionlevel = $errorcorrectionlevel; 20 | $this->bgcolor = $bgcolor; 21 | $this->color = $color; 22 | $this->format = $format; 23 | } 24 | 25 | public function getMimeType() 26 | { 27 | switch (strtolower($this->format)) 28 | { 29 | case 'p': 30 | return 'image/png'; 31 | case 'g': 32 | return 'image/gif'; 33 | case 'j': 34 | return 'image/jpeg'; 35 | } 36 | throw new \QRException(sprintf('Unknown MIME-type: %s', $this->format)); 37 | } 38 | 39 | public function getQRCodeImage($qrtext, $size) 40 | { 41 | return $this->getContent($this->getUrl($qrtext, $size)); 42 | } 43 | 44 | public function getUrl($qrtext, $size) 45 | { 46 | return 'http://qrickit.com/api/qr' 47 | . '?qrsize=' . $size 48 | . '&e=' . strtolower($this->errorcorrectionlevel) 49 | . '&bgdcolor=' . $this->bgcolor 50 | . '&fgdcolor=' . $this->color 51 | . '&t=' . strtolower($this->format) 52 | . '&d=' . rawurlencode($qrtext); 53 | } 54 | } -------------------------------------------------------------------------------- /vendor/robthree/twofactorauth/lib/Providers/Time/NTPTimeProvider.php: -------------------------------------------------------------------------------- 1 | host = $host; 17 | 18 | if (!is_int($port) || $port <= 0 || $port > 65535) 19 | throw new \TimeException('Port must be 0 < port < 65535'); 20 | $this->port = $port; 21 | 22 | if (!is_int($timeout) || $timeout < 0) 23 | throw new \TimeException('Timeout must be >= 0'); 24 | $this->timeout = $timeout; 25 | } 26 | 27 | public function getTime() { 28 | try { 29 | /* Create a socket and connect to NTP server */ 30 | $sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); 31 | socket_set_option($sock, SOL_SOCKET, SO_RCVTIMEO, ['sec' => $this->timeout, 'usec' => 0]); 32 | socket_connect($sock, $this->host, $this->port); 33 | 34 | /* Send request */ 35 | $msg = "\010" . str_repeat("\0", 47); 36 | socket_send($sock, $msg, strlen($msg), 0); 37 | 38 | /* Receive response and close socket */ 39 | if (socket_recv($sock, $recv, 48, MSG_WAITALL) === false) 40 | throw new \Exception(socket_strerror(socket_last_error($sock))); 41 | socket_close($sock); 42 | 43 | /* Interpret response */ 44 | $data = unpack('N12', $recv); 45 | $timestamp = sprintf('%u', $data[9]); 46 | 47 | /* NTP is number of seconds since 0000 UT on 1 January 1900 Unix time is seconds since 0000 UT on 1 January 1970 */ 48 | return $timestamp - 2208988800; 49 | } 50 | catch (Exception $ex) { 51 | throw new \TimeException(sprintf('Unable to retrieve time from %s (%s)', $this->host, $ex->getMessage())); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /vendor/robthree/twofactorauth/lib/Providers/Time/HttpTimeProvider.php: -------------------------------------------------------------------------------- 1 | url = $url; 17 | $this->expectedtimeformat = $expectedtimeformat; 18 | $this->options = $options; 19 | if ($this->options === null) { 20 | $this->options = array( 21 | 'http' => array( 22 | 'method' => 'HEAD', 23 | 'follow_location' => false, 24 | 'ignore_errors' => true, 25 | 'max_redirects' => 0, 26 | 'request_fulluri' => true, 27 | 'header' => array( 28 | 'Connection: close', 29 | 'User-agent: TwoFactorAuth HttpTimeProvider (https://github.com/RobThree/TwoFactorAuth)', 30 | 'Cache-Control: no-cache' 31 | ) 32 | ) 33 | ); 34 | } 35 | } 36 | 37 | public function getTime() { 38 | try { 39 | $context = stream_context_create($this->options); 40 | $fd = fopen($this->url, 'rb', false, $context); 41 | $headers = stream_get_meta_data($fd); 42 | fclose($fd); 43 | 44 | foreach ($headers['wrapper_data'] as $h) { 45 | if (strcasecmp(substr($h, 0, 5), 'Date:') === 0) 46 | return \DateTime::createFromFormat($this->expectedtimeformat, trim(substr($h,5)))->getTimestamp(); 47 | } 48 | throw new \TimeException(sprintf('Unable to retrieve time from %s (Invalid or no "Date:" header found)', $this->url)); 49 | } 50 | catch (Exception $ex) { 51 | throw new \TimeException(sprintf('Unable to retrieve time from %s (%s)', $this->url, $ex->getMessage())); 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /controllers/front/unlock.php: -------------------------------------------------------------------------------- 1 | ajax = 1; 36 | 37 | // Check token 38 | if (!Tools::isPHPCLI()) { 39 | if ($this->module->encrypt('securitylite/unlock') !== Tools::getValue('token') || !Module::isInstalled('securitylite')) { 40 | $response = $this->module->l('Forbidden call.', 'unlock'); 41 | $this->ajaxDie($response); 42 | } 43 | } 44 | 45 | // Try to run cronjob 46 | try { 47 | $response = $this->runCronjob(); 48 | } catch (Exception $e) { 49 | if (true === (bool) Configuration::get('PRO_DEBUG_CRON')) { 50 | $response = $e; 51 | } else { 52 | $response = $this->module->l('Something went wrong.', 'unlock'); 53 | } 54 | } finally { 55 | $this->ajaxDie($response); 56 | } 57 | } 58 | 59 | /** 60 | * Run cronjob 61 | * 62 | * @return string 63 | */ 64 | private function runCronjob() 65 | { 66 | // Check if module is activated 67 | if (true === (bool) $this->module->active) { 68 | $this->module->cron = 1; 69 | } else { 70 | return $this->module->l('securitylite is not active.', 'unlock'); 71 | } 72 | 73 | return $this->module->l('Success!', 'unlock'); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /vendor/robthree/twofactorauth/lib/Providers/Qr/QRServerProvider.php: -------------------------------------------------------------------------------- 1 | verifyssl = $verifyssl; 21 | 22 | $this->errorcorrectionlevel = $errorcorrectionlevel; 23 | $this->margin = $margin; 24 | $this->qzone = $qzone; 25 | $this->bgcolor = $bgcolor; 26 | $this->color = $color; 27 | $this->format = $format; 28 | } 29 | 30 | public function getMimeType() 31 | { 32 | switch (strtolower($this->format)) 33 | { 34 | case 'png': 35 | return 'image/png'; 36 | case 'gif': 37 | return 'image/gif'; 38 | case 'jpg': 39 | case 'jpeg': 40 | return 'image/jpeg'; 41 | case 'svg': 42 | return 'image/svg+xml'; 43 | case 'eps': 44 | return 'application/postscript'; 45 | } 46 | throw new \QRException(sprintf('Unknown MIME-type: %s', $this->format)); 47 | } 48 | 49 | public function getQRCodeImage($qrtext, $size) 50 | { 51 | return $this->getContent($this->getUrl($qrtext, $size)); 52 | } 53 | 54 | private function decodeColor($value) 55 | { 56 | return vsprintf('%d-%d-%d', sscanf($value, "%02x%02x%02x")); 57 | } 58 | 59 | public function getUrl($qrtext, $size) 60 | { 61 | return 'https://api.qrserver.com/v1/create-qr-code/' 62 | . '?size=' . $size . 'x' . $size 63 | . '&ecc=' . strtoupper($this->errorcorrectionlevel) 64 | . '&margin=' . $this->margin 65 | . '&qzone=' . $this->qzone 66 | . '&bgcolor=' . $this->decodeColor($this->bgcolor) 67 | . '&color=' . $this->decodeColor($this->color) 68 | . '&format=' . strtolower($this->format) 69 | . '&data=' . rawurlencode($qrtext); 70 | } 71 | } -------------------------------------------------------------------------------- /views/js/menu.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the securitylite package. 3 | * 4 | * @author Mathias Reker 5 | * @copyright Mathias Reker 6 | * @license Commercial Software License 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | !function(t){"use strict";var a=function(a){this.element=t(a)};a.prototype={constructor:a,show:function(){var a,e,n,i=this.element,s=i.closest("ul:not(.dropdown-menu)"),o=i.attr("data-target");o||(o=(o=i.attr("href"))&&o.replace(/.*(?=#[^\s]*$)/,"")),i.parent("li").hasClass("active")||(a=s.find(".active:last a")[0],n=t.Event("show",{relatedTarget:a}),i.trigger(n),n.isDefaultPrevented()||(e=t(o),this.activate(i.parent("li"),s),this.activate(e,e.parent(),function(){i.trigger({type:"shown",relatedTarget:a})})))},activate:function(a,e,n){var i=e.find("> .active"),s=n&&t.support.transition&&i.hasClass("fade");function o(){i.removeClass("active").find("> .dropdown-menu > .active").removeClass("active"),a.addClass("active"),s?(a[0].offsetWidth,a.addClass("in")):a.removeClass("fade"),a.parent(".dropdown-menu")&&a.closest("li.dropdown").addClass("active"),n&&n()}s?i.one(t.support.transition.end,o):o(),i.removeClass("in"),scroll(0,0)}};var e=t.fn.tab;t.fn.tab=function(e){return this.each(function(){var n=t(this),i=n.data("tab");i||n.data("tab",i=new a(this)),"string"==typeof e&&i[e]()})},t.fn.tab.Constructor=a,t.fn.tab.noConflict=function(){return t.fn.tab=e,this},t(document).on("click.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(a){a.preventDefault(),t(this).tab("show")})}(window.jQuery),function(t){t.createTabs=function(){t("#content").find('form [id^="fieldset"]').length&&(blockTab='
',t.each(t("#content").find('form [id^="fieldset"]'),function(){heading=t(this).find(".panel-heading, legend"),blockTab+=''+heading.html()+"",t(this).addClass("tab-pane")}),blockTab+="
",t("#content").find("form").wrap("
").before(blockTab).addClass("col-lg-10 tab-content"),t("#content").find("form > br").remove(),t("#content").find("#module-tabs a:first").tab("show").addClass("active"),t("#content").find(".list-group-item").on("click",function(){var a=t(this).parent().closest(".list-group").children(".active");a.hasClass("active")&&a.removeClass("active"),t(this).addClass("active")}))}}(jQuery),$(document).ready(function(){$.createTabs(),$('a[data-toggle="tab"]').on("shown",function(t){localStorage.setItem("lastTab",$(t.target).attr("id"))});var t=localStorage.getItem("lastTab");t&&($("#"+t).tab("show"),$("#fieldset_0_securitylite").removeClass("active"),$("#"+t).addClass("active"))}); 13 | -------------------------------------------------------------------------------- /controllers/front/cron.php: -------------------------------------------------------------------------------- 1 | ajax = 1; 38 | 39 | // Check token 40 | if (!Tools::isPHPCLI()) { 41 | if ($this->module->encrypt('securitylite/cron') !== Tools::getValue('token') || !Module::isInstalled('securitylite')) { 42 | $response = $this->module->l('Forbidden call.', 'cron'); 43 | $this->getResponse($response); 44 | } 45 | } 46 | 47 | // Try to run cronjob 48 | try { 49 | $response = $this->runCronjob(); 50 | } catch (Exception $e) { 51 | if (true === (bool) Configuration::get('PRO_DEBUG_CRON')) { 52 | $response = $e; 53 | } else { 54 | $response = $this->module->l('Something went wrong.', 'cron'); 55 | } 56 | } finally { 57 | $this->getResponse($response); 58 | } 59 | } 60 | 61 | /** 62 | * Write to log and display response 63 | * 64 | * @param string $response 65 | */ 66 | private function getResponse($response) 67 | { 68 | $name = Tools::getValue('name'); 69 | 70 | $this->module->logCron($name, $response); 71 | 72 | $this->ajaxDie($response); 73 | } 74 | 75 | /** 76 | * Run cronjob 77 | * 78 | * @return string 79 | */ 80 | private function runCronjob() 81 | { 82 | // Check if module is activated 83 | if (true === (bool) $this->module->active) { 84 | $this->module->cron = 1; 85 | 86 | // Run the cronjob 87 | $name = Tools::getValue('name'); 88 | switch ($name) { 89 | case 'DeleteOldCarts': 90 | $this->module->deleteOldCarts(); 91 | break; 92 | case 'BackupDatabase': 93 | $this->module->backupDatabase(); 94 | break; 95 | default: 96 | return $this->module->l('Cronjob does not exist.', 'cron'); 97 | } 98 | } else { 99 | return $this->module->l('securitylite is not active.', 'cron'); 100 | } 101 | 102 | return $this->module->l('Success!', 'cron'); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /vendor/mlocati/ip-lib/src/Address/AddressInterface.php: -------------------------------------------------------------------------------- 1 | rangeType === null) { 21 | $addressType = $this->getAddressType(); 22 | if ($addressType === AddressType::T_IPv6 && Subnet::get6to4()->containsRange($this)) { 23 | $this->rangeType = Factory::rangeFromBoundaries($this->fromAddress->toIPv4(), $this->toAddress->toIPv4())->getRangeType(); 24 | } else { 25 | switch ($addressType) { 26 | case AddressType::T_IPv4: 27 | $defaultType = IPv4::getDefaultReservedRangeType(); 28 | $reservedRanges = IPv4::getReservedRanges(); 29 | break; 30 | case AddressType::T_IPv6: 31 | $defaultType = IPv6::getDefaultReservedRangeType(); 32 | $reservedRanges = IPv6::getReservedRanges(); 33 | break; 34 | default: 35 | throw new \Exception('@todo'); // @codeCoverageIgnore 36 | } 37 | $rangeType = null; 38 | foreach ($reservedRanges as $reservedRange) { 39 | $rangeType = $reservedRange->getRangeType($this); 40 | if ($rangeType !== null) { 41 | break; 42 | } 43 | } 44 | $this->rangeType = $rangeType === null ? $defaultType : $rangeType; 45 | } 46 | } 47 | 48 | return $this->rangeType === false ? null : $this->rangeType; 49 | } 50 | 51 | /** 52 | * {@inheritdoc} 53 | * 54 | * @see \IPLib\Range\RangeInterface::contains() 55 | */ 56 | public function contains(AddressInterface $address) 57 | { 58 | $result = false; 59 | if ($address->getAddressType() === $this->getAddressType()) { 60 | $cmp = $address->getComparableString(); 61 | $from = $this->getComparableStartString(); 62 | if ($cmp >= $from) { 63 | $to = $this->getComparableEndString(); 64 | if ($cmp <= $to) { 65 | $result = true; 66 | } 67 | } 68 | } 69 | 70 | return $result; 71 | } 72 | 73 | /** 74 | * {@inheritdoc} 75 | * 76 | * @see \IPLib\Range\RangeInterface::containsRange() 77 | */ 78 | public function containsRange(RangeInterface $range) 79 | { 80 | $result = false; 81 | if ($range->getAddressType() === $this->getAddressType()) { 82 | $myStart = $this->getComparableStartString(); 83 | $itsStart = $range->getComparableStartString(); 84 | if ($itsStart >= $myStart) { 85 | $myEnd = $this->getComparableEndString(); 86 | $itsEnd = $range->getComparableEndString(); 87 | if ($itsEnd <= $myEnd) { 88 | $result = true; 89 | } 90 | } 91 | } 92 | 93 | return $result; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /vendor/composer/autoload_classmap.php: -------------------------------------------------------------------------------- 1 | $vendorDir . '/dg/composer-cleaner/src/ComposerCleaner/Cleaner.php', 10 | 'DG\\ComposerCleaner\\Plugin' => $vendorDir . '/dg/composer-cleaner/src/ComposerCleaner/Plugin.php', 11 | 'IPLib\\Address\\AddressInterface' => $vendorDir . '/mlocati/ip-lib/src/Address/AddressInterface.php', 12 | 'IPLib\\Address\\AssignedRange' => $vendorDir . '/mlocati/ip-lib/src/Address/AssignedRange.php', 13 | 'IPLib\\Address\\IPv4' => $vendorDir . '/mlocati/ip-lib/src/Address/IPv4.php', 14 | 'IPLib\\Address\\IPv6' => $vendorDir . '/mlocati/ip-lib/src/Address/IPv6.php', 15 | 'IPLib\\Address\\Type' => $vendorDir . '/mlocati/ip-lib/src/Address/Type.php', 16 | 'IPLib\\Factory' => $vendorDir . '/mlocati/ip-lib/src/Factory.php', 17 | 'IPLib\\Range\\AbstractRange' => $vendorDir . '/mlocati/ip-lib/src/Range/AbstractRange.php', 18 | 'IPLib\\Range\\Pattern' => $vendorDir . '/mlocati/ip-lib/src/Range/Pattern.php', 19 | 'IPLib\\Range\\RangeInterface' => $vendorDir . '/mlocati/ip-lib/src/Range/RangeInterface.php', 20 | 'IPLib\\Range\\Single' => $vendorDir . '/mlocati/ip-lib/src/Range/Single.php', 21 | 'IPLib\\Range\\Subnet' => $vendorDir . '/mlocati/ip-lib/src/Range/Subnet.php', 22 | 'IPLib\\Range\\Type' => $vendorDir . '/mlocati/ip-lib/src/Range/Type.php', 23 | 'RobThree\\Auth\\Providers\\Qr\\BaseHTTPQRCodeProvider' => $vendorDir . '/robthree/twofactorauth/lib/Providers/Qr/BaseHTTPQRCodeProvider.php', 24 | 'RobThree\\Auth\\Providers\\Qr\\IQRCodeProvider' => $vendorDir . '/robthree/twofactorauth/lib/Providers/Qr/IQRCodeProvider.php', 25 | 'RobThree\\Auth\\Providers\\Qr\\ImageChartsQRCodeProvider' => $vendorDir . '/robthree/twofactorauth/lib/Providers/Qr/ImageChartsQRCodeProvider.php', 26 | 'RobThree\\Auth\\Providers\\Qr\\QRServerProvider' => $vendorDir . '/robthree/twofactorauth/lib/Providers/Qr/QRServerProvider.php', 27 | 'RobThree\\Auth\\Providers\\Qr\\QRicketProvider' => $vendorDir . '/robthree/twofactorauth/lib/Providers/Qr/QRicketProvider.php', 28 | 'RobThree\\Auth\\Providers\\Rng\\CSRNGProvider' => $vendorDir . '/robthree/twofactorauth/lib/Providers/Rng/CSRNGProvider.php', 29 | 'RobThree\\Auth\\Providers\\Rng\\HashRNGProvider' => $vendorDir . '/robthree/twofactorauth/lib/Providers/Rng/HashRNGProvider.php', 30 | 'RobThree\\Auth\\Providers\\Rng\\IRNGProvider' => $vendorDir . '/robthree/twofactorauth/lib/Providers/Rng/IRNGProvider.php', 31 | 'RobThree\\Auth\\Providers\\Rng\\MCryptRNGProvider' => $vendorDir . '/robthree/twofactorauth/lib/Providers/Rng/MCryptRNGProvider.php', 32 | 'RobThree\\Auth\\Providers\\Rng\\OpenSSLRNGProvider' => $vendorDir . '/robthree/twofactorauth/lib/Providers/Rng/OpenSSLRNGProvider.php', 33 | 'RobThree\\Auth\\Providers\\Time\\HttpTimeProvider' => $vendorDir . '/robthree/twofactorauth/lib/Providers/Time/HttpTimeProvider.php', 34 | 'RobThree\\Auth\\Providers\\Time\\ITimeProvider' => $vendorDir . '/robthree/twofactorauth/lib/Providers/Time/ITimeProvider.php', 35 | 'RobThree\\Auth\\Providers\\Time\\LocalMachineTimeProvider' => $vendorDir . '/robthree/twofactorauth/lib/Providers/Time/LocalMachineTimeProvider.php', 36 | 'RobThree\\Auth\\Providers\\Time\\NTPTimeProvider' => $vendorDir . '/robthree/twofactorauth/lib/Providers/Time/NTPTimeProvider.php', 37 | 'RobThree\\Auth\\TwoFactorAuth' => $vendorDir . '/robthree/twofactorauth/lib/TwoFactorAuth.php', 38 | 'RobThree\\Auth\\TwoFactorAuthException' => $vendorDir . '/robthree/twofactorauth/lib/TwoFactorAuthException.php', 39 | ); 40 | -------------------------------------------------------------------------------- /vendor/mlocati/ip-lib/src/Range/RangeInterface.php: -------------------------------------------------------------------------------- 1 | range = $range; 43 | $this->type = $type; 44 | $this->exceptions = $exceptions; 45 | } 46 | 47 | /** 48 | * Get the range definition. 49 | * 50 | * @return \IPLib\Range\RangeInterface 51 | */ 52 | public function getRange() 53 | { 54 | return $this->range; 55 | } 56 | 57 | /** 58 | * Get the range type. 59 | * 60 | * @return int one of the \IPLib\Range\Type::T_ constants 61 | */ 62 | public function getType() 63 | { 64 | return $this->type; 65 | } 66 | 67 | /** 68 | * Get the list of exceptions for this range type. 69 | * 70 | * @return \IPLib\Address\AssignedRange[] 71 | */ 72 | public function getExceptions() 73 | { 74 | return $this->exceptions; 75 | } 76 | 77 | /** 78 | * Get the assigned type for a specific address. 79 | * 80 | * @param \IPLib\Address\AddressInterface $address 81 | * 82 | * @return int|null return NULL of the address is outside this address; a \IPLib\Range\Type::T_ constant otherwise 83 | */ 84 | public function getAddressType(AddressInterface $address) 85 | { 86 | $result = null; 87 | if ($this->range->contains($address)) { 88 | foreach ($this->exceptions as $exception) { 89 | $result = $exception->getAddressType($address); 90 | if ($result !== null) { 91 | break; 92 | } 93 | } 94 | if ($result === null) { 95 | $result = $this->type; 96 | } 97 | } 98 | 99 | return $result; 100 | } 101 | 102 | /** 103 | * Get the assigned type for a specific address range. 104 | * 105 | * @param \IPLib\Range\RangeInterface $range 106 | * 107 | * @return int|false|null return NULL of the range is fully outside this range; false if it's partly crosses this range (or it contains mixed types); a \IPLib\Range\Type::T_ constant otherwise 108 | */ 109 | public function getRangeType(RangeInterface $range) 110 | { 111 | $myStart = $this->range->getComparableStartString(); 112 | $rangeEnd = $range->getComparableEndString(); 113 | if ($myStart > $rangeEnd) { 114 | $result = null; 115 | } else { 116 | $myEnd = $this->range->getComparableEndString(); 117 | $rangeStart = $range->getComparableStartString(); 118 | if ($myEnd < $rangeStart) { 119 | $result = null; 120 | } elseif ($rangeStart < $myStart || $rangeEnd > $myEnd) { 121 | $result = false; 122 | } else { 123 | $result = null; 124 | foreach ($this->exceptions as $exception) { 125 | $result = $exception->getRangeType($range); 126 | if ($result !== null) { 127 | break; 128 | } 129 | } 130 | if ($result === null) { 131 | $result = $this->getType(); 132 | } 133 | } 134 | } 135 | 136 | return $result; 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /vendor/composer/autoload_static.php: -------------------------------------------------------------------------------- 1 | 11 | array ( 12 | 'RobThree\\Auth\\' => 14, 13 | ), 14 | 'I' => 15 | array ( 16 | 'IPLib\\' => 6, 17 | ), 18 | ); 19 | 20 | public static $prefixDirsPsr4 = array ( 21 | 'RobThree\\Auth\\' => 22 | array ( 23 | 0 => __DIR__ . '/..' . '/robthree/twofactorauth/lib', 24 | ), 25 | 'IPLib\\' => 26 | array ( 27 | 0 => __DIR__ . '/..' . '/mlocati/ip-lib/src', 28 | ), 29 | ); 30 | 31 | public static $classMap = array ( 32 | 'DG\\ComposerCleaner\\Cleaner' => __DIR__ . '/..' . '/dg/composer-cleaner/src/ComposerCleaner/Cleaner.php', 33 | 'DG\\ComposerCleaner\\Plugin' => __DIR__ . '/..' . '/dg/composer-cleaner/src/ComposerCleaner/Plugin.php', 34 | 'IPLib\\Address\\AddressInterface' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Address/AddressInterface.php', 35 | 'IPLib\\Address\\AssignedRange' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Address/AssignedRange.php', 36 | 'IPLib\\Address\\IPv4' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Address/IPv4.php', 37 | 'IPLib\\Address\\IPv6' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Address/IPv6.php', 38 | 'IPLib\\Address\\Type' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Address/Type.php', 39 | 'IPLib\\Factory' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Factory.php', 40 | 'IPLib\\Range\\AbstractRange' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Range/AbstractRange.php', 41 | 'IPLib\\Range\\Pattern' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Range/Pattern.php', 42 | 'IPLib\\Range\\RangeInterface' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Range/RangeInterface.php', 43 | 'IPLib\\Range\\Single' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Range/Single.php', 44 | 'IPLib\\Range\\Subnet' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Range/Subnet.php', 45 | 'IPLib\\Range\\Type' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Range/Type.php', 46 | 'RobThree\\Auth\\Providers\\Qr\\BaseHTTPQRCodeProvider' => __DIR__ . '/..' . '/robthree/twofactorauth/lib/Providers/Qr/BaseHTTPQRCodeProvider.php', 47 | 'RobThree\\Auth\\Providers\\Qr\\IQRCodeProvider' => __DIR__ . '/..' . '/robthree/twofactorauth/lib/Providers/Qr/IQRCodeProvider.php', 48 | 'RobThree\\Auth\\Providers\\Qr\\ImageChartsQRCodeProvider' => __DIR__ . '/..' . '/robthree/twofactorauth/lib/Providers/Qr/ImageChartsQRCodeProvider.php', 49 | 'RobThree\\Auth\\Providers\\Qr\\QRServerProvider' => __DIR__ . '/..' . '/robthree/twofactorauth/lib/Providers/Qr/QRServerProvider.php', 50 | 'RobThree\\Auth\\Providers\\Qr\\QRicketProvider' => __DIR__ . '/..' . '/robthree/twofactorauth/lib/Providers/Qr/QRicketProvider.php', 51 | 'RobThree\\Auth\\Providers\\Rng\\CSRNGProvider' => __DIR__ . '/..' . '/robthree/twofactorauth/lib/Providers/Rng/CSRNGProvider.php', 52 | 'RobThree\\Auth\\Providers\\Rng\\HashRNGProvider' => __DIR__ . '/..' . '/robthree/twofactorauth/lib/Providers/Rng/HashRNGProvider.php', 53 | 'RobThree\\Auth\\Providers\\Rng\\IRNGProvider' => __DIR__ . '/..' . '/robthree/twofactorauth/lib/Providers/Rng/IRNGProvider.php', 54 | 'RobThree\\Auth\\Providers\\Rng\\MCryptRNGProvider' => __DIR__ . '/..' . '/robthree/twofactorauth/lib/Providers/Rng/MCryptRNGProvider.php', 55 | 'RobThree\\Auth\\Providers\\Rng\\OpenSSLRNGProvider' => __DIR__ . '/..' . '/robthree/twofactorauth/lib/Providers/Rng/OpenSSLRNGProvider.php', 56 | 'RobThree\\Auth\\Providers\\Time\\HttpTimeProvider' => __DIR__ . '/..' . '/robthree/twofactorauth/lib/Providers/Time/HttpTimeProvider.php', 57 | 'RobThree\\Auth\\Providers\\Time\\ITimeProvider' => __DIR__ . '/..' . '/robthree/twofactorauth/lib/Providers/Time/ITimeProvider.php', 58 | 'RobThree\\Auth\\Providers\\Time\\LocalMachineTimeProvider' => __DIR__ . '/..' . '/robthree/twofactorauth/lib/Providers/Time/LocalMachineTimeProvider.php', 59 | 'RobThree\\Auth\\Providers\\Time\\NTPTimeProvider' => __DIR__ . '/..' . '/robthree/twofactorauth/lib/Providers/Time/NTPTimeProvider.php', 60 | 'RobThree\\Auth\\TwoFactorAuth' => __DIR__ . '/..' . '/robthree/twofactorauth/lib/TwoFactorAuth.php', 61 | 'RobThree\\Auth\\TwoFactorAuthException' => __DIR__ . '/..' . '/robthree/twofactorauth/lib/TwoFactorAuthException.php', 62 | ); 63 | 64 | public static function getInitializer(ClassLoader $loader) 65 | { 66 | return \Closure::bind(function () use ($loader) { 67 | $loader->prefixLengthsPsr4 = ComposerStaticInit6e410ad27b65f7365030aa1ea83fae7f::$prefixLengthsPsr4; 68 | $loader->prefixDirsPsr4 = ComposerStaticInit6e410ad27b65f7365030aa1ea83fae7f::$prefixDirsPsr4; 69 | $loader->classMap = ComposerStaticInit6e410ad27b65f7365030aa1ea83fae7f::$classMap; 70 | 71 | }, null, ClassLoader::class); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /vendor/dg/composer-cleaner/src/ComposerCleaner/Cleaner.php: -------------------------------------------------------------------------------- 1 | io = $io; 38 | $this->fileSystem = $fileSystem; 39 | } 40 | 41 | 42 | /** 43 | * @return void 44 | */ 45 | public function clean($vendorDir, array $ignorePaths = []) 46 | { 47 | foreach (new FilesystemIterator($vendorDir) as $packageVendor) { 48 | if (!$packageVendor->isDir()) { 49 | continue; 50 | } 51 | foreach (new FilesystemIterator($packageVendor) as $packageName) { 52 | if (!$packageName->isDir()) { 53 | continue; 54 | } 55 | $name = $packageVendor->getFileName() . '/' . $packageName->getFileName(); 56 | $ignore = isset($ignorePaths[$name]) ? $ignorePaths[$name] : null; 57 | if ($ignore === true) { 58 | $this->io->write("Composer cleaner: Skipped package $name", true, IOInterface::VERBOSE); 59 | } else { 60 | $this->io->write("Composer cleaner: Package $name", true, IOInterface::VERBOSE); 61 | $this->processPackage((string) $packageName, (array) $ignore); 62 | } 63 | } 64 | } 65 | $this->io->write("Composer cleaner: Removed $this->removedCount files or directories."); 66 | } 67 | 68 | 69 | /** 70 | * @return void 71 | */ 72 | private function processPackage($packageDir, array $ignoreFiles) 73 | { 74 | $data = $this->loadComposerJson($packageDir); 75 | $type = isset($data->type) ? $data->type : null; 76 | if (!$data || !in_array($type, self::$allowedComposerTypes, true)) { 77 | return; 78 | } 79 | 80 | foreach ($this->getExcludes($data) as $exclude) { 81 | $dir = trim(ltrim($exclude, '.'), '/'); 82 | if ($dir && strpos($dir, '..') === false && !self::matchMask($dir, $ignoreFiles)) { 83 | $path = $packageDir . '/' . $dir; 84 | $this->io->write("Composer cleaner: Removing $path", true, IOInterface::VERBOSE); 85 | $this->fileSystem->remove($path); 86 | $this->removedCount++; 87 | } 88 | } 89 | 90 | foreach ($this->getSources($data) as $source) { 91 | $dir = strstr(ltrim(ltrim($source, '.'), '/') . '/', '/', true); 92 | $ignoreFiles[] = $dir; 93 | } 94 | 95 | if (!$ignoreFiles || self::matchMask('', $ignoreFiles)) { 96 | return; 97 | } 98 | 99 | $ignoreFiles = array_merge($ignoreFiles, self::$alwaysIgnore); 100 | 101 | foreach (new FilesystemIterator($packageDir) as $path) { 102 | $fileName = $path->getFileName(); 103 | if (!self::matchMask($fileName, $ignoreFiles)) { 104 | $this->io->write("Composer cleaner: Removing $path", true, IOInterface::VERBOSE); 105 | $this->fileSystem->remove($path); 106 | $this->removedCount++; 107 | } 108 | } 109 | } 110 | 111 | 112 | /** 113 | * @param string 114 | * @param string[] 115 | * @return bool 116 | */ 117 | public static function matchMask($fileName, array $patterns) 118 | { 119 | foreach ($patterns as $pattern) { 120 | if (fnmatch($pattern, $fileName)) { 121 | return true; 122 | } 123 | } 124 | return false; 125 | } 126 | 127 | 128 | /** 129 | * @return string[] 130 | */ 131 | private function getSources(stdClass $data) 132 | { 133 | if (empty($data->autoload)) { 134 | return []; 135 | } 136 | 137 | $sources = isset($data->bin) ? (array) $data->bin : []; 138 | 139 | foreach ($data->autoload as $type => $items) { 140 | if ($type === 'psr-0') { 141 | foreach ($items as $namespace => $paths) { 142 | $namespace = strtr($namespace, '\\_', '//'); 143 | foreach ((array) $paths as $path) { 144 | $sources[] = rtrim($path, '\\/') . '/' . $namespace; 145 | } 146 | } 147 | 148 | } elseif ($type === 'psr-4') { 149 | foreach ($items as $namespace => $paths) { 150 | $sources = array_merge($sources, (array) $paths); 151 | } 152 | 153 | } elseif ($type === 'classmap' || $type === 'files') { 154 | $sources = array_merge($sources, (array) $items); 155 | 156 | } elseif ($type === 'exclude-from-classmap') { 157 | // ignore 158 | 159 | } else { 160 | $this->io->writeError("unknown autoload type $type"); 161 | return []; 162 | } 163 | } 164 | 165 | return $sources; 166 | } 167 | 168 | 169 | /** 170 | * @return string[] 171 | */ 172 | private function getExcludes(stdClass $data) 173 | { 174 | return empty($data->autoload->{'exclude-from-classmap'}) 175 | ? [] 176 | : (array) $data->autoload->{'exclude-from-classmap'}; 177 | } 178 | 179 | 180 | /** 181 | * @return stdClass|null 182 | */ 183 | public function loadComposerJson($dir) 184 | { 185 | $file = $dir . '/composer.json'; 186 | if (!is_file($file)) { 187 | $this->io->writeError("Composer cleaner: File $file not found.", true, IOInterface::VERBOSE); 188 | return; 189 | } 190 | $data = json_decode(file_get_contents($file)); 191 | if (!$data instanceof stdClass) { 192 | $this->io->writeError("Composer cleaner: Invalid $file."); 193 | return; 194 | } 195 | return $data; 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /vendor/composer/installed.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "dg/composer-cleaner", 4 | "version": "v2.1", 5 | "version_normalized": "2.1.0.0", 6 | "source": { 7 | "type": "git", 8 | "url": "https://github.com/dg/composer-cleaner.git", 9 | "reference": "91f865f0b50c66dd647955a0e5ba7745d8086945" 10 | }, 11 | "dist": { 12 | "type": "zip", 13 | "url": "https://api.github.com/repos/dg/composer-cleaner/zipball/91f865f0b50c66dd647955a0e5ba7745d8086945", 14 | "reference": "91f865f0b50c66dd647955a0e5ba7745d8086945", 15 | "shasum": "" 16 | }, 17 | "require": { 18 | "composer-plugin-api": "^1.0", 19 | "php": ">=5.4.0" 20 | }, 21 | "require-dev": { 22 | "nette/tester": "^1.7" 23 | }, 24 | "time": "2019-02-05T21:18:31+00:00", 25 | "type": "composer-plugin", 26 | "extra": { 27 | "class": "DG\\ComposerCleaner\\Plugin" 28 | }, 29 | "installation-source": "dist", 30 | "autoload": { 31 | "classmap": [ 32 | "src/" 33 | ] 34 | }, 35 | "notification-url": "https://packagist.org/downloads/", 36 | "license": [ 37 | "BSD-3-Clause" 38 | ], 39 | "authors": [ 40 | { 41 | "name": "David Grudl", 42 | "homepage": "https://davidgrudl.com" 43 | } 44 | ], 45 | "description": "Victor The Cleaner: removes unnecessary files from vendor directory.", 46 | "keywords": [ 47 | "composer" 48 | ] 49 | }, 50 | { 51 | "name": "mlocati/ip-lib", 52 | "version": "1.13.0", 53 | "version_normalized": "1.13.0.0", 54 | "source": { 55 | "type": "git", 56 | "url": "https://github.com/mlocati/ip-lib.git", 57 | "reference": "334de586c7894afd838be44d73e72d8e97e5b0ff" 58 | }, 59 | "dist": { 60 | "type": "zip", 61 | "url": "https://api.github.com/repos/mlocati/ip-lib/zipball/334de586c7894afd838be44d73e72d8e97e5b0ff", 62 | "reference": "334de586c7894afd838be44d73e72d8e97e5b0ff", 63 | "shasum": "" 64 | }, 65 | "require": { 66 | "php": ">=5.3.3" 67 | }, 68 | "require-dev": { 69 | "ext-pdo_sqlite": "*", 70 | "phpunit/dbunit": "^1.4 || ^2 || ^3 || ^4", 71 | "phpunit/phpunit": "^4.8 || ^5.7 || ^6.5" 72 | }, 73 | "time": "2020-10-04T12:22:58+00:00", 74 | "type": "library", 75 | "installation-source": "dist", 76 | "autoload": { 77 | "psr-4": { 78 | "IPLib\\": "src/" 79 | } 80 | }, 81 | "notification-url": "https://packagist.org/downloads/", 82 | "license": [ 83 | "MIT" 84 | ], 85 | "authors": [ 86 | { 87 | "name": "Michele Locati", 88 | "email": "mlocati@gmail.com", 89 | "homepage": "https://github.com/mlocati", 90 | "role": "Author" 91 | } 92 | ], 93 | "description": "Handle IPv4, IPv6 addresses and ranges", 94 | "homepage": "https://github.com/mlocati/ip-lib", 95 | "keywords": [ 96 | "IP", 97 | "address", 98 | "addresses", 99 | "ipv4", 100 | "ipv6", 101 | "manage", 102 | "managing", 103 | "matching", 104 | "network", 105 | "networking", 106 | "range", 107 | "subnet" 108 | ], 109 | "funding": [ 110 | { 111 | "url": "https://github.com/sponsors/mlocati", 112 | "type": "github" 113 | }, 114 | { 115 | "url": "https://paypal.me/mlocati", 116 | "type": "other" 117 | } 118 | ] 119 | }, 120 | { 121 | "name": "robthree/twofactorauth", 122 | "version": "1.7.0", 123 | "version_normalized": "1.7.0.0", 124 | "source": { 125 | "type": "git", 126 | "url": "https://github.com/RobThree/TwoFactorAuth.git", 127 | "reference": "37983bf675c5baca09d19d6705170489d0df0002" 128 | }, 129 | "dist": { 130 | "type": "zip", 131 | "url": "https://api.github.com/repos/RobThree/TwoFactorAuth/zipball/37983bf675c5baca09d19d6705170489d0df0002", 132 | "reference": "37983bf675c5baca09d19d6705170489d0df0002", 133 | "shasum": "" 134 | }, 135 | "require": { 136 | "php": ">=5.6.0" 137 | }, 138 | "require-dev": { 139 | "phpunit/phpunit": "@stable" 140 | }, 141 | "time": "2020-01-02T19:56:46+00:00", 142 | "type": "library", 143 | "installation-source": "dist", 144 | "autoload": { 145 | "psr-4": { 146 | "RobThree\\Auth\\": "lib" 147 | } 148 | }, 149 | "notification-url": "https://packagist.org/downloads/", 150 | "license": [ 151 | "MIT" 152 | ], 153 | "authors": [ 154 | { 155 | "name": "Rob Janssen", 156 | "homepage": "http://robiii.me", 157 | "role": "Developer" 158 | } 159 | ], 160 | "description": "Two Factor Authentication", 161 | "homepage": "https://github.com/RobThree/TwoFactorAuth", 162 | "keywords": [ 163 | "Authentication", 164 | "MFA", 165 | "Multi Factor Authentication", 166 | "Two Factor Authentication", 167 | "authenticator", 168 | "authy", 169 | "php", 170 | "tfa" 171 | ] 172 | } 173 | ] 174 | -------------------------------------------------------------------------------- /views/js/secure-random-password.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the securitylite package. 3 | * 4 | * @author Mathias Reker 5 | * @copyright Mathias Reker 6 | * @license Commercial Software License 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | !function(r){var t={};function n(e){if(t[e])return t[e].exports;var o=t[e]={i:e,l:!1,exports:{}};return r[e].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=r,n.c=t,n.d=function(r,t,e){n.o(r,t)||Object.defineProperty(r,t,{configurable:!1,enumerable:!0,get:e})},n.n=function(r){var t=r&&r.__esModule?function(){return r.default}:function(){return r};return n.d(t,"a",t),t},n.o=function(r,t){return Object.prototype.hasOwnProperty.call(r,t)},n.p="",n(n.s=2)}([function(r,t){r.exports={}},function(r,t,n){"use strict";function e(r){return Array.apply(null,Array(r)).map(function(r,t){return t})}function o(r){return Array.prototype.slice.call(r)}t.assign=function(){var r=o(arguments),t=r[0];return r.slice(1).filter(function(r){return!!r}).forEach(function(r){Object.keys(r).forEach(function(n){t[n]=r[n]})}),t},t.intersection=function(r,t){r=o(r),t=o(t);var n={};r.forEach(function(r){n[r]=!0});var e={};return t.forEach(function(r){e[r]=!0}),Object.keys(n).filter(function(r){return e.hasOwnProperty(r)})},t.isInteger=function(r){return"number"==typeof r&&isFinite(r)&&Math.floor(r)===r},t.isString=function(r){return"string"==typeof r||r instanceof String},t.range=e,t.repeat=function(r,t){return e(t).map(function(){return r})},t.toArray=o},function(r,t,n){window.secureRandomPassword=n(3)},function(r,t,n){"use strict";var e=n(4).default,o=n(7),u=n(1);Object.keys(o).forEach(function(r){t[r]=o[r]});var a=["Il1|","O0"];function c(r){var t={avoidAmbiguous:!0,characters:[o.lower,{characters:o.upper,exactly:1},{characters:o.symbols,exactly:1}],length:12,predicate:function(){return!0},random:e},n=function(r){if(!r.characters)return[];var t=Array.isArray(r.characters)?r.characters:[r.characters];t=t.map(function(r){return u.isString(r)?{characters:r}:r});var n=!0===r.avoidAmbiguous?a:r.avoidAmbiguous||[];return function(r,t){var n=r.map(function(r){return r.characters}).join(""),e=t.filter(function(r){return u.intersection(r,n).length>1}).join("");r.forEach(function(r){r.characters=u.toArray(r.characters).filter(function(r){return e.indexOf(r)<0}).join("")})}(t,n),t}(r=u.assign({},t,r));if(!u.isInteger(r.length))throw new Error("length must be an integer");if(r.length<1)throw new Error("length must be > 0");if(r.length= # of character sets passed");if(n.some(function(r){return!r.characters}))throw new Error("No character set may be empty");if(0===n.length)throw new Error("Must pass one or more character sets");if("function"!=typeof r.predicate)throw new Error("predicate must be a function");var c,s=n.map(function(r){return r.exactly||1}).reduce(function(r,t){return r+t},0);if(r.length=0;e--)t+=r[e]*n,n*=256;return t}u.prototype.choose=function(r){if(!r||!r.length)throw new Error("Must pass 1 or more choices");return r[this._getInt(r.length)]},u.prototype.getInt=function(r){if(void 0===r)throw new Error("Must pass an upper bound");if(!o.isInteger(r))throw new Error("Upper bound must be a number");if(r<1)throw new Error("Upper bound must be > 0");return this._getInt(r)},u.prototype._getInt=function(r){if(1===r)return 0;var t,n=Math.ceil(Math.log(r)/Math.log(256)),e=Math.pow(2,8*n)-Math.pow(2,8*n)%r;do{t=a(this._randomSource(n))}while(t>=e);return t%r},u.prototype.shuffle=function(r){r=Array.prototype.slice.call(r||[]);for(var t=[];r.length;)t.push(r.splice(this._getInt(r.length),1)[0]);return t},t.Random=u,t.default=new u(e)},function(r,t,n){(function(e,o){var u;!function(a){"use strict";function c(r,t){if(t=t||{type:"Array"},void 0!==e&&"number"==typeof e.pid)return function(r,t){var e=n(6).randomBytes(r);switch(t.type){case"Array":return[].slice.call(e);case"Buffer":return e;case"Uint8Array":for(var o=new Uint8Array(r),u=0;u?@[\\]^_`{|}~",t.copyableSymbols="_"}]); 13 | -------------------------------------------------------------------------------- /vendor/mlocati/ip-lib/src/Range/Single.php: -------------------------------------------------------------------------------- 1 | address = $address; 31 | } 32 | 33 | /** 34 | * {@inheritdoc} 35 | * 36 | * @see \IPLib\Range\RangeInterface::__toString() 37 | */ 38 | public function __toString() 39 | { 40 | return $this->address->__toString(); 41 | } 42 | 43 | /** 44 | * Try get the range instance starting from its string representation. 45 | * 46 | * @param string|mixed $range 47 | * @param bool $supportNonDecimalIPv4 set to true to support parsing non decimal (that is, octal and hexadecimal) IPv4 addresses 48 | * 49 | * @return static|null 50 | */ 51 | public static function fromString($range, $supportNonDecimalIPv4 = false) 52 | { 53 | $result = null; 54 | $address = Factory::addressFromString($range, true, true, $supportNonDecimalIPv4); 55 | if ($address !== null) { 56 | $result = new static($address); 57 | } 58 | 59 | return $result; 60 | } 61 | 62 | /** 63 | * Create the range instance starting from an address instance. 64 | * 65 | * @param \IPLib\Address\AddressInterface $address 66 | * 67 | * @return static 68 | */ 69 | public static function fromAddress(AddressInterface $address) 70 | { 71 | return new static($address); 72 | } 73 | 74 | /** 75 | * {@inheritdoc} 76 | * 77 | * @see \IPLib\Range\RangeInterface::toString() 78 | */ 79 | public function toString($long = false) 80 | { 81 | return $this->address->toString($long); 82 | } 83 | 84 | /** 85 | * {@inheritdoc} 86 | * 87 | * @see \IPLib\Range\RangeInterface::getAddressType() 88 | */ 89 | public function getAddressType() 90 | { 91 | return $this->address->getAddressType(); 92 | } 93 | 94 | /** 95 | * {@inheritdoc} 96 | * 97 | * @see \IPLib\Range\RangeInterface::getRangeType() 98 | */ 99 | public function getRangeType() 100 | { 101 | return $this->address->getRangeType(); 102 | } 103 | 104 | /** 105 | * {@inheritdoc} 106 | * 107 | * @see \IPLib\Range\RangeInterface::contains() 108 | */ 109 | public function contains(AddressInterface $address) 110 | { 111 | $result = false; 112 | if ($address->getAddressType() === $this->getAddressType()) { 113 | if ($address->toString(false) === $this->address->toString(false)) { 114 | $result = true; 115 | } 116 | } 117 | 118 | return $result; 119 | } 120 | 121 | /** 122 | * {@inheritdoc} 123 | * 124 | * @see \IPLib\Range\RangeInterface::containsRange() 125 | */ 126 | public function containsRange(RangeInterface $range) 127 | { 128 | $result = false; 129 | if ($range->getAddressType() === $this->getAddressType()) { 130 | if ($range->toString(false) === $this->toString(false)) { 131 | $result = true; 132 | } 133 | } 134 | 135 | return $result; 136 | } 137 | 138 | /** 139 | * {@inheritdoc} 140 | * 141 | * @see \IPLib\Range\RangeInterface::getStartAddress() 142 | */ 143 | public function getStartAddress() 144 | { 145 | return $this->address; 146 | } 147 | 148 | /** 149 | * {@inheritdoc} 150 | * 151 | * @see \IPLib\Range\RangeInterface::getEndAddress() 152 | */ 153 | public function getEndAddress() 154 | { 155 | return $this->address; 156 | } 157 | 158 | /** 159 | * {@inheritdoc} 160 | * 161 | * @see \IPLib\Range\RangeInterface::getComparableStartString() 162 | */ 163 | public function getComparableStartString() 164 | { 165 | return $this->address->getComparableString(); 166 | } 167 | 168 | /** 169 | * {@inheritdoc} 170 | * 171 | * @see \IPLib\Range\RangeInterface::getComparableEndString() 172 | */ 173 | public function getComparableEndString() 174 | { 175 | return $this->address->getComparableString(); 176 | } 177 | 178 | /** 179 | * {@inheritdoc} 180 | * 181 | * @see \IPLib\Range\RangeInterface::asSubnet() 182 | */ 183 | public function asSubnet() 184 | { 185 | $networkPrefixes = array( 186 | AddressType::T_IPv4 => 32, 187 | AddressType::T_IPv6 => 128, 188 | ); 189 | 190 | return new Subnet($this->address, $this->address, $networkPrefixes[$this->address->getAddressType()]); 191 | } 192 | 193 | /** 194 | * {@inheritdoc} 195 | * 196 | * @see \IPLib\Range\RangeInterface::asPattern() 197 | */ 198 | public function asPattern() 199 | { 200 | return new Pattern($this->address, $this->address, 0); 201 | } 202 | 203 | /** 204 | * {@inheritdoc} 205 | * 206 | * @see \IPLib\Range\RangeInterface::getSubnetMask() 207 | */ 208 | public function getSubnetMask() 209 | { 210 | if ($this->getAddressType() !== AddressType::T_IPv4) { 211 | return null; 212 | } 213 | 214 | return IPv4::fromBytes(array(255, 255, 255, 255)); 215 | } 216 | 217 | /** 218 | * {@inheritdoc} 219 | * 220 | * @see \IPLib\Range\RangeInterface::getReverseDNSLookupName() 221 | */ 222 | public function getReverseDNSLookupName() 223 | { 224 | return array($this->getStartAddress()->getReverseDNSLookupName()); 225 | } 226 | } 227 | -------------------------------------------------------------------------------- /vendor/mlocati/ip-lib/src/Factory.php: -------------------------------------------------------------------------------- 1 | getAddressType(); 129 | if ($addressType === $to->getAddressType()) { 130 | $cmp = strcmp($from->getComparableString(), $to->getComparableString()); 131 | if ($cmp === 0) { 132 | $result = Range\Single::fromAddress($from); 133 | } else { 134 | if ($cmp > 0) { 135 | list($from, $to) = array($to, $from); 136 | } 137 | $fromBytes = $from->getBytes(); 138 | $toBytes = $to->getBytes(); 139 | $numBytes = count($fromBytes); 140 | $sameBits = 0; 141 | for ($byteIndex = 0; $byteIndex < $numBytes; $byteIndex++) { 142 | $fromByte = $fromBytes[$byteIndex]; 143 | $toByte = $toBytes[$byteIndex]; 144 | if ($fromByte === $toByte) { 145 | $sameBits += 8; 146 | } else { 147 | $differentBitsInByte = decbin($fromByte ^ $toByte); 148 | $sameBits += 8 - strlen($differentBitsInByte); 149 | break; 150 | } 151 | } 152 | $result = static::rangeFromString($from->toString(true) . '/' . (string) $sameBits); 153 | } 154 | } 155 | } 156 | 157 | return $result; 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /vendor/mlocati/ip-lib/src/Range/Pattern.php: -------------------------------------------------------------------------------- 1 | fromAddress = $fromAddress; 56 | $this->toAddress = $toAddress; 57 | $this->asterisksCount = $asterisksCount; 58 | } 59 | 60 | /** 61 | * {@inheritdoc} 62 | * 63 | * @see \IPLib\Range\RangeInterface::__toString() 64 | */ 65 | public function __toString() 66 | { 67 | return $this->toString(); 68 | } 69 | 70 | /** 71 | * Try get the range instance starting from its string representation. 72 | * 73 | * @param string|mixed $range 74 | * @param bool $supportNonDecimalIPv4 set to true to support parsing non decimal (that is, octal and hexadecimal) IPv4 addresses 75 | * 76 | * @return static|null 77 | */ 78 | public static function fromString($range, $supportNonDecimalIPv4 = false) 79 | { 80 | if (!is_string($range) || strpos($range, '*') === false) { 81 | return null; 82 | } 83 | if ($range === '*.*.*.*') { 84 | return new static(IPv4::fromString('0.0.0.0'), IPv4::fromString('255.255.255.255'), 4); 85 | } 86 | if ($range === '*:*:*:*:*:*:*:*') { 87 | return new static(IPv6::fromString('::'), IPv6::fromString('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'), 8); 88 | } 89 | $matches = null; 90 | if (strpos($range, '.') !== false && preg_match('/^[^*]+((?:\.\*)+)$/', $range, $matches)) { 91 | $asterisksCount = strlen($matches[1]) >> 1; 92 | if ($asterisksCount > 0) { 93 | $missingDots = 3 - substr_count($range, '.'); 94 | if ($missingDots > 0) { 95 | $range .= str_repeat('.*', $missingDots); 96 | $asterisksCount += $missingDots; 97 | } 98 | } 99 | $fromAddress = IPv4::fromString(str_replace('*', '0', $range), true, $supportNonDecimalIPv4); 100 | if ($fromAddress === null) { 101 | return null; 102 | } 103 | $fixedBytes = array_slice($fromAddress->getBytes(), 0, -$asterisksCount); 104 | $otherBytes = array_fill(0, $asterisksCount, 255); 105 | $toAddress = IPv4::fromBytes(array_merge($fixedBytes, $otherBytes)); 106 | 107 | return new static($fromAddress, $toAddress, $asterisksCount); 108 | } 109 | if (strpos($range, ':') !== false && preg_match('/^[^*]+((?::\*)+)$/', $range, $matches)) { 110 | $asterisksCount = strlen($matches[1]) >> 1; 111 | $fromAddress = IPv6::fromString(str_replace('*', '0', $range)); 112 | if ($fromAddress === null) { 113 | return null; 114 | } 115 | $fixedWords = array_slice($fromAddress->getWords(), 0, -$asterisksCount); 116 | $otherWords = array_fill(0, $asterisksCount, 0xffff); 117 | $toAddress = IPv6::fromWords(array_merge($fixedWords, $otherWords)); 118 | 119 | return new static($fromAddress, $toAddress, $asterisksCount); 120 | } 121 | 122 | return null; 123 | } 124 | 125 | /** 126 | * {@inheritdoc} 127 | * 128 | * @see \IPLib\Range\RangeInterface::toString() 129 | */ 130 | public function toString($long = false) 131 | { 132 | if ($this->asterisksCount === 0) { 133 | return $this->fromAddress->toString($long); 134 | } 135 | switch (true) { 136 | case $this->fromAddress instanceof \IPLib\Address\IPv4: 137 | $chunks = explode('.', $this->fromAddress->toString()); 138 | $chunks = array_slice($chunks, 0, -$this->asterisksCount); 139 | $chunks = array_pad($chunks, 4, '*'); 140 | $result = implode('.', $chunks); 141 | break; 142 | case $this->fromAddress instanceof \IPLib\Address\IPv6: 143 | if ($long) { 144 | $chunks = explode(':', $this->fromAddress->toString(true)); 145 | $chunks = array_slice($chunks, 0, -$this->asterisksCount); 146 | $chunks = array_pad($chunks, 8, '*'); 147 | $result = implode(':', $chunks); 148 | } elseif ($this->asterisksCount === 8) { 149 | $result = '*:*:*:*:*:*:*:*'; 150 | } else { 151 | $bytes = $this->toAddress->getBytes(); 152 | $bytes = array_slice($bytes, 0, -$this->asterisksCount * 2); 153 | $bytes = array_pad($bytes, 16, 1); 154 | $address = IPv6::fromBytes($bytes); 155 | $before = substr($address->toString(false), 0, -strlen(':101') * $this->asterisksCount); 156 | $result = $before . str_repeat(':*', $this->asterisksCount); 157 | } 158 | break; 159 | default: 160 | throw new \Exception('@todo'); // @codeCoverageIgnore 161 | } 162 | 163 | return $result; 164 | } 165 | 166 | /** 167 | * {@inheritdoc} 168 | * 169 | * @see \IPLib\Range\RangeInterface::getAddressType() 170 | */ 171 | public function getAddressType() 172 | { 173 | return $this->fromAddress->getAddressType(); 174 | } 175 | 176 | /** 177 | * {@inheritdoc} 178 | * 179 | * @see \IPLib\Range\RangeInterface::getStartAddress() 180 | */ 181 | public function getStartAddress() 182 | { 183 | return $this->fromAddress; 184 | } 185 | 186 | /** 187 | * {@inheritdoc} 188 | * 189 | * @see \IPLib\Range\RangeInterface::getEndAddress() 190 | */ 191 | public function getEndAddress() 192 | { 193 | return $this->toAddress; 194 | } 195 | 196 | /** 197 | * {@inheritdoc} 198 | * 199 | * @see \IPLib\Range\RangeInterface::getComparableStartString() 200 | */ 201 | public function getComparableStartString() 202 | { 203 | return $this->fromAddress->getComparableString(); 204 | } 205 | 206 | /** 207 | * {@inheritdoc} 208 | * 209 | * @see \IPLib\Range\RangeInterface::getComparableEndString() 210 | */ 211 | public function getComparableEndString() 212 | { 213 | return $this->toAddress->getComparableString(); 214 | } 215 | 216 | /** 217 | * {@inheritdoc} 218 | * 219 | * @see \IPLib\Range\RangeInterface::asSubnet() 220 | */ 221 | public function asSubnet() 222 | { 223 | switch ($this->getAddressType()) { 224 | case AddressType::T_IPv4: 225 | return new Subnet($this->getStartAddress(), $this->getEndAddress(), 8 * (4 - $this->asterisksCount)); 226 | case AddressType::T_IPv6: 227 | return new Subnet($this->getStartAddress(), $this->getEndAddress(), 16 * (8 - $this->asterisksCount)); 228 | } 229 | } 230 | 231 | /** 232 | * {@inheritdoc} 233 | * 234 | * @see \IPLib\Range\RangeInterface::asPattern() 235 | */ 236 | public function asPattern() 237 | { 238 | return $this; 239 | } 240 | 241 | /** 242 | * {@inheritdoc} 243 | * 244 | * @see \IPLib\Range\RangeInterface::getSubnetMask() 245 | */ 246 | public function getSubnetMask() 247 | { 248 | if ($this->getAddressType() !== AddressType::T_IPv4) { 249 | return null; 250 | } 251 | switch ($this->asterisksCount) { 252 | case 0: 253 | $bytes = array(255, 255, 255, 255); 254 | break; 255 | case 4: 256 | $bytes = array(0, 0, 0, 0); 257 | break; 258 | default: 259 | $bytes = array_pad(array_fill(0, 4 - $this->asterisksCount, 255), 4, 0); 260 | break; 261 | } 262 | 263 | return IPv4::fromBytes($bytes); 264 | } 265 | 266 | /** 267 | * {@inheritdoc} 268 | * 269 | * @see \IPLib\Range\RangeInterface::getReverseDNSLookupName() 270 | */ 271 | public function getReverseDNSLookupName() 272 | { 273 | return $this->asterisksCount === 0 ? array($this->getStartAddress()->getReverseDNSLookupName()) : $this->asSubnet()->getReverseDNSLookupName(); 274 | } 275 | } 276 | -------------------------------------------------------------------------------- /vendor/mlocati/ip-lib/src/Range/Subnet.php: -------------------------------------------------------------------------------- 1 | fromAddress = $fromAddress; 66 | $this->toAddress = $toAddress; 67 | $this->networkPrefix = $networkPrefix; 68 | } 69 | 70 | /** 71 | * {@inheritdoc} 72 | * 73 | * @see \IPLib\Range\RangeInterface::__toString() 74 | */ 75 | public function __toString() 76 | { 77 | return $this->toString(); 78 | } 79 | 80 | /** 81 | * Try get the range instance starting from its string representation. 82 | * 83 | * @param string|mixed $range 84 | * @param bool $supportNonDecimalIPv4 set to true to support parsing non decimal (that is, octal and hexadecimal) IPv4 addresses 85 | * 86 | * @return static|null 87 | */ 88 | public static function fromString($range, $supportNonDecimalIPv4 = false) 89 | { 90 | if (!is_string($range)) { 91 | return null; 92 | } 93 | $parts = explode('/', $range); 94 | if (count($parts) !== 2) { 95 | return null; 96 | } 97 | $address = Factory::addressFromString($parts[0], true, true, $supportNonDecimalIPv4); 98 | if ($address === null) { 99 | return null; 100 | } 101 | if (!preg_match('/^[0-9]{1,9}$/', $parts[1])) { 102 | return null; 103 | } 104 | $networkPrefix = (int) $parts[1]; 105 | $addressBytes = $address->getBytes(); 106 | $totalBytes = count($addressBytes); 107 | $numDifferentBits = $totalBytes * 8 - $networkPrefix; 108 | if ($numDifferentBits < 0) { 109 | return null; 110 | } 111 | $numSameBytes = $networkPrefix >> 3; 112 | $sameBytes = array_slice($addressBytes, 0, $numSameBytes); 113 | $differentBytesStart = ($totalBytes === $numSameBytes) ? array() : array_fill(0, $totalBytes - $numSameBytes, 0); 114 | $differentBytesEnd = ($totalBytes === $numSameBytes) ? array() : array_fill(0, $totalBytes - $numSameBytes, 255); 115 | $startSameBits = $networkPrefix % 8; 116 | if ($startSameBits !== 0) { 117 | $varyingByte = $addressBytes[$numSameBytes]; 118 | $differentBytesStart[0] = $varyingByte & bindec(str_pad(str_repeat('1', $startSameBits), 8, '0', STR_PAD_RIGHT)); 119 | $differentBytesEnd[0] = $differentBytesStart[0] + bindec(str_repeat('1', 8 - $startSameBits)); 120 | } 121 | 122 | return new static( 123 | Factory::addressFromBytes(array_merge($sameBytes, $differentBytesStart)), 124 | Factory::addressFromBytes(array_merge($sameBytes, $differentBytesEnd)), 125 | $networkPrefix 126 | ); 127 | } 128 | 129 | /** 130 | * {@inheritdoc} 131 | * 132 | * @see \IPLib\Range\RangeInterface::toString() 133 | */ 134 | public function toString($long = false) 135 | { 136 | return $this->fromAddress->toString($long) . '/' . $this->networkPrefix; 137 | } 138 | 139 | /** 140 | * {@inheritdoc} 141 | * 142 | * @see \IPLib\Range\RangeInterface::getAddressType() 143 | */ 144 | public function getAddressType() 145 | { 146 | return $this->fromAddress->getAddressType(); 147 | } 148 | 149 | /** 150 | * {@inheritdoc} 151 | * 152 | * @see \IPLib\Range\RangeInterface::getStartAddress() 153 | */ 154 | public function getStartAddress() 155 | { 156 | return $this->fromAddress; 157 | } 158 | 159 | /** 160 | * {@inheritdoc} 161 | * 162 | * @see \IPLib\Range\RangeInterface::getEndAddress() 163 | */ 164 | public function getEndAddress() 165 | { 166 | return $this->toAddress; 167 | } 168 | 169 | /** 170 | * {@inheritdoc} 171 | * 172 | * @see \IPLib\Range\RangeInterface::getComparableStartString() 173 | */ 174 | public function getComparableStartString() 175 | { 176 | return $this->fromAddress->getComparableString(); 177 | } 178 | 179 | /** 180 | * {@inheritdoc} 181 | * 182 | * @see \IPLib\Range\RangeInterface::getComparableEndString() 183 | */ 184 | public function getComparableEndString() 185 | { 186 | return $this->toAddress->getComparableString(); 187 | } 188 | 189 | /** 190 | * {@inheritdoc} 191 | * 192 | * @see \IPLib\Range\RangeInterface::asSubnet() 193 | */ 194 | public function asSubnet() 195 | { 196 | return $this; 197 | } 198 | 199 | /** 200 | * Get the pattern (asterisk) representation (if applicable) of this range. 201 | * 202 | * @return \IPLib\Range\Pattern|null return NULL if this range can't be represented by a pattern notation 203 | */ 204 | public function asPattern() 205 | { 206 | $address = $this->getStartAddress(); 207 | $networkPrefix = $this->getNetworkPrefix(); 208 | switch ($address->getAddressType()) { 209 | case AddressType::T_IPv4: 210 | return $networkPrefix % 8 === 0 ? new Pattern($address, $address, 4 - $networkPrefix / 8) : null; 211 | case AddressType::T_IPv6: 212 | return $networkPrefix % 16 === 0 ? new Pattern($address, $address, 8 - $networkPrefix / 16) : null; 213 | } 214 | } 215 | 216 | /** 217 | * Get the 6to4 address IPv6 address range. 218 | * 219 | * @return self 220 | */ 221 | public static function get6to4() 222 | { 223 | if (self::$sixToFour === null) { 224 | self::$sixToFour = self::fromString('2002::/16'); 225 | } 226 | 227 | return self::$sixToFour; 228 | } 229 | 230 | /** 231 | * Get subnet prefix. 232 | * 233 | * @return int 234 | */ 235 | public function getNetworkPrefix() 236 | { 237 | return $this->networkPrefix; 238 | } 239 | 240 | /** 241 | * {@inheritdoc} 242 | * 243 | * @see \IPLib\Range\RangeInterface::getSubnetMask() 244 | */ 245 | public function getSubnetMask() 246 | { 247 | if ($this->getAddressType() !== AddressType::T_IPv4) { 248 | return null; 249 | } 250 | $bytes = array(); 251 | $prefix = $this->getNetworkPrefix(); 252 | while ($prefix >= 8) { 253 | $bytes[] = 255; 254 | $prefix -= 8; 255 | } 256 | if ($prefix !== 0) { 257 | $bytes[] = bindec(str_pad(str_repeat('1', $prefix), 8, '0')); 258 | } 259 | $bytes = array_pad($bytes, 4, 0); 260 | 261 | return IPv4::fromBytes($bytes); 262 | } 263 | 264 | /** 265 | * {@inheritdoc} 266 | * 267 | * @see \IPLib\Range\RangeInterface::getReverseDNSLookupName() 268 | */ 269 | public function getReverseDNSLookupName() 270 | { 271 | switch ($this->getAddressType()) { 272 | case AddressType::T_IPv4: 273 | $unitSize = 8; // bytes 274 | $maxUnits = 4; 275 | $isHex = false; 276 | $rxUnit = '\d+'; 277 | break; 278 | case AddressType::T_IPv6: 279 | $unitSize = 4; // nibbles 280 | $maxUnits = 32; 281 | $isHex = true; 282 | $rxUnit = '[0-9A-Fa-f]'; 283 | break; 284 | } 285 | $totBits = $unitSize * $maxUnits; 286 | $prefixUnits = (int) ($this->networkPrefix / $unitSize); 287 | $extraBits = ($totBits - $this->networkPrefix) % $unitSize; 288 | if ($extraBits !== 0) { 289 | $prefixUnits += 1; 290 | } 291 | $numVariants = 1 << $extraBits; 292 | $result = array(); 293 | $unitsToRemove = $maxUnits - $prefixUnits; 294 | $initialPointer = preg_replace("/^(({$rxUnit})\.){{$unitsToRemove}}/", '', $this->getStartAddress()->getReverseDNSLookupName()); 295 | $chunks = explode('.', $initialPointer, 2); 296 | for ($index = 0; $index < $numVariants; $index++) { 297 | if ($index !== 0) { 298 | $chunks[0] = $isHex ? dechex(1 + hexdec($chunks[0])) : (string) (1 + (int) $chunks[0]); 299 | } 300 | $result[] = implode('.', $chunks); 301 | } 302 | 303 | return $result; 304 | } 305 | } 306 | -------------------------------------------------------------------------------- /vendor/robthree/twofactorauth/lib/TwoFactorAuth.php: -------------------------------------------------------------------------------- 1 | issuer = $issuer; 27 | if (!is_int($digits) || $digits <= 0) 28 | throw new TwoFactorAuthException('Digits must be int > 0'); 29 | $this->digits = $digits; 30 | 31 | if (!is_int($period) || $period <= 0) 32 | throw new TwoFactorAuthException('Period must be int > 0'); 33 | $this->period = $period; 34 | 35 | $algorithm = strtolower(trim($algorithm)); 36 | if (!in_array($algorithm, self::$_supportedalgos)) 37 | throw new TwoFactorAuthException('Unsupported algorithm: ' . $algorithm); 38 | $this->algorithm = $algorithm; 39 | $this->qrcodeprovider = $qrcodeprovider; 40 | $this->rngprovider = $rngprovider; 41 | $this->timeprovider = $timeprovider; 42 | 43 | self::$_base32 = str_split(self::$_base32dict); 44 | self::$_base32lookup = array_flip(self::$_base32); 45 | } 46 | 47 | /** 48 | * Create a new secret 49 | */ 50 | public function createSecret($bits = 80, $requirecryptosecure = true) 51 | { 52 | $secret = ''; 53 | $bytes = ceil($bits / 5); //We use 5 bits of each byte (since we have a 32-character 'alphabet' / BASE32) 54 | $rngprovider = $this->getRngprovider(); 55 | if ($requirecryptosecure && !$rngprovider->isCryptographicallySecure()) 56 | throw new TwoFactorAuthException('RNG provider is not cryptographically secure'); 57 | $rnd = $rngprovider->getRandomBytes($bytes); 58 | for ($i = 0; $i < $bytes; $i++) 59 | $secret .= self::$_base32[ord($rnd[$i]) & 31]; //Mask out left 3 bits for 0-31 values 60 | return $secret; 61 | } 62 | 63 | /** 64 | * Calculate the code with given secret and point in time 65 | */ 66 | public function getCode($secret, $time = null) 67 | { 68 | $secretkey = $this->base32Decode($secret); 69 | 70 | $timestamp = "\0\0\0\0" . pack('N*', $this->getTimeSlice($this->getTime($time))); // Pack time into binary string 71 | $hashhmac = hash_hmac($this->algorithm, $timestamp, $secretkey, true); // Hash it with users secret key 72 | $hashpart = substr($hashhmac, ord(substr($hashhmac, -1)) & 0x0F, 4); // Use last nibble of result as index/offset and grab 4 bytes of the result 73 | $value = unpack('N', $hashpart); // Unpack binary value 74 | $value = $value[1] & 0x7FFFFFFF; // Drop MSB, keep only 31 bits 75 | 76 | return str_pad($value % pow(10, $this->digits), $this->digits, '0', STR_PAD_LEFT); 77 | } 78 | 79 | /** 80 | * Check if the code is correct. This will accept codes starting from ($discrepancy * $period) sec ago to ($discrepancy * period) sec from now 81 | */ 82 | public function verifyCode($secret, $code, $discrepancy = 1, $time = null, &$timeslice = 0) 83 | { 84 | $timetamp = $this->getTime($time); 85 | 86 | $timeslice = 0; 87 | 88 | // To keep safe from timing-attacks we iterate *all* possible codes even though we already may have 89 | // verified a code is correct. We use the timeslice variable to hold either 0 (no match) or the timeslice 90 | // of the match. Each iteration we either set the timeslice variable to the timeslice of the match 91 | // or set the value to itself. This is an effort to maintain constant execution time for the code. 92 | for ($i = -$discrepancy; $i <= $discrepancy; $i++) { 93 | $ts = $timetamp + ($i * $this->period); 94 | $slice = $this->getTimeSlice($ts); 95 | $timeslice = $this->codeEquals($this->getCode($secret, $ts), $code) ? $slice : $timeslice; 96 | } 97 | 98 | return $timeslice > 0; 99 | } 100 | 101 | /** 102 | * Timing-attack safe comparison of 2 codes (see http://blog.ircmaxell.com/2014/11/its-all-about-time.html) 103 | */ 104 | private function codeEquals($safe, $user) { 105 | if (function_exists('hash_equals')) { 106 | return hash_equals($safe, $user); 107 | } 108 | // In general, it's not possible to prevent length leaks. So it's OK to leak the length. The important part is that 109 | // we don't leak information about the difference of the two strings. 110 | if (strlen($safe)===strlen($user)) { 111 | $result = 0; 112 | for ($i = 0; $i < strlen($safe); $i++) 113 | $result |= (ord($safe[$i]) ^ ord($user[$i])); 114 | return $result === 0; 115 | } 116 | return false; 117 | } 118 | 119 | /** 120 | * Get data-uri of QRCode 121 | */ 122 | public function getQRCodeImageAsDataUri($label, $secret, $size = 200) 123 | { 124 | if (!is_int($size) || $size <= 0) 125 | throw new TwoFactorAuthException('Size must be int > 0'); 126 | 127 | $qrcodeprovider = $this->getQrCodeProvider(); 128 | return 'data:' 129 | . $qrcodeprovider->getMimeType() 130 | . ';base64,' 131 | . base64_encode($qrcodeprovider->getQRCodeImage($this->getQRText($label, $secret), $size)); 132 | } 133 | 134 | /** 135 | * Compare default timeprovider with specified timeproviders and ensure the time is within the specified number of seconds (leniency) 136 | */ 137 | public function ensureCorrectTime(array $timeproviders = null, $leniency = 5) 138 | { 139 | if ($timeproviders != null && !is_array($timeproviders)) 140 | throw new TwoFactorAuthException('No timeproviders specified'); 141 | 142 | if ($timeproviders == null) 143 | $timeproviders = array( 144 | new Providers\Time\NTPTimeProvider(), 145 | new Providers\Time\HttpTimeProvider() 146 | ); 147 | 148 | // Get default time provider 149 | $timeprovider = $this->getTimeProvider(); 150 | 151 | // Iterate specified time providers 152 | foreach ($timeproviders as $t) { 153 | if (!($t instanceof ITimeProvider)) 154 | throw new TwoFactorAuthException('Object does not implement ITimeProvider'); 155 | 156 | // Get time from default time provider and compare to specific time provider and throw if time difference is more than specified number of seconds leniency 157 | if (abs($timeprovider->getTime() - $t->getTime()) > $leniency) 158 | throw new TwoFactorAuthException(sprintf('Time for timeprovider is off by more than %d seconds when compared to %s', $leniency, get_class($t))); 159 | } 160 | } 161 | 162 | private function getTime($time) 163 | { 164 | return ($time === null) ? $this->getTimeProvider()->getTime() : $time; 165 | } 166 | 167 | private function getTimeSlice($time = null, $offset = 0) 168 | { 169 | return (int)floor($time / $this->period) + ($offset * $this->period); 170 | } 171 | 172 | /** 173 | * Builds a string to be encoded in a QR code 174 | */ 175 | public function getQRText($label, $secret) 176 | { 177 | return 'otpauth://totp/' . rawurlencode($label) 178 | . '?secret=' . rawurlencode($secret) 179 | . '&issuer=' . rawurlencode($this->issuer) 180 | . '&period=' . intval($this->period) 181 | . '&algorithm=' . rawurlencode(strtoupper($this->algorithm)) 182 | . '&digits=' . intval($this->digits); 183 | } 184 | 185 | private function base32Decode($value) 186 | { 187 | if (strlen($value)==0) return ''; 188 | 189 | if (preg_match('/[^'.preg_quote(self::$_base32dict).']/', $value) !== 0) 190 | throw new TwoFactorAuthException('Invalid base32 string'); 191 | 192 | $buffer = ''; 193 | foreach (str_split($value) as $char) 194 | { 195 | if ($char !== '=') 196 | $buffer .= str_pad(decbin(self::$_base32lookup[$char]), 5, 0, STR_PAD_LEFT); 197 | } 198 | $length = strlen($buffer); 199 | $blocks = trim(chunk_split(substr($buffer, 0, $length - ($length % 8)), 8, ' ')); 200 | 201 | $output = ''; 202 | foreach (explode(' ', $blocks) as $block) 203 | $output .= chr(bindec(str_pad($block, 8, 0, STR_PAD_RIGHT))); 204 | return $output; 205 | } 206 | 207 | /** 208 | * @return IQRCodeProvider 209 | * @throws TwoFactorAuthException 210 | */ 211 | public function getQrCodeProvider() 212 | { 213 | // Set default QR Code provider if none was specified 214 | if (null === $this->qrcodeprovider) { 215 | return $this->qrcodeprovider = new Providers\Qr\QRServerProvider(); 216 | } 217 | return $this->qrcodeprovider; 218 | } 219 | 220 | /** 221 | * @return IRNGProvider 222 | * @throws TwoFactorAuthException 223 | */ 224 | public function getRngprovider() 225 | { 226 | if (null !== $this->rngprovider) { 227 | return $this->rngprovider; 228 | } 229 | if (function_exists('random_bytes')) { 230 | return $this->rngprovider = new Providers\Rng\CSRNGProvider(); 231 | } 232 | if (function_exists('mcrypt_create_iv')) { 233 | return $this->rngprovider = new Providers\Rng\MCryptRNGProvider(); 234 | } 235 | if (function_exists('openssl_random_pseudo_bytes')) { 236 | return $this->rngprovider = new Providers\Rng\OpenSSLRNGProvider(); 237 | } 238 | if (function_exists('hash')) { 239 | return $this->rngprovider = new Providers\Rng\HashRNGProvider(); 240 | } 241 | throw new TwoFactorAuthException('Unable to find a suited RNGProvider'); 242 | } 243 | 244 | /** 245 | * @return ITimeProvider 246 | * @throws TwoFactorAuthException 247 | */ 248 | public function getTimeProvider() 249 | { 250 | // Set default time provider if none was specified 251 | if (null === $this->timeprovider) { 252 | return $this->timeprovider = new Providers\Time\LocalMachineTimeProvider(); 253 | } 254 | return $this->timeprovider; 255 | } 256 | } -------------------------------------------------------------------------------- /vendor/mlocati/ip-lib/src/Address/IPv4.php: -------------------------------------------------------------------------------- 1 | address = $address; 59 | $this->bytes = null; 60 | $this->rangeType = null; 61 | $this->comparableString = null; 62 | } 63 | 64 | /** 65 | * {@inheritdoc} 66 | * 67 | * @see \IPLib\Address\AddressInterface::__toString() 68 | */ 69 | public function __toString() 70 | { 71 | return $this->address; 72 | } 73 | 74 | /** 75 | * Parse a string and returns an IPv4 instance if the string is valid, or null otherwise. 76 | * 77 | * @param string|mixed $address the address to parse 78 | * @param bool $mayIncludePort set to false to avoid parsing addresses with ports 79 | * @param bool $supportNonDecimalIPv4 set to true to support parsing non decimal (that is, octal and hexadecimal) IPv4 addresses 80 | * 81 | * @return static|null 82 | */ 83 | public static function fromString($address, $mayIncludePort = true, $supportNonDecimalIPv4 = false) 84 | { 85 | if (!is_string($address) || !strpos($address, '.')) { 86 | return null; 87 | } 88 | $rxChunk = '0?[0-9]{1,3}'; 89 | if ($supportNonDecimalIPv4) { 90 | $rxChunk = "(?:0[Xx]0*[0-9A-Fa-f]{1,2})|(?:{$rxChunk})"; 91 | } 92 | $rx = "0*?({$rxChunk})\.0*?({$rxChunk})\.0*?({$rxChunk})\.0*?({$rxChunk})"; 93 | if ($mayIncludePort) { 94 | $rx .= '(?::\d+)?'; 95 | } 96 | $matches = null; 97 | if (!preg_match('/^' . $rx . '$/', $address, $matches)) { 98 | return null; 99 | } 100 | $nums = array(); 101 | for ($i = 1; $i <= 4; $i++) { 102 | $s = $matches[$i]; 103 | if ($supportNonDecimalIPv4) { 104 | if (stripos($s, '0x') === 0) { 105 | $n = hexdec(substr($s, 2)); 106 | } elseif ($s[0] === '0') { 107 | if (!preg_match('/^[0-7]+$/', $s)) { 108 | return null; 109 | } 110 | $n = octdec(substr($s, 1)); 111 | } else { 112 | $n = (int) $s; 113 | } 114 | } else { 115 | $n = (int) $s; 116 | } 117 | if ($n < 0 || $n > 255) { 118 | return null; 119 | } 120 | $nums[] = (string) $n; 121 | } 122 | 123 | return new static(implode('.', $nums)); 124 | } 125 | 126 | /** 127 | * Parse an array of bytes and returns an IPv4 instance if the array is valid, or null otherwise. 128 | * 129 | * @param int[]|array $bytes 130 | * 131 | * @return static|null 132 | */ 133 | public static function fromBytes(array $bytes) 134 | { 135 | $result = null; 136 | if (count($bytes) === 4) { 137 | $chunks = array_map( 138 | function ($byte) { 139 | return (is_int($byte) && $byte >= 0 && $byte <= 255) ? (string) $byte : false; 140 | }, 141 | $bytes 142 | ); 143 | if (in_array(false, $chunks, true) === false) { 144 | $result = new static(implode('.', $chunks)); 145 | } 146 | } 147 | 148 | return $result; 149 | } 150 | 151 | /** 152 | * {@inheritdoc} 153 | * 154 | * @see \IPLib\Address\AddressInterface::toString() 155 | */ 156 | public function toString($long = false) 157 | { 158 | if ($long) { 159 | return $this->getComparableString(); 160 | } 161 | 162 | return $this->address; 163 | } 164 | 165 | /** 166 | * Get the octal representation of this IP address. 167 | * 168 | * @param bool $long 169 | * 170 | * @return string 171 | * 172 | * @example if $long == false: if the decimal representation is '0.7.8.255': '0.7.010.0377' 173 | * @example if $long == true: if the decimal representation is '0.7.8.255': '0000.0007.0010.0377' 174 | */ 175 | public function toOctal($long = false) 176 | { 177 | $chunks = array(); 178 | foreach ($this->getBytes() as $byte) { 179 | if ($long) { 180 | $chunks[] = sprintf('%04o', $byte); 181 | } else { 182 | $chunks[] = '0' . decoct($byte); 183 | } 184 | } 185 | 186 | return implode('.', $chunks); 187 | } 188 | 189 | /** 190 | * Get the hexadecimal representation of this IP address. 191 | * 192 | * @param bool $long 193 | * 194 | * @return string 195 | * 196 | * @example if $long == false: if the decimal representation is '0.9.10.255': '0.9.0xa.0xff' 197 | * @example if $long == true: if the decimal representation is '0.9.10.255': '0x00.0x09.0x0a.0xff' 198 | */ 199 | public function toHexadecimal($long = false) 200 | { 201 | $chunks = array(); 202 | foreach ($this->getBytes() as $byte) { 203 | if ($long) { 204 | $chunks[] = sprintf('0x%02x', $byte); 205 | } else { 206 | $chunks[] = '0x' . dechex($byte); 207 | } 208 | } 209 | 210 | return implode('.', $chunks); 211 | } 212 | 213 | /** 214 | * {@inheritdoc} 215 | * 216 | * @see \IPLib\Address\AddressInterface::getBytes() 217 | */ 218 | public function getBytes() 219 | { 220 | if ($this->bytes === null) { 221 | $this->bytes = array_map( 222 | function ($chunk) { 223 | return (int) $chunk; 224 | }, 225 | explode('.', $this->address) 226 | ); 227 | } 228 | 229 | return $this->bytes; 230 | } 231 | 232 | /** 233 | * {@inheritdoc} 234 | * 235 | * @see \IPLib\Address\AddressInterface::getAddressType() 236 | */ 237 | public function getAddressType() 238 | { 239 | return Type::T_IPv4; 240 | } 241 | 242 | /** 243 | * {@inheritdoc} 244 | * 245 | * @see \IPLib\Address\AddressInterface::getDefaultReservedRangeType() 246 | */ 247 | public static function getDefaultReservedRangeType() 248 | { 249 | return RangeType::T_PUBLIC; 250 | } 251 | 252 | /** 253 | * {@inheritdoc} 254 | * 255 | * @see \IPLib\Address\AddressInterface::getReservedRanges() 256 | */ 257 | public static function getReservedRanges() 258 | { 259 | if (self::$reservedRanges === null) { 260 | $reservedRanges = array(); 261 | foreach (array( 262 | // RFC 5735 263 | '0.0.0.0/8' => array(RangeType::T_THISNETWORK, array('0.0.0.0/32' => RangeType::T_UNSPECIFIED)), 264 | // RFC 5735 265 | '10.0.0.0/8' => array(RangeType::T_PRIVATENETWORK), 266 | // RFC 6598 267 | '100.64.0.0/10' => array(RangeType::T_CGNAT), 268 | // RFC 5735 269 | '127.0.0.0/8' => array(RangeType::T_LOOPBACK), 270 | // RFC 5735 271 | '169.254.0.0/16' => array(RangeType::T_LINKLOCAL), 272 | // RFC 5735 273 | '172.16.0.0/12' => array(RangeType::T_PRIVATENETWORK), 274 | // RFC 5735 275 | '192.0.0.0/24' => array(RangeType::T_RESERVED), 276 | // RFC 5735 277 | '192.0.2.0/24' => array(RangeType::T_RESERVED), 278 | // RFC 5735 279 | '192.88.99.0/24' => array(RangeType::T_ANYCASTRELAY), 280 | // RFC 5735 281 | '192.168.0.0/16' => array(RangeType::T_PRIVATENETWORK), 282 | // RFC 5735 283 | '198.18.0.0/15' => array(RangeType::T_RESERVED), 284 | // RFC 5735 285 | '198.51.100.0/24' => array(RangeType::T_RESERVED), 286 | // RFC 5735 287 | '203.0.113.0/24' => array(RangeType::T_RESERVED), 288 | // RFC 5735 289 | '224.0.0.0/4' => array(RangeType::T_MULTICAST), 290 | // RFC 5735 291 | '240.0.0.0/4' => array(RangeType::T_RESERVED, array('255.255.255.255/32' => RangeType::T_LIMITEDBROADCAST)), 292 | ) as $range => $data) { 293 | $exceptions = array(); 294 | if (isset($data[1])) { 295 | foreach ($data[1] as $exceptionRange => $exceptionType) { 296 | $exceptions[] = new AssignedRange(Subnet::fromString($exceptionRange), $exceptionType); 297 | } 298 | } 299 | $reservedRanges[] = new AssignedRange(Subnet::fromString($range), $data[0], $exceptions); 300 | } 301 | self::$reservedRanges = $reservedRanges; 302 | } 303 | 304 | return self::$reservedRanges; 305 | } 306 | 307 | /** 308 | * {@inheritdoc} 309 | * 310 | * @see \IPLib\Address\AddressInterface::getRangeType() 311 | */ 312 | public function getRangeType() 313 | { 314 | if ($this->rangeType === null) { 315 | $rangeType = null; 316 | foreach (static::getReservedRanges() as $reservedRange) { 317 | $rangeType = $reservedRange->getAddressType($this); 318 | if ($rangeType !== null) { 319 | break; 320 | } 321 | } 322 | $this->rangeType = $rangeType === null ? static::getDefaultReservedRangeType() : $rangeType; 323 | } 324 | 325 | return $this->rangeType; 326 | } 327 | 328 | /** 329 | * Create an IPv6 representation of this address (in 6to4 notation). 330 | * 331 | * @return \IPLib\Address\IPv6 332 | */ 333 | public function toIPv6() 334 | { 335 | $myBytes = $this->getBytes(); 336 | 337 | return IPv6::fromString('2002:' . sprintf('%02x', $myBytes[0]) . sprintf('%02x', $myBytes[1]) . ':' . sprintf('%02x', $myBytes[2]) . sprintf('%02x', $myBytes[3]) . '::'); 338 | } 339 | 340 | /** 341 | * Create an IPv6 representation of this address (in IPv6 IPv4-mapped notation). 342 | * 343 | * @return \IPLib\Address\IPv6 344 | */ 345 | public function toIPv6IPv4Mapped() 346 | { 347 | return IPv6::fromBytes(array_merge(array(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff), $this->getBytes())); 348 | } 349 | 350 | /** 351 | * {@inheritdoc} 352 | * 353 | * @see \IPLib\Address\AddressInterface::getComparableString() 354 | */ 355 | public function getComparableString() 356 | { 357 | if ($this->comparableString === null) { 358 | $chunks = array(); 359 | foreach ($this->getBytes() as $byte) { 360 | $chunks[] = sprintf('%03d', $byte); 361 | } 362 | $this->comparableString = implode('.', $chunks); 363 | } 364 | 365 | return $this->comparableString; 366 | } 367 | 368 | /** 369 | * {@inheritdoc} 370 | * 371 | * @see \IPLib\Address\AddressInterface::matches() 372 | */ 373 | public function matches(RangeInterface $range) 374 | { 375 | return $range->contains($this); 376 | } 377 | 378 | /** 379 | * {@inheritdoc} 380 | * 381 | * @see \IPLib\Address\AddressInterface::getNextAddress() 382 | */ 383 | public function getNextAddress() 384 | { 385 | $overflow = false; 386 | $bytes = $this->getBytes(); 387 | for ($i = count($bytes) - 1; $i >= 0; $i--) { 388 | if ($bytes[$i] === 255) { 389 | if ($i === 0) { 390 | $overflow = true; 391 | break; 392 | } 393 | $bytes[$i] = 0; 394 | } else { 395 | $bytes[$i]++; 396 | break; 397 | } 398 | } 399 | 400 | return $overflow ? null : static::fromBytes($bytes); 401 | } 402 | 403 | /** 404 | * {@inheritdoc} 405 | * 406 | * @see \IPLib\Address\AddressInterface::getPreviousAddress() 407 | */ 408 | public function getPreviousAddress() 409 | { 410 | $overflow = false; 411 | $bytes = $this->getBytes(); 412 | for ($i = count($bytes) - 1; $i >= 0; $i--) { 413 | if ($bytes[$i] === 0) { 414 | if ($i === 0) { 415 | $overflow = true; 416 | break; 417 | } 418 | $bytes[$i] = 255; 419 | } else { 420 | $bytes[$i]--; 421 | break; 422 | } 423 | } 424 | 425 | return $overflow ? null : static::fromBytes($bytes); 426 | } 427 | 428 | /** 429 | * {@inheritdoc} 430 | * 431 | * @see \IPLib\Address\AddressInterface::getReverseDNSLookupName() 432 | */ 433 | public function getReverseDNSLookupName() 434 | { 435 | return implode( 436 | '.', 437 | array_reverse($this->getBytes()) 438 | ) . '.in-addr.arpa'; 439 | } 440 | } 441 | -------------------------------------------------------------------------------- /vendor/composer/ClassLoader.php: -------------------------------------------------------------------------------- 1 | 7 | * Jordi Boggiano 8 | * 9 | * For the full copyright and license information, please view the LICENSE 10 | * file that was distributed with this source code. 11 | */ 12 | 13 | namespace Composer\Autoload; 14 | 15 | /** 16 | * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. 17 | * 18 | * $loader = new \Composer\Autoload\ClassLoader(); 19 | * 20 | * // register classes with namespaces 21 | * $loader->add('Symfony\Component', __DIR__.'/component'); 22 | * $loader->add('Symfony', __DIR__.'/framework'); 23 | * 24 | * // activate the autoloader 25 | * $loader->register(); 26 | * 27 | * // to enable searching the include path (eg. for PEAR packages) 28 | * $loader->setUseIncludePath(true); 29 | * 30 | * In this example, if you try to use a class in the Symfony\Component 31 | * namespace or one of its children (Symfony\Component\Console for instance), 32 | * the autoloader will first look for the class under the component/ 33 | * directory, and it will then fallback to the framework/ directory if not 34 | * found before giving up. 35 | * 36 | * This class is loosely based on the Symfony UniversalClassLoader. 37 | * 38 | * @author Fabien Potencier 39 | * @author Jordi Boggiano 40 | * @see http://www.php-fig.org/psr/psr-0/ 41 | * @see http://www.php-fig.org/psr/psr-4/ 42 | */ 43 | class ClassLoader 44 | { 45 | // PSR-4 46 | private $prefixLengthsPsr4 = array(); 47 | private $prefixDirsPsr4 = array(); 48 | private $fallbackDirsPsr4 = array(); 49 | 50 | // PSR-0 51 | private $prefixesPsr0 = array(); 52 | private $fallbackDirsPsr0 = array(); 53 | 54 | private $useIncludePath = false; 55 | private $classMap = array(); 56 | private $classMapAuthoritative = false; 57 | private $missingClasses = array(); 58 | private $apcuPrefix; 59 | 60 | public function getPrefixes() 61 | { 62 | if (!empty($this->prefixesPsr0)) { 63 | return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); 64 | } 65 | 66 | return array(); 67 | } 68 | 69 | public function getPrefixesPsr4() 70 | { 71 | return $this->prefixDirsPsr4; 72 | } 73 | 74 | public function getFallbackDirs() 75 | { 76 | return $this->fallbackDirsPsr0; 77 | } 78 | 79 | public function getFallbackDirsPsr4() 80 | { 81 | return $this->fallbackDirsPsr4; 82 | } 83 | 84 | public function getClassMap() 85 | { 86 | return $this->classMap; 87 | } 88 | 89 | /** 90 | * @param array $classMap Class to filename map 91 | */ 92 | public function addClassMap(array $classMap) 93 | { 94 | if ($this->classMap) { 95 | $this->classMap = array_merge($this->classMap, $classMap); 96 | } else { 97 | $this->classMap = $classMap; 98 | } 99 | } 100 | 101 | /** 102 | * Registers a set of PSR-0 directories for a given prefix, either 103 | * appending or prepending to the ones previously set for this prefix. 104 | * 105 | * @param string $prefix The prefix 106 | * @param array|string $paths The PSR-0 root directories 107 | * @param bool $prepend Whether to prepend the directories 108 | */ 109 | public function add($prefix, $paths, $prepend = false) 110 | { 111 | if (!$prefix) { 112 | if ($prepend) { 113 | $this->fallbackDirsPsr0 = array_merge( 114 | (array) $paths, 115 | $this->fallbackDirsPsr0 116 | ); 117 | } else { 118 | $this->fallbackDirsPsr0 = array_merge( 119 | $this->fallbackDirsPsr0, 120 | (array) $paths 121 | ); 122 | } 123 | 124 | return; 125 | } 126 | 127 | $first = $prefix[0]; 128 | if (!isset($this->prefixesPsr0[$first][$prefix])) { 129 | $this->prefixesPsr0[$first][$prefix] = (array) $paths; 130 | 131 | return; 132 | } 133 | if ($prepend) { 134 | $this->prefixesPsr0[$first][$prefix] = array_merge( 135 | (array) $paths, 136 | $this->prefixesPsr0[$first][$prefix] 137 | ); 138 | } else { 139 | $this->prefixesPsr0[$first][$prefix] = array_merge( 140 | $this->prefixesPsr0[$first][$prefix], 141 | (array) $paths 142 | ); 143 | } 144 | } 145 | 146 | /** 147 | * Registers a set of PSR-4 directories for a given namespace, either 148 | * appending or prepending to the ones previously set for this namespace. 149 | * 150 | * @param string $prefix The prefix/namespace, with trailing '\\' 151 | * @param array|string $paths The PSR-4 base directories 152 | * @param bool $prepend Whether to prepend the directories 153 | * 154 | * @throws \InvalidArgumentException 155 | */ 156 | public function addPsr4($prefix, $paths, $prepend = false) 157 | { 158 | if (!$prefix) { 159 | // Register directories for the root namespace. 160 | if ($prepend) { 161 | $this->fallbackDirsPsr4 = array_merge( 162 | (array) $paths, 163 | $this->fallbackDirsPsr4 164 | ); 165 | } else { 166 | $this->fallbackDirsPsr4 = array_merge( 167 | $this->fallbackDirsPsr4, 168 | (array) $paths 169 | ); 170 | } 171 | } elseif (!isset($this->prefixDirsPsr4[$prefix])) { 172 | // Register directories for a new namespace. 173 | $length = strlen($prefix); 174 | if ('\\' !== $prefix[$length - 1]) { 175 | throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); 176 | } 177 | $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; 178 | $this->prefixDirsPsr4[$prefix] = (array) $paths; 179 | } elseif ($prepend) { 180 | // Prepend directories for an already registered namespace. 181 | $this->prefixDirsPsr4[$prefix] = array_merge( 182 | (array) $paths, 183 | $this->prefixDirsPsr4[$prefix] 184 | ); 185 | } else { 186 | // Append directories for an already registered namespace. 187 | $this->prefixDirsPsr4[$prefix] = array_merge( 188 | $this->prefixDirsPsr4[$prefix], 189 | (array) $paths 190 | ); 191 | } 192 | } 193 | 194 | /** 195 | * Registers a set of PSR-0 directories for a given prefix, 196 | * replacing any others previously set for this prefix. 197 | * 198 | * @param string $prefix The prefix 199 | * @param array|string $paths The PSR-0 base directories 200 | */ 201 | public function set($prefix, $paths) 202 | { 203 | if (!$prefix) { 204 | $this->fallbackDirsPsr0 = (array) $paths; 205 | } else { 206 | $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; 207 | } 208 | } 209 | 210 | /** 211 | * Registers a set of PSR-4 directories for a given namespace, 212 | * replacing any others previously set for this namespace. 213 | * 214 | * @param string $prefix The prefix/namespace, with trailing '\\' 215 | * @param array|string $paths The PSR-4 base directories 216 | * 217 | * @throws \InvalidArgumentException 218 | */ 219 | public function setPsr4($prefix, $paths) 220 | { 221 | if (!$prefix) { 222 | $this->fallbackDirsPsr4 = (array) $paths; 223 | } else { 224 | $length = strlen($prefix); 225 | if ('\\' !== $prefix[$length - 1]) { 226 | throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); 227 | } 228 | $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; 229 | $this->prefixDirsPsr4[$prefix] = (array) $paths; 230 | } 231 | } 232 | 233 | /** 234 | * Turns on searching the include path for class files. 235 | * 236 | * @param bool $useIncludePath 237 | */ 238 | public function setUseIncludePath($useIncludePath) 239 | { 240 | $this->useIncludePath = $useIncludePath; 241 | } 242 | 243 | /** 244 | * Can be used to check if the autoloader uses the include path to check 245 | * for classes. 246 | * 247 | * @return bool 248 | */ 249 | public function getUseIncludePath() 250 | { 251 | return $this->useIncludePath; 252 | } 253 | 254 | /** 255 | * Turns off searching the prefix and fallback directories for classes 256 | * that have not been registered with the class map. 257 | * 258 | * @param bool $classMapAuthoritative 259 | */ 260 | public function setClassMapAuthoritative($classMapAuthoritative) 261 | { 262 | $this->classMapAuthoritative = $classMapAuthoritative; 263 | } 264 | 265 | /** 266 | * Should class lookup fail if not found in the current class map? 267 | * 268 | * @return bool 269 | */ 270 | public function isClassMapAuthoritative() 271 | { 272 | return $this->classMapAuthoritative; 273 | } 274 | 275 | /** 276 | * APCu prefix to use to cache found/not-found classes, if the extension is enabled. 277 | * 278 | * @param string|null $apcuPrefix 279 | */ 280 | public function setApcuPrefix($apcuPrefix) 281 | { 282 | $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; 283 | } 284 | 285 | /** 286 | * The APCu prefix in use, or null if APCu caching is not enabled. 287 | * 288 | * @return string|null 289 | */ 290 | public function getApcuPrefix() 291 | { 292 | return $this->apcuPrefix; 293 | } 294 | 295 | /** 296 | * Registers this instance as an autoloader. 297 | * 298 | * @param bool $prepend Whether to prepend the autoloader or not 299 | */ 300 | public function register($prepend = false) 301 | { 302 | spl_autoload_register(array($this, 'loadClass'), true, $prepend); 303 | } 304 | 305 | /** 306 | * Unregisters this instance as an autoloader. 307 | */ 308 | public function unregister() 309 | { 310 | spl_autoload_unregister(array($this, 'loadClass')); 311 | } 312 | 313 | /** 314 | * Loads the given class or interface. 315 | * 316 | * @param string $class The name of the class 317 | * @return bool|null True if loaded, null otherwise 318 | */ 319 | public function loadClass($class) 320 | { 321 | if ($file = $this->findFile($class)) { 322 | includeFile($file); 323 | 324 | return true; 325 | } 326 | } 327 | 328 | /** 329 | * Finds the path to the file where the class is defined. 330 | * 331 | * @param string $class The name of the class 332 | * 333 | * @return string|false The path if found, false otherwise 334 | */ 335 | public function findFile($class) 336 | { 337 | // class map lookup 338 | if (isset($this->classMap[$class])) { 339 | return $this->classMap[$class]; 340 | } 341 | if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { 342 | return false; 343 | } 344 | if (null !== $this->apcuPrefix) { 345 | $file = apcu_fetch($this->apcuPrefix.$class, $hit); 346 | if ($hit) { 347 | return $file; 348 | } 349 | } 350 | 351 | $file = $this->findFileWithExtension($class, '.php'); 352 | 353 | // Search for Hack files if we are running on HHVM 354 | if (false === $file && defined('HHVM_VERSION')) { 355 | $file = $this->findFileWithExtension($class, '.hh'); 356 | } 357 | 358 | if (null !== $this->apcuPrefix) { 359 | apcu_add($this->apcuPrefix.$class, $file); 360 | } 361 | 362 | if (false === $file) { 363 | // Remember that this class does not exist. 364 | $this->missingClasses[$class] = true; 365 | } 366 | 367 | return $file; 368 | } 369 | 370 | private function findFileWithExtension($class, $ext) 371 | { 372 | // PSR-4 lookup 373 | $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; 374 | 375 | $first = $class[0]; 376 | if (isset($this->prefixLengthsPsr4[$first])) { 377 | $subPath = $class; 378 | while (false !== $lastPos = strrpos($subPath, '\\')) { 379 | $subPath = substr($subPath, 0, $lastPos); 380 | $search = $subPath . '\\'; 381 | if (isset($this->prefixDirsPsr4[$search])) { 382 | $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); 383 | foreach ($this->prefixDirsPsr4[$search] as $dir) { 384 | if (file_exists($file = $dir . $pathEnd)) { 385 | return $file; 386 | } 387 | } 388 | } 389 | } 390 | } 391 | 392 | // PSR-4 fallback dirs 393 | foreach ($this->fallbackDirsPsr4 as $dir) { 394 | if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { 395 | return $file; 396 | } 397 | } 398 | 399 | // PSR-0 lookup 400 | if (false !== $pos = strrpos($class, '\\')) { 401 | // namespaced class name 402 | $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) 403 | . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); 404 | } else { 405 | // PEAR-like class name 406 | $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; 407 | } 408 | 409 | if (isset($this->prefixesPsr0[$first])) { 410 | foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { 411 | if (0 === strpos($class, $prefix)) { 412 | foreach ($dirs as $dir) { 413 | if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { 414 | return $file; 415 | } 416 | } 417 | } 418 | } 419 | } 420 | 421 | // PSR-0 fallback dirs 422 | foreach ($this->fallbackDirsPsr0 as $dir) { 423 | if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { 424 | return $file; 425 | } 426 | } 427 | 428 | // PSR-0 include paths. 429 | if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { 430 | return $file; 431 | } 432 | 433 | return false; 434 | } 435 | } 436 | 437 | /** 438 | * Scope isolated include. 439 | * 440 | * Prevents access to $this/self from included files. 441 | */ 442 | function includeFile($file) 443 | { 444 | include $file; 445 | } 446 | -------------------------------------------------------------------------------- /vendor/mlocati/ip-lib/src/Address/IPv6.php: -------------------------------------------------------------------------------- 1 | longAddress = $longAddress; 68 | $this->shortAddress = null; 69 | $this->bytes = null; 70 | $this->words = null; 71 | $this->rangeType = null; 72 | } 73 | 74 | /** 75 | * {@inheritdoc} 76 | * 77 | * @see \IPLib\Address\AddressInterface::__toString() 78 | */ 79 | public function __toString() 80 | { 81 | return $this->toString(); 82 | } 83 | 84 | /** 85 | * Parse a string and returns an IPv6 instance if the string is valid, or null otherwise. 86 | * 87 | * @param string|mixed $address the address to parse 88 | * @param bool $mayIncludePort set to false to avoid parsing addresses with ports 89 | * @param bool $mayIncludeZoneID set to false to avoid parsing addresses with zone IDs (see RFC 4007) 90 | * 91 | * @return static|null 92 | */ 93 | public static function fromString($address, $mayIncludePort = true, $mayIncludeZoneID = true) 94 | { 95 | $result = null; 96 | if (is_string($address) && strpos($address, ':') !== false && strpos($address, ':::') === false) { 97 | $matches = null; 98 | if ($mayIncludePort && $address[0] === '[' && preg_match('/^\[(.+)]:\d+$/', $address, $matches)) { 99 | $address = $matches[1]; 100 | } 101 | if ($mayIncludeZoneID) { 102 | $percentagePos = strpos($address, '%'); 103 | if ($percentagePos > 0) { 104 | $address = substr($address, 0, $percentagePos); 105 | } 106 | } 107 | if (preg_match('/^((?:[0-9a-f]*:+)+)(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/i', $address, $matches)) { 108 | $address6 = static::fromString($matches[1] . '0:0', false); 109 | if ($address6 !== null) { 110 | $address4 = IPv4::fromString($matches[2], false); 111 | if ($address4 !== null) { 112 | $bytes4 = $address4->getBytes(); 113 | $address6->longAddress = substr($address6->longAddress, 0, -9) . sprintf('%02x%02x:%02x%02x', $bytes4[0], $bytes4[1], $bytes4[2], $bytes4[3]); 114 | $result = $address6; 115 | } 116 | } 117 | } else { 118 | if (strpos($address, '::') === false) { 119 | $chunks = explode(':', $address); 120 | } else { 121 | $chunks = array(); 122 | $parts = explode('::', $address); 123 | if (count($parts) === 2) { 124 | $before = ($parts[0] === '') ? array() : explode(':', $parts[0]); 125 | $after = ($parts[1] === '') ? array() : explode(':', $parts[1]); 126 | $missing = 8 - count($before) - count($after); 127 | if ($missing >= 0) { 128 | $chunks = $before; 129 | if ($missing !== 0) { 130 | $chunks = array_merge($chunks, array_fill(0, $missing, '0')); 131 | } 132 | $chunks = array_merge($chunks, $after); 133 | } 134 | } 135 | } 136 | if (count($chunks) === 8) { 137 | $nums = array_map( 138 | function ($chunk) { 139 | return preg_match('/^[0-9A-Fa-f]{1,4}$/', $chunk) ? hexdec($chunk) : false; 140 | }, 141 | $chunks 142 | ); 143 | if (!in_array(false, $nums, true)) { 144 | $longAddress = implode( 145 | ':', 146 | array_map( 147 | function ($num) { 148 | return sprintf('%04x', $num); 149 | }, 150 | $nums 151 | ) 152 | ); 153 | $result = new static($longAddress); 154 | } 155 | } 156 | } 157 | } 158 | 159 | return $result; 160 | } 161 | 162 | /** 163 | * Parse an array of bytes and returns an IPv6 instance if the array is valid, or null otherwise. 164 | * 165 | * @param int[]|array $bytes 166 | * 167 | * @return static|null 168 | */ 169 | public static function fromBytes(array $bytes) 170 | { 171 | $result = null; 172 | if (count($bytes) === 16) { 173 | $address = ''; 174 | for ($i = 0; $i < 16; $i++) { 175 | if ($i !== 0 && $i % 2 === 0) { 176 | $address .= ':'; 177 | } 178 | $byte = $bytes[$i]; 179 | if (is_int($byte) && $byte >= 0 && $byte <= 255) { 180 | $address .= sprintf('%02x', $byte); 181 | } else { 182 | $address = null; 183 | break; 184 | } 185 | } 186 | if ($address !== null) { 187 | $result = new static($address); 188 | } 189 | } 190 | 191 | return $result; 192 | } 193 | 194 | /** 195 | * Parse an array of words and returns an IPv6 instance if the array is valid, or null otherwise. 196 | * 197 | * @param int[]|array $words 198 | * 199 | * @return static|null 200 | */ 201 | public static function fromWords(array $words) 202 | { 203 | $result = null; 204 | if (count($words) === 8) { 205 | $chunks = array(); 206 | for ($i = 0; $i < 8; $i++) { 207 | $word = $words[$i]; 208 | if (is_int($word) && $word >= 0 && $word <= 0xffff) { 209 | $chunks[] = sprintf('%04x', $word); 210 | } else { 211 | $chunks = null; 212 | break; 213 | } 214 | } 215 | if ($chunks !== null) { 216 | $result = new static(implode(':', $chunks)); 217 | } 218 | } 219 | 220 | return $result; 221 | } 222 | 223 | /** 224 | * {@inheritdoc} 225 | * 226 | * @see \IPLib\Address\AddressInterface::toString() 227 | */ 228 | public function toString($long = false) 229 | { 230 | if ($long) { 231 | $result = $this->longAddress; 232 | } else { 233 | if ($this->shortAddress === null) { 234 | if (strpos($this->longAddress, '0000:0000:0000:0000:0000:ffff:') === 0) { 235 | $lastBytes = array_slice($this->getBytes(), -4); 236 | $this->shortAddress = '::ffff:' . implode('.', $lastBytes); 237 | } else { 238 | $chunks = array_map( 239 | function ($word) { 240 | return dechex($word); 241 | }, 242 | $this->getWords() 243 | ); 244 | $shortAddress = implode(':', $chunks); 245 | $matches = null; 246 | for ($i = 8; $i > 1; $i--) { 247 | $search = '(?:^|:)' . rtrim(str_repeat('0:', $i), ':') . '(?:$|:)'; 248 | if (preg_match('/^(.*?)' . $search . '(.*)$/', $shortAddress, $matches)) { 249 | $shortAddress = $matches[1] . '::' . $matches[2]; 250 | break; 251 | } 252 | } 253 | $this->shortAddress = $shortAddress; 254 | } 255 | } 256 | $result = $this->shortAddress; 257 | } 258 | 259 | return $result; 260 | } 261 | 262 | /** 263 | * {@inheritdoc} 264 | * 265 | * @see \IPLib\Address\AddressInterface::getBytes() 266 | */ 267 | public function getBytes() 268 | { 269 | if ($this->bytes === null) { 270 | $bytes = array(); 271 | foreach ($this->getWords() as $word) { 272 | $bytes[] = $word >> 8; 273 | $bytes[] = $word & 0xff; 274 | } 275 | $this->bytes = $bytes; 276 | } 277 | 278 | return $this->bytes; 279 | } 280 | 281 | /** 282 | * Get the word list of the IP address. 283 | * 284 | * @return int[] 285 | */ 286 | public function getWords() 287 | { 288 | if ($this->words === null) { 289 | $this->words = array_map( 290 | function ($chunk) { 291 | return hexdec($chunk); 292 | }, 293 | explode(':', $this->longAddress) 294 | ); 295 | } 296 | 297 | return $this->words; 298 | } 299 | 300 | /** 301 | * {@inheritdoc} 302 | * 303 | * @see \IPLib\Address\AddressInterface::getAddressType() 304 | */ 305 | public function getAddressType() 306 | { 307 | return Type::T_IPv6; 308 | } 309 | 310 | /** 311 | * {@inheritdoc} 312 | * 313 | * @see \IPLib\Address\AddressInterface::getDefaultReservedRangeType() 314 | */ 315 | public static function getDefaultReservedRangeType() 316 | { 317 | return RangeType::T_RESERVED; 318 | } 319 | 320 | /** 321 | * {@inheritdoc} 322 | * 323 | * @see \IPLib\Address\AddressInterface::getReservedRanges() 324 | */ 325 | public static function getReservedRanges() 326 | { 327 | if (self::$reservedRanges === null) { 328 | $reservedRanges = array(); 329 | foreach (array( 330 | // RFC 4291 331 | '::/128' => array(RangeType::T_UNSPECIFIED), 332 | // RFC 4291 333 | '::1/128' => array(RangeType::T_LOOPBACK), 334 | // RFC 4291 335 | '100::/8' => array(RangeType::T_DISCARD, array('100::/64' => RangeType::T_DISCARDONLY)), 336 | //'2002::/16' => array(RangeType::), 337 | // RFC 4291 338 | '2000::/3' => array(RangeType::T_PUBLIC), 339 | // RFC 4193 340 | 'fc00::/7' => array(RangeType::T_PRIVATENETWORK), 341 | // RFC 4291 342 | 'fe80::/10' => array(RangeType::T_LINKLOCAL_UNICAST), 343 | // RFC 4291 344 | 'ff00::/8' => array(RangeType::T_MULTICAST), 345 | // RFC 4291 346 | //'::/8' => array(RangeType::T_RESERVED), 347 | // RFC 4048 348 | //'200::/7' => array(RangeType::T_RESERVED), 349 | // RFC 4291 350 | //'400::/6' => array(RangeType::T_RESERVED), 351 | // RFC 4291 352 | //'800::/5' => array(RangeType::T_RESERVED), 353 | // RFC 4291 354 | //'1000::/4' => array(RangeType::T_RESERVED), 355 | // RFC 4291 356 | //'4000::/3' => array(RangeType::T_RESERVED), 357 | // RFC 4291 358 | //'6000::/3' => array(RangeType::T_RESERVED), 359 | // RFC 4291 360 | //'8000::/3' => array(RangeType::T_RESERVED), 361 | // RFC 4291 362 | //'a000::/3' => array(RangeType::T_RESERVED), 363 | // RFC 4291 364 | //'c000::/3' => array(RangeType::T_RESERVED), 365 | // RFC 4291 366 | //'e000::/4' => array(RangeType::T_RESERVED), 367 | // RFC 4291 368 | //'f000::/5' => array(RangeType::T_RESERVED), 369 | // RFC 4291 370 | //'f800::/6' => array(RangeType::T_RESERVED), 371 | // RFC 4291 372 | //'fe00::/9' => array(RangeType::T_RESERVED), 373 | // RFC 3879 374 | //'fec0::/10' => array(RangeType::T_RESERVED), 375 | ) as $range => $data) { 376 | $exceptions = array(); 377 | if (isset($data[1])) { 378 | foreach ($data[1] as $exceptionRange => $exceptionType) { 379 | $exceptions[] = new AssignedRange(Subnet::fromString($exceptionRange), $exceptionType); 380 | } 381 | } 382 | $reservedRanges[] = new AssignedRange(Subnet::fromString($range), $data[0], $exceptions); 383 | } 384 | self::$reservedRanges = $reservedRanges; 385 | } 386 | 387 | return self::$reservedRanges; 388 | } 389 | 390 | /** 391 | * {@inheritdoc} 392 | * 393 | * @see \IPLib\Address\AddressInterface::getRangeType() 394 | */ 395 | public function getRangeType() 396 | { 397 | if ($this->rangeType === null) { 398 | $ipv4 = $this->toIPv4(); 399 | if ($ipv4 !== null) { 400 | $this->rangeType = $ipv4->getRangeType(); 401 | } else { 402 | $rangeType = null; 403 | foreach (static::getReservedRanges() as $reservedRange) { 404 | $rangeType = $reservedRange->getAddressType($this); 405 | if ($rangeType !== null) { 406 | break; 407 | } 408 | } 409 | $this->rangeType = $rangeType === null ? static::getDefaultReservedRangeType() : $rangeType; 410 | } 411 | } 412 | 413 | return $this->rangeType; 414 | } 415 | 416 | /** 417 | * Create an IPv4 representation of this address (if possible, otherwise returns null). 418 | * 419 | * @return \IPLib\Address\IPv4|null 420 | */ 421 | public function toIPv4() 422 | { 423 | if (strpos($this->longAddress, '2002:') === 0) { 424 | // 6to4 425 | return IPv4::fromBytes(array_slice($this->getBytes(), 2, 4)); 426 | } 427 | if (strpos($this->longAddress, '0000:0000:0000:0000:0000:ffff:') === 0) { 428 | // IPv4-mapped IPv6 addresses 429 | return IPv4::fromBytes(array_slice($this->getBytes(), -4)); 430 | } 431 | 432 | return null; 433 | } 434 | 435 | /** 436 | * Render this IPv6 address in the "mixed" IPv6 (first 12 bytes) + IPv4 (last 4 bytes) mixed syntax. 437 | * 438 | * @param bool $ipV6Long render the IPv6 part in "long" format? 439 | * @param bool $ipV4Long render the IPv4 part in "long" format? 440 | * 441 | * @return string 442 | * 443 | * @example '::13.1.68.3' 444 | * @example '0000:0000:0000:0000:0000:0000:13.1.68.3' when $ipV6Long is true 445 | * @example '::013.001.068.003' when $ipV4Long is true 446 | * @example '0000:0000:0000:0000:0000:0000:013.001.068.003' when $ipV6Long and $ipV4Long are true 447 | * 448 | * @see https://tools.ietf.org/html/rfc4291#section-2.2 point 3. 449 | */ 450 | public function toMixedIPv6IPv4String($ipV6Long = false, $ipV4Long = false) 451 | { 452 | $myBytes = $this->getBytes(); 453 | $ipv6Bytes = array_merge(array_slice($myBytes, 0, 12), array(0xff, 0xff, 0xff, 0xff)); 454 | $ipv6String = static::fromBytes($ipv6Bytes)->toString($ipV6Long); 455 | $ipv4Bytes = array_slice($myBytes, 12, 4); 456 | $ipv4String = IPv4::fromBytes($ipv4Bytes)->toString($ipV4Long); 457 | 458 | return preg_replace('/((ffff:ffff)|(\d+(\.\d+){3}))$/i', $ipv4String, $ipv6String); 459 | } 460 | 461 | /** 462 | * {@inheritdoc} 463 | * 464 | * @see \IPLib\Address\AddressInterface::getComparableString() 465 | */ 466 | public function getComparableString() 467 | { 468 | return $this->longAddress; 469 | } 470 | 471 | /** 472 | * {@inheritdoc} 473 | * 474 | * @see \IPLib\Address\AddressInterface::matches() 475 | */ 476 | public function matches(RangeInterface $range) 477 | { 478 | return $range->contains($this); 479 | } 480 | 481 | /** 482 | * {@inheritdoc} 483 | * 484 | * @see \IPLib\Address\AddressInterface::getNextAddress() 485 | */ 486 | public function getNextAddress() 487 | { 488 | $overflow = false; 489 | $words = $this->getWords(); 490 | for ($i = count($words) - 1; $i >= 0; $i--) { 491 | if ($words[$i] === 0xffff) { 492 | if ($i === 0) { 493 | $overflow = true; 494 | break; 495 | } 496 | $words[$i] = 0; 497 | } else { 498 | $words[$i]++; 499 | break; 500 | } 501 | } 502 | 503 | return $overflow ? null : static::fromWords($words); 504 | } 505 | 506 | /** 507 | * {@inheritdoc} 508 | * 509 | * @see \IPLib\Address\AddressInterface::getPreviousAddress() 510 | */ 511 | public function getPreviousAddress() 512 | { 513 | $overflow = false; 514 | $words = $this->getWords(); 515 | for ($i = count($words) - 1; $i >= 0; $i--) { 516 | if ($words[$i] === 0) { 517 | if ($i === 0) { 518 | $overflow = true; 519 | break; 520 | } 521 | $words[$i] = 0xffff; 522 | } else { 523 | $words[$i]--; 524 | break; 525 | } 526 | } 527 | 528 | return $overflow ? null : static::fromWords($words); 529 | } 530 | 531 | /** 532 | * {@inheritdoc} 533 | * 534 | * @see \IPLib\Address\AddressInterface::getReverseDNSLookupName() 535 | */ 536 | public function getReverseDNSLookupName() 537 | { 538 | return implode( 539 | '.', 540 | array_reverse(str_split(str_replace(':', '', $this->toString(true)), 1)) 541 | ) . '.ip6.arpa'; 542 | } 543 | } 544 | --------------------------------------------------------------------------------