* [bug#32346] [PATCH 2/6] services: tor: Rename activation procedure.
2018-08-02 6:51 ` [bug#32346] [PATCH 1/6] services: tor: Add a system test Chris Marusich
@ 2018-08-02 6:51 ` Chris Marusich
2018-08-20 20:03 ` Ludovic Courtès
2018-08-02 6:51 ` [bug#32346] [PATCH 3/6] marionette: Add support for QEMU's "quit" command Chris Marusich
` (4 subsequent siblings)
5 siblings, 1 reply; 18+ messages in thread
From: Chris Marusich @ 2018-08-02 6:51 UTC (permalink / raw)
To: 32346; +Cc: Chris Marusich
* gnu/services/networking.scm: Rename the procedure
tor-hidden-service-activation to tor-activation.
---
gnu/services/networking.scm | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/gnu/services/networking.scm b/gnu/services/networking.scm
index bd79e6589..9523f97f6 100644
--- a/gnu/services/networking.scm
+++ b/gnu/services/networking.scm
@@ -676,7 +676,7 @@ HiddenServicePort ~a ~a~%"
(stop #~(make-kill-destructor))
(documentation "Run the Tor anonymous network overlay."))))))))
-(define (tor-hidden-service-activation config)
+(define (tor-activation config)
"Set up directories for TOR and its hidden services, if any."
#~(begin
(use-modules (guix build utils))
@@ -721,7 +721,7 @@ HiddenServicePort ~a ~a~%"
(service-extension account-service-type
(const %tor-accounts))
(service-extension activation-service-type
- tor-hidden-service-activation)))
+ tor-activation)))
;; This can be extended with hidden services.
(compose concatenate)
--
2.18.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [bug#32346] [PATCH 3/6] marionette: Add support for QEMU's "quit" command.
2018-08-02 6:51 ` [bug#32346] [PATCH 1/6] services: tor: Add a system test Chris Marusich
2018-08-02 6:51 ` [bug#32346] [PATCH 2/6] services: tor: Rename activation procedure Chris Marusich
@ 2018-08-02 6:51 ` Chris Marusich
2018-08-20 20:03 ` Ludovic Courtès
2018-08-02 6:51 ` [bug#32346] [PATCH 4/6] marionette: Add wait-for-unix-socket Chris Marusich
` (3 subsequent siblings)
5 siblings, 1 reply; 18+ messages in thread
From: Chris Marusich @ 2018-08-02 6:51 UTC (permalink / raw)
To: 32346; +Cc: Chris Marusich
* gnu/build/marionette.scm (marionette-control): Don't wait for the
monitor prompt when the command was "quit".
---
gnu/build/marionette.scm | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/gnu/build/marionette.scm b/gnu/build/marionette.scm
index bb018fc9c..61284b898 100644
--- a/gnu/build/marionette.scm
+++ b/gnu/build/marionette.scm
@@ -222,7 +222,8 @@ pcsys_monitor\")."
(($ <marionette> _ _ monitor)
(display command monitor)
(newline monitor)
- (wait-for-monitor-prompt monitor))))
+ ;; The "quit" command terminates QEMU immediately, with no output.
+ (unless (string=? command "quit") (wait-for-monitor-prompt monitor)))))
(define* (marionette-screen-text marionette
#:key
--
2.18.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [bug#32346] [PATCH 4/6] marionette: Add wait-for-unix-socket.
2018-08-02 6:51 ` [bug#32346] [PATCH 1/6] services: tor: Add a system test Chris Marusich
2018-08-02 6:51 ` [bug#32346] [PATCH 2/6] services: tor: Rename activation procedure Chris Marusich
2018-08-02 6:51 ` [bug#32346] [PATCH 3/6] marionette: Add support for QEMU's "quit" command Chris Marusich
@ 2018-08-02 6:51 ` Chris Marusich
2018-08-20 20:05 ` Ludovic Courtès
2018-08-02 6:51 ` [bug#32346] [PATCH 5/6] tests: tor: Add more test cases Chris Marusich
` (2 subsequent siblings)
5 siblings, 1 reply; 18+ messages in thread
From: Chris Marusich @ 2018-08-02 6:51 UTC (permalink / raw)
To: 32346; +Cc: Chris Marusich
* gnu/build/marionette.scm (wait-for-unix-socket): New variable.
---
gnu/build/marionette.scm | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/gnu/build/marionette.scm b/gnu/build/marionette.scm
index 61284b898..3588bcbe6 100644
--- a/gnu/build/marionette.scm
+++ b/gnu/build/marionette.scm
@@ -1,5 +1,6 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2016, 2017, 2018 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2018 Chris Marusich <cmmarusich@gmail.com>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -27,6 +28,7 @@
marionette-eval
wait-for-file
wait-for-tcp-port
+ wait-for-unix-socket
marionette-control
marionette-screen-text
wait-for-screen-text
@@ -214,6 +216,29 @@ MARIONETTE. Raise an error on failure."
('failure
(error "nobody's listening on port" port))))
+(define* (wait-for-unix-socket path marionette
+ #:key (timeout 20))
+ "Wait for up to TIMEOUT seconds for PATH, a Unix domain socket, to accept
+connections in MARIONETTE. Raise an error on failure."
+ (match (marionette-eval
+ `(begin
+ (let ((sock (socket PF_UNIX SOCK_STREAM 0)))
+ (let loop ((i 0))
+ (catch 'system-error
+ (lambda ()
+ (connect sock AF_UNIX ,path)
+ 'success)
+ (lambda args
+ (if (< i ,timeout)
+ (begin
+ (sleep 1)
+ (loop (+ 1 i)))
+ 'failure))))))
+ marionette)
+ ('success #t)
+ ('failure
+ (error "nobody's listening on unix domain socket" path))))
+
(define (marionette-control command marionette)
"Run COMMAND in the QEMU monitor of MARIONETTE. COMMAND is a string such as
\"sendkey ctrl-alt-f1\" or \"screendump foo.ppm\" (info \"(qemu-doc)
--
2.18.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [bug#32346] [PATCH 5/6] tests: tor: Add more test cases.
2018-08-02 6:51 ` [bug#32346] [PATCH 1/6] services: tor: Add a system test Chris Marusich
` (2 preceding siblings ...)
2018-08-02 6:51 ` [bug#32346] [PATCH 4/6] marionette: Add wait-for-unix-socket Chris Marusich
@ 2018-08-02 6:51 ` Chris Marusich
2018-08-20 20:06 ` Ludovic Courtès
2018-08-02 6:51 ` [bug#32346] [PATCH 6/6] services: tor: Make it easier to use UNIX sockets Chris Marusich
2018-08-20 20:02 ` [bug#32346] [PATCH 1/6] services: tor: Add a system test Ludovic Courtès
5 siblings, 1 reply; 18+ messages in thread
From: Chris Marusich @ 2018-08-02 6:51 UTC (permalink / raw)
To: 32346; +Cc: Chris Marusich
* gnu/tests/networking.scm (%tor-os/unix-socks-socket): New variable.
(run-tor-test) <os/unix-socks-socket, marionette/unix-socks-socket>
<socket-directory>: New variables.
<"tor is alive">: Move common code from this test case...
<tor-is-alive?>: ...into this new procedure.
<"tor is listening", "tor is alive, even when using a SOCKS socket">
<"tor is listening, even when using a SOCKS socket">: New test cases.
---
gnu/tests/networking.scm | 59 ++++++++++++++++++++++++++++++++++++----
1 file changed, 53 insertions(+), 6 deletions(-)
diff --git a/gnu/tests/networking.scm b/gnu/tests/networking.scm
index c9a4f5463..b332ec3cf 100644
--- a/gnu/tests/networking.scm
+++ b/gnu/tests/networking.scm
@@ -1,6 +1,7 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2017 Thomas Danckaert <post@thomasdanckaert.be>
;;; Copyright © 2017 Marius Bakke <mbakke@fastmail.com>
+;;; Copyright © 2018 Chris Marusich <cmmarusich@gmail.com>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -349,12 +350,29 @@ subnet 192.168.1.0 netmask 255.255.255.0 {
(simple-operating-system
(tor-service)))
+(define %tor-os/unix-socks-socket
+ (simple-operating-system
+ (service tor-service-type
+ (tor-configuration
+ (config-file
+ (plain-file "test-torrc"
+ "\
+SocksPort unix:/var/run/tor/socks-sock
+UnixSocksGroupWritable 1
+")
+ )))))
+
(define (run-tor-test)
(define os
(marionette-operating-system %tor-os
#:imported-modules '((gnu services herd))
#:requirements '(tor)))
+ (define os/unix-socks-socket
+ (marionette-operating-system %tor-os/unix-socks-socket
+ #:imported-modules '((gnu services herd))
+ #:requirements '(tor)))
+
(define test
(with-imported-modules '((gnu build marionette))
#~(begin
@@ -366,12 +384,7 @@ subnet 192.168.1.0 netmask 255.255.255.0 {
(define marionette
(make-marionette (list #$(virtual-machine os))))
- (mkdir #$output)
- (chdir #$output)
-
- (test-begin "tor")
-
- (test-assert "tor is alive"
+ (define (tor-is-alive? marionette)
(marionette-eval
'(begin
(use-modules (gnu services herd)
@@ -383,6 +396,40 @@ subnet 192.168.1.0 netmask 255.255.255.0 {
(current-services))))
marionette))
+ (mkdir #$output)
+ (chdir #$output)
+
+ (test-begin "tor")
+
+ ;; Test the usual TOR service.
+
+ (test-assert "tor is alive"
+ (tor-is-alive? marionette))
+
+ (test-assert "tor is listening"
+ (let ((default-port 9050))
+ (wait-for-tcp-port default-port marionette)))
+
+ ;; Don't run two VMs at once.
+ (marionette-control "quit" marionette)
+
+ ;; Test the TOR service using a SOCKS socket.
+
+ (let* ((socket-directory "/tmp/more-sockets")
+ (_ (mkdir socket-directory))
+ (marionette/unix-socks-socket
+ (make-marionette
+ (list #$(virtual-machine os/unix-socks-socket))
+ ;; We can't use the same socket directory as the first
+ ;; marionette.
+ #:socket-directory socket-directory)))
+ (test-assert "tor is alive, even when using a SOCKS socket"
+ (tor-is-alive? marionette/unix-socks-socket))
+
+ (test-assert "tor is listening, even when using a SOCKS socket"
+ (wait-for-unix-socket "/var/run/tor/socks-sock"
+ marionette/unix-socks-socket)))
+
(test-end)
(exit (= (test-runner-fail-count (test-runner-current)) 0)))))
--
2.18.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [bug#32346] [PATCH 5/6] tests: tor: Add more test cases.
2018-08-02 6:51 ` [bug#32346] [PATCH 5/6] tests: tor: Add more test cases Chris Marusich
@ 2018-08-20 20:06 ` Ludovic Courtès
0 siblings, 0 replies; 18+ messages in thread
From: Ludovic Courtès @ 2018-08-20 20:06 UTC (permalink / raw)
To: Chris Marusich; +Cc: 32346
Chris Marusich <cmmarusich@gmail.com> skribis:
> * gnu/tests/networking.scm (%tor-os/unix-socks-socket): New variable.
> (run-tor-test) <os/unix-socks-socket, marionette/unix-socks-socket>
> <socket-directory>: New variables.
> <"tor is alive">: Move common code from this test case...
> <tor-is-alive?>: ...into this new procedure.
> <"tor is listening", "tor is alive, even when using a SOCKS socket">
> <"tor is listening, even when using a SOCKS socket">: New test cases.
Excellent, LGTM!
^ permalink raw reply [flat|nested] 18+ messages in thread
* [bug#32346] [PATCH 6/6] services: tor: Make it easier to use UNIX sockets.
2018-08-02 6:51 ` [bug#32346] [PATCH 1/6] services: tor: Add a system test Chris Marusich
` (3 preceding siblings ...)
2018-08-02 6:51 ` [bug#32346] [PATCH 5/6] tests: tor: Add more test cases Chris Marusich
@ 2018-08-02 6:51 ` Chris Marusich
2018-08-20 20:09 ` Ludovic Courtès
2018-08-20 20:02 ` [bug#32346] [PATCH 1/6] services: tor: Add a system test Ludovic Courtès
5 siblings, 1 reply; 18+ messages in thread
From: Chris Marusich @ 2018-08-02 6:51 UTC (permalink / raw)
To: 32346; +Cc: Chris Marusich
* doc/guix.texi (Networking Services): Document it, and mention that
tor-service is deprecated.
* gnu/services/networking.scm (<tor-configuration>) <socks-socket-type>:
New field.
(tor-configuration->torrc): When socks-socket-type is 'unix, set
SocksPort to UNIX domain socket /var/run/tor/socks-sock and set
UnixSocksGroupWritable to 1.
* gnu/tests/networking.scm (%tor-os/unix-socks-socket): Instead of using
a custom config file, just set socks-socket-type to 'unix.
---
doc/guix.texi | 52 ++++++++++++++++++++++++++++++++-----
gnu/services/networking.scm | 10 +++++--
gnu/tests/networking.scm | 8 +-----
3 files changed, 54 insertions(+), 16 deletions(-)
diff --git a/doc/guix.texi b/doc/guix.texi
index 080b091b3..c72b1e480 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -11445,16 +11445,54 @@ detailed discussion of each configuration field.
@end deftp
@cindex Tor
-@deffn {Scheme Procedure} tor-service [@var{config-file}] [#:tor @var{tor}]
-Return a service to run the @uref{https://torproject.org, Tor} anonymous
-networking daemon.
+@defvr {Scheme Variable} tor-service-type
+This is the type for a service that runs the @uref{https://torproject.org,
+Tor} anonymous networking daemon. The service is configured using a
+@code{<tor-configuration>} record. By default, the TOR daemon runs as the
+@code{tor} unprivileged user, which is a member of the @code{tor} group.
+
+@end defvr
-The daemon runs as the @code{tor} unprivileged user. It is passed
-@var{config-file}, a file-like object, with an additional @code{User tor} line
-and lines for hidden services added via @code{tor-hidden-service}. Run
-@command{man tor} for information about the configuration file.
+@deffn {Scheme Procedure} tor-service [@var{config-file}] [#:tor @var{tor}]
+This procedure is deprecated and will be removed in a future release. Return
+a service of the @code{tor-service-type} type. @var{config-file} and
+@var{tor} have the same meaning as in @code{<tor-configuration>}.
@end deffn
+@deftp {Data Type} tor-configuration
+@table @asis
+@item @code{tor} (default: @code{tor})
+The package that provides the TOR daemon. This package is expected to provide
+the daemon at @file{bin/tor} relative to its output directory. The default
+package is the @uref{https://www.torproject.org, TOR Project's}
+implementation.
+@item @code{config-file} (default: @code{(plain-file "empty" "")})
+The configuration file to use. It will be appended to a default configuration
+file, and the final configuration file will be passed to @code{tor} via its
+@code{-f} option. This may be any ``file-like'' object (@pxref{G-Expressions,
+file-like objects}). See @code{man tor} for details on the configuration file
+syntax.
+@item @code{hidden-services} (default: @code{'()})
+The list of @code{<hidden-service>} records to use. For any hidden service
+you include in this list, appropriate configuration to enable the hidden
+service will be automatically added to the default configuration file. You
+may conveniently create @code{<hidden-service>} records using the
+@code{tor-hidden-service} procedure described below.
+@item @code{socks-socket-type} (default: @code{'tcp})
+The default socket type that TOR should use for its SOCKS socket. This must
+be either @code{'tcp} or @code{'unix}. If it is @code{'tcp}, then by default
+TOR will listen on TCP port 9050 on the loopback interface (i.e., localhost).
+If it is @code{'unix}, then TOR will listen on the UNIX domain socket
+@file{/var/run/tor/socks-sock}, which will be made writable by members of the
+@code{tor} group.
+
+If you want to customize the SOCKS socket in more detail, leave
+@code{socks-socket-type} at its default value of @code{'tcp} and use
+@code{config-file} to override the default by providing your own
+@code{SocksPort} option.
+@end table
+@end deftp
+
@cindex hidden service
@deffn {Scheme Procedure} tor-hidden-service @var{name} @var{mapping}
Define a new Tor @dfn{hidden service} called @var{name} and implementing
diff --git a/gnu/services/networking.scm b/gnu/services/networking.scm
index 9523f97f6..a7f722807 100644
--- a/gnu/services/networking.scm
+++ b/gnu/services/networking.scm
@@ -577,7 +577,9 @@ demand.")))
(config-file tor-configuration-config-file
(default (plain-file "empty" "")))
(hidden-services tor-configuration-hidden-services
- (default '())))
+ (default '()))
+ (socks-socket-type tor-configuration-socks-socket-type ; 'tcp or 'unix
+ (default 'tcp)))
(define %tor-accounts
;; User account and groups for Tor.
@@ -599,7 +601,7 @@ demand.")))
(define (tor-configuration->torrc config)
"Return a 'torrc' file for CONFIG."
(match config
- (($ <tor-configuration> tor config-file services)
+ (($ <tor-configuration> tor config-file services socks-socket-type)
(computed-file
"torrc"
(with-imported-modules '((guix build utils))
@@ -615,6 +617,10 @@ User tor
DataDirectory /var/lib/tor
PidFile /var/run/tor/tor.pid
Log notice syslog\n" port)
+ (when (eq? 'unix '#$socks-socket-type)
+ (display "\
+SocksPort unix:/var/run/tor/socks-sock
+UnixSocksGroupWritable 1\n" port))
(for-each (match-lambda
((service (ports hosts) ...)
diff --git a/gnu/tests/networking.scm b/gnu/tests/networking.scm
index b332ec3cf..06d6250b8 100644
--- a/gnu/tests/networking.scm
+++ b/gnu/tests/networking.scm
@@ -354,13 +354,7 @@ subnet 192.168.1.0 netmask 255.255.255.0 {
(simple-operating-system
(service tor-service-type
(tor-configuration
- (config-file
- (plain-file "test-torrc"
- "\
-SocksPort unix:/var/run/tor/socks-sock
-UnixSocksGroupWritable 1
-")
- )))))
+ (socks-socket-type 'unix)))))
(define (run-tor-test)
(define os
--
2.18.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [bug#32346] [PATCH 6/6] services: tor: Make it easier to use UNIX sockets.
2018-08-02 6:51 ` [bug#32346] [PATCH 6/6] services: tor: Make it easier to use UNIX sockets Chris Marusich
@ 2018-08-20 20:09 ` Ludovic Courtès
0 siblings, 0 replies; 18+ messages in thread
From: Ludovic Courtès @ 2018-08-20 20:09 UTC (permalink / raw)
To: Chris Marusich; +Cc: 32346
Chris Marusich <cmmarusich@gmail.com> skribis:
> * doc/guix.texi (Networking Services): Document it, and mention that
> tor-service is deprecated.
> * gnu/services/networking.scm (<tor-configuration>) <socks-socket-type>:
> New field.
> (tor-configuration->torrc): When socks-socket-type is 'unix, set
> SocksPort to UNIX domain socket /var/run/tor/socks-sock and set
> UnixSocksGroupWritable to 1.
> * gnu/tests/networking.scm (%tor-os/unix-socks-socket): Instead of using
> a custom config file, just set socks-socket-type to 'unix.
[...]
> +This is the type for a service that runs the @uref{https://torproject.org,
> +Tor} anonymous networking daemon. The service is configured using a
> +@code{<tor-configuration>} record. By default, the TOR daemon runs as the
Please s/TOR/Tor/ in this file.
> +@deftp {Data Type} tor-configuration
> +@table @asis
> +@item @code{tor} (default: @code{tor})
> +The package that provides the TOR daemon. This package is expected to provide
> +the daemon at @file{bin/tor} relative to its output directory. The default
> +package is the @uref{https://www.torproject.org, TOR Project's}
> +implementation.
> +@item @code{config-file} (default: @code{(plain-file "empty" "")})
You could skip a line between between each @item for clarity.
Otherwise LGTM.
Thank you for this nice patch series!
Ludo’.
^ permalink raw reply [flat|nested] 18+ messages in thread
* [bug#32346] [PATCH 1/6] services: tor: Add a system test.
2018-08-02 6:51 ` [bug#32346] [PATCH 1/6] services: tor: Add a system test Chris Marusich
` (4 preceding siblings ...)
2018-08-02 6:51 ` [bug#32346] [PATCH 6/6] services: tor: Make it easier to use UNIX sockets Chris Marusich
@ 2018-08-20 20:02 ` Ludovic Courtès
2018-08-28 7:46 ` bug#32346: " Chris Marusich
5 siblings, 1 reply; 18+ messages in thread
From: Ludovic Courtès @ 2018-08-20 20:02 UTC (permalink / raw)
To: Chris Marusich; +Cc: 32346
Hi Chris,
Chris Marusich <cmmarusich@gmail.com> skribis:
> * gnu/services/networking.scm (tor-configuration->torrc): Set PidFile to
> /var/run/tor/tor.pid in the base torrc configuration.
> (tor-shepherd-service) <start>: Call make-forkexec-constructor/container with
> a new #:pid-file argument to tell Shepherd where to find the PID file. Add a
> a new <file-system-mapping> to its existing #:mappings argument to share
> /var/run/tor with the the container.
> (tor-hidden-services-activation): Update docstring. Create /var/run/tor and
> set its permissions so only the tor user can access it.
> * gnu/tests/networking.scm (%test-tor, %tor-os): New variables.
> (run-tor-test): New procedure.
LGTM! Great work.
> + ;; Allow TOR to write its PID file.
Nitpick: I think the maintainers no longer consider the name an acronym
and write it as “Tor”, not “TOR”.
Thanks,
Ludo’.
^ permalink raw reply [flat|nested] 18+ messages in thread
* bug#32346: [PATCH 1/6] services: tor: Add a system test.
2018-08-20 20:02 ` [bug#32346] [PATCH 1/6] services: tor: Add a system test Ludovic Courtès
@ 2018-08-28 7:46 ` Chris Marusich
0 siblings, 0 replies; 18+ messages in thread
From: Chris Marusich @ 2018-08-28 7:46 UTC (permalink / raw)
To: Ludovic Courtès; +Cc: 32346-done
[-- Attachment #1: Type: text/plain, Size: 1735 bytes --]
Hi Ludo,
I've incorporated your feedback and committed this patch series as
3bcb305b98e02f6c9d98e7325813fc00f18f0e6c. Details follow.
ludo@gnu.org (Ludovic Courtès) writes:
> Chris Marusich <cmmarusich@gmail.com> skribis:
>
>
> [...]
>
>> + ;; Allow TOR to write its PID file.
>
> Nitpick: I think the maintainers no longer consider the name an acronym
> and write it as “Tor”, not “TOR”.
This is good to know. In each patch that uses the incorrect name "TOR",
I've changed it to use the correct name "Tor".
>> +(define* (wait-for-unix-socket path marionette
>
> Super nitpick: s/path/file/ or s/path/file-name/, as per GNU
> convention (where “path” means “search path”.)
I've updated this to follow the convention.
>> +@deftp {Data Type} tor-configuration
>> +@table @asis
>> +@item @code{tor} (default: @code{tor})
>> +The package that provides the TOR daemon. This package is expected
>> to provide
>> +the daemon at @file{bin/tor} relative to its output directory. The default
>> +package is the @uref{https://www.torproject.org, TOR Project's}
>> +implementation.
>> +@item @code{config-file} (default: @code{(plain-file "empty" "")})
>
> You could skip a line between between each @item for clarity.
Good idea. I've done this, too.
> Thank you for this nice patch series!
Thank you for the thoughtful review!
I appreciate your attention to detail. If you hadn't told me, I
wouldn't have known about some of these things, such as the GNU
convention to use "file" or "file-name" instead of "path" when speaking
about UNIX domain sockets. I'll remember these things going forward.
And with that, I will now close this patch!
--
Chris
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]
^ permalink raw reply [flat|nested] 18+ messages in thread