diff --git a/mail-server/dovecot.nix b/mail-server/dovecot.nix index e899487..3f8d8af 100644 --- a/mail-server/dovecot.nix +++ b/mail-server/dovecot.nix @@ -65,6 +65,13 @@ let # Prevent world-readable password files, even temporarily. umask 077 + prepend_scheme() { + case "$1" in + {*}*) printf '%s' "$1" ;; + *) printf '{CRYPT}%s' "$1" ;; + esac + } + for f in ${ builtins.toString (lib.mapAttrsToList (name: _: passwordFiles."${name}") cfg.accounts) }; do @@ -81,7 +88,7 @@ let if lib.elem name accountsWithPlaintextPasswordFiles then "${name}:${"$(sed -n '1{p;p;q}' ${passwordFiles."${name}"} | ${lib.getExe' config.services.dovecot2.package "doveadm"} pw)"}::::::" else - "${name}:{CRYPT}${"$(head -n 1 ${passwordFiles."${name}"})"}::::::" + "${name}:${"$(prepend_scheme \"$(head -n 1 ${passwordFiles."${name}"})\")"}::::::" ) cfg.accounts )} EOF diff --git a/tests/internal.nix b/tests/internal.nix index 62dc6d8..e9fe366 100644 --- a/tests/internal.nix +++ b/tests/internal.nix @@ -41,7 +41,19 @@ let mkpasswd -s <<<"$password" > $out ''; + hashPasswordWithScheme = + password: + pkgs.runCommand "password-${password}-hashed-with-scheme" + { + buildInputs = [ pkgs.dovecot ]; + inherit password; + } + '' + printf "$password\n$password\n" | doveadm -O pw -s SSHA256 > $out + ''; + hashedPasswordFile = hashPassword "my-password"; + hashedPasswordFileWithScheme = hashPasswordWithScheme "my-password"; passwordFile = pkgs.writeText "password" "my-password"; in { @@ -100,6 +112,9 @@ in "user3@example.com" = { passwordFile = "/run/passwords/user3"; }; + "user4@example.com" = { + hashedPasswordFile = hashedPasswordFileWithScheme; + }; "send-only@example.com" = { hashedPasswordFile = hashPassword "send-only"; sendOnly = true; @@ -258,6 +273,25 @@ in ) ) + with subtest("user with scheme-prefixed hashedPasswordFile can send and receive"): + machine.succeed( + " ".join( + [ + "mail-check send-and-read", + "--smtp-port 587", + "--smtp-starttls", + "--smtp-host localhost", + "--imap-host localhost", + "--imap-username user4@example.com", + "--from-addr user4@example.com", + "--to-addr user4@example.com", + "--src-password-file ${passwordFile}", + "--dst-password-file ${passwordFile}", + "--ignore-dkim-spf", + ] + ) + ) + with subtest("imap port 143 is closed and imaps is serving SSL"): machine.wait_for_closed_port(143) machine.wait_for_open_port(993)