Andre Noll [Mon, 15 May 2023 16:35:30 +0000 (18:35 +0200)]
openssl: Use the EVP library for RSA private decryption.
This is the counterpart of the previous commit which converted the
public RSA encryption. We employ the HAVE_OSSL_PARAM macro again to
distinguish between the openssl-1 and openssl-3 cases.
Andre Noll [Sun, 7 May 2023 15:49:58 +0000 (17:49 +0200)]
openssl: Use the EVP library for RSA public encryption.
Many functions related to RSA have been deprecated in openssl-3. Users
of the deprecated API are expected to switch to the high-level
cryptographic functions of the EVP library which ships together
with openssl.
Since openssl-1.0 is still supported and even openssl-1.1 lacks some
of the features we need for EVP, for example OSSL_PARAM_construct_BN(),
we check for this symbol at configure time and use #ifdefs in openssl.c
to compile the code conditionally depending on the value of the new
HAVE_OSSL_PARAM preprocessor macro. The code should work with both
old and new openssl versions.
apc_get_pubkey() used to call RSA_size() to obtain the key size in
bytes for the return value, but RSA_size() is one of the functions
that got deprecated in openssl-3. So modify read_public_key() to
return the number of bits of the modulus (rather than the constant
one), and use 1/8 of this number as the return value.
Andre Noll [Sun, 7 May 2023 16:01:43 +0000 (18:01 +0200)]
apc_priv_decrypt: Let the callee allocate the buffer.
This complements the previous commit which made the analogous
change for public encryption. Passing char ** instead of char * to
apc_priv_decrypt() allows us to get rid of the magic 1024 constant
in client_common.c.
Andre Noll [Tue, 2 May 2023 21:56:26 +0000 (23:56 +0200)]
apc_pub_encrypt: Let the callee allocate the buffer.
Change the encryption routine of the apc API to allocate a suitably
sized buffer itself. Currently, the caller has to guess the size of the
buffer to pass to the function and we reuse our 4k handshake buffer for
that. While 4k is is plenty at the moment, that may change, and it's
always better to use the exact size if it is readily available. This
is the case here because the required buffer size is just the number
of bits of the modulus of the key.
Andre Noll [Tue, 2 May 2023 19:52:50 +0000 (21:52 +0200)]
openssl: Assume that openssl allocation functions functions succeed.
We do the same thing with malloc() and friends, so replace error
checking by assertions whenever OOM is the only possible error reason.
Also add assertions for EVP_MD_CTX_new(), whose return value was not
checked at all.
Andre Noll [Tue, 2 May 2023 19:16:29 +0000 (21:16 +0200)]
openssl: Introduce openssl_perror().
Openssl has a decent error reporting framework, but we only employ
it if get_random_bytes_or_die() fails. This patch abstracts out a
new helper which prints the error string of the earliest error code
from the thread's error queue. We make the helper return -E_OPENSSL
unconditionally as this simplifies callers a bit.
Only get_random_bytes_or_die() calls the new helper for now but
additional callers will be added in subsequent commits.
Andre Noll [Mon, 1 May 2023 19:43:18 +0000 (21:43 +0200)]
openssl: Don't pass pointers to RSA structures around.
The RSA structure has been made opaque in openssl-3. As a preparation
for not using this structure any more, pass pointers to the containing
asymmetric key structure instead.
Andre Noll [Sun, 7 May 2023 14:40:26 +0000 (16:40 +0200)]
client: Check buffer size returned by apc_priv_decrypt().
The decoded challenge buffer contains the challenge and the two session
keys but nothing else. So we know its size up-front and should fail
the handshake if the size of the rsa-decrypted buffer differs.
Andre Noll [Sun, 28 Apr 2024 22:52:21 +0000 (00:52 +0200)]
Change color of signature and tar icons.
These icons are currently black, which looks nice on the white
background of the releases page. However, all other pages use a black
background, and it would be nice to extend this to the releases page
page as well (by teaching it to honor our para.css file). As a first
step, switch to grey icon colors as these look nice on both a black
and a white background.
Andre Noll [Sun, 28 Apr 2024 21:09:35 +0000 (23:09 +0200)]
manual: Avoid duplicate section headings.
There exist two "Examples" and two "Troubleshooting"
sections. Unfortunately the discount markdown converter is
unable to create a working table of contents section in this
situation: both links of the table of contents jump to the first
Examples/Troubleshooting section.
Andre Noll [Sun, 28 Apr 2024 19:34:27 +0000 (21:34 +0200)]
manual: Fix local links.
All local links broke after an upgrade of the discount markdown
converter, because this changed the way the anchors of section headings
are encoded. This commit should fix all broken URI fragments.
Andre Noll [Tue, 30 May 2023 22:11:14 +0000 (00:11 +0200)]
Compile with -Wsuggest-attribute=malloc.
We already employ this attribute extensively to help the compiler
improve optimization. However, a few malloc-like functions were not
yet marked with __malloc. Fix that and enable the warning to make
sure that new malloc-like functions get marked.
Since not all supported compilers know about this warning option, we
need to check at compile time whether the option is supported. Thanks
to the existing cc-option make(1) function, this is a simple one-liner
for Makefile.real.
Andre Noll [Tue, 9 May 2023 18:02:09 +0000 (20:02 +0200)]
server: No longer accept "sideband" and "aes_ctr128" features.
Both features are used unconditionally since commit d44413588dd7
(v0.6.3-27) from three years ago when the client stopped to request
the feature. We don't need to support clients older than that any more,
so fail the request if these features are still requested.
Clarify the comment about the sha256 feature while at it.
Andre Noll [Sun, 24 Dec 2023 15:43:04 +0000 (16:43 +0100)]
Merge topic branch t/crypt-cleanups into master
This bunch of mostry trivial changes can be merged early, before the
openssl code is converted to use the EVP API. The topic was cooking
in next for six months.
* refs/heads/t/crypt-cleanups:
openssl: Assign bignums in canonical order.
openssl: Unify naming of public key structures.
openssl: Rename read_private_rsa_params() -> read_openssh_private_key().
openssl: Rename read_rsa_bignums() -> read_public_key().
openssl: Dedox crypt_init().
server: Improve "loading pubkey" log message.
gcrypt: Remove pointless state variable.
client: Reduce line length.
Andre Noll [Sun, 15 Oct 2023 15:54:41 +0000 (17:54 +0200)]
Merge topic branch t/afs-ls-a into master
A new feature for the ls command. Unfortunately, several bugs were
found after the topic graduated to next, so the series contains a few
fixup commits on top of the single patch which implements the feature.
* refs/heads/t/afs-ls-a:
afs: Really fix memory leak in mood_load().
afs: Fix memory leak in mood_load().
playlist: Fix error handling of playlist_load().
server: Fix NULL pointer dereference in com_ls().
Implement ls --admissible=m/foo.
Andre Noll [Mon, 12 Jun 2023 23:14:07 +0000 (01:14 +0200)]
playlist: Fix error handling of playlist_load().
We open a fresh score table if the result pointer is not NULL,
indicating that we are called from com_ls() (with -a=p/foo) rather
than from com_select(). However, if an error occurs afterwards, we
call score_close() unconditionally. This is wrong in the result ==
NULL case (com_select()) because it closes the global score table
which is expected to stay open.
The result is a UAF, which is diagnosed by valgrind as follows:
==4767== Invalid read of size 4
==4767== at 0x408C51E: osl_add_and_get_row (osl.c:1216)
==4767== by 0x408CA99: osl_add_row (osl.c:1348)
==4767== by 0x8060648: score_add (score.c:116)
==4767== by 0x805F08C: add_to_score_table (mood.c:451)
==4767== by 0x805FA3E: mood_load (mood.c:650)
==4767== by 0x8057ECF: activate_mood_or_playlist (afs.c:447)
==4767== by 0x8059637: com_select_callback (afs.c:1005)
Andre Noll [Mon, 12 Jun 2023 16:06:10 +0000 (18:06 +0200)]
server: Fix NULL pointer dereference in com_ls().
The previous commit which extended the -a option of the ls command
to accept an optional argument introduced the following flaw: If the
argument of -a corresponds to the name of a mood for which no files
are admissible, the server crashes due to a NULL pointer dereference
because mood_load() leaves the mood instance pointer uninitialized
although it returns zero, indicating success.
This behaviour of mood_load() contradicts the promises made in
its documentation. Fix mood_load() by not special-casing the "zero
admissible files" case, which even simplifies the code a bit. If all
goes well but no files turn out to be admissible, we now open the
score table anyway and set the mood pointer to the allocated mood as
usual. Since get_statistics() may now be called with zero admissible
files, we have to add a check there before dividing by the number of
admissible files,
Andre Noll [Wed, 17 May 2023 20:13:55 +0000 (22:13 +0200)]
audiod: Fix error checking in init_default_filters().
We ignore the return value of add_filter() instead of assigning it to
ret as usual, then test ret anyway. That's clearly bogus, even more
so since with the old code ret can never be negative at this point, so
the subsequent condition for the subsequent jump to out: is never true.
Andre Noll [Wed, 19 Oct 2022 19:56:51 +0000 (21:56 +0200)]
server: Implement ls --limit.
The new option is quite easy to implement. The patch actually removes
more lines from aft.c than it adds, but this is just because the code
which loops over all matching files was duplicated across the two
branches of the clause which checks whether --reverse was given. The
branches can easily be combined.
Andre Noll [Sat, 22 Oct 2022 19:54:29 +0000 (21:54 +0200)]
server: Implement select -verbose.
Just set ->pbout to NULL if the new option is not given. This supresses
normal output while error messages still make it to the client because
those are sent with afs_error().
Andre Noll [Sun, 7 May 2023 15:16:52 +0000 (17:16 +0200)]
openssl: Assign bignums in canonical order.
The order of the bignums stored in the private key is n, e, d, iqmp, p,
q. We read the bignums in this order, so assign the members of the RSA
structure in the same order. This does not really matter, but still..
Andre Noll [Tue, 2 May 2023 20:28:56 +0000 (22:28 +0200)]
openssl: Unify naming of public key structures.
The pointers to private key structures are all called "priv", but for
their public counterparts we often use "key" rather than "pub". Fix
that to improve readability.
Andre Noll [Wed, 3 May 2023 18:03:18 +0000 (20:03 +0200)]
openssl: Dedox crypt_init().
The API of this function is documented in crypt.h while the comment
in openssl.c describes openssl specific implementation details which
do not need doxygen annotations.
Andre Noll [Sat, 29 Apr 2023 21:23:32 +0000 (23:23 +0200)]
crypt: Deprecate PEM keys.
Users have been advised since 2018 to create RFC4716 keys (see
commit 9e2b093bed5d), and this has been the default key format for
ssh-keygen(1) for a long time as well. Upgrade the severity of the
existing log message from info to warning to encourage users at
runtime to replace their old keys.
Andre Noll [Tue, 9 May 2023 17:42:21 +0000 (19:42 +0200)]
client: Fix has_feature().
The function returns bool, so a return value of zero is regarded as
false. Consequently, server feature #0 (sha256) is not detected even
if it is announced by the server, and therefore the client does not
request it. Hence both sides fall back to sha1.
Andre Noll [Sun, 7 May 2023 18:04:19 +0000 (20:04 +0200)]
afs: Fix memory leak in mood_load().
If mood_load() manages to load the mood but does not find any
admissible files, it does not deallocate the mood instance and does
not set up the global current_mood variable either. Plug the resulting
memory leak by destroying the mood also if there are no admissible
files (ret == 0).
Andre Noll [Wed, 23 Mar 2022 22:19:55 +0000 (23:19 +0100)]
Implement ls --admissible=m/foo.
Currently there can be only one score table at a time because the
functions of score.c refer to the global score_table variable.
To implement the new feature, we need to overcome this restriction
so that the callback of the ls command can populate an independent
score table to print its output without interfering with the score
table that is currently active.
This commit changes most functions of score.c to receive an additional
table pointer argument. All current users of the score table pass a
NULL pointer to instruct the functions to operate on the global score
table as before.
However, if the ls command is invoked with an optional mood argument
to -a. the callback calls mood_load(), followed by mood_loop() and
mood_unload(). The former returns an opaque handle which is then
passed to the other two functions to instruct them to operate on the
temporary score table instead of the global one.
To make the feature work for playlists as well, analogous functionality
is implemented in playlist.c. The new mop_loop() of aft.c performs
the disambiguation in a similar way as the activate_mood_or_playlist()
does. It is a bit simpler though, since the ls command does not have
to deal with NULL arguments and does not need to fall back to the
dummy mood.
Andre Noll [Thu, 11 May 2023 17:50:22 +0000 (19:50 +0200)]
Merge branch 'maint'
Two fixes for gcc-12 warnings, and another fix for a benign but
embarrassing braino in gcrypt.c.
* maint:
gcrypt: Fix return value of apc_get_pubkey().
error.h: Be more careful with error code masking.
mp3_afh: Drop unused fields from struct mp3header.
Andre Noll [Mon, 8 May 2023 19:25:30 +0000 (21:25 +0200)]
gcrypt: Fix return value of apc_get_pubkey().
The function is supposed to return the key size in bytes, but it
returns the number of *bits*. A consequence of this bug is that
RSA keys which are too short to encrypt our 128 byte buffer are not
rejected as they should be. This is not too serious because we'll fail
later during the encryption step. Fix the bug anyway and clarify the
documentation of apc_get_pubkey().
Andre Noll [Sat, 6 May 2023 14:49:56 +0000 (16:49 +0200)]
error.h: Be more careful with error code masking.
It should never happen that two or more of the three special high bits
(osl, lopsub, system) are set in an integer that stores a paraslash
error value, but gcc-12 can't prove this and complains as follows:
Andre Noll [Sat, 6 May 2023 14:47:21 +0000 (16:47 +0200)]
mp3_afh: Drop unused fields from struct mp3header.
These are never initialized, but still checked in compare_headers(), so
gcc-12 is right when it complains about uninitialized use. Fix this by
simply removing the uninitialized fields and the comparisons. Fix also
a whitespace issue in the definition of compare_headers() while at it.
Andre Noll [Sun, 25 Sep 2022 19:17:38 +0000 (21:17 +0200)]
fd: Simplify and move for_each_file_in_dir().
With only one user it can be static in aft.c. Modify the function
so that it no longer changes the current working directory, remove
para_opendir() because it is unused now, dedox the documentation and
streamline it a bit.
Andre Noll [Tue, 1 Nov 2022 20:55:33 +0000 (21:55 +0100)]
fd.c: Improve error checking of para_mkdir().
The old code returned success in case the pathname existed but was
no directory, so try to improve on this a bit. However, don't be
over-zealous as any pathname based approach won't be bullet-proof
because the file identified by the pathname may change at any time.
Andre Noll [Sun, 25 Sep 2022 20:35:16 +0000 (22:35 +0200)]
fd: Revamp para_mkdir().
It has two callers which both pass the mode value 0777 and contain
extra code to regard the EEXIST error case as a success. Move the
common bits into the wrapper and improve the documentation.
Andre Noll [Sun, 25 Sep 2022 20:01:25 +0000 (22:01 +0200)]
fd: Improve read_pattern(), rename it to read_and_compare().
The old name was a poor choice because the pattern argument actually
is neither a regular expression nor a filename pattern.
More importantly, the function receives a buffer size and tries
to read this many bytes but then compares only the first part of
the received buffer to the expected string. This is a rather weird
calling convention.
The only two callers are the http sender and receiver which both
call the function during the initial handshake where no other data is
available. Thus we can change the function to read only the minimal
amount of data (length of the expected string), and drop the bufsize
parameter.
Remove the unnecessary log message in the error case and streamline
the documentation while at it.
Andre Noll [Sun, 25 Sep 2022 20:58:21 +0000 (22:58 +0200)]
fd: Remove log message from para_munmap().
Low-level functions like this should leave it to the caller to log
the error. Extend the documentation a bit while at it to document
the fact that passing NULL is OK.
Andre Noll [Sun, 25 Sep 2022 18:57:16 +0000 (20:57 +0200)]
fd: Open-code para_chdir().
Another public trivial wrapper that can go away because it has only
a single caller. POSIX says
Upon successful completion, 0 shall be returned. Otherwise, −1 shall
be returned, the current working directory shall remain unchanged,
and errno shall be set to indicate the error.
So the new check against zero is equivalent to the old code which
checked whether the return value is non-negative.
Andre Noll [Sun, 25 Sep 2022 18:45:40 +0000 (20:45 +0200)]
fd: Remove file_exists().
Open-coding this function actually improves code readability. The
function name was a misnomer anyway because any error from the stat()
call (such as EACCES) was reported as "file does not exist".
Andre Noll [Sun, 25 Sep 2022 15:57:29 +0000 (17:57 +0200)]
fd: Improve documentation of xwritev().
This is another essential helper which was poorly documented. In
particular the EINTR and short write cases were not covered, and it
was left open what a return value of zero means.
Omit the DCCP-specific part and the sentence which explains what
EAGAIN means.
Andre Noll [Thu, 22 Sep 2022 20:34:14 +0000 (22:34 +0200)]
fd: Improve documentation of write_all().
The name of this public function is a bit of a misnomer, so be at
least clear in the one-line description what the function does in
the EAGAIN case or if a short write occurs.
Andre Noll [Fri, 30 Dec 2022 14:08:59 +0000 (15:08 +0100)]
Consolidate EOF error codes.
Currently we have ~15 error codes which indicate an EOF condition. One
should suffice, so drop all codes except the generic E_EOF and use
that everywhere.
Andre Noll [Fri, 30 Dec 2022 13:47:46 +0000 (14:47 +0100)]
sched: Improve error diagnostics.
Currently the error code of the negative return value
from ->post_monitor() is not logged anywhere under normal
conditions. Instead we log "[dead]" in unlink_and_free_task(). Replace
this by a more meaningful message in task_reap().
Andre Noll [Sun, 13 Nov 2022 00:33:17 +0000 (01:33 +0100)]
build: Activate warnings and LTO on *BSD.
Newer versions of BSD ship compilers/packages which no longer
throw warnings, so activate the warnings on all platforms. Also LTO
(link-time optimization) seems to work on the test machines now,
so activate this as well.
Tested on FreeBSD-13.1 with clang-13.0.0 and on NetBSD-9.3 with
gcc-7.5.0.
Andre Noll [Thu, 29 Sep 2022 15:52:45 +0000 (17:52 +0200)]
Add two new tests for para_server.
In a (non-public) development branch the add subcommand was broken
although t0004-server exercises this subcommand and reported no
error. The bug went unnoticed because it would only bite when the
subcommand was given a directory to add, but the test specifies a
pathname which refers to a regular file.
To detect such breakage early, add a test which tries to add a
directory and another which exercises the rm command.
Andre Noll [Sun, 25 Sep 2022 22:01:48 +0000 (00:01 +0200)]
Manually tweak Doxyfile to squash warnings.
The Doxyfile introduced by the previous commit (created by running doxygen -u)
causes doxygen to complain:
warning: Tag 'TCL_SUBST' at line 260 of file '-' has become obsolete.
To avoid this warning please remove this line from your configuration file or upgrade it using "doxygen -u"
warning: argument 'a4wide' for option PAPER_TYPE is not a valid enum value
Using the default: a4!
Andre Noll [Sun, 25 Sep 2022 21:27:17 +0000 (23:27 +0200)]
Update DOXYFILE.
The patched file was created with doxygen -u with no manual editing. We
picked doxygen-1.8.17 although that's already a bit old because this
version ships with Ubuntu-20.04. However, this version generates a file
list (shown on the Documentation page) which lacks the description
column, so we use a self-compiled doxygen executable for the time
being.
Andre Noll [Mon, 30 Jan 2023 14:10:32 +0000 (15:10 +0100)]
aft: Always copy and compare full hash value.
Although we switched to 32 byte hash function in paraslash-0.7.0,
we kept comparing only the first 20 bytes to verify that the file
has not changed. Also the ls output and the status items contained
only the first 20 bytes of the hash value.
Andre Noll [Tue, 24 Jan 2023 22:13:55 +0000 (23:13 +0100)]
server: Don't save bogus chunk table for aac files.
The audio file selector stores the chunk table of each audio file
as an osl disk object. Since the aac audio format handler employs
dynamic chunks, these on-disk chunk tables of aac files will never
be consulted for streaming. They exist only for consistency with the
other audio formats and should be empty.
Due to a mis-computation of the chunk table size in the callback of
the add command we happen to store the serialized lopsub parse result
as the chunk table.
This is a benign bug since it only affects the ls command, and only
if -l=c is given to print the chunk table.
Andre Noll [Thu, 6 Oct 2022 15:12:13 +0000 (17:12 +0200)]
Fix memory leak in para_play().
We leak one filter parse result per audio file played. Valgrind reports:
==24559== 24 (12 direct, 12 indirect) bytes in 1 blocks are definitely lost in loss record 34 of 104
==24559== at 0x4044B0B: calloc (vg_replace_malloc.c:1328)
==24559== by 0x453A997: lls_parse (lopsub.c:768)
==24559== by 0x8057612: filter_setup (filter_common.c:98)
==24559== by 0x80500A4: load_file (play.c:377)
==24559== by 0x80500A4: load_next_file (play.c:454)
==24559== by 0x80500A4: play_post_monitor (play.c:1154)
==24559== by 0x8051110: call_post_monitor (sched.c:80)
==24559== by 0x8051110: sched_post_monitor (sched.c:106)
==24559== by 0x8051110: schedule (sched.c:148)
==24559== by 0x804EB80: main (play.c:1217)
Andre Noll [Tue, 24 Jan 2023 18:57:33 +0000 (19:57 +0100)]
server: ls -l=c: Don't print chunk table in case of dynamic chunks.
The chunk table stored in the osl disk object of the paraslash
database is useless for audio formats which support dynamic chunks
(aac only). Omit this part of the ls output.
Andre Noll [Tue, 24 Jan 2023 18:16:50 +0000 (19:16 +0100)]
server: Fix ls -l=c.
This classic copy+paste bug caused ls -l=c to work as if -l=m had
been given. Introduced seven years ago in commit 7af252cbfe13 (server:
Convert com_ls() to lopsub).
Andre Noll [Tue, 17 Jan 2023 15:29:16 +0000 (16:29 +0100)]
Merge topic branch t/ff-compat into master
A single commit which removes support for the old syntax of the ff
command where negative values could be specified with a postfix such
as "ff 30-". This syntax has long been deprecated.
* refs/heads/t/ff-compat:
server: Remove compatibility code of com_ff().
Andre Noll [Thu, 1 Dec 2022 17:08:44 +0000 (18:08 +0100)]
Merge topic branch t/openssl-3 into master
Two patches. The first suppresses warnings when compiling against
openssl-3, the second switches the two hash functions over to the
EVP API. More work is needed but it does not hurt to merge this first
step now.
* refs/heads/t/openssl-3:
openssl: Switch to evp API for sha1 and sha256.
openssl: Deactivate openssl-3 warnings for now.