blob: 19843d73c59274ebd03401f62452af9449daf575 [file] [log] [blame]
Guido van Rossumb5903ac1998-04-09 20:37:16 +00001"""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
Jeremy Hylton88d23301999-10-18 22:25:22 +00006On Windows, the msvcrt module will be used.
7On the Mac EasyDialogs.AskPassword is used, if available.
8
Guido van Rossumb5903ac1998-04-09 20:37:16 +00009Authors: Piers Lauder (original)
10 Guido van Rossum (Windows support and cleanup)
11"""
12
Jeremy Hylton88d23301999-10-18 22:25:22 +000013import sys
Guido van Rossumb5903ac1998-04-09 20:37:16 +000014
Jeremy Hylton88d23301999-10-18 22:25:22 +000015def unix_getpass(prompt='Password: '):
Guido van Rossumb5903ac1998-04-09 20:37:16 +000016 """Prompt for a password, with echo turned off.
17
18 Restore terminal settings at end.
Guido van Rossumb5903ac1998-04-09 20:37:16 +000019 """
20
Guido van Rossumb5903ac1998-04-09 20:37:16 +000021 try:
Guido van Rossum0238a251998-09-22 02:38:42 +000022 fd = sys.stdin.fileno()
23 except:
24 return default_getpass(prompt)
Guido van Rossumb5903ac1998-04-09 20:37:16 +000025
Jeremy Hylton88d23301999-10-18 22:25:22 +000026 getpass = default_getpass
Guido van Rossumb5903ac1998-04-09 20:37:16 +000027 old = termios.tcgetattr(fd) # a copy to save
28 new = old[:]
29
30 new[3] = new[3] & ~TERMIOS.ECHO # 3 == 'lflags'
31 try:
32 termios.tcsetattr(fd, TERMIOS.TCSADRAIN, new)
Guido van Rossum1a7bab01998-07-28 19:28:43 +000033 passwd = _raw_input(prompt)
Guido van Rossumb5903ac1998-04-09 20:37:16 +000034 finally:
35 termios.tcsetattr(fd, TERMIOS.TCSADRAIN, old)
36
37 sys.stdout.write('\n')
38 return passwd
39
40
41def win_getpass(prompt='Password: '):
42 """Prompt for password with echo off, using Windows getch()."""
43 import msvcrt
44 for c in prompt:
45 msvcrt.putch(c)
46 pw = ""
47 while 1:
48 c = msvcrt.getch()
49 if c == '\r' or c == '\n':
50 break
Guido van Rossumc3da02e1998-06-12 14:28:38 +000051 if c == '\003':
52 raise KeyboardInterrupt
Guido van Rossumb5903ac1998-04-09 20:37:16 +000053 if c == '\b':
54 pw = pw[:-1]
55 else:
56 pw = pw + c
57 msvcrt.putch('\r')
58 msvcrt.putch('\n')
59 return pw
60
61
Guido van Rossumfb9b7fd1998-04-13 20:22:21 +000062def default_getpass(prompt='Password: '):
Jeremy Hylton88d23301999-10-18 22:25:22 +000063 print "Warning: Problem with getpass. Passwords may be echoed."
Guido van Rossum1a7bab01998-07-28 19:28:43 +000064 return _raw_input(prompt)
65
66
67def _raw_input(prompt=""):
68 # A raw_input() replacement that doesn't save the string in the
69 # GNU readline history.
70 import sys
71 prompt = str(prompt)
72 if prompt:
73 sys.stdout.write(prompt)
74 line = sys.stdin.readline()
75 if not line:
76 raise EOFError
77 if line[-1] == '\n':
78 line = line[:-1]
79 return line
Guido van Rossumfb9b7fd1998-04-13 20:22:21 +000080
81
Guido van Rossumb5903ac1998-04-09 20:37:16 +000082def getuser():
83 """Get the username from the environment or password database.
84
85 First try various environment variables, then the password
86 database. This works on Windows as long as USERNAME is set.
87
88 """
89
90 import os
91
92 for name in ('LOGNAME', 'USER', 'LNAME', 'USERNAME'):
93 user = os.environ.get(name)
94 if user:
95 return user
96
97 # If this fails, the exception will "explain" why
98 import pwd
99 return pwd.getpwuid(os.getuid())[0]
Jeremy Hylton88d23301999-10-18 22:25:22 +0000100
101# Bind the name getpass to the appropriate function
102try:
103 import termios, TERMIOS
104except ImportError:
105 try:
106 import msvcrt
107 except ImportError:
108 try:
109 from EasyDialogs import AskPassword
110 except ImportError:
111 getpass = default_getpass
112 else:
113 getpass = AskPassword
114 else:
115 getpass = win_getpass
116else:
117 getpass = unix_getpass
118