No final, você precisa chamar a função crypt(3)
do libcrypt
(que nos sistemas GNU como o Linux Mint vem com o GNU libc) com a senha como primeiro argumento e o hash ( $6$...
) como segundo argumento.
python
é uma dessas ferramentas que expõe essa função, então você pode fazer:
HASH='$6$...' python2 -c 'import crypt, os, getpass
print(crypt.crypt(getpass.getpass(), os.environ["HASH"]))'
E se a saída corresponder ao hash, essa foi a senha correta.
$HASH
acima pode ser o hash completo (como $6$rounds=1234$somesalt$6eFBNhSgwEwdfZBHueBedpcqaVKGcV2DJy/tQMFd3JL88hwvgTkISJShnOUrbtP1fRs8I9rGIdsgWCoiujxD2/
) ou apenas a parte dele até o nível mais à direita $
, ou seja, o sal e a contagem de round opcional ( $6$rounds=1234$somesalt$
).
Ou você pode fazer a verificação em python
:
HASH='$6$...' python2 -c '
import crypt, os, getpass
hash = os.environ["HASH"]
if crypt.crypt(getpass.getpass(), hash) == hash:
print "OK"
else:
print "Wrong password"'
(então, obviamente, $HASH
tem que conter o hash completo).
Com python
, você também pode chamar funções de bibliotecas arbitrárias usando o módulo ctypes
. Assim, outra maneira de chamar a função crypt()
do sistema (não que você precise como crypt
é um dos módulos padrão, é que eu estava com a impressão de que o módulo crypt
veio com seu próprio código separado crypt()
implementation) é algo como:
HASH='$6$...' python2 -c '
from ctypes import *
import os, getpass
l = CDLL("libcrypt.so.1")
l.crypt.restype = c_char_p
print l.crypt(getpass.getpass(), os.environ["HASH"])'