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