[Python-Dev] getpass and stdin

Leif Walsh adlaiff6 at gmail.com
Tue Feb 26 18:17:32 CET 2008


On Sun, Feb 24, 2008 at 1:02 PM, Shaya Potter <spotter at cs.columbia.edu> wrote:
> [please cc me on responses]
>
>  I was wondering if getpass could be changed to enable piped stdin to work.
>
>  For instance, the getmail program can read my email password in via
>  stdin using getpass functionality.
>
>  However, if I do
>
>  echo password | getmail4
>
>  it will fail due to stdin not being a terminal and therefore not being
>  able to do a old = termios.tcgetattr(fd) on it.
>
>   From what I can tell, the point of this is to only to prevent echoing
>  the password, which isn't a problem in the echo case I give (especially
>  if using bash, then it wont even be on the cmdline when run from a
>  script as it's a builtin, script can also read in the password and store
>  it in memory).
>
>  currently the code is
>
>  -----
>  def unix_getpass(prompt='Password: '):
>      """Prompt for a password, with echo turned off.
>
>      Restore terminal settings at end.
>      """
>
>      try:
>          fd = sys.stdin.fileno()
>      except:
>          return default_getpass(prompt)
>
>      old = termios.tcgetattr(fd)     # a copy to save
>      new = old[:]
>
>      new[3] = new[3] & ~termios.ECHO # 3 == 'lflags'
>      try:
>          termios.tcsetattr(fd, termios.TCSADRAIN, new)
>          passwd = _raw_input(prompt)
>      finally:
>          termios.tcsetattr(fd, termios.TCSADRAIN, old)
>
>      sys.stdout.write('\n')
>      return passwd
>  -----
>
>  it would seem that if the tcgetattr() line is moved into the initial
>  try, my echo case would work as expected (as it would fail, but be
>  caught and then just run default_getpass() (which should just read it
>  from stdin).
>
>  Is there any reason not to do it this way?

It's certainly possible to have getpass() read from stdin
automatically, but it's traditionally understood that having it read
from a tty is much, much better.  Suppose your program were meant to
use getpass, and then read a file from stdin.  Now, all of a sudden,
you miss the first line of the file, and it becomes your password, for
no particular reason.  getpass() works the way it does because it's
been working that way in C for decades.

If you really want to maintain a 'configuration file' for your
password, or have it available on command line, try adding an option
like -p <PASSWD> or -p <PASSFILE> to whatever program you're writing.

-- 
Cheers,
Leif


More information about the Python-Dev mailing list