aboutsummaryrefslogtreecommitdiffstats
Commit message (Expand)AuthorAgeFilesLines
* Only init solanum once in tests/sasl_abort1.c•••Calling solanum_main multiple times results in loading every core/autoload module multiple times (because the check for "is the module already loaded" always returns "no" due to solanum_main clearing the list of loaded modules before attempting the load). Init only once, and use other code to ensure that UIDs are consistent instead by resetting the counter and ensuring we free the clients with the old UIDs at the end of each test run. HEAD mainGravatar Ryan Schmidt13 days1-11/+9
* Call the channel_lowerts hook on SJOIN too•••Previously this hook was called only when a remote join outside of a netjoin burst to an existing channel happens, which is a fairly odd set of criteria. By making it run for SJOIN too, it now covers every case where a channel's TS is lowered, making the hook more reliable for use. Gravatar Ryan Schmidt13 days2-11/+15
* Add user_welcome hook•••This hook is executed when the registration burst is being sent to a new local user, after sending RPL_ISUPPORT but before sending LUSERS output. Many IRCv3 specifications use this timing as the point to send additional information during registration bursts, so having an easy hook point to do that makes implementing such specs possible. Gravatar Ryan Schmidt13 days4-1/+16
* Expand doing_whois/doing_whois_global hook data•••Use hook_data_client_approval instead of hook_data_client so that we can pass whether operspy WHOIS is being performed as part of the hook data. hook_data_client_approval is backwards compatible by having the same beginning layout as hook_data_client, so modules compiled against the old hook data should have no issues. Unlike most hooks where an approval struct is passed, the approved field is meant to be read-only here. The approval struct was simply used out of convenience vs having to define a custom struct with identical layout for the case of WHOIS. Gravatar Ryan Schmidt13 days2-5/+10
* Add sendto_list_local_* and sendto_monitor_with_capability•••These are needed for METADATA support, and sendto_monitor was refactored into a common sendto_list_local_internal method used by all of the newly-added functions as well. Test cases were also added to excercise the new functions. Gravatar Ryan Schmidt13 days3-17/+432
* Expand monitor•••- new is_monitoring function that modules can use to determine if a particular client is monitoring a particular nickname - new hook that is fired when a user adds a nick to their monitor list Gravatar Ryan Schmidt13 days4-1/+46
* Make change_isupport useful•••The function now accepts an optional pointer argument to a new struct that contains all of the data of the previous isupport function (both callback and data), rather than only returning the previous data pointer. This in turn allows modules to both call this function to overwrite an isupport handler in modinit as well as restore the previous handler in moddeinit (something that was impossible before). The return value was changed to int, returning 0 if the named isupport method didn't previously exist and 1 if it did exist, so the caller can judge whether this function actually accomplished anything. There were no callers of this function due to it previously being of questionable use, so no other code needed adjustment. Gravatar Ryan Schmidt13 days2-8/+20
* Pass block name to conf_start callbacks•••Configuration blocks of the form block "name" { ... } previously were unsupported in extensions calling add_top_conf because the name portion was not exposed to anything within the extension. Pass the name along so callbacks can use that data instead of relying on global state in newconf.c with static storage duration. Gravatar Ryan Schmidt13 days2-17/+37
* Meson: Decouple creation and generation data from version•••This fixes the generation counter being hardcoded at 0 and the IRCd birth date being reported as "__DATE__ at __TIME__". Gravatar Aaron Jones2026-07-1913-83/+114
* Move setup.h include above rb_lib.h and fix meson assertion printout•••In autotools, NDEBUG is defined in setup.h, which means we need this included before we include any system headers which depend on it (i.e. assert.h). As such, make this the first include in stdinc.h instead of transitively including it from ircd_defs.h. Also fix the assertions printout provided to the user as b_ndebug=true disables assertions, rather than enabling them. It also takes an if-release value, so detect that properly too. Gravatar Ryan Schmidt2026-07-143-3/+9
* Fix authd crash with dnsbl•••If a dnsbl returned a hit, authd would reliably crash. While this still results in the client being properly rejected, it is very noisy in server notices/logs. Also update reference.conf as it was still using the old (deprecated) block name for DNSBLs. Copy over the updated wording from ircd.conf.example. Gravatar Ryan Schmidt2026-07-142-10/+13
* Clean up outgoing_response_info on parse end•••Failing to set outgoing_response_info to NULL after finishing parsing a command means any future commands that do *not* have a label tag will incorrectly inherit that labeled response context. This can cause, among other things, crashes when sending an unlabeled remote command after a labeled remote command. Also add a regression test for this behaviour. Gravatar Ryan Schmidt2026-07-042-21/+41
* Fix SERVICES cap name in ts6 docs•••Should be plural, not singular. This cap is unused in solanum's codebase yet advertised anyway so the only correction needed to happen is in the cap list table.Gravatar Ryan Schmidt2026-07-041-1/+1
* Address review commentsGravatar Ryan Schmidt2026-07-031-1/+1
* Add tests for labeled-responseGravatar Ryan Schmidt2026-07-034-0/+774
* Fix labeled-response issues•••- Solve crash in free_response_batch by not attempting to remove NULL batch ids from the dictionary (indicating there was no response batch to actually free) - Specify the correct server mask for the solanum.chat/response tag when using hunt_server based on whether the hunted param is a client vs a server Gravatar Ryan Schmidt2026-07-032-2/+3
* Fix narrowing conversion for caps in m_messageGravatar Ryan Schmidt2026-07-031-7/+7
* Avoid spurious printfs in sasl_abort1•••The TAP protocol doesn't allow extra stdout lines unless they're commented (which these were not), and I don't see the value in printing out every line we're munching, so instead use the new drain_client_sendq function introduced in the previous commit to empty out the client's sendq rather than these printf while loops. Gravatar Ryan Schmidt2026-07-031-7/+2
* Test utility fixes and additions•••- Add helper method to drain a client's sendq without asserting on any of its lines - Add helper method to fetch a dictionary by name, as these are typically static linkage but could be useful for inspection or manipulation in tests - Add helper method to run an event by name, as these are typically static linkage but could be useful to run during tests - Make the cleanup_remote functions work properly by exiting the correct client with the correct parameters - Add clients created by text utilities to relevant tracking variables - New helper methods to create clients with IDs - Fix return value of get_client_sendq to always be a char * (some cases previously returned const char *) Gravatar Ryan Schmidt2026-07-039-12/+103
* Use posix-compliant shell syntax•••Local dev env had /bin/sh aliased to /bin/bash but CI runs on Ubuntu where /bin/sh is dash, and lacks array support. Debian is similar in this regard, so ensure that the script works across any posix-compliant shell rather than using bash-isms. Gravatar Ryan Schmidt2026-07-031-6/+6
* Fix meson test•••A new custom build target sets up the runtime dir the way the testsuite expects it so that it can run properly. Also fix the help script as it was trying to treat a file as a symlink when it wasn't which broke the new build target. Tests now also properly use the TAP protocol in the meson build file, and fix a segfault in the send1 tests that passes NULL to a function that previously assumed that NULL would not be passed. Gravatar Ryan Schmidt2026-07-035-3/+57
* Fix memory leak in /LIST processing•••The error path was not freeing memory allocated during earlier loop invocations. Gravatar Aaron Jones2026-06-231-0/+2
* Address review commentsGravatar Ryan Schmidt2026-06-061-29/+63
* Update TS6 documentation•••The new documentation is organized differently to (hopefully) introduce the TS6 server-to-server protocol in an easy to understand manner while also serving as a useful reference for ircd and services developers who wish to make use of this protocol to link to solanum. Other documentation files were updated as well to correct discrepancies noticed while writing the updated TS6 documentation. Gravatar Ryan Schmidt2026-06-064-1282/+2842
* Update labeled-response code•••The previous API was too error-prone, as evidenced by the large amount of crash bugs discovered with it. New functions were added to response.h to more easily manage labeled-response state, and some state tracking was moved into core (such as CLICAP_RECEIVE_LABEL, which must only ever be on one client at a time). Because this tracking is now in core, cap_labeled_response needs to be a core module as having that bit unloaded will cause issues. m_batch was also moved into being a core module as more and more core things have depended on batch support existing (and more will depend on it in the future). m_list no longer re-uses remote response batches for SAFELIST, instead making use of new APIs to suspend a labeled-response batch and more easily resume it. Batch resumption was made more focused as well, to ensure that we don't accidentally lose batches due to setting outgoing_response_info to NULL. The free_response_batch takes a resumption pointer to avoid cases where we could introduce use-after-free by combining free+resume_response_batch. struct ResponseInfo now takes strduped pointers instead of directly holding the buffers, and some fields were merged into a flags field or omitted entirely due to new suspension/resumption support. This will have a minor positive impact on memory usage as we no longer need to allocate buffers for maximum-sized strings for every labeled-response. Finally, shorten the dictionary label for pending responses. It was overflowing its spot in STATS B, making the data after it misaligned. Gravatar Ryan Schmidt2026-06-0414-243/+201
* Fix null dereference in LIST•••Introduced in 66a8049e700c5c55ddd32cf211c1ceef06992ff3 Gravatar Valentin Lorentz2026-05-241-1/+2
* Prevent users from running CAPAB pre-registration•••We now disconnect the client if they attempt to run CAPAB before running PASS (introducing themselves as a TS6 server with an SID) or if they've already sent USER/NICK info. USER/NICK already has the other half of the requisite checks by disconnecting the user if they have an SID. As such, the logic flow of requiring an SID before CAPAB means users can never have server caps set on them. This prevents various issues such as a client sending CAPAB STAG receiving all message tags, including those designed to be s2s-only. Gravatar Ryan Schmidt2026-05-231-1/+10
* Fix missing send_multiline_reset in clicap_generate•••This commit adds a missing send_multiline_reset call before a return in clicap_generate in m_cap.c. Without this, if running CAP LIST, the send_multiline_init call just above it would not be cleaned up. It assumes that send_multiline_reset is always safe to call, which is true at the time of this commit. Gravatar daemoness2026-05-231-1/+4
* Don't auto-expire SAFELIST batches•••Avoids use-after-free if the client takes more than 10 seconds to fully receive the LIST output. Gravatar Ryan Schmidt2026-05-212-2/+3
* Fix timing of free_response_batch on cliexit•••free_response_batch will no-op if MyConnect(client_p) is false. This would always be the case with the former timing, as it was called after exit_local_client which clears the MyConnect flag. Do it before instead so we can properly clean up the tracking vars (namely, the pending_responses dict, which otherwise had a use after free when firing the event to clean up a response for an exited client). While we're at it, change the previous fix in cap_labeled_response from IsIOError to IsAnyDead to catch more cases where a client cannot receive data. This has not caused any crashes, but the expanded check includes IOError so is safe to use, and all of the statuses checked by IsAnyDead preclude the ability to send data to the client. Gravatar Ryan Schmidt2026-05-212-6/+6
* Adjust order of operations•••Compare pointer values and set to NULL before freeing the pointer. Also set outgoing_response_info to NULL as well (this is pointless at the moment since it will always be followed by a call that resets it to the orig_response_info pointer, but future-proofs it in the event that future code doesn't do that) Gravatar Ryan Schmidt2026-05-201-2/+4
* Fix use after free in LIST with labeled-response•••In the event that LIST output is small enough to complete without invoking SAFELIST code (i.e. the buffer doesn't exceed half of the client's SendQ), the stashed outgoing_response_info in struct ListClient is the same pointer as the outgoing_response_info for the LIST command. When we finish sending the LIST, we free the stashed struct ListClient's outgoing_response_info and then restore the outgoing_response_info from the LIST command, and attempt to do things with it. However, that memory has already been freed. Detect the case when the pointers are the same value and properly wipe them both so we no longer attempt to read from it. Gravatar Ryan Schmidt2026-05-201-7/+10
* Fix crash on labeled QUIT•••Trying to send things to disconnected clients turns out to be a bad idea. This change effectively ignores any labels on QUIT. Gravatar Ryan Schmidt2026-05-181-13/+17
* Clean up include/stdinc.h and librb/include/rb_lib.h•••- Unconditionally require stdbool.h in IRCd We are a C99 project anyway (configure.ac and meson.build both require a C99 compiler), so this header will always be present This removes the awful hack defining bool, true, and false in its absense, which was creating build errors when using meson, because meson.build did not set the HAVE_STDBOOL_H macro - Modernise definition of alloca(3) according to GNU guidance This was in both librb and IRCd, while it only needs to be in the former - Fix missing endianness check in librb/meson.build IRCd and librb both use the WORDS_BIGENDIAN macro, which was only being set by their configure.ac (with the AC_C_BIGENDIAN M4 macro) Since IRCd's stdinc.h includes librb's rb_lib.h, which then includes librb's librb-config.h, which would have the macro defined there, we only need to check for it in librb, so we can remove the endianness check from IRCd's configure.ac and don't need to add it to IRCd's meson.build - Use __has_attribute to detect whether compiler attributes are available This is supported by gcc (5+), clang (2.9+), and ICC (17+) - Add a __noreturn macro for __attribute__((__noreturn__)) and adjust the codebase to use that - Remove inclusion of headers that are only used by librb - Remove inclusion of headers that are included in rb_lib.h because stdinc.h includes rb_lib.h anyway - Remove the checks for headers and functions from the IRCd configure.ac and meson.build that are only used by librb - Alphabetise checks for headers and functions (by the name of the macro they define) in the meson.build files - Use check_header() instead of has_header() in meson to see if it is actually possible to compile code using the header - Remove dead code using srand48(3) which has never been compiled because neither build system has ever set the HAVE_SRAND48 macro and the surrounding code makes no use of this libc RNG - Remove the TLS defines from IRCd's meson.build because librb's meson.build already defines them and IRCd pulls those in Gravatar Aaron Jones2026-05-1819-276/+132
* Remove some legacy cruft•••- The hurt extension doesn't work well and is now supplanted by m_quarantine - ip_cloaking_old has been broken (causes segfaults) for years now, remove it - ip_cloaking_3.0 has hardcoded keys that require .c file edits to be secure. Anyone using it will probably maintain their fork of this file anyway, but it's not good for new people to use. Remove that too - Remove LOCOPS and umode +l entirely; they serve no useful purpose on unified networks. This also removes the no_locops extension since it is now useless Gravatar Ryan Schmidt2026-05-1320-1240/+12
* Fix s2s labeled-response batches•••Previously, batches would end prematurely if they traveled through an intermediate server before reaching their destination because the intermediate server would send ENCAP ACK multiple times, causing the pending server count to go down way too fast. Solve this by introducing two things: - Check that the direction of the incoming command matches the direction we'd be sending the ACK to (avoids sending additional ACKs for replies from remote servers that we pass along) - Add a mask parameter to the tracking metadata for remote responses and only send an ACK if we match the mask. this way things like remote WHOIS don't generate ACKs from intermediate servers Additionally, fix our manipulation of outgoing_response_info in m_list to properly set CLICAP_RECEIVE_LABEL during SAFELIST buffering. The logic here largely matches that in m_batch. Gravatar Ryan Schmidt2026-05-1311-41/+120
* Add labeled-response support to m_message•••While base cases already worked fine with just cap_labeled_response, a handful of special cases need batched responses, such as multi-target messages. The module also needed updating to work properly with echo-message, as the spec says that the echo is the one that needs the label if the client messages themselves, rather than the main message, and the echo is always sent last. This logic is also applied to mass messages that include the oper sending it. The handle_special method was broken up and made less special, treating the various cases as additional target types rather than processing them right away. The opers@server hack was also removed entirely since it is obviated by other means of messaging opers on a server such as LOCOPS in the event such is even necessary. Or, you know, just use the staff channel. Gravatar Ryan Schmidt2026-05-133-190/+248
* Add labeled-response support to LIST•••With SAFELIST, the labeled-response batch does not necessarily finish right away. As such, save off the context for the client's LIST command and restore it each time we send them more data. Gravatar Ryan Schmidt2026-05-131-0/+21
* Add labeled-response support to BATCH•••This concerns client-initiated batches only. Save the labeled-response context as part of the Batch so that we can restore that context later once the batch is complete. The label is added to the batch start message, but we only process batches once we receive the batch complete message (which lacks a label tag), and we could potentially be finishing a batch due to it timing out if the client never sends a batch complete message. By restoring context, we ensure that hooks such as outbound_msgbuf are operating with all of the state they would expect to have in order to properly attach tags to outgoing messages. Gravatar Ryan Schmidt2026-05-131-0/+55
* Batch labeled-response multiline responses•••Add calls to generate local or remote labeled-response batches to all modules which generate multiple lines of response. In general, this is only done once we've confirmed we will be sending multiple lines, to avoid spurious batches which only contain single lines inside of the batch, however some cases will always generate a batch regardless due to ease of implementation. This patch covers all of the "easy" cases; future patches will cover the complicated ones: m_batch, m_message, and m_list. Gravatar Ryan Schmidt2026-05-1337-37/+180
* Add cap_labeled_response•••This module provides the labeled-response capability as well as an internal non-propagated ?receive_label capability that is dynamically added/removed from the client which should receive a labeled-response. By using a second dummy capability, I don't need to rewrite our msgbuf caching layer which is keyed entirely off the capmasks of the client in order to vary who receives the label/batch tags. It also introduces a s2s-only message tag solanum.chat/response which is used to inform remote servers that their replies should be labelled. Remote responses are always batched, and the batch is generated by the local server to ensure that 100% of incoming labelled commands receive a labeled-response. The solanum.chat/response tag is passed back in replies so the local server can add the appropriate batch tag to the response passed to the client. Remote servers will also send an ENCAP ACK command to indicate they are done responding in the event that they received an incoming s2s command with the solanum.chat/response tag. The module keeps track of outgoing responses and if, by the end of command processing (parse_end hook), it hasn't attached a label to anything it will send a labelled ACK to the client. If it has begun a labeled-response batch, it will also automatically close that batch, reducing the likelihood of programming errors forgetting to close batches. Gravatar Ryan Schmidt2026-05-133-0/+232
* Expand `STATS t` to include batch info•••Two new lines were added at the end of STATS t output to list the number of pending client-initiated batches (and pending lines in those batches) as well as the number of pending remote labeled-response batches. Gravatar Ryan Schmidt2026-05-132-0/+11
* Fix crash in allocate_batch_message()•••When allocate_batch_message is called on a batch containing valueless tags (i.e. tag value is NULL), the ircd would core because we attempted to call strlen on a NULL pointer. Properly detect NULL values and don't attempt to copy them. Additionally, misbehaving hooks may set tag keys to be NULL. While this is not documented or officially supported, other parts of the codebase detect NULL keys as an indication that the tag should be stripped; detect this as well and avoid copying those tags entirely in the newly-allocated batch message for consistency and to avoid spurious crashes. This crash is currently not exploitable because allocate_batch_message() is only called for client-initiated batches and batches sent s2s, of which there are currently none. Gravatar Ryan Schmidt2026-05-131-6/+22
* Add CLICAP_SERVONLY and CLICAP_FLAGS_NOPROP•••CLICAP_SERVONLY is a client capability that no clients will ever have (it is not associated with any CAP string), but is included in the server's client cap mask. Message tags with their capmask set to CLICAP_SERVONLY will only ever be propagated s2s and will never be sent or received c2s. This allows for the easy introduction of s2s-only message tags. Similarly, a new flag for client capabilities defined by modules was introduced name CLICAP_FLAGS_NOPROP which indicates that message tags having a capmask including such a capability MUST NOT be sent s2s. The CLIENT_CAP_MASK macro in send.c was updated to omit capabilities marked as CLICAP_FLAGS_NOPROP from what it will send s2s. Gravatar Ryan Schmidt2026-05-134-3/+32
* Add core framework needed by labeled-response•••- new struct ResponseInfo that keeps track of all relevant state for a labeled-response (whether local or remote) - event to clean up pending remote labeled-responses that we haven't gotten responses for (perhaps due to a bad network link with the remote server, or it doesn't have labeled-response loaded) - struct Batch grew a new field to track its labeled-response status - struct Client grew a new linked list to track pending remote labeled-responses for it, so we can abort them easily if the client disconnects - struct ListClient grew a new field to track labeled-response status for a SAFELIST iteration - remove arbitrary size limit on batch id generation; it will now fill the passed-in buffer according to the passed-in buffer size, leaving room for the null byte at the end. NULL fields indicate that no responses are being labeled. The actual population of those fields will happen in future patches; this one simply provides the core support needed. Gravatar Ryan Schmidt2026-05-139-6/+294
* Change outbound_msgbuf to use its own data struct•••The new struct is ABI-compatible with hook_data for the first 3 fields so that modules compiled using the old hook definition will continue to work. The new data enables much richer evaluation during outbound_msgbuf hook functions by exposing the target or channel the message is being sent to (if known) as well as whether the message source is a recipient of the message being sent. Gravatar Ryan Schmidt2026-05-138-53/+141
* Add parse_end hook•••This hook runs after parsing and processing a command, so that any cleanup that needs to happen after we're finished with parsing can happen. Some reorganization happened so that we ensure the hook and any tags processing happens for every event that isn't a parse error. This will be used by labeled-response in order to automatically send ACKs or close labeled-response BATCHes after processing client commands. Gravatar Ryan Schmidt2026-05-134-26/+46
* include/serno.h.SH: correct check for git directory•••Commit 6ba61b33f7ec557c02c1 split this logic up from the top level Makefile.am but then failed to adjust the path to the directory in the check The result is that all builds now use a datecode of 0 and a revision of "unknown" Gravatar Aaron Jones2026-05-121-1/+1
* Add "bypass" capability to spamfilter•••A new flag ACT_BYPASS was added as a generic flag to bypass +u if set. Opers remain immune, both as senders and recipients, so that spamfilter cannot be abused to lock people out of managing filters, talking to services, etc. Three new configuration items were added to the general section of ircd.conf to control filter behaviour: - filter_sees_user_info: This replaces the old #defines for FILTER_NICK, FILTER_IDENT, and FILTER_HOST to determine whether the hostmask of the user is passed to the spamfilter or whether we pass a dummy *!*@*. - filter_bypass_all: If set, the new ACT_BYPASS can allow every filter action (DROP, KILL, ALARM) to bypass +u if set in conjunction with those flags. If unset, only the DROP action can bypass +u and ACT_BYPASS has no effect on other actions. - filter_exit_message: This is the quit reason displayed, to move it out of a #define (we still keep a define around for a default reason in case it is unspecified). If either filter_sees_user_info or filter_bypass_all are set, the VERSION command will display a new 'F' flag to indicate the ability for filter to spy on users. Gravatar Ryan Schmidt2026-05-113-58/+167
* Automatically rehash when modules change conf•••When loading a module that modifies config (add/remove conf items or top conf sections), we now queue a rehash operation so that new config can be immediately applied. A new rb_defer_once() function was added to deduplicate these rehash requests so that at most one rehash will occur regardless of how many modules change conf. Gravatar Ryan Schmidt2026-04-297-5/+36