diff options
Diffstat (limited to 'doc')
-rw-r--r-- | doc/Makefile | 20 | ||||
-rw-r--r-- | doc/admin.rst | 305 | ||||
-rw-r--r-- | doc/biboumi.1.rst | 762 | ||||
-rw-r--r-- | doc/conf.py | 146 | ||||
-rw-r--r-- | doc/contributing.rst | 84 | ||||
-rw-r--r-- | doc/developer.rst | 302 | ||||
-rw-r--r-- | doc/example.conf | 14 | ||||
-rw-r--r-- | doc/index.rst | 24 | ||||
-rw-r--r-- | doc/install.rst | 194 | ||||
-rw-r--r-- | doc/man_index.rst | 9 | ||||
-rw-r--r-- | doc/synopsis.rst | 4 | ||||
-rw-r--r-- | doc/user.rst | 513 |
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..c607fc5 --- /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.3' +# The full version, including alpha/beta/rc tags +release = '8.3' + + +# -- 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. |