blob: a726189fe1a07baaf19fbe00d067c2135d64eb46 [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
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000018def unix_getpass(prompt='Password: ', stream=None):
Tim Peters07e99cb2001-01-14 23:47:14 +000019 """Prompt for a password, with echo turned off.
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000020 The prompt is written on stream, by default stdout.
Guido van Rossumb5903ac1998-04-09 20:37:16 +000021
Tim Peters07e99cb2001-01-14 23:47:14 +000022 Restore terminal settings at end.
23 """
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000024 if stream is None:
25 stream = sys.stdout
Guido van Rossumb5903ac1998-04-09 20:37:16 +000026
Tim Peters07e99cb2001-01-14 23:47:14 +000027 try:
28 fd = sys.stdin.fileno()
29 except:
30 return default_getpass(prompt)
Guido van Rossumb5903ac1998-04-09 20:37:16 +000031
Tim Peters07e99cb2001-01-14 23:47:14 +000032 old = termios.tcgetattr(fd) # a copy to save
33 new = old[:]
Guido van Rossumb5903ac1998-04-09 20:37:16 +000034
Fred Drake1191d012001-02-27 21:23:31 +000035 new[3] = new[3] & ~termios.ECHO # 3 == 'lflags'
Tim Peters07e99cb2001-01-14 23:47:14 +000036 try:
Fred Drake1191d012001-02-27 21:23:31 +000037 termios.tcsetattr(fd, termios.TCSADRAIN, new)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000038 passwd = _raw_input(prompt, stream)
Tim Peters07e99cb2001-01-14 23:47:14 +000039 finally:
Fred Drake1191d012001-02-27 21:23:31 +000040 termios.tcsetattr(fd, termios.TCSADRAIN, old)
Guido van Rossumb5903ac1998-04-09 20:37:16 +000041
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000042 stream.write('\n')
Tim Peters07e99cb2001-01-14 23:47:14 +000043 return passwd
Guido van Rossumb5903ac1998-04-09 20:37:16 +000044
45
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000046def win_getpass(prompt='Password: ', stream=None):
Tim Peters07e99cb2001-01-14 23:47:14 +000047 """Prompt for password with echo off, using Windows getch()."""
Guido van Rossum60250e22001-08-30 15:07:44 +000048 if sys.stdin is not sys.__stdin__:
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000049 return default_getpass(prompt, stream)
Tim Peters07e99cb2001-01-14 23:47:14 +000050 import msvcrt
51 for c in prompt:
Christian Heimes0ec88b32007-12-10 17:02:00 +000052 msvcrt.putwch(c)
Tim Peters07e99cb2001-01-14 23:47:14 +000053 pw = ""
54 while 1:
Christian Heimes0ec88b32007-12-10 17:02:00 +000055 c = msvcrt.getwch()
Tim Peters07e99cb2001-01-14 23:47:14 +000056 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
Christian Heimes0ec88b32007-12-10 17:02:00 +000064 msvcrt.putwch('\r')
65 msvcrt.putwch('\n')
Tim Peters07e99cb2001-01-14 23:47:14 +000066 return pw
Guido van Rossumb5903ac1998-04-09 20:37:16 +000067
68
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000069def default_getpass(prompt='Password: ', stream=None):
Guido van Rossumbe19ed72007-02-09 05:37:30 +000070 print("Warning: Problem with getpass. Passwords may be echoed.", file=sys.stderr)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000071 return _raw_input(prompt, stream)
Guido van Rossum1a7bab01998-07-28 19:28:43 +000072
73
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000074def _raw_input(prompt="", stream=None):
Neal Norwitzce96f692006-03-17 06:49:51 +000075 # This doesn't save the string in the GNU readline history.
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000076 if stream is None:
77 stream = sys.stdout
Tim Peters07e99cb2001-01-14 23:47:14 +000078 prompt = str(prompt)
79 if prompt:
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000080 stream.write(prompt)
Tim Peters07e99cb2001-01-14 23:47:14 +000081 line = sys.stdin.readline()
82 if not line:
83 raise EOFError
84 if line[-1] == '\n':
85 line = line[:-1]
86 return line
Guido van Rossumfb9b7fd1998-04-13 20:22:21 +000087
88
Guido van Rossumb5903ac1998-04-09 20:37:16 +000089def getuser():
Tim Peters07e99cb2001-01-14 23:47:14 +000090 """Get the username from the environment or password database.
Guido van Rossumb5903ac1998-04-09 20:37:16 +000091
Tim Peters07e99cb2001-01-14 23:47:14 +000092 First try various environment variables, then the password
93 database. This works on Windows as long as USERNAME is set.
Guido van Rossumb5903ac1998-04-09 20:37:16 +000094
Tim Peters07e99cb2001-01-14 23:47:14 +000095 """
Guido van Rossumb5903ac1998-04-09 20:37:16 +000096
Tim Peters07e99cb2001-01-14 23:47:14 +000097 import os
Guido van Rossumb5903ac1998-04-09 20:37:16 +000098
Tim Peters07e99cb2001-01-14 23:47:14 +000099 for name in ('LOGNAME', 'USER', 'LNAME', 'USERNAME'):
100 user = os.environ.get(name)
101 if user:
102 return user
Guido van Rossumb5903ac1998-04-09 20:37:16 +0000103
Tim Peters07e99cb2001-01-14 23:47:14 +0000104 # If this fails, the exception will "explain" why
105 import pwd
106 return pwd.getpwuid(os.getuid())[0]
Jeremy Hylton88d23301999-10-18 22:25:22 +0000107
108# Bind the name getpass to the appropriate function
109try:
Fred Drake1191d012001-02-27 21:23:31 +0000110 import termios
Neal Norwitz201626e2002-11-20 23:15:54 +0000111 # it's possible there is an incompatible termios from the
112 # McMillan Installer, make sure we have a UNIX-compatible termios
113 termios.tcgetattr, termios.tcsetattr
114except (ImportError, AttributeError):
Tim Peters07e99cb2001-01-14 23:47:14 +0000115 try:
116 import msvcrt
117 except ImportError:
118 try:
119 from EasyDialogs import AskPassword
120 except ImportError:
121 getpass = default_getpass
122 else:
123 getpass = AskPassword
124 else:
125 getpass = win_getpass
Jeremy Hylton88d23301999-10-18 22:25:22 +0000126else:
Tim Peters07e99cb2001-01-14 23:47:14 +0000127 getpass = unix_getpass