Update netrc.py from 3.13.6 and make pwd accesible on Android (#6083)

This commit is contained in:
Shahar Naveh
2025-08-20 08:08:05 +03:00
committed by GitHub
parent 242814fa72
commit e6001a48d7
4 changed files with 40 additions and 24 deletions

31
Lib/netrc.py vendored
View File

@@ -2,11 +2,24 @@
# Module and documentation by Eric S. Raymond, 21 Dec 1998
import os, shlex, stat
import os, stat
__all__ = ["netrc", "NetrcParseError"]
def _can_security_check():
# On WASI, getuid() is indicated as a stub but it may also be missing.
return os.name == 'posix' and hasattr(os, 'getuid')
def _getpwuid(uid):
try:
import pwd
return pwd.getpwuid(uid)[0]
except (ImportError, LookupError):
return f'uid {uid}'
class NetrcParseError(Exception):
"""Exception raised on syntax errors in the .netrc file."""
def __init__(self, msg, filename=None, lineno=None):
@@ -142,18 +155,12 @@ class netrc:
self._security_check(fp, default_netrc, self.hosts[entryname][0])
def _security_check(self, fp, default_netrc, login):
if os.name == 'posix' and default_netrc and login != "anonymous":
if _can_security_check() and default_netrc and login != "anonymous":
prop = os.fstat(fp.fileno())
if prop.st_uid != os.getuid():
import pwd
try:
fowner = pwd.getpwuid(prop.st_uid)[0]
except KeyError:
fowner = 'uid %s' % prop.st_uid
try:
user = pwd.getpwuid(os.getuid())[0]
except KeyError:
user = 'uid %s' % os.getuid()
current_user_id = os.getuid()
if prop.st_uid != current_user_id:
fowner = _getpwuid(prop.st_uid)
user = _getpwuid(current_user_id)
raise NetrcParseError(
(f"~/.netrc file owner ({fowner}, {user}) does not match"
" current user"))

View File

@@ -1,10 +1,6 @@
import netrc, os, unittest, sys, textwrap
from test.support import os_helper, run_unittest
try:
import pwd
except ImportError:
pwd = None
from test import support
from test.support import os_helper
temp_filename = os_helper.TESTFN
@@ -269,9 +265,14 @@ class NetrcTestCase(unittest.TestCase):
machine bar.domain.com login foo password pass
""", '#pass')
@unittest.skipUnless(support.is_wasi, 'WASI only test')
def test_security_on_WASI(self):
self.assertFalse(netrc._can_security_check())
self.assertEqual(netrc._getpwuid(0), 'uid 0')
self.assertEqual(netrc._getpwuid(123456), 'uid 123456')
@unittest.skipUnless(os.name == 'posix', 'POSIX only test')
@unittest.skipIf(pwd is None, 'security check requires pwd module')
@unittest.skipUnless(hasattr(os, 'getuid'), "os.getuid is required")
@os_helper.skip_unless_working_chmod
def test_security(self):
# This test is incomplete since we are normally not run as root and
@@ -308,8 +309,6 @@ class NetrcTestCase(unittest.TestCase):
self.assertEqual(nrc.hosts['foo.domain.com'],
('anonymous', '', 'pass'))
def test_main():
run_unittest(NetrcTestCase)
if __name__ == "__main__":
test_main()
unittest.main()

View File

@@ -46,8 +46,13 @@ pub mod posix;
mod ctypes;
#[cfg(windows)]
pub(crate) mod msvcrt;
#[cfg(all(unix, not(any(target_os = "android", target_os = "redox"))))]
#[cfg(all(
unix,
not(any(target_os = "ios", target_os = "wasi", target_os = "redox"))
))]
mod pwd;
pub(crate) mod signal;
pub mod sys;
#[cfg(windows)]
@@ -120,7 +125,10 @@ pub fn get_module_inits() -> StdlibMap {
"_thread" => thread::make_module,
}
// Unix-only
#[cfg(all(unix, not(any(target_os = "android", target_os = "redox"))))]
#[cfg(all(
unix,
not(any(target_os = "ios", target_os = "wasi", target_os = "redox"))
))]
{
"pwd" => pwd::make_module,
}

View File

@@ -26,6 +26,7 @@ mod pwd {
pw_dir: String,
pw_shell: String,
}
#[pyclass(with(PyStructSequence))]
impl Passwd {}
@@ -91,6 +92,7 @@ mod pwd {
}
// TODO: maybe merge this functionality into nix?
#[cfg(not(target_os = "android"))]
#[pyfunction]
fn getpwall(vm: &VirtualMachine) -> PyResult<Vec<PyObjectRef>> {
// setpwent, getpwent, etc are not thread safe. Could use fgetpwent_r, but this is easier