diff --git a/src/twc-config.c b/src/twc-config.c index 0d7e3f6..45e794f 100644 --- a/src/twc-config.c +++ b/src/twc-config.c @@ -48,6 +48,7 @@ char *twc_profile_option_names[TWC_PROFILE_NUM_OPTIONS] = "proxy_type", "udp", "ipv6", + "passphrase", }; /** @@ -210,6 +211,11 @@ twc_config_init_option(struct t_config_section *section, min = 0; max = INT_MAX; default_value = "100"; break; + case TWC_PROFILE_OPTION_PASSPHRASE: + type = "string"; + description = "passphrase for encrypted profile"; + null_allowed = true; + break; case TWC_PROFILE_OPTION_PROXY_ADDRESS: type = "string"; description = "proxy address"; diff --git a/src/twc-profile.c b/src/twc-profile.c index 8676b41..b41b30a 100644 --- a/src/twc-profile.c +++ b/src/twc-profile.c @@ -24,6 +24,7 @@ #include #include +#include #include "twc.h" #include "twc-list.h" @@ -83,14 +84,34 @@ twc_profile_save_data_file(struct t_twc_profile *profile) // save Tox data to a buffer size_t size = tox_get_savedata_size(profile->tox); - uint8_t *data = malloc(size); + uint8_t data[size]; + uint8_t enc_data[size + TOX_PASS_ENCRYPTION_EXTRA_LENGTH]; + uint8_t *d = data; tox_get_savedata(profile->tox, data); + char *pw = weechat_config_string(profile->options[TWC_PROFILE_OPTION_PASSPHRASE]); + + if (pw) + pw = weechat_string_eval_expression(pw, NULL, NULL, NULL); + + if (pw) + { + if (!tox_pass_encrypt(data, size, (uint8_t *)pw, strlen(pw), enc_data, NULL)) + { + free(pw); + weechat_printf(profile->buffer, "error encrypting data"); + return -1; + } + free(pw); + d = enc_data; + size += TOX_PASS_ENCRYPTION_EXTRA_LENGTH; + } + // save buffer to a file FILE *file = fopen(full_path, "w"); if (file) { - size_t saved_size = fwrite(data, 1, size, file); + size_t saved_size = fwrite(d, 1, size, file); fclose(file); return saved_size == size; @@ -274,8 +295,8 @@ twc_profile_load(struct t_twc_profile *profile) // create Tox options object struct Tox_Options options; - tox_options_default(&options); - //twc_profile_set_options(options, profile); + //tox_options_default(&options); + twc_profile_set_options(&options, profile); // print a proxy message if (options.proxy_type != TOX_PROXY_TYPE_NONE) @@ -300,6 +321,7 @@ twc_profile_load(struct t_twc_profile *profile) data_size = ftell(file); } uint8_t data[data_size]; + uint8_t dec_data[data_size]; if (file) { rewind(file); @@ -311,8 +333,33 @@ twc_profile_load(struct t_twc_profile *profile) } fclose(file); } + if (data_size && tox_is_data_encrypted(data)) + { + char *pw = weechat_config_string(profile->options[TWC_PROFILE_OPTION_PASSPHRASE]); + if (pw) + { + // evaluate password option and duplicate as tox_*_decrypt wipes it + pw = weechat_string_eval_expression(pw, NULL, NULL, NULL); + } + + if (pw) + { + if (!tox_pass_decrypt(data, data_size, (uint8_t *)pw, strlen(pw), dec_data, NULL)) + { + free(pw); + weechat_printf(profile->buffer, "%scould not decrypt Tox data file, aborting", + weechat_prefix("error")); + return TWC_RC_ERROR; + } + free(pw); + data_size -= TOX_PASS_ENCRYPTION_EXTRA_LENGTH; + } + options.savedata_data = dec_data; + } + else + options.savedata_data = data; + options.savedata_type = (data_size == 0)? TOX_SAVEDATA_TYPE_NONE: TOX_SAVEDATA_TYPE_TOX_SAVE; - options.savedata_data = data; options.savedata_length = data_size; // create Tox @@ -321,6 +368,7 @@ twc_profile_load(struct t_twc_profile *profile) if (rc != TOX_ERR_NEW_OK) { twc_tox_new_print_error(profile, &options, rc); + profile->tox = NULL; return rc == TOX_ERR_NEW_MALLOC ? TWC_RC_ERROR_MALLOC : TWC_RC_ERROR; } @@ -509,6 +557,9 @@ twc_profile_delete(struct t_twc_profile *profile, { char *data_path = twc_profile_expanded_data_path(profile); + for (size_t i = 0; i < TWC_PROFILE_NUM_OPTIONS; ++i) + weechat_config_option_free(profile->options[i]); + twc_profile_free(profile); if (delete_data) diff --git a/src/twc-profile.h b/src/twc-profile.h index dbfc5ab..6518578 100644 --- a/src/twc-profile.h +++ b/src/twc-profile.h @@ -36,6 +36,7 @@ enum t_twc_profile_option TWC_PROFILE_OPTION_PROXY_TYPE, TWC_PROFILE_OPTION_UDP, TWC_PROFILE_OPTION_IPV6, + TWC_PROFILE_OPTION_PASSPHRASE, TWC_PROFILE_NUM_OPTIONS, };