[Python-Dev] getpass and stdin
Shaya Potter
spotter at cs.columbia.edu
Tue Feb 26 18:43:59 CET 2008
Leif Walsh wrote:
> 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.
the -p <PASSWD> option is not good on multi user systems
the -p <PASSFILE> option is not particularly good on NFS based systems
(have to trust every user on every machine with access to NFS share)
and now, assuming what you say is part of the design behind the code
what's the point of this part of the code
>> try:
>> fd = sys.stdin.fileno()
>> except:
>> return default_getpass(prompt)
>>
i.e. the exception handler, default_getpass() is always going to read
from stdin at the end of the day.
line = sys.stdin.readline()
I'm assuming I'm missing something
More information about the Python-Dev
mailing list