Leif Walsh wrote:
On Sun, Feb 24, 2008 at 1:02 PM, Shaya Potter
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