system-configuration/modules/services/mail.scm

mail.scm

1
;;; GNU Guix --- Functional package management for GNU
2
;;; Copyright © 2019 Julien Lepiller <julien@lepiller.eu>
3
;;;
4
;;; This file is part of GNU Guix.
5
;;;
6
;;; GNU Guix is free software; you can redistribute it and/or modify it
7
;;; under the terms of the GNU General Public License as published by
8
;;; the Free Software Foundation; either version 3 of the License, or (at
9
;;; your option) any later version.
10
;;;
11
;;; GNU Guix is distributed in the hope that it will be useful, but
12
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
13
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
;;; GNU General Public License for more details.
15
;;;
16
;;; You should have received a copy of the GNU General Public License
17
;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
18
;;;
19
;;; Some of the help text was taken from the default dovecot.conf files.
20
21
(define-module (services mail)
22
  #:use-module (gnu services)
23
  #:use-module (gnu services base)
24
  #:use-module (gnu services configuration)
25
  #:use-module (gnu services shepherd)
26
  #:use-module (gnu system pam)
27
  #:use-module (gnu system shadow)
28
  #:use-module (gnu packages admin)
29
  #:use-module (gnu packages mail)
30
  #:use-module (guix gexp)
31
  #:use-module (guix records)
32
  #:use-module (ice-9 match)
33
  #:export (dkimproxy-out-service-type
34
35
            dkimproxy-out-signature-configuration
36
            dkimproxy-out-signature-configuration-type
37
            dkimproxy-out-signature-configuration-key
38
            dkimproxy-out-signature-configuration-algorithm
39
            dkimproxy-out-signature-configuration-method
40
            dkimproxy-out-signature-configuration-domain
41
            dkimproxy-out-signature-configuration-identity
42
            dkimproxy-out-signature-configuration-selector
43
44
            dkimproxy-out-configuration
45
            dkimproxy-out-configuration-package
46
            dkimproxy-out-configuration-listen
47
            dkimproxy-out-configuration-relay
48
            dkimproxy-out-configuration-list-id-map
49
            dkimproxy-out-configuration-sender-map
50
            dkimproxy-out-configuration-reject-error?
51
52
            dkimproxy-out-configuration-config-file))
53
54
(define-record-type* <dkimproxy-out-signature-configuration>
55
  dkimproxy-out-signature-configuration make-dkimproxy-out-signature-configuration
56
  dkimproxy-out-signature-configuration?
57
  (type      dkimproxy-out-signature-configuration-type
58
             (default 'dkim))
59
  (key       dkimproxy-out-signature-configuration-key
60
             (default #f))
61
  (algorithm dkimproxy-out-signature-configuration-algorithm
62
             (default #f))
63
  (method    dkimproxy-out-signature-configuration-method
64
             (default #f))
65
  (domain    dkimproxy-out-signature-configuration-domain
66
             (default #f))
67
  (identity  dkimproxy-out-signature-configuration-identity
68
             (default #f))
69
  (selector  dkimproxy-out-signature-configuration-selector
70
             (default #f)))
71
72
(define generate-dkimproxy-out-signature-configuration
73
  (match-lambda
74
    (($ <dkimproxy-out-signature-configuration>
75
        type key algorithm method domain identity selector)
76
     (string-append
77
       (match type
78
         ('dkim "dkim")
79
         ('domainkeys "domainkeys"))
80
       (if (or key algorithm method domain identity selector)
81
           (string-append
82
             "("
83
             (string-join
84
              `(
85
                ,@(if key
86
                    (list (string-append "key=" key))
87
                    '())
88
               ,@(if algorithm
89
                   (list (string-append "a=" algorithm))
90
                   '())
91
               ,@(if method
92
                   (list (string-append "c=" method))
93
                   '())
94
               ,@(if domain
95
                   (list (string-append "d=" domain))
96
                   '())
97
               ,@(if identity
98
                   (list (string-append "i=" identity))
99
                   '())
100
               ,@(if selector
101
                   (list (string-append "s=" selector))
102
                   '()))
103
              ",")
104
             ")")
105
           "")))))
106
107
(define-record-type* <dkimproxy-out-configuration>
108
  dkimproxy-out-configuration make-dkimproxy-out-configuration
109
  dkimproxy-out-configuration?
110
  (package     dkimproxy-out-configuration-package
111
               (default dkimproxy))
112
  (listen      dkimproxy-out-configuration-listen
113
               (default #f))
114
  (relay       dkimproxy-out-configuration-relay
115
               (default #f))
116
  (list-id-map dkimproxy-out-configuration-list-id-map
117
               (default '()))
118
  (sender-map  dkimproxy-out-configuration-sender-map
119
               (default '()))
120
  (reject-error? dkimproxy-out-configuration-sender-reject-error?
121
                 (default #f))
122
  (config-file dkimproxy-out-configuration-config-file
123
               (default #f)))
124
125
(define (generate-map-file config filename)
126
  (apply plain-file filename
127
         (map (lambda (config)
128
                (match config
129
                  ((selector (config ...))
130
                   (string-append
131
                     selector " "
132
                     (string-join
133
                       (map generate-dkimproxy-out-signature-configuration config)
134
                       "\n")))
135
                  ((selector config)
136
                   (string-append
137
                     selector " "
138
                     (generate-dkimproxy-out-signature-configuration config)))))
139
              config)))
140
141
(define dkimproxy-out-shepherd-service
142
  (match-lambda
143
    (($ <dkimproxy-out-configuration> package listen relay list-id-map sender-map
144
        reject-error? config-file)
145
     (list (shepherd-service
146
             (provision '(dkimproxy-out))
147
             (requirement '(loopback))
148
             (documentation "Outbound DKIM proxy.")
149
             (start (let ((proxy (file-append package "/bin/dkimproxy.out")))
150
                      (if config-file
151
                        #~(make-forkexec-constructor
152
                            (list #$proxy (string-append "--conf_file=" #$config-file)
153
                                  "--pidfile=/var/run/dkimproxy.out.pid"
154
                                  "--user=dkimproxy" "--group=dkimproxy")
155
                            #:pid-file "/var/run/dkimproxy.out.pid")
156
                        (let* ((first-signature (match sender-map
157
                                                 (((sender (signature _ ...)) _ ...)
158
                                                   signature)
159
                                                 (((sender signature) _ ...)
160
                                                   signature)))
161
                               (domains
162
                                 (apply append
163
                                   (map
164
                                     (lambda (sender)
165
                                       (match sender
166
                                         (((domains ...) config)
167
                                          domains)
168
                                         ((domain config)
169
                                          domain)))
170
                                     sender-map)))
171
                               (sender-map (generate-map-file sender-map
172
                                                              "sender.map"))
173
                               (listid-map
174
                                 (if (null? list-id-map)
175
                                     #f
176
                                     (generate-map-file list-id-map "listid.map")))
177
                               (keyfile
178
                                 (dkimproxy-out-signature-configuration-key
179
                                   first-signature))
180
                               (selector
181
                                 (dkimproxy-out-signature-configuration-selector
182
                                   first-signature))
183
                               (method
184
                                 (dkimproxy-out-signature-configuration-method
185
                                   first-signature))
186
                               (signature
187
                                 (match (dkimproxy-out-signature-configuration-type
188
                                          first-signature)
189
				   ('dkim "dkim")
190
				   ('domainkeys "domainkeys"))))
191
                          #~(make-forkexec-constructor
192
                              `(,#$proxy "--pidfile=/var/run/dkimproxy.out.pid"
193
                                "--user=dkimproxy" "--group=dkimproxy"
194
                                ,(string-append "--listen=" #$listen)
195
                                ,(string-append "--relay=" #$relay)
196
                                ,(string-append "--sender_map=" #$sender-map)
197
                                ,@(if #$listid-map
198
                                    (list
199
                                      (string-append "--listid_map=" #$listid-map))
200
                                    '())
201
                                ,(string-append "--domain=" #$domains)
202
                                ,(string-append "--keyfile=" #$keyfile)
203
                                ,(string-append "--selector=" #$selector)
204
                                ,@(if #$method
205
                                      (list
206
                                        (string-append "--method=" #$method))
207
                                      '())
208
                                ,@(if #$reject-error?
209
                                      '("--reject_error")
210
                                      '())
211
                                ,@(if #$signature
212
                                      (list
213
                                        (string-append "--signature=" #$signature))
214
                                      '())))))))
215
             (stop #~(make-kill-destructor)))))))
216
217
(define %dkimproxy-accounts
218
  (list (user-group
219
          (name "dkimproxy")
220
          (system? #t))
221
        (user-account
222
          (name "dkimproxy")
223
          (group "dkimproxy")
224
          (system? #t)
225
          (comment "Dkimproxy user")
226
          (home-directory "/var/empty")
227
          (shell (file-append shadow "/sbin/nologin")))))
228
229
(define dkimproxy-out-service-type
230
  (service-type
231
    (name 'dkimproxy-out)
232
    (description "dkimproxy-out service")
233
    (extensions
234
      (list (service-extension account-service-type
235
                               (const %dkimproxy-accounts))
236
            (service-extension shepherd-root-service-type
237
                               dkimproxy-out-shepherd-service)))))
238