cpython/Lib/getpass.py

129 lines
3.3 KiB
Python
Raw Normal View History

"""Utilities to get a password and/or the current user name.
getpass(prompt) - prompt for a password, with echo turned off
getuser() - get the user name from the environment or password database
On Windows, the msvcrt module will be used.
On the Mac EasyDialogs.AskPassword is used, if available.
"""
# Authors: Piers Lauder (original)
# Guido van Rossum (Windows support and cleanup)
import sys
2001-01-20 23:34:12 +00:00
__all__ = ["getpass","getuser"]
def unix_getpass(prompt='Password: ', stream=None):
2001-01-14 23:47:14 +00:00
"""Prompt for a password, with echo turned off.
The prompt is written on stream, by default stdout.
2001-01-14 23:47:14 +00:00
Restore terminal settings at end.
"""
if stream is None:
stream = sys.stdout
2001-01-14 23:47:14 +00:00
try:
fd = sys.stdin.fileno()
except:
return default_getpass(prompt)
2001-01-14 23:47:14 +00:00
old = termios.tcgetattr(fd) # a copy to save
new = old[:]
new[3] = new[3] & ~termios.ECHO # 3 == 'lflags'
2001-01-14 23:47:14 +00:00
try:
termios.tcsetattr(fd, termios.TCSADRAIN, new)
passwd = _raw_input(prompt, stream)
2001-01-14 23:47:14 +00:00
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old)
stream.write('\n')
2001-01-14 23:47:14 +00:00
return passwd
def win_getpass(prompt='Password: ', stream=None):
2001-01-14 23:47:14 +00:00
"""Prompt for password with echo off, using Windows getch()."""
if sys.stdin is not sys.__stdin__:
return default_getpass(prompt, stream)
2001-01-14 23:47:14 +00:00
import msvcrt
for c in prompt:
2007-12-10 17:02:00 +00:00
msvcrt.putwch(c)
2001-01-14 23:47:14 +00:00
pw = ""
while 1:
2007-12-10 17:02:00 +00:00
c = msvcrt.getwch()
2001-01-14 23:47:14 +00:00
if c == '\r' or c == '\n':
break
if c == '\003':
raise KeyboardInterrupt
if c == '\b':
pw = pw[:-1]
else:
pw = pw + c
2007-12-10 17:02:00 +00:00
msvcrt.putwch('\r')
msvcrt.putwch('\n')
2001-01-14 23:47:14 +00:00
return pw
def default_getpass(prompt='Password: ', stream=None):
print("Warning: Problem with getpass. Passwords may be echoed.", file=sys.stderr)
return _raw_input(prompt, stream)
def _raw_input(prompt="", stream=None):
# This doesn't save the string in the GNU readline history.
if stream is None:
stream = sys.stdout
2001-01-14 23:47:14 +00:00
prompt = str(prompt)
if prompt:
stream.write(prompt)
stream.flush()
2001-01-14 23:47:14 +00:00
line = sys.stdin.readline()
if not line:
raise EOFError
if line[-1] == '\n':
line = line[:-1]
return line
def getuser():
2001-01-14 23:47:14 +00:00
"""Get the username from the environment or password database.
2001-01-14 23:47:14 +00:00
First try various environment variables, then the password
database. This works on Windows as long as USERNAME is set.
2001-01-14 23:47:14 +00:00
"""
2001-01-14 23:47:14 +00:00
import os
2001-01-14 23:47:14 +00:00
for name in ('LOGNAME', 'USER', 'LNAME', 'USERNAME'):
user = os.environ.get(name)
if user:
return user
2001-01-14 23:47:14 +00:00
# If this fails, the exception will "explain" why
import pwd
return pwd.getpwuid(os.getuid())[0]
# Bind the name getpass to the appropriate function
try:
import termios
# it's possible there is an incompatible termios from the
# McMillan Installer, make sure we have a UNIX-compatible termios
termios.tcgetattr, termios.tcsetattr
except (ImportError, AttributeError):
2001-01-14 23:47:14 +00:00
try:
import msvcrt
except ImportError:
try:
from EasyDialogs import AskPassword
except ImportError:
getpass = default_getpass
else:
getpass = AskPassword
else:
getpass = win_getpass
else:
2001-01-14 23:47:14 +00:00
getpass = unix_getpass