getpass - Chiede all'utente una password senza emettere caratteri

Scopo Chiede all'utente un valore, in genere una password, senza emettere sullo schermo i cartteri digitati nella console
Versione Python 1.5.2 e superiore

Molti programmi che interagiscono con l'utente attraverso un terminale devono richiedere una password senza mostrare quello l'utente sta digitando. Il modulo getpass fornisce un modo portabile per gestire in sicurezza queste richieste

Esempio

La funzione getpass() stampa un prompt che legge l'input digitato dall'utente, fino a che egli non preme Invio. Quanto digitato viene poi passato come stringa al chiamante

import getpass

p = getpass.getpass()
print 'Hai digitato:', p

Il prompt predefinito, se nulla è stato specificato dal chiamante, è "Password:".

$ python getpass_defaults.py

Password:
Hai digitato: segreta

Il prompt predefinto può essere modificato con qualsiasi valore il proprio programma necessiti.

import getpass

p = getpass.getpass(prompt="Qual'è il tuo colore preferito? ")
if p.lower() == 'blu':
    print 'Corretto, puoi proseguire.'
else:
    print 'Auuuuugh!'

Non si consiglia uno schema di autenticazione così debole, ma si vuole solo illustrare il punto.

$ python getpass_prompt.py
Qual'è il tuo colore preferito?
Corretto, puoi proseguire.

$ python getpass_prompt.py
Qual'è il tuo colore preferito?
Auuuuugh!

Nella modalità predefinita getpass() utilizza stdout per stampare la stringa prompt. Per un programma che debba produrre un output utilizzabile su sys.stdout, spesso è meglio indirizzare il prompt verso una altro flusso tipo sys.stderr.

import getpass
import sys

p = getpass.getpass(stream=sys.stderr)
print 'Hai digitato:', p

In questo modo l'output standard può essere rediretto (ad un pipe oppure ad un file) senza vedere il prompt per la password. Il valore digitato dall'utente non viene comunque ripetuto sullo schermo.

$ python getpass_stream.py > /dev/null

Password:

Utilizzare getpass Senza un Terminale

Su Unix, getpass() richiede un tty (comando Unix che restituisce il nome del terminale corrente - n.d.t) che possa controllare tramite termios (una struttura dati utilizzata da tutte le chiamate di libreria del terminale - n.d.t.) in modo che la ripetizione dei caratteri sullo schermo possa essere disabilitata. Il che significa che i valorei non saranno letti da un flusso non di terminale rediretto verso lo standard input.

$ echo "sekret" | python getpass_defaults.py
Traceback (most recent call last):
 File "getpass_defaults.py", line 34, in
   p = getpass.getpass()
 File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/getpass.py", line 32, in unix_getpass
   old = termios.tcgetattr(fd)     # a copy to save
termios.error: (25, 'Inappropriate ioctl for device')

Spetta al chiamante rilevare quando il flusso in input non è un tty ed utilizzare un metodo alternativo per la lettura in quel caso

import getpass
import sys

if sys.stdin.isatty():
    p = getpass.getpass('Si usa getpass: ')
else:
    print 'Si usa readline'
    p = sys.stdin.readline().rstrip()

print 'Letto: ', p

Con un tty

$ python getpass_noterminal.py
Si usa getpass:
Letto:  segreta

Senza un tty

$ echo "segreta" | python getpass_noterminal.py
Si usa readline:
Letto:  segreta

Vedere anche:

weakref
La documentazione della libreria standard per questo modulo.
readline
Libreria per prompt interattivo