Config
4 months ago
Db
3 months ago
Handler
2 years ago
Visit
1 month ago
Action.php
3 months ago
ActionPageview.php
2 years ago
BotRequest.php
3 months ago
BotRequestProcessor.php
1 month ago
Cache.php
6 months ago
Db.php
1 year ago
Failures.php
6 months ago
FingerprintSalt.php
1 year ago
GoalManager.php
1 month ago
Handler.php
2 years ago
IgnoreCookie.php
1 year ago
LogTable.php
1 year ago
Model.php
6 months ago
PageUrl.php
2 weeks ago
Request.php
1 month ago
RequestHandlerTrait.php
4 months ago
RequestProcessor.php
1 month ago
RequestSet.php
6 months ago
Response.php
3 months ago
ScheduledTasksRunner.php
1 year ago
Settings.php
3 months ago
TableLogAction.php
6 months ago
TrackerCodeGenerator.php
1 year ago
TrackerConfig.php
1 month ago
Visit.php
3 months ago
VisitExcluded.php
3 months ago
VisitInterface.php
3 months ago
Visitor.php
1 month ago
VisitorNotFoundInDb.php
1 month ago
VisitorRecognizer.php
1 year ago
Settings.php
128 lines
| 1 | <?php |
| 2 | |
| 3 | /** |
| 4 | * Matomo - free/libre analytics platform |
| 5 | * |
| 6 | * @link https://matomo.org |
| 7 | * @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later |
| 8 | */ |
| 9 | namespace Piwik\Tracker; |
| 10 | |
| 11 | use Piwik\Config; |
| 12 | use Piwik\Container\StaticContainer; |
| 13 | use Piwik\Date; |
| 14 | use Piwik\Tracker; |
| 15 | use Piwik\DeviceDetector\DeviceDetectorFactory; |
| 16 | use Piwik\SettingsPiwik; |
| 17 | class Settings |
| 18 | { |
| 19 | public const OS_BOT = 'BOT'; |
| 20 | /** |
| 21 | * If `true`, the config ID for a visitor will be the same no matter what site is being tracked. |
| 22 | * If `false, the config ID will be different. |
| 23 | * |
| 24 | * @var bool |
| 25 | */ |
| 26 | private $isSameFingerprintsAcrossWebsites; |
| 27 | public function __construct($isSameFingerprintsAcrossWebsites) |
| 28 | { |
| 29 | $this->isSameFingerprintsAcrossWebsites = $isSameFingerprintsAcrossWebsites; |
| 30 | } |
| 31 | public function getConfigId(\Piwik\Tracker\Request $request, $ipAddress) : string |
| 32 | { |
| 33 | list($plugin_Flash, $plugin_Java, $plugin_Quicktime, $plugin_RealPlayer, $plugin_PDF, $plugin_WindowsMedia, $plugin_Silverlight, $plugin_Cookie) = $request->getPlugins(); |
| 34 | $userAgent = $request->getUserAgent(); |
| 35 | $deviceDetector = StaticContainer::get(DeviceDetectorFactory::class)->makeInstance($userAgent, $request->getClientHints()); |
| 36 | $aBrowserInfo = $deviceDetector->getClient(); |
| 37 | if (empty($aBrowserInfo['type']) || 'browser' !== $aBrowserInfo['type']) { |
| 38 | // for now only track browsers |
| 39 | unset($aBrowserInfo); |
| 40 | } |
| 41 | $browserName = !empty($aBrowserInfo['short_name']) ? $aBrowserInfo['short_name'] : 'UNK'; |
| 42 | $browserVersion = !empty($aBrowserInfo['version']) ? $aBrowserInfo['version'] : ''; |
| 43 | if ($deviceDetector->isBot()) { |
| 44 | $os = self::OS_BOT; |
| 45 | } else { |
| 46 | $os = $deviceDetector->getOS(); |
| 47 | $os = empty($os['short_name']) ? 'UNK' : $os['short_name']; |
| 48 | } |
| 49 | $client = $deviceDetector->getClient(); |
| 50 | if (!empty($client['name']) && $client['name'] === 'Internet Explorer') { |
| 51 | // we assume cookies are disabled... when in tracker cookies are disabled, this ensures when upgrading to this version |
| 52 | // that no fingerprint changes in the 30min window during the upgrade... |
| 53 | // We don't include it anymore as it otherwise may cause new visits to be created when switching between |
| 54 | // cookies disabled and enabled in IE11 or older. Before Matomo 3.13.7 when cookies were disabled, then |
| 55 | // this value was set to 0. For people with cookies enabled the fingerprint is not as relevant as the visitorId |
| 56 | // is used to identify a visitor |
| 57 | $plugin_Cookie = '0'; |
| 58 | } |
| 59 | $browserLang = substr($request->getBrowserLanguage(), 0, 20); |
| 60 | // limit the length of this string to match db |
| 61 | $trackerConfig = Config::getInstance()->Tracker; |
| 62 | $fingerprintSalt = ''; |
| 63 | // fingerprint salt won't work when across multiple sites since all sites could have different timezones |
| 64 | // also cant add fingerprint salt for a specific day when we dont create new visit after midnight |
| 65 | if (!$this->isSameFingerprintsAcrossWebsites && !empty($trackerConfig['create_new_visit_after_midnight'])) { |
| 66 | $cache = \Piwik\Tracker\Cache::getCacheWebsiteAttributes($request->getIdSite()); |
| 67 | $date = Date::factory((int) $request->getCurrentTimestamp()); |
| 68 | $fingerprintSaltKey = new \Piwik\Tracker\FingerprintSalt(); |
| 69 | $dateString = $fingerprintSaltKey->getDateString($date, $cache['timezone']); |
| 70 | if (!empty($cache[\Piwik\Tracker\FingerprintSalt::OPTION_PREFIX . $dateString])) { |
| 71 | $fingerprintSalt = $cache[\Piwik\Tracker\FingerprintSalt::OPTION_PREFIX . $dateString]; |
| 72 | } else { |
| 73 | // we query the DB directly for requests older than 2-3 days... |
| 74 | $fingerprintSalt = $fingerprintSaltKey->getSalt($dateString, $request->getIdSite()); |
| 75 | } |
| 76 | $fingerprintSalt .= $dateString; |
| 77 | if (defined('PIWIK_TEST_MODE') && PIWIK_TEST_MODE) { |
| 78 | $fingerprintSalt = ''; |
| 79 | // use fixed value so they don't change randomly in tests |
| 80 | } |
| 81 | } |
| 82 | return $this->getConfigHash($request, $os, $browserName, $browserVersion, $plugin_Flash, $plugin_Java, $plugin_Quicktime, $plugin_RealPlayer, $plugin_PDF, $plugin_WindowsMedia, $plugin_Silverlight, $plugin_Cookie, $ipAddress, $browserLang, $fingerprintSalt); |
| 83 | } |
| 84 | public function getRandomConfigId() : string |
| 85 | { |
| 86 | return $this->getRandomConfigHash(); |
| 87 | } |
| 88 | /** |
| 89 | * Returns a 64-bit hash that attempts to identify a user. |
| 90 | * Maintaining some privacy by default, eg. prevents the merging of several Piwik serve together for matching across instances.. |
| 91 | * |
| 92 | * @param $os |
| 93 | * @param $browserName |
| 94 | * @param $browserVersion |
| 95 | * @param $plugin_Flash |
| 96 | * @param $plugin_Java |
| 97 | * @param $plugin_Quicktime |
| 98 | * @param $plugin_RealPlayer |
| 99 | * @param $plugin_PDF |
| 100 | * @param $plugin_WindowsMedia |
| 101 | * @param $plugin_Silverlight |
| 102 | * @param $plugin_Cookie |
| 103 | * @param $ip |
| 104 | * @param $browserLang |
| 105 | * @param $fingerprintHash |
| 106 | */ |
| 107 | protected function getConfigHash(\Piwik\Tracker\Request $request, $os, $browserName, $browserVersion, $plugin_Flash, $plugin_Java, $plugin_Quicktime, $plugin_RealPlayer, $plugin_PDF, $plugin_WindowsMedia, $plugin_Silverlight, $plugin_Cookie, $ip, $browserLang, $fingerprintHash) : string |
| 108 | { |
| 109 | // prevent the config hash from being the same, across different Piwik instances |
| 110 | // (limits ability of different Piwik instances to cross-match users) |
| 111 | $salt = SettingsPiwik::getSalt(); |
| 112 | $configString = $os . $browserName . $browserVersion . $plugin_Flash . $plugin_Java . '0' . $plugin_Quicktime . $plugin_RealPlayer . $plugin_PDF . $plugin_WindowsMedia . '0' . $plugin_Silverlight . $plugin_Cookie . $ip . $browserLang . $salt . $fingerprintHash; |
| 113 | if (!$this->isSameFingerprintsAcrossWebsites) { |
| 114 | $configString .= $request->getIdSite(); |
| 115 | } |
| 116 | return $this->createHashOfConfigString($configString); |
| 117 | } |
| 118 | protected function getRandomConfigHash() : string |
| 119 | { |
| 120 | return $this->createHashOfConfigString(random_bytes(64)); |
| 121 | } |
| 122 | private function createHashOfConfigString(string $configString) : string |
| 123 | { |
| 124 | $hash = md5($configString, $raw_output = \true); |
| 125 | return substr($hash, 0, Tracker::LENGTH_BINARY_ID); |
| 126 | } |
| 127 | } |
| 128 |