Files
sergioandsergio 6f0ba974c7 feat(atuq): la boveda de la suite guarda las contrasenas, y el gestor de Gecko se aparta
La decima extension de atuq. Ofrece la credencial que corresponde al sitio
abierto y la pone en el formulario, pero NO puede sacar una contrasena de la
boveda por su cuenta: pregunta cuales corresponden —y eso contesta titulo y
usuario, nada mas— y la contrasena sale por otro verbo que pregunta en el
escritorio antes de contestar. Si la extension queda comprometida, o si una
pagina consigue hablarle, lo que obtiene es la lista de titulos de los sitios
que coinciden con su propia direccion.

La direccion siempre la pone el chrome y nunca la pagina. Lo unico que el
trozo que corre dentro del sitio aporta es que HAY un formulario y lo que el
usuario tipeo; si pudiera decir de quien es la pagina, podria decir que es el
banco.

Y la extension no decide nada: quien sabe que credencial va en que sitio es
la funcion del otro lado del cable. Ponerlo en JS seria reimplementar el
original y, peor, poner en la pagina la decision de a quien se le entrega una
contrasena.

EL GESTOR DE GECKO SE APAGA, pero como valor de arranque y no como politica.
Dos gestores peleando por el mismo campo es la peor experiencia que puede
tener alguien que solo quiere entrar a su correo: el sitio se rellena dos
veces, o ninguna, y no hay forma de saber cual tiene la buena. De fabrica
manda la boveda; el que prefiera el de Gecko lo prende y listo. Prohibirselo
seria decidir por el, que es lo que este fichero dice en su cabecera que atuq
no quiere ser.

Y un guardian nuevo, que corre en un segundo y sin construir nada. Una
extension esta enchufada en CUATRO lugares distintos y ninguno da error si
falta: el identificador que ella declara, la politica que la instala, el
permiso para hablarle al host, y las preferencias que la acompanan. Si falta
la politica no se instala. Si falta el permiso se instala y se conecta a
nada, en silencio, y la insignia no aparece nunca. Si faltan las preferencias
los dos gestores se pelean. Ninguno de los tres se ve como un error: se ven
como "no anda". El guardian los mira todos y trae su control negativo, que le
saca el permiso del host y exige que lo detecte.

No reemplaza al guardian de metal —servidor, navegador real, login real, el
dialogo a la vista—: lo precede, y ahorra descubrir construyendo que faltaba
un renglon en un JSON.

Los cinco verbos del otro lado ya estan en tawasuyu (bc6903f9e), con trece
tests que leen el cable.
2026-09-15 10:08:20 -04:00

134 lines
9.3 KiB
INI

// ⚠ LA PRIMERA LÍNEA DE UN FICHERO AUTOCONFIG SE IGNORA — SIEMPRE, POR DISEÑO.
// El parser de Gecko salta la línea 1 sin mirarla (herencia del formato de Netscape). Si acá
// hubiera código en vez de este comentario, no correría y no habría ningún error: el fallo más caro
// de este fichero es el que no dice nada. Por eso la línea 1 es, deliberadamente, un comentario.
// ── PREFS DE FÁBRICA ───────────────────────────────────────────────────────────────────────────
// `defaultPref` y no `lockPref`: son valores de arranque, no una cárcel. Una distro que decide POR
// el usuario y no lo deja cambiar de idea es exactamente lo que atuq no quiere ser. Lo que sí se
// bloquea con política de verdad va en `distribution/policies.json`.
// Los dientes: pestañas verticales, que Firefox trae nativas desde la 133 y vienen apagadas.
defaultPref("sidebar.revamp", true);
defaultPref("sidebar.verticalTabs", true);
// ── LOS CONTENEDORES, PRENDIDOS DE FÁBRICA (SDD 26 §6.8) ───────────────────────────────────────
// Firefox trae los contenedores en el motor desde hace años y los deja APAGADOS: para usarlos hay
// que prender una pref escondida o instalar la extensión de Mozilla. atuq los prende de fábrica
// porque son la mitad de abajo del proxy por contenedor —la que separa cookies, sesión y
// almacenamiento—; la otra mitad, la que separa por dónde SALEN los paquetes, la pone la extensión
// `proxy@atuq.tawasuyu`.
//
// Los contenedores CONCRETOS (Personal/Trabajo/Banco/Compras) no se declaran acá sino en
// `distribution/policies.json`, con la política `Containers.Default`: es el único mecanismo que
// crea contenedores en un perfil NUEVO sin que el usuario los escriba a mano. Comprobado dentro del
// artefacto, no en la documentación: `ContextualIdentityService.sys.mjs` los lee de
// `Services.policies.getActivePolicies().Containers.Default` en su `init()`.
//
// ⚠ `privacy.userContext.enabled` es la pref que ese mismo servicio observa: si alguna vez pasa a
// false, Gecko CIERRA las pestañas de contenedor y borra la lista. Va como `defaultPref` igual que
// todo lo demás —el usuario puede apagarlo—, pero apagarlo no es cosmético y por eso queda dicho.
defaultPref("privacy.userContext.enabled", true);
defaultPref("privacy.userContext.ui.enabled", true);
// La distro se actualiza con hammer. Un navegador que se auto-actualiza por su cuenta rompería el
// invariante entero: el binario dejaría de ser el que el artefacto dice que es.
defaultPref("app.update.auto", false);
defaultPref("browser.shell.checkDefaultBrowser", false);
// Telemetría. No es «apagar una casilla»: es que la distro no reporta, punto. Lo verificable de
// verdad —que la clausura no tenga a dónde reportar— es otro frente (SDD 26 §6); esto es el suelo.
defaultPref("datareporting.healthreport.uploadEnabled", false);
defaultPref("datareporting.policy.dataSubmissionEnabled", false);
defaultPref("toolkit.telemetry.enabled", false);
defaultPref("toolkit.telemetry.unified", false);
defaultPref("toolkit.telemetry.archive.enabled", false);
// Extensiones que la distro deja en `distribution/extensions/`: sin esto Gecko las instala
// DESACTIVADAS y el usuario ve una lista de complementos apagados que nunca pidió apagar.
// El otro lado de esto es `--with-unsigned-addon-scopes=app,system`, que va en el CONFIGURE de
// `recipes/firefox.toml` y por eso no se puede resolver desde acá.
defaultPref("extensions.autoDisableScopes", 0);
// ── LA FIRMA DE COMPLEMENTOS ───────────────────────────────────────────────────────────────────
// Sin esto la política de instalación muere con un error que no menciona la firma por su nombre:
// Policies: Download failed - ERROR_SIGNEDSTATE_REQUIRED - file:///…/inicio@atuq…xpi
// Firefox exige que todo XPI esté firmado por Mozilla, y `--with-unsigned-addon-scopes=app,system`
// —que sí está en el build— NO cubre el camino de instalación por política.
//
// Esta pref sólo tiene efecto en builds **unbranded**, y la nuestra lo es: `recipes/firefox.toml`
// construye con `--with-branding=browser/branding/unofficial`. O sea que esto funciona por una
// decisión que ya estaba tomada, no por una excepción nueva.
//
// ⚠ Lo que se pierde, dicho: atuq deja de exigir la firma de Mozilla para CUALQUIER complemento,
// no sólo el suyo. Es la misma postura que toman las distros que empaquetan extensiones propias, y
// la alternativa real —firmar con AMO— exige una cuenta y una revisión de Mozilla por cada versión,
// que es exactamente la dependencia externa que esta distro existe para no tener.
lockPref("xpinstall.signatures.required", false);
// La página de inicio la pone la extensión `inicio@atuq.tawasuyu` con
// `chrome_settings_overrides.homepage`; acá sólo se dice que al arrancar se abra la HOME y no la
// sesión anterior. Poner la URL a mano en `browser.startup.homepage` pelearía con la extensión, y
// gana la última que escribe: dos dueños para un valor es la forma de que el arranque sea sorpresa.
defaultPref("browser.startup.page", 1);
// ── EL CHROME ──────────────────────────────────────────────────────────────────────────────────
// Por qué acá y no en `userChrome.css`: ese fichero vive en el PERFIL y exige que el usuario prenda
// `toolkit.legacyUserProfileCustomizations.stylesheets`. atuq tiene que verse como atuq en el
// primer arranque, con un perfil recién creado, sin que nadie prenda nada. El único gancho a nivel
// de APLICACIÓN es nsIStyleSheetService, y llegar a él es la razón de `sandbox_enabled = false`.
//
// USER_SHEET y no AGENT_SHEET: es el mismo nivel de cascada que usa `userChrome.css`, así que lo
// que se escriba en `chrome/atuq.css` se comporta como la gente espera y el usuario puede seguir
// pisándolo con el suyo. AGENT_SHEET ganaría siempre y además alcanzaría al CONTENIDO de las
// páginas, que no es lo que queremos tocar.
try {
const { classes: Cc, interfaces: Ci } = Components;
// ── TESTIGO: «¿corrió este fichero?» es la PRIMERA pregunta de cualquier diagnóstico ─────────
// `defaultPref` no deja rastro en `prefs.js` (sólo se guardan los valores que difieren del
// default), así que un autoconfig que no se ejecuta es INDISTINGUIBLE de uno que se ejecutó y no
// hizo nada. Esto escribe una pref de USUARIO, que sí queda en el perfil y se puede leer desde
// fuera sin abrir el navegador.
Cc["@mozilla.org/preferences-service;1"]
.getService(Ci.nsIPrefBranch)
.setBoolPref("atuq.autoconfig.ok", true);
const sss = Cc["@mozilla.org/content/style-sheet-service;1"]
.getService(Ci.nsIStyleSheetService);
const ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
const dirs = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
// "GreD" = el directorio de la aplicación (donde vive el binario). En una instalación normal es
// el mismo que "XCurProcD"; se usa GreD porque es el que no cambia si algún día atuq se lanza
// con un `-app`.
const css = dirs.get("GreD", Ci.nsIFile);
css.append("chrome");
css.append("atuq.css");
if (css.exists()) {
const uri = ios.newFileURI(css);
if (!sss.sheetRegistered(uri, sss.USER_SHEET)) {
sss.loadAndRegisterSheet(uri, sss.USER_SHEET);
}
}
} catch (e) {
// Un fallo acá NO debe impedir que el navegador arranque: sin estilo es feo, sin navegador no hay
// nada. Queda en la consola de errores, que es donde se mira cuando «atuq se ve como Firefox».
Components.utils.reportError("atuq.cfg: no pude registrar chrome/atuq.css: " + e);
}
// ── LA BÓVEDA, Y EL GESTOR QUE SE APAGA PARA DEJARLE LUGAR (SDD-BOVEDA D7) ─────────────────────
// Las contraseñas las guarda la suite: la bóveda las ofrece en el sitio que corresponde, las
// sincroniza entre los equipos de la persona y se puede recuperar si se pierde el equipo. Gecko
// trae su propio gestor, y DOS gestores peleando por el mismo campo es la peor experiencia que
// puede tener alguien que sólo quiere entrar a su correo: el sitio se rellena dos veces, o ninguna,
// y no hay forma de saber cuál de los dos tiene la contraseña buena.
//
// Por eso de fábrica manda la bóveda. Pero va como `defaultPref` y NO como política: el que
// prefiera el de Gecko lo prende y listo. Prohibírselo sería decidir por él, que es exactamente lo
// que este fichero dice en su cabecera que atuq no quiere ser — y el costo de equivocarse acá lo
// paga alguien que se queda sin poder guardar una contraseña en su propia máquina.
defaultPref("signon.rememberSignons", false);
defaultPref("signon.autofillForms", false);
// Y que tampoco ofrezca la que ya tenga guardada de antes: el usuario que migra sus claves con
// `foreign-mozlogins` se las lleva a la bóveda, y ver las dos listas a la vez es confuso sin
// motivo.
defaultPref("signon.autofillForms.autocompleteOff", false);