Aaron Jones [Sat, 29 May 2021 13:56:09 +0000 (13:56 +0000)]
modules/saslserv/main: downgrade severity of no mechanism log message
It was discovered while testing some improvements to contrib/sasl_blacklist
that clients can trigger this message remotely and at will, just by not
adhering to the SASL specification.
This reflects a similar Solanum PR: solanum-ircd/solanum#150
It might be slightly more proper to have this option apply specifically
to the solanum protocol module once we have one, but we don't, plus
there isn't currently any precedent for config options added from
protocol modules.
The option is deliberately rehashable as the Solanum option is as well,
allowing a synchronized change in configuration across a network without
requiring restarts.
Aaron Jones [Sun, 28 Mar 2021 21:06:53 +0000 (21:06 +0000)]
include/atheme/hooktypes.in: add a hook for password (hash) change
This will allow modules to detect when a user's account password
(or its hash) has been changed (after the fact; use the hook added
in the previous commit if you need to access the plaintext password
for some reason).
Aaron Jones [Sun, 28 Mar 2021 20:30:21 +0000 (20:30 +0000)]
nickserv/set_password: allow a hook to deny a password change
This prevents bypassing nickserv/pwquality, by initially registering
with a password that it does not object to, and then changing it to
a more insecure one.
Aaron Jones [Fri, 26 Mar 2021 12:03:09 +0000 (12:03 +0000)]
libathemecore/connection.c: free vhost_addr after using it.
Caught by Clang's AddressSanitizer, eventually, after a few inexplicable
corrupt addresses were output. I'm not sure why it didn't catch this
immediately.
Fixes: 642759fc2907efe5e0ba ("libathemecore/connection.c: use
connection->name to store addrs & ports")
Aaron Jones [Thu, 25 Mar 2021 17:19:24 +0000 (17:19 +0000)]
libathemecore/connection.c: use connection->name to store addrs & ports
Also obtain IP addresses where the sockets are created, instead of in
connection_add(). This is a better approach than that taken by commit 1bb7e1e587306239ca87, and restores the ability to perform non-blocking
connections.
Finally, since connection_add() creates the mowgli.pollable object for
the fd, don't bother testing if the fd is valid. Add an assertion for a
valid fd being passed, because an invalid fd will only result in
nothing working anyway. Likewise assert that the connection name is
valid, and that at least one I/O handler was supplied.
Aaron Jones [Thu, 18 Mar 2021 21:11:08 +0000 (21:11 +0000)]
modules/contrib/: transition to independent build system
Having to duplicate configure tests in all supported Atheme release and
development branches, to enable contrib modules to be built reliably on
all of our supported platforms, was quickly becoming untenable.
Aaron Jones [Sat, 13 Mar 2021 21:20:55 +0000 (21:20 +0000)]
Build System: Improve handling of enabling and configuring submodules
- When performing the libmowgli test, don't pollute CFLAGS / CPPFLAGS /
LDFLAGS / LIBS variables. Set library-specific variables, just like
the other library tests do
This allows us to configure submodules later without having to save
the environment variables first
- When --with-libmowgli=yes is given, require that pkg-config is
available and that it can detect the library, erroring out otherwise
- Put the logic for handling enabling and configuring submodules into
its own M4 file
Aaron Jones [Sat, 13 Mar 2021 18:31:30 +0000 (18:31 +0000)]
configure.ac: rename autoconf/ to build-aux/
This is the name that a lot of other projects use, the name that is
recommended by the GNU autoconf documentation, and the name that is
used by the upstream buildsys project [1] (though we have diverged
from that significantly).
Aaron Jones [Thu, 11 Mar 2021 20:04:39 +0000 (20:04 +0000)]
configure: put directory macros in a header file, not in CPPFLAGS
This will be necessary for my near-future intention to change the contrib
modules repository to be self-building; i.e. to have its own configure
script and build system.
Also don't try to expand directories like MODDIR for pretty printing,
because it sometimes doesn't work depending on the directory arguments
given to ./configure. Yeah, the config output looks worse, but oh well.
Aaron Jones [Thu, 11 Mar 2021 14:18:23 +0000 (14:18 +0000)]
m4/atheme-*.m4: use autoconf flow control macros exclusively
The AS_IF and AS_CASE macros enable one to write "if" and "case"
shell statements in a portable way. They still generate more or
less the same output, but code which works better on various
obscure platforms.
They also allow autoconf to examine the conditional block bodies
for macro calls, to ensure those macros are available. This will
become more necessary in future versions of autoconf.
Also use these to replace an unguarded grep(1) invocation in the
Perl library testing macro.
Aaron Jones [Thu, 11 Mar 2021 14:02:42 +0000 (14:02 +0000)]
libathemecore/: rename openbsd random backend to arc4random
There may well be platforms in the future that have a secure algorithm
backing their arc4random(3) implementation. For the moment we continue
to support only OpenBSD, but make it easier to adjust in the future.
The buildsys.mk.in and buildsys.module.mk files already add these
variables to CFLAGS and LDFLAGS during execution of CompileModule,
CompilePlugin, and Link steps.
Aaron Jones [Tue, 9 Mar 2021 17:49:41 +0000 (17:49 +0000)]
configure.ac: approach noexecstack differently
This can also be passed as -Wl,-z,noexecstack which saves Clang warning
about it being unused during compilation. Since -Wl arguments are only
used by the linker, take it out of CFLAGS. This continues to work on
GCC.
Aaron Jones [Tue, 9 Mar 2021 17:38:14 +0000 (17:38 +0000)]
configure.ac: prepend LIBPCRE_CFLAGS and LIBPCRE_LIBS
The entire codebase depends on libpcre if it is detected successfully,
so we need to build all of the .c files with the appropriate CFLAGS &
LIBS.
This was taken care of in libathemecore/Makefile, but nowhere else.
It's better to just have configure.ac take care of adding it if they
are non-empty.
Aaron Jones [Tue, 9 Mar 2021 08:37:42 +0000 (08:37 +0000)]
m4/atheme-featuretest-contrib.m4: fix test for res_query(3)
Most platforms have these as enums, which are converted to int (for use
as arguments) by the compiler automatically. However, some platforms do
not have these as enums, and use macros to define their values instead.
The former platforms also have those macros to define them in terms of
the corresponding enum, so use the macros instead of the enums for
broader compatibility, defining them in terms of their enums when they
don't exist.
glibc2 and musl have enums and compatibility macros, uclibc and
uclibc-ng have enums only, and OpenBSD libc has macros only.
Aaron Jones [Tue, 2 Mar 2021 05:46:12 +0000 (05:46 +0000)]
include/atheme/mkserno.sh: exit early in presence of an environment variable
This makes life easier for people who want to package snapshots
of a git branch. They must provide their own serno.h in this
case, containing also, perhaps, the date the snapshot was
downloaded or such.
Aaron Jones [Tue, 2 Mar 2021 00:48:18 +0000 (00:48 +0000)]
Build System: Compiler Sanitizers: Some small improvements
- Remove a few levels of indentation by swapping the following approach:
< Try to enable LTO >
if (that succeeded) {
< Try to enable some sanitizers >
if (one of those succeeded) {
AC_DEFINE(...)
} else {
AC_MSG_FAILURE(...)
}
} else {
AC_MSG_FAILURE(...)
}
... for this equivalent approach instead:
< Try to enable LTO >
if (that failed) {
AC_MSG_FAILURE(...)
}
< Try to enable some sanitizers >
If (none of those succeeded) {
AC_MSG_FAILURE(...)
}
AC_DEFINE(...)
This is equivalent because AC_MSG_FAILURE terminates the script
- Add support for -fsanitize=bounds
This enables some checks not enabled by -fsanitize=undefined on Clang
- Add support for falling back to individual undefined behaviour
sanitizers if the compiler does not support -fsanitize=undefined
This may seem pointless, but it may benefit older compilers, and
compilers that are not GCC or Clang.
- Adjust the compiler sanitizers driver to take the name of a sanitizer
rather than its whole -fsanitize= option. Use this to collect a list
of enabled sanitizers and report it in the output of ./configure
Aaron Jones [Mon, 1 Mar 2021 20:21:38 +0000 (20:21 +0000)]
GitHub Actions: CI: Tidy up a bit
- Clone the repository first
This is likely to be much faster than downloading the dependencies,
which will result in the job aborting much earlier and wasting less
data if for some reason the clone cannot succeed
- Remove a pointless single-valued option from the build matrix
This more closely aligns it with the Coverity Scan action.
Aaron Jones [Sun, 28 Feb 2021 02:15:43 +0000 (02:15 +0000)]
Build System: Detect user error w/ downloading sourcecode
A frequent complaint we receive is that serno.h is missing. This turns
out to be users downloading release tarballs from GitHub, which does
not include the .git directory, thus making the target for serno.h
fail.
Detect whether .git/ exists; reference GIT-Access.txt then. Otherwise,
this must be a release tarball, so see if it has a pre-supplied serno.h
and error if not (this could only be caused by downloading a GitHub
source code link instead of an asset/release tarball).
Also tidy up mkserno.sh a bit. It still can't use git-describe(1) on
this branch (lack of recent tags), but will be made to do so on release
branches.
Thanks to ilbelkyr for the idea (pointing out that the sourcecode links
on GitHub don't include the .git/ directory, making it possible to
distinguish between that and git-clone(1)).
Aaron Jones [Sat, 27 Feb 2021 21:14:22 +0000 (21:14 +0000)]
Build System: Several small improvements
- Don't let autoconf add "-O2 -g" to the CFLAGS variable. Detect
optimisations automatically (if sanitizers are not enabled) or
explicitly disable them (if they are). Detect debugging flags
automatically, preferring DWARF, then GDB, then regular -g as
autoconf does. This allows more accurate debugging when supported
by the toolchain. Allow debugging symbols to be disabled; enable
them by default.
- When requested to enable compiler sanitizers, bail out with an
error when they cannot be enabled. Update the comment on
ATHEME_ENABLE_COMPILER_SANITIZERS to reflect that sanitizers are
enabled; rather than just the configure argument given.
- Move the logic for testing CFLAGS / CPPFLAGS / LDFLAGS / some
combination of them to a dedicated separate file. Tidy up those
functions to use the same M4sh coding style as the other files.
Explicitly provide a program with both a header and main body when
doing compiler and linker tests. Use a unified function and variable
name scheme.
- Rewrite the compiler sanitizers driver function to use the new
combined compiler and linker test logic.
- Update the comment in the compiler sanitizers feature file to explain
why we are trying to enable LTO (Clang sanitizers require it).
- Clean up temporary _SAVED variables at the end of function execution
in various feature and library tests.
- Remove 2 unsubstituted and unused variables from extra.mk.in.
- Support the -Wa,--noexecstack flag to the compiler and linker; enable
it by default.
Aaron Jones [Sat, 27 Feb 2021 15:14:33 +0000 (15:14 +0000)]
libathemecore/logger.c: logfile_new(): fix up close-on-exec logic
We were calling fcntl(2) F_SETFD without first obtaining the current
file descriptor flags with F_GETFD. Furthermore, we were not checking
the return value of the F_SETFD operation. Now we obtain the current
flags to bitwise-OR FD_CLOEXEC them with, and we warn if the operation
fails.
However, it would be better if we didn't have to try to call it in the
first place, so try opening the file descriptor with the O_CLOEXEC flag
first, which is safer too.
While we're at it, make sure that the log file doesn't end up being
world-readable if services' umask is not sufficient to prevent this.
We should check if getpeername(2) fails, and we must use inet_ntop(3)
properly.
Previously the code assumed that "(struct sockaddr_in *)->sin_addr" and
"(struct sockaddr_in6 *)->sin6_addr" both started at the same offset.
While we're at it, use the proper "struct sockaddr_storage" type for
passing to inet_pton(3), capable of holding any kind of sockaddr
structure, and remove it from `struct connection', as it was not
referenced anywhere. Also remove some unused macros and the now-unused
sockaddr_any union.
Finally, remove the non-blocking invocation from connection_open_tcp();
this prevents getpeername(2) from functioning alltogether (the socket
is not yet connected). connection_add() itself sets the socket non-
blocking.
Most socket-level options utilize an int argument for optval. For
setsockopt(2), the argument should be non-zero to enable a boolean
option, or zero if the option is to be disabled. For a description
of the available socket options see socket(7) and the appropriate
protocol man pages.
From socket(7):
The socket options listed below can be set by using setsockopt(2)
and read with getsockopt(2) with the socket level set to SOL_SOCKET
for all sockets. Unless otherwise noted, optval is a pointer to an
int.
SO_REUSEADDR
Indicates that the rules used in validating addresses supplied
in a bind(2) call should allow reuse of local addresses. For
AF_INET sockets this means that a socket may bind, except when
there is an active listening socket bound to the address. When
the listening socket is bound to INADDR_ANY with a specific port
then it is not possible to bind to this port for any local
address. Argument is an integer boolean flag.
Therefore, the argument must be a pointer to int. Further, check the
return value of setsockopt(2) to ensure that it succeeds.
Most socket-level options utilize an int argument for optval. For
setsockopt(2), the argument should be non-zero to enable a boolean
option, or zero if the option is to be disabled. For a description
of the available socket options see socket(7) and the appropriate
protocol man pages.
From socket(7):
The socket options listed below can be set by using setsockopt(2)
and read with getsockopt(2) with the socket level set to SOL_SOCKET
for all sockets. Unless otherwise noted, optval is a pointer to an
int.
SO_REUSEADDR
Indicates that the rules used in validating addresses supplied
in a bind(2) call should allow reuse of local addresses. For
AF_INET sockets this means that a socket may bind, except when
there is an active listening socket bound to the address. When
the listening socket is bound to INADDR_ANY with a specific port
then it is not possible to bind to this port for any local
address. Argument is an integer boolean flag.
Therefore, the argument must be a pointer to int. Further, check the
return value of setsockopt(2) to ensure that it succeeds.
Code above this already tests if si->v is NULL; indicating that it can
be NULL (and it can be). Therefore, check if it's NULL again before
attempting to dereference it again.
At present this cannot be the case, but guard against it anyway, making
sure to fill the result buffer with something in any case.
Code above this already tests if si->v is NULL; indicating that it can
be NULL (and it can be). Therefore, check if it's NULL again before
attempting to dereference it again.
At present this cannot be the case, but guard against it anyway, making
sure to fill the result buffer with something in any case.
Code above this already tests if si->v is NULL; indicating that it can
be NULL (and it can be). Therefore, check if it's NULL again before
attempting to dereference it again.
At present this cannot be the case, but guard against it anyway, making
sure to fill the result buffer with something in any case.
Code above this already tests if si->v is NULL; indicating that it can
be NULL (and it can be). Therefore, check if it's NULL again before
attempting to dereference it again.
At present this cannot be the case, but guard against it anyway, making
sure to fill the result buffer with something in any case.
These modules would not check whether the target channel existed
ircd-side, instead failing on their chanuser_find call and causing an
assertion failure. Add a proper check instead.
Aaron Jones [Mon, 22 Feb 2021 19:43:35 +0000 (19:43 +0000)]
modules/scripting/perl: make non-unloadable
Reloading this module causes services to segfault because the
PERL_SYS_INIT3() macro should only be called once during the entire
lifetime of the process [1]. Allowing it to be unloaded thus carries the
risk that it will be reloaded (or, at a later date, loaded again).
I tried to (ab)use Mowgli's global storage API to only call it once
(regardless of how many times it's loaded), and to not call the
PERL_SYS_TERM() macro at all, but this only lead to a different crash on
reload: trying to allocate a little less than 100 TiB of memory (!).
If a Perl expert comes along and weighs in, this commit can be reverted
and the underlying problem fixed. Nonetheless, libperl did exhibit *dozens*
of uses of unintialized data on reload (confirmed by valgrind), followed by
a segmentation fault even if we skip calling PERL_SYS_INIT3() again
(because, naturally, such a large allocation will usually return NULL, and
it apparently doesn't deal with that).
Aaron Jones [Sun, 21 Feb 2021 23:08:41 +0000 (23:08 +0000)]
README.md, GIT-Access.txt: Some small improvements
- Recommend an explicit directory name for the clone, to avoid cloning
into ~/atheme/ if the user runs the `git clone` operation in their
home directory. Atheme defaults to installing to ~/atheme/, and you
cannot install Atheme to its source directory. [1]
- Recommend the use of the `--recursive` option to `git clone` in
`README.md`, as it was already recommended in `GIT-Access.txt`. [1]
- Provide alternative command sequences for people who have very old
versions of git, which may not even support the `--init` option of
`git submodule update`, let alone the `--recursive` option of
`git clone`.
- Quote a filesystem path.
- Tidy up the more information section in the bottom of `README.md`.
[1] Suggested by GitHub user @PeGaSuS-Coder in PR #764