Cleanup of the conversion-safety warnings exposed by enabling
-Wconversion / -Wsign-compare in the previous commit, plus guard
clauses at the few places where unsigned arithmetic could actually
misbehave.
Build:
- configure.ac drops -Wno-error=conversion and
-Wno-error=float-conversion. Only -Wno-error=sign-conversion and
-Wno-error=sign-compare remain, gating the ~230 sign warnings
inherited from upstream that will be cleaned up in follow-ups.
Type / conversion fixes (no behaviour change):
- Length-like locals in command/cmd_ac.c, command/cmd_funcs.c,
pgp/gpg.c, tools/autocomplete.c, tools/parser.c and ui/mucwin.c
switched from int to size_t / glong (matching strlen /
g_utf8_strlen return type) so we no longer need an (int) cast and
loop counters / array sizes stay in their natural unsigned domain.
- g_timer_elapsed / GTimeSpan -> int casts in session.c, iq.c,
core.c, server_events.c, window.c.
- _win_print_wrapped: indent parameter and local curx/maxx switched
from size_t to int to match _win_indent / getcurx / getmaxx.
- Port casts (int -> unsigned short) at the libstrophe boundary in
connection.c and session.c, each preceded by
g_assert(port >= 0 && port <= UINT16_MAX) so the truncation is
documented at the call-site.
- curl_off_t / fread size_t results cast at usage in http_upload.c,
http_download.c, omemo/crypto.c.
- strtoul results cast to uint32_t in xmpp/omemo.c and omemo/omemo.c
where device/prekey IDs are genuinely 32-bit.
- config/color.c: fg/bg/palette indices switched to `short`
end-to-end (find_col, color_hash, find_closest_col,
_color_pair_cache_get, cache.pairs), so the ncurses init_pair
boundary needs at most one (short)i cast for the cache index. Also
TODO-noted: init_extended_pair is needed for >15-bit palettes.
- xmpp/avatar.c: float arithmetic explicitly casts its int operands.
- tests/functionaltests/proftest.c: read() result handling uses
size_t for the accumulator, _read_output returns ssize_t, and the
buffer-shift check happens before space subtraction so the
expression cannot underflow.
Real-risk guard clauses (the part that actually fixes bugs):
- src/ui/statusbar.c _tabs_width: `end > opened_tabs - 1` rewritten
as `end < opened_tabs` so opened_tabs == 0 no longer underflows.
- src/ui/statusbar.c _status_bar_draw_extended_tabs: the mirror
comparison rewritten as `end >= opened_tabs`.
- src/ui/statusbar.c status_bar_draw: replaced
`MAX(0, getmaxx - (int)_tabs_width)` with an explicit precheck
before subtraction.
- src/omemo/omemo.c prekey selection: prekey_index is now uint32_t
and randomized into an unsigned buffer, so modulo with prekeys_len
cannot yield a negative index for g_list_nth_data.
- src/omemo/crypto.c omemo_decrypt_func: PKCS#5/PKCS#7 unpadding
reads `plaintext[plaintext_len - 1]`, which would underflow on a
malformed empty ciphertext and read past the heap buffer. Reject
plaintext_len == 0 before the padding peek and validate the
padding byte against the buffer length before the unpad loop.
Initialise plaintext = NULL so the early `goto out` cannot free
uninitialised memory.
- src/ui/inputwin.c (4 mbrlen sites) and src/ui/window.c
_win_print_wrapped: mbrlen() returns 0 for the null wide
character. The existing checks rejected (size_t)-1 / -2 but
treated 0 as a valid step, so the surrounding loops would either
advance by SIZE_MAX (i += ch_len - 1) or spin in place
(word_pos += 0 forever). Add `|| ch_len == 0` to each guard;
inside the spell-check word-emission loop also fall back to a
one-byte advance.
- Defensive `len > 0 ? len - 1 : 0` prechecks at the strlen-based
g_strndup / loop sites in ui/console.c, plugins/c_api.c and
plugins/python_plugins.c.
recp elements were accessed without verifying the success of
_ox_key_lookup().
Also fix several memory leaks.
gpgme_data_new() followed 'gpgme_data_new_from_mem' was redundant.
The gpgme_set_passphrase_cb function expects a function
pointer of type gpgme_passphrase_cb_t.
The gpgme_passphrase_cb_t typedef specifies a function that returns
gpgme_error_t so return GPG_ERR_NO_ERROR instead of 0.
Several users have reported segfaults when starting up profanity which
has OMEMO support, but OMEMO is not set up yet.
@StefanKropp has been able to reproduce this and tracked it down to
`_load_identity()` calling `omemo_known_devices_keyfile_save()`.
The latter then calls `save_keyfile()` which calls
`g_key_file_save_to_file()`. This can then fail if one of the first two
strings is NULL and won't set the `error` on return. In its error handling
`save_keyfile()` unconditionally dereferences `error` which leads to the
segfault.
Fix this and also go through the entire codebase and verify that the usage
of `GError` is done correctly.
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
Replace deprecated gpgme_key_get_string_attr with modern API
This commit fixes the build failure against GPGME >= 2.0.0 where
gpgme_key_get_string_attr and GPGME_ATTR_EMAIL were removed.
Changes made:
- Replaced direct call to gpgme_key_get_string_attr(key, GPGME_ATTR_EMAIL, NULL, 0)
- Added new helper function _gpgme_key_get_email() with backwards compatibility
- Function uses conditional compilation to support both old and new GPGME versions
Backwards Compatibility:
- GPGME < 2.0.0: Uses gpgme_key_get_string_attr() if GPGME_ATTR_EMAIL is available
- GPGME >= 2.0.0: Uses modern key->uids->email API
Forward Compatibility:
- Code compiles successfully with GPGME 2.0.0+ where deprecated functions are removed
- Uses modern GPGME API that iterates through key user IDs to find email addresses
Testing:
- Tested with GPGME 1.18.0 (backwards compatibility confirmed)
- Tested compilation compatibility for both old and new GPGME versions
- Verified the exact error from issue #2048 is resolved
- Confirmed no regression in functionality
Fixes: #2048
Resolves compilation error: 'gpgme_key_get_string_attr' undeclared
Resolves compilation error: 'GPGME_ATTR_EMAIL' undeclared
Instead of adding stuff to `_shutdown()`, we can now register a shutdown
routine from the respective `init()` function of our modules.
This also has the advantage, that we're sure they're called in reverse
order from how the initialization happened.
I didn't simply use `atexit()` because POSIX says that the number of
possible callbacks is limited (min 32) and I was not sure whether
we will maybe extend this number at one point.
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
Refactor `p_gpg_list_keys`
Add `/pgp autoimport` command,
it's not described in XEP-0027, but used in some clients,
such as PSI, Pidgin. It will autoimport keys received with
`/pgp sendpub`, in plain text as a message, or using features,
provided in other clients. It doesn't autoassign them, but shows
command to assign, letting user to decide.
Improve documentation for some preexisting functions
Add contact argument to `/pgp sendpub`
Command allows to share your PGP pub key with ease,
it's not described in XEP-0027, but used in some clients,
such as PSI, Pidgin.
Fix typos
Minor improvements
Under certain circumstances setting plain_str[len] to 0 might lead to crash
and it does not follow the best practices as well.
This change allows better handling of buffer copying and prevents crash.
Maybe we can make this configurable later.
So users have the freedom to be more strict.
This commit partly reverts 62018f48c5.
Example to edit trust level:
```
gpg --edit-key somekeyid
gpg (GnuPG) 2.3.4; Copyright (C) 2021 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
pub rsa4096/keyid
created: 2020-06-26 expires: 2022-06-26 usage: SC
trust: unknown validity: full
sub rsa4096/keyid
created: 2020-06-26 expires: 2022-06-26 usage: E
[ full ] (1). xmpp:user@domain.de
gpg> trust
pub rsa4096/keyid
created: 2020-06-26 expires: 2022-06-26 usage: SC
trust: unknown validity: full
sub rsa4096/keyid
created: 2020-06-26 expires: 2022-06-26 usage: E
[ full ] (1). xmpp:user@domain.de
Please decide how far you trust this user to correctly verify other users' keys
(by looking at passports, checking fingerprints from different sources, etc.)
1 = I don't know or won't say
2 = I do NOT trust
3 = I trust marginally
4 = I trust fully
5 = I trust ultimately
m = back to the main menu
Your decision? 3
pub rsa4096/keyid
created: 2020-06-26 expires: 2022-06-26 usage: SC
trust: marginal validity: full
sub rsa4096/keyid
created: 2020-06-26 expires: 2022-06-26 usage: E
[ full ] (1). xmpp:user@domain.de
Please note that the shown key validity is not necessarily correct
unless you restart the program.
gpg> quit
```
* Added logging messages (INFO if key can not be used)
* Check owner_trust < GPGME_VALIDITY_MARGINAL
The key can not be used if the owner_trust is less than MARGINAL.
As all parts of the code invoking the `files_get_account_data_path()`
function did the same afterwards, a function has been added with the same
behavior.
1. create path
2. `mkdir` of that path
3. return final path
Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
Discovering Public Keys via PEP
* 4.3 Discovering Public Keys of a User
* 4.4 Requesting Public Keys
* Import Public Keys into GnuPG's local keyring.
Issue: #1331
src/pgp/gpg.c:p_ox_gpg_readkey
Used to read a public key from a file. The function will return the fingerprint
of the file and the base64 encoded key.
src/xmpp/ox.[hc]
ox_announce_public_key(const char* const filename) can be called from the /ox
announce <filename> command. The key within the file will be pushed on PEP and
the Metadata node will be set.
Issue: #1331