ssh.scm
| 1 | ;;; Guix Home Manager. |
| 2 | ;;; |
| 3 | ;;; Copyright © 2019 Julien Lepiller <julien@lepiller.eu> |
| 4 | ;;; |
| 5 | ;;; This program is free software: you can redistribute it and/or modify |
| 6 | ;;; it under the terms of the GNU General Public License as published by |
| 7 | ;;; the Free Software Foundation, either version 3 of the License, or |
| 8 | ;;; (at your option) any later version. |
| 9 | ;;; |
| 10 | ;;; This program is distributed in the hope that it will be useful, |
| 11 | ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 13 | ;;; GNU General Public License for more details. |
| 14 | ;;; |
| 15 | ;;; You should have received a copy of the GNU General Public License |
| 16 | ;;; along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 17 | |
| 18 | (define-module (home ssh) |
| 19 | #:use-module (guix build utils) |
| 20 | #:use-module (guix gexp) |
| 21 | #:use-module (guix records) |
| 22 | #:use-module (gnu packages lxde) |
| 23 | #:use-module (ice-9 match) |
| 24 | #:export (ssh-configuration |
| 25 | ssh-configuration-authorized-keys |
| 26 | ssh-configuration-known-hosts |
| 27 | ssh-configuration-hosts |
| 28 | ssh-configuration-default-host |
| 29 | |
| 30 | ssh-host-configuration |
| 31 | ssh-host-configuration-host-name |
| 32 | ssh-host-configuration-identity-file |
| 33 | ssh-host-configuration-name |
| 34 | ssh-host-configuration-port |
| 35 | ssh-host-configuration-user |
| 36 | |
| 37 | ssh-known-host-configuration |
| 38 | ssh-known-host-configuration-names |
| 39 | ssh-known-host-configuration-algo |
| 40 | ssh-known-host-configuration-key |
| 41 | |
| 42 | ssh-home)) |
| 43 | |
| 44 | (define-record-type* <ssh-host-configuration> |
| 45 | ssh-host-configuration make-ssh-host-configuration |
| 46 | ssh-host-configuration? |
| 47 | (host-name ssh-host-configuration-host-name |
| 48 | (default "*")) |
| 49 | (identity-file ssh-host-configuration-identity-file |
| 50 | (default #f)) |
| 51 | (name ssh-host-configuration-name |
| 52 | (default "*")) |
| 53 | (port ssh-host-configuration-port |
| 54 | (default #f)) |
| 55 | (user ssh-host-configuration-user |
| 56 | (default #f))) |
| 57 | |
| 58 | (define (ssh-host config) |
| 59 | (match config |
| 60 | (($ <ssh-host-configuration> host-name identity-file name port user) |
| 61 | (string-append "Host " name "\n" |
| 62 | " HostName " host-name "\n" |
| 63 | (if identity-file |
| 64 | (string-append " IdentityFile " identity-file "\n") |
| 65 | "") |
| 66 | (if port |
| 67 | (string-append " Port " port "\n") |
| 68 | "") |
| 69 | (if user |
| 70 | (string-append " User " user "\n") |
| 71 | ""))))) |
| 72 | |
| 73 | (define (default-ssh config) |
| 74 | (match config |
| 75 | (($ <ssh-host-configuration> host-name identity-file name port user) |
| 76 | (string-append |
| 77 | (if identity-file |
| 78 | (string-append "IdentityFile " identity-file "\n") |
| 79 | "") |
| 80 | (if port |
| 81 | (string-append "Port " port "\n") |
| 82 | "") |
| 83 | (if user |
| 84 | (string-append "User " user "\n") |
| 85 | ""))))) |
| 86 | |
| 87 | (define (generate-ssh-hosts lst) |
| 88 | (string-join (map ssh-host lst) "\n\n")) |
| 89 | |
| 90 | (define (generate-ssh-config hosts default-host) |
| 91 | (string-append (generate-ssh-hosts hosts) |
| 92 | "\n\n" |
| 93 | (default-ssh default-host))) |
| 94 | |
| 95 | (define-record-type* <ssh-known-host-configuration> |
| 96 | ssh-known-host-configuration make-ssh-known-host-configuration |
| 97 | ssh-known-host-configuration? |
| 98 | (names ssh-known-host-configuration-names) |
| 99 | (algo ssh-known-host-configuration-algo |
| 100 | (default "ecdsa-sha2-nistp256")) |
| 101 | (key ssh-known-host-configuration-key)) |
| 102 | |
| 103 | |
| 104 | (define (known-host config) |
| 105 | (match config |
| 106 | (($ <ssh-known-host-configuration> names algo key) |
| 107 | (string-append |
| 108 | (match names |
| 109 | ((name) name) |
| 110 | ((n1 ns ...) |
| 111 | (string-join names ","))) |
| 112 | " " algo " " key)))) |
| 113 | |
| 114 | (define-record-type* <ssh-configuration> |
| 115 | ssh-configuration make-ssh-configuration |
| 116 | ssh-configuration? |
| 117 | (authorized-keys ssh-configuration-authorized-keys |
| 118 | (default '())) |
| 119 | (known-hosts ssh-configuration-known-hosts |
| 120 | (default '())) |
| 121 | (hosts ssh-configuration-hosts |
| 122 | (default '())) |
| 123 | (default-host ssh-configuration-default-host |
| 124 | (default #f))) |
| 125 | |
| 126 | (define (generate-ssh-authorized-keys lst) |
| 127 | (string-join lst "\n")) |
| 128 | |
| 129 | (define (generate-ssh-known-hosts lst) |
| 130 | (string-join (map known-host lst) "\n")) |
| 131 | |
| 132 | (define (ssh-home config) |
| 133 | (computed-file "ssh-home" |
| 134 | (match config |
| 135 | (($ <ssh-configuration> authorized-keys known-hosts hosts default-host) |
| 136 | #~(let ((config #$(plain-file "config" (generate-ssh-config hosts default-host))) |
| 137 | (known-hosts #$(plain-file "known_hosts" |
| 138 | (generate-ssh-known-hosts known-hosts))) |
| 139 | (authorized-keys #$(plain-file |
| 140 | "authorized_keys" |
| 141 | (generate-ssh-authorized-keys authorized-keys))) |
| 142 | (ssh-dir (string-append #$output "/.ssh"))) |
| 143 | (use-modules (guix build utils)) |
| 144 | (mkdir-p ssh-dir) |
| 145 | (copy-file authorized-keys (string-append ssh-dir "/authorized_keys")) |
| 146 | (copy-file known-hosts (string-append ssh-dir "/known_hosts")) |
| 147 | (copy-file config (string-append ssh-dir "/config"))))) |
| 148 | #:options |
| 149 | '(#:local-build? #t |
| 150 | #:modules ((guix build utils))))) |
| 151 |