diff --git a/.gitignore b/.gitignore index 947f765..e0f8ae3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ configuration.nix -hardware-configuration.nix *~ +hardware-configuration.nix diff --git a/config/fudo/mail-container.nix b/config/fudo/mail-container.nix index e12b9ff..c918116 100644 --- a/config/fudo/mail-container.nix +++ b/config/fudo/mail-container.nix @@ -160,22 +160,6 @@ in rec { }; }; - # users = { - # users = { - # ${container-mail-user} = { - # isSystemUser = true; - # uid = container-mail-user-id; - # group = "mailer"; - # }; - # }; - - # groups = { - # ${container-mail-group} = { - # members = ["mailer"]; - # }; - # }; - # }; - fudo.mail-server = { enable = true; hostname = cfg.hostname; diff --git a/config/fudo/mail/dovecot.nix b/config/fudo/mail/dovecot.nix index ae994b7..8724f07 100644 --- a/config/fudo/mail/dovecot.nix +++ b/config/fudo/mail/dovecot.nix @@ -232,6 +232,10 @@ in { user = root } + service imap { + vsz_limit = 1024M + } + namespace inbox { separator = "/" inbox = yes diff --git a/config/fudo/mail/postfix.nix b/config/fudo/mail/postfix.nix index d05bf6d..7b96652 100644 --- a/config/fudo/mail/postfix.nix +++ b/config/fudo/mail/postfix.nix @@ -130,7 +130,7 @@ in { virtual = '' ${make-user-aliases cfg.user-aliases} - ${make-alias-users cfg.local-domains cfg.alias-users} + ${make-alias-users ([cfg.domain] ++ cfg.local-domains) cfg.alias-users} ''; sslCert = cfg.postfix.ssl-certificate; diff --git a/config/fudo/prometheus.nix b/config/fudo/prometheus.nix index 54e5b6a..7951932 100644 --- a/config/fudo/prometheus.nix +++ b/config/fudo/prometheus.nix @@ -111,6 +111,8 @@ in { webExternalUrl = "https://${cfg.hostname}"; + listenAddress = "127.0.0.1:9090"; + scrapeConfigs = [ { job_name = "docker"; diff --git a/config/fudo/system.nix b/config/fudo/system.nix index b25aaf4..5303a6c 100644 --- a/config/fudo/system.nix +++ b/config/fudo/system.nix @@ -20,6 +20,12 @@ in { default = []; example = ["redis.service"]; }; + + tmpOnTmpfs = mkOption { + type = types.bool; + description = "Put tmp filesystem on tmpfs (needs enough RAM)."; + default = true; + }; }; config = mkIf cfg.disableTransparentHugePages { diff --git a/config/fudo/vpn.nix b/config/fudo/vpn.nix new file mode 100644 index 0000000..1467fbb --- /dev/null +++ b/config/fudo/vpn.nix @@ -0,0 +1,73 @@ +{ pkgs, lib, config, ... }: + +with lib; +let + cfg = config.fudo.vpn; + + peerOpts = { peer-name, ... }: { + options = with types; { + public-key = mkOption { + type = str; + description = "Peer public key."; + }; + + allowed-ips = mkOption { + type = listOf str; + description = "List of allowed IP ranges from which this peer can connect."; + example = [ "10.100.0.0/16" ]; + default = []; + }; + }; + }; + +in { + options.fudo.vpn = with types; { + enable = mkEnableOption "Enable Fudo VPN"; + + ips = mkOption { + type = str; + description = "IP range to assign this interface."; + default = "10.100.0.0/16"; + }; + + private-key-file = mkOption { + type = str; + description = "Path to the secret key (generated with wg [genkey/pubkey])."; + example = "/path/to/secret.key"; + }; + + listen-port = mkOption { + type = port; + description = "Port on which to listen for incoming connections."; + default = 51820; + }; + + peers = mkOption { + type = loaOf (submodule peerOpts); + description = "A list of peers allowed to connect."; + default = {}; + example = { + peer0 = { + public-key = "xyz"; + allowed-ips = ["10.100.1.0/24"]; + }; + }; + }; + }; + + config = mkIf cfg.enable { + networking.wireguard = { + enable = true; + interfaces.wgtun0 = { + generatePrivateKeyFile = false; + ips = [ cfg.ips ]; + listenPort = cfg.listen-port; + peers = mapAttrsToList (peer-name: peer-config: { + publicKey = peer-config.public-key; + allowedIPs = peer-config.allowed-ips; + }) cfg.peers; + privateKeyFile = cfg.private-key-file; + }; + }; + }; +} diff --git a/config/local.nix b/config/local.nix index b1f2ec5..e2fdf34 100644 --- a/config/local.nix +++ b/config/local.nix @@ -23,6 +23,7 @@ with lib; ./fudo/secure-dns-proxy.nix ./fudo/slynk.nix ./fudo/system.nix + ./fudo/vpn.nix ./fudo/webmail.nix ./informis/cl-gemini.nix diff --git a/defaults.nix b/defaults.nix index 37e0b4a..d6b19cd 100644 --- a/defaults.nix +++ b/defaults.nix @@ -46,13 +46,16 @@ ipfs iptables jdk + jq kerberos + leiningen libisofs libstdcxxHook lispPackages.alexandria lispPackages.cl-ppcre lispPackages.clx lispPackages.quicklisp + lsof lshw mkpasswd ncurses5 @@ -68,7 +71,6 @@ pinentry.curses pv pwgen - racket ruby rustc sbcl diff --git a/fudo/alias-users.nix b/fudo/alias-users.nix index a0bd333..bbced07 100644 --- a/fudo/alias-users.nix +++ b/fudo/alias-users.nix @@ -15,4 +15,6 @@ in { system = admin-users; asdf = ["mswaffer@gmail.com" "bouncetest@fudo.org"]; + + network-info = ["niten@fudo.org"]; } diff --git a/fudo/email.nix b/fudo/email.nix index e622728..11c7c40 100644 --- a/fudo/email.nix +++ b/fudo/email.nix @@ -1,15 +1,10 @@ # Fudo email settings { config }: -let - mail-hostname = "france.fudo.org"; - -in { - +{ domain = "fudo.org"; local-domains = [ - "mail.fudo.org" "${config.networking.hostName}" "selby.ca" "mail.selby.ca" diff --git a/fudo/profiles/common-ui.nix b/fudo/profiles/common-ui.nix index 424fbbf..e016ef8 100644 --- a/fudo/profiles/common-ui.nix +++ b/fudo/profiles/common-ui.nix @@ -34,6 +34,7 @@ let mplayer mpv pdftk + racket redshift rhythmbox shotwell @@ -86,15 +87,17 @@ in mkIf ((profile == "desktop") || (profile == "laptop")) { displayManager.gdm.enable = true; - displayManager.defaultSession = "gnome"; + # displayManager.defaultSession = "gnome"; - windowManager.session = pkgs.lib.singleton { - name = "stumpwm"; - start = '' - ${pkgs.lispPackages.stumpwm}/bin/stumpwm & - waidPID=$! - ''; - }; + windowManager.stumpwm.enable = true; + + # windowManager.session = pkgs.lib.singleton { + # name = "stumpwm"; + # start = '' + # ${pkgs.lispPackages.stumpwm}/bin/stumpwm & + # waidPID=$! + # ''; + # }; } else { layout = "us"; xkbVariant = "dvp"; diff --git a/fudo/profiles/server.nix b/fudo/profiles/server.nix index 7e1b7c3..b99c451 100644 --- a/fudo/profiles/server.nix +++ b/fudo/profiles/server.nix @@ -53,8 +53,9 @@ in { systemPackages = with pkgs; [ ldns ldns.examples - test-config + racket-minimal reboot-if-necessary + test-config ]; noXlibs = true; @@ -66,8 +67,8 @@ in { networking = { networkmanager.enable = mkForce false; - }; - + } +; boot.tmpOnTmpfs = true; services.xserver.enable = false; diff --git a/fudo/system-users.nix b/fudo/system-users.nix index 21830ef..4ac5c76 100644 --- a/fudo/system-users.nix +++ b/fudo/system-users.nix @@ -13,4 +13,9 @@ description = "User Database Reader"; hashed-password = "{SSHA}IVKhrB+wMOCI/CCzbJW8sNDbH67ZTMBv"; }; + + jabber = { + description = "Jabber Server"; + hashed-password = "{SSHA}KlQpe0n+NP0WcJUniHTD+JzUugzLo8Ib"; + }; } diff --git a/fudo/users.nix b/fudo/users.nix index 565f14b..b7c943e 100644 --- a/fudo/users.nix +++ b/fudo/users.nix @@ -422,4 +422,11 @@ common-name = "Kevin"; hashed-password = "{SSHA}1onx6HPMKCJvmLnRf1tiWFJ1D92DEtnl"; }; + + netinfo = { + uid = 10113; + group = "fudo"; + common-name = "Network Info Mailer"; + hashed-password = "{SSHA}UQHfW0IzjIbRU6VV+DraxvZFWt0to3oc"; + }; } diff --git a/hosts/atom.nix b/hosts/atom.nix index 2a8aef4..efd4498 100644 --- a/hosts/atom.nix +++ b/hosts/atom.nix @@ -34,7 +34,7 @@ in { }; fudo.laptop.use-network-manager = false; - fudo.common.enable-gui = false; + fudo.common.enable-gui = true; hardware.opengl.driSupport32Bit = true; hardware.opengl.extraPackages32 = with pkgs.pkgsi686Linux; [ libva ]; diff --git a/hosts/france.nix b/hosts/france.nix index 4158f01..72f8aec 100644 --- a/hosts/france.nix +++ b/hosts/france.nix @@ -4,7 +4,7 @@ with lib; let domain = "fudo.org"; hostname = "france.${domain}"; - mail-hostname = hostname; + mail-hostname = "mail.${domain}"; host_ipv4 = "208.81.3.117"; # Use a special IP for git.fudo.org, since it needs to be SSH-able git_ipv4 = "208.81.3.126"; @@ -30,8 +30,16 @@ in { imports = [ ../hardware-configuration.nix - ../defaults.nix + ./france/jabber.nix + ]; + + environment.systemPackages = with pkgs; [ + docker + lxd + multipath-tools + nix-prefetch-docker + tshark ]; # services.openssh = { @@ -62,14 +70,6 @@ in { ]; }; - environment.systemPackages = with pkgs; [ - docker - lxd - multipath-tools - nix-prefetch-docker - tshark - ]; - fudo.prometheus = { enable = true; hostname = "metrics.fudo.org"; @@ -186,16 +186,9 @@ in { # sslKey = (acme-private-key hostname); # sslCACert = acme-ca; - # TODO: loop over v4 and v6 IPs. listen-uris = [ "ldap:///" "ldaps:///" - # "ldap://${host_ipv4}/" - # "ldaps://${host_ipv4}/" - # "ldap://localhost/" - # "ldaps://localhost/" - # "ldap://127.0.1.1/" - # "ldaps://127.0.1.1/" "ldapi:///" ]; @@ -274,7 +267,21 @@ in { "webmail.test.fudo.org" = { title = "Fudo Webmail"; favicon = "/etc/nixos/static/fudo.org/favicon.ico"; - mail-server = "mail.fudo.org"; + mail-server = mail-hostname; + domain = "fudo.org"; + edit-mode = "Plain"; + database = { + name = "webmail"; + hostname = "localhost"; + user = "webmail"; + password-file = "/srv/webmail/secure/db.passwd"; + }; + }; + + "webmail.fudo.org" = { + title = "Fudo Webmail"; + favicon = "/etc/nixos/static/fudo.org/favicon.ico"; + mail-server = mail-hostname; domain = "fudo.org"; edit-mode = "Plain"; database = { @@ -288,7 +295,20 @@ in { "webmail.test.selby.ca" = { title = "Selby Webmail"; favicon = "/etc/nixos/static/selby.ca/favicon.ico"; - mail-server = "mail.selby.ca"; + mail-server = mail-hostname; + domain = "selby.ca"; + database = { + name = "webmail"; + hostname = "localhost"; + user = "webmail"; + password-file = "/srv/webmail/secure/db.passwd"; + }; + }; + + "webmail.selby.ca" = { + title = "Selby Webmail"; + favicon = "/etc/nixos/static/selby.ca/favicon.ico"; + mail-server = mail-hostname; domain = "selby.ca"; database = { name = "webmail"; @@ -305,7 +325,7 @@ in { hostname = "chat.fudo.org"; site-name = "Fudo Chat"; - smtp-server = "france.fudo.org"; + smtp-server = "mail.fudo.org"; smtp-user = "chat"; smtp-password-file = "/srv/mattermost/secure/smtp.passwd"; database = { @@ -342,7 +362,7 @@ in { useDHCP = false; # TODO: fix IPv6 - enableIPv6 = false; + enableIPv6 = true; # Create a bridge for VMs to use macvlans = { @@ -460,14 +480,10 @@ in { }; }; - fudo.system = { - disableTransparentHugePages = true; - postHugePageServices = ["redis.service"]; - }; - security.acme.certs = { "archiva.fudo.org".email = config.fudo.common.admin-email; "git.fudo.org".email = config.fudo.common.admin-email; + "mail.fudo.org".email = config.fudo.common.admin-email; }; services = { @@ -494,6 +510,15 @@ in { ''; }; }; + + # Needed to grab a cert for the mail server. + "mail.fudo.org" = { + enableACME = true; + # Stopped relocating all because we need /metrics/... paths to remain unforwarded + locations."/" = { + return = "301 https://webmail.fudo.org$request_uri"; + }; + }; }; }; }; @@ -510,6 +535,7 @@ in { environment = { # Not directly connected to the world anyway SSL_ENABLED = "false"; + PROXY_BASE_URL = "https://archiva.fudo.org/"; }; }; }; @@ -520,7 +546,7 @@ in { fudo.minecraft-server = { enable = true; - package = pkgs.minecraft-server_1_16_1; + package = pkgs.minecraft-server_1_16_2; data-dir = minecraft-data-dir; world-name = "selbyland"; motd = "Welcome to the Selby Minecraft server."; diff --git a/hosts/france/jabber.nix b/hosts/france/jabber.nix new file mode 100644 index 0000000..df4c16b --- /dev/null +++ b/hosts/france/jabber.nix @@ -0,0 +1,222 @@ +{ pkgs, lib, config, ... }: + +with lib; +let + backplane-auth = "/etc/nixos/static/backplane-auth.scm"; + + cert-basedir = "/var/lib/ejabberd/certs"; + + target-certs = ["key" "cert" "chain" "fullchain"]; + + cert-origin = hostname: filename: "/var/lib/acme/${hostname}/${filename}.pem"; + cert-target = hostname: filename: "${cert-basedir}/${hostname}-${filename}.pem"; + + move-server-certs = hostnames: + let + move-server-cert = hostname: + map (filename: '' + ensure_exists ${cert-origin hostname filename} + cp -L ${cert-origin hostname filename} ${cert-target hostname filename} + '') + target-certs; + in pkgs.writeShellScript "move-server-certs" '' + function ensure_exists() { + FILENAME=$1 + if [ ! -e $FILENAME ]; then + echo "file does not exist: $FILENAME" + exit 1 + fi + } + + if [ -d ${cert-basedir} ]; then + mkdir ${cert-basedir} + fi + + ${concatStringsSep "\n" (concatMap move-server-cert hostnames)} + + chown -R ${config.services.ejabberd.user}:${config.services.ejabberd.group} ${cert-basedir} + + exit 0 + ''; + + remove-server-certs = pkgs.writeShellScript "ejabberd-rm-combined-certs" '' + rm ${cert-basedir}/*.pem + ''; + + +in { + config = { + + security.acme.certs."fudo.im".email = "admin@fudo.org"; + security.acme.certs."backplane.fudo.org".email = "admin@fudo.org"; + + systemd.services = { + ejabberd-generate-certs = { + enable = true; + description = "Generate required SSL certs for ejabberd."; + wantedBy = [ "ejabberd.service" ]; + after = [ + "acme-backplane.fudo.org.service" + "acme-fudo.im.service" + ]; + + serviceConfig = { + Type = "oneshot"; + ExecStart = "${move-server-certs ["fudo.im" "backplane.fudo.org"]}"; + RemainAfterExit = true; + ExecStop = remove-server-certs; + StandardOutput = "journal"; + }; + }; + + ejabberd = { + requires = [ "ejabberd-generate-certs.service" ]; + environment = { + FUDO_HOST_PASSWD_FILE = "/srv/jabber/secret/hosts-passwd.scm"; + FUDO_SERVICE_PASSWD_FILE = "/srv/jabber/secret/services-passwd.scm"; + }; + }; + }; + + services = { + nginx = { + virtualHosts = { + "backplane.fudo.org" = { + enableACME = true; + }; + + "fudo.im" = { + enableACME = true; + }; + }; + }; + + ejabberd = { + enable = true; + + configFile = pkgs.writeText "ejabberd-config.yml" (builtins.toJSON { + loglevel = 4; + + access_rules = { + c2s = { allow = "all"; }; + announce = { allow = "admin"; }; + configure = { allow = "admin"; }; + pubsub_createnode = { allow = "local"; }; + }; + + acl = { + admin = { + user = [ + "niten@fudo.org" + ]; + }; + }; + + hosts = [ + "fudo.im" + "backplane.fudo.org" + ]; + + listen = [ + { + port = 5222; + module = "ejabberd_c2s"; + ip = "0.0.0.0"; + starttls = true; + starttls_required = true; + } + ]; + + certfiles = + concatMap (hostname: map (filename: cert-target hostname filename) target-certs) + ["fudo.im" "backplane.fudo.org"]; + + host_config = { + "fudo.im" = { + auth_method = "ldap"; + ldap_servers = ["auth.fudo.org"]; + ldap_port = 389; + ldap_rootdn = "cn=jabber,dc=fudo,dc=org"; + ldap_password = fileContents /srv/jabber/secret/ldap.passwd; + ldap_base = "ou=members,dc=fudo,dc=org"; + ldap_filter = "(objectClass=posixAccount)"; + ldap_uids = { uid = "%u"; }; + + modules = { + mod_adhoc = {}; + mod_announce = {}; + mod_avatar = {}; + mod_blocking = {}; + mod_caps = {}; + mod_carboncopy = {}; + mod_client_state = {}; + mod_configure = {}; + mod_disco = {}; + mod_fail2ban = {}; + mod_last = {}; + mod_offline = { + access_max_user_messages = 5000; + }; + mod_ping = {}; + mod_privacy = {}; + mod_private = {}; + mod_pubsub = { + access_createnode = "pubsub_createnode"; + ignore_pep_from_offline = true; + last_item_cache = false; + plugins = [ + "flat" + "pep" + ]; + }; + mod_roster = {}; + mod_stream_mgmt = {}; + mod_time = {}; + mod_vcard = { + search = false; + }; + mod_vcard_xupdate = {}; + mod_version = {}; + }; + }; + + "backplane.fudo.org" = { + auth_method = "external"; + extauth_program = "${pkgs.guile}/bin/guile -s ${backplane-auth}"; + extauth_pool_size = 3; + auth_use_cache = true; + + modules = { + mod_adhoc = {}; + mod_caps = {}; + mod_carboncopy = {}; + mod_client_state = {}; + mod_configure = {}; + mod_disco = {}; + mod_fail2ban = {}; + mod_last = {}; + mod_offline = { + access_max_user_messages = 5000; + }; + mod_ping = {}; + mod_pubsub = { + access_createnode = "pubsub_createnode"; + ignore_pep_from_offline = true; + last_item_cache = false; + plugins = [ + "flat" + "pep" + ]; + }; + mod_roster = {}; + mod_stream_mgmt = {}; + mod_time = {}; + mod_version = {}; + }; + }; + }; + }); + }; + }; + }; +} diff --git a/hosts/procul.nix b/hosts/procul.nix index 2276e63..ead5d09 100644 --- a/hosts/procul.nix +++ b/hosts/procul.nix @@ -55,6 +55,13 @@ in { }; }; + # For WireGuard + nat = { + enable = true; + externalInterface = "extif0"; + internalInterfaces = [ "wgtun0" ]; + }; + interfaces = { extif0 = { # result of: @@ -119,6 +126,8 @@ in { ]; }; + system.tmpOnTmpfs = false; + secure-dns-proxy = { enable = true; upstream-dns = [ "https://cloudflare-dns.com/dns-query" ]; @@ -263,6 +272,26 @@ in { }; }; + fudo.vpn = { + enable = true; + ips = "10.100.0.0/16"; + private-key-file = "/srv/wireguard/secure/secret.key"; + peers = { + peter = { + allowed-ips = [ "10.100.1.0/24" ]; + public-key = "d1NfRFWRkcKq2gxvqfMy7Oe+JFYf5DjomnsTyisvgB4="; + }; + ken = { + allowed-ips = [ "10.100.2.0/24" ]; + public-key = "y294rTCK0iSRhA6EIOErPzEuqzJMuYAG4XbHasySMVU="; + }; + helen = { + allowed-ips = [ "10.100.3.0/24" ]; + public-key = "7Hdko6RibhIYdoPLWXGwmElY5vKvZ+rURmqFTDUfC2w="; + }; + }; + }; + informis.cl-gemini = { enable = true; diff --git a/hosts/spark.nix b/hosts/spark.nix index bc2adae..e86fc06 100644 --- a/hosts/spark.nix +++ b/hosts/spark.nix @@ -6,20 +6,42 @@ let in { imports = [ ../defaults.nix - ../networks/sea.fudo.org.nix - ../profiles/desktop.nix ../hardware-configuration.nix ]; + nixpkgs.config.permittedInsecurePackages = [ + "google-chrome-81.0.4044.138" + ]; + + environment.systemPackages = with pkgs; [ + # androidStudioPackages.canary + androidenv.androidPkgs_9_0.platform-tools + cmake + glxinfo + opencv4 + qemu_kvm + signal-cli + signal-desktop + teamviewer + thunderbird + wireshark + ]; + + fudo.common = { + profile = "desktop"; + site = "seattle"; + enable-gui = true; + }; + # Use the systemd-boot EFI boot loader. boot.loader.systemd-boot.enable = true; boot.loader.efi = { canTouchEfiVariables = true; - efibootmgr = { - efiDisk = "/dev/sda1"; - }; + }; - # efiSysMountPoint = "/boot/efi"; + programs = { + adb.enable = true; + bash.enableCompletion = true; }; networking.hostName = hostname; @@ -29,4 +51,13 @@ in { hardware.opengl.driSupport32Bit = true; hardware.opengl.driSupport = true; + services = { + trezord.enable = true; + }; + + virtualisation.libvirtd = { + enable = true; + qemuPackage = pkgs.qemu_kvm; + onShutdown = "shutdown"; + }; } diff --git a/packages/archiva.nix b/packages/archiva.nix new file mode 100644 index 0000000..054cc8d --- /dev/null +++ b/packages/archiva.nix @@ -0,0 +1,27 @@ +{ pkgs, fetchurl, ... }: + +let + version = "2.2.5"; + url = "https://mirrors.sonic.net/apache/archiva/${version}/binaries/apache-archiva-${version}-bin.tar.gz"; + sha256 = "01119af2d9950eacbcce0b7f8db5067b166ad26c1e1701bef829105441bb6e29"; + +in pkgs.stdenv.mkDerivation { + name = "archiva-${version}"; + + src = builtins.fetchurl { + url = url; + sha256 = sha256; + }; + + phases = ["installPhase"]; + + buildInputs = with pkgs; [ stdenv procps makeWrapper ]; + + installPhase = '' + mkdir $out + tar -xzf $src + cd apache-archiva-${version} + mv {LICENSE,NOTICE,apps,bin,conf,contexts,lib,logs,temp} $out + makeWrapper $out/bin/archiva $out/bin/archivaWrapped --set PATH ${pkgs.stdenv.lib.makeBinPath [ pkgs.procps ]} + ''; +} diff --git a/packages/local.nix b/packages/local.nix index 7e72555..16637da 100644 --- a/packages/local.nix +++ b/packages/local.nix @@ -35,6 +35,18 @@ }; })); + minecraft-server_1_16_2 = let + version = "1.16.2"; + url = "https://launcher.mojang.com/v1/objects/c5f6fb23c3876461d46ec380421e42b289789530/server.jar"; + sha256 = "0fbghwrj9b2y9lkn2b17id4ghglwvyvcc8065h582ksfz0zys0i9"; + in (pkgs.minecraft-server.overrideAttrs (oldAttrs: rec { + name = "minecraft-server-${version}"; + inherit version; + src = pkgs.fetchurl { + inherit url sha256; + }; + })); + postgresql_11_gssapi = pkgs.postgresql_11.overrideAttrs (oldAttrs: rec { configureFlags = oldAttrs.configureFlags ++ [ "--with-gssapi" ]; buildInputs = oldAttrs.buildInputs ++ [ pkgs.krb5 ]; @@ -54,5 +66,10 @@ stdenv = pkgs.stdenv; fetchgit = pkgs.fetchgit; }; + + fudo-service = import ./fudo-service.nix { + fetchgit = pkgs.fetchgit; + pkgs = pkgs; + }; }; } diff --git a/static/backplane-auth.scm b/static/backplane-auth.scm new file mode 100644 index 0000000..f23ee80 --- /dev/null +++ b/static/backplane-auth.scm @@ -0,0 +1,66 @@ +(use-modules (srfi srfi-1) + (srfi srfi-13) + (ice-9 binary-ports) + (ice-9 textual-ports) + (ice-9 format) + (ice-9 regex) + (rnrs bytevectors)) + +(define *host-passwd-file* (getenv "FUDO_HOST_PASSWD_FILE")) +(when (not *host-passwd-file*) + (format (current-error-port "FUDO_HOST_PASSWD_FILE not set~%")) + (exit 1)) + +(define *service-passwd-file* (getenv "FUDO_SERVICE_PASSWD_FILE")) +(when (not *service-passwd-file*) + (format (current-error-port "FUDO_SERVICE_PASSWD_FILE not set~%")) + (exit 1)) + +(define host-regex "^host-([a-zA-Z][a-zA-Z0-9_-]+)$") +(define service-regex "^service-([a-zA-Z][a-zA-Z0-9_-]+)$") + +(define (make-verifier passwd-file) + (let ((passwds (load passwd-file))) + (lambda (username passwd) + (and (> (string-length passwd) 6) + (equal? (assoc-ref passwds username) passwd))))) + +(define (make-authenticator host-verifier service-verifier) + (lambda (username hostname password) + (cond ((string-match host-regex username) + (host-verifier (match:substring (string-match host-regex username) 1) + password)) + + ((string-match service-regex username) + (service-verifier (match:substring (string-match service-regex username) 1) + password)) + + (else #f)))) + +(define (make-handler handlers) + (lambda (request) + (let ((op (assoc-ref handlers (first request)))) + (if op + (apply op (cdr request)) + #f)))) + +(define (auth-listener handler) + (let ((in (current-input-port)) + (out (current-output-port))) + (while #t + (let ((size (bytevector-u16-ref (get-bytevector-n in 2) 0 (endianness big))) + (response (make-bytevector 4 0))) + (bytevector-u8-set! response 1 #x02) + (if (handler (string-split (get-string-n in size) #\:)) + (begin (bytevector-u8-set! response 3 #x01) + (put-bytevector out response 0 4) + (force-output out)) + (begin (bytevector-u8-set! response 3 #x00) + (put-bytevector out response 0 4) + (force-output out))))))) + +(auth-listener + (make-handler + (list (cons "auth" + (make-authenticator (make-verifier *host-passwd-file*) + (make-verifier *service-passwd-file*))))))