gnu: emacs-ebib: Update to 2.39.3.
[jackhill/guix/guix.git] / gnu / services / telephony.scm
CommitLineData
b6d2930d 1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2017 nee <nee-git@hidamari.blue>
374fea0f 3;;; Copyright © 2021, 2022 Maxim Cournoyer <maxim.cournoyer@gmail.com>
b6d2930d 4;;;
5;;; This file is part of GNU Guix.
6;;;
7;;; GNU Guix is free software; you can redistribute it and/or modify it
8;;; under the terms of the GNU General Public License as published by
9;;; the Free Software Foundation; either version 3 of the License, or (at
10;;; your option) any later version.
11;;;
12;;; GNU Guix is distributed in the hope that it will be useful, but
13;;; WITHOUT ANY WARRANTY; without even the implied warranty of
14;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15;;; GNU General Public License for more details.
16;;;
17;;; You should have received a copy of the GNU General Public License
18;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
19
20(define-module (gnu services telephony)
10f55470
MC
21 #:use-module ((gnu build jami-service) #:select (account-fingerprint?))
22 #:use-module ((gnu services) #:hide (delete))
23 #:use-module (gnu services configuration)
b6d2930d 24 #:use-module (gnu services shepherd)
25 #:use-module (gnu system shadow)
26 #:use-module (gnu packages admin)
10f55470
MC
27 #:use-module (gnu packages certs)
28 #:use-module (gnu packages glib)
85b4dabd 29 #:use-module (gnu packages guile-xyz)
10f55470 30 #:use-module (gnu packages jami)
b6d2930d 31 #:use-module (gnu packages telephony)
42679e3f 32 #:use-module (guix deprecation)
b6d2930d 33 #:use-module (guix records)
10f55470
MC
34 #:use-module (guix modules)
35 #:use-module (guix packages)
b6d2930d 36 #:use-module (guix gexp)
37 #:use-module (srfi srfi-1)
10f55470
MC
38 #:use-module (srfi srfi-2)
39 #:use-module (srfi srfi-26)
40 #:use-module (ice-9 format)
b6d2930d 41 #:use-module (ice-9 match)
10f55470
MC
42 #:export (jami-account
43 jami-account-archive
44 jami-account-allowed-contacts
45 jami-account-moderators
46 jami-account-rendezvous-point?
47 jami-account-discovery?
48 jami-account-bootstrap-uri
49 jami-account-name-server-uri
50
51 jami-configuration
8649ac5e 52 jami-configuration-libjami
10f55470
MC
53 jami-configuration-dbus
54 jami-configuration-enable-logging?
55 jami-configuration-debug?
56 jami-configuration-auto-answer?
57 jami-configuration-accounts
58
59 jami-service-type
60
42679e3f
LMP
61 mumble-server-configuration
62 make-mumble-server-configuration
63 mumble-server-configuration?
64 mumble-server-configuration-package
65 mumble-server-configuration-user
66 mumble-server-configuration-group
67 mumble-server-configuration-port
68 mumble-server-configuration-welcome-text
69 mumble-server-configuration-server-password
70 mumble-server-configuration-max-users
71 mumble-server-configuration-max-user-bandwidth
72 mumble-server-configuration-database-file
73 mumble-server-configuration-log-file
74 mumble-server-configuration-pid-file
75 mumble-server-configuration-autoban-attempts
76 mumble-server-configuration-autoban-timeframe
77 mumble-server-configuration-autoban-time
78 mumble-server-configuration-opus-threshold
79 mumble-server-configuration-channel-nesting-limit
80 mumble-server-configuration-channelname-regex
81 mumble-server-configuration-username-regex
82 mumble-server-configuration-text-message-length
83 mumble-server-configuration-image-message-length
84 mumble-server-configuration-cert-required?
85 mumble-server-configuration-remember-channel?
86 mumble-server-configuration-allow-html?
87 mumble-server-configuration-allow-ping?
88 mumble-server-configuration-bonjour?
89 mumble-server-configuration-send-version?
90 mumble-server-configuration-log-days
91 mumble-server-configuration-obfuscate-ips?
92 mumble-server-configuration-ssl-cert
93 mumble-server-configuration-ssl-key
94 mumble-server-configuration-ssl-dh-params
95 mumble-server-configuration-ssl-ciphers
96 mumble-server-configuration-public-registration
97 mumble-server-configuration-file
98
99 mumble-server-public-registration-configuration
100 make-mumble-server-public-registration-configuration
101 mumble-server-public-registration-configuration?
102 mumble-server-public-registration-configuration-name
103 mumble-server-public-registration-configuration-url
104 mumble-server-public-registration-configuration-password
105 mumble-server-public-registration-configuration-hostname
106
107 mumble-server-service-type))
b6d2930d 108
10f55470
MC
109\f
110;;;
111;;; Jami daemon.
112;;;
113
114;;; XXX: Passing a computed-file object as the account is used for tests.
115(define (string-or-computed-file? val)
116 (or (string? val)
117 (computed-file? val)))
118
119(define (string-list? val)
120 (and (list? val)
121 (and-map string? val)))
122
123(define (account-fingerprint-list? val)
124 (and (list? val)
125 (and-map account-fingerprint? val)))
126
127(define-maybe string-list)
128
129(define-maybe/no-serialization account-fingerprint-list)
130
131(define-maybe boolean)
132
133(define-maybe string)
134
135;;; The following serializers are used to derive an account details alist from
136;;; a <jami-account> record.
137(define (serialize-string-list _ val)
138 (string-join val ";"))
139
140(define (serialize-boolean _ val)
141 (format #f "~:[false~;true~]" val))
142
143(define (serialize-string _ val)
144 val)
145
146;;; Note: Serialization is used to produce an account details alist that can
147;;; be passed to the SET-ACCOUNT-DETAILS procedure. Fields that do not map to
148;;; a Jami account 'detail' should have their serialization disabled via the
149;;; 'empty-serializer' procedure.
150(define-configuration jami-account
151 (archive
152 (string-or-computed-file)
153 "The account archive (backup) file name of the account. This is used to
154provision the account when the service starts. The account archive should
155@emph{not} be encrypted. It is highly recommended to make it readable only to
156the @samp{root} user (i.e., not in the store), to guard against leaking the
157secret key material of the Jami account it contains."
158 empty-serializer)
159 (allowed-contacts
8cb1a49a 160 maybe-account-fingerprint-list
10f55470
MC
161 "The list of allowed contacts for the account, entered as their 40
162characters long fingerprint. Messages or calls from accounts not in that list
163will be rejected. When unspecified, the configuration of the account archive
164is used as-is with respect to contacts and public inbound calls/messaging
165allowance, which typically defaults to allow any contact to communicate with
166the account."
167 empty-serializer)
168 (moderators
8cb1a49a 169 maybe-account-fingerprint-list
10f55470
MC
170 "The list of contacts that should have moderation privileges (to ban, mute,
171etc. other users) in rendezvous conferences, entered as their 40 characters
172long fingerprint. When unspecified, the configuration of the account archive
173is used as-is with respect to moderation, which typically defaults to allow
174anyone to moderate."
175 empty-serializer)
176 ;; The serializable fields below are to be set with set-account-details.
177 (rendezvous-point?
8cb1a49a 178 maybe-boolean
10f55470
MC
179 "Whether the account should operate in the rendezvous mode. In this mode,
180all the incoming audio/video calls are mixed into a conference. When left
181unspecified, the value from the account archive prevails.")
182 (peer-discovery?
8cb1a49a 183 maybe-boolean
10f55470
MC
184 "Whether peer discovery should be enabled. Peer discovery is used to
185discover other OpenDHT nodes on the local network, which can be useful to
186maintain communication between devices on such network even when the
187connection to the the Internet has been lost. When left unspecified, the
188value from the account archive prevails.")
189 (bootstrap-hostnames
8cb1a49a 190 maybe-string-list
10f55470
MC
191 "A list of hostnames or IPs pointing to OpenDHT nodes, that should be used
192to initially join the OpenDHT network. When left unspecified, the value from
193the account archive prevails.")
194 (name-server-uri
8cb1a49a 195 maybe-string
10f55470
MC
196 "The URI of the name server to use, that can be used to retrieve the
197account fingerprint for a registered username."))
198
199(define (jami-account->alist jami-account-object)
200 "Serialize the JAMI-ACCOUNT object as an alist suitable to be passed to
201SET-ACCOUNT-DETAILS."
202 (define (field-name->account-detail name)
203 (match name
204 ('rendezvous-point? "Account.rendezVous")
205 ('peer-discovery? "Account.peerDiscovery")
206 ('bootstrap-hostnames "Account.hostname")
207 ('name-server-uri "RingNS.uri")
208 (_ #f)))
209
210 (filter-map (lambda (field)
211 (and-let* ((name (field-name->account-detail
212 (configuration-field-name field)))
213 (value ((configuration-field-serializer field)
214 name ((configuration-field-getter field)
215 jami-account-object)))
216 ;; The define-maybe default serializer produces an
8cb1a49a 217 ;; empty string for unspecified values.
10f55470
MC
218 (value* (if (string-null? value)
219 #f
220 value)))
221 (cons name value*)))
222 jami-account-fields))
223
224(define (jami-account-list? val)
225 (and (list? val)
226 (and-map jami-account? val)))
227
228(define-maybe/no-serialization jami-account-list)
229
230(define-configuration/no-serialization jami-configuration
8649ac5e 231 (libjami
374fea0f 232 (file-like libjami)
10f55470
MC
233 "The Jami daemon package to use.")
234 (dbus
85b4dabd 235 (file-like dbus-for-jami)
10f55470
MC
236 "The D-Bus package to use to start the required D-Bus session.")
237 (nss-certs
892f1b72 238 (file-like nss-certs)
10f55470
MC
239 "The nss-certs package to use to provide TLS certificates.")
240 (enable-logging?
241 (boolean #t)
242 "Whether to enable logging to syslog.")
243 (debug?
244 (boolean #f)
245 "Whether to enable debug level messages.")
246 (auto-answer?
247 (boolean #f)
248 "Whether to force automatic answer to incoming calls.")
249 (accounts
8cb1a49a 250 maybe-jami-account-list
10f55470
MC
251 "A list of Jami accounts to be (re-)provisioned every time the Jami daemon
252service starts. When providing this field, the account directories under
253@file{/var/lib/jami/} are recreated every time the service starts, ensuring a
254consistent state."))
255
256(define %jami-accounts
257 (list (user-group (name "jami") (system? #t))
258 (user-account
259 (name "jami")
260 (group "jami")
261 (system? #t)
262 (comment "Jami daemon user")
263 (home-directory "/var/lib/jami"))))
264
265(define (jami-configuration->command-line-arguments config)
266 "Derive the command line arguments to used to launch the Jami daemon from
267CONFIG, a <jami-configuration> object."
268 (match-record config <jami-configuration>
8649ac5e
MC
269 (libjami dbus enable-logging? debug? auto-answer?)
270 `(,(file-append libjami "/libexec/jamid")
10f55470
MC
271 "--persistent" ;stay alive after client quits
272 ,@(if enable-logging?
273 '() ;logs go to syslog by default
274 (list "--console")) ;else stdout/stderr
275 ,@(if debug?
276 (list "--debug")
277 '())
278 ,@(if auto-answer?
279 (list "--auto-answer")
280 '()))))
281
282(define (jami-dbus-session-activation config)
283 "Create a directory to hold the Jami D-Bus session socket."
284 (with-imported-modules (source-module-closure '((gnu build activation)))
285 #~(begin
286 (use-modules (gnu build activation))
287 (let ((user (getpwnam "jami")))
85b4dabd
MC
288 (mkdir-p/perms "/var/run/jami" user #o700)
289 ;; Customize the D-Bus policy to allow 'root' to access other users'
290 ;; session bus. Also modify the location of the written PID file,
291 ;; from the default '/var/run/dbus/pid' location. This file is only
292 ;; honored by the 'dbus-for-jami' package variant.
293 (call-with-output-file "/var/run/jami/session-local.conf"
294 (lambda (port)
295 (format port "\
296<busconfig>
297 <pidfile>/var/run/jami/pid</pidfile>
298 <policy context=\"mandatory\">
299 <allow user=\"root\"/>
300 </policy>
301</busconfig>~%")))))))
10f55470
MC
302
303(define (jami-shepherd-services config)
304 "Return a <shepherd-service> running the Jami daemon."
8649ac5e 305 (let* ((libjami (jami-configuration-libjami config))
10f55470
MC
306 (nss-certs (jami-configuration-nss-certs config))
307 (dbus (jami-configuration-dbus config))
308 (dbus-daemon (file-append dbus "/bin/dbus-daemon"))
10f55470 309 (accounts (jami-configuration-accounts config))
ee08277a 310 (declarative-mode? (maybe-value-set? accounts)))
10f55470 311
85b4dabd
MC
312 (with-extensions (list guile-packrat ;used by guile-ac-d-bus
313 guile-ac-d-bus
314 ;; Fibers is needed to provide the non-blocking
315 ;; variant of the 'sleep' procedure.
316 guile-fibers)
317 (with-imported-modules (source-module-closure
318 '((gnu build dbus-service)
319 (gnu build jami-service)
320 (gnu build shepherd)
321 (gnu system file-systems)))
322
323 (define list-accounts-action
324 (shepherd-action
325 (name 'list-accounts)
326 (documentation "List the available Jami accounts. Return the account
10f55470 327details alists keyed by their account username.")
85b4dabd
MC
328 (procedure
329 #~(lambda _
10f55470
MC
330 ;; Print the accounts summary or long listing, according to
331 ;; user-provided option.
332 (let* ((usernames (get-usernames))
333 (accounts (map-in-order username->account usernames)))
334 (match accounts
335 (() ;empty list
336 (format #t "There is no Jami account available.~%"))
337 ((one two ...)
338 (format #t "The following Jami accounts are available:~%")
339 (for-each
340 (lambda (account)
341 (define fingerprint (assoc-ref account
342 "Account.username"))
343 (define human-friendly-name
344 (or (assoc-ref account
345 "Account.registeredName")
346 (assoc-ref account
347 "Account.displayName")
348 (assoc-ref account
349 "Account.alias")))
350 (define disabled?
351 (and=> (assoc-ref account "Account.enable")
352 (cut string=? "false" <>)))
353
354 (format #t " - ~a~@[ (~a)~] ~:[~;[disabled]~]~%"
355 fingerprint human-friendly-name disabled?))
356 accounts)
357 (display "\n")))
358 ;; Return the account-details-list alist.
85b4dabd 359 (map cons usernames accounts))))))
10f55470 360
85b4dabd
MC
361 (define list-account-details-action
362 (shepherd-action
363 (name 'list-account-details)
364 (documentation "Display the account details of the available Jami
10f55470
MC
365accounts in the @code{recutils} format. Return the account details alists
366keyed by their account username.")
85b4dabd
MC
367 (procedure
368 #~(lambda _
10f55470
MC
369 (let* ((usernames (get-usernames))
370 (accounts (map-in-order username->account usernames)))
371 (for-each (lambda (account)
372 (display (account-details->recutil account))
373 (display "\n\n"))
374 accounts)
85b4dabd 375 (map cons usernames accounts))))))
10f55470 376
85b4dabd
MC
377 (define list-contacts-action
378 (shepherd-action
379 (name 'list-contacts)
380 (documentation "Display the contacts for each Jami account. Return
10f55470 381an alist containing the contacts keyed by the account usernames.")
85b4dabd
MC
382 (procedure
383 #~(lambda _
10f55470
MC
384 (let* ((usernames (get-usernames))
385 (contacts (map-in-order username->contacts usernames)))
386 (for-each (lambda (username contacts)
387 (format #t "Contacts for account ~a:~%"
388 username)
389 (format #t "~{ - ~a~%~}~%" contacts))
390 usernames contacts)
85b4dabd 391 (map cons usernames contacts))))))
10f55470 392
85b4dabd
MC
393 (define list-moderators-action
394 (shepherd-action
395 (name 'list-moderators)
396 (documentation "Display the moderators for each Jami account. Return
10f55470 397an alist containing the moderators keyed by the account usernames.")
85b4dabd
MC
398 (procedure
399 #~(lambda _
10f55470
MC
400 (let* ((usernames (get-usernames))
401 (moderators (map-in-order username->moderators
402 usernames)))
403 (for-each
404 (lambda (username moderators)
405 (if (username->all-moderators? username)
406 (format #t "Anyone can moderate for account ~a~%"
407 username)
408 (begin
409 (format #t "Moderators for account ~a:~%" username)
410 (format #t "~{ - ~a~%~}~%" moderators))))
411 usernames moderators)
85b4dabd 412 (map cons usernames moderators))))))
10f55470 413
85b4dabd
MC
414 (define add-moderator-action
415 (shepherd-action
416 (name 'add-moderator)
417 (documentation "Add a moderator for a given Jami account. The
10f55470
MC
418MODERATOR contact must be given as its 40 characters fingerprint, while the
419Jami account can be provided as its registered USERNAME or fingerprint.
420
421@example
422herd add-moderator jami 1dbcb0f5f37324228235564b79f2b9737e9a008f username
423@end example
424
425Return the moderators for the account known by USERNAME.")
85b4dabd
MC
426 (procedure
427 #~(lambda (_ moderator username)
10f55470
MC
428 (set-all-moderators #f username)
429 (add-contact moderator username)
430 (set-moderator moderator #t username)
85b4dabd 431 (username->moderators username)))))
10f55470 432
85b4dabd
MC
433 (define ban-contact-action
434 (shepherd-action
435 (name 'ban-contact)
436 (documentation "Ban a contact for a given or all Jami accounts, and
10f55470
MC
437clear their moderator flag. The CONTACT must be given as its 40 characters
438fingerprint, while the Jami account can be provided as its registered USERNAME
439or fingerprint, or omitted. When the account is omitted, CONTACT is banned
440from all accounts.
441
442@example
443herd ban-contact jami 1dbcb0f5f37324228235564b79f2b9737e9a008f [username]
444@end example")
85b4dabd
MC
445 (procedure
446 #~(lambda* (_ contact #:optional username)
10f55470
MC
447 (let ((usernames (or (and=> username list)
448 (get-usernames))))
449 (for-each (lambda (username)
450 (set-moderator contact #f username)
451 (remove-contact contact username #:ban? #t))
85b4dabd 452 usernames))))))
10f55470 453
85b4dabd
MC
454 (define list-banned-contacts-action
455 (shepherd-action
456 (name 'list-banned-contacts)
457 (documentation "List the banned contacts for each accounts. Return
10f55470 458an alist of the banned contacts, keyed by the account usernames.")
85b4dabd
MC
459 (procedure
460 #~(lambda _
10f55470
MC
461 (define banned-contacts
462 (let ((usernames (get-usernames)))
463 (map cons usernames
464 (map-in-order (lambda (x)
465 (receive (_ banned)
466 (username->contacts x)
467 banned))
468 usernames))))
469
470 (for-each (match-lambda
471 ((username . banned)
472 (unless (null? banned)
473 (format #t "Banned contacts for account ~a:~%"
474 username)
475 (format #t "~{ - ~a~%~}~%" banned))))
476 banned-contacts)
85b4dabd 477 banned-contacts))))
10f55470 478
85b4dabd
MC
479 (define enable-account-action
480 (shepherd-action
481 (name 'enable-account)
482 (documentation "Enable an account. It takes USERNAME as an argument,
10f55470 483either a registered username or the fingerprint of the account.")
85b4dabd
MC
484 (procedure
485 #~(lambda (_ username)
486 (enable-account username)))))
487
488 (define disable-account-action
489 (shepherd-action
490 (name 'disable-account)
491 (documentation "Disable an account. It takes USERNAME as an
10f55470 492argument, either a registered username or the fingerprint of the account.")
85b4dabd
MC
493 (procedure
494 #~(lambda (_ username)
495 (disable-account username)))))
496
497 (list (shepherd-service
498 (documentation "Run a D-Bus session for the Jami daemon.")
499 (provision '(jami-dbus-session))
500 (modules `((gnu build shepherd)
501 (gnu build dbus-service)
502 (gnu build jami-service)
503 (gnu system file-systems)
504 ,@%default-modules))
505 ;; The requirement on dbus-system is to ensure other required
506 ;; activation for D-Bus, such as a /etc/machine-id file.
507 (requirement '(dbus-system syslogd))
508 (start
509 #~(make-forkexec-constructor/container
510 (list #$dbus-daemon "--session"
511 "--address=unix:path=/var/run/jami/bus"
512 "--syslog-only")
513 #:pid-file "/var/run/jami/pid"
514 #:mappings
515 (list (file-system-mapping
516 (source "/dev/log") ;for syslog
517 (target source))
518 (file-system-mapping
519 (source "/var/run/jami")
520 (target source)
521 (writable? #t)))
522 #:user "jami"
523 #:group "jami"
524 #:environment-variables
525 ;; This is so that the cx.ring.Ring service D-Bus
526 ;; definition is found by dbus-daemon.
8649ac5e 527 (list (string-append "XDG_DATA_DIRS=" #$libjami "/share"))))
85b4dabd
MC
528 (stop #~(make-kill-destructor)))
529
530 (shepherd-service
531 (documentation "Run the Jami daemon.")
532 (provision '(jami))
533 (actions (list list-accounts-action
534 list-account-details-action
535 list-contacts-action
536 list-moderators-action
537 add-moderator-action
538 ban-contact-action
539 list-banned-contacts-action
540 enable-account-action
541 disable-account-action))
542 (requirement '(jami-dbus-session))
543 (modules `((ice-9 format)
544 (ice-9 ftw)
545 (ice-9 match)
546 (ice-9 receive)
547 (srfi srfi-1)
548 (srfi srfi-26)
549 (gnu build dbus-service)
550 (gnu build jami-service)
551 (gnu build shepherd)
552 (gnu system file-systems)
553 ,@%default-modules))
554 (start
555 #~(lambda args
556 (define (delete-file-recursively/safe file)
557 ;; Ensure we're not deleting things outside of
558 ;; /var/lib/jami. This prevents a possible attack in case
559 ;; the daemon is compromised and an attacker gains write
560 ;; access to /var/lib/jami.
561 (let ((parent-directory (dirname file)))
562 (if (eq? 'symlink (stat:type (stat parent-directory)))
563 (error "abnormality detected; unexpected symlink found at"
564 parent-directory)
565 (delete-file-recursively file))))
566
567 (when #$declarative-mode?
568 ;; Clear the Jami configuration and accounts, to enforce the
569 ;; declared state.
570 (catch #t
571 (lambda ()
572 (for-each (cut delete-file-recursively/safe <>)
573 '("/var/lib/jami/.cache/jami"
574 "/var/lib/jami/.config/jami"
575 "/var/lib/jami/.local/share/jami"
576 "/var/lib/jami/accounts")))
577 (lambda args
578 #t))
579 ;; Copy the Jami account archives from somewhere readable
580 ;; by root to a place only the jami user can read.
581 (let* ((accounts-dir "/var/lib/jami/accounts/")
582 (pwd (getpwnam "jami"))
583 (user (passwd:uid pwd))
584 (group (passwd:gid pwd)))
585 (mkdir-p accounts-dir)
586 (chown accounts-dir user group)
587 (for-each (lambda (f)
588 (let ((dest (string-append accounts-dir
589 (basename f))))
590 (copy-file f dest)
591 (chown dest user group)))
592 '#$(and declarative-mode?
593 (map jami-account-archive accounts)))))
594
595 ;; Start the daemon.
596 (define daemon-pid
597 ((make-forkexec-constructor/container
598 '#$(jami-configuration->command-line-arguments config)
599 #:mappings
600 (list (file-system-mapping
601 (source "/dev/log") ;for syslog
602 (target source))
603 (file-system-mapping
604 (source "/var/lib/jami")
605 (target source)
606 (writable? #t))
607 (file-system-mapping
608 (source "/var/run/jami")
609 (target source)
610 (writable? #t))
611 ;; Expose TLS certificates for GnuTLS.
612 (file-system-mapping
613 (source #$(file-append nss-certs "/etc/ssl/certs"))
614 (target "/etc/ssl/certs")))
615 #:user "jami"
616 #:group "jami"
617 #:environment-variables
618 (list (string-append "DBUS_SESSION_BUS_ADDRESS="
619 "unix:path=/var/run/jami/bus")
620 ;; Expose TLS certificates for OpenSSL.
621 "SSL_CERT_DIR=/etc/ssl/certs"))))
622
623 (setenv "DBUS_SESSION_BUS_ADDRESS"
624 "unix:path=/var/run/jami/bus")
10f55470
MC
625
626 ;; Wait until the service name has been acquired by D-Bus.
85b4dabd 627 (with-retries 20 1 (jami-service-available?))
10f55470
MC
628
629 (when #$declarative-mode?
630 ;; Provision the accounts via the D-Bus API of the daemon.
631 (let* ((jami-account-archives
632 (map (cut string-append
633 "/var/lib/jami/accounts/" <>)
634 (scandir "/var/lib/jami/accounts/"
635 (lambda (f)
636 (not (member f '("." "..")))))))
637 (usernames (map-in-order (cut add-account <>)
638 jami-account-archives)))
639
640 (define (archive-name->username archive)
641 (list-ref
642 usernames
643 (list-index (lambda (f)
644 (string-suffix? (basename archive) f))
645 jami-account-archives)))
646
647 (for-each
648 (lambda (archive allowed-contacts moderators
649 account-details)
650 (let ((username (archive-name->username
651 archive)))
ee08277a 652 (when (not (eq? '#$%unset-value allowed-contacts))
10f55470
MC
653 ;; Reject calls from unknown contacts.
654 (set-account-details
655 '(("DHT.PublicInCalls" . "false")) username)
656 ;; Remove all contacts.
657 (for-each (cut remove-contact <> username)
658 (username->contacts username))
659 ;; Add allowed ones.
660 (for-each (cut add-contact <> username)
661 allowed-contacts))
ee08277a 662 (when (not (eq? '#$%unset-value moderators))
10f55470
MC
663 ;; Disable the 'AllModerators' property.
664 (set-all-moderators #f username)
665 ;; Remove all moderators.
666 (for-each (cut set-moderator <> #f username)
667 (username->moderators username))
668 ;; Add declared moderators.
669 (for-each (cut set-moderator <> #t username)
670 moderators))
671 ;; Set the various account parameters.
672 (set-account-details account-details username)))
673 '#$(and declarative-mode?
674 (map-in-order (cut jami-account-archive <>)
675 accounts))
676 '#$(and declarative-mode?
677 (map-in-order
678 (cut jami-account-allowed-contacts <>)
679 accounts))
680 '#$(and declarative-mode?
681 (map-in-order (cut jami-account-moderators <>)
682 accounts))
683 '#$(and declarative-mode?
85b4dabd
MC
684 (map-in-order jami-account->alist accounts)))))
685
686 ;; Finally, return the PID of the daemon process.
687 daemon-pid))
effdc6c8
MC
688 ;; XXX: jamid takes some time to terminate, and GNU Shepherd
689 ;; doesn't block when calling waitpid (see:
690 ;; https://issues.guix.gnu.org/57922). Using SIGKILL instead
691 ;; of SIGTERM works around that.
692 (stop #~(make-kill-destructor SIGKILL))))))))
10f55470
MC
693
694(define jami-service-type
695 (service-type
696 (name 'jami)
697 (default-value (jami-configuration))
698 (extensions
699 (list (service-extension shepherd-root-service-type
700 jami-shepherd-services)
701 (service-extension account-service-type
702 (const %jami-accounts))
703 (service-extension activation-service-type
704 jami-dbus-session-activation)))
374fea0f 705 (description "Run the Jami daemon (@command{jamid}). This service is
10f55470
MC
706geared toward the use case of hosting Jami rendezvous points over a headless
707server. If you use Jami on your local machine, you may prefer to setup a user
708Shepherd service for it instead; this way, the daemon will be shared via your
709normal user D-Bus session bus.")))
710
711\f
712;;;
42679e3f 713;;; Mumble server.
10f55470
MC
714;;;
715
b6d2930d 716;; https://github.com/mumble-voip/mumble/blob/master/scripts/murmur.ini
717
42679e3f
LMP
718(define-record-type* <mumble-server-configuration> mumble-server-configuration
719 make-mumble-server-configuration
720 mumble-server-configuration?
721 (package mumble-server-configuration-package ;file-like
b6d2930d 722 (default mumble))
42679e3f
LMP
723 (user mumble-server-configuration-user
724 (default "mumble-server"))
725 (group mumble-server-configuration-group
726 (default "mumble-server"))
727 (port mumble-server-configuration-port
b6d2930d 728 (default 64738))
42679e3f 729 (welcome-text mumble-server-configuration-welcome-text
b6d2930d 730 (default ""))
42679e3f 731 (server-password mumble-server-configuration-server-password
b6d2930d 732 (default ""))
42679e3f 733 (max-users mumble-server-configuration-max-users
b6d2930d 734 (default 100))
42679e3f 735 (max-user-bandwidth mumble-server-configuration-max-user-bandwidth
b6d2930d 736 (default #f))
42679e3f
LMP
737 (database-file mumble-server-configuration-database-file
738 (default "/var/lib/mumble-server/db.sqlite"))
739 (log-file mumble-server-configuration-log-file
740 (default "/var/log/mumble-server/mumble-server.log"))
741 (pid-file mumble-server-configuration-pid-file
742 (default "/var/run/mumble-server/mumble-server.pid"))
743 (autoban-attempts mumble-server-configuration-autoban-attempts
b6d2930d 744 (default 10))
42679e3f 745 (autoban-timeframe mumble-server-configuration-autoban-timeframe
b6d2930d 746 (default 120))
42679e3f 747 (autoban-time mumble-server-configuration-autoban-time
b6d2930d 748 (default 300))
42679e3f 749 (opus-threshold mumble-server-configuration-opus-threshold
b6d2930d 750 (default 100)) ; integer percent
42679e3f 751 (channel-nesting-limit mumble-server-configuration-channel-nesting-limit
b6d2930d 752 (default 10))
42679e3f 753 (channelname-regex mumble-server-configuration-channelname-regex
b6d2930d 754 (default #f))
42679e3f 755 (username-regex mumble-server-configuration-username-regex
b6d2930d 756 (default #f))
42679e3f 757 (text-message-length mumble-server-configuration-text-message-length
b6d2930d 758 (default 5000))
42679e3f 759 (image-message-length mumble-server-configuration-image-message-length
b6d2930d 760 (default (* 128 1024))) ; 128 Kilobytes
42679e3f 761 (cert-required? mumble-server-configuration-cert-required?
b6d2930d 762 (default #f))
42679e3f 763 (remember-channel? mumble-server-configuration-remember-channel?
b6d2930d 764 (default #f))
42679e3f 765 (allow-html? mumble-server-configuration-allow-html?
b6d2930d 766 (default #f))
42679e3f 767 (allow-ping? mumble-server-configuration-allow-ping?
b6d2930d 768 (default #f))
42679e3f 769 (bonjour? mumble-server-configuration-bonjour?
b6d2930d 770 (default #f))
42679e3f 771 (send-version? mumble-server-configuration-send-version?
b6d2930d 772 (default #f))
42679e3f 773 (log-days mumble-server-configuration-log-days
b6d2930d 774 (default 31))
42679e3f 775 (obfuscate-ips? mumble-server-obfuscate-ips?
b6d2930d 776 (default #t))
42679e3f 777 (ssl-cert mumble-server-configuration-ssl-cert
b6d2930d 778 (default #f))
42679e3f 779 (ssl-key mumble-server-configuration-ssl-key
b6d2930d 780 (default #f))
42679e3f 781 (ssl-dh-params mumble-server-configuration-ssl-dh-params
b6d2930d 782 (default #f))
42679e3f 783 (ssl-ciphers mumble-server-configuration-ssl-ciphers
b6d2930d 784 (default #f))
42679e3f
LMP
785 (public-registration mumble-server-configuration-public-registration
786 (default #f)) ; <mumble-server-public-registration-configuration>
787 (file mumble-server-configuration-file
b6d2930d 788 (default #f)))
789
42679e3f
LMP
790(define-record-type* <mumble-server-public-registration-configuration>
791 mumble-server-public-registration-configuration
792 make-mumble-server-public-registration-configuration
793 mumble-server-public-registration-configuration?
794 (name mumble-server-public-registration-configuration-name)
795 (password mumble-server-public-registration-configuration-password)
796 (url mumble-server-public-registration-configuration-url)
797 (hostname mumble-server-public-registration-configuration-hostname
b6d2930d 798 (default #f)))
799
800(define (flatten . lst)
801 "Return a list that recursively concatenates all sub-lists of LST."
802 (define (flatten1 head out)
803 (if (list? head)
804 (fold-right flatten1 out head)
805 (cons head out)))
806 (fold-right flatten1 '() lst))
807
42679e3f 808(define (default-mumble-server-config config)
b6d2930d 809 (match-record
810 config
42679e3f 811 <mumble-server-configuration>
b6d2930d 812 (user port welcome-text server-password max-users max-user-bandwidth
813 database-file log-file pid-file autoban-attempts autoban-timeframe
814 autoban-time opus-threshold channel-nesting-limit channelname-regex
815 username-regex text-message-length image-message-length cert-required?
816 remember-channel? allow-html? allow-ping? bonjour? send-version?
817 log-days obfuscate-ips? ssl-cert ssl-key ssl-dh-params ssl-ciphers
818 public-registration)
42679e3f 819 (apply mixed-text-file "mumble-server.ini"
b6d2930d 820 (flatten
821 "welcometext=" welcome-text "\n"
822 "port=" (number->string port) "\n"
823 (if server-password (list "serverpassword=" server-password "\n") '())
83670e02
SM
824 (if max-user-bandwidth (list "bandwidth="
825 (number->string max-user-bandwidth) "\n")
826 '())
b6d2930d 827 "users=" (number->string max-users) "\n"
828 "uname=" user "\n"
829 "database=" database-file "\n"
830 "logfile=" log-file "\n"
831 "pidfile=" pid-file "\n"
832 (if autoban-attempts (list "autobanAttempts=" (number->string autoban-attempts) "\n") '())
833 (if autoban-timeframe (list "autobanTimeframe=" (number->string autoban-timeframe) "\n") '())
834 (if autoban-time (list "autobanTime=" (number->string autoban-time) "\n") '())
835 (if opus-threshold (list "opusthreshold=" (number->string opus-threshold) "\n") '())
836 (if channel-nesting-limit (list "channelnestinglimit=" (number->string channel-nesting-limit) "\n") '())
837 (if channelname-regex (list "channelname=" channelname-regex "\n") '())
838 (if username-regex (list "username=" username-regex "\n") '())
839 (if text-message-length (list "textmessagelength=" (number->string text-message-length) "\n") '())
840 (if image-message-length (list "imagemessagelength=" (number->string image-message-length) "\n") '())
841 (if log-days (list "logdays=" (number->string log-days) "\n") '())
842 "obfuscate=" (if obfuscate-ips? "true" "false") "\n"
843 "certrequired=" (if cert-required? "true" "false") "\n"
844 "rememberchannel=" (if remember-channel? "true" "false") "\n"
845 "allowhtml=" (if allow-html? "true" "false") "\n"
846 "allowping=" (if allow-ping? "true" "false") "\n"
847 "bonjour=" (if bonjour? "true" "false") "\n"
848 "sendversion=" (if send-version? "true" "false") "\n"
849 (cond ((and ssl-cert ssl-key)
850 (list
851 "sslCert=" ssl-cert "\n"
852 "sslKey=" ssl-key "\n"))
853 ((or ssl-cert ssl-key)
854 (error "ssl-cert and ssl-key must both be set"
855 ssl-cert ssl-key))
856 (else '()))
857 (if ssl-dh-params (list "sslDHParams=" ssl-dh-params) '())
858 (if ssl-ciphers (list "sslCiphers=" ssl-ciphers) '())
859
860 (match public-registration
861 (#f '())
42679e3f 862 (($ <mumble-server-public-registration-configuration>
b6d2930d 863 name password url hostname)
864 (if (and (or (not server-password) (string-null? server-password))
865 allow-ping?)
866 (list
867 "registerName=" name "\n"
868 "registerPassword=" password "\n"
869 "registerUrl=" url "\n"
870 (if hostname
871 (string-append "registerHostname=" hostname "\n")
872 ""))
42679e3f 873 (error "To publicly register your mumble-server server your server must be publicy visible
b6d2930d 874and users must be able to join without a password. To fix this set:
875(allow-ping? #t)
876(server-password \"\")
877Or set public-registration to #f"))))))))
878
42679e3f 879(define (mumble-server-activation config)
b6d2930d 880 #~(begin
881 (use-modules (guix build utils))
42679e3f
LMP
882 (let* ((log-dir (dirname #$(mumble-server-configuration-log-file config)))
883 (pid-dir (dirname #$(mumble-server-configuration-pid-file config)))
884 (db-dir (dirname #$(mumble-server-configuration-database-file config)))
885 (user (getpwnam #$(mumble-server-configuration-user config)))
b6d2930d 886 (init-dir
887 (lambda (name dir)
42679e3f 888 (format #t "creating mumble-server ~a directory '~a'\n" name dir)
b6d2930d 889 (mkdir-p dir)
890 (chown dir (passwd:uid user) (passwd:gid user))
891 (chmod dir #o700)))
42679e3f
LMP
892 (ini #$(or (mumble-server-configuration-file config)
893 (default-mumble-server-config config))))
b6d2930d 894 (init-dir "log" log-dir)
895 (init-dir "pid" pid-dir)
896 (init-dir "database" db-dir)
897
42679e3f
LMP
898 (format #t "mumble-server: use config file: ~a~%\n" ini)
899 (format #t "mumble-server: to set the SuperUser password run:
b6d2930d 900 `~a -ini ~a -readsupw`\n"
42679e3f 901 #$(file-append (mumble-server-configuration-package config)
8044a1fe 902 "/bin/mumble-server") ini)
b6d2930d 903 #t)))
904
42679e3f 905(define mumble-server-accounts
b6d2930d 906 (match-lambda
42679e3f 907 (($ <mumble-server-configuration> _ user group)
b6d2930d 908 (list
909 (user-group
910 (name group)
911 (system? #t))
912 (user-account
913 (name user)
914 (group group)
915 (system? #t)
42679e3f 916 (comment "Mumble server daemon")
b6d2930d 917 (home-directory "/var/empty")
918 (shell (file-append shadow "/sbin/nologin")))))))
919
42679e3f 920(define (mumble-server-shepherd-service config)
b6d2930d 921 (list (shepherd-service
42679e3f
LMP
922 (provision '(mumble-server))
923 (documentation "Run the Mumble server.")
b6d2930d 924 (requirement '(networking))
925 (start #~(make-forkexec-constructor
42679e3f 926 '(#$(file-append (mumble-server-configuration-package config)
8044a1fe 927 "/bin/mumble-server")
b6d2930d 928 "-ini"
42679e3f
LMP
929 #$(or (mumble-server-configuration-file config)
930 (default-mumble-server-config config)))
931 #:pid-file #$(mumble-server-configuration-pid-file config)))
b6d2930d 932 (stop #~(make-kill-destructor)))))
933
42679e3f
LMP
934(define mumble-server-service-type
935 (service-type (name 'mumble-server)
b6d2930d 936 (description
42679e3f 937 "Run the Mumble voice-over-IP (VoIP) server.")
b6d2930d 938 (extensions
939 (list (service-extension shepherd-root-service-type
42679e3f 940 mumble-server-shepherd-service)
b6d2930d 941 (service-extension activation-service-type
42679e3f 942 mumble-server-activation)
b6d2930d 943 (service-extension account-service-type
42679e3f
LMP
944 mumble-server-accounts)))
945 (default-value (mumble-server-configuration))))
946
947(define-deprecated/public-alias
948 murmur-configuration
949 mumble-server-configuration)
950(define-deprecated/public-alias
951 make-murmur-configuration
952 make-mumble-server-configuration)
953(define-deprecated/public-alias
954 murmur-configuration?
955 mumble-server-configuration?)
956(define-deprecated/public-alias
957 murmur-configuration-package
958 mumble-server-configuration-package)
959(define-deprecated/public-alias
960 murmur-configuration-user
961 mumble-server-configuration-user)
962(define-deprecated/public-alias
963 murmur-configuration-group
964 mumble-server-configuration-group)
965(define-deprecated/public-alias
966 murmur-configuration-port
967 mumble-server-configuration-port)
968(define-deprecated/public-alias
969 murmur-configuration-welcome-text
970 mumble-server-configuration-welcome-text)
971(define-deprecated/public-alias
972 murmur-configuration-server-password
973 mumble-server-configuration-server-password)
974(define-deprecated/public-alias
975 murmur-configuration-max-users
976 mumble-server-configuration-max-users)
977(define-deprecated/public-alias
978 murmur-configuration-max-user-bandwidth
979 mumble-server-configuration-max-user-bandwidth)
980(define-deprecated/public-alias
981 murmur-configuration-database-file
982 mumble-server-configuration-database-file)
983(define-deprecated/public-alias
984 murmur-configuration-log-file
985 mumble-server-configuration-log-file)
986(define-deprecated/public-alias
987 murmur-configuration-pid-file
988 mumble-server-configuration-pid-file)
989(define-deprecated/public-alias
990 murmur-configuration-autoban-attempts
991 mumble-server-configuration-autoban-attempts)
992(define-deprecated/public-alias
993 murmur-configuration-autoban-timeframe
994 mumble-server-configuration-autoban-timeframe)
995(define-deprecated/public-alias
996 murmur-configuration-autoban-time
997 mumble-server-configuration-autoban-time)
998(define-deprecated/public-alias
999 murmur-configuration-opus-threshold
1000 mumble-server-configuration-opus-threshold)
1001(define-deprecated/public-alias
1002 murmur-configuration-channel-nesting-limit
1003 mumble-server-configuration-channel-nesting-limit)
1004(define-deprecated/public-alias
1005 murmur-configuration-channelname-regex
1006 mumble-server-configuration-channelname-regex)
1007(define-deprecated/public-alias
1008 murmur-configuration-username-regex
1009 mumble-server-configuration-username-regex)
1010(define-deprecated/public-alias
1011 murmur-configuration-text-message-length
1012 mumble-server-configuration-text-message-length)
1013(define-deprecated/public-alias
1014 murmur-configuration-image-message-length
1015 mumble-server-configuration-image-message-length)
1016(define-deprecated/public-alias
1017 murmur-configuration-cert-required?
1018 mumble-server-configuration-cert-required?)
1019(define-deprecated/public-alias
1020 murmur-configuration-remember-channel?
1021 mumble-server-configuration-remember-channel?)
1022(define-deprecated/public-alias
1023 murmur-configuration-allow-html?
1024 mumble-server-configuration-allow-html?)
1025(define-deprecated/public-alias
1026 murmur-configuration-allow-ping?
1027 mumble-server-configuration-allow-ping?)
1028(define-deprecated/public-alias
1029 murmur-configuration-bonjour?
1030 mumble-server-configuration-bonjour?)
1031(define-deprecated/public-alias
1032 murmur-configuration-send-version?
1033 mumble-server-configuration-send-version?)
1034(define-deprecated/public-alias
1035 murmur-configuration-log-days
1036 mumble-server-configuration-log-days)
1037(define-deprecated/public-alias
1038 murmur-configuration-obfuscate-ips?
1039 mumble-server-configuration-obfuscate-ips?)
1040(define-deprecated/public-alias
1041 murmur-configuration-ssl-cert
1042 mumble-server-configuration-ssl-cert)
1043(define-deprecated/public-alias
1044 murmur-configuration-ssl-key
1045 mumble-server-configuration-ssl-key)
1046(define-deprecated/public-alias
1047 murmur-configuration-ssl-dh-params
1048 mumble-server-configuration-ssl-dh-params)
1049(define-deprecated/public-alias
1050 murmur-configuration-ssl-ciphers
1051 mumble-server-configuration-ssl-ciphers)
1052(define-deprecated/public-alias
1053 murmur-configuration-public-registration
1054 mumble-server-configuration-public-registration)
1055(define-deprecated/public-alias
1056 murmur-configuration-file
1057 mumble-server-configuration-file)
1058
1059(define-deprecated/public-alias
1060 murmur-public-registration-configuration
1061 mumble-server-public-registration-configuration)
1062(define-deprecated/public-alias
1063 make-murmur-public-registration-configuration
1064 make-mumble-server-public-registration-configuration)
1065(define-deprecated/public-alias
1066 murmur-public-registration-configuration?
1067 mumble-server-public-registration-configuration?)
1068(define-deprecated/public-alias
1069 murmur-public-registration-configuration-name
1070 mumble-server-public-registration-configuration-name)
1071(define-deprecated/public-alias
1072 murmur-public-registration-configuration-url
1073 mumble-server-public-registration-configuration-url)
1074(define-deprecated/public-alias
1075 murmur-public-registration-configuration-password
1076 mumble-server-public-registration-configuration-password)
1077(define-deprecated/public-alias
1078 murmur-public-registration-configuration-hostname
1079 mumble-server-public-registration-configuration-hostname)
1080
1081(define-deprecated/public-alias
1082 murmur-service-type
1083 mumble-server-service-type)
10f55470
MC
1084
1085;; Local Variables:
1086;; eval: (put 'with-retries 'scheme-indent-function 2)
1087;; End: