Commit Graph

437 Commits

Author SHA1 Message Date
Simon Ser
fa6f52ed08 xirc: encode tokens in GenerateIsupport 2022-05-29 18:24:10 +02:00
Simon Ser
c10d382a7d xirfc: move over message generation functions 2022-05-29 17:57:21 +02:00
Simon Ser
c50fb4a26d xirc: move command constants over 2022-05-09 17:18:51 +02:00
Simon Ser
620a8789b0 Add msgstore package 2022-05-09 16:25:57 +02:00
Simon Ser
b92afa7cca Introduce an xirc package 2022-05-09 16:15:00 +02:00
Simon Ser
89412187d4 msgstore: rename searchMessageOptions, export fields
Preparation for splitting msgstore into a separate package.
2022-05-09 15:44:41 +02:00
Simon Ser
f508d36c38 msgstore: add loadMessageOptions
A struct containing common parameters for all messageStore.Load*
functions returning messages.
2022-05-09 15:36:39 +02:00
Simon Ser
3a7dee8128 Introduce a database package 2022-05-09 15:08:04 +02:00
Simon Ser
d37f946e83 downstream: fix setting tls=0 in bouncer-networks
The old code resulted in URLs like "irc+insecure://0".
2022-05-03 10:43:02 +02:00
Simon Ser
2e5474d05a downstream: improve error message on unrecognized message 2022-04-27 19:05:01 +02:00
Simon Ser
f3932ab500 Drop user.forEachDownstream
It's just a for loop.
2022-04-15 10:32:28 +02:00
delthas
b790db1423 Keep batch tag for downstreams with batch cap
On upstreams without message-tags support, we do not advertise
message-tags anymore. Still, we want to send the batch tag when the
client explicitly requested it.

This fixes a critical issue where we drop the batch tag on chathistory
messages for upstreams that do not support message-tags.
2022-04-12 17:58:36 +02:00
delthas
683cfe0615 Add support for the SEARCH extension 2022-04-12 17:58:16 +02:00
delthas
b67b9b3cd2 Enable message-tags only when all upstreams support it
Previously, we would always advertise mesasge-tags. This made
downstreams believe they could send TAGMSG to the upstream, even though
the upstream did not support it.
2022-04-12 12:41:50 +02:00
delthas
abe5291b62 Add support for the upstream echo-message capability
This adds support for upstream echo-message. This capability is
enabled when the upstream supports labeled-response.

When it is enabled, we don't echo downstream messages in the downstream
handler, but rather wait for the upstream to echo it, to produce it to
downstreams.

When it is disabled, we keep the same behaviour as before: produce the
message to all downstreams as soon as it is received from the
downstream.

In other words, the main functional difference is that when the upstream
supports labeled-response, the client will now receive an echo for its
messages when the server acknowledges them, rather than when soju acks
them.

Additionally, uc.produce was refactored to take an ID rather than a
downstream.
2022-04-11 17:27:47 +02:00
delthas
f7a468194d bouncer-networks: Add a read-only error attribute
This is useful for clients to display additional info abotu why a
network is disconnected.
2022-04-11 08:38:31 +02:00
delthas
d8ca6d2222 Enable resetting a BOUNCER NETWORK port
When a client sends BOUNCER CHANGENETWORK with no value (or an empty
port value), this means it wants to reset the port value to its default
value.

Previously we considered an empty port as an actual valid, empty port
value, which would then be used to connect to the server (dial
'example.com:' (ie 'example.com:0'), which failed.
2022-04-10 18:12:12 +02:00
Simon Ser
793ac29571 downstream: use upstream user/host for echo message 2022-04-05 10:09:49 +02:00
Simon Ser
9513c28208 downstream: unify PRIVMSG/NOTICE and TAGMSG codepaths
They are nearly identical, the only difference is that TAGMSG has
no text parameter.

Inspired from a patch from delthas:
https://lists.sr.ht/~emersion/soju-dev/patches/30651
2022-04-05 10:09:29 +02:00
Simon Ser
846c99dedc Queue WHOIS commands
This avoids having more than one in flight at a time (avoids
hitting rate limits a bit) and routes back replies to the correct
downstream connection (even if labeled-response isn't supported).

Closes: https://todo.sr.ht/~emersion/soju/193
2022-04-04 09:58:26 +02:00
Simon Ser
303c663d02 Refuse to change nick on bouncer connection
Also simplify the code.

Closes: https://todo.sr.ht/~emersion/soju/192
2022-04-01 14:55:36 +02:00
Simon Ser
29b1e6f47b downstream: update user realname on SETNAME 2022-03-30 17:51:04 +02:00
Simon Ser
d7b5f5d12c downstream: set realname for network-less connections
Send the user-wide realname config. We still need to handle SETNAME
properly.
2022-03-30 14:17:09 +02:00
Simon Ser
0ec3e63ace downstream: send RPL_ENDOFWHO on unmarshalEntity error
Also remove a couple of outdated comments.
2022-03-23 19:15:52 +01:00
Simon Ser
44efe37292 downstream: clarify "user not active" error message 2022-03-23 13:11:37 +01:00
Simon Ser
43371bf347 Add the soju.im/no-implicit-names extension
References: https://github.com/ircv3/ircv3-ideas/issues/87
2022-03-22 21:03:20 +01:00
Simon Ser
128aefcc50 downstream: strip back "*" prefix 2022-03-21 17:16:02 +01:00
Simon Ser
8e4c8f7e5a downstream: copy message when degrading extended-join
Otherwise we mutate the input argument and loops over downstream
connections to send messages will be messed up.
2022-03-21 17:13:55 +01:00
Simon Ser
883683c0b7 downstream: always populate downstreamConn.username
This ensures we don't send a prefix without a username in it.
2022-03-21 16:37:04 +01:00
Simon Ser
069625d30d downstream: rejigger hostname logic in newDOwnstreamConn
I find it easier to read this way.
2022-03-21 16:33:58 +01:00
Simon Ser
e403b88a3d Add support for chghost 2022-03-21 16:30:58 +01:00
Simon Ser
78d9a84a6f Add support for RPL_VISIBLEHOST 2022-03-21 16:09:45 +01:00
Simon Ser
b0dbb3cef1 downstream: explain when downstreamConn.sasl is nil 2022-03-21 15:11:43 +01:00
Simon Ser
70ba7032f1 downstream: move negotiatingCaps to downstreamRegistration
This field is only relevant during connection registration.
2022-03-21 15:09:31 +01:00
Simon Ser
884bfec6a6 downstream: improve grouping of downstreamConn fields 2022-03-21 15:08:12 +01:00
Simon Ser
b3425ba1a3 downstream: process BOUNCER BIND in downstreamConn.welcome
This allows clients to send BOUNCER BIND before SASL auth, or to
use BOUNCER BIND with PASS.
2022-03-21 15:02:54 +01:00
Simon Ser
2c691d012d downstream: reject negative or zero network IDs in parseBouncerNetID 2022-03-21 15:00:30 +01:00
Simon Ser
d9468b983f downstream: move multi-upstream name handling to loadNetwork 2022-03-21 14:54:23 +01:00
Simon Ser
bed50c10ce downstream: ignore nickname during connection registration
Just force-set the nickname and completely disregard what the client
sets during connection registration. Clients must discover their
effective nickname via RPL_WELCOME.
2022-03-21 14:54:21 +01:00
delthas
2ac9bd9c94 Require an explicit * network suffix for multi-upstream
Most users will connect to their server with `<username>` as their
username in order to configure their upstreams.

Multi-upstream can be unintuitive to them and should not be enabled on
that first connection that is usually used for upstream configuration.

Multi-upstream is instead a power-user feature that should be explicitly
enabled with a specific network suffix.

We reserve the network suffix `*` and use it a special case to mean that
it requests multi-upstream mode.
2022-03-21 09:56:20 +01:00
Simon Ser
744c6e3f6d Enable bot mode for BouncerServ
See [1] for details.

[1]: https://ircv3.net/specs/extensions/bot-mode
2022-03-16 18:35:48 +01:00
Simon Ser
777adbd5e1 downstream: improve ERR_ERRONEUSNICKNAME message a bit 2022-03-16 12:33:23 +01:00
Simon Ser
35b09f069c downstream: atomically ack/nak capabilities 2022-03-14 19:30:29 +01:00
Simon Ser
6e094b1099 Use capRegistry for upstreamConn 2022-03-14 19:25:49 +01:00
Simon Ser
74fd506fef Use capRegistry for downstreamConn 2022-03-14 19:25:49 +01:00
delthas
9376c8885c downstream: Enable handling READ when upstream is disconnected
Previously, when we sent READ for an upstream which was disconnected,
we would fail with an error. This is because we called unmarshalEntity,
which checked that the upstream was in the connected status.

But we don't need to be connected to update the READ timestamp, this is
a purely offline (wrt the upstream) operation.

This simply switches the call from unmarshalEntity to
unmarshalEntityNetwork to fix the issue.
2022-03-08 22:35:46 +01:00
Simon Ser
fdf9727600 Mark BouncerServ as online in MONITOR, don't forward to upstream 2022-03-08 21:29:04 +01:00
Simon Ser
d8f5f8481f downstream: set case-mapping for monitored 2022-03-08 21:28:43 +01:00
Simon Ser
2060ae05cf downstream: drop delivery receipts when client supports chathistory
When the client supports draft/chathistory, no need to request
delivery receipts via PING messages. Let's just not leave delivery
receipts alone. They'll go stale but should be never used (or used
by a non-chathistory client).
2022-03-08 16:45:45 +01:00
Simon Ser
a438c34489 downstream: disallow '.' in nicknames
See [1] and [2].

[1]: https://github.com/ircdocs/modern-irc/pull/148
[2]: eff6dd242b/irc/strings.go (L29)
2022-03-03 10:54:21 +01:00
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