]> granicus.if.org Git - python/commitdiff
Fixes issue7208 - getpass would still allow the password to be echoed on
authorGregory P. Smith <greg@mad-scientist.com>
Sat, 31 Oct 2009 21:26:08 +0000 (21:26 +0000)
committerGregory P. Smith <greg@mad-scientist.com>
Sat, 31 Oct 2009 21:26:08 +0000 (21:26 +0000)
Solaris due to not flushing the input buffer.

This change also incorporates some additional getpass implementation
suggestions for security based on an analysis of getpass.c linked to from the
issue.

Lib/getpass.py

index 9a1273cbc82b50a192c874e4654949a6ad4b30f7..4745ea944ce258af7461e4783f3134c5960cce57 100644 (file)
@@ -62,12 +62,16 @@ def unix_getpass(prompt='Password: ', stream=None):
         try:
             old = termios.tcgetattr(fd)     # a copy to save
             new = old[:]
-            new[3] &= ~termios.ECHO  # 3 == 'lflags'
+            new[3] &= ~(termios.ECHO|termios.ISIG)  # 3 == 'lflags'
+            tcsetattr_flags = termios.TCSAFLUSH
+            if hasattr(termios, 'TCSASOFT'):
+                tcsetattr_flags |= termios.TCSASOFT
             try:
-                termios.tcsetattr(fd, termios.TCSADRAIN, new)
+                termios.tcsetattr(fd, tcsetattr_flags, new)
                 passwd = _raw_input(prompt, stream, input=input)
             finally:
-                termios.tcsetattr(fd, termios.TCSADRAIN, old)
+                termios.tcsetattr(fd, tcsetattr_flags, old)
+                stream.flush()  # issue7208
         except termios.error, e:
             if passwd is not None:
                 # _raw_input succeeded.  The final tcsetattr failed.  Reraise
@@ -125,6 +129,7 @@ def _raw_input(prompt="", stream=None, input=None):
     if prompt:
         stream.write(prompt)
         stream.flush()
+    # NOTE: The Python C API calls flockfile() (and unlock) during readline.
     line = input.readline()
     if not line:
         raise EOFError