blob: 918f2edc76246c8cc4477c1f4dbfb3a5f38269d7 [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
Jeremy Hylton88d23301999-10-18 22:25:22 +000016def unix_getpass(prompt='Password: '):
Tim Peters07e99cb2001-01-14 23:47:14 +000017 """Prompt for a password, with echo turned off.
Guido van Rossumb5903ac1998-04-09 20:37:16 +000018
Tim Peters07e99cb2001-01-14 23:47:14 +000019 Restore terminal settings at end.
20 """
Guido van Rossumb5903ac1998-04-09 20:37:16 +000021
Tim Peters07e99cb2001-01-14 23:47:14 +000022 try:
23 fd = sys.stdin.fileno()
24 except:
25 return default_getpass(prompt)
Guido van Rossumb5903ac1998-04-09 20:37:16 +000026
Tim Peters07e99cb2001-01-14 23:47:14 +000027 getpass = default_getpass
28 old = termios.tcgetattr(fd) # a copy to save
29 new = old[:]
Guido van Rossumb5903ac1998-04-09 20:37:16 +000030
Tim Peters07e99cb2001-01-14 23:47:14 +000031 new[3] = new[3] & ~TERMIOS.ECHO # 3 == 'lflags'
32 try:
33 termios.tcsetattr(fd, TERMIOS.TCSADRAIN, new)
34 passwd = _raw_input(prompt)
35 finally:
36 termios.tcsetattr(fd, TERMIOS.TCSADRAIN, old)
Guido van Rossumb5903ac1998-04-09 20:37:16 +000037
Tim Peters07e99cb2001-01-14 23:47:14 +000038 sys.stdout.write('\n')
39 return passwd
Guido van Rossumb5903ac1998-04-09 20:37:16 +000040
41
42def win_getpass(prompt='Password: '):
Tim Peters07e99cb2001-01-14 23:47:14 +000043 """Prompt for password with echo off, using Windows getch()."""
44 import msvcrt
45 for c in prompt:
46 msvcrt.putch(c)
47 pw = ""
48 while 1:
49 c = msvcrt.getch()
50 if c == '\r' or c == '\n':
51 break
52 if c == '\003':
53 raise KeyboardInterrupt
54 if c == '\b':
55 pw = pw[:-1]
56 else:
57 pw = pw + c
58 msvcrt.putch('\r')
59 msvcrt.putch('\n')
60 return pw
Guido van Rossumb5903ac1998-04-09 20:37:16 +000061
62
Guido van Rossumfb9b7fd1998-04-13 20:22:21 +000063def default_getpass(prompt='Password: '):
Tim Peters07e99cb2001-01-14 23:47:14 +000064 print "Warning: Problem with getpass. Passwords may be echoed."
65 return _raw_input(prompt)
Guido van Rossum1a7bab01998-07-28 19:28:43 +000066
67
68def _raw_input(prompt=""):
Tim Peters07e99cb2001-01-14 23:47:14 +000069 # A raw_input() replacement that doesn't save the string in the
70 # GNU readline history.
71 import sys
72 prompt = str(prompt)
73 if prompt:
74 sys.stdout.write(prompt)
75 line = sys.stdin.readline()
76 if not line:
77 raise EOFError
78 if line[-1] == '\n':
79 line = line[:-1]
80 return line
Guido van Rossumfb9b7fd1998-04-13 20:22:21 +000081
82
Guido van Rossumb5903ac1998-04-09 20:37:16 +000083def getuser():
Tim Peters07e99cb2001-01-14 23:47:14 +000084 """Get the username from the environment or password database.
Guido van Rossumb5903ac1998-04-09 20:37:16 +000085
Tim Peters07e99cb2001-01-14 23:47:14 +000086 First try various environment variables, then the password
87 database. This works on Windows as long as USERNAME is set.
Guido van Rossumb5903ac1998-04-09 20:37:16 +000088
Tim Peters07e99cb2001-01-14 23:47:14 +000089 """
Guido van Rossumb5903ac1998-04-09 20:37:16 +000090
Tim Peters07e99cb2001-01-14 23:47:14 +000091 import os
Guido van Rossumb5903ac1998-04-09 20:37:16 +000092
Tim Peters07e99cb2001-01-14 23:47:14 +000093 for name in ('LOGNAME', 'USER', 'LNAME', 'USERNAME'):
94 user = os.environ.get(name)
95 if user:
96 return user
Guido van Rossumb5903ac1998-04-09 20:37:16 +000097
Tim Peters07e99cb2001-01-14 23:47:14 +000098 # If this fails, the exception will "explain" why
99 import pwd
100 return pwd.getpwuid(os.getuid())[0]
Jeremy Hylton88d23301999-10-18 22:25:22 +0000101
102# Bind the name getpass to the appropriate function
103try:
Tim Peters07e99cb2001-01-14 23:47:14 +0000104 import termios, TERMIOS
Jeremy Hylton88d23301999-10-18 22:25:22 +0000105except ImportError:
Tim Peters07e99cb2001-01-14 23:47:14 +0000106 try:
107 import msvcrt
108 except ImportError:
109 try:
110 from EasyDialogs import AskPassword
111 except ImportError:
112 getpass = default_getpass
113 else:
114 getpass = AskPassword
115 else:
116 getpass = win_getpass
Jeremy Hylton88d23301999-10-18 22:25:22 +0000117else:
Tim Peters07e99cb2001-01-14 23:47:14 +0000118 getpass = unix_getpass