(address . guix-patches@gnu.org)(name . Joshua Branson)(address . jbranso@dismail.de)
Openmstpd-configuration may only be configured by a config-file. This
patch, enables one to configure opensmtpd by using some guile record
types (defined via define-record-type*).
This patch is mostly complete, but I could use some guidance on what
else needs to be done for it to be accepted in to guix properly.
I do have some documentation written for the opensmtpd-service,
but it is probably not complete and is currently written in the
org-mode format.
* gnu/services/mail.scm (opensmtpd-table-configuration): New record.
* gnu/services/mail.scm (opensmtpd-ca-configuration): New record.
* gnu/services/mail.scm (opensmtpd-pki-configuration): New record.
* gnu/services/mail.scm (opensmtpd-action-local-delivery-configuration): New record.
* gnu/services/mail.scm (opensmtpd-maildir-configuration): New record.
* gnu/services/mail.scm (opensmtpd-mda-configuration): New record.
* gnu/services/mail.scm (opensmtpd-action-relay-configuration): New record.
* gnu/services/mail.scm (opensmtpd-option-configuration): New record.
* gnu/services/mail.scm (opensmtpd-filter-phase-configuration): New record.
* gnu/services/mail.scm (opensmtpd-filter-configuration): New record.
* gnu/services/mail.scm (opensmtpd-listen-on-configuration): New record.
* gnu/services/mail.scm (opensmtpd-listen-on-socket-configuration): New record.
* gnu/services/mail.scm (opensmtpd-match-configuration): New record.
* gnu/services/mail.scm (opensmtpd-smtp-configuration): New record.
* gnu/services/mail.scm (opensmtpd-srs-configuration): New record.
* gnu/services/mail.scm (opensmtpd-queue-configuration): New record.
* gnu/services/mail.scm (opensmtpd-configuration): New record.
---
gnu/services/mail.scm | 2016 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 2013 insertions(+), 3 deletions(-)
Toggle diff (369 lines)
diff --git a/gnu/services/mail.scm b/gnu/services/mail.scm
index d99743ac31..bdc0ee3bf7 100644
--- a/gnu/services/mail.scm
+++ b/gnu/services/mail.scm
@@ -57,8 +57,143 @@ (define-module (gnu services mail)
mailbox-configuration
namespace-configuration
+ opensmtpd-table-configuration
+ opensmtpd-table-configuration?
+ opensmtpd-table-configuration-name
+ opensmtpd-table-configuration-file-db
+ opensmtpd-table-configuration-data
+
+ opensmtpd-ca-configuration
+ opensmtpd-ca-configuration?
+ opensmtpd-ca-configuration-name
+ opensmtpd-ca-configuration-file
+
+ opensmtpd-pki-configuration
+ opensmtpd-pki-configuration?
+ opensmtpd-pki-configuration-domain
+ opensmtpd-pki-configuration-cert
+ opensmtpd-pki-configuration-key
+ opensmtpd-pki-configuration-dhe
+
+ opensmtpd-action-local-delivery-configuration
+ opensmtpd-action-local-delivery-configuration?
+ opensmtpd-action-local-delivery-configuration-method
+ opensmtpd-action-local-delivery-configuration-alias
+ opensmtpd-action-local-delivery-configuration-ttl
+ opensmtpd-action-local-delivery-configuration-user
+ opensmtpd-action-local-delivery-configuration-userbase
+ opensmtpd-action-local-delivery-configuration-virtual
+ opensmtpd-action-local-delivery-configuration-wrapper
+
+ opensmtpd-maildir-configuration
+ opensmtpd-maildir-configuration?
+ opensmtpd-maildir-configuration-pathname
+ opensmtpd-maildir-configuration-junk
+
+ opensmtpd-mda-configuration
+ opensmtpd-mda-configuration-name
+ opensmtpd-mda-configuration-command
+
+ opensmtpd-action-relay-configuration
+ opensmtpd-action-relay-configuration?
+ opensmtpd-action-relay-configuration-backup
+ opensmtpd-action-relay-configuration-backup-mx
+ opensmtpd-action-relay-configuration-helo
+ opensmtpd-action-relay-configuration-domain
+ opensmtpd-action-relay-configuration-host
+ opensmtpd-action-relay-configuration-pki
+ opensmtpd-action-relay-configuration-srs
+ opensmtpd-action-relay-configuration-tls
+ opensmtpd-action-relay-configuration-auth
+ opensmtpd-action-relay-configuration-mail-from
+ opensmtpd-action-relay-configuration-src
+
+ opensmtpd-option-configuration
+ opensmtpd-option-configuration?
+ opensmtpd-option-configuration-option
+ opensmtpd-option-configuration-not
+ opensmtpd-option-configuration-regex
+ opensmtpd-option-configuration-data
+
+ opensmtpd-filter-phase-configuration
+ opensmtpd-filter-phase-configuration?
+ opensmtpd-filter-phase-configuration-name
+ opensmtpd-filter-phase-configuration-phase-name
+ opensmtpd-filter-phase-configuration-options
+ opensmtpd-filter-phase-configuration-decision
+ opensmtpd-filter-phase-configuration-message
+ opensmtpd-filter-phase-configuration-value
+
+ opensmtpd-filter-configuration
+ opensmtpd-filter-configuration?
+ opensmtpd-filter-configuration-name
+ opensmtpd-filter-configuration-proc
+
+ opensmtpd-listen-on-configuration
+ opensmtpd-listen-on-configuration?
+ opensmtpd-listen-on-configuration-interface
+ opensmtpd-listen-on-configuration-family
+ opensmtpd-listen-on-configuration-auth
+ opensmtpd-listen-on-configuration-auth-optional
+ opensmtpd-listen-on-configuration-filters
+ opensmtpd-listen-on-configuration-hostname
+ opensmtpd-listen-on-configuration-hostnames
+ opensmtpd-listen-on-configuration-mask-src
+ opensmtpd-listen-on-configuration-disable-dsn
+ opensmtpd-listen-on-configuration-pki
+ opensmtpd-listen-on-configuration-port
+ opensmtpd-listen-on-configuration-proxy-v2
+ opensmtpd-listen-on-configuration-received-auth
+ opensmtpd-listen-on-configuration-senders
+ opensmtpd-listen-on-configuration-secure-connection
+ opensmtpd-listen-on-configuration-tag
+
+ opensmtpd-listen-on-socket-configuration
+ opensmtpd-listen-on-socket-configuration?
+ opensmtpd-listen-on-socket-configuration-filters
+ opensmtpd-listen-on-socket-configuration-mask-src
+ opensmtpd-listen-on-socket-configuration-tag
+
+ opensmtpd-match-configuration
+ opensmtpd-match-configuration?
+ opensmtpd-match-configuration-action
+ opensmtpd-match-configuration-options
+
+ opensmtpd-smtp-configuration
+ opensmtpd-smtp-configuration?
+ opensmtpd-smtp-configuration-ciphers
+ opensmtpd-smtp-configuration-limit-max-mails
+ opensmtpd-smtp-configuration-limit-max-rcpt
+ opensmtpd-smtp-configuration-max-message-size
+ opensmtpd-smtp-configuration-sub-addr-delim character
+
+ opensmtpd-srs-configuration
+ opensmtpd-srs-configuration?
+ opensmtpd-srs-configuration-key
+ opensmtpd-srs-configuration-backup-key
+ opensmtpd-srs-configuration-ttl-delay
+
+ opensmtpd-queue-configuration
+ opensmtpd-queue-configuration?
+ opensmtpd-queue-configuration-compression
+ opensmtpd-queue-configuration-encryption
+ opensmtpd-queue-configuration-ttl-delay
+
opensmtpd-configuration
opensmtpd-configuration?
+ opensmtpd-package
+ opensmtpd-config-file
+ opensmtpd-configuration-bounce
+ opensmtpd-configuration-listen-ons
+ opensmtpd-configuration-listen-on-socket
+ opensmtpd-configuration-includes
+ opensmtpd-configuration-matches
+ opensmtpd-configuration-mda-wrappers
+ opensmtpd-configuration-mta-max-deferred
+ opensmtpd-configuration-srs
+ opensmtpd-configuration-smtp
+ opensmtpd-configuration-queue
+
opensmtpd-service-type
%default-opensmtpd-config-file
@@ -1651,13 +1786,1888 @@ (define (generate-dovecot-documentation)
;;; OpenSMTPD.
;;;
+;; some fieldnames have a default value of #f, which is ok. They cannot have a value of #t.
+;; for example opensmtpd-table-configuration-data can be #f, BUT NOT true.
+;; my/sanitize procedure tests values to see if they are of the right kind.
+;; procedure false? is needed to allow fields like 'values' to be blank, (empty), or #f BUT also
+;; have a value like a list of strings.
+(define (false? var)
+ (eq? #f var))
+
+;; this procedure takes in a var and a list of procedures. It loops through list of procedures passing in var to each.
+;; if one procedure returns #t, the function returns true. Otherwise #f.
+;; TODO for fun rewrite this using map
+;; If I rewrote it in map, then it may help with sanitizing.
+;; eg: I could then potentially easily sanitize vars with lambda procedures.
+(define (is-value-right-type? var list-of-procedures record fieldname)
+ (if (null? list-of-procedures)
+ #f
+ (cond [(procedure? (car list-of-procedures))
+ (if ((car list-of-procedures) var)
+ #t
+ (is-value-right-type? var (cdr list-of-procedures) record fieldname))]
+ [(and (sanitize-configuration? (car list-of-procedures))
+ (sanitize-configuration-error-if-proc-fails (car list-of-procedures))
+ (if ((sanitize-configuration-proc (car list-of-procedures)) var)
+ #t
+ (begin
+ (apply string-append
+ (sanitize-configuration-error-message (car list-of-procedures)))
+ (throw 'bad! var))))]
+ [else (if ((sanitize-configuration-proc (car list-of-procedures)) var)
+ #t
+ (is-value-right-type? var (cdr list-of-procedures) record fieldname))])))
+
+;; converts strings like this:
+;; "apple, ham, cherry" -> "apple, ham, or cherry"
+;; "pineapple" -> "pinneapple".
+;; "cheese, grapefruit, or jam" -> "cheese, grapefruit, or jam"
+(define (add-comma-or string)
+ (define last-comma-location (string-rindex string #\,))
+ (if last-comma-location
+ (if (string-contains string ", or" last-comma-location)
+ string
+ (string-replace string ", or" last-comma-location
+ (+ 1 last-comma-location)))
+ string))
+
+;; I could test for read-ability of a file, but then I would have to
+;; test the program as root everytime instead of as a normal user...
+(define (file-exists? file)
+(if (string? file)
+ (access? file F_OK)
+ #f))
+
+(define (list-of-procedures->string procedures)
+ (define string
+ (let loop ([procedures procedures])
+ (if (null? procedures)
+ ""
+ (begin
+ (string-append
+ (cond [(eq? false? (car procedures))
+ "#f , "]
+ [(eq? boolean? (car procedures))
+ "boolean, "]
+ [(eq? string? (car procedures))
+ "string, "]
+ [(eq? integer? (car procedures))
+ "integer, "]
+ [(eq? list-of-strings? (car procedures))
+ "list of strings, "]
+ [(eq? assoc-list? (car procedures))
+ "an association list, "]
+ [(eq? opensmtpd-pki-configuration? (car procedures))
+ "an <opensmtpd-pki-configuration> record, "]
+ [(eq? opensmtpd-table-configuration? (car procedures))
+ "an <opensmtpd-table-configuration> record, "]
+ [(eq? list-of-unique-opensmtpd-match-configuration? (car procedures))
+ "a list of unique <opensmtpd-match-configuration> records, "]
+ [(eq? table-whose-data-are-assoc-list? (car procedures))
+ (string-append
+ "an <opensmtpd-table-configuration> record whose fieldname 'values' are an assoc-list \n"
+ "(eg: (opensmtpd-table-configuration (name \"table\") (data '(\"joshua\" . \"$encrypted$password\")))), ")]
+ [(eq? file-exists? (car procedures))
+ "file, "]
+ [else "has an incorrect value, "])
+ (loop (cdr procedures)))))))
+ (add-comma-or (string-append (string-drop-right string 2) ".\n")))
+
+;; TODO can I M-x raise-sexp (string=? string var) in this procedure? and get rid of checking
+;; if the var is a string? The previous string-in-list? had that check.
+;; (string-in-list? '("hello" 5 "cat")) currently works. If I M-x raise-sexp (string=? string var)
+;; then it will no longer work.
+(define (string-in-list? string list)
+ (primitive-eval (cons 'or (map (lambda (var) (and (string? var) (string=? string var))) list))))
+
+(define (my/sanitize var record fieldname list-of-procedures)
+ (if (is-value-right-type? var list-of-procedures record fieldname)
+ var
+ (begin
+ (display (string-append "<" record "> fieldname: '" fieldname "' is of type "
+ (list-of-procedures->string list-of-procedures) "\n"))
+ (throw 'bad! var))))
+
+;; Some example opensmtpd-table-configurations:
+;;
+;; (opensmtpd-table-configuration (name "root accounts") (data '(("joshua" . "root@dismail.de") ("joshua" . "postmaster@dismail.de"))))
+;; (opensmtpd-table-configuration (name "root accounts") (data (list "mysite.me" "your-site.com")))
+;; TODO should <opensmtpd-table-configuration> support have a fieldname 'file'?
+;; Or should I change name to name-or-file ?
+(define-record-type* <opensmtpd-table-configuration>
+ opensmtpd-table-configuration make-opensmtpd-table-configuration
+ opensmtpd-table-configuration?
+ this-record
+ (name opensmtpd-table-configuration-name ;; string
+ (default #f)
+ (sanitize (lambda (var)
+ (my/sanitize var "opensmtpd-table-configuration" "name" (list string?)))))
+ (file-db opensmtpd-table-configuration-file-db
+ (default #f)
+ (sanitize (lambda (var)
+ (my/sanitize var "opensmtpd-table-configuration" "file-db"
+ (list boolean?)))))
+ ;; FIXME support an aliasing table as described here:
+ ;; https://man.openbsd.org/table.5
+ ;; One may have to use the record file for this. I don't think tables support a table like this:
+ ;; table "name" { joshua = joshua@gnucode.me,joshua@gnu-hurd.com,joshua@propernaming.org, root = root@gnucode.me }
+ ;; If values is an absolute filename, then it will use said filename to house the table info.
+ ;; filename must be an absolute filename.
+ (data opensmtpd-table-configuration-data
+ (default #f)
+ (sanitize (lambda (var)
+ (my/sanitize var "opensmtpd-table-configuration" "values"
+ (list file-exists? list-of-strings? assoc-list?)))))
+ ;; is a list of values or key values
+ ;; eg: (list "mysite.me" "your-site.com")
+ ;; eg: (list ("joshua" . "joshua@gnu.org") ("james" . "james@gnu.org"))
+ ;; I am currently making these values be as assocation list of strings only.
+ ;; FIXME should I allow a var like this?
+ ;; (list (cons "gnucode.me" 234.949.392.23))
+ ;; can be of type: (quote list-of-strings) or (quote assoc-list)
+ ;; (opensmtpd-table-configuration-type record) returns the values' type. The user SHOULD NEVER set the type.
+ ;; TODO jpoiret: on irc reccomends that I just use an outside function to determine fieldname 'values', type.
+ ;; it would be "simpler" and possibly easier for the next person working on this code to understand what is happening.
+ (type opensmtpd-table-configuration-type
+ (default #f)
+ (thunked)
+ (sanitize (lambda (var)
+ (cond [(opensmtpd-table-configuration-data this-record)
+ (if (list-of-strings? (opensmtpd-table-configuration-data this-record))
+ (quote list-of-strings)
+ (quote assoc-list))]
+ [(file-exists? (opensmtpd-table-configuration-data this-record))
+ (if (opensmtpd-table-configuration-file-db this-record)
+ (quote db)
+ (quote file))]
+ [else
+ (display "opensmtpd-table-configuration-type is broke\n")
+ (throw 'bad! var)])))))
+
+(define-record-type* <opensmtpd-ca-configuration>
+ opensmtpd-ca-configuration make-opensmtpd-ca-configuration
+ opensmtpd-ca-configuration?
+ (name opensmtpd-ca-configuration-name
+ (default #f)
+ (sanitize (lambda (var)
+ (my/sanitize var "opensmtpd-ca-configuration" "name" (list string?)))))
+ (file opensmtpd-ca-configuration-file
+ (default #f)
+ (sanitize (lambda (var)
+ (my/sanitize var "opensmtpd-ca-configuration" "file" (list file-exists?))))))
+
+(define-record-type* <opensmtpd-pki-configuration>
+ opensmtpd-pki-configuration make-opensmtpd-pki-configuration
+ opensmtpd-pki-configuration?
+ (domain opensmtpd-pki-configuration-domain
+ (default #f)
+ (sanitize (lambda (var)
+ (my/sanitize var "opensmtpd-pki-configuration" "domain" (list string?)))))
+ ;; TODO/FIXME this should probably be a list of files. The opensmtpd documentation says
+ ;; that you could have a list of files:
+ ;;
+ ;; pki pkiname cert certfile
+ ;; Associate certificate file certfile with host pkiname, and use that file to prove
+ ;; the identity of the mail server to clients. pkiname is the server's name, de?
+ ;; rived from the default hostname or set using either
+ ;; /gnu/store/2d13sdz76ldq8zgwv4wif0zx7hkr3mh2-opensmtpd-6.8.0p2/etc/mailname or us?
+ ;; ing the hostname directive. If a fallback certificate or SNI is wanted, the ‘*’
+ ;; wildcard may be used as pkiname.
+
+ ;; A certificate chain may be created by appending one or many certificates, includ?
+ ;; ing a Certificate Authority certificate, to certfile. The creation of certifi?
+ ;; cates is documented in starttls(8).
+ (cert opensmtpd-pki-configuration-cert
+ (default #f)
+ (sanitize (lambda (var)
+ (my/sanitize var "opensmtpd-pki-configuration" "cert" (list file-exists?)))))
+ (key opensmtpd-pki-configuration-key
+ (default #f)
+ (sanitize (lambda (var)
+ (my/sanitize var "opensmtpd-pki-configuration" "key" (list file-exists?)))))
+ ; todo sanitize this. valid parameters are "none", "legacy", or "auto".
+ (dhe opensmtpd-pki-configuration-dhe
+ (default #f)
+ (sanitize (lambda (var)
+ (my/sanitize var "opensmtpd-dhe" "dhe" (list false? string?))))))
+
+(define-record-type* <opensmtpd-lmtp-configuration>
+ opensmtpd-lmtp-configuration make-opensmtpd-lmtp-configuration
+ opensmtpd-lmtp-configuration?
+ (destination opensmtpd-lmtp-configuration-destination
+ (default #f)
+ (sanitize (lambda (var)
+ (my/sanitize var "opensmtpd-lmtp-configuration" "destination"
+ (list string?)))))
+ (rcpt-to opensmtpd-lmtp-configuration-rcpt-to
+ (default #f)
+ (sanitize (lambda (var)
+ (my/sanitize var "opensmtpd-lmt
This message was truncated. Download the full message here.