From unknown Sun Aug 17 09:10:09 2025 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-Mailer: MIME-tools 5.509 (Entity 5.509) Content-Type: text/plain; charset=utf-8 From: bug#77922 <77922@debbugs.gnu.org> To: bug#77922 <77922@debbugs.gnu.org> Subject: Status: [PATCH] services: pounce: New service. Reply-To: bug#77922 <77922@debbugs.gnu.org> Date: Sun, 17 Aug 2025 16:10:09 +0000 retitle 77922 [PATCH] services: pounce: New service. reassign 77922 guix-patches submitter 77922 Maxim Cournoyer severity 77922 normal tag 77922 patch thanks From debbugs-submit-bounces@debbugs.gnu.org Sat Apr 19 08:26:06 2025 Received: (at submit) by debbugs.gnu.org; 19 Apr 2025 12:26:06 +0000 Received: from localhost ([127.0.0.1]:59531 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1u67Gm-0002HF-DK for submit@debbugs.gnu.org; Sat, 19 Apr 2025 08:26:06 -0400 Received: from lists.gnu.org ([2001:470:142::17]:38002) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1u67Gh-0002FU-JY for submit@debbugs.gnu.org; Sat, 19 Apr 2025 08:26:02 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1u67GR-0007hO-LM for guix-patches@gnu.org; Sat, 19 Apr 2025 08:25:43 -0400 Received: from mail-pf1-x42d.google.com ([2607:f8b0:4864:20::42d]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1u67GM-0004xJ-1f for guix-patches@gnu.org; Sat, 19 Apr 2025 08:25:42 -0400 Received: by mail-pf1-x42d.google.com with SMTP id d2e1a72fcca58-736c1cf75e4so2402935b3a.2 for ; Sat, 19 Apr 2025 05:25:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1745065534; x=1745670334; darn=gnu.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=08m4mZmJVI2kkjsxVxRCnyXPa6SbjJj8M9XkwG6x7bM=; b=K+N995sUxFY0ZsI3QoRsHBblR1aMperc652vUsq0T27NB3dA55cK64AKfk/XXqnvIk N2MNbiSsAcea6T/OnKq32DyQqh5wz2THJDivo9ZznI47XuycT5Mtlq4YTrdRZ9fIoA49 2iHk9tlBo/0V4ugkiIsrBGFPw19bxAWvHNokO1CjghiLLEgLJTzSOx1dluT2k0Njibu+ 560I/p5Rinxv/f9IB/bPVerK2cYVtWblLfwihMmIUdCoVeigratKvqU0lioFo3FDo0gr VlrUWutWsiPC92HyH/AodeTvtda+jtONcAHuY5WDmDULr+triMQFBVTFByj+t/oStZ/S 5BHQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1745065534; x=1745670334; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=08m4mZmJVI2kkjsxVxRCnyXPa6SbjJj8M9XkwG6x7bM=; b=NvVJAuWw7EMiAesfV3JPGaa6iIBGJr7Q9xB0DYOKH7LhEO6zitkieRbl59crj/QCS7 acLfM58Xg5Vryl8C8GkWqsxerLyVzVYpc6PwGFRXQBU2vgFwEos0x+J/CI2N7kVzZHJz WIvJqgzCNOZ79k+xElFimsn5Kx/MwTVnawCHAK1vCIer955q9aUlJLCdvq3wMF1Ac2rG I2nSfD1YBucIqd8DZIZA3yEtinvlPJbz3DlQBpbif5TNJGSUTjrsseI7q82ndz9+f/tv rdJdujURQuK79wzgwD9ldZVs4C1brjrGYw5arAq8JmXefor2Q/WUyBKo4nnZ4A+iXDUl Mprg== X-Gm-Message-State: AOJu0YzZ5KeRiu7NWh9Xj4DqCx5z+v5nbwaY3OfFJ+45X8UgGIyl77Hf csLq6WGhY0vHJEBBqnnRp5ess6Z2E/n3/O7qoSygkiZxArmYJT3DUsJ0aQ== X-Gm-Gg: ASbGncsbVcpcmxYyXcSfn0lwDXjoW/VvrkRD4YmGfaMtu4VQUB6NVpxDIj/qOUpiK8u gx2BYzoUv3FCF7sLp+DKmbhC4H39c9K5KN5WHHOpjQW85ylu36zNHi6n+TgoCLiEWwyds46VAMb rCJH1e/jIhzdOHZj1ND85NjD3U0EgQvcd2S8wcksKef91FEsBcv4J3Y0VSio+ADtV15SWQ8Uw3Q BREZCHFfnFFb7yWZEOIBYDaY7cRM5xNeuIwZRyEZQbAKGzB1ZCRpGETFZ3sKIfV1ab8J+C6QtyD 7VOlNuHibpuIS/UvyW5VYhQmnPHb4oOgusY6AQa7xvKMyE9oRpvyv4psDHPdfhsO824jaog= X-Google-Smtp-Source: AGHT+IFaoTKsxIRKTR2jSBUtfoMYidcAtiW0CFwL7+gmffnnQRk+RhY2RcMpvwp+fEAC8uGf/Xmgdw== X-Received: by 2002:a05:6a21:1643:b0:1f5:9330:2a18 with SMTP id adf61e73a8af0-203cbc712damr8266550637.23.1745065533270; Sat, 19 Apr 2025 05:25:33 -0700 (PDT) Received: from localhost.localdomain ([2405:6586:be0:0:83c8:d31d:2cec:f542]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-73dbf8bf5a1sm3197515b3a.2.2025.04.19.05.25.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 19 Apr 2025 05:25:32 -0700 (PDT) From: Maxim Cournoyer To: guix-patches@gnu.org Subject: [PATCH] services: pounce: New service. Date: Sat, 19 Apr 2025 21:25:03 +0900 Message-ID: <164c4298f45762194cadba963ce489d2adc1c427.1745065503.git.maxim.cournoyer@gmail.com> X-Mailer: git-send-email 2.49.0 MIME-Version: 1.0 X-Debbugs-Cc: Ludovic Courtès , Maxim Cournoyer Content-Transfer-Encoding: 8bit Received-SPF: pass client-ip=2607:f8b0:4864:20::42d; envelope-from=maxim.cournoyer@gmail.com; helo=mail-pf1-x42d.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Spam-Score: 1.0 (+) X-Debbugs-Envelope-To: submit Cc: Maxim Cournoyer X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.0 (/) * gnu/services/messaging.scm (pounce-serialize-boolean): (pounce-serialize-string, pounce-serialize-list-of-strings) (pounce-serialize-pair, power-of-two?) (pounce-serialize-number, pounce-serialize-power-of-two) (pounce-serialize-port, pounce-serialize-maybe-boolean) (pounce-serialize-maybe-number, pounce-serialize-maybe-pair) (pounce-serialize-maybe-port, pounce-serialize-maybe-port (pounce-maybe-power-of-two, pounce-serialize-maybe-string) (pounce-serialize-maybe-list-of-strings): New procedures. (pounce-configuration): New configuration. (pounce-activation): New procedure. (serialize-pounce-configuration, pounce-wrapper): Likewise. (pounce-service-type): New service type. * gnu/tests/messaging.scm (ngircd-tls-cert-service-type): New variable. (%pounce-os): Likewise. (run-pounce-test): New procedure. (%test-pounce): New test. * doc/guix.texi (Messaging Services): Document it. Change-Id: I4bbd2bc4821072a93c2c4017b86df329c4b240cb --- doc/guix.texi | 212 ++++++++++++++++++++ gnu/services/messaging.scm | 382 +++++++++++++++++++++++++++++++++++++ gnu/tests/messaging.scm | 212 ++++++++++++++++++++ 3 files changed, 806 insertions(+) diff --git a/doc/guix.texi b/doc/guix.texi index 070528667fa..eb64089f0b7 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -30791,6 +30791,218 @@ Messaging Services @end deftp +@c %end of fragment + +@subsubheading Pounce Service + +@cindex IRC (Internet Relay Chat) +@cindex bouncer, IRC +@cindex Bounced Network Connection, BNC +@url{https://git.causal.agency/pounce/about/, pounce} is a multi-client, +TLS-only IRC bouncer. It maintains a persistent connection to an IRC +server, acting as a proxy and buffer for a number of clients. + +@defvar pounce-service-type +This is the service type for the pounce IRC bouncer. Its value is a +@code{pounce-configuration} configuration instance, which is documented +below. + +@cindex IRC bouncer configuration for Libera.Chat +@cindex Libera.Chat, IRC bouncer configuration +The following example configures pounce to act as an IRC bouncer for the +@url{https://libera.chat, Libera.Chat} server, using @acronym{CertFP, +client certificate fingerprint} authentication to avoid leaking a +sensitive password to the publicly readable store. The equally +sensitive TLS certificate file should be created in-place or transferred +using a secure means such as SSH, prior to deploying the service. The +service activation will ensure the ownership and permissions of the +certificate/key files are set correctly. In the below example, it is +placed at @file{/etc/pounce/libera.pem} on the target machine. Pounce +itself can be used to generate a TLS certificate, using the @samp{pounce +-g libera.pem} command, which concatenates both the private key and the +public certificate in the specified file name. For more information +regarding CertFP authentication, refer to @samp{man pounce} or the +Libera.Chat guide at @url{https://libera.chat/guides/certfp}. + +@lisp +(service pounce-service-type + (pounce-configuration + (host "irc.libera.chat") + (client-cert "/etc/pounce/libera.pem") + (nick "hannah") + (join (list "#gnu" "#guix" "#guile" "#hurd")))) +@end lisp + +Once deployed on the target machine, pounce will act as an IRC server +listening for TLS connections on the 6697 TCP port of the +@samp{localhost} address of that machine. By default, a self-signed +certificate for pounce is created at +@file{/var/lib/pounce/.config/pounce/localhost.cert}. If you plan to +expose the bouncer to the public Internet, it is advisable to use a +@acronym{CA, Certificate Authority}-signed certificate, as can be +obtained using a certificate service (@pxref{Certificate Services}), so +that IRC clients can verify the certificate out of the box. If you +instead plan to connect to the bouncer strictly via a secure connection, +for example using a @acronym{VPN, Virtual Private Network} or +@acronym{SSH, Secure Shell}, then it is acceptable to simply let your +IRC client trust the auto-generated, self-signed pounce certificate or +even disable TLS certificate verification in your client. + +@cindex IRC bouncer configuration for OFTC +@cindex OFTC, IRC bouncer configuration +To connect to a second server, a second pounce instance is needed, +taking care to specify the @code{provision} field of its +@code{pounce-configuration} to avoid a name clash with the previous +service, along with a distinct @code{local-port} and @code{log-file}. +The following example shows how to configure another bouncer, this time +for the @url{https://www.oftc.net, OFTC} IRC server. Like in the +previous example, CertFP authentication is used, which can be configured +similarly. For more details about using CertFP with the OFTC IRC +server, refer to @url{https://www.oftc.net/NickServ/CertFP/}. + +@lisp +(service pounce-service-type + (pounce-configuration + (provision '(pounce-oftc)) + (local-port 6698) + (log-file "/var/log/pounce-oftc.log") + (host "irc.oftc.net") + (client-cert "/etc/pounce/oftc.pem") + (nick "sena") + (join (list "#gcc" "#glibc")))) +@end lisp + +@end defvar + +@c Auto-generated via (configuration->documentation 'pounce-configuration). +@c %start of fragment + +@deftp {Data Type} pounce-configuration +Available @code{pounce-configuration} fields are: + +@table @asis +@item @code{pounce} (default: @code{pounce}) (type: file-like) +The @code{pounce} package to use. + +@item @code{shepherd-provision} (default: @code{(pounce)}) (type: list-of-symbols) +The name(s) of the service. + +@item @code{shepherd-requirement} (default: @code{(user-processes)}) (type: list-of-symbols) +Shepherd requirements the service should depend on. + +@item @code{log-file} (default: @code{"/var/log/pounce.log"}) (type: string) +The log file name to use. + +@item @code{verbose?} (type: maybe-boolean) +When true, log IRC messages to standard output. + +@item @code{local-host} (default: @code{"localhost"}) (type: maybe-string) +The host to bind to. + +@item @code{local-port} (default: @code{6697}) (type: maybe-port) +The port to bind to. + +@item @code{local-ca} (type: maybe-string) +Require clients to authenticate using a TLS client certificate either +contained in or signed by a certificate in the file loaded from +@{local-ca + +@item @code{local-cert} (type: maybe-string) +File name of the TLS certificate to load. The file is reloaded when the +SIGUSR1 signal is received. Unless specified, a self-signed certificate +is generated at @file{/var/lib/pounce/.config/pounce/@var{host}.pem}, +where @var{host} corresponds to the value of the @code{local-host} +field. + +@item @code{local-priv} (type: maybe-string) +File name of the private TLS key to load. Unless specified, a key is +generated at @file{/var/lib/pounce/.config/pounce/@var{host}.key}, where +@var{host} corresponds to the value of the @code{local-host} field. + +@item @code{local-pass} (type: maybe-string) +Require the server password pass for clients to connect. The pass +string must be hashed using @samp{pounce -x}. + +@item @code{size} (default: @code{4096}) (type: maybe-power-of-two) +Set the number of messages contained in the buffer to @var{size}. This +sets the maximum number of recent messages which can be relayed to a +reconnecting client. The size must be a power of two. + +@item @code{bind} (type: maybe-string) +Host to bind the @emph{source} address to when connecting to the server. +To connect from any address over IPv4 only, use @samp{0.0.0.0}. To +connect from any address over IPv6 only, use @samp{::}. + +@item @code{host} (type: string) +The host name to connect to. + +@item @code{port} (type: maybe-port) +The port number to connect to. + +@item @code{pass} (type: maybe-string) +Password to use to log in with the server. The password must have been +hashed via the @samp{pounce -x} command. + +@item @code{join} (type: maybe-list-of-strings) +The list of channels to join. + +@item @code{mode} (type: maybe-string) +The user mode. + +@item @code{user} (type: maybe-string) +To set the username. The default username is the same as the nickname. + +@item @code{nick} (default: @code{"pounce"}) (type: maybe-string) +Set nickname to @var{nick}. + +@item @code{real} (type: maybe-string) +Set the real name. The default is @code{nick}. + +@item @code{away} (type: maybe-string) +The away status to use when no clients are connected and no other away +status has been set. + +@item @code{quit} (type: maybe-string) +The message to use when quitting. + +@item @code{no-names?} (type: maybe-boolean) +Do not request @samp{NAMES} for each channel when a client connects. +This avoids already connected clients receiving unsolicited responses +but prevents new clients from populating user lists. + +@item @code{queue-interval} (default: @code{200}) (type: maybe-number) +Set the server send queue interval in milliseconds. The queue is used +to send automated messages from pounce to the server. Messages from +clients are sent to the server directly. + +@item @code{trust} (type: maybe-string) +File name of a certificate to trust. When used, server name +verification is disabled. + +@item @code{client-cert} (type: maybe-string) +The file name of the TLS client. If the private key is in a separate +file, it is loaded with @code{client-priv}. With @code{sasl-external?}, +authenticate using SASL EXTERNAL. Certificates can be generated with +@samp{pounce -g}. For more details, refer to ``Generating Client +Certificates'' in @samp{man 1 pounce}. + +@item @code{client-priv} (type: maybe-string) +The file name of the TLS client private key. + +@item @code{sasl-plain} (type: maybe-pair) +A pair of the username and password in plain text to authenticate using +SASL PLAIN. Since this method requires the account password in plain +text, it is recommended to use CertFP instead with @code{sasl-external}. + +@item @code{sasl-external?} (type: maybe-boolean) +Authenticate using SASL EXTERNAL, also known as CertFP. The TLS client +certificate is loaded from @code{client-cert}. + +@end table + +@end deftp + + @c %end of fragment @subsubheading Quassel Service diff --git a/gnu/services/messaging.scm b/gnu/services/messaging.scm index 2a93d42bf2a..2e006f0e448 100644 --- a/gnu/services/messaging.scm +++ b/gnu/services/messaging.scm @@ -149,6 +149,40 @@ (define-module (gnu services messaging) ngircd-channel-modes ngircd-channel-key-file + pounce-configuration + pounce-configuration-pounce + pounce-configuration-shepherd-provision + pounce-configuration-shepherd-requirement + pounce-configuration-log-file + pounce-configuration-verbose? + pounce-configuration-local-host + pounce-configuration-local-port + pounce-configuration-local-ca + pounce-configuration-local-cert + pounce-configuration-local-priv + pounce-configuration-local-pass + pounce-configuration-size + pounce-configuration-bind + pounce-configuration-host + pounce-configuration-port + pounce-configuration-pass + pounce-configuration-join + pounce-configuration-mode + pounce-configuration-user + pounce-configuration-nick + pounce-configuration-real + pounce-configuration-away + pounce-configuration-quit + pounce-configuration-no-names? + pounce-configuration-queue-interval + pounce-configuration-trust + pounce-configuration-client-cert + pounce-configuration-client-priv + pounce-configuration-sasl-plain + pounce-configuration-sasl-external? + + pounce-service-type + quassel-configuration quassel-service-type @@ -1637,6 +1671,354 @@ (define ngircd-service-type "Run @url{https://ngircd.barton.de/, ngIRCd}, a lightweight @acronym{IRC, Internet Relay Chat} daemon."))) + +;;; +;;; Pounce. +;;; +(define (pounce-serialize-boolean field value) + "Boolean arguments for pounce serialize to their field name, minus the +trailing '?'." + (let ((name (symbol->string field))) + (string-append (if (string-suffix? "?" name) + (string-drop-right name 1) + name) + "\n"))) + +(define (pounce-serialize-string field value) + (format #f "~a=~a~%" field value)) + +(define (pounce-serialize-list-of-strings field value) + (format #f "~a=~{~a~^,~}~%" field value)) + +(define (pounce-serialize-pair field value) + (match value + ((head . tail) + (format #f "~a=~a:~a~%" field head tail)))) + +(define (power-of-two? x) + "Predicate to check if X is an exact power of two." + (exact-integer? (sqrt x))) + +(define pounce-serialize-number pounce-serialize-string) +(define pounce-serialize-power-of-two pounce-serialize-number) +(define pounce-serialize-port pounce-serialize-number) + +(define-maybe boolean (prefix pounce-)) +(define-maybe number (prefix pounce-)) +(define-maybe pair (prefix pounce-)) +(define-maybe port (prefix pounce-)) +(define-maybe power-of-two (prefix pounce-)) +(define-maybe string (prefix pounce-)) +(define-maybe list-of-strings (prefix pounce-)) + +;;; For a reference w.r.t. which options require an argument, refer to the +;;; `options' array defined in bounce.c. +(define-configuration pounce-configuration + (pounce + (file-like pounce) + "The @code{pounce} package to use." + (serializer empty-serializer)) + + (shepherd-provision + (list-of-symbols '(pounce)) + "The name(s) of the service." + (serializer empty-serializer)) + + (shepherd-requirement + (list-of-symbols '(user-processes)) + "Shepherd requirements the service should depend on." + (serializer empty-serializer)) + + (log-file + (string "/var/log/pounce.log") + "The log file name to use." + (serializer empty-serializer)) + + (verbose? + maybe-boolean + "When true, log IRC messages to standard output.") + + ;; Client options. + (local-host + (maybe-string "localhost") + "The host to bind to.") + + (local-port + (maybe-port 6697) + "The port to bind to.") + + (local-ca + maybe-string + "Require clients to authenticate using a TLS client certificate either +contained in or signed by a certificate in the file loaded from @{local-ca}, a +file name. The file is reloaded when the SIGUSR1 signal is received.") + + (local-cert + maybe-string + "File name of the TLS certificate to load. The file is reloaded when the +SIGUSR1 signal is received. Unless specified, a self-signed certificate is +generated at @file{/var/lib/pounce/.config/pounce/@var{host}.pem}, where +@var{host} corresponds to the value of the @code{local-host} field.") + + (local-priv + maybe-string + "File name of the private TLS key to load. Unless specified, a key is +generated at @file{/var/lib/pounce/.config/pounce/@var{host}.key}, where +@var{host} corresponds to the value of the @code{local-host} field.") + + (local-pass + maybe-string + "Require the server password pass for clients to connect. The pass string +must be hashed using @samp{pounce -x}.") + + (size + (maybe-power-of-two 4096) + "Set the number of messages contained in the buffer to @var{size}. This +sets the maximum number of recent messages which can be relayed to a +reconnecting client. The size must be a power of two.") + + ;; Server options. + (bind + maybe-string + "Host to bind the @emph{source} address to when connecting to the server. +To connect from any address over IPv4 only, use @samp{0.0.0.0}. To connect +from any address over IPv6 only, use @samp{::}." ) + + (host + string + "The host name to connect to.") + + (port + maybe-port + "The port number to connect to.") + + (pass + maybe-string + "Password to use to log in with the server. The password must have been +hashed via the @samp{pounce -x} command.") + + (join + maybe-list-of-strings + "The list of channels to join.") + + (mode maybe-string "The user mode.") + + (user + maybe-string + "To set the username. The default username is the same as the nickname.") + + (nick + (maybe-string "pounce") + "Set nickname to @var{nick}.") + + (real + maybe-string + "Set the real name. The default is @code{nick}.") + + (away + maybe-string + "The away status to use when no clients are connected and no other away +status has been set.") + + (quit + maybe-string + "The message to use when quitting.") + + (no-names? + maybe-boolean + "Do not request @samp{NAMES} for each channel when a client connects. This +avoids already connected clients receiving unsolicited responses but prevents +new clients from populating user lists.") + + (queue-interval + (maybe-number 200) + "Set the server send queue interval in milliseconds. The queue is used to +send automated messages from pounce to the server. Messages from clients are +sent to the server directly.") + + (trust + maybe-string + "File name of a certificate to trust. When used, server name verification +is disabled.") + + (client-cert + maybe-string + "The file name of the TLS client. If the private key is in a separate +file, it is loaded with @code{client-priv}. With @code{sasl-external?}, +authenticate using SASL EXTERNAL. Certificates can be generated with +@samp{pounce -g}. For more details, refer to ``Generating Client +Certificates'' in @samp{man 1 pounce}.") + + (client-priv + maybe-string + "The file name of the TLS client private key.") + + (sasl-plain + maybe-pair + "A pair of the username and password in plain text to authenticate using +SASL PLAIN. Since this method requires the account password in plain text, it +is recommended to use CertFP instead with @code{sasl-external}.") + + (sasl-external? + maybe-boolean + "Authenticate using SASL EXTERNAL, also known as CertFP. The TLS client +certificate is loaded from @code{client-cert}.") + (prefix pounce-)) + +(define %pounce-account + (list (user-group (name "pounce") (system? #t)) + (user-account + (name "pounce") + (group "pounce") + (system? #t) + (comment "Pounce daemon user") + (home-directory "/var/lib/pounce") + (shell (file-append shadow "/sbin/nologin"))))) + +(define (pounce-activation config) + "Create the HOME directory for pounce as well as the default TLS certificate +and key, if not explicitly provided." + (match-record config + ( local-host local-ca local-cert local-priv + trust client-cert client-priv) + (with-imported-modules (source-module-closure + '((gnu build activation))) + #~(begin + (use-modules (gnu build activation) + (srfi srfi-34)) + + (let* ((home "/var/lib/pounce") + (user (getpwnam "pounce")) + (confdir (string-append home "/.config/pounce")) + (default-cert (string-append confdir "/" #$local-host ".pem")) + (default-key (string-append confdir "/" #$local-host ".key"))) + + (define* (sanitize-permissions file #:optional (mode #o400)) + (guard (c (#t #t)) + (chown file (passwd:uid user) (passwd:gid user)) + (chmod file mode))) + + ;; Create home directory for pounce user. + (mkdir-p/perms home user #o755) + + ;; Best effort at sanitizing the ownership/permissions of the + ;; certificate/keys. Since a cert file may incorporate the + ;; security key, keep the permissions as tight as possible (owner + ;; read-only / #o400). + (when #$(maybe-value-set? local-ca) + (sanitize-permissions #$local-ca)) + (if #$(maybe-value-set? local-cert) + (sanitize-permissions #$local-cert) + (sanitize-permissions default-cert)) + (if #$(maybe-value-set? local-priv) + (sanitize-permissions #$local-priv) + (sanitize-permissions default-key)) + (when #$(maybe-value-set? trust) + (sanitize-permissions #$trust)) + (when #$(maybe-value-set? client-cert) + (sanitize-permissions #$client-cert)) + (when #$(maybe-value-set? client-priv) + (sanitize-permissions #$client-priv)) + + ;; Generate a default self-signed TLS certificate and private key + ;; unless explicitly provided. + (unless #$(maybe-value-set? local-cert) + (unless (file-exists? default-cert) + (mkdir-p/perms confdir user #o755) + (let ((openssl #$(file-append openssl "/bin/openssl")) + (args `("req" "-newkey" "rsa" "-x509" "-days" "3650" + "-noenc" "-subj" "/C=CA/CN=Pounce Certificate" + ,@(if #$(maybe-value-set? local-priv) + '() ;XXX: likely bogus case + (list "-keyout" default-key)) + "-out" ,default-cert))) + + ;; XXX: Manually guard against and report exceptions until + ;; bug#77365 is addressed. + (guard (c ((invoke-error? c) + (format (current-error-port) + "pounce: error generating pounce tls \ +certificate: ~a~%" c))) + (apply invoke openssl args)) + (sanitize-permissions default-cert #o444) + (unless #$(maybe-value-set? local-priv) + (sanitize-permissions default-key #o400)))))))))) + +(define (serialize-pounce-configuration config) + "Return a file-like object corresponding to the serialized CONFIG + record." + (mixed-text-file "pounce.conf" + (serialize-configuration config + pounce-configuration-fields))) + +(define (pounce-wrapper config) + "Take CONFIG, a object, and provide a least-authority +wrapper for the 'ngircd' command." + (match-record config + (local-ca local-cert local-priv trust client-cert client-priv) + (let* ((pounce.conf (serialize-pounce-configuration config))) + (least-authority-wrapper + (file-append (pounce-configuration-pounce config) "/bin/pounce") + #:name "pounce-pola-wrapper" + ;; Expose all needed files, such as options corresponding to string + ;; file names. + #:mappings + (append + (list (file-system-mapping + (source pounce.conf) + (target source)) + (file-system-mapping + (source "/var/lib/pounce") + (target source) + (writable? #t)) + (file-system-mapping + (source "/var/log/pounce.log") + (target source) + (writable? #t))) + (filter-map (lambda (value) + (if (maybe-value-set? value) + (file-system-mapping + (source value) + (target source)) + #f)) + (list local-ca local-cert local-priv + trust client-cert client-priv))) + #:user "pounce" + #:group "pounce" + #:preserved-environment-variables + (cons "HOME" %default-preserved-environment-variables) + ;; Without preserving the user namespace, pounce fails to access the + ;; provisioned TLS certificates due to permission errors. + #:namespaces (fold delq %namespaces '(net user)))))) + +(define (pounce-shepherd-service config) + (let ((pounce.cfg (serialize-pounce-configuration config))) + (list (shepherd-service + (provision (pounce-configuration-shepherd-provision config)) + (requirement (pounce-configuration-shepherd-requirement config)) + (actions (list (shepherd-configuration-action pounce.cfg))) + (start #~(make-forkexec-constructor + (list #$(pounce-wrapper config) #$pounce.cfg) + #:environment-variables (list "HOME=/var/lib/pounce") + #:log-file #$(pounce-configuration-log-file config))) + (stop #~(make-kill-destructor)))))) + +(define pounce-service-type + (service-type + (name 'pounce) + (extensions + (list (service-extension shepherd-root-service-type + pounce-shepherd-service) + (service-extension profile-service-type + (compose list pounce-configuration-pounce)) + (service-extension account-service-type + (const %pounce-account)) + (service-extension activation-service-type + pounce-activation))) + (description + "Run @url{https://git.causal.agency/pounce/about/, pounce}, +the IRC bouncer."))) + ;;; ;;; Quassel. diff --git a/gnu/tests/messaging.scm b/gnu/tests/messaging.scm index d17bce21ef9..e004f160f96 100644 --- a/gnu/tests/messaging.scm +++ b/gnu/tests/messaging.scm @@ -27,16 +27,20 @@ (define-module (gnu tests messaging) #:use-module (gnu services base) #:use-module (gnu services messaging) #:use-module (gnu services networking) + #:use-module (gnu services shepherd) #:use-module (gnu services ssh) + #:use-module (gnu packages) #:use-module (gnu packages irc) #:use-module (gnu packages messaging) #:use-module (gnu packages screen) + #:use-module (gnu packages tls) #:use-module (guix gexp) #:use-module (guix store) #:use-module (guix modules) #:export (%test-prosody %test-bitlbee %test-ngircd + %test-pounce %test-quassel)) (define (run-xmpp-test name xmpp-service pid-file create-account) @@ -329,6 +333,214 @@ (define %test-ngircd (description "Connect to a ngircd IRC server.") (value (run-ngircd-test)))) + +;;; +;;; Pounce. +;;; + +;;; Code to generate a self-signed TLS certificate/private key for ngIRCd. +;;; The ngIRCd certificate must be added to pounce's 'trust' file so that it +;;; is trusted. It is deployed via a one-shot shepherd service required by +;;; ngircd, which avoids having to allow file-like objects in the ngircd-ssl +;;; configuration record (which would be unsafe as the store is public). +(define ngircd-tls-cert-service-type + (shepherd-service-type + 'ngircd-tls-cert + (lambda _ + (shepherd-service + (documentation "Generate TLS certificate/key for ngIRCd") + (modules (append '((gnu build activation) + (srfi srfi-26)) + %default-modules)) + (provision '(ngircd-tls-cert)) + (start + (with-imported-modules (source-module-closure + '((gnu build activation))) + #~(lambda _ + (let ((certtool #$(file-append gnutls "/bin/certtool")) + (user (getpwnam "ngircd"))) + (mkdir-p/perms "/etc/ngircd" user #o755) + (call-with-output-file "/tmp/template" + (cut format <> "expiration_days = -1~%")) + ;; XXX: Beware, chdir + invoke do not work together in Shepherd + ;; services (see bug#77707). + (invoke certtool "--generate-privkey" + "--outfile" "/etc/ngircd/ca-key.pem") + (invoke certtool "--generate-self-signed" + "--load-privkey" "/etc/ngircd/ca-key.pem" + "--outfile" "/etc/ngircd/ca-cert.pem" + "--template" "/tmp/template") + (chdir "/etc/ngircd") + (chown "ca-key.pem" (passwd:uid user) (passwd:gid user)) + (chmod "ca-key.pem" #o400) + (chown "ca-cert.pem" (passwd:uid user) (passwd:gid user)) + (chmod "ca-cert.pem" #o444) + (delete-file "/tmp/template") + #t)))) + (one-shot? #t))) + #t ;dummy default value + (description "Generate a self-signed TLS certificate for ngIRCd"))) + +;;; To generate a VM image to test with, run: +;;; guix system vm -e '(@@ (gnu tests messaging) %pounce-os)' --no-graphic +;;; After login, resize tty to your needs, e.g.: 'stty rows 52 columns 234' +(define %pounce-os + (operating-system + (inherit %simple-os) + (packages + (append (specifications->packages + '("ii" "socat" + ;; Uncomment for debugging. + ;; "gdb" + ;; "gnutls" ;for gnutls-cli + ;; "screen" + ;; "strace" + ;; "ngircd:debug" + ;; "pounce:debug" + ;; "libressl:debug" + ;; "gnutls:debug" + )) + %base-packages)) + (services + (cons* + (service dhcp-client-service-type) + (service ngircd-tls-cert-service-type) + (service ngircd-service-type + (ngircd-configuration + (debug? #t) + (shepherd-requirement '(user-processes ngircd-tls-cert)) + (ssl (ngircd-ssl + (ports (list 6697)) + (cert-file "/etc/ngircd/ca-cert.pem") + (key-file "/etc/ngircd/ca-key.pem"))) + (channels (list (ngircd-channel (name "#irc")))))) + (service pounce-service-type + (pounce-configuration + (host "localhost") ;connect to ngIRCd server + ;; Trust the IRC server self-signed certificate. + (trust "/etc/ngircd/ca-cert.pem") + (verbose? #t) + ;; The password below was generated by inputting 1234 at the + ;; prompt requested by 'pounce -x'. + (local-pass "\ +$6$rviyVy+iFC9vT37o$2RUAhhFzD8gklXRk9X5KuHYtp6APk8nEXf1uroY2/KlgO9nQ0O/Dj05fzJ\ +/qNlpJQOijJMOyKm4fXjw.Ck9F91") + (local-port 7000) ;listen on port 7000 + (nick "apteryx") + (join (list "#irc")))) + %base-services)))) + +(define (run-pounce-test) + (define vm + (virtual-machine + (operating-system + (marionette-operating-system + %pounce-os + #:imported-modules (source-module-closure + '((gnu build dbus-service) + (guix build utils) + (gnu services herd))))) + (memory-size 1024))) + + (define test + (with-imported-modules '((gnu build marionette)) + #~(begin + (use-modules (srfi srfi-64) + (gnu build marionette)) + + (define marionette + (make-marionette (list #$vm))) + + (test-runner-current (system-test-runner #$output)) + (test-begin "pounce") + + (test-assert "IRC test server listens on TCP port 6697" + (wait-for-tcp-port 6697 marionette)) + + (test-assert "pounce service runs" + (marionette-eval + '(begin + (use-modules (gnu services herd)) + (wait-for-service 'pounce)) + marionette)) + + (test-assert "pounce listens on TCP port 7000" + (wait-for-tcp-port 7000 marionette)) + + (test-assert "pounce functions as an irc bouncer" + (marionette-eval + '(begin + (use-modules ((gnu build dbus-service) #:select (with-retries)) + (guix build utils) + (ice-9 textual-ports)) + + (define (write-command command) + (call-with-output-file "in" + (lambda (port) + (display (string-append command "\n") port)))) + + (define (grep-output text) + (with-retries 5 1 ;retry for 5 seconds + (string-contains (call-with-input-file "out" get-string-all) + (pk 'output-text: text)))) + + (define (connect-to-ngircd) + (mkdir-p "/tmp/pounce") + (unless (zero? (system "ii -s localhost -i /tmp/ngircd \ +-n ayoli &")) + (error "error connecting to irc server")) + (with-retries 5 1 (file-exists? "/tmp/ngircd/localhost")) + (with-directory-excursion "/tmp/ngircd/localhost" + (write-command "/join #irc")) + (with-retries 5 1 + (file-exists? "/tmp/ngircd/localhost/#irc"))) + + (define (connect-to-pounce) + (mkdir-p "/tmp/pounce") + ;; Expose a tunnel encrypting communication via TLS to + ;; pounce (mandated by pounce but supported by ii). + (system "socat UNIX-LISTEN:/tmp/pounce/socket \ +OPENSSL:localhost:7000,verify=0 &") + (with-retries 5 1 (file-exists? "/tmp/pounce/socket")) + (setenv "PASS" "1234") + (unless (zero? (system "ii -s localhost -i /tmp/pounce \ +-u /tmp/pounce/socket -n apteryx -k PASS &")) + (error "error connecting to pounce server")) + (with-retries 5 1 (file-exists? "/tmp/pounce/localhost")) + (with-directory-excursion "/tmp/pounce/localhost" + (write-command "/join #irc")) + (with-retries 5 1 + (file-exists? "/tmp/pounce/localhost/#irc"))) + + (connect-to-ngircd) + (connect-to-pounce) + + ;; Send a message via pounce. + (with-directory-excursion "/tmp/pounce/localhost/#irc" + (write-command "hi! Does pounce work well as a bouncer?") + (write-command "/quit")) + + ;; Someone replied while we were away. + (with-directory-excursion "/tmp/ngircd/localhost/#irc" + (write-command "apteryx: pounce does work well")) + + ;; We reconnect some time later and receive the missed + ;; message. + (with-retries 5 1 (not (file-exists? "/tmp/pounce/socket"))) + (connect-to-pounce) + (with-directory-excursion "/tmp/pounce/localhost/#irc" + (grep-output "apteryx: pounce does work well"))) + marionette)) + (test-end)))) + + (gexp->derivation "pounce-test" test)) + +(define %test-pounce + (system-test + (name "pounce") + (description "Connect to a pounce IRC network bouncer.") + (value (run-pounce-test)))) + ;;; ;;; Quassel. base-commit: 7686fe9d4fa1c40fd78e2ed57c60531c94bc9fd7 -- 2.49.0 From debbugs-submit-bounces@debbugs.gnu.org Sat Apr 19 09:46:59 2025 Received: (at 77922) by debbugs.gnu.org; 19 Apr 2025 13:47:00 +0000 Received: from localhost ([127.0.0.1]:60345 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1u68X4-0004mT-Ay for submit@debbugs.gnu.org; Sat, 19 Apr 2025 09:46:59 -0400 Received: from mx1.dismail.de ([78.46.223.134]:40554) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1u68Wj-0004il-4F for 77922@debbugs.gnu.org; Sat, 19 Apr 2025 09:46:38 -0400 Received: from mx1.dismail.de (localhost [127.0.0.1]) by mx1.dismail.de (OpenSMTPD) with ESMTP id 6e95adb7; Sat, 19 Apr 2025 15:46:29 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed; d=dismail.de; h=from:to:cc :subject:in-reply-to:date:message-id:mime-version:content-type; s=20190914; bh=iFEie4AczPFvBTfw9e13dyiGxQdMtN6ck5F8buRG9wk=; b= YDrcRxobM1i7gpkGuQIGr0mqIIY/f4vDdZdPOMwwqSyCoxrdufqwy8X67+qkQZaT SANdwnsHhEmcLozazAnuyJAn1u0uFoyqzUafgsAHWW9LfCxpyySVUC/0DiTcFROS 0jz1ygcZJlXUZ3k0PGtQDl+t08u6t8FtkQQP0TMpRJvkLy6kzB1BOaTfN1iFMkP3 hAJf16anniUAkA8bo2sV3pYyjdTJ6BoD374xsRaScfTXpsIQdcTNOE4huG0PyUix Di2oR4tfyrV+X2B7t5BkhfwHg6KKsLCxFFRJNtYaZFxo4zl1l4Pe0+61wnUQw16f O7ixHbs4/FggEDBY1Ay18w== Received: from smtp1.dismail.de ( [10.240.26.11]) by mx1.dismail.de (OpenSMTPD) with ESMTP id df92ea55; Sat, 19 Apr 2025 15:46:28 +0200 (CEST) Received: from smtp1.dismail.de (localhost [127.0.0.1]) by smtp1.dismail.de (OpenSMTPD) with ESMTP id e02c25e5; Sat, 19 Apr 2025 15:46:27 +0200 (CEST) Received: by dismail.de (OpenSMTPD) with ESMTPSA id c4bee347 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Sat, 19 Apr 2025 15:46:26 +0200 (CEST) From: jgart To: 77922@debbugs.gnu.org Subject: Re: [PATCH] services: pounce: New service. In-Reply-To: <164c4298f45762194cadba963ce489d2adc1c427.1745065503.git.maxim.cournoyer@gmail.com> Date: Sat, 19 Apr 2025 08:46:05 -0500 Message-ID: <871ptoxo0y.fsf@unknownee2179f0a061.attlocal.net> MIME-Version: 1.0 Content-Type: text/plain X-Spam-Score: -0.7 (/) X-Debbugs-Envelope-To: 77922 Cc: Maxim Cournoyer X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.7 (-) Oh, this is really nice! From debbugs-submit-bounces@debbugs.gnu.org Sat Apr 19 16:51:54 2025 Received: (at 77922) by debbugs.gnu.org; 19 Apr 2025 20:51:54 +0000 Received: from localhost ([127.0.0.1]:38624 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1u6FAH-0006Wx-Ap for submit@debbugs.gnu.org; Sat, 19 Apr 2025 16:51:54 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37074) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1u6FAC-0006Vm-4z for 77922@debbugs.gnu.org; Sat, 19 Apr 2025 16:51:49 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1u6FA6-00059s-RO; Sat, 19 Apr 2025 16:51:42 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=MIME-Version:Date:References:In-Reply-To:Subject:To: From; bh=BJcDiXAubG/eUusmM3oSewGsfMrOndBFqOY6Wb4Lz9Y=; b=npEf0wxswHYq5+SaS6oP 8dGxasS13Dknou8Lb3ofs7U78Njn3bzRNOOoBw5BLkYeAKO+551AGZw+v1Y7uJ5ZfWYl4Mo9Dr8ch yN6n+9Wy/LYcEw9QeAygPmOiAHpns0yg5rnEBIvO3XIYtER+rvAFAwqhajXkGI8Vd8Olu+0rTjuE4 c1OR0ROD6fzr1yJndPj2XHnva/gfsVHhmfp8Uaij2SJh7qT8CEsk8C4NtcRObGuYhboNoRbfatpEb l7FQ5VC69JUgm1TPJXRsCyGzblNnt2mJ6UZeMmQU09LsEup2fUT2ZLfIAYbs+tZEQEW4azIWKwmd8 s/E5fiGhvL/Nnw==; From: =?utf-8?Q?Ludovic_Court=C3=A8s?= To: Maxim Cournoyer Subject: Re: [bug#77922] [PATCH] services: pounce: New service. In-Reply-To: <164c4298f45762194cadba963ce489d2adc1c427.1745065503.git.maxim.cournoyer@gmail.com> (Maxim Cournoyer's message of "Sat, 19 Apr 2025 21:25:03 +0900") References: <164c4298f45762194cadba963ce489d2adc1c427.1745065503.git.maxim.cournoyer@gmail.com> User-Agent: mu4e 1.12.9; emacs 29.4 X-URL: https://people.bordeaux.inria.fr/lcourtes/ X-PGP-Fingerprint: 3CE4 6455 8A84 FDC6 9DB4 0CFB 090B 1199 3D9A EBB5 X-OS: x86_64-pc-linux-gnu X-Revolutionary-Date: =?utf-8?Q?D=C3=A9cadi?= 30 Germinal an 233 de la =?utf-8?Q?R=C3=A9volution=2C?= jour du Greffoir Date: Sat, 19 Apr 2025 22:50:02 +0200 Message-ID: <87wmbfev0l.fsf@gnu.org> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 77922 Cc: 77922@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) Hello, Maxim Cournoyer writes: > * gnu/services/messaging.scm (pounce-serialize-boolean): > (pounce-serialize-string, pounce-serialize-list-of-strings) > (pounce-serialize-pair, power-of-two?) > (pounce-serialize-number, pounce-serialize-power-of-two) > (pounce-serialize-port, pounce-serialize-maybe-boolean) > (pounce-serialize-maybe-number, pounce-serialize-maybe-pair) > (pounce-serialize-maybe-port, pounce-serialize-maybe-port > (pounce-maybe-power-of-two, pounce-serialize-maybe-string) > (pounce-serialize-maybe-list-of-strings): New procedures. > (pounce-configuration): New configuration. > (pounce-activation): New procedure. > (serialize-pounce-configuration, pounce-wrapper): Likewise. > (pounce-service-type): New service type. > * gnu/tests/messaging.scm (ngircd-tls-cert-service-type): New variable. > (%pounce-os): Likewise. > (run-pounce-test): New procedure. > (%test-pounce): New test. > * doc/guix.texi (Messaging Services): Document it. > > Change-Id: I4bbd2bc4821072a93c2c4017b86df329c4b240cb I had a quick look and this looks great to me. Minor issues: > +@item @code{local-ca} (type: maybe-string) > +Require clients to authenticate using a TLS client certificate either > +contained in or signed by a certificate in the file loaded from > +@{local-ca There=E2=80=99s a bug here: the line is truncated and markup is bogus. Also maybe =E2=80=9Clocal-certificate-authorities=E2=80=9D? > +@item @code{local-cert} (type: maybe-string) =E2=80=9Clocal-certificate=E2=80=9D? > +@item @code{local-priv} (type: maybe-string) =E2=80=9Clocal-private-key=E2=80=9D > +@item @code{client-cert} (type: maybe-string) [...] > +@item @code{client-priv} (type: maybe-string) Likewise. Thanks, Ludo=E2=80=99. From debbugs-submit-bounces@debbugs.gnu.org Mon Apr 21 22:38:21 2025 Received: (at 77922-done) by debbugs.gnu.org; 22 Apr 2025 02:38:21 +0000 Received: from localhost ([127.0.0.1]:42069 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1u73We-0006zK-Vd for submit@debbugs.gnu.org; Mon, 21 Apr 2025 22:38:21 -0400 Received: from mail-pl1-x629.google.com ([2607:f8b0:4864:20::629]:42381) by debbugs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.84_2) (envelope-from ) id 1u73Wb-0006z2-6H for 77922-done@debbugs.gnu.org; Mon, 21 Apr 2025 22:38:19 -0400 Received: by mail-pl1-x629.google.com with SMTP id d9443c01a7336-223f4c06e9fso38928015ad.1 for <77922-done@debbugs.gnu.org>; Mon, 21 Apr 2025 19:38:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1745289491; x=1745894291; darn=debbugs.gnu.org; h=content-transfer-encoding:mime-version:user-agent:message-id:date :references:in-reply-to:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=lEgE3p1T55+vrYah7/y3p8dxjfSO8BixlbM7rndKG5Y=; b=TdUqJVTSVhXDX3iQaTkzMJc+ob74vceEpvVvMJZN8KgBkfCYXY+elMyDyao+AfisT2 nmFBE5uzVg4O8xwfk8Wftf/WFWyBfcBCtbFI72wz02Qs8dk3JjC1m9IGLXe4gEpSgQAU AW2L6/KKvy38D8fNSm/wapMW6WNxSiPH0JPu/a75noQI7B7HqGZryoYFPPe4OCinrt1Z 0at7sX+YpGz1bA12LuiOnciSJj0Rk1cKBntmdMjvL7Vg4VHDcYhJu2qbV4qbRwFcnWPS exIL1sfjHtRjNr/K1rfohpQ3PkSATqf7xd+9z+JczerO6MFfTmVs2LusxT1dY0zaFIBQ ubbw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1745289491; x=1745894291; h=content-transfer-encoding:mime-version:user-agent:message-id:date :references:in-reply-to:subject:cc:to:from:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=lEgE3p1T55+vrYah7/y3p8dxjfSO8BixlbM7rndKG5Y=; b=JDEsjY027GIXDcK5lgz2dChPvSf0OnYiBRiFh3OI+o9Zzp8IVP34gQ0hBhQxbphFyF jeB1VyGxTh8Ibw4VfAZ9dEPCnM46M+ouKhqtgJ61Rp3VQB5ohAG5ubfN41d7VB7ZTf3X pt515unH47SALsrS7JVn3x7S9BzWRXaZDiOo93auQqRxQAilYamzwkEPXrdcnS80k++m x+KG6OADE3RTpJhqbRAnGhljnilEwzER5gydPFVl6erjjqcR5U+PmLocY5GlO81cl1GK cd2+ftypMbkaXI8nyIZ1ZsLLVzuJzA48CZ9h5kheWM2ezZnqtxpKHT/qeVdLPDniIV7i GiOQ== X-Gm-Message-State: AOJu0YxrEhCHH/DILAQWUJGzrrc+ZMj8fOqljheBxP+1THxB/7B6kkiD 6Q27CSYz4rZn91nGti6b2XakUpUQfaZraM+QZpecldGvuzN/pTOR X-Gm-Gg: ASbGncutSwPQmysQsB0KyzGVza5tSOlJW5DgE55u7jSYs1Kl2twx6RpDv3aAuH7D8uP nlF4BAP89vxNB4cX977ZwL9CYKirCwfWEYEz618/ate7n0ms0IZ5HbH1tL+QIpSqE03ebPqfMap xqZlMqFE05CSYtb0Kf+nfqAw0P0Tr2FO99vGjqSvmvA0Qy39IJAVomWk9qxGXY4eDvyQZECEBo6 w8aFBXCBFma/DknBuIsxQMYagshKI33vL/6sQkNzvtm/qWy2Bsq66wCYFAcsoV7em3sP64MqWrf IqdRv40t4BNb2YHzC/rP0Kvce1esso+l9oilnbk= X-Google-Smtp-Source: AGHT+IH/VfvgZyx20U0QpcaVGPuHRAWNN9G56t+tJGijfn7W/Rose62Isl7BwBRjdOEok+aFZbsLZQ== X-Received: by 2002:a17:903:2acb:b0:216:4676:dfb5 with SMTP id d9443c01a7336-22c53f0dcfcmr191652015ad.21.1745289490875; Mon, 21 Apr 2025 19:38:10 -0700 (PDT) Received: from terra ([2405:6586:be0:0:83c8:d31d:2cec:f542]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-22c50ed1a64sm72830675ad.203.2025.04.21.19.38.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 21 Apr 2025 19:38:10 -0700 (PDT) From: Maxim Cournoyer To: Ludovic =?utf-8?Q?Court=C3=A8s?= Subject: Re: [bug#77922] [PATCH] services: pounce: New service. In-Reply-To: <87wmbfev0l.fsf@gnu.org> ("Ludovic =?utf-8?Q?Court=C3=A8s=22'?= =?utf-8?Q?s?= message of "Sat, 19 Apr 2025 22:50:02 +0200") References: <164c4298f45762194cadba963ce489d2adc1c427.1745065503.git.maxim.cournoyer@gmail.com> <87wmbfev0l.fsf@gnu.org> Date: Tue, 22 Apr 2025 11:38:07 +0900 Message-ID: <87r01kly40.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: 0.0 (/) X-Debbugs-Envelope-To: 77922-done Cc: 77922-done@debbugs.gnu.org, Jorge Gomez X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Hi Ludovic, Ludovic Court=C3=A8s writes: > Hello, > > Maxim Cournoyer writes: > >> * gnu/services/messaging.scm (pounce-serialize-boolean): >> (pounce-serialize-string, pounce-serialize-list-of-strings) >> (pounce-serialize-pair, power-of-two?) >> (pounce-serialize-number, pounce-serialize-power-of-two) >> (pounce-serialize-port, pounce-serialize-maybe-boolean) >> (pounce-serialize-maybe-number, pounce-serialize-maybe-pair) >> (pounce-serialize-maybe-port, pounce-serialize-maybe-port >> (pounce-maybe-power-of-two, pounce-serialize-maybe-string) >> (pounce-serialize-maybe-list-of-strings): New procedures. >> (pounce-configuration): New configuration. >> (pounce-activation): New procedure. >> (serialize-pounce-configuration, pounce-wrapper): Likewise. >> (pounce-service-type): New service type. >> * gnu/tests/messaging.scm (ngircd-tls-cert-service-type): New variable. >> (%pounce-os): Likewise. >> (run-pounce-test): New procedure. >> (%test-pounce): New test. >> * doc/guix.texi (Messaging Services): Document it. >> >> Change-Id: I4bbd2bc4821072a93c2c4017b86df329c4b240cb > > I had a quick look and this looks great to me. Thanks for the review! > Minor issues: > >> +@item @code{local-ca} (type: maybe-string) >> +Require clients to authenticate using a TLS client certificate either >> +contained in or signed by a certificate in the file loaded from >> +@{local-ca > > There=E2=80=99s a bug here: the line is truncated and markup is bogus. Good catch! Fixed like so: --8<---------------cut here---------------start------------->8--- modified doc/guix.texi @@ -30905,7 +30905,8 @@ Messaging Services @item @code{local-ca} (type: maybe-string) Require clients to authenticate using a TLS client certificate either contained in or signed by a certificate in the file loaded from -@{local-ca +@code{local-ca}, a file name. The file is reloaded when the SIGUSR1 +signal is received. =20 @item @code{local-cert} (type: maybe-string) File name of the TLS certificate to load. The file is reloaded when the modified gnu/services/messaging.scm @@ -1750,8 +1750,9 @@ (define-configuration pounce-configuration (local-ca maybe-string "Require clients to authenticate using a TLS client certificate either -contained in or signed by a certificate in the file loaded from @{local-ca= }, a -file name. The file is reloaded when the SIGUSR1 signal is received.") +contained in or signed by a certificate in the file loaded from +@code{local-ca}, a file name. The file is reloaded when the SIGUSR1 signa= l is +received.") =20 (local-cert maybe-string --8<---------------cut here---------------end--------------->8--- > Also maybe =E2=80=9Clocal-certificate-authorities=E2=80=9D? > >> +@item @code{local-cert} (type: maybe-string) > > =E2=80=9Clocal-certificate=E2=80=9D? > >> +@item @code{local-priv} (type: maybe-string) > > =E2=80=9Clocal-private-key=E2=80=9D > >> +@item @code{client-cert} (type: maybe-string) > > [...] > >> +@item @code{client-priv} (type: maybe-string) > > Likewise. All of the option names used match 1:1 what goes in the serialized configuration file, and thus what is documented in 'man pounce'; so I've chosen to keep the current names, for consistency. Pushed as commit aab89b3d934. --=20 Thanks, Maxim From unknown Sun Aug 17 09:10:09 2025 Received: (at fakecontrol) by fakecontrolmessage; To: internal_control@debbugs.gnu.org From: Debbugs Internal Request Subject: Internal Control Message-Id: bug archived. Date: Tue, 20 May 2025 11:24:11 +0000 User-Agent: Fakemail v42.6.9 # This is a fake control message. # # The action: # bug archived. thanks # This fakemail brought to you by your local debbugs # administrator