blob: a30d3a154164b70c9a32028134b636bc099b1ad7 [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 +00009"""
10
Guido van Rossum98d9fd32000-02-28 15:12:25 +000011# Authors: Piers Lauder (original)
12# Guido van Rossum (Windows support and cleanup)
13
Jeremy Hylton88d23301999-10-18 22:25:22 +000014import sys
Guido van Rossumb5903ac1998-04-09 20:37:16 +000015
Skip Montanaroeccd02a2001-01-20 23:34:12 +000016__all__ = ["getpass","getuser"]
17
Jeremy Hylton88d23301999-10-18 22:25:22 +000018def unix_getpass(prompt='Password: '):
Tim Peters07e99cb2001-01-14 23:47:14 +000019 """Prompt for a password, with echo turned off.
Guido van Rossumb5903ac1998-04-09 20:37:16 +000020
Tim Peters07e99cb2001-01-14 23:47:14 +000021 Restore terminal settings at end.
22 """
Guido van Rossumb5903ac1998-04-09 20:37:16 +000023
Tim Peters07e99cb2001-01-14 23:47:14 +000024 try:
25 fd = sys.stdin.fileno()
26 except:
27 return default_getpass(prompt)
Guido van Rossumb5903ac1998-04-09 20:37:16 +000028
Tim Peters07e99cb2001-01-14 23:47:14 +000029 old = termios.tcgetattr(fd) # a copy to save
30 new = old[:]
Guido van Rossumb5903ac1998-04-09 20:37:16 +000031
Fred Drake1191d012001-02-27 21:23:31 +000032 new[3] = new[3] & ~termios.ECHO # 3 == 'lflags'
Tim Peters07e99cb2001-01-14 23:47:14 +000033 try:
Fred Drake1191d012001-02-27 21:23:31 +000034 termios.tcsetattr(fd, termios.TCSADRAIN, new)
Tim Peters07e99cb2001-01-14 23:47:14 +000035 passwd = _raw_input(prompt)
36 finally:
Fred Drake1191d012001-02-27 21:23:31 +000037 termios.tcsetattr(fd, termios.TCSADRAIN, old)
Guido van Rossumb5903ac1998-04-09 20:37:16 +000038
Tim Peters07e99cb2001-01-14 23:47:14 +000039 sys.stdout.write('\n')
40 return passwd
Guido van Rossumb5903ac1998-04-09 20:37:16 +000041
42
43def win_getpass(prompt='Password: '):
Tim Peters07e99cb2001-01-14 23:47:14 +000044 """Prompt for password with echo off, using Windows getch()."""
Guido van Rossum60250e22001-08-30 15:07:44 +000045 if sys.stdin is not sys.__stdin__:
46 return default_getpass(prompt)
Tim Peters07e99cb2001-01-14 23:47:14 +000047 import msvcrt
48 for c in prompt:
49 msvcrt.putch(c)
50 pw = ""
51 while 1:
52 c = msvcrt.getch()
53 if c == '\r' or c == '\n':
54 break
55 if c == '\003':
56 raise KeyboardInterrupt
57 if c == '\b':
58 pw = pw[:-1]
59 else:
60 pw = pw + c
61 msvcrt.putch('\r')
62 msvcrt.putch('\n')
63 return pw
Guido van Rossumb5903ac1998-04-09 20:37:16 +000064
65
Guido van Rossumfb9b7fd1998-04-13 20:22:21 +000066def default_getpass(prompt='Password: '):
Tim Peters07e99cb2001-01-14 23:47:14 +000067 print "Warning: Problem with getpass. Passwords may be echoed."
68 return _raw_input(prompt)
Guido van Rossum1a7bab01998-07-28 19:28:43 +000069
70
71def _raw_input(prompt=""):
Neal Norwitzce96f692006-03-17 06:49:51 +000072 # This doesn't save the string in the GNU readline history.
Tim Peters07e99cb2001-01-14 23:47:14 +000073 prompt = str(prompt)
74 if prompt:
75 sys.stdout.write(prompt)
76 line = sys.stdin.readline()
77 if not line:
78 raise EOFError
79 if line[-1] == '\n':
80 line = line[:-1]
81 return line
Guido van Rossumfb9b7fd1998-04-13 20:22:21 +000082
83
Guido van Rossumb5903ac1998-04-09 20:37:16 +000084def getuser():
Tim Peters07e99cb2001-01-14 23:47:14 +000085 """Get the username from the environment or password database.
Guido van Rossumb5903ac1998-04-09 20:37:16 +000086
Tim Peters07e99cb2001-01-14 23:47:14 +000087 First try various environment variables, then the password
88 database. This works on Windows as long as USERNAME is set.
Guido van Rossumb5903ac1998-04-09 20:37:16 +000089
Tim Peters07e99cb2001-01-14 23:47:14 +000090 """
Guido van Rossumb5903ac1998-04-09 20:37:16 +000091
Tim Peters07e99cb2001-01-14 23:47:14 +000092 import os
Guido van Rossumb5903ac1998-04-09 20:37:16 +000093
Tim Peters07e99cb2001-01-14 23:47:14 +000094 for name in ('LOGNAME', 'USER', 'LNAME', 'USERNAME'):
95 user = os.environ.get(name)
96 if user:
97 return user
Guido van Rossumb5903ac1998-04-09 20:37:16 +000098
Tim Peters07e99cb2001-01-14 23:47:14 +000099 # If this fails, the exception will "explain" why
100 import pwd
101 return pwd.getpwuid(os.getuid())[0]
Jeremy Hylton88d23301999-10-18 22:25:22 +0000102
103# Bind the name getpass to the appropriate function
104try:
Fred Drake1191d012001-02-27 21:23:31 +0000105 import termios
Neal Norwitz201626e2002-11-20 23:15:54 +0000106 # it's possible there is an incompatible termios from the
107 # McMillan Installer, make sure we have a UNIX-compatible termios
108 termios.tcgetattr, termios.tcsetattr
109except (ImportError, AttributeError):
Tim Peters07e99cb2001-01-14 23:47:14 +0000110 try:
111 import msvcrt
112 except ImportError:
113 try:
114 from EasyDialogs import AskPassword
115 except ImportError:
116 getpass = default_getpass
117 else:
118 getpass = AskPassword
119 else:
120 getpass = win_getpass
Jeremy Hylton88d23301999-10-18 22:25:22 +0000121else:
Tim Peters07e99cb2001-01-14 23:47:14 +0000122 getpass = unix_getpass