summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/Makefile20
-rw-r--r--doc/admin.rst305
-rw-r--r--doc/biboumi.1.rst762
-rw-r--r--doc/conf.py146
-rw-r--r--doc/contributing.rst84
-rw-r--r--doc/developer.rst302
-rw-r--r--doc/example.conf14
-rw-r--r--doc/index.rst24
-rw-r--r--doc/install.rst194
-rw-r--r--doc/man_index.rst9
-rw-r--r--doc/synopsis.rst4
-rw-r--r--doc/user.rst513
12 files changed, 1601 insertions, 776 deletions
diff --git a/doc/Makefile b/doc/Makefile
new file mode 100644
index 0000000..934bdf7
--- /dev/null
+++ b/doc/Makefile
@@ -0,0 +1,20 @@
+# Minimal makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+SPHINXPROJ = biboumi
+SOURCEDIR = .
+BUILDDIR = _build
+
+# Put it first so that "make" without argument is like "make help".
+help:
+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+.PHONY: help Makefile
+
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
+%: Makefile
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file
diff --git a/doc/admin.rst b/doc/admin.rst
new file mode 100644
index 0000000..a5850a7
--- /dev/null
+++ b/doc/admin.rst
@@ -0,0 +1,305 @@
+###########################
+Administrator documentation
+###########################
+
+Usage
+=====
+
+Biboumi acts as a server, it should be run as a daemon that lives in the
+background for as long as it is needed. Note that biboumi does not
+daemonize itself, this task should be done by your init system (SysVinit,
+systemd, upstart).
+
+When started, biboumi connects, without encryption (see :ref:`Security`), to the
+local XMPP server on the port ``5347`` and authenticates with the provided
+password. Biboumi then serves the configured ``hostname``: this means that
+all XMPP stanza with a `to` JID on that domain will be forwarded to biboumi
+by the XMPP server, and biboumi will only send messages coming from that
+hostname.
+
+To cleanly shutdown the component, send a SIGINT or SIGTERM signal to it.
+It will send messages to all connected IRC and XMPP servers to indicate a
+reason why the users are being disconnected. Biboumi exits when the end of
+communication is acknowledged by all IRC servers. If one or more IRC
+servers do not respond, biboumi will only exit if it receives the same
+signal again or if a 2 seconds delay has passed.
+
+Configuration
+=============
+
+Configuration happens in different places, with different purposes:
+
+- The main and global configuration that specifies vital settings for the
+ daemon to run, like the hostname, password etc. This is an admin-only
+ configuration, and this is described in the next section.
+- A TLS configuration, also admin-only, that can be either global or
+ per-domain. See `TLS configuration`_ section.
+- Using the :ref:`ad-hoc commands`, each user can configure various
+ settings for themself
+
+Daemon configuration
+--------------------
+
+The configuration file is read by biboumi as it starts. The path is
+specified as the only argument to the biboumi binary.
+
+The configuration file uses a simple format of the form ``option=value``
+(note that there are no spaces before or after the equal sign).
+
+The values from the configuration file can be overridden by environment
+variables, with the name all in upper case and prefixed with `BIBOUMI_`.
+For example, if the environment contains “BIBOUMI_PASSWORD=blah", this will
+override the value of the “password” option in the configuration file.
+
+Sending SIGUSR1, SIGUSR2 or SIGHUP (see kill(1)) to the process will force
+it to re-read the configuration and make it close and re-open the log
+files. You can use this to change any configuration option at runtime, or
+do a log rotation.
+
+Options
+-------
+
+A configuration file can look something like this:
+
+.. code-block:: ini
+
+ hostname=biboumi.example.com
+ password=mypassword
+ xmpp_server_ip=127.0.0.1
+ port=5347
+ admin=myself@example.com
+ db_name=postgresql://biboumi:password@localhost/biboumi
+ realname_customization=true
+ realname_from_jid=false
+ log_file=
+ ca_file=
+ outgoing_bind=192.168.0.12
+
+
+Here is a description of all available options
+
+hostname
+~~~~~~~~
+
+Mandatory. The hostname served by the XMPP gateway. This domain must be
+configured in the XMPP server as an external component. See the manual
+for your XMPP server for more information. For prosody, see
+http://prosody.im/doc/components#adding_an_external_component
+
+password
+~~~~~~~~
+
+Mandatory. The password used to authenticate the XMPP component to your
+XMPP server. This password must be configured in the XMPP server,
+associated with the external component on *hostname*.
+
+xmpp_server_ip
+~~~~~~~~~~~~~~
+
+The IP address to connect to the XMPP server on. The connection to the
+XMPP server is unencrypted, so the biboumi instance and the server should
+normally be on the same host. The default value is 127.0.0.1.
+
+port
+~~~~
+
+The TCP port to use to connect to the local XMPP component. The default
+value is 5347.
+
+db_name
+~~~~~~~
+
+The name of the database to use. This option can only be used if biboumi
+has been compiled with a database support (Sqlite3 and/or PostgreSQL). If
+the value begins with the postgresql scheme, “postgresql://” or
+“postgres://”, then biboumi will try to connect to the PostgreSQL database
+specified by the URI. See `the PostgreSQL doc
+<https://www.postgresql.org/docs/current/static/libpq-connect.html#idm46428693970032>`_
+for all possible values. For example the value could be
+“postgresql://user:secret@localhost”. If the value does not start with the
+postgresql scheme, then it specifies a filename that will be opened with
+Sqlite3. For example the value could be “/var/lib/biboumi/biboumi.sqlite”.
+
+admin
+~~~~~
+
+The bare JID of the gateway administrator. This JID will have more
+privileges than other standard users, for example some administration
+ad-hoc commands will only be available to that JID.
+
+If you need more than one administrator, separate them with a colon (:).
+
+fixed_irc_server
+~~~~~~~~~~~~~~~~
+
+If this option contains the hostname of an IRC server (for example
+irc.example.org), then biboumi will enforce the connexion to that IRC
+server only. This means that a JID like ``#chan@biboumi.example.com``
+must be used instead of ``#chan%irc.example.org@biboumi.example.com``. The
+`%` character loses any meaning in the JIDs. It can appear in the JID but
+will not be interpreted as a separator (thus the JID
+``#channel%hello@biboumi.example.com`` points to the channel named
+``#channel%hello`` on the configured IRC server) This option can for
+example be used by an administrator that just wants to let their users
+join their own IRC server using an XMPP client, while forbidding access to
+any other IRC server.
+
+persistent_by_default
+~~~~~~~~~~~~~~~~~~~~~
+
+If this option is set to `true`, all rooms will be persistent by default:
+the value of the “persistent” option in the global configuration of each
+user will be “true”, but the value of each individual room will still
+default to false. This means that a user just needs to change the global
+“persistent” configuration option to false in order to override this.
+
+If it is set to false (the default value), all rooms are not persistent by
+default.
+
+Each room can be configured individually by each user, to override this
+default value. See :ref:`Ad-hoc commands`.
+
+realname_customization
+~~~~~~~~~~~~~~~~~~~~~~
+
+If this option is set to “false” (default is “true”), the users will not be
+able to use the ad-hoc commands that lets them configure their realname and
+username.
+
+realname_from_jid
+~~~~~~~~~~~~~~~~~
+
+If this option is set to “true”, the realname and username of each biboumi
+user will be extracted from their JID. The realname is their bare JID, and
+the username is the node-part of their JID. Note that if
+``realname_customization`` is “true”, each user will still be able to
+customize their realname and username, this option just decides the default
+realname and username.
+
+If this option is set to “false” (the default value), the realname and
+username of each user will be set to the nick they used to connect to the
+IRC server.
+
+webirc_password
+~~~~~~~~~~~~~~~
+
+Configure a password to be communicated to the IRC server, as part of the
+WEBIRC message (see https://kiwiirc.com/docs/webirc). If this option is
+set, an additional DNS resolution of the hostname of each XMPP server will
+be made when connecting to an IRC server.
+
+log_file
+~~~~~~~~
+
+A filename into which logs are written. If none is provided, the logs are
+written on standard output.
+
+log_level
+~~~~~~~~~
+
+Indicate what type of log messages to write in the logs. Value can be
+from 0 to 3. 0 is debug, 1 is info, 2 is warning, 3 is error. The
+default is 0, but a more practical value for production use is 1.
+
+ca_file
+~~~~~~~
+
+Specifies which file should be used as the list of trusted CA when
+negociating a TLS session. By default this value is unset and biboumi
+tries a list of well-known paths.
+
+outgoing_bind
+~~~~~~~~~~~~~
+
+An address (IPv4 or IPv6) to bind the outgoing sockets to. If no value is
+specified, it will use the one assigned by the operating system. You can
+for example use outgoing_bind=192.168.1.11 to force biboumi to use the
+interface with this address. Note that this is only used for connections
+to IRC servers.
+
+identd_port
+~~~~~~~~~~~
+
+The TCP port on which to listen for identd queries. The default is the
+standard value: 113. To be able to listen on this privileged port, biboumi
+needs to have certain capabilities: on linux, using systemd, this can be
+achieved by adding `AmbientCapabilities=CAP_NET_BIND_SERVICE` to the unit
+file. On other systems, other solutions exist, like the portacl module on
+FreeBSD.
+
+If biboumi’s identd server is properly started, it will receive queries from
+the IRC servers asking for the “identity” of each IRC connection made to it.
+Biboumi will answer with a hash of the JID that made the connection. This is
+useful for the IRC server to be able to distinguish the different users, and
+be able to deal with the absuses without having to simply ban the IP. Without
+this identd server, moderation is a lot harder, because all the different
+users of a single biboumi instance all share the same IP, and they can’t be
+distinguished by the IRC servers.
+
+To disable the built-in identd, you may set identd_port to 0.
+
+policy_directory
+~~~~~~~~~~~~~~~~
+
+A directory that should contain the policy files, used to customize
+Botan’s behaviour when negociating the TLS connections with the IRC
+servers. If not specified, the directory is the one where biboumi’s
+configuration file is located: for example if biboumi reads its
+configuration from /etc/biboumi/biboumi.cfg, the policy_directory value
+will be /etc/biboumi.
+
+
+TLS configuration
+-----------------
+
+Various settings of the TLS connections can be customized using policy
+files. The files should be located in the directory specified by the
+configuration option `policy_directory`_. When attempting to connect to
+an IRC server using TLS, biboumi will use Botan’s default TLS policy, and
+then will try to load some policy files to override the values found in
+these files. For example, if policy_directory is /etc/biboumi, when
+trying to connect to irc.example.com, biboumi will try to read
+/etc/biboumi/policy.txt, use the values found to override the default
+values, then it will try to read /etc/biboumi/irc.example.com.policy.txt
+and re-override the policy with the values found in this file.
+
+The policy.txt file applies to all the connections, and
+irc.example.policy.txt will only apply (in addition to policy.txt) when
+connecting to that specific server.
+
+To see the list of possible options to configure, refer to `Botan’s TLS
+documentation <https://botan.randombit.net/manual/tls.html#tls-policies>`_.
+In addition to these Botan options, biboumi implements a few custom options
+listed hereafter:
+- verify_certificate: if this value is set to false, biboumi will not check
+the certificate validity at all. The default value is true.
+
+By default, biboumi provides a few policy files, to work around some
+issues found with a few well-known IRC servers.
+
+
+Security
+========
+
+The connection to the XMPP server can only be made on localhost. The
+XMPP server is not supposed to accept non-local connections from
+components. Thus, encryption is not used to connect to the local
+XMPP server because it is useless.
+
+If compiled with the Botan library, biboumi can use TLS when communicating
+with the IRC servers. It will first try ports 6697 and 6670 and use TLS
+if it succeeds, if connection fails on both these ports, the connection is
+established on port 6667 without any encryption.
+
+Biboumi does not check if the received JIDs are properly formatted using
+nodeprep. This must be done by the XMPP server to which biboumi is
+directly connected.
+
+Biboumi does not provide a way to ban users from connecting to it, has no
+protection against flood or any sort of abuse that your users may cause on
+the IRC servers. Some XMPP server however offer the possibility to restrict
+what JID can access a gateway. Use that feature if you wish to grant access
+to your biboumi instance only to a list of trusted users.
+
+
+
diff --git a/doc/biboumi.1.rst b/doc/biboumi.1.rst
deleted file mode 100644
index 03e8a36..0000000
--- a/doc/biboumi.1.rst
+++ /dev/null
@@ -1,762 +0,0 @@
-======================
-Biboumi(1) User Manual
-======================
-
-.. contents:: :depth: 2
-
-NAME
-====
-
-biboumi - XMPP gateway to IRC
-
-Description
-===========
-
-Biboumi is an XMPP gateway that connects to IRC servers and translates
-between the two protocols. It can be used to access IRC channels using any
-XMPP client as if these channels were XMPP MUCs.
-
-Synopsis
-========
-
-biboumi [*config_filename*]
-
-Options
-=======
-
-Available command line options:
-
-config_filename
----------------
-
-Specify the file to read for configuration. See the `Configuration`_ section for more
-details on its content.
-
-Configuration
-=============
-
-The configuration file uses a simple format of the form ``option=value``.
-
-The values from the configuration file can be overridden by environment
-variables, with the name all in upper case and prefixed with "BIBOUMI_".
-For example, if the environment contains “BIBOUMI_PASSWORD=blah", this will
-override the value of the “password” option in the configuration file.
-
-Sending SIGUSR1 or SIGUSR2 (see kill(1)) to the process will force it to
-re-read the configuration and make it close and re-open the log files. You
-can use this to change any configuration option at runtime, or do a log
-rotation.
-
-Here is a description of every possible option:
-
-hostname
---------
-
-Mandatory. The hostname served by the XMPP gateway. This domain must be
-configured in the XMPP server as an external component. See the manual
-for your XMPP server for more information. For prosody, see
-http://prosody.im/doc/components#adding_an_external_component
-
-password
---------
-
-Mandatory. The password used to authenticate the XMPP component to your
-XMPP server. This password must be configured in the XMPP server,
-associated with the external component on *hostname*.
-
-xmpp_server_ip
---------------
-
-The IP address to connect to the XMPP server on. The connection to the
-XMPP server is unencrypted, so the biboumi instance and the server should
-normally be on the same host. The default value is 127.0.0.1.
-
-port
-----
-
-The TCP port to use to connect to the local XMPP component. The default
-value is 5347.
-
-db_name
--------
-
-The name of the database to use. This option can only be used if biboumi
-has been compiled with a database support (Sqlite3 and/or PostgreSQL). If
-the value begins with the postgresql scheme, “postgresql://” or
-“postgres://”, then biboumi will try to connect to the PostgreSQL database
-specified by the URI. See
-https://www.postgresql.org/docs/current/static/libpq-connect.html#idm46428693970032
-for all possible values. For example the value could be
-“postgresql://user:secret@localhost”. If the value does not start with the
-postgresql scheme, then it specifies a filename that will be opened with
-Sqlite3. For example the value could be “/var/lib/biboumi/biboumi.sqlite”.
-
-admin
------
-
-The bare JID of the gateway administrator. This JID will have more
-privileges than other standard users, for example some administration
-ad-hoc commands will only be available to that JID.
-
-If you need more than one administrator, separate them with a colon (:).
-
-fixed_irc_server
-----------------
-
-If this option contains the hostname of an IRC server (for example
-irc.example.org), then biboumi will enforce the connexion to that IRC
-server only. This means that a JID like ``#chan@biboumi.example.com``
-must be used instead of ``#chan%irc.example.org@biboumi.example.com``. The
-`%` character loses any meaning in the JIDs. It can appear in the JID but
-will not be interpreted as a separator (thus the JID
-``#channel%hello@biboumi.example.com`` points to the channel named
-``#channel%hello`` on the configured IRC server) This option can for
-example be used by an administrator that just wants to let their users
-join their own IRC server using an XMPP client, while forbidding access to
-any other IRC server.
-
-persistent_by_default
----------------------
-
-If this option is set to `true`, all rooms will be persistent by default:
-the value of the “persistent” option in the global configuration of each
-user will be “true”, but the value of each individual room will still
-default to false. This means that a user just needs to change the global
-“persistent” configuration option to false in order to override this.
-
-If it is set to false (the default value), all rooms are not persistent by
-default.
-
-Each room can be configured individually by each user, to override this
-default value. See `Ad-hoc commands`_.
-
-realname_customization
-----------------------
-
-If this option is set to “false” (default is “true”), the users will not be
-able to use the ad-hoc commands that lets them configure their realname and
-username.
-
-realname_from_jid
------------------
-
-If this option is set to “true”, the realname and username of each biboumi
-user will be extracted from their JID. The realname is their bare JID, and
-the username is the node-part of their JID. Note that if
-``realname_customization`` is “true”, each user will still be able to
-customize their realname and username, this option just decides the default
-realname and username.
-
-If this option is set to “false” (the default value), the realname and
-username of each user will be set to the nick they used to connect to the
-IRC server.
-
-webirc_password
----------------
-
-Configure a password to be communicated to the IRC server, as part of the
-WEBIRC message (see https://kiwiirc.com/docs/webirc). If this option is
-set, an additional DNS resolution of the hostname of each XMPP server will
-be made when connecting to an IRC server.
-
-log_file
---------
-
-A filename into which logs are written. If none is provided, the logs are
-written on standard output.
-
-log_level
----------
-
-Indicate what type of log messages to write in the logs. Value can be
-from 0 to 3. 0 is debug, 1 is info, 2 is warning, 3 is error. The
-default is 0, but a more practical value for production use is 1.
-
-ca_file
--------
-
-Specifies which file should be used as the list of trusted CA when
-negociating a TLS session. By default this value is unset and biboumi
-tries a list of well-known paths.
-
-outgoing_bind
--------------
-
-An address (IPv4 or IPv6) to bind the outgoing sockets to. If no value is
-specified, it will use the one assigned by the operating system. You can
-for example use outgoing_bind=192.168.1.11 to force biboumi to use the
-interface with this address. Note that this is only used for connections
-to IRC servers.
-
-identd_port
------------
-
-The TCP port on which to listen for identd queries. The default is the
-standard value: 113. To be able to listen on this privileged port, biboumi
-needs to have certain capabilities: on linux, using systemd, this can be
-achieved by adding `AmbientCapabilities=CAP_NET_BIND_SERVICE` to the unit
-file. On other systems, other solutions exist, like the portacl module on
-FreeBSD.
-
-If biboumi’s identd server is properly started, it will receive queries from
-the IRC servers asking for the “identity” of each IRC connection made to it.
-Biboumi will answer with a hash of the JID that made the connection. This is
-useful for the IRC server to be able to distinguish the different users, and
-be able to deal with the absuses without having to simply ban the IP. Without
-this identd server, moderation is a lot harder, because all the different
-users of a single biboumi instance all share the same IP, and they can’t be
-distinguished by the IRC servers.
-
-To disable the built-in identd, you may set identd_port to 0.
-
-policy_directory
-----------------
-
-A directory that should contain the policy files, used to customize
-Botan’s behaviour when negociating the TLS connections with the IRC
-servers. If not specified, the directory is the one where biboumi’s
-configuration file is located: for example if biboumi reads its
-configuration from /etc/biboumi/biboumi.cfg, the policy_directory value
-will be /etc/biboumi.
-
-
-TLS configuration
-=================
-
-Various settings of the TLS connections can be customized using policy
-files. The files should be located in the directory specified by the
-configuration option `policy_directory`_. When attempting to connect to
-an IRC server using TLS, biboumi will use Botan’s default TLS policy, and
-then will try to load some policy files to override the values found in
-these files. For example, if policy_directory is /etc/biboumi, when
-trying to connect to irc.example.com, biboumi will try to read
-/etc/biboumi/policy.txt, use the values found to override the default
-values, then it will try to read /etc/biboumi/irc.example.com.policy.txt
-and re-override the policy with the values found in this file.
-
-The policy.txt file applies to all the connections, and
-irc.example.policy.txt will only apply (in addition to policy.txt) when
-connecting to that specific server.
-
-To see the list of possible options to configure, refer to `Botan’s TLS
-documentation <https://botan.randombit.net/manual/tls.html#tls-policies>`_.
-
-By default, biboumi provides a few policy files, to work around some
-issues found with a few well-known IRC servers.
-
-Usage
-=====
-
-Biboumi acts as a server, it should be run as a daemon that lives in the
-background for as long as it is needed. Note that biboumi does not
-daemonize itself, this task should be done by your init system (SysVinit,
-systemd, upstart).
-
-When started, biboumi connects, without encryption (see `Security`_), to the
-local XMPP server on the port ``5347`` and authenticates with the provided
-password. Biboumi then serves the configured ``hostname``: this means that
-all XMPP stanza with a `to` JID on that domain will be forwarded to biboumi
-by the XMPP server, and biboumi will only send messages coming from that
-hostname.
-
-When a user joins an IRC channel on an IRC server (see `Join an IRC
-channel`_), biboumi connects to the remote IRC server, sets the user’s nick
-as requested, and then tries to join the specified channel. If the same
-user subsequently tries to connect to an other channel on the same server,
-the same IRC connection is used. If, however, an other user wants to join
-an IRC channel on that same IRC server, biboumi opens a new connection to
-that server. Biboumi connects once to each IRC server, for each user on it.
-
-Additionally, if one user is using more than one clients (with the same bare
-JID), they can join the same IRC channel (on the same server) behind one
-single nickname. Biboumi will forward all the messages (the channel ones and
-the private ones) and the presences to all the resources behind that nick.
-There is no need to have multiple nicknames and multiple connections to be
-able to take part in a conversation (or idle) in a channel from a mobile client
-while the desktop client is still connected, for example.
-
-To cleanly shutdown the component, send a SIGINT or SIGTERM signal to it.
-It will send messages to all connected IRC and XMPP servers to indicate a
-reason why the users are being disconnected. Biboumi exits when the end of
-communication is acknowledged by all IRC servers. If one or more IRC
-servers do not respond, biboumi will only exit if it receives the same
-signal again or if a 2 seconds delay has passed.
-
-Addressing
-----------
-
-IRC entities are represented by XMPP JIDs. The domain part of the JID is
-the domain served by biboumi (the part after the `@`, biboumi.example.com in
-the examples), and the local part (the part before the `@`) depends on the
-concerned entity.
-
-IRC channels and IRC users have a local part formed like this:
-``name`` % ``irc_server``.
-
-``name`` can be a channel name or an user nickname. The distinction between
-the two is based on the first character: by default, if the name starts with
-``'#'`` or ``'&'`` (but this can be overridden by the server, using the
-ISUPPORT extension) then it’s a channel name, otherwise this is a nickname.
-
-There is two ways to address an IRC user, using a local part like this:
-``nickname`` % ``irc_server`` or by using the in-room address of the
-participant, like this:
-``channel_name`` % ``irc_server`` @ ``biboumi.example.com`` / ``Nickname``
-
-The second JID is available only to be compatible with XMPP clients when the
-user wants to send a private message to the participant ``Nickname`` in the
-room ``channel_name%irc_server@biboumi.example.com``.
-
-On XMPP, the node part of the JID can only be lowercase. On the other hand,
-IRC nicknames are case-insensitive, this means that the nicknames toto,
-Toto, tOtO and TOTO all represent the same IRC user. This means you can
-talk to the user toto, and this will work.
-
-Also note that some IRC nicknames or channels may contain characters that are
-not allowed in the local part of a JID (for example '@'). If you need to send a
-message to a nick containing such a character, you can use a jid like
-``%irc.example.com@biboumi.example.com/AnnoyingNickn@me``, because the JID
-``AnnoyingNickn@me%irc.example.com@biboumi.example.com`` would not work.
-And if you need to address a channel that contains such invalid characters, you
-have to use `jid-escaping <http://www.xmpp.org/extensions/xep-0106.html#escaping>`_,
-and replace each of these characters with their escaped version, for example to
-join the channel ``#b@byfoot``, you need to use the following JID:
-``#b\40byfoot%irc.example.com@biboumi.example.com``.
-
-
-Examples:
-
-* ``#foo%irc.example.com@biboumi.example.com`` is the #foo IRC channel, on the
- irc.example.com IRC server, and this is served by the biboumi instance on
- biboumi.example.com
-
-* ``toto%irc.example.com@biboumi.example.com`` is the IRC user named toto, or
- TotO, etc.
-
-* ``irc.example.com@biboumi.example.com`` is the IRC server irc.example.com.
-
-Note: Some JIDs are valid but make no sense in the context of
-biboumi:
-
-* ``#test%@biboumi.example.com``, or any other JID that does not contain an
- IRC server is invalid. Any message to that kind of JID will trigger an
- error, or will be ignored.
-
-If compiled with Libidn, an IRC channel participant has a bare JID
-representing the “hostname” provided by the IRC server. This JID can only
-be used to set IRC modes (for example to ban a user based on its IP), or to
-identify user. It cannot be used to contact that user using biboumi.
-
-Join an IRC channel
--------------------
-
-To join an IRC channel ``#foo`` on the IRC server ``irc.example.com``,
-join the XMPP MUC ``#foo%irc.example.com@biboumi.example.com``.
-
-Connect to an IRC server
-------------------------
-
-The connection to the IRC server is automatically made when the user tries
-to join any channel on that IRC server. The connection is closed whenever
-the last channel on that server is left by the user.
-
-Roster
-------
-
-You can add some JIDs provided by biboumi into your own roster, to receive
-presence from them. Biboumi will always automatically accept your requests.
-
-Biboumi’s JID
--------------
-
-By adding the component JID into your roster, the user will receive an available
-presence whenever it is started, and an unavailable presence whenever it is being
-shutdown. This is useful to quickly view if that biboumi instance is started or
-not.
-
-IRC server JID
---------------
-
-These presence will appear online in the user’s roster whenever they are
-connected to that IRC server (see `Connect to an IRC server`_ for more
-details). This is useful to keep track of which server an user is connected
-to: this is sometimes hard to remember, when they have many clients, or if
-they are using persistent channels.
-
-Channel messages
-----------------
-
-On XMPP, unlike on IRC, the displayed order of the messages is the same for
-all participants of a MUC. Biboumi can not however provide this feature, as
-it cannot know whether the IRC server has received and forwarded the
-messages to other users. This means that the order of the messages
-displayed in your XMPP client may not be the same as the order on other
-IRC users’.
-
-History
--------
-
-Public channel messages are saved into archives, inside the database, unless
-the `record_history` option is set to false by that user (see `Ad-hoc commands`_).
-Private messages (messages that are sent directly to a nickname, not a
-channel) are never stored in the database.
-
-A channel history can be retrieved by using `Message archive management (MAM)
-<https://xmpp.org/extensions/xep-0313.htm>`_ on the channel JID. The results
-can be filtered by start and end dates.
-
-When a channel is joined, if the client doesn’t specify any limit, biboumi
-sends the `max_history_length` last messages found in the database as the
-MUC history. If a client wants to only use MAM for the archives (because
-it’s more convenient and powerful), it should request to receive no
-history by using an attribute maxchars='0' or maxstanzas='0' as defined in
-XEP 0045, and do a proper MAM request instead.
-
-Note: the maxchars attribute is ignored unless its value is exactly 0.
-Supporting it properly would be very hard and would introduce a lot of
-complexity for almost no benefit.
-
-For a given channel, each user has her or his own archive. The content of
-the archives are never shared, and thus a user can not use someone else’s
-archive to get the messages that they didn’t receive when they were offline.
-Although this feature would be very convenient, this would introduce a very
-important privacy issue: for example if a biboumi gateway is used by two
-users, by querying the archive one user would be able to know whether or not
-the other user was in a room at a given time.
-
-
-List channels
--------------
-
-You can list the IRC channels on a given IRC server by sending an XMPP disco
-items request on the IRC server JID. The number of channels on some servers
-is huge so the result stanza may be very big, unless your client supports
-result set management (XEP 0059)
-
-Nicknames
----------
-
-On IRC, nicknames are server-wide. This means that one user only has one
-single nickname at one given time on all the channels of a server. This is
-different from XMPP where a user can have a different nick on each MUC,
-even if these MUCs are on the same server.
-
-This means that the nick you choose when joining your first IRC channel on a
-given IRC server will be your nickname in all other channels that you join
-on that same IRC server.
-If you explicitely change your nickname on one channel, your nickname will
-be changed on all channels on the same server as well.
-Joining a new channel with a different nick, however, will not change your
-nick. The provided nick will be ignored, in order to avoid changing your
-nick on the whole server by mistake. If you want to have a different
-nickname in the channel you’re going to join, you need to do it explicitly
-with the NICK command before joining the channel.
-
-Private messages
-----------------
-
-Private messages are handled differently on IRC and on XMPP. On IRC, you
-talk directly to one server-user: toto on the channel #foo is the same user
-as toto on the channel #bar (as long as these two channels are on the same
-IRC server). By default you will receive private messages from the “global”
-user (aka nickname%irc.example.com@biboumi.example.com), unless you
-previously sent a message to an in-room participant (something like
-\#test%irc.example.com@biboumi.example.com/nickname), in which case future
-messages from that same user will be received from that same “in-room” JID.
-
-Notices
--------
-
-Notices are received exactly like private messages. It is not possible to
-send a notice.
-
-Topic
------
-
-The topic can be set and retrieved seemlessly. The unique difference is that
-if an XMPP user tries to set a multiline topic, every line return (\\n) will
-be replaced by a space, because the IRC server wouldn’t accept it.
-
-Invitations
------------
-
-If the invited JID is a user JID served by this biboumi instance, it will forward the
-invitation to the target nick, over IRC.
-Otherwise, the mediated instance will directly be sent to the invited JID, over XMPP.
-
-Example: if the user wishes to invite the IRC user “FooBar” into a room, they can
-invite one of the following “JIDs” (one of them is not a JID, actually):
-
-- foobar%anything@biboumi.example.com
-- anything@biboumi.example.com/FooBar
-- FooBar
-
-(Note that the “anything” parts are simply ignored because they carry no
-additional meaning for biboumi: we already know which IRC server is targeted
-using the JID of the target channel.)
-
-Otherwise, any valid JID can be used, to invite any XMPP user.
-
-Kicks and bans
---------------
-
-Kicks are transparently translated from one protocol to another. However
-banning an XMPP participant has no effect. To ban an user you need to set a
-mode +b on that user nick or host (see `IRC modes`_) and then kick it.
-
-Encoding
---------
-
-On XMPP, the encoding is always ``UTF-8``, whereas on IRC the encoding of
-each message can be anything.
-
-This means that biboumi has to convert everything coming from IRC into UTF-8
-without knowing the encoding of the received messages. To do so, it checks
-if each message is UTF-8 valid, if not it tries to convert from
-``iso_8859-1`` (because this appears to be the most common case, at least
-on the channels I visit) to ``UTF-8``. If that conversion fails at some
-point, a placeholder character ``'�'`` is inserted to indicate this
-decoding error.
-
-Messages are always sent in UTF-8 over IRC, no conversion is done in that
-direction.
-
-IRC modes
----------
-
-One feature that doesn’t exist on XMPP but does on IRC is the ``modes``.
-Although some of these modes have a correspondance in the XMPP world (for
-example the ``+o`` mode on a user corresponds to the ``moderator`` role in
-XMPP), it is impossible to map all these modes to an XMPP feature. To
-circumvent this problem, biboumi provides a raw notification when modes are
-changed, and lets the user change the modes directly.
-
-To change modes, simply send a message starting with “``/mode``” followed by
-the modes and the arguments you want to send to the IRC server. For example
-“/mode +aho louiz”. Note that your XMPP client may interprete messages
-begining with “/” like a command. To actually send a message starting with
-a slash, you may need to start your message with “//mode” or “/say /mode”,
-depending on your client.
-
-When a mode is changed, the user is notified by a message coming from the
-MUC bare JID, looking like “Mode #foo [+ov] [toto tutu]”. In addition, if
-the mode change can be translated to an XMPP feature, the user will be
-notified of this XMPP event as well. For example if a mode “+o toto” is
-received, then toto’s role will be changed to moderator. The mapping
-between IRC modes and XMPP features is as follow:
-
-``+q``
- Sets the participant’s role to ``moderator`` and its affiliation to ``owner``.
-
-``+a``
- Sets the participant’s role to ``moderator`` and its affiliation to ``owner``.
-
-``+o``
- Sets the participant’s role to ``moderator`` and its affiliation to ``admin``.
-
-``+h``
- Sets the participant’s role to ``moderator`` and its affiliation to ``member``.
-
-``+v``
- Sets the participant’s role to ``participant`` and its affiliation to ``member``.
-
-Similarly, when a biboumi user changes some participant's affiliation or role, biboumi translates that in an IRC mode change.
-
-Affiliation set to ``none``
- Sets mode to -vhoaq
-
-Affiliation set to ``member``
- Sets mode to +v-hoaq
-
-Role set to ``moderator``
- Sets mode to +h-oaq
-
-Affiliation set to ``admin``
- Sets mode to +o-aq
-
-Affiliation set to ``owner``
- Sets mode to +a-q
-
-Ad-hoc commands
----------------
-
-Biboumi supports a few ad-hoc commands, as described in the XEP 0050.
-Different ad-hoc commands are available for each JID type.
-
-On the gateway itself (e.g on the JID biboumi.example.com):
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-- ping: Just respond “pong”
-
-- hello: Provide a form, where the user enters their name, and biboumi
- responds with a nice greeting.
-
-- disconnect-user: Only available to the administrator. The user provides
- a list of JIDs, and a quit message. All the selected users are
- disconnected from all the IRC servers to which they were connected,
- using the provided quit message. Sending SIGINT to biboumi is equivalent
- to using this command by selecting all the connected JIDs and using the
- “Gateway shutdown” quit message, except that biboumi does not exit when
- using this ad-hoc command.
-
-- disconnect-from-irc-servers: Disconnect a single user from one or more
- IRC server. The user is immediately disconnected by closing the socket,
- no message is sent to the IRC server, but the user is of course notified
- with an XMPP message. The administrator can disconnect any user, while
- the other users can only disconnect themselves.
-
-- configure: Lets each user configure some options that applies globally.
- The provided configuration form contains these fields:
- * Record History: whether or not history messages should be saved in
- the database.
- * Max history length: The maximum number of lines in the history
- that the server is allowed to send when joining a channel.
-
- * Persistent: Overrides the value specified in each individual channel.
- If this option is set to true, all channels are persistent, whether
- or not their specific value is true or false. This option is true by
- default for everyone if the `persistent_by_default` configuration
- option is true, otherwise it’s false. See below for more details on
- what a persistent channel is. This value is
-
-On a server JID (e.g on the JID chat.freenode.org@biboumi.example.com)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-- configure: Lets each user configure some options that applies to the
- concerned IRC server. The provided configuration form contains these
- fields:
-
- * Address: This address (IPv4, IPv6 or hostname) will be used, when
- biboumi connects to this server. This is a very handy way to have a
- custom name for a network, and be able to edit the address to use
- if one endpoint for that server is dead, but continue using the same
- JID. For example, a user could configure the server
- “freenode@biboumi.example.com”, set “chat.freenode.net” in its
- “Address” field, and then they would be able to use “freenode” as
- the network name forever: if “chat.freenode.net” breaks for some
- reason, it can be changed to “irc.freenode.org” instead, and the user
- would not need to change all their bookmarks and settings.
- * Realname: The customized “real name” as it will appear on the
- user’s whois. This option is not available if biboumi is configured
- with realname_customization to false.
- * Username: The “user” part in your `user@host`. This option is not
- available if biboumi is configured with realname_customization to
- false.
- * In encoding: The incoming encoding. Any received message that is not
- proper UTF-8 will be converted will be converted from the configured
- In encoding into UTF-8. If the conversion fails at some point, some
- characters will be replaced by the placeholders.
- * Out encoding: Currently ignored.
- * After-connection IRC commands: Raw IRC commands that will be sent
- one by one to the server immediately after the connection has been
- successful. It can for example be used to identify yourself using
- NickServ, with a command like this: `PRIVMSG NickServ :identify
- PASSWORD`.
- * Ports: The list of TCP ports to use when connecting to this IRC server.
- This list will be tried in sequence, until the connection succeeds for
- one of them. The connection made on these ports will not use TLS, the
- communication will be insecure. The default list contains 6697 and 6670.
- * TLS ports: A second list of ports to try when connecting to the IRC
- server. The only difference is that TLS will be used if the connection
- is established on one of these ports. All the ports in this list will
- be tried before using the other plain-text ports list. To entirely
- disable any non-TLS connection, just remove all the values from the
- “normal” ports list. The default list contains 6697.
- * Verify certificate: If set to true (the default value), when connecting
- on a TLS port, the connection will be aborted if the certificate is
- not valid (for example if it’s not signed by a known authority, or if
- the domain name doesn’t match, etc). Set it to false if you want to
- connect on a server with a self-signed certificate.
- * SHA-1 fingerprint of the TLS certificate to trust: if you know the hash
- of the certificate that the server is supposed to use, and you only want
- to accept this one, set its SHA-1 hash in this field.
- * Nickname: A nickname that will be used instead of the nickname provided
- in the initial presence sent to join a channel. This can be used if the
- user always wants to have the same nickname on a given server, and not
- have to bother with setting that nick in all the bookmarks on that
- server. The nickname can still manually be changed with a standard nick
- change presence.
- * Server password: A password that will be sent just after the connection,
- in a PASS command. This is usually used in private servers, where you’re
- only allowed to connect if you have the password. Note that, although
- this is NOT a password that will be sent to NickServ (or some author
- authentication service), some server (notably Freenode) use it as if it
- was sent to NickServ to identify your nickname.
-
-- get-irc-connection-info: Returns some information about the IRC server,
- for the executing user. It lets the user know if they are connected to
- this server, from what port, with or without TLS, and it gives the list
- of joined IRC channel, with a detailed list of which resource is in which
- channel.
-
-On a channel JID (e.g on the JID #test%chat.freenode.org@biboumi.example.com)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-- configure: Lets each user configure some options that applies to the
- concerned IRC channel. Some of these options, if not configured for a
- specific channel, defaults to the value configured at the IRC server
- level. For example the encoding can be specified for both the channel
- and the server. If an encoding is not specified for a channel, the
- encoding configured in the server applies. The provided configuration
- form contains these fields:
- * In encoding: see the option with the same name in the server configuration
- form.
- * Out encoding: Currently ignored.
- * Persistent: If set to true, biboumi will stay in this channel even when
- all the XMPP resources have left the room. I.e. it will not send a PART
- command, and will stay idle in the channel until the connection is
- forcibly closed. If a resource comes back in the room again, and if
- the archiving of messages is enabled for this room, the client will
- receive the messages that where sent in this channel. This option can be
- used to make biboumi act as an IRC bouncer.
- * Record History: whether or not history messages should be saved in
- the database, for this specific channel. If the value is “unset” (the
- default), then the value configured globally is used. This option is there,
- for example, to be able to enable history recording globally while disabling
- it for a few specific “private” channels.
-
-Raw IRC messages
-----------------
-
-Biboumi tries to support as many IRC features as possible, but doesn’t
-handle everything yet (or ever). In order to let the user send any
-arbitrary IRC message, biboumi forwards any XMPP message received on an IRC
-Server JID (see `Addressing`_) as a raw command to that IRC server.
-
-For example, to WHOIS the user Foo on the server irc.example.com, a user can
-send the message “WHOIS Foo” to ``irc.example.com@biboumi.example.com``.
-
-The message will be forwarded as is, without any modification appart from
-adding ``\r\n`` at the end (to make it a valid IRC message). You need to
-have a little bit of understanding of the IRC protocol to use this feature.
-
-Security
-========
-
-The connection to the XMPP server can only be made on localhost. The
-XMPP server is not supposed to accept non-local connections from components.
-Thus, encryption is not used to connect to the local XMPP server because it
-is useless.
-
-If compiled with the Botan library, biboumi can use TLS when communicating
-with the IRC servers. It will first try ports 6697 and 6670 and use TLS if
-it succeeds, if connection fails on both these ports, the connection is
-established on port 6667 without any encryption.
-
-Biboumi does not check if the received JIDs are properly formatted using
-nodeprep. This must be done by the XMPP server to which biboumi is directly
-connected.
-
-Note if you use a biboumi that you have no control on: remember that the
-administrator of the gateway you use is able to view all your IRC
-conversations, whether you’re using encryption or not. This is exactly as
-if you were running your IRC client on someone else’s server. Only use
-biboumi if you trust its administrator (or, better, if you are the
-administrator) or if you don’t intend to have any private conversation.
-
-Biboumi does not provide a way to ban users from connecting to it, has no
-protection against flood or any sort of abuse that your users may cause on
-the IRC servers. Some XMPP server however offer the possibility to restrict
-what JID can access a gateway. Use that feature if you wish to grant access
-to your biboumi instance only to a list of trusted users.
-
diff --git a/doc/conf.py b/doc/conf.py
new file mode 100644
index 0000000..504c15b
--- /dev/null
+++ b/doc/conf.py
@@ -0,0 +1,146 @@
+# -*- coding: utf-8 -*-
+#
+# Configuration file for the Sphinx documentation builder.
+#
+# This file does only contain a selection of the most common options. For a
+# full list see the documentation:
+# http://www.sphinx-doc.org/en/master/config
+
+# -- Path setup --------------------------------------------------------------
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#
+# import os
+# import sys
+# sys.path.insert(0, os.path.abspath('.'))
+
+
+# -- Project information -----------------------------------------------------
+
+project = 'biboumi'
+copyright = '2018, Florent Le Coz'
+author = 'Florent Le Coz'
+
+# The short X.Y version
+version = '8.4'
+# The full version, including alpha/beta/rc tags
+release = '8.4'
+
+
+# -- General configuration ---------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#
+# needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+ 'sphinx.ext.coverage',
+ 'sphinx.ext.autosectionlabel',
+]
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix(es) of source filenames.
+# You can specify multiple suffix as a list of string:
+#
+# source_suffix = ['.rst', '.md']
+source_suffix = '.rst'
+
+master_doc = 'index'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#
+# This is also used if you do content translation via gettext catalogs.
+# Usually you set "language" from the command line for these cases.
+language = None
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+# This pattern also affects html_static_path and html_extra_path .
+exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+
+# -- Options for HTML output -------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+#
+html_theme = 'sphinx_rtd_theme'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+#
+# html_theme_options = {}
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+#html_static_path = ['_static']
+
+# Custom sidebar templates, must be a dictionary that maps document names
+# to template names.
+#
+# The default sidebars (for documents that don't match any pattern) are
+# defined by theme itself. Builtin themes are using these templates by
+# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
+# 'searchbox.html']``.
+#
+# html_sidebars = {}
+
+
+# -- Options for HTMLHelp output ---------------------------------------------
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'biboumidoc'
+
+
+# -- Options for LaTeX output ------------------------------------------------
+
+latex_elements = {
+ # The paper size ('letterpaper' or 'a4paper').
+ #
+ # 'papersize': 'letterpaper',
+
+ # The font size ('10pt', '11pt' or '12pt').
+ #
+ # 'pointsize': '10pt',
+
+ # Additional stuff for the LaTeX preamble.
+ #
+ # 'preamble': '',
+
+ # Latex figure (float) alignment
+ #
+ # 'figure_align': 'htbp',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+# author, documentclass [howto, manual, or own class]).
+latex_documents = [
+ (master_doc, 'biboumi.tex', 'biboumi Documentation',
+ author, 'manual'),
+]
+
+
+# -- Options for manual page output ------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+ ('man_index', 'biboumi', 'biboumi Documentation',
+ [author], 1)
+]
+
+# -- Extension configuration -------------------------------------------------
diff --git a/doc/contributing.rst b/doc/contributing.rst
new file mode 100644
index 0000000..8f01c82
--- /dev/null
+++ b/doc/contributing.rst
@@ -0,0 +1,84 @@
+#######################
+Contributing to biboumi
+#######################
+
+Biboumi’s main workplace is at https://lab.louiz.org/louiz/biboumi
+
+The repository is also mirrored on other websites, for example on github,
+but that’s mainly for the convenience of users.
+
+Before doing anything, you can come on the `XMPP chatroom`_ to discuss your
+changes, issues or ideas.
+
+
+Bug reports, feature requests
+-----------------------------
+
+To open a bug report, or a feature request, please do so on `our gitlab’s
+bug tracker`_.
+
+If the bug you’re reporting is about a bad behaviour of biboumi when some XMPP
+or IRC events occur, please try to reproduce the issue with a biboumi running
+in log_level=0, and include the relevant logs in your bug report.
+
+If the issue you’re reporting may have security implications, please
+select the “confidential” flag in your bug report. This includes, but is not limited to:
+
+- disclosure of private data that was supposed to be encrypted using TLS
+- denial of service (crash, infinite loop, etc) that can be caused by any
+ user
+
+
+Code
+----
+
+To contribute code, you can do so using git: commit your changes on any
+publicly available git repository and communicate us its address. This can
+be done with a `gitlab merge request`_, or a `github pull request`_ or just
+by sending a message into the `XMPP chatroom`_.
+
+It is suggested that you use gitlab’s merge requests: this will
+automatically run our continuous integration tests.
+
+It is also recommended to add some unit or end-to-end tests for the proposed
+changes.
+
+
+Tests
+-----
+
+There are two test suites for biboumi:
+
+- unit tests that can be run simply using `make check`.
+ These tests use the Catch2 test framework, are written in pure C++
+ and they should always succeed, in all possible build configuration.
+
+- a more complex end-to-end test suite. This test suite is written in python3,
+ uses a specific IRC server (`charybdis`_), and only tests the most complete
+ biboumi configuration (when all dependencies are used).
+ Read more about these tests in the specific documentation TODO.
+
+All these tests automatically run with various configurations, on various
+platforms, using gitlab CI.
+
+
+Coding style
+------------
+Please try to follow the existing style:
+
+- Use only spaces, not tabs.
+- Curly brackets are on their own lines.
+- Use this-> everywhere it’s possible.
+- Don’t start class attributes with “m\_” or similar.
+- Type names are in PascalCase.
+- Everything else is in snake_case.
+
+
+.. _our gitlab’s bug tracker: https://lab.louiz.org/louiz/biboumi/issues/new
+.. _gitlab merge request: https://lab.louiz.org/louiz/biboumi/merge_requests/new
+.. _github pull request: https://github.com/louiz/biboumi/pulls
+.. _XMPP chatroom: xmpp:biboumi@muc.poez.io
+.. _Dockerfile.base: docker/biboumi-test/fedora/Dockerfile.base
+.. _Dockerfile: docker/biboumi-test/fedora/Dockerfile
+.. _charybdis: https://github.com/charybdis-ircd/charybdis
+.. _the __main__.py file: tests/end_to_end/__main__.py
diff --git a/doc/developer.rst b/doc/developer.rst
new file mode 100644
index 0000000..b3ef158
--- /dev/null
+++ b/doc/developer.rst
@@ -0,0 +1,302 @@
+########################
+Developer documentation
+########################
+
+End-to-end test suite
+---------------------
+
+A powerful test suite has been developped to test biboumi’s behaviour in
+many scenarios. Its goal is to simulate a real-world usage of biboumi,
+including its interactions with a real IRC server an a real XMPP client.
+
+An IRC server is started, with a specific version and configuration, then,
+for every scenario that we want to test:
+
+- Biboumi is started, with a specific configuration
+- An XMPP “client” starts, communicates with biboumi and checks that
+ biboumi responds in the expected way.
+
+The XMPP client is actually not a real client, it’s a python script that
+uses the slixmpp library to imitate an XMPP server that would transmit the
+stanzas of one client to its component (biboumi). In real life, the
+communication to biboumi is done between the XMPP server and biboumi, but
+since the server just forwards the messages that clients send unmodified,
+we’ll call that “the clients”.
+
+A scenario is a list of functions that will be executed one by one, to
+verify the behaviour of one specific feature. Ideally, they should be
+short and test one specific aspect.
+
+Run the test suite locally
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Since this requires a lot of dependencies (an IRC server with some TLS
+certificate, slixmpp, many libraries…), it might be cumbersome to get
+everything on your machine to be able to run them.
+
+The simplest solution (as long as you have docker installed and properly
+configured to be able to run as your developer user… It’s as simple as
+“dnf install docker” and “chmod o+rw /var/run/docker.sock”, but that’s not
+recommended, because this lets anybody on the system use docker, and
+docker is very unsecure) is to follow these instructions:
+
+.. code-block:: bash
+ :caption: Start a docker container with everything installed
+
+ docker run --name biboumi-e2e -v /home/louiz/biboumi/:/home/tester/biboumi \
+ --add-host="irc.localhost:127.0.0.1" \
+ --add-host="biboumi.localhost:127.0.0.1" \
+ --rm -it docker.louiz.org/louiz/biboumi/test-alpine \
+ /bin/bash
+
+This creates a container where every dependency is already installed. We
+mount your working directory inside the container: be sure to modify the
+first path `/home/louiz/biboumi` with your own. The hosts that we add are
+needed for the test suite to properly work.
+
+You can use the test-fedora or test-debian images instead of test-alpine
+if you want, but it should not change anything (even if your host machine
+uses debian or fedora), alpine is just the lighter one.
+
+.. note::
+
+ This container should stay alive as long as you want to run the test
+ suite. For example if you want to run it many times until your code is
+ fine and all tests pass, just leave that shell somewhere without
+ touching it.
+
+Then, from an other shell (do NOT run that inside the container we just
+created):
+
+.. code-block:: bash
+ :caption: Configure and build biboumi from inside the container
+
+ docker exec biboumi-e2e sh -c "cd biboumi && mkdir docker-build/ && cd docker-build/ && cmake .."
+
+This is needed (only once), because if you configure it from your host
+machine, then the paths generated by cmake will be all wrong when you try
+to compile from inside the container and nothing will work.
+
+.. code-block:: bash
+ :caption: Re-compile and run the test suite inside the container
+
+ docker exec biboumi-e2e sh -c "cd biboumi/docker-build && make e2e"
+
+This should now build everything correctly, and run the test suite. If you
+want to re-run it again after you edited something in your source tree,
+just run this last command again. You don’t need to touch anything inside
+the container again.
+
+When you’re done, just close the shell we opened with the first command.
+
+Available functions
+~~~~~~~~~~~~~~~~~~~
+
+.. py:function:: send_stanza(str)
+
+ sends one stanza to biboumi. The stanza is written entirely
+ as a string (with a few automatic replacements). The “from” and “to”
+ values have to be specified everytime, because each stanza can come from
+ different clients and be directed to any IRC server/channel
+
+ .. code-block:: python
+
+ send_stanza("<message from='{jid_one}/{resource_one}' to='#foo@{biboumi_host}' type='groupchat'><body>coucou</body></message>"),
+
+.. py:function:: expect_stanza(xpath[, …])
+
+ Waits for a stanza to be received by biboumi, and checks that this
+ stanza matches one or more xpath. If the stanza doesn’t match all the
+ given xpaths, then the scenario ends and we report that as an error.
+
+ .. code-block:: python
+
+ expect_stanza("/message[@from='#foo@{biboumi_host}/{nick_one}']/body[text()='coucou']",
+ "/message/delay:delay[@from='#foo@{biboumi_host}']"),
+
+ This waits for exactly 1 stanza, that is compared against 2 xpaths. Here
+ we check that it is a message, that it has the proper `from` value, the
+ correct body, and a <delay/>.
+
+.. py:function:: expect_unordered(list_of_xpaths[, list_of_xpaths, …])
+
+ we wait for more than one stanzas, that could be received in any order.
+ For example, in certain scenario, we wait for two presence stanzas, but
+ it’s perfectly valid to receive them in any order (one is for one
+ client, the other one for an other client). To do that, we pass multiple
+ lists of xpath. Each list can contain one or more xpath (just like
+ `expect_stanza`). When a stanza is received, it is compared with all the
+ xpaths of the first list. If it doesn’t match, it is compared with the
+ xpaths of the second list, and so on. If nothing matchs, it’s an error
+ and we stop this scenario. If the stanza matches with one of the xpath
+ lists, we remove that list, and we wait for the next stanza, until there
+ are no more xpaths.
+
+ .. code-block:: python
+
+ expect_unordered(
+ [
+ "/presence[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_two}/{resource_one}'][@type='unavailable']/muc_user:x/muc_user:item[@nick='Bernard']",
+ "/presence/muc_user:x/muc_user:status[@code='303']",
+ ],
+ [
+ "/presence[@from='#foo%{irc_server_one}/{nick_three}'][@to='{jid_two}/{resource_one}']",
+ ],
+ [
+ "/presence[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='unavailable']/muc_user:x/muc_user:item[@nick='Bernard']",
+ "/presence/muc_user:x/muc_user:status[@code='303']",
+ "/presence/muc_user:x/muc_user:status[@code='110']",
+ ],
+ [
+ "/presence[@from='#foo%{irc_server_one}/{nick_three}'][@to='{jid_one}/{resource_one}']",
+ "/presence/muc_user:x/muc_user:status[@code='110']",
+ ],
+ ),
+
+ This will wait for 4 stanzas that could be received in any order.
+
+To avoid many repetitions between each tests, some helpful sequences are
+available, `sequences.connection(…)` and `sequences.connection_tls(…)`.
+They do all the steps that are needed (send and receive stanzas) to
+connect to the component, or an IRC server.
+
+It’s also possible to reuse one simple scenario into an other scenario.
+The most notable example is to start your own scenario with
+`scenarios.simple_channel_join.scenario`, if you need your client to be in
+a channel before you can start your actual scenario. For example if you
+want to test the behaviour of a topic change, you need to first join a
+channel. Since this is a very common patern, it’s simpler to just included
+this very basic scenario at the start of your own scenarios, instead of
+copy pasting the same thing over and over.
+
+Examples of a scenario
+~~~~~~~~~~~~~~~~~~~~~~
+
+First example
+^^^^^^^^^^^^^
+
+Here we’ll describe how to write your own scenario, from scratch. For this, we will take an existing scenario and explain how it was written, line by line.
+
+See for example the scenario tests/end_to_end/scenarios/self_ping_on_real_channel.py
+
+.. code-block:: python
+
+ from scenarios import *
+
+All the tests should start with this import. It imports the file
+tests/end_to_end/scenarios/__init__.py This make all the functions
+available (send_stanza, expect_stanza…) available, as well as some very
+common scenarios that you often need to re-use.
+
+.. code-block:: python
+
+ scenario = (
+ # …
+ )
+
+This is the only required element of your scenario. This object is a tuple of function calls OR other scenarios.
+
+.. code-block:: python
+
+ scenarios.simple_channel_join.scenario,
+
+The first line of our scenario is actually including an other existing
+scenario. You can find it at
+tests/end_to_end/scenarios/simple_channel_join.py As its name shows, it’s
+very basic: one client {jid_one}/{resource_one} just joins one room
+#foo%{irc_server_one} with the nick {nick_one}.
+
+Since we want to test the behaviour of a ping to ourself when we are in a
+room, we just join this room without repeating everything.
+
+It is possible to directly insert a scenario inside our scenario without
+having to extract all the steps: the test suite is smart enough to detect
+that and extract the inner steps automatically.
+
+.. code-block:: python
+
+ # Send a ping to ourself
+ send_stanza("<iq type='get' from='{jid_one}/{resource_one}' id='first_ping' to='#foo%{irc_server_one}/{nick_one}'><ping xmlns='urn:xmpp:ping' /></iq>"),
+ expect_stanza("/iq[@from='#foo%{irc_server_one}/{nick_one}'][@type='result'][@to='{jid_one}/{resource_one}'][@id='first_ping']"),
+
+Here we simple send an iq stanza, properly formatted, using the same JIDs
+{jid_one}/{resource_one} and #foo%{irc_server_one}/{nick_one} to ping
+ourself in the room. We them immediately expect one stanza to be received,
+that is the response to our ping. It only contains one single xpath
+because everything we need to check can be expressed in one line.
+
+Note that it is recommended to explain all the steps of your scenario with
+comments. This helps understand what is being tested, and why, without
+having to analyze all the stanza individually.
+
+.. code-block:: python
+
+ # Now join the same room, from the same bare JID, behind the same nick
+ send_stanza("<presence from='{jid_one}/{resource_two}' to='#foo%{irc_server_one}/{nick_one}' />"),
+ expect_stanza("/presence[@to='{jid_one}/{resource_two}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']",
+ "/presence/muc_user:x/muc_user:status[@code='110']"),
+
+ expect_stanza("/message[@from='#foo%{irc_server_one}'][@type='groupchat'][@to='{jid_one}/{resource_two}']/subject[not(text())]"),
+
+Here we send a presence stanza to join the same channel with an other
+resource (note the {resource_two}). As a result, we expect two stanzas:
+The first stanza (our self-presence) is checked against two xpaths, and
+the second stanza (the empty subject of the room) against only one.
+
+.. code-block:: python
+
+ # And re-send a self ping
+ send_stanza("<iq type='get' from='{jid_one}/{resource_one}' id='second_ping' to='#foo%{irc_server_one}/{nick_one}'><ping xmlns='urn:xmpp:ping' /></iq>"),
+ expect_stanza("/iq[@from='#foo%{irc_server_one}/{nick_one}'][@type='result'][@to='{jid_one}/{resource_one}'][@id='second_ping']"),
+ ## And re-do exactly the same thing, just change the resource initiating the self ping
+ send_stanza("<iq type='get' from='{jid_one}/{resource_two}' id='third_ping' to='#foo%{irc_server_one}/{nick_one}'><ping xmlns='urn:xmpp:ping' /></iq>"),
+ expect_stanza("/iq[@from='#foo%{irc_server_one}/{nick_one}'][@type='result'][@to='{jid_one}/{resource_two}'][@id='third_ping']"),
+
+And finally, we test a second ping, and check that the behaviour is correct that we now have two resources in that channel.
+
+Second example
+^^^^^^^^^^^^^^
+
+Sometimes we want to do more with the received stanzas. For example we
+need to extract some values from the received stanzas, to reuse them in
+future stanzas we send. The most obvious example is iq IDs, that we need
+to extract, to reuse them in our response.
+
+Let’s use for example the tests/end_to_end/scenarios/execute_incomplete_hello_adhoc_command.py scenario:
+
+.. code-block:: python
+
+ from scenarios import *
+
+ scenario = (
+ send_stanza("<iq type='set' id='hello-command1' from='{jid_one}/{resource_one}' to='{biboumi_host}'><command xmlns='http://jabber.org/protocol/commands' node='hello' action='execute' /></iq>"),
+ expect_stanza("/iq[@type='result']/commands:command[@node='hello'][@sessionid][@status='executing']",
+ "/iq/commands:command/commands:actions/commands:complete",
+ after = save_value("sessionid", extract_attribute("/iq[@type='result']/commands:command[@node='hello']", "sessionid"))
+ ),
+
+Here is where the magic happens: as an additional argument to the
+expect_stanza function, we pass an other function (callback) with the
+“after=” keyword argument. This “after” callback gets called once the
+expected stanza has been received and validated. Here we use
+`save_value(key, value)`. This function just saves a value in our global
+values that can be used with “send_stanza”, associated with the given
+“key”. For example if you do `save_value("something_important", "blah")`
+then you can use `{something_important}` in any future stanza that you
+send and it will be replaced with “blah”.
+
+But this is only useful if we can save some value that we extract from the
+stanza. That’s where `extract_attribute(xpath, attribute_name)` comes into
+play. As the first argument, you pass an xpath corresponding to one
+specific node of the XML that is received, and the second argument is just
+the name of the attribute whose value you want.
+
+Here, we extract the value of the “sessionid=” in the node `<iq
+type='result'><commands:command node='hello' sessionid='…' /></iq>`, and
+we save that value, globally, with the name “sessionid”.
+
+.. code-block:: python
+
+ send_stanza("<iq type='set' id='hello-command2' from='{jid_one}/{resource_one}' to='{biboumi_host}'><command xmlns='http://jabber.org/protocol/commands' node='hello' sessionid='{sessionid}' action='complete'><x xmlns='jabber:x:data' type='submit'></x></command></iq>"),
+
+Here we send a second iq, to continue our ad-hoc command, and we use {sessionid} to indicate that we are continuing the session we started before.
diff --git a/doc/example.conf b/doc/example.conf
deleted file mode 100644
index 42631b2..0000000
--- a/doc/example.conf
+++ /dev/null
@@ -1,14 +0,0 @@
-# This is an example configuration for the biboumi component.
-# It only contains the default values, and some example values for the
-# required fields (hostname and password).
-
-hostname=biboumi.example.com
-password=mypassword
-xmpp_server_ip=127.0.0.1
-port=5347
-admin=
-realname_customization=true
-realname_from_jid=false
-log_file=
-ca_file=
-outgoing_bind=
diff --git a/doc/index.rst b/doc/index.rst
new file mode 100644
index 0000000..819a3e5
--- /dev/null
+++ b/doc/index.rst
@@ -0,0 +1,24 @@
+.. biboumi documentation master file, created by
+ sphinx-quickstart on Mon Aug 27 19:50:26 2018.
+ You can adapt this file completely to your liking, but it should at least
+ contain the root `toctree` directive.
+
+Biboumi – XMPP gateway to IRC
+=============================
+
+Homepage: https://biboumi.louiz.org
+
+Forge: https://lab.louiz.org/louiz/biboumi
+
+Biboumi is an XMPP gateway that connects to IRC servers and translates
+between the two protocols. It can be used to access IRC channels using any
+XMPP client as if these channels were XMPP MUCs.
+
+.. toctree::
+ :maxdepth: 2
+
+ install
+ admin
+ user
+ contributing
+ developer
diff --git a/doc/install.rst b/doc/install.rst
new file mode 100644
index 0000000..685511d
--- /dev/null
+++ b/doc/install.rst
@@ -0,0 +1,194 @@
+Installation
+============
+
+The very short version:
+
+.. code-block:: sh
+
+ cmake . && make && ./biboumi
+
+If that didn’t work, read on.
+
+Dependencies
+------------
+
+Here’s the list of all the build and runtime dependencies. Because we
+strive to use the smallest number of dependencies possible, many of them
+are optional. That being said, you will have the best experience using
+biboumi by having all dependencies.
+
+Tools:
+~~~~~~
+
+- A C++14 compiler (clang >= 3.4 or gcc >= 5.0 for example)
+- CMake
+- sphinx (optional) to build the documentation
+
+Libraries:
+~~~~~~~~~~
+
+expat_
+ Used to parse XML from the XMPP server.
+
+libiconv_
+ Encoding from anything into UTF-8
+
+libuuid_
+ Generate unique IDs
+
+sqlite3_ or libpq_ (optional, but recommented)
+ Provides a way to store various options and messages archives in a
+ database. Each user of the gateway can store their own values (for
+ example their prefered port, or their IRC password). Without this
+ dependency, many interesting features are missing.
+
+libidn_ (optional, but recommended)
+ Provides the stringprep functionality. Without it, JIDs for IRC users are
+ not provided.
+
+udns_ (optional, but recommended)
+ Asynchronously resolve domain names. This offers better reactivity and
+ performances when connecting to a big number of IRC servers at the same
+ time.
+
+libbotan_ 2.x (optional, but recommended)
+ Provides TLS support. Without it, IRC connections are all made in
+ plain-text mode.
+
+gcrypt_ (mandatory only if botan is absent)
+ Provides the SHA-1 hash function, for the case where Botan is absent. It
+ does NOT provide any TLS or encryption feature.
+
+systemd_ (optional)
+ Provides the support for a systemd service of Type=notify. This is useful only
+ if you are packaging biboumi in a distribution with Systemd.
+
+Customize
+---------
+
+The basics
+~~~~~~~~~~
+
+Once you have all the dependencies you need, configure the build system
+using cmake. The cleanest way is to create a build directory, and run
+everything inside it:
+
+
+.. code-block:: sh
+
+ mkdir build/ && cd build/ && cmake ..
+
+Choosing the dependencies
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Without any option, cmake will look for all dependencies available on the
+system and use everything it finds. If a mandatory dependency is missing
+it will obviously stop and yield an error, however if an optional
+dependency is missing, it will just ignore it.
+
+To specify that you want or don’t want to use, you need to
+pass an option like this:
+
+.. code-block:: sh
+
+ cmake .. -DWITH_XXXX=1 -DWITHOUT_XXXX=1
+
+The `WITH_` prefix indicates that cmake should stop if that dependency can
+not be found, and the `WITHOUT_` prefix indicates that this dependency
+should not be used even if it is present on the system.
+
+The `XXXX` part needs to be replaced by one of the following: BOTAN,
+LIBIDN, SYSTEMD, DOC, UDNS, SQLITE3, POSTGRESQL.
+
+Other options
+~~~~~~~~~~~~~
+
+The default build type is "Debug", if you want to build a release version,
+set the CMAKE_BUILD_TYPE variable to "release", by running this command
+instead:
+
+.. code-block:: sh
+
+ cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr
+
+You can also configure many parameters of the build (like customize CFLAGS,
+the install path, choose the compiler, or enabling some options like the
+POLLER to use), using the ncurses interface of ccmake:
+
+.. code-block:: sh
+
+ ccmake ..
+
+In ccmake, first use 'c' to configure the build system, edit the values you
+need and finaly use 'g' to generate the Makefiles to build the system and
+quit ccmake.
+
+You can also configure these options using a -D command line flag.
+
+Biboumi also has a few advanced options that are useful only in very
+specific cases.
+
+- POLLER: lets you select the poller used by biboumi, at
+ compile-time. Possible values are:
+
+ - EPOLL: use the Linux-specific epoll(7). This is the default on Linux.
+ - POLL: use the standard poll(2). This is the default value on all non-Linux
+ platforms.
+
+- DEBUG_SQL_QUERIES: If set to ON, additional debug logging and timing
+ will be done for every SQL query that is executed. The default is OFF.
+ Please set it to ON if you intend to share your debug logs on the bug
+ trackers, if your issue affects the database.
+
+Example:
+
+.. code-block:: sh
+
+ cmake . -DCMAKE_BUILD_TYPE=release -DCMAKE_INSTALL_PREFIX=/usr -DWITH_BOTAN=1 -DWITHOUT_SYSTEMD=1
+
+This command will configure the project to build a release, with TLS enabled
+(using Botan) but without using Systemd (even if available on the system).
+
+
+Build
+-----
+
+Once you’ve configured everything using cmake, build the software:
+
+To build the biboumi binary, run:
+
+.. code-block:: sh
+
+ make
+
+
+Install
+-------
+
+And then, optionaly, Install the software system-wide
+
+.. code-block:: sh
+
+ make install
+
+This will install the biboumi binary, but also the man-page (if configured
+with it), the policy files, the systemd unit file, etc.
+
+
+Run
+---
+
+Finally, run the software using the `biboumi` binary. Read the documentation (the
+man page biboumi(1)) or the usage page.
+
+.. _expat: http://expat.sourceforge.net/
+.. _libiconv: http://www.gnu.org/software/libiconv/
+.. _libuuid: http://sourceforge.net/projects/libuuid/
+.. _libidn: http://www.gnu.org/software/libidn/
+.. _libbotan: http://botan.randombit.net/
+.. _udns: http://www.corpit.ru/mjt/udns.html
+.. _sqlite3: https://sqlite.org
+.. _systemd: https://www.freedesktop.org/wiki/Software/systemd/
+.. _biboumi.1.rst: doc/biboumi.1.rst
+.. _gcrypt: https://www.gnu.org/software/libgcrypt/
+.. _libpq: https://www.postgresql.org/docs/current/static/libpq.html
diff --git a/doc/man_index.rst b/doc/man_index.rst
new file mode 100644
index 0000000..3de981d
--- /dev/null
+++ b/doc/man_index.rst
@@ -0,0 +1,9 @@
+Biboumi's man page index
+========================
+
+.. toctree::
+ :maxdepth: 2
+ :caption: Contents:
+
+ synopsis
+ admin
diff --git a/doc/synopsis.rst b/doc/synopsis.rst
new file mode 100644
index 0000000..5b93a92
--- /dev/null
+++ b/doc/synopsis.rst
@@ -0,0 +1,4 @@
+Synopsis
+========
+
+biboumi [*config_filename*]
diff --git a/doc/user.rst b/doc/user.rst
new file mode 100644
index 0000000..505e3b9
--- /dev/null
+++ b/doc/user.rst
@@ -0,0 +1,513 @@
+######################
+End-user documentation
+######################
+
+Quick-start
+-----------
+
+When a user joins an IRC channel on an IRC server (see `Join an IRC
+channel`_), biboumi connects to the remote IRC server, sets the user’s nick
+as requested, and then tries to join the specified channel. If the same
+user subsequently tries to connect to an other channel on the same server,
+the same IRC connection is used. If, however, an other user wants to join
+an IRC channel on that same IRC server, biboumi opens a new connection to
+that server. Biboumi connects once to each IRC servner, for each user on it.
+
+Additionally, if one user is using more than one clients (with the same bare
+JID), they can join the same IRC channel (on the same server) behind one
+single nickname. Biboumi will forward all the messages (the channel ones and
+the private ones) and the presences to all the resources behind that nick.
+There is no need to have multiple nicknames and multiple connections to be
+able to take part in a conversation (or idle) in a channel from a mobile client
+while the desktop client is still connected, for example.
+
+.. note:: If you use a biboumi that you have no control on: remember that the
+ administrator of the gateway you use is able to view all your IRC
+ conversations, whether you’re using encryption or not. This is exactly as
+ if you were running your IRC client on someone else’s server. Only use
+ biboumi if you trust its administrator (or, better, if you are the
+ administrator) or if you don’t intend to have any private conversation.
+
+Addressing
+----------
+
+IRC entities are represented by XMPP JIDs. The domain part of the JID is
+the domain served by biboumi (the part after the `@`, biboumi.example.com in
+the examples), and the local part (the part before the `@`) depends on the
+concerned entity.
+
+IRC channels and IRC users have a local part formed like this:
+``name`` % ``irc_server``.
+
+``name`` can be a channel name or an user nickname. The distinction between
+the two is based on the first character: by default, if the name starts with
+``'#'`` or ``'&'`` (but this can be overridden by the server, using the
+ISUPPORT extension) then it’s a channel name, otherwise this is a nickname.
+
+There is two ways to address an IRC user, using a local part like this:
+``nickname`` % ``irc_server`` or by using the in-room address of the
+participant, like this:
+``channel_name`` % ``irc_server`` @ ``biboumi.example.com`` / ``Nickname``
+
+The second JID is available only to be compatible with XMPP clients when the
+user wants to send a private message to the participant ``Nickname`` in the
+room ``channel_name%irc_server@biboumi.example.com``.
+
+On XMPP, the node part of the JID can only be lowercase. On the other hand,
+IRC nicknames are case-insensitive, this means that the nicknames toto,
+Toto, tOtO and TOTO all represent the same IRC user. This means you can
+talk to the user toto, and this will work.
+
+Also note that some IRC nicknames or channels may contain characters that
+are not allowed in the local part of a JID (for example '@'). If you need
+to send a message to a nick containing such a character, you can use a jid
+like ``%irc.example.com@biboumi.example.com/AnnoyingNickn@me``, because
+the JID ``AnnoyingNickn@me%irc.example.com@biboumi.example.com`` would not
+work. This “weird” JID is just using the fact that you can send a private
+message through any room (even a room with an empty name) because, on IRC,
+a query does not go through any room at all, it’s just server-wide. So,
+sending a message to #doesnotexist%irc@biboumi/User is exactly the same as
+sending one to %irc@biboumi/User.
+
+And if you need to address a channel that contains such invalid characters, you
+have to use `jid-escaping <http://www.xmpp.org/extensions/xep-0106.html#escaping>`_,
+and replace each of these characters with their escaped version, for example to
+join the channel ``#b@byfoot``, you need to use the following JID:
+``#b\40byfoot%irc.example.com@biboumi.example.com``.
+
+
+Examples:
+
+* ``#foo%irc.example.com@biboumi.example.com`` is the #foo IRC channel, on the
+ irc.example.com IRC server, and this is served by the biboumi instance on
+ biboumi.example.com
+
+* ``toto%irc.example.com@biboumi.example.com`` is the IRC user named toto, or
+ TotO, etc.
+
+* ``irc.example.com@biboumi.example.com`` is the IRC server irc.example.com.
+
+Note: Some JIDs are valid but make no sense in the context of
+biboumi:
+
+* ``#test%@biboumi.example.com``, or any other JID that does not contain an
+ IRC server is invalid. Any message to that kind of JID will trigger an
+ error, or will be ignored.
+
+If compiled with Libidn, an IRC channel participant has a bare JID
+representing the “hostname” provided by the IRC server. This JID can only
+be used to set IRC modes (for example to ban a user based on its IP), or to
+identify user. It cannot be used to contact that user using biboumi.
+
+Join an IRC channel
+-------------------
+
+To join an IRC channel ``#foo`` on the IRC server ``irc.example.com``,
+join the XMPP MUC ``#foo%irc.example.com@biboumi.example.com``.
+
+Connect to an IRC server
+------------------------
+
+The connection to the IRC server is automatically made when the user tries
+to join any channel on that IRC server. The connection is closed whenever
+the last channel on that server is left by the user.
+
+Roster
+------
+
+You can add some JIDs provided by biboumi into your own roster, to receive
+presence from them. Biboumi will always automatically accept your requests.
+
+Biboumi’s JID
+~~~~~~~~~~~~~
+
+By adding the component JID into your roster, the user will receive an available
+presence whenever it is started, and an unavailable presence whenever it is being
+shutdown. This is useful to quickly view if that biboumi instance is started or
+not.
+
+IRC server JID
+~~~~~~~~~~~~~~
+
+These presence will appear online in the user’s roster whenever they are
+connected to that IRC server (see `Connect to an IRC server`_ for more
+details). This is useful to keep track of which server an user is connected
+to: this is sometimes hard to remember, when they have many clients, or if
+they are using persistent channels.
+
+Channel messages
+----------------
+
+On XMPP, unlike on IRC, the displayed order of the messages is the same for
+all participants of a MUC. Biboumi can not however provide this feature, as
+it cannot know whether the IRC server has received and forwarded the
+messages to other users. This means that the order of the messages
+displayed in your XMPP client may not be the same as the order on other
+IRC users’.
+
+History
+-------
+
+Public channel messages are saved into archives, inside the database,
+unless the `record_history` option is set to false by that user (see
+`Ad-hoc commands`_). Private messages (messages that are sent directly to
+a nickname, not a channel) are never stored in the database.
+
+A channel history can be retrieved by using `Message archive management
+(MAM) <https://xmpp.org/extensions/xep-0313.htm>`_ on the channel JID.
+The results can be filtered by start and end dates.
+
+When a channel is joined, if the client doesn’t specify any limit, biboumi
+sends the `max_history_length` last messages found in the database as the
+MUC history. If a client wants to only use MAM for the archives (because
+it’s more convenient and powerful), it should request to receive no
+history by using an attribute maxchars='0' or maxstanzas='0' as defined in
+XEP 0045, and do a proper MAM request instead.
+
+Note: the maxchars attribute is ignored unless its value is exactly 0.
+Supporting it properly would be very hard and would introduce a lot of
+complexity for almost no benefit.
+
+For a given channel, each user has her or his own archive. The content of
+the archives are never shared, and thus a user can not use someone else’s
+archive to get the messages that they didn’t receive when they were
+offline. Although this feature would be very convenient, this would
+introduce a very important privacy issue: for example if a biboumi gateway
+is used by two users, by querying the archive one user would be able to
+know whether or not the other user was in a room at a given time.
+
+
+List channels
+-------------
+
+You can list the IRC channels on a given IRC server by sending an XMPP
+disco items request on the IRC server JID. The number of channels on some
+servers is huge so the result stanza may be very big, unless your client
+supports result set management (XEP 0059)
+
+Nicknames
+---------
+
+On IRC, nicknames are server-wide. This means that one user only has one
+single nickname at one given time on all the channels of a server. This is
+different from XMPP where a user can have a different nick on each MUC,
+even if these MUCs are on the same server.
+
+This means that the nick you choose when joining your first IRC channel on
+a given IRC server will be your nickname in all other channels that you
+join on that same IRC server.
+
+If you explicitely change your nickname on one channel, your nickname will
+be changed on all channels on the same server as well. Joining a new
+channel with a different nick, however, will not change your nick. The
+provided nick will be ignored, in order to avoid changing your nick on the
+whole server by mistake. If you want to have a different nickname in the
+channel you’re going to join, you need to do it explicitly with the NICK
+command before joining the channel.
+
+Private messages
+----------------
+
+Private messages are handled differently on IRC and on XMPP. On IRC, you
+talk directly to one server-user: toto on the channel #foo is the same user
+as toto on the channel #bar (as long as these two channels are on the same
+IRC server). By default you will receive private messages from the “global”
+user (aka nickname%irc.example.com@biboumi.example.com), unless you
+previously sent a message to an in-room participant (something like
+\#test%irc.example.com@biboumi.example.com/nickname), in which case future
+messages from that same user will be received from that same “in-room” JID.
+
+Notices
+-------
+
+Notices are received exactly like private messages. It is not possible to
+send a notice.
+
+Topic
+-----
+
+The topic can be set and retrieved seemlessly. The unique difference is that
+if an XMPP user tries to set a multiline topic, every line return (\\n) will
+be replaced by a space, because the IRC server wouldn’t accept it.
+
+Invitations
+-----------
+
+If the invited JID is a user JID served by this biboumi instance, it will forward the
+invitation to the target nick, over IRC.
+Otherwise, the mediated instance will directly be sent to the invited JID, over XMPP.
+
+Example: if the user wishes to invite the IRC user “FooBar” into a room, they can
+invite one of the following “JIDs” (one of them is not a JID, actually):
+
+- foobar%anything@biboumi.example.com
+- anything@biboumi.example.com/FooBar
+- FooBar
+
+(Note that the “anything” parts are simply ignored because they carry no
+additional meaning for biboumi: we already know which IRC server is targeted
+using the JID of the target channel.)
+
+Otherwise, any valid JID can be used, to invite any XMPP user.
+
+Kicks and bans
+--------------
+
+Kicks are transparently translated from one protocol to another. However
+banning an XMPP participant has no effect. To ban an user you need to set a
+mode +b on that user nick or host (see `IRC modes`_) and then kick it.
+
+Encoding
+--------
+
+On XMPP, the encoding is always ``UTF-8``, whereas on IRC the encoding of
+each message can be anything.
+
+This means that biboumi has to convert everything coming from IRC into UTF-8
+without knowing the encoding of the received messages. To do so, it checks
+if each message is UTF-8 valid, if not it tries to convert from
+``iso_8859-1`` (because this appears to be the most common case, at least
+on the channels I visit) to ``UTF-8``. If that conversion fails at some
+point, a placeholder character ``'�'`` is inserted to indicate this
+decoding error.
+
+Messages are always sent in UTF-8 over IRC, no conversion is done in that
+direction.
+
+IRC modes
+---------
+
+One feature that doesn’t exist on XMPP but does on IRC is the ``modes``.
+Although some of these modes have a correspondance in the XMPP world (for
+example the ``+o`` mode on a user corresponds to the ``moderator`` role in
+XMPP), it is impossible to map all these modes to an XMPP feature. To
+circumvent this problem, biboumi provides a raw notification when modes are
+changed, and lets the user change the modes directly.
+
+To change modes, simply send a message starting with “``/mode``” followed by
+the modes and the arguments you want to send to the IRC server. For example
+“/mode +aho louiz”. Note that your XMPP client may interprete messages
+begining with “/” like a command. To actually send a message starting with
+a slash, you may need to start your message with “//mode” or “/say /mode”,
+depending on your client.
+
+When a mode is changed, the user is notified by a message coming from the
+MUC bare JID, looking like “Mode #foo [+ov] [toto tutu]”. In addition, if
+the mode change can be translated to an XMPP feature, the user will be
+notified of this XMPP event as well. For example if a mode “+o toto” is
+received, then toto’s role will be changed to moderator. The mapping
+between IRC modes and XMPP features is as follow:
+
+``+q``
+ Sets the participant’s role to ``moderator`` and its affiliation to ``owner``.
+
+``+a``
+ Sets the participant’s role to ``moderator`` and its affiliation to ``owner``.
+
+``+o``
+ Sets the participant’s role to ``moderator`` and its affiliation to ``admin``.
+
+``+h``
+ Sets the participant’s role to ``moderator`` and its affiliation to ``member``.
+
+``+v``
+ Sets the participant’s role to ``participant`` and its affiliation to ``member``.
+
+Similarly, when a biboumi user changes some participant's affiliation or role, biboumi translates that in an IRC mode change.
+
+Affiliation set to ``none``
+ Sets mode to -vhoaq
+
+Affiliation set to ``member``
+ Sets mode to +v-hoaq
+
+Role set to ``moderator``
+ Sets mode to +h-oaq
+
+Affiliation set to ``admin``
+ Sets mode to +o-aq
+
+Affiliation set to ``owner``
+ Sets mode to +a-q
+
+Ad-hoc commands
+---------------
+
+Biboumi supports a few ad-hoc commands, as described in the XEP 0050.
+Different ad-hoc commands are available for each JID type.
+
+On the gateway itself
+~~~~~~~~~~~~~~~~~~~~~
+
+.. note:: For example on the JID biboumi.example.com
+
+ping
+^^^^
+Just respond “pong”
+
+hello
+^^^^^
+
+Provide a form, where the user enters their name, and biboumi responds
+with a nice greeting.
+
+disconnect-user
+^^^^^^^^^^^^^^^
+
+Only available to the administrator. The user provides a list of JIDs, and
+a quit message. All the selected users are disconnected from all the IRC
+servers to which they were connected, using the provided quit message.
+
+disconnect-from-irc-servers
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Disconnect a single user from one or more IRC server. The user is
+immediately disconnected by closing the socket, no message is sent to the
+IRC server, but the user is of course notified with an XMPP message. The
+administrator can disconnect any user, while the other users can only
+disconnect themselves.
+
+configure
+^^^^^^^^^
+
+Lets each user configure some options that apply globally.
+The provided configuration form contains these fields:
+
+- **Record History**: whether or not history messages should be saved in
+ the database.
+- **Max history length**: The maximum number of lines in the history that
+ the server is allowed to send when joining a channel.
+- **Persistent**: Overrides the value specified in each individual
+ channel. If this option is set to true, all channels are persistent,
+ whether or not their specific value is true or false. This option is true
+ by default for everyone if the `persistent_by_default` configuration
+ option is true, otherwise it’s false. See below for more details on what a
+ persistent channel is.
+
+On a server JID
+~~~~~~~~~~~~~~~
+
+.. note:: For example on the JID chat.freenode.org@biboumi.example.com
+
+configure
+^^^^^^^^^
+
+Lets each user configure some options that applies to the concerned IRC
+server. The provided configuration form contains these fields:
+
+- **Address**: This address (IPv4, IPv6 or hostname) will be used, when
+ biboumi connects to this server. This is a very handy way to have a
+ custom name for a network, and be able to edit the address to use
+ if one endpoint for that server is dead, but continue using the same
+ JID. For example, a user could configure the server
+ “freenode@biboumi.example.com”, set “chat.freenode.net” in its
+ “Address” field, and then they would be able to use “freenode” as
+ the network name forever: if “chat.freenode.net” breaks for some
+ reason, it can be changed to “irc.freenode.org” instead, and the user
+ would not need to change all their bookmarks and settings.
+- **Realname**: The customized “real name” as it will appear on the
+ user’s whois. This option is not available if biboumi is configured
+ with realname_customization to false.
+- **Username**: The “user” part in your `user@host`. This option is not
+ available if biboumi is configured with realname_customization to
+ false.
+- **In encoding**: The incoming encoding. Any received message that is not
+ proper UTF-8 will be converted from the configured In encoding into UTF-8.
+ If the conversion fails at some point, some characters will be replaced by
+ the placeholders.
+- **Out encoding**: Currently ignored.
+- **After-connection IRC commands**: Raw IRC commands that will be sent
+ one by one to the server immediately after the connection has been
+ successful. It can for example be used to identify yourself using
+ NickServ, with a command like this: `PRIVMSG NickServ :identify
+ PASSWORD`.
+- **Ports**: The list of TCP ports to use when connecting to this IRC server.
+ This list will be tried in sequence, until the connection succeeds for
+ one of them. The connection made on these ports will not use TLS, the
+ communication will be insecure. The default list contains 6697 and 6670.
+- **TLS ports**: A second list of ports to try when connecting to the IRC
+ server. The only difference is that TLS will be used if the connection
+ is established on one of these ports. All the ports in this list will
+ be tried before using the other plain-text ports list. To entirely
+ disable any non-TLS connection, just remove all the values from the
+ “normal” ports list. The default list contains 6697.
+- **Verify certificate**: If set to true (the default value), when connecting
+ on a TLS port, the connection will be aborted if the certificate is
+ not valid (for example if it’s not signed by a known authority, or if
+ the domain name doesn’t match, etc). Set it to false if you want to
+ connect on a server with a self-signed certificate.
+- **SHA-1 fingerprint of the TLS certificate to trust**: if you know the hash
+ of the certificate that the server is supposed to use, and you only want
+ to accept this one, set its SHA-1 hash in this field.
+- **Nickname**: A nickname that will be used instead of the nickname provided
+ in the initial presence sent to join a channel. This can be used if the
+ user always wants to have the same nickname on a given server, and not
+ have to bother with setting that nick in all the bookmarks on that
+ server. The nickname can still manually be changed with a standard nick
+ change presence.
+- **Server password**: A password that will be sent just after the connection,
+ in a PASS command. This is usually used in private servers, where you’re
+ only allowed to connect if you have the password. Note that, although
+ this is NOT a password that will be sent to NickServ (or some author
+ authentication service), some server (notably Freenode) use it as if it
+ was sent to NickServ to identify your nickname.
+- **Throttle limit**: specifies a number of messages that can be sent
+ without a limit, before the throttling takes place. When messages
+ are throttled, only one command per second is sent to the server.
+ The default is 10. You can lower this value if you are ever kicked
+ for excess flood. If the value is 0, all messages are throttled. To
+ disable this feature, set it to a negative number, or an empty string.
+
+get-irc-connection-info
+^^^^^^^^^^^^^^^^^^^^^^^
+
+Returns some information about the IRC server, for the executing user. It
+lets the user know if they are connected to this server, from what port,
+with or without TLS, and it gives the list of joined IRC channel, with a
+detailed list of which resource is in which channel.
+
+On a channel JID
+~~~~~~~~~~~~~~~~
+
+.. note:: For example on the JID #test%chat.freenode.org@biboumi.example.com
+
+configure
+^^^^^^^^^
+
+Lets each user configure some options that applies to the concerned IRC
+channel. Some of these options, if not configured for a specific channel,
+defaults to the value configured at the IRC server level. For example the
+encoding can be specified for both the channel and the server. If an
+encoding is not specified for a channel, the encoding configured in the
+server applies. The provided configuration form contains these fields:
+
+- **In encoding**: see the option with the same name in the server configuration
+ form.
+- **Out encoding**: Currently ignored.
+- **Persistent**: If set to true, biboumi will stay in this channel even when
+ all the XMPP resources have left the room. I.e. it will not send a PART
+ command, and will stay idle in the channel until the connection is
+ forcibly closed. If a resource comes back in the room again, and if
+ the archiving of messages is enabled for this room, the client will
+ receive the messages that where sent in this channel. This option can be
+ used to make biboumi act as an IRC bouncer.
+- **Record History**: whether or not history messages should be saved in
+ the database, for this specific channel. If the value is “unset” (the
+ default), then the value configured globally is used. This option is there,
+ for example, to be able to enable history recording globally while disabling
+ it for a few specific “private” channels.
+
+Raw IRC messages
+----------------
+
+Biboumi tries to support as many IRC features as possible, but doesn’t
+handle everything yet (or ever). In order to let the user send any
+arbitrary IRC message, biboumi forwards any XMPP message received on an IRC
+Server JID (see `Addressing`_) as a raw command to that IRC server.
+
+For example, to WHOIS the user Foo on the server irc.example.com, a user can
+send the message “WHOIS Foo” to ``irc.example.com@biboumi.example.com``.
+
+The message will be forwarded as is, without any modification appart from
+adding ``\r\n`` at the end (to make it a valid IRC message). You need to
+have a little bit of understanding of the IRC protocol to use this feature.