Cómo ocultar contraseñas en nuestro código Elisp con auth.el
La situación hipotética es la siguiente. Imaginemos que estamos escribiendo alguna función
en Emacs Lisp que incluye como cadena de texto cierta información que nos conviene ofuscar
de alguna manera, tal un nombre de usuario y una contraseña, bien porque queremos publicar
ese código en la web o lo tenemos en la nube y (por muy segura que sea nuestra nube)
queremos curarnos en salud. La solución en GNU Emacs es muy sencilla gracias a la
biblioteca auth.el
, que nos resultará muy útil a la hora de extraer información
contenida en el archivo ~/.authinfo
y aplicarla a nuestra función como variables
locales, de forma que no tengamos que poner una contraseña de manera literal.
El archivo .authinfo
Si ya somos habituales usuarios del cliente emacsiano de correo y noticias Gnus,
estaremos familiarizados con el fichero .authinfo
que reside en nuestro directorio
local. Si no, aquí sigue un breve recordatorio. authinfo
se emplea para almacenar todo
tipo de usuarios y contraseñas (incluso nuestro usuario y contraseña de administrador del
equipo donde estamos), si bien aquí nos centraremos (siguiendo con nuestro caso
hipotético) en una imaginaria cuenta de correo correofeten.xyz
donde el usuario
imaginario es «donnadie» y su contraseña «pi_31416
». La sintaxis de authinfo
está muy
definida y requiere un campo para cada uno de esos elementos y otros necesarios a la hora
de identificarse. En este caso concreto, la línea que tendríamos que añadir para ese
usuario sería algo así como:
machine correofeten.xyz login donnadie password pi_31416 port 993
Y lo que necesitamos añadir a nuestra función como cadena de texto son precisamente los
campos login
y password
. ¿Cómo lo logramos? Bien, con la biblioteca auth.el
,
incluída de fábrica en Emacs, resulta bastante simple, y así lo veremos a continuación.
auth.el
al rescate
La biblioteca auth.el
nos proporciona la utilísima función auth-source-search
, que
buscará en nuestro documento authinfo
aquella línea que contenga la propiedad requerida,
y nos devolverá una lista cuyo primer elemento es una «plist», es decir, una «lista de
propiedades» en la jerga elispiana.
Si queremos pasar a nuestra función el usuario y la contraseña como variables locales,
podemos empezar definiendo (recuérdese que ponemos la expresión let
con asterisco para
que se respete el orden de variables):
(let* ((autent (car (auth-source-search :host "correofeten.xyz" :requires '(user secret))))
Es decir, la primera variable, que hemos llamado autent
nos devolverá una lista de
propiedades a partir de la línea de nuestro authinfo
que contenga el :host
«correofeten.xyz». Ya sólo nos quedaría (las dos siguientes variables) extraer de esa
lista la propiedad :user
para el usuario y la propiedad :secret
, que almacena la
cadena de la contraseña, teniendo en cuenta que ésta última será una función lambda que
debe evaluarse para obtener dicha cadena:
(mi-usuario (plist-get autent :user)) (mi-password (funcall (plist-get autent :secret))))
Y para comprobar que ambas variables recogen la información correcta, cerramos nuestra
expresión let
con un mensaje. Evaluamos toda la expresión.
(let* ((autent (car (auth-source-search :host "correofeten.xyz" :requires '(user secret)))) (mi-usuario (plist-get autent :user)) (mi-password (funcall (plist-get autent :secret)))) (message "El usuario es %s y la contraseña es %s" mi-usuario mi-password))
"El usuario es donnadie y la contraseña es pi_31416"
Una vez que hemos comprobado que las variables almacenan bien ambos datos sensibles, ya
podemos extender a conveniencia nuestra función o código que necesiten incluirlos, sin
temor de que estén al alcance de ojos maliciosos, puesto que los tenemos guardados en
nuestro archivo authinfo
.
∞
Publicado: 12/11/20
Última actualización: 16/08/23
Esta obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial 4.0 Internacional.