1"""Utilities to get a password and/or the current user name. 2 3getpass(prompt) - prompt for a password, with echo turned off 4getuser() - get the user name from the environment or password database 5 6On Windows, the msvcrt module will be used. 7On the Mac EasyDialogs.AskPassword is used, if available. 8 9""" 10 11# From CPython 2.5.1 with a fix to _raw_input (see 12# http://bugs.python.org/issue1703 ) 13 14# Authors: Piers Lauder (original) 15# Guido van Rossum (Windows support and cleanup) 16 17import os 18import sys 19 20__all__ = ["getpass","getuser"] 21 22def jython_getpass(prompt='Password: ', stream=None): 23 """Prompt for a password, with echo turned off. 24 The prompt is written on stream, by default stdout. 25 26 Restore terminal settings at end. 27 """ 28 if stream is None: 29 stream = sys.stdout 30 31 try: 32 terminal = sys._jy_interpreter.reader.terminal 33 except: 34 return default_getpass(prompt) 35 36 echoed = terminal.getEcho() 37 terminal.disableEcho() 38 try: 39 passwd = _raw_input(prompt, stream) 40 finally: 41 if echoed: 42 terminal.enableEcho() 43 44 stream.write('\n') 45 return passwd 46 47 48def unix_getpass(prompt='Password: ', stream=None): 49 """Prompt for a password, with echo turned off. 50 The prompt is written on stream, by default stdout. 51 52 Restore terminal settings at end. 53 """ 54 if stream is None: 55 stream = sys.stdout 56 57 try: 58 fd = sys.stdin.fileno() 59 except: 60 return default_getpass(prompt) 61 62 old = termios.tcgetattr(fd) # a copy to save 63 new = old[:] 64 65 new[3] = new[3] & ~termios.ECHO # 3 == 'lflags' 66 try: 67 termios.tcsetattr(fd, termios.TCSADRAIN, new) 68 passwd = _raw_input(prompt, stream) 69 finally: 70 termios.tcsetattr(fd, termios.TCSADRAIN, old) 71 72 stream.write('\n') 73 return passwd 74 75 76def win_getpass(prompt='Password: ', stream=None): 77 """Prompt for password with echo off, using Windows getch().""" 78 if sys.stdin is not sys.__stdin__: 79 return default_getpass(prompt, stream) 80 import msvcrt 81 for c in prompt: 82 msvcrt.putch(c) 83 pw = "" 84 while 1: 85 c = msvcrt.getch() 86 if c == '\r' or c == '\n': 87 break 88 if c == '\003': 89 raise KeyboardInterrupt 90 if c == '\b': 91 pw = pw[:-1] 92 else: 93 pw = pw + c 94 msvcrt.putch('\r') 95 msvcrt.putch('\n') 96 return pw 97 98 99def default_getpass(prompt='Password: ', stream=None): 100 print >>sys.stderr, "Warning: Problem with getpass. Passwords may be echoed." 101 return _raw_input(prompt, stream) 102 103 104def _raw_input(prompt="", stream=None): 105 # A raw_input() replacement that doesn't save the string in the 106 # GNU readline history. 107 if stream is None: 108 stream = sys.stdout 109 prompt = str(prompt) 110 if prompt: 111 stream.write(prompt) 112 stream.flush() 113 line = sys.stdin.readline() 114 if not line: 115 raise EOFError 116 if line[-1] == '\n': 117 line = line[:-1] 118 return line 119 120 121def getuser(): 122 """Get the username from the environment or password database. 123 124 First try various environment variables, then the password 125 database. This works on Windows as long as USERNAME is set. 126 127 """ 128 129 for name in ('LOGNAME', 'USER', 'LNAME', 'USERNAME'): 130 user = os.environ.get(name) 131 if user: 132 return user 133 134 # If this fails, the exception will "explain" why 135 import pwd 136 return pwd.getpwuid(os.getuid())[0] 137 138# Bind the name getpass to the appropriate function 139try: 140 import termios 141 # it's possible there is an incompatible termios from the 142 # McMillan Installer, make sure we have a UNIX-compatible termios 143 termios.tcgetattr, termios.tcsetattr 144except (ImportError, AttributeError): 145 try: 146 import msvcrt 147 except ImportError: 148 try: 149 from EasyDialogs import AskPassword 150 except ImportError: 151 if os.name == 'java': 152 getpass = jython_getpass 153 else: 154 getpass = default_getpass 155 else: 156 getpass = AskPassword 157 else: 158 getpass = win_getpass 159else: 160 getpass = unix_getpass 161