diff options
author | EuAndreh <eu@euandre.org> | 2023-03-13 14:20:36 -0300 |
---|---|---|
committer | EuAndreh <eu@euandre.org> | 2023-03-13 14:23:09 -0300 |
commit | 830185d4e914e5e33fc27fa865dc441305eaf8a8 (patch) | |
tree | 52024fa8aad0da935071bc509565dd601a84fbec /src/org/euandre/queue.scm | |
parent | queue.scm: Name the "Spam" folder by its "special" name, "Junk" (diff) | |
download | package-repository-830185d4e914e5e33fc27fa865dc441305eaf8a8.tar.gz package-repository-830185d4e914e5e33fc27fa865dc441305eaf8a8.tar.xz |
git mv src/xyz/euandreh/* src/org/euandre/
Diffstat (limited to 'src/org/euandre/queue.scm')
-rw-r--r-- | src/org/euandre/queue.scm | 1394 |
1 files changed, 1394 insertions, 0 deletions
diff --git a/src/org/euandre/queue.scm b/src/org/euandre/queue.scm new file mode 100644 index 0000000..9ab0b27 --- /dev/null +++ b/src/org/euandre/queue.scm @@ -0,0 +1,1394 @@ +(define-module (org euandre queue) + #:use-module ((gnu build linux-container) #:prefix container:) + #:use-module ((guix licenses) #:prefix license:) + #:use-module ((srfi srfi-1) #:prefix srfi-1:) + #:use-module (guix build-system gnu) + #:use-module (guix build-system python) + #:use-module (guix build-system trivial) + #:use-module (guix download) + #:use-module (guix gexp) + #:use-module (guix git-download) + #:use-module (guix least-authority) + #:use-module (guix packages) + #:use-module (guix records) + #:use-module (guix utils) + #:use-module (gnu) + #:use-module (gnu packages admin) + #:use-module (gnu packages check) + #:use-module (gnu packages cpio) + #:use-module (gnu packages cups) + #:use-module (gnu packages cyrus-sasl) + #:use-module (gnu packages dbm) + #:use-module (gnu packages image) + #:use-module (gnu packages glib) + #:use-module (gnu packages gnome) + #:use-module (gnu packages mail) + #:use-module (gnu packages m4) + #:use-module (gnu packages onc-rpc) + #:use-module (gnu packages package-management) + #:use-module (gnu packages perl) + #:use-module (gnu packages python-build) + #:use-module (gnu packages python-crypto) + #:use-module (gnu packages python-web) + #:use-module (gnu packages python-xyz) + #:use-module (gnu packages time) + #:use-module (gnu packages tls) + #:use-module (gnu packages xml) + #:use-module (gnu services certbot) + #:use-module (gnu services mail) + #:use-module (gnu services shepherd) + #:use-module (gnu services web) + #:use-module (gnu system setuid) + #:export (<shadow-group-configuration> + shadow-group-configuration + shadow-group-configuration-group + + shadow-group-activation + shadow-group-accounts + shadow-group-service-type + + + <cyrus-service-configuration> + cyrus-service-configuration + cyrus-service-configuration-name + cyrus-service-configuration-authmech + cyrus-service-configuration-log-level + + <cyrus-sasl-configuration> + cyrus-sasl-configuration + cyrus-sasl-configuration-cyrus-sasl + cyrus-sasl-configuration-authmech + cyrus-sasl-configuration-services + cyrus-sasl-configuration-state-dir + + cyrus-sasl-etc-files + cyrus-sasl-activation + cyrus-sasl-accounts + cyrus-sasl-shepherd-service + cyrus-sasl-service-type + + + <dkimproxyout-configuration> + dkimproxyout-configuration + dkimproxyout-configuration-dkimproxy + dkimproxyout-configuration-user + dkimproxyout-configuration-group + dkimproxyout-configuration-listen + dkimproxyout-configuration-relay + dkimproxyout-configuration-domains + dkimproxyout-configuration-selector + dkimproxyout-configuration-key-size + dkimproxyout-configuration-data-directory + + dkimproxyout-etc-files + dkimproxyout-accounts + dkimproxyout-activation + dkimproxyout-shepherd-service + dkimproxyout-service-type + + postfix-service-type + postfix-configuration + + dovecot2-service-type + dovecot2-configuration)) + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; packages ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + +(define-public postfix + (package + (name "postfix") + (version "3.8-20221023") + (source + (origin + (method url-fetch) + (uri + (string-append + "http://cdn.postfix.johnriley.me/mirrors/postfix-release/experimental/postfix-" + version + ".tar.gz")) + (sha256 + (base32 "0aaylhn81n9z3kidx53kzf2jrilr3lgwfxsk1r4hn7nkrp62bcwm")))) + (build-system gnu-build-system) + (arguments + (list + #:tests? #f + #:modules `((srfi srfi-26) + ,@%gnu-build-system-modules) + #:phases + #~(modify-phases %standard-phases + (add-before 'configure 'patch-/bin/sh + (lambda _ + (substitute* (find-files "." "^Makefile") + (("/bin/sh") + (which "sh"))))) + (add-before 'configure 'patch-bdb-include + (lambda* (#:key inputs #:allow-other-keys) + (substitute* "makedefs" + (("/usr/include") + (string-append (assoc-ref inputs "bdb") + "/include"))))) + (add-before 'configure 'dont-hardcode-PATH + (lambda _ + (substitute* '("postfix-install" + "conf/post-install") + (("^PATH=") + "# PATH=")))) + (add-before 'configure 'fix-strict-PATH + (lambda _ + (substitute* "src/util/sys_defs.h" + (("^#define (ROOT_PATH|_PATH_DEFPATH|_PATH_STDPATH).*") + "#define ROOT_PATH \"/run/setuid-programs:/run/current-system/profile/bin:/run/current-system/profile/sbin\"\n")))) + (add-before 'configure 'use-relative-symlink-to-store + (lambda _ + (substitute* "postfix-install" + (("ln -sf") + "ln -rsf")))) + (add-before 'configure 'fix-absolute-path-to-setuid-programs + (lambda _ + (substitute* "conf/postfix-script" + (("\\$command_directory/postqueue") + "/run/setuid-programs/postqueue") + (("\\$command_directory/postdrop") + "/run/setuid-programs/postdrop")))) + (add-before 'configure 'disable-warning-on-non-writable-config-files + (lambda _ + (substitute* "conf/postfix-script" + (("find \\$todo \\\\\\( -perm -020 -o -perm -002 \\\\\\) \\\\\n") + " # find $todo \\( -perm -020 -o -perm -002 \\)")))) + (add-before 'configure 'disable-write-to-/etc/postfix + (lambda _ + (substitute* "src/postconf/postconf_edit.c" + (("pcf_set_config_dir.*") + "return;")))) + (add-before 'configure 'setup-environment + (lambda* (#:key outputs inputs #:allow-other-keys) + (setenv "CCARGS" (string-append "-DUSE_TLS -DUSE_SASL_AUTH -DUSE_CYRUS_SASL -I" + (assoc-ref inputs "cyrus-sasl") + "/include/sasl")) + (setenv "AUXLIBS" "-lnsl -lcrypto -lssl -lsasl2") + (let* ((out (assoc-ref outputs "out")) + (bin (string-append out "/bin")) + (sbin (string-append out "/sbin")) + (lib (string-append out "/lib/postfix")) + (libexec (string-append out "/libexec/postfix")) + (etc (string-append out "/etc/postfix")) + (man (string-append out "/share/man")) + (doc (string-append out "/share/doc/postfix-" #$version)) + (html (string-append doc "/html"))) + (setenv "install_root" "wip-prefix") + (setenv "newaliases_path" (string-append bin "/newaliases")) + (setenv "mailq_path" (string-append bin "/mailq")) + (setenv "sendmail_path" (string-append sbin "/sendmail")) + (setenv "command_directory" sbin) + (setenv "shlib_directory" lib) + (setenv "daemon_directory" libexec) + (setenv "meta_directory" etc) + (setenv "sample_directory" etc) + (setenv "manpage_directory" man) + (setenv "readme_directory" doc) + (setenv "html_directory" html) + (setenv "sample_directory" (string-append out "/share/postfix"))))) + (replace 'configure + (lambda _ + (invoke "make" "makefiles" + "pie=yes" + "dynamicmaps=yes"))) + (replace 'install + (lambda* (#:key outputs #:allow-other-keys) + (let ((out (assoc-ref outputs "out"))) + (invoke "make" "non-interactive-package") + (delete-file-recursively "wip-prefix/var") + (copy-recursively "wip-prefix/etc" (string-append out "/etc")) + (copy-recursively (string-append "wip-prefix" out) out))))))) + (inputs + (list bdb + cyrus-sasl + libnsl + openssl + perl)) + (native-inputs + (list m4)) + (home-page "https://www.postfix.org") + (synopsis "sendmail compatible MTA") + (description + "Postfix is Wietse Venema's mail server that started life at IBM research +as an alternative to the widely-used Sendmail program. Now at Google, Wietse +continues to support Postfix. + +Postfix attempts to be fast, easy to administer, and secure. The outside has a +definite Sendmail-ish flavor, but the inside is completely different.") + (license (list license:ibmpl1.0 + license:epl2.0)))) + +(define-public python-pytest-tornado5 + (package + (name "python-pytest-tornado5") + (version "2.0.0") + (source + (origin + (method url-fetch) + (uri + (pypi-uri "pytest-tornado5" version)) + (sha256 + (base32 "0qb62jw2w0xr6y942yp0qxiy755bismjfpnxaxjjm05gy2pymr8d")))) + (build-system python-build-system) + (propagated-inputs (list python-pytest python-tornado)) + (home-page "https://github.com/vidartf/pytest-tornado") + (synopsis + "A py.test plugin providing fixtures and markers to simplify testing of asynchronous tornado applications.") + (description + "This package provides a py.test plugin providing fixtures and markers to +simplify testing of asynchronous tornado applications.") + (license license:asl2.0))) + +;; FIXME +#; +(define-public python-futures + (package + (name "python-futures") + (version "3.3.0") + (source + (origin + (method url-fetch) + (uri + (pypi-uri "futures" version)) + (sha256 + (base32 "154pvaybk9ncyb1wpcnzgd7ayvvhhzk92ynsas7gadaydbvkl0vy")))) + (build-system python-build-system) + (home-page "https://github.com/agronholm/pythonfutures") + (synopsis "Backport of the concurrent.futures package from Python 3") + (description "Backport of the concurrent.futures package from Python 3") + (license #f))) + +(define-public python-ordereddict + (package + (name "python-ordereddict") + (version "1.1") + (source + (origin + (method url-fetch) + (uri + (pypi-uri "ordereddict" version)) + (sha256 + (base32 "07qvy11nvgxpzarrni3wrww3vpc9yafgi2bch4j2vvvc42nb8d8w")))) + (build-system python-build-system) + (arguments + `(#:phases + (modify-phases %standard-phases + (delete 'sanity-check)))) + (home-page "UNKNOWN") + (synopsis + "A drop-in substitute for Py2.7's new collections.OrderedDict that works in Python 2.4-2.6.") + (description "This package provides a drop-in substitute for Py2.7's new +collections.OrderedDict that works in Python 2.4-2.6.") + (license #f))) + +(define-public python-funcsigs + (package + (name "python-funcsigs") + (version "1.0.2") + (source + (origin + (method url-fetch) + (uri + (pypi-uri "funcsigs" version)) + (sha256 + (base32 "0l4g5818ffyfmfs1a924811azhjj8ax9xd1cffr1mzd3ycn0zfx7")))) + (build-system python-build-system) + (propagated-inputs + (list python-ordereddict)) + (native-inputs + (list python-unittest2)) + (home-page "http://funcsigs.readthedocs.org") + (synopsis + "Python function signatures from PEP362 for Python 2.6, 2.7 and 3.2+") + (description + "Python function signatures from PEP362 for Python 2.6, 2.7 and 3.2+") + (license #f))) + +(define-public python-apscheduler + (package + (name "python-apscheduler") + (version "3.9.1") + (source + (origin + (method url-fetch) + (uri + (pypi-uri "APScheduler" version)) + (sha256 + (base32 "1qzi1pr7q72vs49p7vr1mp350zaggs52lpq43lvqsjcmcd5mgrk5")))) + (build-system python-build-system) + (arguments + `(#:tests? #f)) + (propagated-inputs + (list python-funcsigs + ; python-futures + python-pytz + python-setuptools + python-six + python-tzlocal)) + (native-inputs + (list python-mock + python-pytest + python-pytest-asyncio + python-pytest-cov + python-pytest-tornado5 + python-setuptools-scm)) + (home-page "https://github.com/agronholm/apscheduler") + (synopsis "In-process task scheduler with Cron-like capabilities") + (description "In-process task scheduler with Cron-like capabilities") + (license license:expat))) + +(define-public python-telegram-bot + (package + (name "python-telegram-bot") + (version "13.12") + (source + (origin + (method url-fetch) + (uri + (pypi-uri "python-telegram-bot" version)) + (sha256 + (base32 "1rbdyr1f9mndlh83in47k8if65yp9n1dy4px2wipbf0qyjv5zxfs")))) + (build-system python-build-system) + (arguments + `(#:tests? #f + #:phases + (modify-phases %standard-phases + (delete 'sanity-check)))) + (native-inputs + (list python-apscheduler)) + (propagated-inputs + (list python-apscheduler + python-cachetools + python-certifi + python-pytz + python-tornado)) + (home-page "https://python-telegram-bot.org/") + (synopsis "Python library to interface with the Telegram Bot API") + (description "We have made you a wrapper you can't refuse") + (license #f))) + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; services ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + +(define-record-type* <shadow-group-configuration> + shadow-group-configuration + make-shadow-group-configuration + shadow-group-configuration? + (group shadow-group-configuration-group (default "etc-shadow"))) + +(define (shadow-group-activation config) + (match-record config <shadow-group-configuration> + (group) + #~(begin + (use-modules (guix build utils)) + (format (current-error-port) + "Setting ownership and permission for \"/etc/shadow\".~%") + (chown "/etc/shadow" + (passwd:uid (getpwnam "root")) + (group:gid (getgrnam #$group))) + (chmod "/etc/shadow" #o640)))) + +(define (shadow-group-accounts config) + (match-record config <shadow-group-configuration> + (group) + (list + (user-group + (name group) + (system? #t))))) + +(define shadow-group-service-type + (service-type + (name 'shadow-group) + (extensions + (list + (service-extension activation-service-type + shadow-group-activation) + (service-extension account-service-type + shadow-group-accounts))) + (default-value (shadow-group-configuration)) + (description "FIXME:DOCUMENTATION"))) + + +(define-record-type* <cyrus-service-configuration> + cyrus-service-configuration + make-cyrus-service-configuration + cyrus-service-configuration? + (name cyrus-service-configuration-name) + (authmech cyrus-service-configuration-authmech (default "saslauthd")) + (log-level cyrus-service-configuration-log-level (default 7))) + +(define-record-type* <cyrus-sasl-configuration> + cyrus-sasl-configuration + make-cyrus-sasl-configuration + cyrus-sasl-configuration? + (cyrus-sasl cyrus-sasl-configuration-cyrus-sasl (default cyrus-sasl)) + (user cyrus-sasl-configuration-user (default "cyrus-sasl")) + (group cyrus-sasl-configuration-group (default "cyrus-sasl")) + (supplementary-groups cyrus-sasl-configuration-supplementary-groups (default '("etc-shadow"))) + (authmech cyrus-sasl-configuration-authmech (default "shadow")) + (services cyrus-sasl-configuration-services (default '())) + (config-dirname cyrus-sasl-configuration-config-dirname (default "sasl2")) + (run-directory cyrus-sasl-configuration-run-directory (default "/var/run/saslauthd")) + (run-in-container? cyrus-sasl-configuration-run-in-container? (default #t)) + (container-name cyrus-sasl-configuration-container-name (default "saslauthd")) + (container-namespaces cyrus-sasl-configuration-container-namespaces (default container:%namespaces)) + (extra-mappings cyrus-sasl-configuration-extra-mappings (default '()))) + + +(define (cyrus-sasl-etc-files config) + ;; FIXME: support opaque files + ;; FIXME: extend this with postfix instead of making postfix add here + (match-record config <cyrus-sasl-configuration> + (services config-dirname run-directory) + `((,config-dirname + ,(file-union + config-dirname + (map (lambda (service-config) + (match-record service-config <cyrus-service-configuration> + (name authmech log-level) + `(,name ,(plain-file + name + (format #f + "pwcheck_method: ~a~%saslauthd_path: ~a/mux~%log_level: ~a~%" + authmech + run-directory + log-level))))) + services)))))) + +(define (cyrus-sasl-activation config) + (match-record config <cyrus-sasl-configuration> + (user run-directory) + #~(begin + (use-modules (guix build utils)) + (let ((user (getpwnam #$user))) + (format (current-error-port) + "Creating Cyrus SASL socket directory: \"~a\".~%" #$run-directory) + (mkdir-p #$run-directory) + (chown #$run-directory (passwd:uid user) (passwd:gid user)) + (chmod #$run-directory #o755))))) + +(define (cyrus-sasl-accounts config) + (match-record config <cyrus-sasl-configuration> + (user group supplementary-groups) + (list + (user-account + (name user) + (group group) + (supplementary-groups supplementary-groups) + (comment "Cyrus SASL system user") + (home-directory "/var/empty") + (create-home-directory? #f) + (shell + (file-append shadow "/sbin/nologin")) + (system? #t)) + (user-group + (name group) + (system? #t))))) + + +(define (cyrus-sasl-shepherd-service config) + (match-record config <cyrus-sasl-configuration> + (cyrus-sasl user group supplementary-groups authmech config-dirname run-directory + services run-in-container? container-name container-namespaces extra-mappings) + (let* ((config-dir (string-append "/etc/" config-dirname)) + (bin (file-append cyrus-sasl "/sbin/saslauthd")) + (cmd (if (not run-in-container?) + bin + (least-authority-wrapper + bin + #:name container-name + #:mappings (append + (list + (file-system-mapping + (source run-directory) + (target source) + (writable? #t)) + (file-system-mapping + (source "/etc/passwd") + (target source)) + (file-system-mapping + (source "/etc/shadow") + (target source))) + extra-mappings) + #:namespaces container-namespaces)))) + (list + (shepherd-service + (provision '(cyrus-sasl)) + (documentation "FIXME:DOCUMENTATION") + (start #~(make-forkexec-constructor + (list #$cmd "-a" #$authmech "-d" "-m" #$run-directory) + #:user #$user + #:group #$group + #:supplementary-groups '(#$@supplementary-groups))) + (stop #~(make-kill-destructor)) + (actions + (list + (shepherd-action + (name 'configuration) + (documentation "FIXME:DOCUMENTATION") + (procedure + #~(lambda _ + (format #t "Debug procedure")) + #;(lambda _ + (for-each (lambda (name) + (format #t "~a/~a~%" #$config-dir name)) + (map cyrus-service-configuration-name #$services)))))))))))) + +(define cyrus-sasl-service-type + (service-type + (name 'cyrus-sasl) + (extensions + (list + (service-extension etc-service-type + cyrus-sasl-etc-files) + (service-extension activation-service-type + cyrus-sasl-activation) + (service-extension profile-service-type + (compose list cyrus-sasl-configuration-cyrus-sasl)) + (service-extension account-service-type + cyrus-sasl-accounts) + (service-extension shepherd-root-service-type + cyrus-sasl-shepherd-service))) + (compose srfi-1:concatenate) + (extend (lambda (config services) + (cyrus-sasl-configuration + (inherit config) + (services + (append + (cyrus-sasl-configuration-services config) + services))))) + (default-value (cyrus-sasl-configuration)) + (description "FIXME:DOCUMENTATION"))) + + +(define-record-type* <dkimproxyout-configuration> + dkimproxyout-configuration + make-dkimproxyout-configuration + dkimproxyout-configuration? + (dkimproxy dkimproxyout-configuration-dkimproxy (default dkimproxy)) + (user dkimproxyout-configuration-user (default "dkimproxyout")) + (group dkimproxyout-configuration-group (default "dkimproxyout")) + (config-name dkimproxyout-configuration-config-name (default "dkimproxyout.conf")) + (listen dkimproxyout-configuration-listen (default "127.0.0.1:10027")) + (relay dkimproxyout-configuration-relay (default "127.0.0.1:10028")) + (domains dkimproxyout-configuration-domains (default (list (gethostname)))) + (selector dkimproxyout-configuration-selector (default "dkimproxyout")) + (key-size dkimproxyout-configuration-key-size (default 2048)) + (data-directory dkimproxyout-configuration-data-directory (default "/var/lib/dkimproxyout")) + (run-in-container? dkimproxyout-configuration-run-in-container? (default #f)) + (container-name dkimproxyout-configuration-container-name (default "dkimproxyout")) + (container-namespaces dkimproxyout-configuration-container-namespaces (default (srfi-1:fold delq container:%namespaces '(net)))) + (extra-mappings dkimproxyout-configuration-extra-mappings (default '()))) + +(define (generate-out.cf config) + (match-record config <dkimproxyout-configuration> + (listen relay domains selector data-directory) + (format #f +" +listen ~a +relay ~a + +domain ~a +selector ~a + +signature dkim(c=relaxed/relaxed) + +# FIXME:DOCUMENTATION add this to the service documentation +# the corresponding public key is available at: +# ~a/public.key +keyfile ~a/private.key +" + listen + relay + (string-join domains ",") + selector + data-directory + data-directory))) + +(define (dkimproxyout-etc-files config) + (match-record config <dkimproxyout-configuration> + (config-name) + `((,config-name ,(plain-file config-name (generate-out.cf config)))))) + +(define (dkimproxyout-accounts config) + (match-record config <dkimproxyout-configuration> + (user group) + (list + (user-account + (name user) + (group group) + (comment "DKIMproxy.out signing system user") + (home-directory "/var/empty") + (create-home-directory? #f) + (shell + (file-append shadow "/sbin/nologin")) + (system? #t)) + (user-group + (name group) + (system? #t))))) + +(define (dkimproxyout-activation config) + (match-record config <dkimproxyout-configuration> + (user group data-directory key-size) + #~(begin + (use-modules (guix build utils)) + (let ((uid (passwd:uid (getpwnam #$user))) + (gid (group:gid (getgrnam #$group)))) + (format (current-error-port) + "Creating DKIMproxy.out data directory: \"~a\".~%" #$data-directory) + (mkdir-p #$data-directory) + (chown #$data-directory uid gid) + (chmod #$data-directory #o755) + (let ((private-key (string-append #$data-directory "/private.key")) + (public-key (string-append #$data-directory "/public.key"))) + (unless (file-exists? private-key) + (format (current-error-port) + "The public/private keypair doesn't exist yet. Generating one...~%") + (cond + ((zero? (system* #$(file-append openssl "/bin/openssl") + "genrsa" + "-out" + private-key + (number->string #$key-size))) + (format (current-error-port) + "DKIMproxy.out private key file created: \"~a\".~%" private-key)) + (else + (format (current-error-port) + "Failed to create DKIMproxy.out private key file: \"~a\".~%" private-key)))) + (invoke #$(file-append openssl "/bin/openssl") + "rsa" + "-in" + private-key + "-pubout" + "-out" + public-key) + (format (current-error-port) + "Setting permissions for the public/private DKIMproxy.out keypair: \"~a/{public,private}.key\".~%" #$data-directory) + (chown private-key uid gid) + (chown public-key uid gid) + (chmod private-key #o400) + (chmod public-key #o644)))))) + + +(define (dkimproxyout-shepherd-service config) + (match-record config <dkimproxyout-configuration> + (dkimproxy user group config-name data-directory + run-in-container? container-name container-namespaces extra-mappings) + (let* ((config-file (string-append "/etc/" config-name)) + (bin (file-append dkimproxy "/bin/dkimproxy.out")) + (cmd (if (not run-in-container?) + bin + (least-authority-wrapper + bin + #:name container-name + #:mappings (append + (list + (file-system-mapping + (source config-file) + (target source)) + (file-system-mapping + (source + (string-append data-directory "/private.key")) + (target source))) + extra-mappings) + #:namespaces container-namespaces)))) + (list + (shepherd-service + (provision '(dkimproxyout)) + (documentation "FIXME:DOCUMENTATION") + (start #~(make-forkexec-constructor + (list #$cmd "--conf_file" #$config-file) + #:user #$user + #:group #$group)) + (stop #~(make-kill-destructor)) + (actions + (list + (shepherd-action + (name 'configuration) + (documentation "FIXME:DOCUMENTATION") + (procedure + #~(lambda _ + (format #t "~a~%" #$config-file))))))))))) + + +(define-public dkimproxyout-service-type + (service-type + (name 'dkimproxyout) + (extensions + (list + (service-extension etc-service-type + dkimproxyout-etc-files) + (service-extension account-service-type + dkimproxyout-accounts) + (service-extension activation-service-type + dkimproxyout-activation) + (service-extension profile-service-type + (compose list dkimproxyout-configuration-dkimproxy)) + (service-extension shepherd-root-service-type + dkimproxyout-shepherd-service))) + (default-value (dkimproxyout-configuration)) + (description "FIXME:DOCUMENTATION"))) + + + + + + + + + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Postfix ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + +(define-record-type* <postfix-configuration> + postfix-configuration + make-postfix-configuration + postfix-configuration? + (postfix postfix-configuration-postfix (default postfix)) + (mail-in-home? postfix-configuration-mail-in-home? (default #f)) + (set-sendmail? postfix-configuration-set-sendmail? (default #t)) + (master.cf-file postfix-configuration-master.cf-file (default #f)) + (main.cf-file postfix-configuration-main.cf-file (default #f)) + (master.cf-extra postfix-configuration-master.cf-extra (default "")) + (main.cf-extra postfix-configuration-main.cf-extra (default "")) + (config-dirname postfix-configuration-config-dirname (default "postfix")) + (data-directory postfix-configuration-data-directory (default "/var/lib/postfix")) + (queue-directory postfix-configuration-queue-directory (default "/var/spool/postfix")) + (user postfix-configuration-user (default "postfix")) + (group postfix-configuration-group (default "postfix")) + (setgid-group postfix-configuration-setgid-group (default "postdrop")) + (root-aliases postfix-configuration-root-aliases (default '("abuse" "admin" "hostmaster" "postmaster"))) + (cert-file postfix-configuration-cert-file (default #f)) + (key-file postfix-configuration-key-file (default #f)) + (hostname postfix-configuration-hostname (default (gethostname))) + (run-in-container? postfix-configuration-run-in-container? (default #f)) + (container-name postfix-configuration-container-name (default "postfix")) + (container-namespaces postfix-configuration-container-namespaces (default (srfi-1:fold delq container:%namespaces '(net)))) + (extra-mappings postfix-configuration-extra-mappings (default '()))) + +; FIXME: hardcoded value of dkimproxy listen and relay +(define (generate-master.cf config) + (match-record config <postfix-configuration> + (master.cf-extra) + (format #f + " +# ============================================================================================================ +# service type private unpriv chroot wakeup maxproc command + args +# (yes) (yes) (no) (never) (100) +# ============================================================================================================= + + +anvil unix - - n - 1 anvil +bounce unix - - n - 0 bounce +cleanup unix n - n - 0 cleanup +defer unix - - n - 0 bounce +discard unix - - n - - discard +error unix - - n - - error +flush unix n - n 1000? 0 flush +lmtp unix - - n - - lmtp +local unix - n n - - local +# FIXME: replace 127.0.0.1 with localhost +pickup unix n - n 60 1 pickup + -o content_filter=dksign:[127.0.0.1]:10027 +proxymap unix - - n - - proxymap +proxywrite unix - - n - 1 proxymap +qmgr unix n - n 300 1 qmgr +relay unix - - n - - smtp -o syslog_name=postfix/relay +retry unix - - n - - error +rewrite unix - - n - - trivial-rewrite +scache unix - - n - 1 scache +showq unix n - n - - showq +smtp inet n - n - - smtpd -o syslog_name=postfix/smtp +smtp unix - - n - - smtp +submission inet n - n - - smtpd -o syslog_name=postfix/submission + -o smtpd_tls_security_level=encrypt + -o content_filter=dksign:[127.0.0.1]:10027 +tlsmgr unix - - n 1000? 1 tlsmgr +trace unix - - n - 0 bounce +verify unix - - n - 1 verify +virtual unix - n n - - virtual +postlog unix-dgram n - n - 1 postlogd + +# FIXME: doesn't work for sendmail -t in localhost +dksign unix - - n - - smtp + -o syslog_name=postfix/dkimproxyout-listen + -o smtp_send_xforward_command=yes + -o smtp_discard_ehlo_keywords=8bitmime,starttls +127.0.0.1:10028 inet n - n - - smtpd + -o syslog_name=postfix/dkimproxyout-relay + -o content_filter= + -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks + -o smtpd_helo_restrictions= + -o smtpd_client_restrictions= + -o smtpd_sender_restrictions= + -o smtpd_recipient_restrictions=permit_mynetworks,reject + -o mynetworks=127.0.0.0/8 + -o smtpd_authorized_xforward_hosts=127.0.0.0/8 +~a +" + master.cf-extra))) + +(define (cert-for prefix config) + (match-record config <postfix-configuration> + (cert-file hostname) + (or cert-file (format #f "/etc/letsencrypt/live/~a~a/fullchain.pem" prefix hostname)))) + +(define (key-for prefix config) + (match-record config <postfix-configuration> + (key-file hostname) + (or key-file (format #f "/etc/letsencrypt/live/~a~a/privkey.pem" prefix hostname)))) + +(define (generate-main.cf config) + (match-record config <postfix-configuration> + (postfix mail-in-home? queue-directory data-directory user setgid-group hostname main.cf-extra) + (format #f + " +compatibility_level = 3.6 + +queue_directory = ~a +data_directory = ~a +mail_owner = ~a +setgid_group = ~a + +myhostname = ~a +mydestination = $myhostname, $mydomain, localhost.$mydomain, localhost + +alias_maps = hash:/etc/aliases +# alias_maps = hash:/etc/aliases, static:andreh + +header_checks = regexp:{ { /^Received:.*/ IGNORE }, { /^X-Originating-IP:.*/ IGNORE } } + +~a + +smtpd_use_tls = yes +smtpd_tls_cert_file = ~a +smtpd_tls_key_file = ~a +smtp_use_tls = $smtpd_use_tls +smtp_tls_cert_file = $smtpd_tls_cert_file +smtp_tls_key_file = $smtpd_tls_key_file + +smtp_tls_security_level = may + +recipient_delimiter = + + +# smtpd_sasl_security_options = FIXME: deny all +smtpd_sasl_tls_security_options = noanonymous +# FIXME: shouldn't this be 'encrypt'? +smtpd_tls_security_level = may +smtpd_tls_auth_only = yes + +smtpd_relay_restrictions = $smtpd_recipient_restrictions +smtpd_recipient_restrictions = permit_mynetworks, + permit_sasl_authenticated, reject_unauth_destination +smtpd_sasl_auth_enable = yes +cyrus_sasl_config_path = /etc/sasl2 +debug_peer_list = 127.0.0.1 + +milter_default_action = accept +# smtpd_milters = FIXME +~a +" + queue-directory + data-directory + user + setgid-group + hostname + + (if mail-in-home? + "home_mailbox = Mail/Inbox/" + "mail_spool_directory = /var/mail/") + + (cert-for "" config) + (key-for "" config) + main.cf-extra))) + +(define (postfix-etc-files config) + (match-record config <postfix-configuration> + (master.cf-file main.cf-file config-dirname) + `((,config-dirname + ,(file-union + config-dirname + `(("master.cf" ,(plain-file "master.cf" (or master.cf-file (generate-master.cf config)))) + ("main.cf" ,(plain-file "main.cf" (or main.cf-file (generate-main.cf config)))))))))) + +(define (postfix-accounts config) + (match-record config <postfix-configuration> + (user group setgid-group) + (list + (user-account + (name user) + (group group) + (comment "Postfix system user") + (home-directory "/var/empty") + (create-home-directory? #f) + (shell + (file-append shadow "/sbin/nologin")) + (system? #t)) + (user-group + (name group) + (system? #t)) + (user-group + (name setgid-group) + (system? #t))))) + +(define (postfix-setuid-programs config) + (match-record config <postfix-configuration> + (postfix setgid-group set-sendmail?) + (append + (list + (setuid-program + (program (file-append postfix "/sbin/postdrop")) + (setuid? #f) + (setgid? #t) + (group setgid-group)) + (setuid-program + (program (file-append postfix "/sbin/postqueue")) + (setuid? #f) + (setgid? #t) + (group setgid-group))) + (if set-sendmail? + (list + (setuid-program + (program (file-append postfix "/sbin/sendmail")) + (setuid? #f) + (setgid? #t) + (group setgid-group))) + '())))) + +(define (postfix-activation config) + (match-record config <postfix-configuration> + (queue-directory) + #~(begin + (use-modules (guix build utils)) + (let ((user (getpwnam "root"))) + (format (current-error-port) + "Creating Postfix queue directory: \"~a\".~%" #$queue-directory) + (mkdir-p #$queue-directory) + (chown #$queue-directory (passwd:uid user) (passwd:gid user)) + (chmod #$queue-directory #o755) + (format (current-error-port) + "Creating email spool director: \"/var/mail\".~%") + (mkdir-p "/var/mail") + (format (current-error-port) + "Updating /etc/aliases: FIXME.~%") + ;; FIXME: add -c option +#; + (invoke #$(file-append postfix "/sbin/postalias") "/etc/aliases"))))) + +(define (postfix-shepherd-service config) + (match-record config <postfix-configuration> + (postfix config-dirname data-directory queue-directory + run-in-container? container-name container-namespaces extra-mappings) + (let* ((config-dir (string-append "/etc/" config-dirname)) + (bin (file-append postfix "/sbin/postfix")) + (cmd (if (not run-in-container?) + bin + (least-authority-wrapper + bin + #:name container-name + #:mappings (append + (list + (file-system-mapping + (source data-directory) + (target source) + (writable? #t)) + (file-system-mapping + (source queue-directory) + (target source) + (writable? #t))) + extra-mappings) + #:namespaces container-namespaces)))) + (list + (shepherd-service + (provision '(postfix)) + (documentation + "- + Run the Postfix MTA. + + This is the entrypoint for starting the \"master\" process. Then the + \"master\" process itself takes responsability of starting all the + required daemons and commands.") + (start #~(make-forkexec-constructor + (list + #$(file-append postfix "/sbin/postfix") + "-c" + #$config-dir + "start-fg") + #:pid-file "/var/lib/postfix/master.lock")) + (stop #~(make-kill-destructor SIGKILL)) + (actions + (list + (shepherd-action + (name 'configuration) + (documentation "FIXME:DOCUMENTATION") + (procedure + #~(lambda _ + (format #t "~a/master.cf~%" #$config-dir) + (format #t "~a/main.cf~%" #$config-dir)))) + (shepherd-action + (name 'reload) + (documentation + " + Re-read the \"master.cf\" and \"main.cf\" configuration files. + + Daemon processes terminate when possible, and when restarted + use the values of the new configuration files. + + This live-reload option is usually preferable over a stop/start + cycle, as it incurs in no interruption of the running service.") + (procedure + #~(lambda _ + (invoke #$(file-append postfix "/sbin/postfix") + "-c" + #$config-dir + "reload"))))))))))) + +(define (postfix-aliases config) + (match-record config <postfix-configuration> + (root-aliases) + (map (lambda (alias) + `(,alias "root")) + root-aliases))) + + +(define (postfix-nginx-locations config) + (match-record config <postfix-configuration> + (hostname) + (list + (nginx-server-configuration + (server-name (list (string-append "mta-sts." hostname))) + (listen '("[::]:443 ssl http2" "443 ssl http2")) + (ssl-certificate (cert-for "mta-sts." config)) + (ssl-certificate-key (key-for "mta-sts." config)) + (locations + (list + (nginx-location-configuration + (uri "= /.well-known/mta-sts.txt") + (body + (list + (list "alias " + (plain-file + "mta-sts.txt" + (format #f "version: STSv1 +mode: enforce +mx: ~a +max_age: 604800 +" + hostname)) + ";")))))))))) + +(define (postfix-certificates config) + (match-record config <postfix-configuration> + (hostname) + (list + (certificate-configuration + (domains (list (string-append "mta-sts." hostname))))))) + +(define (postfix-sasl-services _config) + (list + (cyrus-service-configuration + (name "smtpd.conf")))) + + +(define postfix-service-type + (service-type + (name 'postfix) + (extensions + (list + (service-extension etc-service-type + postfix-etc-files) + (service-extension account-service-type + postfix-accounts) + (service-extension setuid-program-service-type + postfix-setuid-programs) + (service-extension activation-service-type + postfix-activation) + (service-extension mail-aliases-service-type + postfix-aliases) + (service-extension profile-service-type + (compose list postfix-configuration-postfix)) + (service-extension shepherd-root-service-type + postfix-shepherd-service) + (service-extension nginx-service-type + postfix-nginx-locations) + (service-extension certbot-service-type + postfix-certificates) + (service-extension cyrus-sasl-service-type + postfix-sasl-services))) + (default-value (postfix-configuration)) + (description + " + Run the Postfix MTA. + + This is the top-level system service for Postfix. + + It includes: + - populating /etc/postfix/ with read-only configuration files; + - the user and groups used by Postfix when handling email delivery; + - the special setgid binaries for daily usage, such as \"sendmail\"; + - the Shepherd service for starting, stopping and *reloading* the + service without restarting it; + - the activation script for creating the required directories and + configuring them with the correct permissions; + - the binaries in the system profile so that one doesn't need to explicilty + include the package when the service is already enabled. + + An extension to the log-rotation service isn't included: the default + rottlog configuration already includes /var/log/maillog in its routine, + so it is kept out. + + The defaults of <postfix-configuration> provide sane default values for + most things, such as group names, data and queue directories, etc. When + used as-is, it creates a Postfix server that sends email from local users + of the domain provided by \"/etc/hostname\"."))) + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Dovecot ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + +(define-record-type* <dovecot2-configuration> + dovecot2-configuration + make-dovecot2-configuration + dovecot2-configuration? + (dovecot2 dovecot2-configuration-dovecot2 (default dovecot)) + (mail-in-home? dovecot2-configuration-mail-in-home? (default #f)) + (raw-file dovecot2-configuration-raw-file (default #f)) + (extra-content dovecot2-configuration-extra-content (default "")) + (config-name dovecot2-configuration-config-name (default "dovecot2.conf")) + (user dovecot2-configuration-user (default "dovecot2")) + (group dovecot2-configuration-group (default "dovecot2")) + (auth-worker-group dovecot2-configuration-auth-worker-group (default "etc-shadow")) + (untrusted-user dovecot2-configuration-untrusted-user (default "dovenull2")) + (untrusted-group dovecot2-configuration-untrusted-group (default "dovenull2")) + (base-dir dovecot2-configuration-base-dir (default "/var/run/dovecot2")) + (state-dir dovecot2-configuration-state-dir (default "/var/lib/dovecot2")) + (hostname dovecot2-configuration-hostname (default (gethostname)))) + +(define (generate-dovecot-config config) + (match-record config <dovecot2-configuration> + (mail-in-home? user group auth-worker-group untrusted-user + hostname base-dir state-dir extra-content) + (format #f + " +protocols = imap + +default_internal_user = ~a +default_internal_group = ~a +default_login_user = ~a +auth_mechanisms = plain login +auth_username_format = %n + +passdb { + driver = shadow +} +userdb { + driver = passwd +} +service auth-worker { + group = ~a +} + + +ssl = required +ssl_cert = </etc/letsencrypt/live/~a/fullchain.pem +ssl_key = </etc/letsencrypt/live/~a/privkey.pem +ssl_dh = <~a/dhparam.pem + +base_dir = ~a +state_dir = ~a + +verbose_proctitle = yes + +mail_location = maildir:~a:INBOX=~a:LAYOUT=fs + +# FIXME: +# mail_plugins + + +namespace inbox { + inbox = yes + mailbox Drafts { + special_use = \\Drafts + auto = subscribe + } + mailbox Sent { + special_use = \\Sent + auto = subscribe + } + mailbox Archive { + special_use = \\Archive + auto = subscribe + } + mailbox Junk { + special_use = \\Junk + auto = subscribe + autoexpunge = 30d + } + mailbox Trash { + special_use = \\Trash + auto = subscribe + } +} +~a +" + user + group + untrusted-user + auth-worker-group + hostname + hostname + state-dir + base-dir + state-dir + + (if mail-in-home? "~/Mail" "/var/mail/%u") + (if mail-in-home? "~/Mail/Inbox" "/var/mail/%u") + + extra-content))) + +(define (dovecot2-etc-files config) + (match-record config <dovecot2-configuration> + (raw-file config-name) + `((,config-name ,(plain-file config-name + (or raw-file + (generate-dovecot-config config))))))) + +(define (dovecot2-accounts config) + (match-record config <dovecot2-configuration> + (user group untrusted-user untrusted-group) + (list + (user-account + (name user) + (group group) + (comment "Dovecot system user") + (home-directory "/var/empty") + (create-home-directory? #f) + (shell + (file-append shadow "/sbin/nologin")) + (system? #t)) + (user-account + (name untrusted-user) + (group untrusted-group) + (comment "Dovecot user for untrusted logins") + (home-directory "/var/empty") + (create-home-directory? #f) + (shell + (file-append shadow "/sbin/nologin")) + (system? #t)) + (user-group + (name group) + (system? #t)) + (user-group + (name untrusted-group) + (system? #t))))) + +(define (dovecot2-activation config) + (match-record config <dovecot2-configuration> + (base-dir state-dir) + #~(begin + (use-modules (guix build utils)) + (let ((user (getpwnam "root"))) + (format (current-error-port) + "Creating Dovecot base_dir directory: \"~a\".~%" #$base-dir) + (mkdir-p #$base-dir) + (let ((dhparam.pem (string-append #$state-dir "/dhparam.pem"))) + (mkdir-p #$state-dir) + (unless (file-exists? dhparam.pem) + (format (current-error-port) + "dhparam.pem file doesn't exist yet. Generating one...~%") + (cond + ((zero? (system* (string-append #$openssl "/bin/openssl") + "dhparam" "-out" dhparam.pem "2048")) + (format (current-error-port) + "Dovecot2 dhparam.pem file created: \"~a\".~%" dhparam.pem)) + (else + (format (current-error-port) + "Failed to create dhparam.pem file: \"~a\".~%" dhparam.pem))))))))) + +(define (dovecot2-shepherd-service config) + (match-record config <dovecot2-configuration> + (dovecot2 config-name) + (let ((config-file (string-append "/etc/" config-name))) + (list + (shepherd-service + (provision '(dovecot2)) + (documentation "FIXME:DOCUMENTATION: heredoc syntax") + (start #~(make-forkexec-constructor + (list + #$(file-append dovecot2 "/sbin/dovecot") + "-F" + "-c" + #$config-file))) + (stop #~(make-kill-destructor)) + (actions + (list + (shepherd-action + (name 'configuration) + (documentation "FIXME:DOCUMENTATION: heredoc syntax") + (procedure + #~(lambda _ + (format #t "~a~%" #$config-file)))) + (shepherd-action + (name 'reload) + (documentation "FIXME:DOCUMENTATION: heredoc syntax") + (procedure + #~(lambda _ + (invoke #$(file-append dovecot "/bin/doveadm") + "-c" + #$config-file + "reload"))))))))))) + +(define dovecot2-service-type + (service-type + (name 'dovecot2) + (extensions + (list + (service-extension etc-service-type + dovecot2-etc-files) + (service-extension account-service-type + dovecot2-accounts) + (service-extension activation-service-type + dovecot2-activation) + (service-extension profile-service-type + (compose list dovecot2-configuration-dovecot2)) + (service-extension shepherd-root-service-type + dovecot2-shepherd-service))) + (default-value (dovecot2-configuration)) + (description "FIXME:DOCUMENTATION: heredoc syntax"))) + +;; FIXME +;; automate personal server with: +;; - euandreh:git-service-type +;; - euandreh:mail-service-type + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; OS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + +(list + postfix + python-telegram-bot) |