aboutsummaryrefslogtreecommitdiffstats
path: root/common (follow)
Commit message (Collapse)AuthorAgeFilesLines
...
* common: New flags for gnupg_spawn_processWerner Koch2022-03-183-9/+29
| | | | | | | | | * common/exechelp.h (GNUPG_SPAWN_KEEP_STDIN): New. (GNUPG_SPAWN_KEEP_STDOUT): New. (GNUPG_SPAWN_KEEP_STDERR): New. * common/exechelp-posix.c (do_exec): Add arg flags and implement new flags. * common/exechelp-w32.c (gnupg_spawn_process): Implement new flags.
* common: Fix a race condition removing stale lockfile.NIIBE Yutaka2022-03-181-9/+24
| | | | | | | | | | | * common/dotlock.c (read_lockfile): Return the file descriptor when R_FD is available. (dotlock_take_unix): Check the case the lockfile was already removed. -- GnuPG-bug-id: 5884 Signed-off-by: NIIBE Yutaka <[email protected]>
* common: More heavy test condition for t-dotlock.c.NIIBE Yutaka2022-03-181-4/+21
| | | | | | | | | | | * common/t-dotlock.c (lock_and_unlock): Use usleep and faster. Loop at least once. Use getrandom for random time. (main): Add new option --one-shot to run lock/unlock once. -- GnuPG-bug-id: 5884 Signed-off-by: NIIBE Yutaka <[email protected]>
* gpg: fix --enarmor with zero length source fileJussi Kivilinna2022-03-081-8/+0
| | | | | | | | | | | | | | | | | * common/iobuf.c (filter_flush): Remove "src_len == 0" check. * g10/compress-bz2.c (do_compress): Exit early if flush not forced and input length is zero. * g10/compress.c (do_compress): Likewise. -- Remove "(src_len == 0)" check in filter_flush which was introduced to fix compress failure caused by zero length flush from iobuf_close. However this check broke enarmoring file with length of zero. Patch instead fixes zero length flush problem in compress filters. GnuPG-bug-id: T5828 Signed-off-by: Jussi Kivilinna <[email protected]>
* iobuf: add zerocopy optimization for iobuf_writeJussi Kivilinna2022-03-081-6/+75
| | | | | | | | | | | | | | | * common/iobuf.c (filter_flush): Use 'iobuf->e_d' if configured. (iobuf_write): Configure 'iobuf->e_d' for 'filter_flush' if 'iobuf->d.buf' is empty and external buffer is larger than threshold. -- Zero-copy operation in iobuf_write() and filter_flush() allow bypassing 'iobuf->d.buf' for greater performance. This mainly helps OCB performance where additional memory copies through iobuf stack can take significant portion of program time. GnuPG-bug-id: T5828 Signed-off-by: Jussi Kivilinna <[email protected]>
* iobuf: add zerocopy optimization for iobuf_readJussi Kivilinna2022-03-082-14/+118
| | | | | | | | | | | | | | | | | | | * common/iobuf.h (iobuf_struct): Add 'e_d' substructure and members. * common/iobuf.c (IOBUF_ZEROCOPY_THRESHOLD): New. (iobuf_alloc): Clear 'iobuf->e_d'. (underflow_target): Use 'iobuf->e_d' when configured to bypass copying through 'iobuf->d.buf'. (iobuf_read): Configure 'iobuf->e_d' for 'underflow' if 'iobuf->d.buf' is empty and external buffer is larger than threshold. -- Zero-copy operation in iobuf_read() and underflow() allow bypassing 'iobuf->d.buf' for greater performance. This mainly helps OCB performance where additional memory copies through iobuf stack can take significant portion of program time. GnuPG-bug-id: T5828 Signed-off-by: Jussi Kivilinna <[email protected]>
* Use iobuf buffer size for temporary buffer sizeJussi Kivilinna2022-03-081-3/+4
| | | | | | | | | | | | | | * common/iobuf.c (iobuf_copy): Use iobuf buffer size for temporary buffers. * g10/plaintext.c (handle_plaintext, do_hash): Likewise. * g10/sign.c (sign_file): Likewise. -- As iobuf will have zerocopy operation for read/write, it is better to use same size buffers as iobuf for temporary copy buffers. GnuPG-bug-id: T5828 Signed-off-by: Jussi Kivilinna <[email protected]>
* common,w32: Support file names longer than MAX_PATH in iobuf.Werner Koch2022-03-081-18/+4
| | | | | * common/iobuf.c (direct_open): Use gpgrt_fname_to_wchar. (any8bitchar): Remove.
* common: Fix confusion of get_pk_algo_from_key.NIIBE Yutaka2022-03-041-4/+4
| | | | | | | | | * common/ssh-utils.c (ssh_public_key_in_base64): Fix the constants. -- Fixes-commit: 8e650dbd48fa5fde6d8f08154e6a892d495e9227 Signed-off-by: NIIBE Yutaka <[email protected]>
* scd: Let READKEY support --format=ssh option.NIIBE Yutaka2022-03-022-0/+292
| | | | | | | | | | | | * scd/command.c (do_readkey): Support --format=ssh option. * common/ssh-utils.c (ssh_public_key_in_base64): New. * common/ssh-utils.h (ssh_public_key_in_base64): New declaration. -- Code duplication (agent/command-ssh.c) will be cleaned up later. Signed-off-by: NIIBE Yutaka <[email protected]>
* sm: Fix use of value NONE in gnupg_isotime_t type.NIIBE Yutaka2022-02-181-0/+5
| | | | | | | | | | | | | | * common/gettime.h (GNUPG_ISOTIME_NONE): New. * sm/call-dirmngr.c (gpgsm_dirmngr_isvalid): Use it. * sm/certlist.c (gpgsm_add_to_certlist): Likewise. * sm/import.c (check_and_store): Likewise. * sm/keylist.c (list_cert_colon, list_cert_raw): Likewise. (list_cert_std): Likewise. * sm/sign.c (gpgsm_sign): Likewise. -- Signed-off-by: NIIBE Yutaka <[email protected]>
* doc: Typo fixes.Werner Koch2021-12-301-2/+2
| | | | --
* common: Add set_membuf_err.Werner Koch2021-12-202-0/+13
| | | | * common/membuf.c (set_membuf_err): New.
* w32: Prepare for the case gcrypt.h will not include winsock2.h.NIIBE Yutaka2021-12-174-1/+13
| | | | | | | | | | | | | | | * common/dynload.h: Include specific headers only. * common/exechelp-w32.c: Include <windows.h>. * common/gettime.c: Likewise. * common/utf8conv.c: Likewise. * tests/gpgscm/ffi.c: Likewise. * tools/gpgconf.c: Likewise. * configure.ac: Check winsock2.h, removing gl_HEADER_SYS_SOCKET. -- GnuPG-bug-id: 5731 Signed-off-by: NIIBE Yutaka <[email protected]>
* homedir: Avoid memory leaks on errorsJakub Jelen2021-11-241-0/+2
| | | | | | | | * common/homedir.c (unix_rootdir): Free allocated memory on error path -- GnuPG-bug-id: 5393 Signed-off-by: Jakub Jelen <[email protected]>
* gpg,gpgsm: Add option --min-rsa-length.Werner Koch2021-11-182-8/+27
| | | | | | | | | | | | | | | * common/compliance.c (min_compliant_rsa_length): New. (gnupg_pk_is_compliant): Take in account. (gnupg_pk_is_allowed): Ditto. (gnupg_set_compliance_extra_info): New. * g10/gpg.c (oMinRSALength): New. (opts): Add --min-rsa-length. (main): Set value. * g10/options.h (opt): Add field min_rsa_length. * sm/gpgsm.c (oMinRSALength): New. (opts): Add --min-rsa-length. (main): Set value. * sm/gpgsm.h (opt): Add field min_rsa_length.
* common,w32: New function read_w32_reg_string.Werner Koch2021-11-173-179/+65
| | | | | | | * common/w32-reg.c (get_root_key): Remove. (read_w32_registry_string): Turn into a wrapper for the gpgrt function. (read_w32_reg_string): New.
* common: Support MYPROC_SELF_EXE for SolarisWerner Koch2021-10-272-1/+3
| | | | | | | * common/homedir.c (MYPROC_SELF_EXE): Add case for SunOS. -- GnuPG-bug-id: 5671
* common: Silence warning from unix_rootdir on systems w/o /procWerner Koch2021-10-201-4/+6
| | | | | | | | | * common/homedir.c (unix_rootdir): Silence diagnostic in the common case. (MYPROC_SELF_EXE): Support NetBSD. -- GnuPG-bug-id: 5656
* common,w32: Do not always print "Garbled console data" warning.Werner Koch2021-10-201-2/+8
| | | | | * common/init.c (_init_common_subsystems): Silence message. --
* common: Respect gpgconf.ctl when looking up translationsIngo Klöcker2021-10-061-3/+3
| | | | | | | | | | | | | * common/i18n.c (i18n_init): Use gnupg_localedir() instead of LOCALEDIR. (i18n_localegettext): Ditto. * tools/gpgconf-comp.c (my_dgettext): Ditto. -- On Unix, gnupg_localedir() returns the locale directory relative to the root directory of the gnupg installation if specified in the gpgconf.ctl. Otherwise, it returns the built-in LOCALEDIR. GnuPG-bug-id: 5999
* dirmngr: New option --ignore-certWerner Koch2021-10-061-1/+2
| | | | | | | | | | | | | | | | * dirmngr/dirmngr.h (struct fingerprint_list_s): Add field binlen. (opt): Add field ignored_certs. * dirmngr/dirmngr.c: Add option --ignore-cert (parse_rereadable_options): Handle that option. (parse_ocsp_signer): Rename to ... (parse_fingerprint_item): this and add two args. * dirmngr/certcache.c (put_cert): Ignore all to be igored certs. Change callers to handle the new error return. -- This option is useful as a workaround in case we ill run into other chain validation errors like what we fixed in GnuPG-bug-id: 5639
* common: Support gpgconf.ctl also for BSDs.Werner Koch2021-10-011-10/+25
| | | | | | | | | | * common/homedir.c (MYPROC_SELF_EXE): New. (unix_rootdir): Use it here. Also support GNUPG_BUILD_ROOT as fallback. -- In addition this adds a fallback method for AIX etc which do not have an easy way to get the info.
* common: Add keyword sysconfdir to the optional gpgconf.ctl file.Werner Koch2021-10-011-18/+69
| | | | | | | | | | * common/homedir.c (unix_rootdir): Add arg want_sysconfdir. (gnupg_sysconfdir): Return it. -- Our regression test suite has the problem that we can't disable the use of the global config files or test them using the regualr binaries. This new keyword will allow us to overcome the problem.
* common: Support a gpgconf.ctl file under Unix.Werner Koch2021-09-171-17/+252
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * common/homedir.c (unix_rootdir): New. (gnupg_bindir): Use it. (gnupg_libexecdir): Use it. (gnupg_libdir): Use it. (gnupg_datadir): Use it. (gnupg_localedir): Use it. -- This feature is useful for building and using an AppImage version of gnupg and probably also for some other use cases. GnuPG-bug-id: 5999 Here is a sample gpgconf.ctl file --8<---------------cut here---------------start------------->8--- # gpgconf.ctl # # This file is used to change the directories where the gpg components # are installed. It does not change the configuration directories. # The file is expected in the same directory as gpgconf. The physical # installation directories are evaluated and no symlinks. Blank lines # and lines starting with pound signed are ignored. No errors are # printed for unknown keywords or commands. The only defined key for # now is "rootdir" which must be followed by one optional space, an # equal sign, and the value for the root directory. Environment # variables are substituted in standard shell manner, the final value # must start with a slash, trailing slashed are stripped. rootdir = $APPDIR/gnupg --8<---------------cut here---------------end--------------->8---
* common: New function substitute_envvars.Werner Koch2021-09-173-0/+206
| | | | | | | | | | * common/stringhelp.c (substitute_envvars): New. Based on code in gpg-connect-agent. * common/t-stringhelp.c: Include sysutils.h. (test_substitute_envvars): New. -- GnuPG-bug-id: 5599
* common: New envvar GNUPG_EXEC_DEBUG_FLAGS.Werner Koch2021-09-131-4/+16
| | | | | * common/exechelp-w32.c (gnupg_spawn_process_detached): Silence breakaway messages and turn them again into debug messages.
* common: Fix put_membuf.NIIBE Yutaka2021-08-271-1/+4
| | | | | | | | | | * common/membuf.c (put_membuf): Allow NULL for the second arg. -- There has been such a use case in keybox-blob.c. Signed-off-by: NIIBE Yutaka <[email protected]>
* common: Fix get_signal_name for GNU/Linux.NIIBE Yutaka2021-08-261-1/+3
| | | | | | | | | | * common/signal.c (get_signal_name): Use sigdescr_np if available. * configure.ac: Check the function. -- GnuPG-bug-id: 5568 Signed-off-by: NIIBE Yutaka <[email protected]>
* wkd: Fix client issue with leading or trailing spaces in user-ids.Werner Koch2021-08-204-18/+195
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * common/recsel.c (recsel_parse_expr): Add flag -t. * common/stringhelp.c: Remove assert.h. (strtokenize): Factor code out to do_strtokenize. (strtokenize_nt): New. (do_strtokenize): Add arg trim to support the strtokenize_nt. * common/t-stringhelp.c (test_strtokenize_nt): New test cases. * tools/wks-util.c (wks_list_key): Use strtokenize_nt and the recsel flag -t. -- This fixes a bug with user ids with leading spaces because: wks-client lists all mail addresses from the key and matches them to the requested mail address. If there are several user-ids all with the same mail address wks-client picks one of them and then extracts exactly that user id. However, here it does not match by the mail address but by the full user-id so that we can be sure that there will be only one user-id in the final key. The filter built expression unfortunately strips leading blanks but requires a verbatim match. Thus it won't find the user id again and errors out. The new -t flag and a non-trimming strtokenize solves the problem. Signed-off-by: Werner Koch <[email protected]>
* common,w32: Replace log_debug by log_info for InProcessJobsWerner Koch2021-08-181-3/+3
| | | | * common/exechelp-w32.c (gnupg_spawn_process_detached): Use log_info.
* w32: Move socketdir to LCOAL_APPDATAWerner Koch2021-08-114-85/+150
| | | | | | | | | | | | | | | | | | | | | | | * common/homedir.c (is_gnupg_default_homedir): Use standard_homedir instead of the constant which makes a difference on Windows. (_gnupg_socketdir_internal) [W32]: Move the directory to LOCAL_APPDATA. (gnupg_cachedir): Remove unsued function. * common/sysutils.c (gnupg_rmdir): New. * tools/gpgconf.c (main): s/rmdir/gnupg_rmdir/. -- That is actually a more correct directory than APPDATA. This fixes a problem with installations where the APPDATA is non a network drive and the resulting socket filename is truncated in our socket helper function (because we use sockaddr also for our local socket emulation on Windows). LOCAL_APPDATA is expected to be on the local box and thus in the majority of cases the resulting socket file name will be short enough. GnuPG-bug-id: 5537 Signed-off-by: Werner Koch <[email protected]>
* common: Pass XDG_SESSION_TYPE and QT_QPA_PLATFORM envvars to pinentryIngo Klöcker2021-08-021-0/+5
| | | | | | | | | | | | | * common/session-env.c (stdenvnames): Add XDG_SESSION_TYPE and QT_QPA_PLATFORM. -- On Unix systems (except Darwin), Qt uses those two environment variables additionally to DISPLAY and WAYLAND_DISPLAY to figure out whether to use X11 or Wayland. For example, QT_QPA_PLATFORM needs to be set to "wayland" to make Qt use Wayland on Gnome. GnuPG-bug-id: 3659
* kbx: Fix keyboxd searching with multiple patterns.Werner Koch2021-07-081-0/+10
| | | | | | | | | | | | | | | | | | | | * kbx/keybox-search-desc.h (struct keydb_search_desc): New flag name_used. * common/userids.c (classify_user_id): Set flag. * kbx/kbxserver.c (struct search_backing_store_s): New. (cmd_search): use a backing store for the const pointers. (kbxd_start_command_handler): Release the backing store. -- Well, the search object partly uses buffers but also const pointers (for strings and the serial number). This when assigning such objects to an another one we should really take a deep copy and not just copy the pointer. The more clean solution would have been to provide a storage option the search object but that needs checking the code at too many places so that I decided to use a separate backing store array here. Signed-off-by: Werner Koch <[email protected]>
* tests: Cope with broken Libgcrypt versionsWerner Koch2021-06-221-11/+27
| | | | | | | | | | | | | | * common/t-sexputil.c (test_ecc_uncompress): Ignore unknwon curve errors. -- For unknown reasons some versions of Fedora or RHEL provide a patched version of Libgcrypt with Brainpool support removed. We better ignore this error because it is a regression in 2.2.28 although that older versions could not used Brainpool keys. GnuPG-bug-id: 5502 Signed-off-by: Werner Koch <[email protected]>
* w32: Add fallback in case the Windows console can't cope with Unicode.Werner Koch2021-06-221-4/+18
| | | | | | | | | | | | | | | | | | | | | * common/ttyio.c (w32_write_console): Fallback to WriteConsoleA on error. -- To test this switch the Windows Console to "legacy mode" set LANG=de gpg --card-edit and enter an invalid command. The response contains an Umlaut and old Windows versions (and the legacy console) don't have a proper font installed for this. Without this patch this runs into a log_fatal error. The mitigation we implement is to fallback to WriteConsoleA, that is accepting wrong encoding and to print a note about the problem. GnuPG-bug-id: 5491
* gpg,sm: Simplify keyserver spec parsing.Werner Koch2021-06-162-74/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | * common/keyserver.h: Remove. * sm/gpgsm.h (struct keyserver_spec): Remove. (opt): Change keyserver to a strlist_t. * sm/gpgsm.c (keyserver_list_free): Remove. (parse_keyserver_line): Remove. (main): Store keyserver in an strlist. * sm/call-dirmngr.c (prepare_dirmngr): Adjust for the strlist. Avoid an ambiguity in dirmngr by adding a prefix if needed. * g10/options.h (struct keyserver_spec): Move definition from keyserver.h to here. Remove most fields. * g10/keyserver.c (free_keyserver_spec): Adjust. (cmp_keyserver_spec): Adjust. (parse_keyserver_uri): Simplify. (keyidlist): Remove fakev3 arg which does not make any sense because we don't even support v3 keys. -- We now rely on the dirmngr to parse the keyserver specs. Thus a bad specification will not be caught immediately. However, even before that dirmngr had stricter tests. Signed-off-by: Werner Koch <[email protected]> Ported-from: 9f586700ec4ceac97fd47cd799878a8847342ffa
* common: Allow for GCM decryption in de-vs mode.Werner Koch2021-06-021-1/+2
| | | | | | | | | | | * common/compliance.c (gnupg_cipher_is_allowed): Allow GCM for gpgsm in decrypt mode. * tests/cms/samplemsgs/pwri-sample.gcm.p7m: Remove duplicated authtag -- We allow GCM in de-vs mode for decryption although this has not been evaluation. It is decryption and thus no serious harm may happen.
* gpg: Partial fix for Unicode problem in output files.Werner Koch2021-05-251-1/+1
| | | | | | | | | | * g10/openfile.c (overwrite_filep): Use gnupg_access. -- As said, this is just an obvious but partial fix. We need to review things for the output module. Signed-off-by: Werner Koch <[email protected]>
* common: Annotate leaked memory in homedir.cWerner Koch2021-05-212-13/+61
| | | | | | | | | | | | | | | | | | | | | * g10/trustdb.c (how_to_fix_the_trustdb): Use gnupg_homedir. * common/homedir.c (standard_homedir): Annotate leaked memory. (gnupg_daemon_rootdir): Ditto. (gnupg_socketdir): Ditto. (gnupg_sysconfdir): Ditto. (gnupg_bindir): Ditto. (gnupg_libdir): Ditto. (gnupg_datadir): Ditto. (gnupg_localedir): Ditto. (gnupg_cachedir): Ditto. (gpg_agent_socket_name): Ditto. (dirmngr_socket_name): Ditto. (keyboxd_socket_name): Ditto. (get_default_pinentry_name): Ditto. (gnupg_module_name): Ditto. (default_homedir): Ditto. Make static. Signed-off-by: Werner Koch <[email protected]>
* common: Avoid double-freeJakub Jelen2021-05-201-0/+1
| | | | | | | | | | * common/name-value.c (do_nvc_parse): reset to null after ownership change -- Signed-off-by: Jakub Jelen <[email protected]> GnuPG-bug-id: 5393
* agent: Avoid memory leaks in error code paths.Jakub Jelen2021-05-201-0/+1
| | | | | | | | | | | | | | | | | | | | * agent/command.c (cmd_genkey): Use goto instead of return. * agent/cvt-openpgp.c (convert_from_openpgp_main): Ditto. * agent/genkey.c (agent_ask_new_passphrase): Fix typo to free correct pointer (agent_genkey): Release memory * agent/gpg-agent.c (check_own_socket): Free sockname * agent/protect-tool.c (read_key): Free buf. (agent_askpin): Free passphrase -- Signed-off-by: Jakub Jelen <[email protected]> Changed original patch to not add a free before a GPG_ERR_BUG. Signed-off-by: Werner Koch <[email protected]> GnuPG-bug-id: 5393
* gpg,gpgsm: Move use-keyboxd to the new conf file common.confWerner Koch2021-04-193-0/+182
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | * common/comopt.c, common/comopt.h: New. * common/Makefile.am: Add them. * g10/gpg.c: Include comopt.h. (main): Also parse common.conf. * sm/gpgsm.c: Include comopt.h. (main): Set a flag for the --no-logfile option. Parse common.conf. * tools/gpgconf-comp.c (known_options_gpg): Remove "use-keyboxd", add pseudo option "use_keyboxd". (known_pseudo_options_gpg): Add pseudo option "use_keyboxd". (known_options_gpgsm): Remove "use-keyboxd". * tests/openpgp/defs.scm (create-gpghome): Create common.conf. * doc/examples/common.conf: New. -- Note that --use-keybox still works but prints a warning. We will eventually remove this option becuase it was marked as an experimental feature anyway. It would be too confusing if gpg and gpgsm use different key storages. Further, other components (e.g. dirmngr or gpg-wks-client) which call gpg or gpgsm need to be aware that the keyboxd is used and pass that option on the command line. Now that common.conf is always read (even if --no-options is used) those tools will work instantly.
* common: New module to compute openpgp fingerprintsWerner Koch2021-04-163-0/+304
| | | | | | | | | | * common/openpgp-fpr.c: New. * common/Makefile.am (common_sources): Add it. -- This function is targeted to handle keys on smartcards. Signed-off-by: Werner Koch <[email protected]>
* common: Fix memory leaks.Jakub Jelen2021-04-132-2/+12
| | | | | | | | | | * common/name-value.c (do_nvc_parse): Free NAME. * common/recsel.c (recsel_parse_expr): Release SE_HEAD and EXPR_BUFFER. -- GnuPG-bug-id: 5393 Signed-off-by: Jakub Jelen <[email protected]>
* common: Fix gnupg_wait_processes, by skipping invalid PID.NIIBE Yutaka2021-04-081-1/+6
| | | | | | | | * common/exechelp-posix.c (gnupg_wait_processes): Skip invalid PID. -- Signed-off-by: NIIBE Yutaka <[email protected]>
* common: Make the compliance check more robust.Werner Koch2021-04-011-16/+58
| | | | | | | | | | | | | * common/compliance.c (get_compliance_cache): New. (gnupg_rng_is_compliant): Use per mode cache. (gnupg_gcrypt_is_compliant): Ditto. -- This addresses the problem tha the check might be called with different compliance values and thus it should return the corresponding cached result. Signed-off-by: Werner Koch <[email protected]>
* common: New function to uncompress an ECC public key.Werner Koch2021-03-263-0/+503
| | | | | | | | | | | | * common/sexputil.c (ec2os): New. (uncompress_ecc_q_in_canon_sexp): New. * common/t-sexputil.c (fail2): new. (test_ecc_uncompress): New. (main): Run new test. -- Signed-off-by: Werner Koch <[email protected]>
* indent: Modernize mem2str.Werner Koch2021-03-261-18/+20
| | | | --
* gpg: Support exporting Ed448 SSH key.NIIBE Yutaka2021-03-222-0/+29
| | | | | | | | | * common/openpgp-oid.c (oid_ed448, openpgp_oidbuf_is_ed448): New. (openpgp_oid_is_ed448): New. * common/util.h (openpgp_oid_is_ed448): New. * g10/export.c (export_one_ssh_key): Support Ed448 key. Signed-off-by: NIIBE Yutaka <[email protected]>