Saltar al contenido

El servicio de secretos

Linux no tiene un almacén: tiene una especificación y un servicio que puede estar o no. Qué es D-Bus, qué define el protocolo, y por qué eso cambia la forma de programar contra él.

Qué hay debajo

La primera fila es la diferencia de fondo. En los otros dos sistemas, guardar un secreto es una llamada al sistema que siempre existe. En Linux es una conversación con otro programa, y las conversaciones pueden no tener interlocutor.

El modelo

Suficientemente parecido a los otros dos para que una librería lo unifique:

  • Una colección es un conjunto de secretos, y la que importa es la que se llama por omisión —normalmente el «anillo de inicio de sesión»—. Puede estar bloqueada o desbloqueada, y ésa es la palabra clave del nivel 37.3.
  • Un elemento es una etiqueta, unos atributos y el secreto.
  • Los atributos son un diccionario libre que tú eliges, y la búsqueda es por atributos. Es más flexible que macOS —donde la identidad era servicio y cuenta— y por eso las librerías construyen atributos equivalentes para que el código sea el mismo.
Rust
// lo que una librería manda por debajo: un diccionario de atributos// { "service": "dev.wandres.miapp", "username": "ana@ejemplo.com" }// y busca por ese mismo diccionario

La consecuencia práctica es buena: si usas una librería, los identificadores que diseñaste en el nivel 34.3 funcionan igual aquí. Lo que cambia no es la forma, es cuándo falla.

Quién puede leer

La respuesta honesta, y es la más débil de los tres sistemas:

Así que el modelo de amenaza de Linux es el de Windows: protege de otros usuarios y de las copias, no de otros programas del mismo usuario. Y la conclusión de diseño es la misma que la del nivel 36.1: que el secreto valga poco fuera de su sitio.

Programar contra algo que puede no estar

La diferencia que sí cambia el código, y es la única de esta lección que hay que escribir:

Rust
// en Linux, "no hay servicio" es un resultado posible de cualquier operación,// incluida guardar — no solo de leerpub fn guardar(cuenta: &str, secreto: &str) -> Result<(), Error> {    match Entry::new(SERVICIO, cuenta)?.set_password(secreto) {        Ok(()) => Ok(()),        Err(e) if sin_servicio(&e) => Err(Error::SinAlmacen),   // nivel 37.4        Err(e) => Err(e.into()),    }}

En macOS y Windows, guardar prácticamente no falla. En Linux sí, y falla por una razón estructural —no hay servicio— que ninguna cantidad de reintentos arregla. Una aplicación que asume que guardar funciona se queda sin plan justo cuando el usuario acaba de iniciar sesión y espera que se recuerde.