[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