;;; Copyright © 2015 Andy Wingo <wingo@igalia.com>
;;; Copyright © 2017, 2018 Clément Lassieur <clement@lassieur.org>
;;; Copyright © 2017 Carlo Zancanaro <carlo@zancanaro.id.au>
-;;; Copyright © 2017 Tobias Geerinckx-Rice <me@tobias.gr>
+;;; Copyright © 2017, 2020 Tobias Geerinckx-Rice <me@tobias.gr>
+;;; Copyright © 2019 Kristofer Buffington <kristoferbuffington@gmail.com>
+;;; Copyright © 2020 Jonathan Brielmaier <jonathan.brielmaier@web.de>
;;;
;;; This file is part of GNU Guix.
;;;
#:use-module (gnu system shadow)
#:use-module (gnu packages mail)
#:use-module (gnu packages admin)
+ #:use-module (gnu packages dav)
#:use-module (gnu packages tls)
#:use-module (guix records)
#:use-module (guix packages)
exim-configuration
exim-configuration?
exim-service-type
- %default-exim-config-file))
+ %default-exim-config-file
+
+ imap4d-configuration
+ imap4d-configuration?
+ imap4d-service-type
+ %default-imap4d-config-file
+
+ radicale-configuration
+ radicale-configuration?
+ radicale-service-type
+ %default-radicale-config-file))
;;; Commentary:
;;;
(and (string? x) (not (string-index x #\space))))
val)))
(define (serialize-space-separated-string-list field-name val)
- (serialize-field field-name (string-join val " ")))
+ (match val
+ (() #f)
+ (_ (serialize-field field-name (string-join val " ")))))
(define (comma-separated-string-list? val)
(and (list? val)
(define (free-form-fields? val)
(match val
(() #t)
- ((((? symbol?) . (? string)) . val) (free-form-fields? val))
+ ((((? symbol?) . (? string?)) . val) (free-form-fields? val))
(_ #f)))
(define (serialize-free-form-fields field-name val)
(for-each (match-lambda ((k . v) (serialize-field k v))) val))
(define (free-form-args? val)
(match val
(() #t)
- ((((? symbol?) . (? string)) . val) (free-form-args? val))
+ ((((? symbol?) . (? string?)) . val) (free-form-args? val))
(_ #f)))
(define (serialize-free-form-args field-name val)
(serialize-field field-name
(string-join
- (map (match-lambda ((k . v) (format #t "~a=~a" k v))) val)
+ (map (match-lambda ((k . v) (format #f "~a=~a" k v))) val)
" ")))
(define-configuration dict-configuration
complex, customize the address and port fields of the
@samp{inet-listener} of the specific services you are interested in.")
- (protocols
- (protocol-configuration-list
- (list (protocol-configuration
- (name "imap"))))
- "List of protocols we want to serve. Available protocols include
-@samp{imap}, @samp{pop3}, and @samp{lmtp}.")
-
- (services
- (service-configuration-list
- (list
- (service-configuration
- (kind "imap-login")
- (client-limit 0)
- (process-limit 0)
- (listeners
- (list
- (inet-listener-configuration (protocol "imap") (port 143) (ssl? #f))
- (inet-listener-configuration (protocol "imaps") (port 993) (ssl? #t)))))
- (service-configuration
- (kind "pop3-login")
- (listeners
- (list
- (inet-listener-configuration (protocol "pop3") (port 110) (ssl? #f))
- (inet-listener-configuration (protocol "pop3s") (port 995) (ssl? #t)))))
- (service-configuration
- (kind "lmtp")
- (client-limit 1)
- (process-limit 0)
- (listeners
- (list (unix-listener-configuration (path "lmtp") (mode "0666")))))
- (service-configuration
- (kind "imap")
- (client-limit 1)
- (process-limit 1024))
- (service-configuration
- (kind "pop3")
- (client-limit 1)
- (process-limit 1024))
- (service-configuration
- (kind "auth")
- (service-count 0)
- (client-limit 0)
- (process-limit 1)
- (listeners
- (list (unix-listener-configuration (path "auth-userdb")))))
- (service-configuration
- (kind "auth-worker")
- (client-limit 1)
- (process-limit 0))
- (service-configuration
- (kind "dict")
- (client-limit 1)
- (process-limit 0)
- (listeners (list (unix-listener-configuration (path "dict")))))))
- "List of services to enable. Available services include @samp{imap},
-@samp{imap-login}, @samp{pop3}, @samp{pop3-login}, @samp{auth}, and
-@samp{lmtp}.")
-
(dict
(dict-configuration (dict-configuration))
"Dict configuration, as created by the @code{dict-configuration}
"Log unsuccessful authentication attempts and the reasons why they
failed.")
- (auth-verbose-passwords?
- (boolean #f)
+ (auth-verbose-passwords
+ (string "no")
"In case of password mismatches, log the attempted password. Valid
values are no, plain and sha1. sha1 can be useful for detecting brute
force password attempts vs. user simply trying the same password over
(imap-urlauth-host
(string "")
- "Host allowed in URLAUTH URLs sent by client. \"*\" allows all.") )
+ "Host allowed in URLAUTH URLs sent by client. \"*\" allows all.")
+
+ (protocols
+ (protocol-configuration-list
+ (list (protocol-configuration
+ (name "imap"))))
+ "List of protocols we want to serve. Available protocols include
+@samp{imap}, @samp{pop3}, and @samp{lmtp}.")
+
+ (services
+ (service-configuration-list
+ (list
+ (service-configuration
+ (kind "imap-login")
+ (client-limit 0)
+ (process-limit 0)
+ (listeners
+ (list
+ (inet-listener-configuration (protocol "imap") (port 143) (ssl? #f))
+ (inet-listener-configuration (protocol "imaps") (port 993) (ssl? #t)))))
+ (service-configuration
+ (kind "pop3-login")
+ (listeners
+ (list
+ (inet-listener-configuration (protocol "pop3") (port 110) (ssl? #f))
+ (inet-listener-configuration (protocol "pop3s") (port 995) (ssl? #t)))))
+ (service-configuration
+ (kind "lmtp")
+ (client-limit 1)
+ (process-limit 0)
+ (listeners
+ (list (unix-listener-configuration (path "lmtp") (mode "0666")))))
+ (service-configuration
+ (kind "imap")
+ (client-limit 1)
+ (process-limit 1024))
+ (service-configuration
+ (kind "pop3")
+ (client-limit 1)
+ (process-limit 1024))
+ (service-configuration
+ (kind "auth")
+ (service-count 0)
+ (client-limit 0)
+ (process-limit 1)
+ (listeners
+ (list (unix-listener-configuration (path "auth-userdb")))))
+ (service-configuration
+ (kind "auth-worker")
+ (client-limit 1)
+ (process-limit 0))
+ (service-configuration
+ (kind "dict")
+ (client-limit 1)
+ (process-limit 0)
+ (listeners (list (unix-listener-configuration (path "dict")))))))
+ "List of services to enable. Available services include @samp{imap},
+@samp{imap-login}, @samp{pop3}, @samp{pop3-login}, @samp{auth}, and
+@samp{lmtp}."))
(define-configuration opaque-dovecot-configuration
(dovecot
(define* (create-self-signed-certificate-if-absent
#:key private-key public-key (owner (getpwnam "root"))
(common-name (gethostname))
- (organization-name "GuixSD")
+ (organization-name "Guix")
(organization-unit-name "Default Self-Signed Certificate")
(subject-parameters `(("CN" . ,common-name)
("O" . ,organization-name)
(start #~(make-forkexec-constructor
(list (string-append #$dovecot "/sbin/dovecot")
"-F")))
- (stop #~(make-forkexec-constructor
- (list (string-append #$dovecot "/sbin/dovecot")
- "stop")))))))
+ (stop #~(lambda _
+ (invoke #$(file-append dovecot "/sbin/dovecot")
+ "stop")
+ #f))))))
(define %dovecot-pam-services
(list (unix-pam-service "dovecot")))
(define %default-opensmtpd-config-file
(plain-file "smtpd.conf" "
listen on lo
-accept from any for local deliver to mbox
-accept from local for any relay
+
+action inbound mbox
+match for local action inbound
+
+action outbound relay
+match from local for any action outbound
"))
(define opensmtpd-shepherd-service
;; Create mbox and spool directories.
(mkdir-p "/var/mail")
(mkdir-p "/var/spool/smtpd")
- (chmod "/var/spool/smtpd" #o711))))))
+ (chmod "/var/spool/smtpd" #o711)
+ (mkdir-p "/var/spool/mail")
+ (chmod "/var/spool/mail" #o711))))))
+
+(define %opensmtpd-pam-services
+ (list (unix-pam-service "smtpd")))
(define opensmtpd-service-type
(service-type
(const %opensmtpd-accounts))
(service-extension activation-service-type
opensmtpd-activation)
+ (service-extension pam-root-service-type
+ (const %opensmtpd-pam-services))
(service-extension profile-service-type
(compose list opensmtpd-configuration-package))
(service-extension shepherd-root-service-type
(service-extension activation-service-type exim-activation)
(service-extension profile-service-type exim-profile)
(service-extension mail-aliases-service-type (const '()))))))
+
+\f
+;;;
+;;; GNU Mailutils IMAP4 Daemon.
+;;;
+
+(define %default-imap4d-config-file
+ (plain-file "imap4d.conf" "server localhost {};\n"))
+
+(define-record-type* <imap4d-configuration>
+ imap4d-configuration make-imap4d-configuration imap4d-configuration?
+ (package imap4d-configuration-package
+ (default mailutils))
+ (config-file imap4d-configuration-config-file
+ (default %default-imap4d-config-file)))
+
+(define imap4d-shepherd-service
+ (match-lambda
+ (($ <imap4d-configuration> package config-file)
+ (list (shepherd-service
+ (provision '(imap4d))
+ (requirement '(networking syslogd))
+ (documentation "Run the imap4d daemon.")
+ (start (let ((imap4d (file-append package "/sbin/imap4d")))
+ #~(make-forkexec-constructor
+ (list #$imap4d "--daemon" "--foreground"
+ "--config-file" #$config-file))))
+ (stop #~(make-kill-destructor)))))))
+
+(define imap4d-service-type
+ (service-type
+ (name 'imap4d)
+ (description
+ "Run the GNU @command{imap4d} to serve e-mail messages through IMAP.")
+ (extensions
+ (list (service-extension
+ shepherd-root-service-type imap4d-shepherd-service)))
+ (default-value (imap4d-configuration))))
+
+\f
+;;;
+;;; Radicale.
+;;;
+
+(define-record-type* <radicale-configuration>
+ radicale-configuration make-radicale-configuration
+ radicale-configuration?
+ (package radicale-configuration-package
+ (default radicale))
+ (config-file radicale-configuration-config-file
+ (default %default-radicale-config-file)))
+
+(define %default-radicale-config-file
+ (plain-file "radicale.conf" "
+[auth]
+type = htpasswd
+htpasswd_filename = /var/lib/radicale/users
+htpasswd_encryption = plain
+
+[server]
+hosts = localhost:5232"))
+
+(define %radicale-accounts
+ (list (user-group
+ (name "radicale")
+ (system? #t))
+ (user-account
+ (name "radicale")
+ (group "radicale")
+ (system? #t)
+ (comment "Radicale Daemon")
+ (home-directory "/var/empty")
+ (shell (file-append shadow "/sbin/nologin")))))
+
+(define radicale-shepherd-service
+ (match-lambda
+ (($ <radicale-configuration> package config-file)
+ (list (shepherd-service
+ (provision '(radicale))
+ (documentation "Run the radicale daemon.")
+ (requirement '(networking))
+ (start #~(make-forkexec-constructor
+ (list #$(file-append package "/bin/radicale")
+ "-C" #$config-file)
+ #:user "radicale"
+ #:group "radicale"))
+ (stop #~(make-kill-destructor)))))))
+
+(define radicale-activation
+ (match-lambda
+ (($ <radicale-configuration> package config-file)
+ (with-imported-modules '((guix build utils))
+ #~(begin
+ (use-modules (guix build utils))
+ (let ((uid (passwd:uid (getpw "radicale")))
+ (gid (group:gid (getgr "radicale"))))
+ (mkdir-p "/var/lib/radicale/collections")
+ (chown "/var/lib/radicale" uid gid)
+ (chown "/var/lib/radicale/collections" uid gid)
+ (chmod "/var/lib/radicale" #o700)))))))
+
+(define radicale-service-type
+ (service-type
+ (name 'radicale)
+ (description "Run radicale, a small CalDAV and CardDAV server.")
+ (extensions
+ (list (service-extension shepherd-root-service-type radicale-shepherd-service)
+ (service-extension account-service-type (const %radicale-accounts))
+ (service-extension activation-service-type radicale-activation)))
+ (default-value (radicale-configuration))))