PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 5.8.0
Defender Security – Malware Scanner, Login Security & Firewall v5.8.0
6.3.0 6.2.3 6.2.4 6.2.0 6.2.1 6.2.2 6.1.0 5.3.1 5.4.0 5.4.1 5.5.0 5.5.1 5.6.0 5.6.1 5.6.2 5.7.0 5.7.1 5.7.2 5.8.0 5.8.1 5.9.0 6.0.0 6.0.1 3.0.1 3.1.0 All 141 releases
defender-security / vendor / ramsey / uuid / src / Provider / Node / SystemNodeProvider.php

SystemNodeProvider.php in Defender Security – Malware Scanner, Login Security & Firewall 5.8.0, at vendor/ramsey/uuid/src/Provider/Node/SystemNodeProvider.php

185 lines 4.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * This file is part of the ramsey/uuid library
5 *
6 * For the full copyright and license information, please view the LICENSE
7 * file that was distributed with this source code.
8 *
9 * @copyright Copyright (c) Ben Ramsey <[email protected]>
10 * @license http://opensource.org/licenses/MIT MIT
11 */
12
13 declare(strict_types=1);
14
15 namespace Ramsey\Uuid\Provider\Node;
16
17 use Ramsey\Uuid\Exception\NodeException;
18 use Ramsey\Uuid\Provider\NodeProviderInterface;
19 use Ramsey\Uuid\Type\Hexadecimal;
20
21 use function array_filter;
22 use function array_map;
23 use function array_walk;
24 use function count;
25 use function ob_get_clean;
26 use function ob_start;
27 use function preg_match;
28 use function preg_match_all;
29 use function reset;
30 use function str_contains;
31 use function str_replace;
32 use function strtolower;
33 use function strtoupper;
34 use function substr;
35
36 use const GLOB_NOSORT;
37 use const PREG_PATTERN_ORDER;
38
39 /**
40 * SystemNodeProvider retrieves the system node ID, if possible
41 *
42 * The system node ID, or host ID, is often the same as the MAC address for a network interface on the host.
43 */
44 class SystemNodeProvider implements NodeProviderInterface
45 {
46 /**
47 * Pattern to match nodes in `ifconfig` and `ipconfig` output.
48 */
49 private const IFCONFIG_PATTERN = '/[^:]([0-9a-f]{2}([:-])[0-9a-f]{2}(\2[0-9a-f]{2}){4})[^:]/i';
50
51 /**
52 * Pattern to match nodes in sysfs stream output.
53 */
54 private const SYSFS_PATTERN = '/^([0-9a-f]{2}:){5}[0-9a-f]{2}$/i';
55
56 public function getNode(): Hexadecimal
57 {
58 $node = $this->getNodeFromSystem();
59
60 if ($node === '') {
61 throw new NodeException('Unable to fetch a node for this system');
62 }
63
64 return new Hexadecimal($node);
65 }
66
67 /**
68 * Returns the system node if found
69 */
70 protected function getNodeFromSystem(): string
71 {
72 /** @var string | null $node */
73 static $node = null;
74
75 if ($node !== null) {
76 return $node;
77 }
78
79 // First, try a Linux-specific approach.
80 $node = $this->getSysfs();
81
82 if ($node === '') {
83 // Search ifconfig output for MAC addresses & return the first one.
84 $node = $this->getIfconfig();
85 }
86
87 $node = str_replace([':', '-'], '', $node);
88
89 return $node;
90 }
91
92 /**
93 * Returns the network interface configuration for the system
94 *
95 * @codeCoverageIgnore
96 */
97 protected function getIfconfig(): string
98 {
99 if (str_contains(strtolower((string) ini_get('disable_functions')), 'passthru')) {
100 return '';
101 }
102
103 /** @var string $phpOs */
104 $phpOs = constant('PHP_OS');
105
106 ob_start();
107 switch (strtoupper(substr($phpOs, 0, 3))) {
108 case 'WIN':
109 passthru('ipconfig /all 2>&1');
110
111 break;
112 case 'DAR':
113 passthru('ifconfig 2>&1');
114
115 break;
116 case 'FRE':
117 passthru('netstat -i -f link 2>&1');
118
119 break;
120 case 'LIN':
121 default:
122 passthru('netstat -ie 2>&1');
123
124 break;
125 }
126
127 $ifconfig = (string) ob_get_clean();
128
129 if (preg_match_all(self::IFCONFIG_PATTERN, $ifconfig, $matches, PREG_PATTERN_ORDER)) {
130 foreach ($matches[1] as $iface) {
131 if ($iface !== '00:00:00:00:00:00' && $iface !== '00-00-00-00-00-00') {
132 return $iface;
133 }
134 }
135 }
136
137 return '';
138 }
139
140 /**
141 * Returns MAC address from the first system interface via the sysfs interface
142 */
143 protected function getSysfs(): string
144 {
145 /** @var string $phpOs */
146 $phpOs = constant('PHP_OS');
147
148 if (strtoupper($phpOs) !== 'LINUX') {
149 return '';
150 }
151
152 $addressPaths = glob('/sys/class/net/*/address', GLOB_NOSORT);
153
154 if ($addressPaths === false || count($addressPaths) === 0) {
155 return '';
156 }
157
158 /** @var array<array-key, string> $macs */
159 $macs = [];
160
161 array_walk($addressPaths, function (string $addressPath) use (&$macs): void {
162 if (is_readable($addressPath)) {
163 $macs[] = file_get_contents($addressPath);
164 }
165 });
166
167 /** @var callable $trim */
168 $trim = 'trim';
169
170 $macs = array_map($trim, $macs);
171
172 // Remove invalid entries.
173 $macs = array_filter($macs, function (mixed $address): bool {
174 assert(is_string($address));
175
176 return $address !== '00:00:00:00:00:00' && preg_match(self::SYSFS_PATTERN, $address);
177 });
178
179 /** @var bool | string $mac */
180 $mac = reset($macs);
181
182 return (string) $mac;
183 }
184 }
185