<commit_before>{ config, pkgs, ... }:

with pkgs.lib;

let

  cfg  = config.services.openssh;
  cfgc = config.programs.ssh;

  nssModulesPath = config.system.nssModules.path;

  permitRootLoginCheck = v:
    v == "yes" ||
    v == "without-password" ||
    v == "forced-commands-only" ||
    v == "no";

  hostKeyTypeNames = {
    dsa1024  = "dsa";
    rsa1024  = "rsa";
    ecdsa521 = "ecdsa";
  };

  hostKeyTypeBits = {
    dsa1024  = 1024;
    rsa1024  = 1024;
    ecdsa521 = 521;
  };

  hktn = attrByPath [cfg.hostKeyType] (throw "unknown host key type `${cfg.hostKeyType}'") hostKeyTypeNames;
  hktb = attrByPath [cfg.hostKeyType] (throw "unknown host key type `${cfg.hostKeyType}'") hostKeyTypeBits;

  userOptions = {
    openssh.authorizedKeys = {

      preserveExistingKeys = mkOption {
        type = types.bool;
        default = true;
        description = ''
          If this option is enabled, the keys specified in
          <literal>keys</literal> and/or <literal>keyFiles</literal> will be
          placed in a special section of the user's authorized_keys file
          and any existing keys will be preserved. That section will be
          regenerated each time NixOS is activated. However, if
          <literal>preserveExisting</literal> isn't enabled, the complete file
          will be generated, and any user modifications will be wiped out.
        '';
      };

      keys = mkOption {
        type = types.listOf types.string;
        default = [];
        description = ''
          A list of verbatim OpenSSH public keys that should be inserted into the
          user's authorized_keys file. You can combine the <literal>keys</literal> and
          <literal>keyFiles</literal> options.
        '';
      };

      keyFiles = mkOption {
        #type = types.listOf types.string;
        default = [];
        description = ''
          A list of files each containing one OpenSSH public keys that should be
          inserted into the user's authorized_keys file. You can combine
          the <literal>keyFiles</literal> and
          <literal>keys</literal> options.
        '';
      };

    };
  };

  mkAuthkeyScript =
    let
      marker1 = "### NixOS auto-added key. Do not edit!";
      marker2 = "### NixOS will regenerate this file. Do not edit!";
      users = map (userName: getAttr userName config.users.extraUsers) (attrNames config.users.extraUsers);
      usersWithKeys = flip filter users (u:
        length u.openssh.authorizedKeys.keys != 0 || length u.openssh.authorizedKeys.keyFiles != 0
      );
      userLoop = flip concatMapStrings usersWithKeys (u:
        let
          authKeys = concatStringsSep "," u.openssh.authorizedKeys.keys;
          authKeyFiles = concatStringsSep " " u.openssh.authorizedKeys.keyFiles;
          preserveExisting = if u.openssh.authorizedKeys.preserveExistingKeys then "true" else "false";
        in ''
          mkAuthKeysFile "${u.name}" "${authKeys}" "${authKeyFiles}" "${preserveExisting}"
        ''
      );
    in ''
      mkAuthKeysFile() {
        local userName="$1"
        local authKeys="$2"
        local authKeyFiles="$3"
        local preserveExisting="$4"

        eval authfile=~$userName/.ssh/authorized_keys
        mkdir -p "$(dirname $authfile)"
        touch "$authfile"
        if [ "$preserveExisting" == false ]; then
          rm -f "$authfile"
          echo "${marker2}" > "$authfile"
        else
          sed -i '/${marker1}/ d' "$authfile"
        fi
        IFS=,
        for f in $authKeys; do
          echo "$f ${marker1}" >> "$authfile"
        done
        unset IFS
        for f in $authKeyFiles; do
          if [ -f "$f" ]; then
            echo "$(cat "$f") ${marker1}" >> "$authfile"
          fi
        done
      }

      exec >> /tmp/log 2>&1
      set -x
      ${userLoop}
    '';


in

{

  ###### interface

  options = {

    services.openssh = {

      enable = mkOption {<commit_msg>modules/services/networking/ssh/sshd.nix: don't write debug output to /tmp/log<commit_after>{ config, pkgs, ... }:

with pkgs.lib;

let

  cfg  = config.services.openssh;
  cfgc = config.programs.ssh;

  nssModulesPath = config.system.nssModules.path;

  permitRootLoginCheck = v:
    v == "yes" ||
    v == "without-password" ||
    v == "forced-commands-only" ||
    v == "no";

  hostKeyTypeNames = {
    dsa1024  = "dsa";
    rsa1024  = "rsa";
    ecdsa521 = "ecdsa";
  };

  hostKeyTypeBits = {
    dsa1024  = 1024;
    rsa1024  = 1024;
    ecdsa521 = 521;
  };

  hktn = attrByPath [cfg.hostKeyType] (throw "unknown host key type `${cfg.hostKeyType}'") hostKeyTypeNames;
  hktb = attrByPath [cfg.hostKeyType] (throw "unknown host key type `${cfg.hostKeyType}'") hostKeyTypeBits;

  userOptions = {
    openssh.authorizedKeys = {

      preserveExistingKeys = mkOption {
        type = types.bool;
        default = true;
        description = ''
          If this option is enabled, the keys specified in
          <literal>keys</literal> and/or <literal>keyFiles</literal> will be
          placed in a special section of the user's authorized_keys file
          and any existing keys will be preserved. That section will be
          regenerated each time NixOS is activated. However, if
          <literal>preserveExisting</literal> isn't enabled, the complete file
          will be generated, and any user modifications will be wiped out.
        '';
      };

      keys = mkOption {
        type = types.listOf types.string;
        default = [];
        description = ''
          A list of verbatim OpenSSH public keys that should be inserted into the
          user's authorized_keys file. You can combine the <literal>keys</literal> and
          <literal>keyFiles</literal> options.
        '';
      };

      keyFiles = mkOption {
        #type = types.listOf types.string;
        default = [];
        description = ''
          A list of files each containing one OpenSSH public keys that should be
          inserted into the user's authorized_keys file. You can combine
          the <literal>keyFiles</literal> and
          <literal>keys</literal> options.
        '';
      };

    };
  };

  mkAuthkeyScript =
    let
      marker1 = "### NixOS auto-added key. Do not edit!";
      marker2 = "### NixOS will regenerate this file. Do not edit!";
      users = map (userName: getAttr userName config.users.extraUsers) (attrNames config.users.extraUsers);
      usersWithKeys = flip filter users (u:
        length u.openssh.authorizedKeys.keys != 0 || length u.openssh.authorizedKeys.keyFiles != 0
      );
      userLoop = flip concatMapStrings usersWithKeys (u:
        let
          authKeys = concatStringsSep "," u.openssh.authorizedKeys.keys;
          authKeyFiles = concatStringsSep " " u.openssh.authorizedKeys.keyFiles;
          preserveExisting = if u.openssh.authorizedKeys.preserveExistingKeys then "true" else "false";
        in ''
          mkAuthKeysFile "${u.name}" "${authKeys}" "${authKeyFiles}" "${preserveExisting}"
        ''
      );
    in ''
      mkAuthKeysFile() {
        local userName="$1"
        local authKeys="$2"
        local authKeyFiles="$3"
        local preserveExisting="$4"

        eval authfile=~$userName/.ssh/authorized_keys
        mkdir -p "$(dirname $authfile)"
        touch "$authfile"
        if [ "$preserveExisting" == false ]; then
          rm -f "$authfile"
          echo "${marker2}" > "$authfile"
        else
          sed -i '/${marker1}/ d' "$authfile"
        fi
        IFS=,
        for f in $authKeys; do
          echo "$f ${marker1}" >> "$authfile"
        done
        unset IFS
        for f in $authKeyFiles; do
          if [ -f "$f" ]; then
            echo "$(cat "$f") ${marker1}" >> "$authfile"
          fi
        done
      }

      ${userLoop}
    '';


in

{

  ###### interface

  options = {

    services.openssh = {

      enable = mkOption {
{'fraction_non_alphanumeric': 0.11708058793715155, 'fraction_numerical': 0.011657374556512924, 'mean_word_length': 2.1737032569360677, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 44, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '238198', 'n_tokens_mistral': 2417, 'n_tokens_neox': 2307, 'n_words': 657}