POUNCE(1)                   General Commands Manual                  POUNCE(1)

NAME
     pounce – IRC bouncer

SYNOPSIS
     pounce [-LNTev] [-A local-ca] [-C local-cert] [-H local-host]
            [-K local-priv] [-P local-port] [-Q queue-interval] [-R blind-req]
            [-S bind] [-U local-path] [-W local-pass] [-a sasl-plain]
            [-c client-cert] [-f save] [-h host] [-j join] [-k client-priv]
            [-m mode] [-n nick] [-p port] [-q quit] [-r real] [-t trust]
            [-s size] [-u user] [-w pass] [-y away] [config ...]
     pounce -o [-S bind] [-h host] [-p port] [config ...]
     pounce [-A ca] -g cert
     pounce -x

DESCRIPTION
     The pounce program is a multi-client, TLS-only IRC bouncer.  It maintains
     a persistent connection to an IRC server while allowing clients to
     connect and disconnect, receiving messages that were missed upon
     reconnection.  Clients must uniquely identify themselves to pounce by
     their IRC username (not nickname).  The IRCv3 server-time extension is
     used to indicate when messages were originally received.  See Client
     Configuration for details.

     The local server portion of pounce requires a TLS certificate, which can
     be obtained for example by an ACME client such as acme-client(8).  The
     private key must be made readable by the user running pounce.

     One instance of pounce must be configured for each IRC network.
     Instances of pounce must either use different local ports with local-port
     or different local host names with local-host and local-path to be
     dispatched from the same port by calico(1).

     Client connections are not accepted until successful login to the server.
     If the server connection is lost, the pounce process exits.

     Options can be loaded from files listed on the command line.  Files are
     searched for in $XDG_CONFIG_DIRS/pounce (usually ~/.config/pounce) unless
     the path starts with ‘/’, ‘./’ or ‘../’.  Certificate and private key
     paths are searched for in the same manner.  Files and flags listed later
     on the command line take precedence over those listed earlier.

     Each option is placed on a line, and lines beginning with ‘#’ are
     ignored.  The options are listed below following their corresponding
     flags.

   Local Server Options
     -A path | local-ca = path
             Require clients to authenticate using a TLS client certificate
             either contained in or signed by a certificate in the file loaded
             from path.  The file is reloaded when the SIGUSR1 signal is
             received.  See Generating Client Certificates.  If local-pass is
             also set, clients may instead authenticate with a server
             password.

     -C path | local-cert = path
             Load TLS certificate from path.  The file is reloaded when the
             SIGUSR1 signal is received.  The default path is host.pem, where
             host is set by local-host.

     -H host | local-host = host
             Bind to host.  The default host is localhost.

     -K path | local-priv = path
             Load TLS private key from path.  The file is reloaded when the
             SIGUSR1 signal is received.  The default path is host.key, where
             host is set by local-host.

     -L | palaver
             Advertise the palaverapp.com IRCv3 vendor-specific capability to
             clients.  This option only enables the capability; push
             notifications must be provided by the pounce-palaver(1) special-
             purpose client.

     -P port | local-port = port
             Bind to port.  The default port is 6697.

     -T | no-sts
             Do not advertise a strict transport security (STS) policy to
             clients.

     -U path | local-path = path
             Bind to a UNIX-domain socket at path.  Clients are only accepted
             as dispatched by calico(1).  If path is a directory, the host set
             by local-host is appended to it.  This option takes precedence
             over local-host and local-port.

     -W pass | local-pass = pass
             Require the server password pass for clients to connect.  The
             pass string must be hashed using -x.  If local-ca is also set,
             clients may instead authenticate using a TLS client certificate.

     -f path | save = path
             Save and load the contents of the buffer from path in
             $XDG_DATA_DIRS/pounce, usually ~/.local/share/pounce, or an
             absolute or relative path if path starts with ‘/’, ‘./’ or ‘../’.
             The file is truncated after loading.

     -s size | size = size
             Set the number of messages contained in the buffer to 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.  The
             default size is 4096.

   Remote Server Options
     -N | no-names
             Do not request ‘NAMES’ for each channel when a client connects.
             This avoids already connected clients receiving unsolicited
             responses but prevents new clients from populating user lists.

     -Q ms | queue-interval = ms
             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.  The
             default interval is 200 milliseconds.

     -R caps | blind-req = caps
             Blindly request the IRCv3 capabilities caps, which must be
             supported by pounce.  This can be used to enable hidden
             capabilities, such as userhost-in-names on some networks.

     -S host | bind = host
             Bind to source address host when connecting to the server.  To
             connect from any address over IPv4 only, use 0.0.0.0.  To connect
             from any address over IPv6 only, use ::.

     -a user:pass | sasl-plain = user:pass
             Authenticate as user with pass using SASL PLAIN.  Since this
             method requires the account password in plaintext, it is
             recommended to use CertFP instead with sasl-external.

     -c path | client-cert = path
             Load the TLS client certificate from path.  If the private key is
             in a separate file, it is loaded with client-priv.  With
             sasl-external, authenticate using SASL EXTERNAL.  Certificates
             can be generated with -g.

     -e | sasl-external
             Authenticate using SASL EXTERNAL, also known as CertFP.  The TLS
             client certificate is loaded with client-cert.  See Configuring
             CertFP.

     -h host | host = host
             Connect to host.

     -j channels [keys] | join = channels [keys]
             Join the comma-separated list of channels with the optional
             comma-separated list of channel keys.

     -k path | client-priv = path
             Load the TLS client private key from path.

     -m mode | mode = mode
             Set the user mode.

     -n nick | nick = nick
             Set nickname to nick.  The default nickname is the user's name.

     -p port | port = port
             Connect to port.  The default port is 6697.

     -q mesg | quit = mesg
             Quit with message mesg when shutting down.

     -r real | real = real
             Set realname to real.  The default realname is the same as the
             nickname.

     -t path | trust = path
             Trust the certificate loaded from path.  Server name verification
             is disabled.  See Connecting to Servers with Self-signed
             Certificates.

     -u user | user = user
             Set username to user.  The default username is the same as the
             nickname.

     -w pass | pass = pass
             Log in with the server password pass.

     -y mesg | away = mesg
             Set away status to mesg when no clients are connected and no
             other away status has been set.

   Other Options
     -g path
             Generate a TLS client certificate using openssl(1) and write it
             to path.  The certificate is signed by the certificate authority
             if -A is set, otherwise it is self-signed.

     -o      Print the server certificate chain to standard output in PEM
             format and exit.

     -v | verbose
             Log IRC messages to standard output:

             <<  from pounce to the server
             >>  from the server to pounce
             ->  from clients to pounce
             <-  from pounce to clients

     -x      Prompt for a password and output a hash for use with local-pass.

   Client Configuration
     Clients should be configured to connect to the host and port set by
     local-host and local-port, with TLS or SSL enabled.  If local-pass is
     used, clients must send a server password.  If local-ca is used, clients
     must connect with a client certificate and may request SASL EXTERNAL.  If
     both are used, clients may authenticate with either method.

     Clients must register with unique usernames (not nicknames), for example
     the name of the client software or location from which it is connecting.
     New clients with the same username are assumed to be reconnections and
     will cause previous connections to stop receiving messages.  The nickname
     and real name sent by clients are ignored.

     Normally a client sending QUIT will simply be disconnected from pounce.
     If, however, the quit message starts with the keyword $pounce, pounce
     itself will quit.  The remainder of the message following the keyword
     will be used as pounce's quit message, or the default set by quit if
     there isn't any.

     Clients which request the causal.agency/passive capability or with
     usernames beginning with hyphen ‘-’ are considered passive and do not
     affect automatic away status.

     Pass-through of the following IRCv3 capabilities is supported:
     account-notify, account-tag, away-notify, batch, cap-notify, chghost,
     echo-message, extended-join, extended-monitor, invite-notify,
     labeled-response, message-tags, multi-prefix, server-time, setname,
     userhost-in-names.

     Private messages and notices sent to the user's own nickname are relayed
     only to other clients, not to the server.

   Generating Client Certificates
     1.   Generate self-signed client certificates and private keys:

                $ pounce -g client1.pem
                $ pounce -g client2.pem

     2.   Concatenate the certificate public keys into a CA file:

                $ openssl x509 -subject -in client1.pem \
                        >> ~/.config/pounce/auth.pem
                $ openssl x509 -subject -in client2.pem \
                        >> ~/.config/pounce/auth.pem

     3.   Configure pounce to verify client certificates against the CA file:

                local-ca = auth.pem
                # or: $ pounce -A auth.pem

     Alternatively, client certificates can be signed by a generated
     certificate authority:

     1.   Generate a self-signed certificate authority:

                $ pounce -g auth.pem

     2.   Generate and sign client certificates using the CA:

                $ pounce -A auth.pem -g client1.pem
                $ pounce -A auth.pem -g client2.pem

     3.   Since only the public key is needed for certificate verification,
          extract it from the CA:

                $ openssl x509 -in auth.pem -out ~/.config/pounce/auth.crt

     4.   Configure pounce to verify client certificates against the CA:

                local-ca = auth.crt
                # or: $ pounce -A auth.crt

   Configuring CertFP
     1.   Generate a new TLS client certificate:

                $ pounce -g ~/.config/pounce/example.pem

     2.   Connect to the server using the certificate:

                client-cert = example.pem
                # or: $ pounce -c example.pem

     3.   Identify with services or use sasl-plain, then add the certificate
          fingerprint to your account:

                /msg NickServ CERT ADD

     4.   Enable SASL EXTERNAL to require successful authentication when
          connecting:

                client-cert = example.pem
                sasl-external
                # or: $ pounce -e -c example.pem

   Connecting to Servers with Self-signed Certificates
     1.   Connect to the server and write its certificate to a file:

                $ pounce -o -h irc.example.org > ~/.config/pounce/example.pem

     2.   Configure pounce to trust the certificate:

                trust = example.pem
                # or: $ pounce -t example.pem

ENVIRONMENT
     USER    The default nickname.

FILES
     $XDG_CONFIG_DIRS/pounce
             Configuration files, certificates and private keys are searched
             for first in $XDG_CONFIG_HOME, usually ~/.config, followed by the
             colon-separated list of paths $XDG_CONFIG_DIRS, usually /etc/xdg.

     ~/.config/pounce
             The most likely location of configuration files.

     $XDG_DATA_DIRS/pounce
             Save files are searched for first in $XDG_DATA_HOME, usually
             ~/.local/share, followed by the colon-separated list of paths
             $XDG_DATA_DIRS, usually /usr/local/share:/usr/share.  New save
             files are created in $XDG_DATA_HOME.

     ~/.local/share/pounce
             The most likely location of save files.

EXAMPLES
     Start pounce:

           $ pounce -H irc.example.org -h irc.tilde.chat -j '#ascii.town'

     Write an equivalent configuration file to ~/.config/pounce/tilde.conf:

           local-host = irc.example.org
           host = irc.tilde.chat
           join = #ascii.town

     Load the configuration file:

           $ pounce tilde.conf

     Add a certificate to acme-client.conf(5):

           domain irc.example.org {
                   domain key "/home/user/.config/pounce/irc.example.org.key"
                   domain full chain certificate \
                           "/home/user/.config/pounce/irc.example.org.pem"
                   sign with letsencrypt
           }

     Obtain the certificate and make the private key readable by pounce:

           # acme-client irc.example.org
           # chown user /home/user/.config/pounce/irc.example.org.key

     Renew and reload the certificate with a cron(8) job:

           ~ * * * *       acme-client irc.example.org && pkill -USR1 pounce

DIAGNOSTICS
     Upon receiving the SIGINFO signal, pounce prints the current producer
     position and the positions of each consumer identified by username.
     Following each consumer position is the number by which it trails the
     producer.  On systems lacking SIGINFO, SIGUSR2 is used.

     If a client reconnects after having missed more messages than the size of
     the buffer, pounce will print a warning:

           consumer name dropped n messages

     The size of the buffer can be adjusted with -s.

SEE ALSO
     calico(1)

STANDARDS
     Waldo Bastian, Ryan Lortie, and Lennart Poettering, XDG Base Directory
     Specification,
     https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html,
     November 24, 2010.

     Kyle Fuller, Stéphan Kochen, Alexey Sokolov, and James Wheare, server-
     time Extension, IRCv3 Working Group,
     https://ircv3.net/specs/extensions/server-time.

     Lee Hardy, Perry Lorier, Kevin L. Mitchell, Attila Molnar, Daniel Oakley,
     William Pitcock, and James Wheare, IRCv3 Client Capability Negotiation,
     IRCv3 Working Group, https://ircv3.net/specs/core/capability-negotiation.

     S. Josefsson, The Base16, Base32, and Base64 Data Encodings, IETF, RFC
     4648, https://tools.ietf.org/html/rfc4648, October 2006.

     C. Kalt, Internet Relay Chat: Client Protocol, IETF, RFC 2812,
     https://tools.ietf.org/html/rfc2812, April 2000.

     Attila Molnar and James Wheare, IRCv3 Strict Transport Security, IRCv3
     Working Group, https://ircv3.net/specs/extensions/sts.

     Attila Molnar and William Pitcock, IRCv3.2 SASL Authentication, IRCv3
     Working Group, https://ircv3.net/specs/extensions/sasl-3.2.

     Simon Ser and delthas, Read marker, IRCv3 Working Group,
     https://ircv3.net/specs/extensions/read-marker.

     K. Zeilenga, Ed., The PLAIN Simple Authentication and Security Layer
     (SASL) Mechanism, IETF, RFC 4616, https://tools.ietf.org/html/rfc4616,
     August 2006.

   Extensions
     The causal.agency/consumer vendor-specific IRCv3 capability enables the
     causal.agency/pos message tag.  The value of this tag is a 64-bit
     unsigned integer indicating the consumer position of the client after
     receiving each message, e.g. ‘@causal.agency/pos=42069’.  This capability
     may be requested with the value of the last causal.agency/pos tag
     received by the client, e.g. ‘CAP REQ causal.agency/consumer=42069’,
     setting its consumer position.  By persisting this value across
     connections, a client can ensure no messages are missed, even in case of
     network issues or application crashes.

     IRCv3 Client Capability Negotiation specifies that capabilities MAY have
     values in ‘CAP LS’ or ‘CAP NEW’ responses.  It does not, however,
     indicate if ‘CAP REQ’ capabilities MUST NOT have values.  The pounce
     implementation parses ‘CAP REQ’ values in the same way as ‘CAP LS’
     values.

     The causal.agency/passive vendor-specific IRCv3 capability indicates that
     a client should not affect the automatic away status.

AUTHORS
     June McEnroe <june@causal.agency>

BUGS
     Send mail to <list+pounce@causal.agency> or join #ascii.town on
     irc.tilde.chat.

     A client will sometimes receive its own message, causing it to be
     displayed twice.  This happens when a message is sent while responses are
     not yet consumed.

Linux 6.10.6-artix1-1            July 16, 2023           Linux 6.10.6-artix1-1