~malept/ubuntu/lucid/python2.6/dev-dependency-fix

« back to all changes in this revision

Viewing changes to Lib/getpass.py

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2009-02-13 12:51:00 UTC
  • Revision ID: james.westby@ubuntu.com-20090213125100-uufgcb9yeqzujpqw
Tags: upstream-2.6.1
ImportĀ upstreamĀ versionĀ 2.6.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"""Utilities to get a password and/or the current user name.
 
2
 
 
3
getpass(prompt[, stream]) - Prompt for a password, with echo turned off.
 
4
getuser() - Get the user name from the environment or password database.
 
5
 
 
6
GetPassWarning - This UserWarning is issued when getpass() cannot prevent
 
7
                 echoing of the password contents while reading.
 
8
 
 
9
On Windows, the msvcrt module will be used.
 
10
On the Mac EasyDialogs.AskPassword is used, if available.
 
11
 
 
12
"""
 
13
 
 
14
# Authors: Piers Lauder (original)
 
15
#          Guido van Rossum (Windows support and cleanup)
 
16
#          Gregory P. Smith (tty support & GetPassWarning)
 
17
 
 
18
import os, sys, warnings
 
19
 
 
20
__all__ = ["getpass","getuser","GetPassWarning"]
 
21
 
 
22
 
 
23
class GetPassWarning(UserWarning): pass
 
24
 
 
25
 
 
26
def unix_getpass(prompt='Password: ', stream=None):
 
27
    """Prompt for a password, with echo turned off.
 
28
 
 
29
    Args:
 
30
      prompt: Written on stream to ask for the input.  Default: 'Password: '
 
31
      stream: A writable file object to display the prompt.  Defaults to
 
32
              the tty.  If no tty is available defaults to sys.stderr.
 
33
    Returns:
 
34
      The seKr3t input.
 
35
    Raises:
 
36
      EOFError: If our input tty or stdin was closed.
 
37
      GetPassWarning: When we were unable to turn echo off on the input.
 
38
 
 
39
    Always restores terminal settings before returning.
 
40
    """
 
41
    fd = None
 
42
    tty = None
 
43
    try:
 
44
        # Always try reading and writing directly on the tty first.
 
45
        fd = os.open('/dev/tty', os.O_RDWR|os.O_NOCTTY)
 
46
        tty = os.fdopen(fd, 'w+', 1)
 
47
        input = tty
 
48
        if not stream:
 
49
            stream = tty
 
50
    except EnvironmentError, e:
 
51
        # If that fails, see if stdin can be controlled.
 
52
        try:
 
53
            fd = sys.stdin.fileno()
 
54
        except:
 
55
            passwd = fallback_getpass(prompt, stream)
 
56
        input = sys.stdin
 
57
        if not stream:
 
58
            stream = sys.stderr
 
59
 
 
60
    if fd is not None:
 
61
        passwd = None
 
62
        try:
 
63
            old = termios.tcgetattr(fd)     # a copy to save
 
64
            new = old[:]
 
65
            new[3] &= ~termios.ECHO  # 3 == 'lflags'
 
66
            try:
 
67
                termios.tcsetattr(fd, termios.TCSADRAIN, new)
 
68
                passwd = _raw_input(prompt, stream, input=input)
 
69
            finally:
 
70
                termios.tcsetattr(fd, termios.TCSADRAIN, old)
 
71
        except termios.error, e:
 
72
            if passwd is not None:
 
73
                # _raw_input succeeded.  The final tcsetattr failed.  Reraise
 
74
                # instead of leaving the terminal in an unknown state.
 
75
                raise
 
76
            # We can't control the tty or stdin.  Give up and use normal IO.
 
77
            # fallback_getpass() raises an appropriate warning.
 
78
            del input, tty  # clean up unused file objects before blocking
 
79
            passwd = fallback_getpass(prompt, stream)
 
80
 
 
81
    stream.write('\n')
 
82
    return passwd
 
83
 
 
84
 
 
85
def win_getpass(prompt='Password: ', stream=None):
 
86
    """Prompt for password with echo off, using Windows getch()."""
 
87
    if sys.stdin is not sys.__stdin__:
 
88
        return fallback_getpass(prompt, stream)
 
89
    import msvcrt
 
90
    for c in prompt:
 
91
        msvcrt.putch(c)
 
92
    pw = ""
 
93
    while 1:
 
94
        c = msvcrt.getch()
 
95
        if c == '\r' or c == '\n':
 
96
            break
 
97
        if c == '\003':
 
98
            raise KeyboardInterrupt
 
99
        if c == '\b':
 
100
            pw = pw[:-1]
 
101
        else:
 
102
            pw = pw + c
 
103
    msvcrt.putch('\r')
 
104
    msvcrt.putch('\n')
 
105
    return pw
 
106
 
 
107
 
 
108
def fallback_getpass(prompt='Password: ', stream=None):
 
109
    warnings.warn("Can not control echo on the terminal.", GetPassWarning,
 
110
                  stacklevel=2)
 
111
    if not stream:
 
112
        stream = sys.stderr
 
113
    print >>stream, "Warning: Password input may be echoed."
 
114
    return _raw_input(prompt, stream)
 
115
 
 
116
 
 
117
def _raw_input(prompt="", stream=None, input=None):
 
118
    # A raw_input() replacement that doesn't save the string in the
 
119
    # GNU readline history.
 
120
    if not stream:
 
121
        stream = sys.stderr
 
122
    if not input:
 
123
        input = sys.stdin
 
124
    prompt = str(prompt)
 
125
    if prompt:
 
126
        stream.write(prompt)
 
127
        stream.flush()
 
128
    line = input.readline()
 
129
    if not line:
 
130
        raise EOFError
 
131
    if line[-1] == '\n':
 
132
        line = line[:-1]
 
133
    return line
 
134
 
 
135
 
 
136
def getuser():
 
137
    """Get the username from the environment or password database.
 
138
 
 
139
    First try various environment variables, then the password
 
140
    database.  This works on Windows as long as USERNAME is set.
 
141
 
 
142
    """
 
143
 
 
144
    import os
 
145
 
 
146
    for name in ('LOGNAME', 'USER', 'LNAME', 'USERNAME'):
 
147
        user = os.environ.get(name)
 
148
        if user:
 
149
            return user
 
150
 
 
151
    # If this fails, the exception will "explain" why
 
152
    import pwd
 
153
    return pwd.getpwuid(os.getuid())[0]
 
154
 
 
155
# Bind the name getpass to the appropriate function
 
156
try:
 
157
    import termios
 
158
    # it's possible there is an incompatible termios from the
 
159
    # McMillan Installer, make sure we have a UNIX-compatible termios
 
160
    termios.tcgetattr, termios.tcsetattr
 
161
except (ImportError, AttributeError):
 
162
    try:
 
163
        import msvcrt
 
164
    except ImportError:
 
165
        try:
 
166
            from EasyDialogs import AskPassword
 
167
        except ImportError:
 
168
            getpass = fallback_getpass
 
169
        else:
 
170
            getpass = AskPassword
 
171
    else:
 
172
        getpass = win_getpass
 
173
else:
 
174
    getpass = unix_getpass