8000 Issue #19855: uuid.getnode() on Unix now looks on the PATH for the · python/cpython@51c1162 · GitHub
[go: up one dir, main page]

Skip to content

Commit 51c1162

Browse files
committed
Issue #19855: uuid.getnode() on Unix now looks on the PATH for the
executables used to find the mac address, with /sbin and /usr/sbin as fallbacks. Issue #11508: Fixed uuid.getnode() and uuid.uuid1() on environment with virtual interface. Original patch by Kent Frazier. Issue #18784: The uuid module no more attempts to load libc via ctypes.CDLL, if all necessary functions are already found in libuuid. Patch by Evgeny Sologubov. Issue #16102: Make uuid._netbios_getnode() work again on Python 3.
1 parent 3bc3567 commit 51c1162

File tree

4 files changed

+67
-16
lines changed

4 files changed

+67
-16
lines changed

Lib/test/test_uuid.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from unittest import TestCase
22
from test import support
33
import builtins
4+
import io
5+
import os
46
import uuid
57

68
def importable(name):
@@ -360,6 +362,25 @@ def test_getnode(self):
360362

361363
self.assertEqual(node1, node2)
362364

365+
def test_find_mac(self):
366+
data = '''\
367+
368+
fake hwaddr
369+
cscotun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
370+
eth0 Link encap:Ethernet HWaddr 12:34:56:78:90:ab
371+
'''
372+
def mock_popen(cmd):
373+
return io.StringIO(data)
374+
375+
with support.swap_attr(os, 'popen', mock_popen):
376+
mac = uuid._find_mac(
377+
command='ifconfig',
378+
args='',
379+
hw_identifiers=['hwaddr'],
380+
get_index=lambda x: x + 1,
381+
)
382+
self.assertEqual(mac, 0x1234567890ab)
383+
363384
def test_uuid1(self):
364385
# uuid1 requires ctypes.
365386
try:

Lib/uuid.py

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -313,25 +313,38 @@ def version(self):
313313

314314
def _find_mac(command, args, hw_identifiers, get_index):
315315
import os
316-
for dir in ['', '/sbin/', '/usr/sbin']:
316+
path = os.environ.get("PATH", os.defpath).split(os.pathsep)
317+
path.extend(('/sbin', '/usr/sbin'))
318+
for dir in path:
317319
executable = os.path.join(dir, command)
318-
if not os.path.exists(executable):
319-
continue
320+
if (os.path.exists(executable) and
321+
os.access(executable, os.F_OK | os.X_OK) and
322+
not os.path.isdir(executable)):
323+
break
324+
else:
325+
return None
320326

321-
try:
322-
# LC_ALL to get English output, 2>/dev/null to
323-
# prevent output on stderr
324-
cmd = 'LC_ALL=C %s %s 2>/dev/null' % (executable, args)
325-
with os.popen(cmd) as pipe:
326-
for line in pipe:
327-
words = line.lower().split()
328-
for i in range(len(words)):
329-
if words[i] in hw_identifiers:
327+
try:
328+
# LC_ALL to ensure English output, 2>/dev/null to
329+
# prevent output on stderr
330+
cmd = 'LC_ALL=C %s %s 2>/dev/null' % (executable, args)
331+
with os.popen(cmd) as pipe:
332+
for line in pipe:
333+
words = line.lower().split()
334+
for i in range(len(words)):
335+
if words[i] in hw_identifiers:
336+
try:
330337
return int(
331338
words[get_index(i)].replace(':', ''), 16)
332-
except IOError:
333-
continue
334-
return None
339+
except (ValueError, IndexError):
340+
# Virtual interfaces, such as those provided by
341+
# VPNs, do not have a colon-delimited MAC address
342+
# as expected, but a 16-byte HWAddr separated by
343+
# dashes. These should be ignored in favor of a
344+
# real MAC address
345+
pass
346+
except IOError:
347+
pass
335348

336349
def _ifconfig_getnode():
337350
"""Get the hardware address on Unix by running ifconfig."""
@@ -406,7 +419,7 @@ def _netbios_getnode():
406419
if win32wnet.Netbios(ncb) != 0:
407420
continue
408421
status._unpack()
409-
bytes = map(ord, status.adapter_address)
422+
bytes = status.adapter_address
410423
return ((bytes[0]<<40) + (bytes[1]<<32) + (bytes[2]<<24) +
411424
(bytes[3]<<16) + (bytes[4]<<8) + bytes[5])
412425

@@ -429,6 +442,8 @@ def _netbios_getnode():
429442
_uuid_generate_random = lib.uuid_generate_random
430443
if hasattr(lib, 'uuid_generate_time'):
431444
_uuid_generate_time = lib.uuid_generate_time
445+
if _uuid_generate_random is not None:
446+
break # found everything we were looking for
432447

433448
# The uuid_generate_* functions are broken on MacOS X 10.5, as noted
434449
# in issue #8621 the function generates the same sequence of values

Misc/ACKS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ Doug Fort
353353
John Fouhy
354354
Stefan Franke
355355
Martin Franklin
356+
Kent Frazier
356357
Robin Friedrich
357358
Bradley Froehle
358359
Ivan Frohne
@@ -1028,6 +1029,7 @@ Ryan Smith-Roberts
10281029
Rafal Smotrzyk
10291030
Dirk Soede
10301031
Paul Sokolovsky
1032+
Evgeny Sologubov
10311033
Cody Somerville
10321034
Clay Spence
10331035
Stefan Sperling

Misc/NEWS

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,19 @@ Library
4747
with non-standard cookie handling in some Web browsers. Reported by
4848
Sergey Bobrov.
4949

50+
- Issue #19855: uuid.getnode() on Unix now looks on the PATH for the
51+
executables used to find the mac address, with /sbin and /usr/sbin as
52+
fallbacks.
53< 7BB2 /td>+
54+
- Issue #11508: Fixed uuid.getnode() and uuid.uuid1() on environment with
55+
virtual interface. Original patch by Kent Frazier.
56+
57+
- Issue #18784: The uuid module no more attempts to load libc via ctypes.CDLL,
58+
if all necessary functions are already found in libuuid.
59+
Patch by Evgeny Sologubov.
60+
61+
- Issue #16102: Make uuid._netbios_getnode() work again on Python 3.
62+
5063
- Issue #21766: Prevent a security hole in CGIHTTPServer by URL unquoting paths
5164
before checking for a CGI script at that path.
5265

0 commit comments

Comments
 (0)
0