From 985fbac89cf20af7959c4efead97fa075cb04c5a Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Wed, 14 Jan 2026 20:21:56 -0600 Subject: [PATCH] Progress: Continue adding GPGME support. I'm getting closer to determining how to use GPGME to get what I want. This restructures the GPGME files. I am isolating this commit so that I can start focusing on adding negotiation support so that a key can be created and sent by both ends. I need to wrap up a lot of the TODOs. I also might need to restructure some of the logic to better handle the negotiation or hand shaking where the Public keys are generated and exchanged. Hopefully GPGME does not saves these in the system users GNUPG directory. --- data/build/tacocat/settings | 2 + .../program/kevux/tools/tacocat/main/common/type.h | 3 - sources/c/program/kevux/tools/tacocat/main/gpgme.c | 33 +++----- .../program/kevux/tools/tacocat/main/print/gpgme.c | 6 +- .../program/kevux/tools/tacocat/main/print/gpgme.h | 4 +- sources/c/program/kevux/tools/tacocat/main/send.c | 9 +- .../kevux/tools/tacocat/main/send/step/done.c | 6 ++ .../kevux/tools/tacocat/main/send/step/encrypt.c | 95 +-------------------- .../kevux/tools/tacocat/main/send/step/encrypt.h | 23 ++--- .../kevux/tools/tacocat/main/send/step/file.c | 39 +++++---- .../tools/tacocat/main/send/step/gpgme/done.c | 22 +++++ .../tools/tacocat/main/send/step/gpgme/done.h | 50 +++++++++++ .../tools/tacocat/main/send/step/gpgme/encrypt.c | 34 ++++++++ .../tools/tacocat/main/send/step/gpgme/encrypt.h | 50 +++++++++++ .../tools/tacocat/main/send/step/gpgme/file.c | 58 +++++++++++++ .../tools/tacocat/main/send/step/gpgme/file.h | 60 +++++++++++++ .../tools/tacocat/main/send/step/gpgme/size.c | 99 ++++++++++++++++++++++ .../tools/tacocat/main/send/step/gpgme/size.h | 64 ++++++++++++++ .../kevux/tools/tacocat/main/send/step/size.c | 5 +- .../c/program/kevux/tools/tacocat/main/tacocat.h | 4 + 20 files changed, 507 insertions(+), 159 deletions(-) create mode 100644 sources/c/program/kevux/tools/tacocat/main/send/step/gpgme/done.c create mode 100644 sources/c/program/kevux/tools/tacocat/main/send/step/gpgme/done.h create mode 100644 sources/c/program/kevux/tools/tacocat/main/send/step/gpgme/encrypt.c create mode 100644 sources/c/program/kevux/tools/tacocat/main/send/step/gpgme/encrypt.h create mode 100644 sources/c/program/kevux/tools/tacocat/main/send/step/gpgme/file.c create mode 100644 sources/c/program/kevux/tools/tacocat/main/send/step/gpgme/file.h create mode 100644 sources/c/program/kevux/tools/tacocat/main/send/step/gpgme/size.c create mode 100644 sources/c/program/kevux/tools/tacocat/main/send/step/gpgme/size.h diff --git a/data/build/tacocat/settings b/data/build/tacocat/settings index 21628a7..ce2886b 100644 --- a/data/build/tacocat/settings +++ b/data/build/tacocat/settings @@ -64,6 +64,7 @@ build_sources_headers receive/step/check.h receive/step/control.h receive/step/d build_sources_headers send/step/build.h send/step/check.h send/step/done.h send/step/encode.h send/step/encrypt.h send/step/file.h send/step/header.h send/step/packet.h send/step/size.h send/step/wait.h build_sources_headers-gpgme gpgme.h print/gpgme.h +build_sources_headers-gpgme send/step/gpgme/done.h send/step/gpgme/encrypt.h send/step/gpgme/file.h send/step/gpgme/size.h build_sources_library common.c common/define.c common/enumeration.c common/string.c common/type.c build_sources_library print/error.c print/message.c print/verbose.c print/warning.c @@ -72,6 +73,7 @@ build_sources_library receive/step/check.c receive/step/control.c receive/step/d build_sources_library send/step/build.c send/step/check.c send/step/done.c send/step/encode.c send/step/encrypt.c send/step/file.c send/step/header.c send/step/packet.c send/step/size.c send/step/wait.c build_sources_library-gpgme gpgme.c print/gpgme.c +build_sources_library-gpgme send/step/gpgme/done.c send/step/gpgme/encrypt.c send/step/gpgme/file.c send/step/gpgme/size.c build_sources_documentation man diff --git a/sources/c/program/kevux/tools/tacocat/main/common/type.h b/sources/c/program/kevux/tools/tacocat/main/common/type.h index f48f2f7..460db2a 100644 --- a/sources/c/program/kevux/tools/tacocat/main/common/type.h +++ b/sources/c/program/kevux/tools/tacocat/main/common/type.h @@ -461,7 +461,6 @@ extern "C" { * Properties: * - context: The GPGME context data. * - engine: The GPGME engine inforrmation data. - * - error: The GPGME error data. * * - version: The GPGME reported version. */ @@ -469,7 +468,6 @@ extern "C" { typedef struct { gpgme_ctx_t context; gpgme_engine_info_t engine; - gpgme_error_t error; f_string_constant_t version; } kt_tacocat_gpgme_t; @@ -477,7 +475,6 @@ extern "C" { #define kt_tacocat_gpgme_t_initialize { \ .context = 0, \ .engine = 0, \ - .error = 0, \ .version = f_string_empty_s.string, \ } #endif // defined(_en_gpgme_support_) && !defined(_di_kt_tacocat_gpgme_t_) diff --git a/sources/c/program/kevux/tools/tacocat/main/gpgme.c b/sources/c/program/kevux/tools/tacocat/main/gpgme.c index 457dc28..662ebdf 100644 --- a/sources/c/program/kevux/tools/tacocat/main/gpgme.c +++ b/sources/c/program/kevux/tools/tacocat/main/gpgme.c @@ -11,34 +11,28 @@ extern "C" { kt_tacocat_gpgme_t * const gpgme = &main->gpgme; - gpgme->version = gpgme_check_version(0); - - gpgme->error = gpgme_engine_check_version(GPGME_PROTOCOL_OPENPGP); + gpgme_error_t error = 0; - if (gpgme->error != GPG_ERR_NO_ERROR) { - main->setting.state.status = F_status_set_error(F_failure); + gpgme->version = gpgme_check_version(0); - kt_tacocat_print_gpgme_error(&main->program.error, F_status_debug_source_d); + error = gpgme_engine_check_version(GPGME_PROTOCOL_OPENPGP); - return; + if (error == GPG_ERR_NO_ERROR) { + error = gpgme_get_engine_info(&gpgme->engine); } - gpgme->error = gpgme_get_engine_info(&gpgme->engine); - - if (gpgme->error != GPG_ERR_NO_ERROR) { - main->setting.state.status = F_status_set_error(F_failure); - - kt_tacocat_print_gpgme_error(&main->program.error, F_status_debug_source_d); - - return; + if (error == GPG_ERR_NO_ERROR) { + error = gpgme_new(&gpgme->context); } - gpgme->error = gpgme_new(&gpgme->context); + if (error == GPG_ERR_NO_ERROR) { + error = gpgme_ctx_set_engine_info(gpgme->context, GPGME_PROTOCOL_OpenPGP, gpgme->engine->file_name, gpgme->engine->home_dir); + } - if (gpgme->error != GPG_ERR_NO_ERROR) { + if (error != GPG_ERR_NO_ERROR) { main->setting.state.status = F_status_set_error(F_failure); - kt_tacocat_print_gpgme_error(&main->program.error, F_status_debug_source_d); + kt_tacocat_print_gpgme_error(&main->program.error, F_status_debug_source_d, error); return; } @@ -49,9 +43,6 @@ extern "C" { // Disable online access. gpgme_set_offline(gpgme->context, F_true); - // Is this necessary? - //err = gpgme_ctx_set_engine_info(ceofcontext, GPGME_PROTOCOL_OpenPGP, enginfo->file_name, enginfo->home_dir); - main->setting.state.status = F_okay; } #endif // defined(_en_gpgme_support_) && !defined(_di_kt_tacocat_gpgme_setup_) diff --git a/sources/c/program/kevux/tools/tacocat/main/print/gpgme.c b/sources/c/program/kevux/tools/tacocat/main/print/gpgme.c index e95d4c7..f055191 100644 --- a/sources/c/program/kevux/tools/tacocat/main/print/gpgme.c +++ b/sources/c/program/kevux/tools/tacocat/main/print/gpgme.c @@ -5,7 +5,7 @@ extern "C" { #endif #if defined(_en_gpgme_support_) && !defined(_di_kt_tacocat_print_gpgme_error_) - f_status_t kt_tacocat_print_gpgme_error(fl_print_t * const print, const f_string_t debug) { + f_status_t kt_tacocat_print_gpgme_error(fl_print_t * const print, const f_string_t debug, const gpgme_error_t error) { if (!print || !print->custom) return F_status_set_error(F_output_not); if (print->verbosity < f_console_verbosity_error_e) return F_output_not; @@ -15,9 +15,9 @@ extern "C" { f_file_stream_lock(print->to); fl_print_format("%[%QGPGME error:%] ", print->to, print->set->error, print->prefix, print->set->error); - fl_print_format(f_string_format_S_single_s.string, print->to, print->set->notable, gpgme_strerror(main->gpgme.error), print->set->notable); + fl_print_format(f_string_format_S_single_s.string, print->to, print->set->notable, gpgme_strerror(error), print->set->notable); fl_print_format(" %[(%]", print->to, print->set->error, print->set->error); - fl_print_format(f_string_format_S_single_s.string, print->to, print->set->notable, gpgme_strsource(main->gpgme.error), print->set->notable); + fl_print_format(f_string_format_S_single_s.string, print->to, print->set->notable, gpgme_strsource(error), print->set->notable); fl_print_format("%[)", print->to, print->set->error); if (debug && *debug) { diff --git a/sources/c/program/kevux/tools/tacocat/main/print/gpgme.h b/sources/c/program/kevux/tools/tacocat/main/print/gpgme.h index f72cb19..3485354 100644 --- a/sources/c/program/kevux/tools/tacocat/main/print/gpgme.h +++ b/sources/c/program/kevux/tools/tacocat/main/print/gpgme.h @@ -31,6 +31,8 @@ extern "C" { * (optional) The debug details, such as file, line number, and function. * * Set to NULL to disable. + * @param error + * The GPGME error code. * * @return * F_okay on success. @@ -41,7 +43,7 @@ extern "C" { * @see fll_error_print() */ #if defined(_en_gpgme_support_) && !defined(_di_kt_tacocat_print_gpgme_error_) - extern f_status_t kt_tacocat_print_gpgme_error(fl_print_t * const print, const f_string_t debug); + extern f_status_t kt_tacocat_print_gpgme_error(fl_print_t * const print, const f_string_t debug, const gpgme_error_t error); #endif // defined(_en_gpgme_support_) && !defined(_di_kt_tacocat_print_gpgme_error_) #ifdef __cplusplus diff --git a/sources/c/program/kevux/tools/tacocat/main/send.c b/sources/c/program/kevux/tools/tacocat/main/send.c index ca313fe..a45d9d8 100644 --- a/sources/c/program/kevux/tools/tacocat/main/send.c +++ b/sources/c/program/kevux/tools/tacocat/main/send.c @@ -248,20 +248,17 @@ extern "C" { // Fallback to ASCII based on current index position. if (modded < 10) { - set->id.string[set->id.used++] = (modded) + 48; + set->id.string[set->id.used++] = modded + 48; } else if (modded < 36) { - set->id.string[set->id.used++] = (modded) + 55; // ASCII 65 - 10 = 55. + set->id.string[set->id.used++] = modded + 55; // ASCII 65 - 10 = 55. } else { - set->id.string[set->id.used++] = (modded) + 61; // ASCII 97 - 36 = 61. + set->id.string[set->id.used++] = modded + 61; // ASCII 97 - 36 = 61. } } } // for } - else { - // @todo manually generate something, probably use the file name and the port number. - } } if (F_status_is_error_not(set->status)) { diff --git a/sources/c/program/kevux/tools/tacocat/main/send/step/done.c b/sources/c/program/kevux/tools/tacocat/main/send/step/done.c index b46e4a9..c12e992 100644 --- a/sources/c/program/kevux/tools/tacocat/main/send/step/done.c +++ b/sources/c/program/kevux/tools/tacocat/main/send/step/done.c @@ -11,6 +11,12 @@ extern "C" { //@todo send done packet. + if (main->setting.flag & kt_tacocat_main_flag_encrypt_d) { + #ifdef _en_gpgme_support_ + kt_tacocat_send_step_gpgme_done(main, set); + #endif // _en_gpgme_support_ + } + if (main->setting.flag & kt_tacocat_main_flag_headers_d) { kt_tacocat_print_message_headers(&main->program.message, *set, F_true); } diff --git a/sources/c/program/kevux/tools/tacocat/main/send/step/encrypt.c b/sources/c/program/kevux/tools/tacocat/main/send/step/encrypt.c index 3a64f67..807dedf 100644 --- a/sources/c/program/kevux/tools/tacocat/main/send/step/encrypt.c +++ b/sources/c/program/kevux/tools/tacocat/main/send/step/encrypt.c @@ -4,103 +4,16 @@ extern "C" { #endif -#if defined(_en_gpgme_support_) && !defined(_di_kt_tacocat_send_step_encrypt_size_) - void kt_tacocat_send_step_encrypt_size(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set) { +#ifdef _di_kt_tacocat_send_step_encrypt_ + void kt_tacocat_send_step_encrypt(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set) { if (!main || !set || F_status_is_error(set->status)) return; - if (set->encrypt_read) { - gpgme_data_release(set->encrypt_read); - - set->encrypt_read = 0; - } - - gpgme_error_t error = gpgme_data_new_from_fd(&set->encrypt_read, set->file.id); - - if (error != GPG_ERR_NO_ERROR) { - set->status = F_status_set_error(F_memory); - - kt_tacocat_print_error_on_file_send(&main->program.error, F_status_debug_source_d, kt_tacocat_send_s, set->network, set->status, set->name, f_file_operation_read_s); - - return; - } - - error = gpgme_data_set_encoding(set->encrypt_read, GPGME_DATA_ENCODING_ARMOR); - - if (error != GPG_ERR_NO_ERROR) { - set->status = F_status_set_error(F_failure); - - kt_tacocat_print_error_on_file_send(&main->program.error, F_status_debug_source_d, kt_tacocat_send_s, set->network, set->status, set->name, f_file_operation_read_s); - - return; - } - - // Total is used here to explicitly pass a pointer of off_t rather than a pointer of size_t cast to an off_t. - // GPGME provides no way to get the file size of the encrypted data, so load the file and determine the file size as it is loading. - off_t total = 0; - gpgme_ssize_t bytes = 1; - - for (char buffer[set->file.size_read + 1]; bytes > 0 && total <= F_number_t_size_unsigned_d; total += bytes) { - bytes = gpgme_data_read(set->encrypt_read, buffer, set->file.size_read); - } // for - - if (bytes == -1) { - set->status = F_status_set_error(F_failure); - - kt_tacocat_print_error_on_file_send(&main->program.error, F_status_debug_source_d, kt_tacocat_send_s, set->network, set->status, set->name, f_file_operation_read_s); - - return; - } - - if ((f_number_unsigned_t) total > F_number_t_size_unsigned_d) { - set->status = F_status_set_error(F_too_large); - - kt_tacocat_print_error_on_file_too_large(&main->program.error, set->name, kt_tacocat_send_s, set->network, F_number_t_size_unsigned_d, set->abstruses.array[4].value.is.a_unsigned); - - return; - } - - error = gpgme_data_rewind(set->encrypt_read); - - if (error != GPG_ERR_NO_ERROR) { - set->status = F_status_set_error(F_failure); - - kt_tacocat_print_error_on_file_send(&main->program.error, F_status_debug_source_d, kt_tacocat_send_s, set->network, set->status, set->name, f_file_operation_read_s); + if (F_status_is_error(set->status)) { + kt_tacocat_print_error_on(&main->program.error, F_status_debug_source_d, kt_tacocat_send_file_s, set->network, set->status, set->name); return; } - - set->abstruses.array[3].value.is.a_unsigned = 0; - set->size_total = (f_number_unsigned_t) total; - - if (total) { - if (set->size_total < set->file.size_read) { - set->abstruses.array[2].value.is.a_unsigned = set->size_total; - set->abstruses.array[4].value.is.a_unsigned = 1; - } - else { - set->abstruses.array[2].value.is.a_unsigned = set->file.size_read; - set->abstruses.array[4].value.is.a_unsigned = set->size_total / set->file.size_read; - - if (set->abstruses.array[4].value.is.a_unsigned % set->file.size_read) { - ++set->abstruses.array[4].value.is.a_unsigned; - } - } - } - else { - set->abstruses.array[2].value.is.a_unsigned = set->size_total; - set->abstruses.array[4].value.is.a_unsigned = 1; - } - } -#endif // defined(_en_gpgme_support_) && !defined(_di_kt_tacocat_send_step_encrypt_size_) - -#if !defined(_en_gpgme_support_) && !defined(_di_kt_tacocat_send_step_encrypt_size_) - void kt_tacocat_send_step_encrypt_size(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set) { - - set->status = F_status_set_error(F_implement_not); - - // @todo replace this with an error on encryption unsupported. - kt_tacocat_print_error_on(&main->program.error, F_status_debug_source_d, kt_tacocat_send_s, set->network, set->status, set->name); } #endif // _di_kt_tacocat_send_step_encrypt_ diff --git a/sources/c/program/kevux/tools/tacocat/main/send/step/encrypt.h b/sources/c/program/kevux/tools/tacocat/main/send/step/encrypt.h index 670c591..2e85626 100644 --- a/sources/c/program/kevux/tools/tacocat/main/send/step/encrypt.h +++ b/sources/c/program/kevux/tools/tacocat/main/send/step/encrypt.h @@ -17,7 +17,7 @@ extern "C" { #endif /** - * Perform the size step of a send request using encryption. + * Perform the encrypt step of a send request. * * This prints on error. * @@ -35,24 +35,13 @@ extern "C" { * This alters set.status: * F_okay on success. * - * F_done (with error bit) on error that cannot continue, such as out of memory. - * F_too_large (with error bit) on file too large. + * Errors (with error bit) from: gpgme_data_release() * - * Errors (with error bit) from: f_memory_array_increase_by() - * - * Errors (with error bit) from: gpgme_data_new_from_fd() - * Errors (with error bit) from: gpgme_data_read() - * Errors (with error bit) from: gpgme_data_set_encoding() - * - * @see f_memory_array_increase_by() - * - * @see gpgme_data_new_from_fd() - * @see gpgme_data_read() - * @see gpgme_data_set_encoding() + * @see gpgme_data_release() */ -#ifndef _di_kt_tacocat_send_step_encrypt_size_ - extern void kt_tacocat_send_step_encrypt_size(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set); -#endif // _di_kt_tacocat_send_step_encrypt_size_ +#ifndef _di_kt_tacocat_send_step_encrypt_ + extern void kt_tacocat_send_step_encrypt(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set); +#endif // _di_kt_tacocat_send_step_encrypt_ #ifdef __cplusplus } // extern "C" diff --git a/sources/c/program/kevux/tools/tacocat/main/send/step/file.c b/sources/c/program/kevux/tools/tacocat/main/send/step/file.c index 3fa7ac9..6efa4bc 100644 --- a/sources/c/program/kevux/tools/tacocat/main/send/step/file.c +++ b/sources/c/program/kevux/tools/tacocat/main/send/step/file.c @@ -9,33 +9,40 @@ extern "C" { if (!main || !set || F_status_is_error(set->status)) return; - // @todo if (main->setting.flag & kt_tacocat_main_flag_encrypt_d) { - set->status = f_string_dynamic_append(f_fss_payload_object_payload_s, &set->buffer); if (F_status_is_error_not(set->status)) { set->status = f_string_dynamic_append(f_fss_payload_object_end_s, &set->buffer); } - // Always reset the seek position in case a retry happened after the file block is read. - if (F_status_is_error_not(set->status)) { - off_t seeked = 0; - - set->status = f_file_seek(set->file, SEEK_SET, set->size_done, &seeked); + if (main->setting.flag & kt_tacocat_main_flag_encrypt_d) { + #ifdef _en_gpgme_support_ + kt_tacocat_send_step_gpgme_file(main, set); + if (F_status_is_error(set->status)) return; + #endif // _en_gpgme_support_ } + else { - if (F_status_is_error_not(set->status)) { - set->status = f_file_read_block(set->file, &set->buffer); - } + // Always reset the seek position in case a retry happened after the file block is read. + if (F_status_is_error_not(set->status)) { + off_t seeked = 0; - if (F_status_is_error_not(set->status)) { - set->status = f_string_dynamic_terminate_after(&set->buffer); - } + set->status = f_file_seek(set->file, SEEK_SET, set->size_done, &seeked); + } + + if (F_status_is_error_not(set->status)) { + set->status = f_file_read_block(set->file, &set->buffer); + } + + if (F_status_is_error_not(set->status)) { + set->status = f_string_dynamic_terminate_after(&set->buffer); + } - if (F_status_is_error(set->status)) { - kt_tacocat_print_error_on(&main->program.error, F_status_debug_source_d, kt_tacocat_send_file_s, set->network, set->status, set->name); + if (F_status_is_error(set->status)) { + kt_tacocat_print_error_on(&main->program.error, F_status_debug_source_d, kt_tacocat_send_file_s, set->network, set->status, set->name); - return; + return; + } } set->retry = 0; diff --git a/sources/c/program/kevux/tools/tacocat/main/send/step/gpgme/done.c b/sources/c/program/kevux/tools/tacocat/main/send/step/gpgme/done.c new file mode 100644 index 0000000..d9bc73f --- /dev/null +++ b/sources/c/program/kevux/tools/tacocat/main/send/step/gpgme/done.c @@ -0,0 +1,22 @@ +#include "../../../tacocat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_en_gpgme_support_) && !defined(_di_kt_tacocat_send_step_gpgme_done_) + void kt_tacocat_send_step_gpgme_done(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set) { + + if (!main || !set || F_status_is_error(set->status)) return; + + if (set->encrypt_read) { + gpgme_data_release(set->encrypt_read); + + set->encrypt_read = 0; + } + } +#endif // defined(_en_gpgme_support_) && !defined(_di_kt_tacocat_send_step_gpgme_done_) + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/sources/c/program/kevux/tools/tacocat/main/send/step/gpgme/done.h b/sources/c/program/kevux/tools/tacocat/main/send/step/gpgme/done.h new file mode 100644 index 0000000..0eac333 --- /dev/null +++ b/sources/c/program/kevux/tools/tacocat/main/send/step/gpgme/done.h @@ -0,0 +1,50 @@ +/** + * Kevux Tools - TacocaT + * + * Project: Kevux Tools + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Provides send gpgme step done functionality. + * + * This is auto-included and should not need to be explicitly included. + */ +#ifndef _kt_tacocat_send_step_gpgme_done_h +#define _kt_tacocat_send_step_gpgme_done_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Perform the done step of a send request using GPGME encryption. + * + * This prints on error. + * + * @param main + * The main program and settings data. + * + * Must not be NULL. + * + * This does not alter main.setting.state.status, except on interrupt signal. + * @param set + * The socket set to process. + * + * Must not be NULL. + * + * This alters set.status: + * F_okay on success. + * + * Errors (with error bit) from: gpgme_data_release() + * + * @see gpgme_data_release() + */ +#if defined(_en_gpgme_support_) && !defined(_di_kt_tacocat_send_step_gpgme_done_) + extern void kt_tacocat_send_step_gpgme_done(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set); +#endif // defined(_en_gpgme_support_) && !defined(_di_kt_tacocat_send_step_gpgme_done_) + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _kt_tacocat_send_step_gpgme_done_h diff --git a/sources/c/program/kevux/tools/tacocat/main/send/step/gpgme/encrypt.c b/sources/c/program/kevux/tools/tacocat/main/send/step/gpgme/encrypt.c new file mode 100644 index 0000000..478bcde --- /dev/null +++ b/sources/c/program/kevux/tools/tacocat/main/send/step/gpgme/encrypt.c @@ -0,0 +1,34 @@ +#include "../../../tacocat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_en_gpgme_support_) && !defined(_di_kt_tacocat_send_step_gpgme_encrypt_) + void kt_tacocat_send_step_gpgme_encrypt(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set) { + + if (!main || !set || F_status_is_error(set->status)) return; + + // @todo + /* + gpgme_error_t error = gpgme_data_new(&cipher); // gpgme_data_t cipher; + + gpgme_key_t recipient = 0; + + error = gpgme_get_key(context, "FULL_KEY_HERE", &recipient, 0); + + error = gpgme_op_encrypt(context, recipient, GPGME_ENCRYPT_ALWAYS_TRUST, plain, cipher); + + // gpgme_data_seek(cipher, 0, SEEK_SET); + // Then save it in buffer. + + gpgme_key_unref(recipient); + + gpgme_data_release(cipher); + */ + } +#endif // defined(_en_gpgme_support_) && !defined(_di_kt_tacocat_send_step_gpgme_encrypt_) + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/sources/c/program/kevux/tools/tacocat/main/send/step/gpgme/encrypt.h b/sources/c/program/kevux/tools/tacocat/main/send/step/gpgme/encrypt.h new file mode 100644 index 0000000..c45fa47 --- /dev/null +++ b/sources/c/program/kevux/tools/tacocat/main/send/step/gpgme/encrypt.h @@ -0,0 +1,50 @@ +/** + * Kevux Tools - TacocaT + * + * Project: Kevux Tools + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Provides send gpgme step encrypt functionality. + * + * This is auto-included and should not need to be explicitly included. + */ +#ifndef _kt_tacocat_send_step_gpgme_encrypt_h +#define _kt_tacocat_send_step_gpgme_encrypt_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Perform the encryption step of a send request using GPGME encryption. + * + * This prints on error. + * + * @param main + * The main program and settings data. + * + * Must not be NULL. + * + * This does not alter main.setting.state.status, except on interrupt signal. + * @param set + * The socket set to process. + * + * Must not be NULL. + * + * This alters set.status: + * F_okay on success. + * + * Errors (with error bit) from: gpgme_data_release() + * + * @see gpgme_data_release() + */ +#if defined(_en_gpgme_support_) && !defined(_di_kt_tacocat_send_step_gpgme_encrypt_) + extern void kt_tacocat_send_step_gpgme_encrypt(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set); +#endif // defined(_en_gpgme_support_) && !defined(_di_kt_tacocat_send_step_gpgme_encrypt_) + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _kt_tacocat_send_step_gpgme_encrypt_h diff --git a/sources/c/program/kevux/tools/tacocat/main/send/step/gpgme/file.c b/sources/c/program/kevux/tools/tacocat/main/send/step/gpgme/file.c new file mode 100644 index 0000000..7962c00 --- /dev/null +++ b/sources/c/program/kevux/tools/tacocat/main/send/step/gpgme/file.c @@ -0,0 +1,58 @@ +#include "../../../tacocat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_en_gpgme_support_) && !defined(_di_kt_tacocat_send_step_gpgme_file_) + void kt_tacocat_send_step_gpgme_file(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set) { + + if (!main || !set || F_status_is_error(set->status)) return; + + char buffer[set->file.size_read + 1]; + buffer[set->file.size_read] = 0; + + // Always reset the seek position in case a retry happened after the file block is read. + if (F_status_is_error_not(set->status)) { + const gpgme_off_t seeked = gpgme_data_seek(set->encrypt_read, set->size_done, 0); + + if (seeked == -1) { + set->status = F_status_set_error(F_failure); + + kt_tacocat_print_error_on_file_send(&main->program.error, F_status_debug_source_d, kt_tacocat_send_s, set->network, set->status, set->name, f_file_operation_read_s); + + return; + } + } + + const gpgme_ssize_t bytes = gpgme_data_read(set->encrypt_read, buffer, set->file.size_read); + + if (bytes == -1) { + set->status = F_status_set_error(F_failure); + + kt_tacocat_print_error_on_file_send(&main->program.error, F_status_debug_source_d, kt_tacocat_send_s, set->network, set->status, set->name, f_file_operation_read_s); + + return; + } + + { + const f_string_static_t encrypted = macro_f_string_static_t_initialize_3(buffer, bytes); + + set->status = f_string_dynamic_append(encrypted, &set->buffer); + } + + if (F_status_is_error_not(set->status)) { + set->status = f_string_dynamic_terminate_after(&set->buffer); + } + + if (F_status_is_error(set->status)) { + kt_tacocat_print_error_on(&main->program.error, F_status_debug_source_d, kt_tacocat_send_file_s, set->network, set->status, set->name); + + return; + } + } +#endif // defined(_en_gpgme_support_) && !defined(_di_kt_tacocat_send_step_gpgme_file_) + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/sources/c/program/kevux/tools/tacocat/main/send/step/gpgme/file.h b/sources/c/program/kevux/tools/tacocat/main/send/step/gpgme/file.h new file mode 100644 index 0000000..da69b3f --- /dev/null +++ b/sources/c/program/kevux/tools/tacocat/main/send/step/gpgme/file.h @@ -0,0 +1,60 @@ +/** + * Kevux Tools - TacocaT + * + * Project: Kevux Tools + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Provides send gpgme step file functionality. + * + * This is auto-included and should not need to be explicitly included. + */ +#ifndef _kt_tacocat_send_step_gpgme_file_h +#define _kt_tacocat_send_step_gpgme_file_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Perform the file step of a send request using GPGME encryption. + * + * This prints on error. + * + * @param main + * The main program and settings data. + * + * Must not be NULL. + * + * This does not alter main.setting.state.status, except on interrupt signal. + * @param set + * The socket set to process. + * + * Must not be NULL. + * + * This alters set.status: + * F_okay on success. + * + * F_failure (with error bit) on any other error. + * + * Errors (with error bit) from: f_string_dynamic_append() + * Errors (with error bit) from: f_string_dynamic_terminate_after() + * + * Errors (with error bit) from: gpgme_data_seek() + * Errors (with error bit) from: gpgme_data_read() + * + * @see f_string_dynamic_append() + * @see f_string_dynamic_terminate_after() + * + * @see gpgme_data_seek() + * @see gpgme_data_read() + */ +#if defined(_en_gpgme_support_) && !defined(_di_kt_tacocat_send_step_gpgme_file_) + extern void kt_tacocat_send_step_gpgme_file(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set); +#endif // defined(_en_gpgme_support_) && !defined(_di_kt_tacocat_send_step_gpgme_file_) + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _kt_tacocat_send_step_gpgme_file_h diff --git a/sources/c/program/kevux/tools/tacocat/main/send/step/gpgme/size.c b/sources/c/program/kevux/tools/tacocat/main/send/step/gpgme/size.c new file mode 100644 index 0000000..5cf1f47 --- /dev/null +++ b/sources/c/program/kevux/tools/tacocat/main/send/step/gpgme/size.c @@ -0,0 +1,99 @@ +#include "../../../tacocat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_en_gpgme_support_) && !defined(_di_kt_tacocat_send_step_gpgme_size_) + void kt_tacocat_send_step_gpgme_size(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set) { + + if (!main || !set || F_status_is_error(set->status)) return; + + if (set->encrypt_read) { + gpgme_data_release(set->encrypt_read); + + set->encrypt_read = 0; + } + + gpgme_error_t error = gpgme_data_new_from_fd(&set->encrypt_read, set->file.id); + + if (error != GPG_ERR_NO_ERROR) { + set->status = F_status_set_error(F_memory); + + kt_tacocat_print_error_on_file_send(&main->program.error, F_status_debug_source_d, kt_tacocat_send_s, set->network, set->status, set->name, f_file_operation_read_s); + + return; + } + + error = gpgme_data_set_encoding(set->encrypt_read, GPGME_DATA_ENCODING_ARMOR); + + if (error != GPG_ERR_NO_ERROR) { + set->status = F_status_set_error(F_failure); + + kt_tacocat_print_error_on_file_send(&main->program.error, F_status_debug_source_d, kt_tacocat_send_s, set->network, set->status, set->name, f_file_operation_read_s); + + return; + } + + // Total is used here to explicitly pass a pointer of off_t rather than a pointer of size_t cast to an off_t. + // GPGME provides no way to get the file size of the encrypted data, so load the file and determine the file size as it is loading. + off_t total = 0; + gpgme_ssize_t bytes = 1; + + for (char buffer[set->file.size_read + 1]; bytes > 0 && total <= F_number_t_size_unsigned_d; total += bytes) { + bytes = gpgme_data_read(set->encrypt_read, buffer, set->file.size_read); + } // for + + if (bytes == -1) { + set->status = F_status_set_error(F_failure); + + kt_tacocat_print_error_on_file_send(&main->program.error, F_status_debug_source_d, kt_tacocat_send_s, set->network, set->status, set->name, f_file_operation_read_s); + + return; + } + + if ((f_number_unsigned_t) total > F_number_t_size_unsigned_d) { + set->status = F_status_set_error(F_too_large); + + kt_tacocat_print_error_on_file_too_large(&main->program.error, set->name, kt_tacocat_send_s, set->network, F_number_t_size_unsigned_d, set->abstruses.array[4].value.is.a_unsigned); + + return; + } + + error = gpgme_data_rewind(set->encrypt_read); + + if (error != GPG_ERR_NO_ERROR) { + set->status = F_status_set_error(F_failure); + + kt_tacocat_print_error_on_file_send(&main->program.error, F_status_debug_source_d, kt_tacocat_send_s, set->network, set->status, set->name, f_file_operation_read_s); + + return; + } + + set->abstruses.array[3].value.is.a_unsigned = 0; + set->size_total = (f_number_unsigned_t) total; + + if (total) { + if (set->size_total < set->file.size_read) { + set->abstruses.array[2].value.is.a_unsigned = set->size_total; + set->abstruses.array[4].value.is.a_unsigned = 1; + } + else { + set->abstruses.array[2].value.is.a_unsigned = set->file.size_read; + set->abstruses.array[4].value.is.a_unsigned = set->size_total / set->file.size_read; + + if (set->abstruses.array[4].value.is.a_unsigned % set->file.size_read) { + ++set->abstruses.array[4].value.is.a_unsigned; + } + } + } + else { + set->abstruses.array[2].value.is.a_unsigned = set->size_total; + set->abstruses.array[4].value.is.a_unsigned = 1; + } + } +#endif // defined(_en_gpgme_support_) && !defined(_di_kt_tacocat_send_step_gpgme_size_) + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/sources/c/program/kevux/tools/tacocat/main/send/step/gpgme/size.h b/sources/c/program/kevux/tools/tacocat/main/send/step/gpgme/size.h new file mode 100644 index 0000000..96f504f --- /dev/null +++ b/sources/c/program/kevux/tools/tacocat/main/send/step/gpgme/size.h @@ -0,0 +1,64 @@ +/** + * Kevux Tools - TacocaT + * + * Project: Kevux Tools + * API Version: 0.7 + * Licenses: lgpl-2.1-or-later + * + * Provides send gpgme step size functionality. + * + * This is auto-included and should not need to be explicitly included. + */ +#ifndef _kt_tacocat_send_step_gpgme_size_h +#define _kt_tacocat_send_step_gpgme_size_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Perform the size step of a send request using GPGME encryption. + * + * This prints on error. + * + * @param main + * The main program and settings data. + * + * Must not be NULL. + * + * This does not alter main.setting.state.status, except on interrupt signal. + * @param set + * The socket set to process. + * + * Must not be NULL. + * + * This alters set.status: + * F_okay on success. + * + * F_done (with error bit) on error that cannot continue, such as out of memory. + * F_memory (with error bit) on on out of memory. + * F_too_large (with error bit) on file too large. + * + * F_failure (with error bit) on any other error. + * + * Errors (with error bit) from: f_memory_array_increase_by() + * + * Errors (with error bit) from: gpgme_data_new_from_fd() + * Errors (with error bit) from: gpgme_data_read() + * Errors (with error bit) from: gpgme_data_set_encoding() + * + * @see f_memory_array_increase_by() + * + * @see gpgme_data_new_from_fd() + * @see gpgme_data_read() + * @see gpgme_data_set_encoding() + */ +#if defined(_en_gpgme_support_) && !defined(_di_kt_tacocat_send_step_gpgme_size_) + extern void kt_tacocat_send_step_gpgme_size(kt_tacocat_main_t * const main, kt_tacocat_socket_set_t * const set); +#endif // defined(_en_gpgme_support_) && !defined(_di_kt_tacocat_send_step_gpgme_size_) + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _kt_tacocat_send_step_gpgme_size_h diff --git a/sources/c/program/kevux/tools/tacocat/main/send/step/size.c b/sources/c/program/kevux/tools/tacocat/main/send/step/size.c index 68c7fc2..6479131 100644 --- a/sources/c/program/kevux/tools/tacocat/main/send/step/size.c +++ b/sources/c/program/kevux/tools/tacocat/main/send/step/size.c @@ -20,7 +20,10 @@ extern "C" { } if (main->setting.flag & kt_tacocat_main_flag_encrypt_d) { - kt_tacocat_send_step_encrypt_size(main, set); + #ifdef _en_gpgme_support_ + kt_tacocat_send_step_gpgme_size(main, set); + if (F_status_is_error(set->status)) return; + #endif // _en_gpgme_support_ } else { // Total is used here to explicitly pass a pointer of off_t rather than a pointer of size_t cast to an off_t. diff --git a/sources/c/program/kevux/tools/tacocat/main/tacocat.h b/sources/c/program/kevux/tools/tacocat/main/tacocat.h index 2684a55..ae71534 100644 --- a/sources/c/program/kevux/tools/tacocat/main/tacocat.h +++ b/sources/c/program/kevux/tools/tacocat/main/tacocat.h @@ -98,6 +98,10 @@ #ifdef _en_gpgme_support_ #include #include + #include + #include + #include + #include #endif // _en_gpgme_support_ #ifdef __cplusplus -- 1.8.3.1