|
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 |