8000 fix netrc security checks on WASI · python/cpython@d2a13f6 · GitHub
[go: up one dir, main page]

Skip to content

Commit d2a13f6

Browse files
committed
fix netrc security checks on WASI
1 parent ac9d37c commit d2a13f6

File tree

4 files changed

+28
-17
lines changed

4 files changed

+28
-17
lines changed

Doc/library/netrc.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@ the Unix :program:`ftp` program and other FTP clients.
2424
a :exc:`FileNotFoundError` exception will be raised.
2525
Parse errors will raise :exc:`NetrcParseError` with diagnostic
2626
information including the file name, line number, and terminating token.
27+
2728
If no argument is specified on a POSIX system, the presence of passwords in
2829
the :file:`.netrc` file will raise a :exc:`NetrcParseError` if the file
2930
ownership or permissions are insecure (owned by a user other than the user
3031
running the process, or accessible for read or write by any other user).
3132
This implements security behavior equivalent to that of ftp and other
32-
programs that use :file:`.netrc`.
33+
programs that use :file:`.netrc`. Such security checks are not available
34+
on platforms that do not support :func:`os.getuid`.
3335

3436
.. versionchanged:: 3.4 Added the POSIX permission check.
3537

Lib/netrc.py

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,19 @@
77
__all__ = ["netrc", "NetrcParseError"]
88

99

10+
def _can_security_check():
11+
# On WASI, getuid() is indicated as a stub but it may also be missing.
12+
return os.name == 'posix' and hasattr(os, 'getuid')
13+
14+
15+
def _getpwuid(uid):
16+
try:
17+
import pwd
18+
return pwd.getpwuid(uid)[0]
19+
except (ImportError, LookupError):
20+
return f'uid {uid}'
21+
22+
1023
class NetrcParseError(Exception):
1124
"""Exception raised on syntax errors in the .netrc file."""
1225
def __init__(self, msg, filename=None, lineno=None):
@@ -142,18 +155,11 @@ def _parse(self, file, fp, default_netrc):
142155
self._security_check(fp, default_netrc, self.hosts[entryname][0])
143156

144157
def _security_check(self, fp, default_netrc, login):
145-
if os.name == 'posix' and default_netrc and login != "anonymous":
158+
if _can_security_check() and default_netrc and login != "anonymous":
146159
prop = os.fstat(fp.fileno())
147160
if prop.st_uid != os.getuid():
148-
import pwd
149-
try:
150-
fowner = pwd.getpwuid(prop.st_uid)[0]
151-
except KeyError:
152-
fowner = 'uid %s' % prop.st_uid
153-
try:
154-
user = pwd.getpwuid(os.getuid())[0]
155-
except KeyError:
156-
user = 'uid %s' % os.getuid()
161+
fowner = _getpwuid(prop.st_uid)
162+
user = _getpwuid(os.getuid())
157163
raise NetrcParseError(
158164
(f"~/.netrc file owner ({fowner}, {user}) does not match"
159165
" current user"))

Lib/test/test_netrc.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
import netrc, os, unittest, sys, textwrap
2+
from test import support
23
from test.support import os_helper
34

4-
try:
5-
import pwd
6-
except ImportError:
7-
pwd = None
8-
95
temp_filename = os_helper.TESTFN
106

117
class NetrcTestCase(unittest.TestCase):
@@ -269,9 +265,14 @@ def test_comment_at_end_of_machine_line_pass_has_hash(self):
269265
machine bar.domain.com login foo password pass
270266
""", '#pass')
271267

268+
@unittest.skipUnless(support.is_wasi, 'WASI only test')
269+
def test_security_on_WASI(self):
270+
self.assertFalse(netrc._can_security_check())
271+
self.assertEqual(netrc._getpwuid(0), 'uid 0')
272+
self.assertEqual(netrc._getpwuid(123456), 'uid 123456')
272273

273274
@unittest.skipUnless(os.name == 'posix', 'POSIX only test')
274-
@unittest.skipIf(pwd is None, 'security check requires pwd module')
275+
@unittest.skipUnless(hasattr(os, 'getuid'), "os.getuid is required")
275276
@os_helper.skip_unless_working_chmod
276277
def test_security(self):
277278
# This test is incomplete since we are normally not run as root and
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
:mod:`netrc`: skip security checks if :func:`os.getuid` is missing.
2+
Patch by Bénédikt Tran.

0 commit comments

Comments
 (0)
0