1*cda5da8dSAndroid Build Coastguard Worker"""Utilities to get a password and/or the current user name. 2*cda5da8dSAndroid Build Coastguard Worker 3*cda5da8dSAndroid Build Coastguard Workergetpass(prompt[, stream]) - Prompt for a password, with echo turned off. 4*cda5da8dSAndroid Build Coastguard Workergetuser() - Get the user name from the environment or password database. 5*cda5da8dSAndroid Build Coastguard Worker 6*cda5da8dSAndroid Build Coastguard WorkerGetPassWarning - This UserWarning is issued when getpass() cannot prevent 7*cda5da8dSAndroid Build Coastguard Worker echoing of the password contents while reading. 8*cda5da8dSAndroid Build Coastguard Worker 9*cda5da8dSAndroid Build Coastguard WorkerOn Windows, the msvcrt module will be used. 10*cda5da8dSAndroid Build Coastguard Worker 11*cda5da8dSAndroid Build Coastguard Worker""" 12*cda5da8dSAndroid Build Coastguard Worker 13*cda5da8dSAndroid Build Coastguard Worker# Authors: Piers Lauder (original) 14*cda5da8dSAndroid Build Coastguard Worker# Guido van Rossum (Windows support and cleanup) 15*cda5da8dSAndroid Build Coastguard Worker# Gregory P. Smith (tty support & GetPassWarning) 16*cda5da8dSAndroid Build Coastguard Worker 17*cda5da8dSAndroid Build Coastguard Workerimport contextlib 18*cda5da8dSAndroid Build Coastguard Workerimport io 19*cda5da8dSAndroid Build Coastguard Workerimport os 20*cda5da8dSAndroid Build Coastguard Workerimport sys 21*cda5da8dSAndroid Build Coastguard Workerimport warnings 22*cda5da8dSAndroid Build Coastguard Worker 23*cda5da8dSAndroid Build Coastguard Worker__all__ = ["getpass","getuser","GetPassWarning"] 24*cda5da8dSAndroid Build Coastguard Worker 25*cda5da8dSAndroid Build Coastguard Worker 26*cda5da8dSAndroid Build Coastguard Workerclass GetPassWarning(UserWarning): pass 27*cda5da8dSAndroid Build Coastguard Worker 28*cda5da8dSAndroid Build Coastguard Worker 29*cda5da8dSAndroid Build Coastguard Workerdef unix_getpass(prompt='Password: ', stream=None): 30*cda5da8dSAndroid Build Coastguard Worker """Prompt for a password, with echo turned off. 31*cda5da8dSAndroid Build Coastguard Worker 32*cda5da8dSAndroid Build Coastguard Worker Args: 33*cda5da8dSAndroid Build Coastguard Worker prompt: Written on stream to ask for the input. Default: 'Password: ' 34*cda5da8dSAndroid Build Coastguard Worker stream: A writable file object to display the prompt. Defaults to 35*cda5da8dSAndroid Build Coastguard Worker the tty. If no tty is available defaults to sys.stderr. 36*cda5da8dSAndroid Build Coastguard Worker Returns: 37*cda5da8dSAndroid Build Coastguard Worker The seKr3t input. 38*cda5da8dSAndroid Build Coastguard Worker Raises: 39*cda5da8dSAndroid Build Coastguard Worker EOFError: If our input tty or stdin was closed. 40*cda5da8dSAndroid Build Coastguard Worker GetPassWarning: When we were unable to turn echo off on the input. 41*cda5da8dSAndroid Build Coastguard Worker 42*cda5da8dSAndroid Build Coastguard Worker Always restores terminal settings before returning. 43*cda5da8dSAndroid Build Coastguard Worker """ 44*cda5da8dSAndroid Build Coastguard Worker passwd = None 45*cda5da8dSAndroid Build Coastguard Worker with contextlib.ExitStack() as stack: 46*cda5da8dSAndroid Build Coastguard Worker try: 47*cda5da8dSAndroid Build Coastguard Worker # Always try reading and writing directly on the tty first. 48*cda5da8dSAndroid Build Coastguard Worker fd = os.open('/dev/tty', os.O_RDWR|os.O_NOCTTY) 49*cda5da8dSAndroid Build Coastguard Worker tty = io.FileIO(fd, 'w+') 50*cda5da8dSAndroid Build Coastguard Worker stack.enter_context(tty) 51*cda5da8dSAndroid Build Coastguard Worker input = io.TextIOWrapper(tty) 52*cda5da8dSAndroid Build Coastguard Worker stack.enter_context(input) 53*cda5da8dSAndroid Build Coastguard Worker if not stream: 54*cda5da8dSAndroid Build Coastguard Worker stream = input 55*cda5da8dSAndroid Build Coastguard Worker except OSError: 56*cda5da8dSAndroid Build Coastguard Worker # If that fails, see if stdin can be controlled. 57*cda5da8dSAndroid Build Coastguard Worker stack.close() 58*cda5da8dSAndroid Build Coastguard Worker try: 59*cda5da8dSAndroid Build Coastguard Worker fd = sys.stdin.fileno() 60*cda5da8dSAndroid Build Coastguard Worker except (AttributeError, ValueError): 61*cda5da8dSAndroid Build Coastguard Worker fd = None 62*cda5da8dSAndroid Build Coastguard Worker passwd = fallback_getpass(prompt, stream) 63*cda5da8dSAndroid Build Coastguard Worker input = sys.stdin 64*cda5da8dSAndroid Build Coastguard Worker if not stream: 65*cda5da8dSAndroid Build Coastguard Worker stream = sys.stderr 66*cda5da8dSAndroid Build Coastguard Worker 67*cda5da8dSAndroid Build Coastguard Worker if fd is not None: 68*cda5da8dSAndroid Build Coastguard Worker try: 69*cda5da8dSAndroid Build Coastguard Worker old = termios.tcgetattr(fd) # a copy to save 70*cda5da8dSAndroid Build Coastguard Worker new = old[:] 71*cda5da8dSAndroid Build Coastguard Worker new[3] &= ~termios.ECHO # 3 == 'lflags' 72*cda5da8dSAndroid Build Coastguard Worker tcsetattr_flags = termios.TCSAFLUSH 73*cda5da8dSAndroid Build Coastguard Worker if hasattr(termios, 'TCSASOFT'): 74*cda5da8dSAndroid Build Coastguard Worker tcsetattr_flags |= termios.TCSASOFT 75*cda5da8dSAndroid Build Coastguard Worker try: 76*cda5da8dSAndroid Build Coastguard Worker termios.tcsetattr(fd, tcsetattr_flags, new) 77*cda5da8dSAndroid Build Coastguard Worker passwd = _raw_input(prompt, stream, input=input) 78*cda5da8dSAndroid Build Coastguard Worker finally: 79*cda5da8dSAndroid Build Coastguard Worker termios.tcsetattr(fd, tcsetattr_flags, old) 80*cda5da8dSAndroid Build Coastguard Worker stream.flush() # issue7208 81*cda5da8dSAndroid Build Coastguard Worker except termios.error: 82*cda5da8dSAndroid Build Coastguard Worker if passwd is not None: 83*cda5da8dSAndroid Build Coastguard Worker # _raw_input succeeded. The final tcsetattr failed. Reraise 84*cda5da8dSAndroid Build Coastguard Worker # instead of leaving the terminal in an unknown state. 85*cda5da8dSAndroid Build Coastguard Worker raise 86*cda5da8dSAndroid Build Coastguard Worker # We can't control the tty or stdin. Give up and use normal IO. 87*cda5da8dSAndroid Build Coastguard Worker # fallback_getpass() raises an appropriate warning. 88*cda5da8dSAndroid Build Coastguard Worker if stream is not input: 89*cda5da8dSAndroid Build Coastguard Worker # clean up unused file objects before blocking 90*cda5da8dSAndroid Build Coastguard Worker stack.close() 91*cda5da8dSAndroid Build Coastguard Worker passwd = fallback_getpass(prompt, stream) 92*cda5da8dSAndroid Build Coastguard Worker 93*cda5da8dSAndroid Build Coastguard Worker stream.write('\n') 94*cda5da8dSAndroid Build Coastguard Worker return passwd 95*cda5da8dSAndroid Build Coastguard Worker 96*cda5da8dSAndroid Build Coastguard Worker 97*cda5da8dSAndroid Build Coastguard Workerdef win_getpass(prompt='Password: ', stream=None): 98*cda5da8dSAndroid Build Coastguard Worker """Prompt for password with echo off, using Windows getwch().""" 99*cda5da8dSAndroid Build Coastguard Worker if sys.stdin is not sys.__stdin__: 100*cda5da8dSAndroid Build Coastguard Worker return fallback_getpass(prompt, stream) 101*cda5da8dSAndroid Build Coastguard Worker 102*cda5da8dSAndroid Build Coastguard Worker for c in prompt: 103*cda5da8dSAndroid Build Coastguard Worker msvcrt.putwch(c) 104*cda5da8dSAndroid Build Coastguard Worker pw = "" 105*cda5da8dSAndroid Build Coastguard Worker while 1: 106*cda5da8dSAndroid Build Coastguard Worker c = msvcrt.getwch() 107*cda5da8dSAndroid Build Coastguard Worker if c == '\r' or c == '\n': 108*cda5da8dSAndroid Build Coastguard Worker break 109*cda5da8dSAndroid Build Coastguard Worker if c == '\003': 110*cda5da8dSAndroid Build Coastguard Worker raise KeyboardInterrupt 111*cda5da8dSAndroid Build Coastguard Worker if c == '\b': 112*cda5da8dSAndroid Build Coastguard Worker pw = pw[:-1] 113*cda5da8dSAndroid Build Coastguard Worker else: 114*cda5da8dSAndroid Build Coastguard Worker pw = pw + c 115*cda5da8dSAndroid Build Coastguard Worker msvcrt.putwch('\r') 116*cda5da8dSAndroid Build Coastguard Worker msvcrt.putwch('\n') 117*cda5da8dSAndroid Build Coastguard Worker return pw 118*cda5da8dSAndroid Build Coastguard Worker 119*cda5da8dSAndroid Build Coastguard Worker 120*cda5da8dSAndroid Build Coastguard Workerdef fallback_getpass(prompt='Password: ', stream=None): 121*cda5da8dSAndroid Build Coastguard Worker warnings.warn("Can not control echo on the terminal.", GetPassWarning, 122*cda5da8dSAndroid Build Coastguard Worker stacklevel=2) 123*cda5da8dSAndroid Build Coastguard Worker if not stream: 124*cda5da8dSAndroid Build Coastguard Worker stream = sys.stderr 125*cda5da8dSAndroid Build Coastguard Worker print("Warning: Password input may be echoed.", file=stream) 126*cda5da8dSAndroid Build Coastguard Worker return _raw_input(prompt, stream) 127*cda5da8dSAndroid Build Coastguard Worker 128*cda5da8dSAndroid Build Coastguard Worker 129*cda5da8dSAndroid Build Coastguard Workerdef _raw_input(prompt="", stream=None, input=None): 130*cda5da8dSAndroid Build Coastguard Worker # This doesn't save the string in the GNU readline history. 131*cda5da8dSAndroid Build Coastguard Worker if not stream: 132*cda5da8dSAndroid Build Coastguard Worker stream = sys.stderr 133*cda5da8dSAndroid Build Coastguard Worker if not input: 134*cda5da8dSAndroid Build Coastguard Worker input = sys.stdin 135*cda5da8dSAndroid Build Coastguard Worker prompt = str(prompt) 136*cda5da8dSAndroid Build Coastguard Worker if prompt: 137*cda5da8dSAndroid Build Coastguard Worker try: 138*cda5da8dSAndroid Build Coastguard Worker stream.write(prompt) 139*cda5da8dSAndroid Build Coastguard Worker except UnicodeEncodeError: 140*cda5da8dSAndroid Build Coastguard Worker # Use replace error handler to get as much as possible printed. 141*cda5da8dSAndroid Build Coastguard Worker prompt = prompt.encode(stream.encoding, 'replace') 142*cda5da8dSAndroid Build Coastguard Worker prompt = prompt.decode(stream.encoding) 143*cda5da8dSAndroid Build Coastguard Worker stream.write(prompt) 144*cda5da8dSAndroid Build Coastguard Worker stream.flush() 145*cda5da8dSAndroid Build Coastguard Worker # NOTE: The Python C API calls flockfile() (and unlock) during readline. 146*cda5da8dSAndroid Build Coastguard Worker line = input.readline() 147*cda5da8dSAndroid Build Coastguard Worker if not line: 148*cda5da8dSAndroid Build Coastguard Worker raise EOFError 149*cda5da8dSAndroid Build Coastguard Worker if line[-1] == '\n': 150*cda5da8dSAndroid Build Coastguard Worker line = line[:-1] 151*cda5da8dSAndroid Build Coastguard Worker return line 152*cda5da8dSAndroid Build Coastguard Worker 153*cda5da8dSAndroid Build Coastguard Worker 154*cda5da8dSAndroid Build Coastguard Workerdef getuser(): 155*cda5da8dSAndroid Build Coastguard Worker """Get the username from the environment or password database. 156*cda5da8dSAndroid Build Coastguard Worker 157*cda5da8dSAndroid Build Coastguard Worker First try various environment variables, then the password 158*cda5da8dSAndroid Build Coastguard Worker database. This works on Windows as long as USERNAME is set. 159*cda5da8dSAndroid Build Coastguard Worker 160*cda5da8dSAndroid Build Coastguard Worker """ 161*cda5da8dSAndroid Build Coastguard Worker 162*cda5da8dSAndroid Build Coastguard Worker for name in ('LOGNAME', 'USER', 'LNAME', 'USERNAME'): 163*cda5da8dSAndroid Build Coastguard Worker user = os.environ.get(name) 164*cda5da8dSAndroid Build Coastguard Worker if user: 165*cda5da8dSAndroid Build Coastguard Worker return user 166*cda5da8dSAndroid Build Coastguard Worker 167*cda5da8dSAndroid Build Coastguard Worker # If this fails, the exception will "explain" why 168*cda5da8dSAndroid Build Coastguard Worker import pwd 169*cda5da8dSAndroid Build Coastguard Worker return pwd.getpwuid(os.getuid())[0] 170*cda5da8dSAndroid Build Coastguard Worker 171*cda5da8dSAndroid Build Coastguard Worker# Bind the name getpass to the appropriate function 172*cda5da8dSAndroid Build Coastguard Workertry: 173*cda5da8dSAndroid Build Coastguard Worker import termios 174*cda5da8dSAndroid Build Coastguard Worker # it's possible there is an incompatible termios from the 175*cda5da8dSAndroid Build Coastguard Worker # McMillan Installer, make sure we have a UNIX-compatible termios 176*cda5da8dSAndroid Build Coastguard Worker termios.tcgetattr, termios.tcsetattr 177*cda5da8dSAndroid Build Coastguard Workerexcept (ImportError, AttributeError): 178*cda5da8dSAndroid Build Coastguard Worker try: 179*cda5da8dSAndroid Build Coastguard Worker import msvcrt 180*cda5da8dSAndroid Build Coastguard Worker except ImportError: 181*cda5da8dSAndroid Build Coastguard Worker getpass = fallback_getpass 182*cda5da8dSAndroid Build Coastguard Worker else: 183*cda5da8dSAndroid Build Coastguard Worker getpass = win_getpass 184*cda5da8dSAndroid Build Coastguard Workerelse: 185*cda5da8dSAndroid Build Coastguard Worker getpass = unix_getpass 186