diff --git a/CMakeLists.txt b/CMakeLists.txt index d40e1f0..656e050 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,7 +26,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH}) find_package(WeeChat REQUIRED) find_package(Tox REQUIRED COMPONENTS CORE - OPTIONAL_COMPONENTS AV) + OPTIONAL_COMPONENTS AV ENCRYPTSAVE) set(PLUGIN_PATH "lib/weechat/plugins" CACHE PATH "Path to install the plugin binary to.") @@ -60,6 +60,10 @@ if(Tox_AV_FOUND) add_definitions(-DTOXAV_ENABLED) endif() +if(Tox_ENCRYPTSAVE_FOUND) + add_definitions(-DTOXENCRYPTSAVE_ENABLED) +endif() + # remove lib prefix (libtox.so -> tox.so) set_target_properties(tox PROPERTIES PREFIX "") diff --git a/src/twc-profile.c b/src/twc-profile.c index b41b30a..ecca15c 100644 --- a/src/twc-profile.c +++ b/src/twc-profile.c @@ -24,7 +24,9 @@ #include #include -#include +#ifdef TOXENCRYPTSAVE_ENABLED + #include +#endif // TOXENCRYPTSAVE_ENABLED #include "twc.h" #include "twc-list.h" @@ -52,72 +54,70 @@ struct t_config_option *twc_config_profile_default[TWC_PROFILE_NUM_OPTIONS]; char * twc_profile_expanded_data_path(struct t_twc_profile *profile) { - const char *weechat_dir = weechat_info_get ("weechat_dir", NULL); - const char *base_path = TWC_PROFILE_OPTION_STRING(profile, TWC_PROFILE_OPTION_SAVEFILE); - char *home_expanded = weechat_string_replace(base_path, "%h", weechat_dir); - char *full_path = weechat_string_replace(home_expanded, "%p", profile->name); - free(home_expanded); + const char *weechat_dir = weechat_info_get ("weechat_dir", NULL); + const char *base_path = TWC_PROFILE_OPTION_STRING(profile, TWC_PROFILE_OPTION_SAVEFILE); + char *home_expanded = weechat_string_replace(base_path, "%h", weechat_dir); + char *full_path = weechat_string_replace(home_expanded, "%p", profile->name); + free(home_expanded); - return full_path; + return full_path; } /** * Save a profile's Tox data to disk. * * Returns 0 on success, -1 on failure. - * - * TODO: support encrypted save files */ int twc_profile_save_data_file(struct t_twc_profile *profile) { - if (!(profile->tox)) + if (!(profile->tox)) return -1; - char *full_path = twc_profile_expanded_data_path(profile); + char *full_path = twc_profile_expanded_data_path(profile); - // create containing folder if it doesn't exist - char *rightmost_slash = strrchr(full_path, '/'); - char *dir_path = weechat_strndup(full_path, rightmost_slash - full_path); - weechat_mkdir_parents(dir_path, 0755); - free(dir_path); + // create containing folder if it doesn't exist + char *rightmost_slash = strrchr(full_path, '/'); + char *dir_path = weechat_strndup(full_path, rightmost_slash - full_path); + weechat_mkdir_parents(dir_path, 0755); + free(dir_path); - // save Tox data to a buffer - size_t size = tox_get_savedata_size(profile->tox); - uint8_t data[size]; - uint8_t enc_data[size + TOX_PASS_ENCRYPTION_EXTRA_LENGTH]; - uint8_t *d = data; - tox_get_savedata(profile->tox, data); + // save Tox data to a buffer + size_t size = tox_get_savedata_size(profile->tox); + uint8_t data[size]; + uint8_t *d = data; + tox_get_savedata(profile->tox, data); - char *pw = weechat_config_string(profile->options[TWC_PROFILE_OPTION_PASSPHRASE]); +#ifdef TOXENCRYPTSAVE_ENABLED + uint8_t enc_data[size + TOX_PASS_ENCRYPTION_EXTRA_LENGTH]; + 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 (pw) { - if (!tox_pass_encrypt(data, size, (uint8_t *)pw, strlen(pw), enc_data, NULL)) + pw = weechat_string_eval_expression(pw, NULL, NULL, NULL); + 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); + weechat_printf(profile->buffer, "error encrypting data"); + return -1; } - free(pw); - d = enc_data; - size += TOX_PASS_ENCRYPTION_EXTRA_LENGTH; + free(pw); + d = enc_data; + size += TOX_PASS_ENCRYPTION_EXTRA_LENGTH; } +#endif // TOXENCRYPTSAVE_ENABLED - // save buffer to a file - FILE *file = fopen(full_path, "w"); - if (file) + // save buffer to a file + FILE *file = fopen(full_path, "w"); + if (file) { - size_t saved_size = fwrite(d, 1, size, file); - fclose(file); + size_t saved_size = fwrite(d, 1, size, file); + fclose(file); - return saved_size == size; + return saved_size == size; } - return -1; + return -1; } /** @@ -127,12 +127,12 @@ int twc_profile_buffer_close_callback(void *data, struct t_gui_buffer *buffer) { - struct t_twc_profile *profile = data; + struct t_twc_profile *profile = data; - profile->buffer = NULL; - twc_profile_unload(profile); + profile->buffer = NULL; + twc_profile_unload(profile); - return WEECHAT_RC_OK; + return WEECHAT_RC_OK; } /** @@ -141,7 +141,7 @@ twc_profile_buffer_close_callback(void *data, void twc_profile_init() { - twc_profiles = twc_list_new(); + twc_profiles = twc_list_new(); } /** @@ -150,30 +150,30 @@ twc_profile_init() struct t_twc_profile * twc_profile_new(const char *name) { - struct t_twc_profile *profile = malloc(sizeof(struct t_twc_profile)); - profile->name = strdup(name); + struct t_twc_profile *profile = malloc(sizeof(struct t_twc_profile)); + profile->name = strdup(name); - // add to profile list - twc_list_item_new_data_add(twc_profiles, profile); + // add to profile list + twc_list_item_new_data_add(twc_profiles, profile); - // set up internal vars - profile->tox = NULL; - profile->buffer = NULL; - profile->tox_do_timer = NULL; - profile->tox_online = false; + // set up internal vars + profile->tox = NULL; + profile->buffer = NULL; + profile->tox_do_timer = NULL; + profile->tox_online = false; - profile->chats = twc_list_new(); - profile->friend_requests = twc_list_new(); - profile->group_chat_invites = twc_list_new(); - profile->message_queues = weechat_hashtable_new(32, - WEECHAT_HASHTABLE_INTEGER, - WEECHAT_HASHTABLE_POINTER, - NULL, NULL); + profile->chats = twc_list_new(); + profile->friend_requests = twc_list_new(); + profile->group_chat_invites = twc_list_new(); + profile->message_queues = weechat_hashtable_new(32, + WEECHAT_HASHTABLE_INTEGER, + WEECHAT_HASHTABLE_POINTER, + NULL, NULL); - // set up config - twc_config_init_profile(profile); + // set up config + twc_config_init_profile(profile); - return profile; + return profile; } /** @@ -183,31 +183,31 @@ void twc_profile_set_options(struct Tox_Options *options, struct t_twc_profile *profile) { - tox_options_default(options); + tox_options_default(options); - const char *proxy_host = - TWC_PROFILE_OPTION_STRING(profile, TWC_PROFILE_OPTION_PROXY_ADDRESS); - if (proxy_host) - options->proxy_host = proxy_host; + const char *proxy_host = + TWC_PROFILE_OPTION_STRING(profile, TWC_PROFILE_OPTION_PROXY_ADDRESS); + if (proxy_host) + options->proxy_host = proxy_host; - switch (TWC_PROFILE_OPTION_INTEGER(profile, TWC_PROFILE_OPTION_PROXY_TYPE)) + switch (TWC_PROFILE_OPTION_INTEGER(profile, TWC_PROFILE_OPTION_PROXY_TYPE)) { - case TWC_PROXY_NONE: - options->proxy_type = TOX_PROXY_TYPE_NONE; - break; - case TWC_PROXY_SOCKS5: - options->proxy_type = TOX_PROXY_TYPE_SOCKS5; - break; - case TWC_PROXY_HTTP: - options->proxy_type = TOX_PROXY_TYPE_HTTP; - break; + case TWC_PROXY_NONE: + options->proxy_type = TOX_PROXY_TYPE_NONE; + break; + case TWC_PROXY_SOCKS5: + options->proxy_type = TOX_PROXY_TYPE_SOCKS5; + break; + case TWC_PROXY_HTTP: + options->proxy_type = TOX_PROXY_TYPE_HTTP; + break; } - options->proxy_port = + options->proxy_port = TWC_PROFILE_OPTION_INTEGER(profile, TWC_PROFILE_OPTION_PROXY_PORT); - options->udp_enabled = + options->udp_enabled = TWC_PROFILE_OPTION_BOOLEAN(profile, TWC_PROFILE_OPTION_UDP); - options->ipv6_enabled = + options->ipv6_enabled = TWC_PROFILE_OPTION_BOOLEAN(profile, TWC_PROFILE_OPTION_IPV6); } @@ -216,56 +216,55 @@ twc_tox_new_print_error(struct t_twc_profile *profile, struct Tox_Options *options, TOX_ERR_NEW error) { - switch (error) + switch (error) { case TOX_ERR_NEW_MALLOC: - weechat_printf(profile->buffer, - "%scould not load Tox (malloc error)", - weechat_prefix("error")); - break; + weechat_printf(profile->buffer, + "%scould not load Tox (malloc error)", + weechat_prefix("error")); + break; case TOX_ERR_NEW_PORT_ALLOC: - weechat_printf(profile->buffer, - "%scould not load Tox (failed to allocate a port)", - weechat_prefix("error")); - break; + weechat_printf(profile->buffer, + "%scould not load Tox (failed to allocate a port)", + weechat_prefix("error")); + break; case TOX_ERR_NEW_PROXY_BAD_TYPE: - weechat_printf(profile->buffer, - "%scould not load Tox (internal error; bad proxy type)", - weechat_prefix("error")); - break; + weechat_printf(profile->buffer, + "%scould not load Tox (internal error; bad proxy type)", + weechat_prefix("error")); + break; case TOX_ERR_NEW_PROXY_BAD_HOST: - weechat_printf(profile->buffer, - "%scould not load Tox (invalid proxy host: \"%s\")", - weechat_prefix("error"), options->proxy_host); - break; + weechat_printf(profile->buffer, + "%scould not load Tox (invalid proxy host: \"%s\")", + weechat_prefix("error"), options->proxy_host); + break; case TOX_ERR_NEW_PROXY_BAD_PORT: - weechat_printf(profile->buffer, - "%scould not load Tox (invalid proxy port: \"%d\")", - weechat_prefix("error"), options->proxy_port); - break; + weechat_printf(profile->buffer, + "%scould not load Tox (invalid proxy port: \"%d\")", + weechat_prefix("error"), options->proxy_port); + break; case TOX_ERR_NEW_PROXY_NOT_FOUND: - weechat_printf(profile->buffer, - "%scould not load Tox (proxy host not found: \"%s\")", - weechat_prefix("error"), options->proxy_host); - break; + weechat_printf(profile->buffer, + "%scould not load Tox (proxy host not found: \"%s\")", + weechat_prefix("error"), options->proxy_host); + break; case TOX_ERR_NEW_LOAD_ENCRYPTED: - weechat_printf(profile->buffer, - "%scould not load Tox (encrypted data files are not yet supported)", - weechat_prefix("error")); - break; + weechat_printf(profile->buffer, + "%scould not load Tox (encrypted data files are not yet supported)", + weechat_prefix("error")); + break; case TOX_ERR_NEW_LOAD_BAD_FORMAT: - weechat_printf(profile->buffer, - "%scould not load Tox (invalid data file, some data " - "may have been loaded; use -force to try using it)", - weechat_prefix("error")); - break; + weechat_printf(profile->buffer, + "%scould not load Tox (invalid data file, some data " + "may have been loaded; use -force to try using it)", + weechat_prefix("error")); + break; default: - weechat_printf(profile->buffer, - "%scould not load Tox (unknown error %d)", - weechat_prefix("error"), error); - break; + weechat_printf(profile->buffer, + "%scould not load Tox (unknown error %d)", + weechat_prefix("error"), error); + break; } - } /** @@ -279,14 +278,14 @@ twc_profile_load(struct t_twc_profile *profile) return TWC_RC_ERROR; if (!(profile->buffer)) - { - // create main buffer - profile->buffer = weechat_buffer_new(profile->name, - NULL, NULL, - twc_profile_buffer_close_callback, profile); - if (!(profile->buffer)) - return TWC_RC_ERROR; - } + { + // create main buffer + profile->buffer = weechat_buffer_new(profile->name, + NULL, NULL, + twc_profile_buffer_close_callback, profile); + if (!(profile->buffer)) + return TWC_RC_ERROR; + } weechat_printf(profile->buffer, "%sprofile %s connecting", @@ -300,32 +299,38 @@ twc_profile_load(struct t_twc_profile *profile) // print a proxy message if (options.proxy_type != TOX_PROXY_TYPE_NONE) - { - weechat_printf(profile->buffer, - "%susing %s proxy %s:%d", - weechat_prefix("network"), - options.proxy_type == TOX_PROXY_TYPE_HTTP ? "HTTP" : - TOX_PROXY_TYPE_SOCKS5 ? "SOCKS5" : - NULL, - options.proxy_host, options.proxy_port); - } + { + weechat_printf(profile->buffer, + "%susing %s proxy %s:%d", + weechat_prefix("network"), + options.proxy_type == TOX_PROXY_TYPE_HTTP ? "HTTP" : + TOX_PROXY_TYPE_SOCKS5 ? "SOCKS5" : + NULL, + options.proxy_host, options.proxy_port); + } // try loading data file char *path = twc_profile_expanded_data_path(profile); FILE *file = NULL; size_t data_size; + if (!(file = fopen(path, "r"))) + { data_size = 0; - else { + } + else + { fseek(file, 0, SEEK_END); data_size = ftell(file); } - uint8_t data[data_size]; - uint8_t dec_data[data_size]; - if (file) { + uint8_t data[data_size]; + + if (file) + { rewind(file); - if ((data_size != fread(&data, 1, data_size, file))) { + if ((data_size != fread(&data, 1, data_size, file))) + { fclose(file); weechat_printf(profile->buffer, "%scould not load Tox data file, aborting", weechat_prefix("error")); @@ -333,6 +338,10 @@ twc_profile_load(struct t_twc_profile *profile) } fclose(file); } + +#if TOXENCRYPTSAVE_ENABLED + uint8_t dec_data[data_size]; + if (data_size && tox_is_data_encrypted(data)) { char *pw = weechat_config_string(profile->options[TWC_PROFILE_OPTION_PASSPHRASE]); @@ -357,9 +366,12 @@ twc_profile_load(struct t_twc_profile *profile) options.savedata_data = dec_data; } else + { options.savedata_data = data; + } +#endif // TOXENCRYPTSAVE_ENABLED - options.savedata_type = (data_size == 0)? TOX_SAVEDATA_TYPE_NONE: TOX_SAVEDATA_TYPE_TOX_SAVE; + options.savedata_type = (data_size == 0) ? TOX_SAVEDATA_TYPE_NONE : TOX_SAVEDATA_TYPE_TOX_SAVE; options.savedata_length = data_size; // create Tox