Commit graph

387 commits

Author SHA1 Message Date
Simon Ser 7b3e46a7c2 downstream: re-format illegalNickChars doc comment 2022-03-03 10:53:33 +01:00
Simon Ser c742726316 downstream: fix network name msimatch check being too strict
The network name can be set via BOUNCER BIND. In that case we
don't want to error out when fallbackNetworkName == "".
2022-03-03 09:08:51 +01:00
Simon Ser 8421c27544 downstream: fail on client or network name mismatch
This probably indicates a mis-configuration.
2022-03-03 08:50:37 +01:00
Simon Ser 348e6da1fc downstream: be less strict when picking up client name
Allow e.g. the SASL username to contain "username/network" and the
raw username to contain "username@client", for instance.
2022-03-03 08:35:34 +01:00
Simon Ser df4af1856a downstream: panic when registering twice
This would be a soju bug.
2022-03-03 08:33:10 +01:00
Simon Ser 1a56b2f658 Introduce formatServerTime
It's too easy to forget to convert to UTC.
2022-02-16 14:45:09 +01:00
Simon Ser 155e811cd9 Ignore READ commands for service 2022-02-12 19:07:30 +01:00
delthas cae248f672 Add support for the wip soju.im/read capability and READ command
READ lets downstream clients share information between each other about
what messages have been read by other downstreams.

Each target/entity has an optional corresponding read receipt, which is
stored as a timestamp.

- When a downstream sends:
  READ #chan timestamp=2020-01-01T01:23:45.000Z
  the read receipt for that target is set to that date
- soju sends READ to downstreams:
  - on JOIN, if the client uses the soju.im/read capability
  - when the read receipt timestamp is set by any downstream

The read receipt date is clamped by the previous receipt date and the
current time.
2022-02-11 19:41:46 +01:00
delthas 17cd3b3e98 Fix echo-message for TAGMSG
A previous fix (d4b7bb02da) only fixed sending echo-message for
TAGMSG to self. We also need to send echo-message for TAGMSG to
other targets.

Closes: https://todo.sr.ht/~emersion/soju/111
2022-02-09 16:58:54 +01:00
Simon Ser 0b5da29916 Drop user.forEachNetwork
It's a trivial for loop.
2022-02-04 14:01:27 +01:00
Simon Ser fe564af756 Handle upstream multi-line SASL
References: https://todo.sr.ht/~emersion/soju/173
2021-12-10 10:46:41 +01:00
Simon Ser e7f9d2332b Add support for downstream multi-line AUTHENTICATE commands
Useful for long passwords.
2021-12-09 23:21:08 +01:00
Simon Ser bad8154da8 Don't forward duplicate JOIN commands
Closes: https://todo.sr.ht/~emersion/soju/171
2021-12-08 18:23:46 +01:00
Simon Ser 66aea1b4a2 Add context to {conn,upstreamConn}.SendMessage
This avoids blocking on upstream message rate limiting for too
long.
2021-12-08 18:03:40 +01:00
Simon Ser f7e151396d Use dc.nick instead of "*" for RPL_* messages
Makes it clearer what these fields are used for. The default value
for dc.nick is "*".
2021-12-07 09:42:32 +01:00
Simon Ser aae0fb9f22 Improve error message when downstream doesn't authenticate 2021-12-07 09:40:02 +01:00
Simon Ser 5c819a2c6c Disallow ',' in nicknames
It breaks lists as in `PRIVMSG a,b,c :foo`.
2021-12-06 19:23:28 +01:00
Simon Ser 1a78b3d905 Add username to downstreamConn log messages 2021-12-06 18:56:00 +01:00
Simon Ser f2a28f6e22 Avoid forwarding MONITOR requests if upstream doesn't support it
Clients aren't supposed to do this, but in case they do, let's
send them an error.
2021-12-04 19:29:39 +01:00
Simon Ser 23fd727618 Add support for draft/account-registration proxying
This adds support for the draft/account-registration extension [1].
This allows downstreams to register on upstream networks.

[1]: https://ircv3.net/specs/extensions/account-registration
2021-11-30 12:02:54 +01:00
Simon Ser 522e20cca1 downstream: improve unmarshalEntityNetwork error message
Closes: https://todo.sr.ht/~emersion/soju/162
2021-11-29 16:41:52 +01:00
Simon Ser c36192ab02 Return more descriptive auth failure errors 2021-11-29 13:14:16 +01:00
Simon Ser e3d7c33bcd Remove sasl cap after registration if network doesn't support it
This will stop clients from trying to issue AUTHENTICATE requests
after connection registration.
2021-11-21 16:28:38 +01:00
Simon Ser 313c6e7f97 Add support for post-connection-registration upstream SASL auth
Once the downstream connection has logged in with their bouncer
credentials, allow them to issue more SASL auths which will be
redirected to the upstream network. This allows downstream clients
to provide UIs to login to transparently login to upstream networks.
2021-11-21 16:10:54 +01:00
Simon Ser 4e84b41592 Send RPL_LOGGEDIN with bouncer account in multi-upstream mode 2021-11-21 11:00:57 +01:00
Simon Ser c2a5461cb8 Use RPL_LOGGEDIN/OUT to mirror upstream status
This will allow clients to properly show/hide UI to login and
register.
2021-11-19 19:21:48 +01:00
Simon Ser b5a868bbcd Abort SASL if in-progress while completing registration
Implements the following recommendation from the spec:

> If the client completes registration (with CAP END, NICK, USER and any other
> necessary messages) while the SASL authentication is still in progress, the
> server SHOULD abort it and send a 906 numeric, then register the client
> without authentication.
2021-11-19 18:55:07 +01:00
Simon Ser c6f5508765 Add missing account-notify to permanentUpstreamCaps 2021-11-19 11:55:22 +01:00
Thomas Vigouroux 4831b61186 Add CHATHISTORY LATEST support
This patch adds a bit more compliance to the chathistory IRCv3 specification.
2021-11-18 21:06:26 +01:00
Simon Ser ac4696a507 Disallow empty string for nick 2021-11-18 09:44:33 +01:00
Hubert Hirtz dcc1eff130 Allow AUTHENTICATE before NICK
Now that dc.nick is not blank during registration, sasl replies from the
server are correct and cap handling can be a bit simplified.
2021-11-18 09:40:23 +01:00
Simon Ser 5a5c93a756 Add message counter metrics 2021-11-17 15:58:19 +01:00
Simon Ser 4d3b640989 Update downstream caps/nick/realname before sending MOTD
The MOTD indicates the end of the registration's message burst, and
the server can send arbitrary messages before it.

Update the supported capabilities, the nick and the realname before
MOTD to make it so client logic that runs on MOTD can work with
up-to-date info.
2021-11-17 15:27:34 +01:00
Simon Ser 97152191ad Add timeout for downstream connection registration 2021-11-17 14:54:03 +01:00
Simon Ser 6143e6f12d Introduce conn.NewContext
This function wraps a parent context, and returns a new context
cancelled when the connection is closed. This will make it so
operations started from downstreamConn.handleMessage will be
cancelled when the connection is closed.
2021-11-17 13:13:55 +01:00
Simon Ser eb47f0dcd7 Lift up context to downstreamConn.handleMessage 2021-11-17 12:38:08 +01:00
Simon Ser e28332a5aa Add context arg to downstreamConn.welcome() 2021-11-17 12:33:30 +01:00
Simon Ser e459dcdb76 Add context to downstreamConn.handleMessageUnregistered 2021-11-17 12:29:23 +01:00
Simon Ser 06ce0b8da9 Lower sanityCheckServer timeout to 15s
Should still be more than enough to connect even if the network is
somewhat flaky.
2021-11-17 12:12:40 +01:00
Simon Ser 47c8ec5238 Add context arg to sanityCheckServer
As a bonus, the timeout now applies to the whole TLS dial
operation. Before the timeout only applied to the net dial
operation, making it possible for a bad server to stall the request
by making the TLS handshake extremely slow.
2021-11-17 12:10:56 +01:00
Simon Ser 3941f67380 Add config option to globally disable multi-upstream mode
Closes: https://todo.sr.ht/~emersion/soju/122
2021-11-17 11:41:11 +01:00
Simon Ser 61e6b2efa4 Set isMultiUpstream flag in downstreamConn.welcome()
This will make it easier to globally disable multi-upstream mode.
2021-11-17 11:22:26 +01:00
Simon Ser ff44ea314e Add downstreamConn.isMultiUpstream 2021-11-17 11:17:09 +01:00
Simon Ser 73295e4fa7 Allow most config options to be reloaded
Closes: https://todo.sr.ht/~emersion/soju/42
2021-11-16 00:38:04 +01:00
Simon Ser e44f4b2eee Don't send user in prefix for echo messages
This is not very useful and confuses clients.
2021-11-15 23:53:25 +01:00
delthas 37c1b3e29c Return an empty CHATHISTORY TARGETS batch when in multi-upstream
When on an unbound bouncer network downstream, we should return no
targets (there are none, because there are no upstreams at all).

When on a multi-upstream downstream, we should return no targets as we
don't support multi-upstream CHATHISTORY TARGETS.

Before this patch, we returned a misleading error message:
:example.com 403 :Missing network suffix in name
2021-11-15 21:30:04 +01:00
delthas 179991036c Send the downstream host for PRIVMSG echo messages
If a downstream of prefix host `foo` sends a message, the other
downstream of prefix host `bar` should receive an echo PRIVMSG with
prefix host bar.

This fixes a regression where no prefix host was sent at all.
2021-11-15 17:45:23 +01:00
delthas 840d142f1c Add support for draft/extended-monitor
References: https://github.com/ircv3/ircv3-specifications/pull/466
2021-11-15 14:38:19 +01:00
Simon Ser 5d46dd72a4 Add support for MONITOR
Add support for MONITOR in single-upstream mode.

Each downstream has its own set of monitored targets. These sets
are merged together to compute the MONITOR commands to send to
upstream.

Each upstream has a set of monitored targets accepted by the server
alongside with their status (online/offline). This is used to
directly send replies to downstreams adding a target another
downstream has already added, and send MONITOR S[TATUS] replies.

Co-authored-by: delthas <delthas@dille.cc>
2021-11-15 14:34:04 +01:00
Simon Ser f920f27e02 Add ELIST support in single-upstream mode
We just forward the command as-is, so we can pass down the ISUPPORT
token as well.

Closes: https://todo.sr.ht/~emersion/soju/148
2021-11-09 22:12:46 +01:00
Simon Ser 0b6ff2e61a Add a queue for WHO commands
This has the following upsides:

- We can now routes WHO replies to the correct client, without
  broadcasting them to everybody.
- We are less likely to hit server rate limits when multiple downstreams
  are issuing WHO commands at the same time.
2021-11-09 22:09:17 +01:00
Simon Ser 0c360d24c5 Remove support for mixed multi-upstream LIST
Multi-upstream connections can still send LIST commands with a
network suffix.
2021-11-09 21:32:26 +01:00
Simon Ser 802e82c272 Add context support to service
References: https://todo.sr.ht/~emersion/soju/141
2021-11-08 19:40:48 +01:00
Simon Ser c21202160c Add context support to user and network mutations
References: https://todo.sr.ht/~emersion/soju/141
2021-11-08 19:36:10 +01:00
Simon Ser 8b3e5e7465 Plumb context in downstreamConn.handleMessageRegistered
References: https://todo.sr.ht/~emersion/soju/141
2021-11-08 18:11:24 +01:00
Simon Ser c2047dc1a8 Add plus sign in RPL_UMODEIS reply 2021-11-03 22:02:19 +01:00
Simon Ser 26cdb0d328 Set mode +o on admins for bouncer-only connections 2021-11-03 21:42:42 +01:00
Simon Ser abe5f362db Turn CHATHISTORY and backlog limits into constants 2021-11-03 18:29:21 +01:00
Simon Ser ce69f00e3f msgstore: add context to messageStore methods
This allows setting a hard timeout.
2021-11-03 18:21:05 +01:00
Simon Ser 2b4f0a870f msgstore: take Network as arg instead of network
The message stores don't need to access the internal network
struct, they just need network metadata such as ID and name.

This can ease moving message stores into a separate package in the
future.
2021-11-03 16:37:01 +01:00
delthas 03f8972305 Add support for draft/event-playback 2021-11-03 15:17:16 +01:00
Simon Ser a6aa7f0008 Make Network.Nick optional
Make Network.Nick optional, default to the user's username. This
will allow adding a global setting to set the nickname in the
future, just like we have for the real name.

References: https://todo.sr.ht/~emersion/soju/110
2021-11-02 23:33:17 +01:00
Simon Ser 07c962018d Add title config option
Closes: https://todo.sr.ht/~emersion/soju/146
2021-11-02 22:38:07 +01:00
Simon Ser 832d8b89a2 Mark bouncer users and BouncerServ as authenticated in WHOX/WHOIS 2021-11-02 18:32:39 +01:00
Simon Ser 241e27b00e Add support for WHOX
This adds support for WHOX, without bothering about flags and mask2
because Solanum and Ergo [1] don't support it either.

The motivation is to allow clients to reliably query account names.

It's not possible to use WHOX tokens to route replies to the right
client, because RPL_ENDOFWHO doesn't contain it.

[1]: https://github.com/ergochat/ergo/pull/1184

Closes: https://todo.sr.ht/~emersion/soju/135
2021-11-02 18:25:43 +01:00
Simon Ser 8c7c907d6f Fix operator flag in RPL_WHOREPLY
@ and + indicate channel privileges. * indicates that the user is
a server operator.
2021-11-01 18:36:21 +01:00
Simon Ser 62d92c660f Mark admins as server operators in self WHO/WHOIS replies 2021-11-01 18:32:01 +01:00
Simon Ser 3ab8ef17df Mark BouncerServ as server operator
That's what some widely used IRC servers do for their own services
(e.g. NickServ and ChanServ). This adds an additional level of
trust to make sure BouncerServ isn't typo'ed or impersonated.
2021-11-01 18:28:19 +01:00
Simon Ser aa407a46e6 Get rid of io.EOF errors in logs
Closes: https://todo.sr.ht/~emersion/soju/150
2021-10-29 16:03:04 +02:00
Simon Ser 0cd18a78db Unify BOUNCER ADDNETWORK and CHANGENETWORK 2021-10-29 15:51:13 +02:00
Simon Ser de38d93085 Always reply ERR_SASLABORTED on SASL abort
Some clients (Hexchat) always expect AUTHENTICATE * to succeed with
ERR_SASLABORTED even if SASL hasn't been started.
2021-10-28 11:29:34 +02:00
Simon Ser 9ec1f1a5b0 Add context args to Database interface
This is a mecanical change, which just lifts up the context.TODO()
calls from inside the DB implementations to the callers.

Future work involves properly wiring up the contexts when it makes
sense.
2021-10-18 19:15:15 +02:00
Simon Ser 4be6c4b19c Remove unnecessary downstream cap checks
downstreamConn.SendMessage already performs this cap checking.
2021-10-18 09:20:11 +02:00
Simon Ser 1507e88b36 Remove incorrect AWAY TODO in downstreamConn.SendMessage
PRIVMSG/NOTICE get RPL_AWAY, not AWAY.
2021-10-18 09:08:52 +02:00
Simon Ser 324d0fb0ac Unify away-notify and account-notify handling 2021-10-17 21:54:18 +02:00
Simon Ser 455fef2421 Add support for account-notify 2021-10-17 21:54:18 +02:00
Simon Ser 2f495e9768 Remove unused REGISTRATION_IS_COMPLETED in handleMessageUnregistered
downstreamConn.handleMessageUnregistered is only called when the
user isn't registered.
2021-10-16 11:42:32 +02:00
Simon Ser ade59beb8c Send BOUNCER REGISTRATION_IS_COMPLETED error 2021-10-16 11:41:37 +02:00
Alexey Yerin 3109340651 downstream: handle name=... in BOUNCER 2021-10-14 16:03:14 +02:00
Simon Ser a9a066faac Add bouncer MOTD
Closes: https://todo.sr.ht/~emersion/soju/137
2021-10-13 10:58:34 +02:00
Simon Ser e55d0d7552 Stop sending RPL_CREATED
There's no point in sending this numeric if it doesn't contain any
useful info.
2021-10-12 19:28:44 +02:00
Simon Ser 6e8b6fa153 Fix printf formatting in error message 2021-10-12 17:36:00 +02:00
Hubert Hirtz 3a171607e0 Correctly send back PRIVMSGs and NOTICEs to self 2021-10-10 12:05:41 +02:00
Hubert Hirtz d4b7bb02da Send back TAGMSGs to self 2021-10-10 12:05:41 +02:00
Hubert Hirtz 0fd81f38fa Dismiss TAGMSGs directed to BouncerServ 2021-10-10 12:05:40 +02:00
Simon Ser 1d56ef19e7 Add WHOIS reply for BouncerServ 2021-10-06 11:50:12 +02:00
Hubert Hirtz 2554c92df7 Allow CAP negotiation to happen with CAP REQ
See https://ircv3.net/specs/extensions/capability-negotiation

> Upon receiving either a CAP LS or CAP REQ command during connection
> registration, the server MUST not complete registration until the
> client sends a CAP END command to indicate that capability negotiation
> has ended.

This commit should prevent soju from trying to authenticate the user
prior to having received AUTHENTICATE messages, when the client eagerly
requests capabilities with CAP REQ seeing available capabilities
beforehand with CAP LS.
2021-09-19 16:50:47 +02:00
Simon Ser 0f2f4de275 Send empty history for service
Fixes error when fetching chat history for BouncerServ.
2021-09-13 11:36:25 +02:00
Simon Ser fba1fdb31e Don't require upstream to be connected for CHATHISTORY
Closes: https://todo.sr.ht/~emersion/soju/127
2021-09-13 11:25:38 +02:00
Simon Ser cd64a7ffda Split unmarshalEntity into two functions
Some command handlers need to unmarshal without requiring the
upstream to be connected.
2021-09-13 11:14:47 +02:00
Simon Ser c5d5259243 Pass-through CLIENTTAGDENY in ISUPPORT 2021-07-09 22:48:58 +02:00
Simon Ser a14f646135 Add per-user realname setting
This allows users to set a default realname used if the per-network
realname isn't set.

A new "user update" command is introduced and can be extended to edit
other user properties and other users in the future.
2021-06-25 20:33:13 +02:00
Simon Ser f3f864dddc Disallow '$' in nicks 2021-06-23 19:54:22 +02:00
Simon Ser d7b1c5a9a2 Allow admins to broadcast message to all bouncer users
Typically done via:

    /notice $<bouncer> <message>

Or, for a connection not bound to a specific network:

    /notice $* <message>

The message is broadcast as BouncerServ, because that's the only
user that can be trusted to belong to the bouncer by users. Any
other prefix would conflict with the upstream network.
2021-06-23 19:23:09 +02:00
Simon Ser eca4c41223 Unify downstream PRIVMSG and NOTICE handling
We were doing some things wrong here, e.g. not sending echo messages
for NOTICE.
2021-06-23 18:17:30 +02:00
Simon Ser faa89333bf Add support for utf8-only 2021-06-15 15:48:10 +02:00
Simon Ser b609b86f97 Add support for account-tag 2021-06-14 21:44:38 +02:00
Simon Ser 0557ca5871 Don't suggest users to /motd in multi-upstream mode 2021-06-10 12:16:33 +02:00
Simon Ser 2b3782a507 Make user MODE commands fail in multi-upstream mode
References: https://todo.sr.ht/~emersion/soju/20
2021-06-10 11:24:10 +02:00
Gregory Anders 0e9ef1f97c Forward user mode changes in single-upstream mode
References: https://todo.sr.ht/~emersion/soju/20
2021-06-10 11:17:00 +02:00