From a4901950324eb47ef5ce09264170281413d4218c Mon Sep 17 00:00:00 2001 From: Sebastien Helleu Date: Sat, 27 Jul 2013 12:57:08 +0200 Subject: [PATCH 1/7] core: add secured data with optional encryption in file sec.conf --- doc/en/weechat_dev.en.txt | 19 +- po/POTFILES.in | 2 + po/srcfiles.cmake | 2 + src/core/CMakeLists.txt | 1 + src/core/Makefile.am | 2 + src/core/wee-command.c | 186 +++- src/core/wee-completion.c | 44 + src/core/wee-config.c | 4 +- src/core/wee-eval.c | 46 +- src/core/wee-network.c | 34 +- src/core/wee-network.h | 5 +- src/core/wee-secure.c | 1039 ++++++++++++++++++++++ src/core/wee-secure.h | 67 ++ src/core/wee-string.c | 96 +- src/core/wee-string.h | 4 + src/core/wee-upgrade.c | 4 + src/core/weechat.c | 18 +- src/gui/curses/gui-curses-main.c | 57 ++ src/gui/gui-key.c | 1 + src/gui/gui-main.h | 3 + src/plugins/irc/irc-protocol.c | 40 +- src/plugins/irc/irc-server.c | 48 +- src/plugins/rmodifier/rmodifier-config.c | 3 + 23 files changed, 1632 insertions(+), 93 deletions(-) create mode 100644 src/core/wee-secure.c create mode 100644 src/core/wee-secure.h diff --git a/doc/en/weechat_dev.en.txt b/doc/en/weechat_dev.en.txt index e892c8024..4d38299fe 100644 --- a/doc/en/weechat_dev.en.txt +++ b/doc/en/weechat_dev.en.txt @@ -96,7 +96,7 @@ WeeChat "core" reside in following directories: | wee-command.c | WeeChat core commands | wee-completion.c | Completion on command line | wee-config-file.c | Configuration file management -| wee-config.c | Configuration options for WeeChat core (options weechat.*) +| wee-config.c | Configuration options for WeeChat core (file weechat.conf) | wee-debug.c | Some debug functions | wee-eval.c | Evaluate expressions with references to internal vars | wee-hashtable.c | Hashtables @@ -108,6 +108,7 @@ WeeChat "core" reside in following directories: | wee-log.c | Write to WeeChat log file (weechat.log) | wee-network.c | Network functions (connection to servers, proxy) | wee-proxy.c | Proxy management +| wee-secure.c | Secured data options (file sec.conf) | wee-string.c | Functions on strings | wee-upgrade-file.c | Internal upgrade system | wee-upgrade.c | Upgrade for WeeChat core (buffers, lines, history, ...) @@ -163,14 +164,14 @@ Plugins | weechat-plugin.h | Header designed to be distributed with WeeChat plugins, in order to compile them | alias/ | Alias plugin | alias.c | Main alias functions -| alias-config.c | Alias config options +| alias-config.c | Alias config options (file alias.conf) | alias-info.c | Alias info/infolists/hdata | aspell/ | Aspell plugin | weechat-aspell.c | Main aspell functions | weechat-aspell-bar-item.c | Aspell bar items | weechat-aspell-command.c | Aspell commands | weechat-aspell-completion.c | Aspell completions -| weechat-aspell-config.c | Aspell config options +| weechat-aspell-config.c | Aspell config options (file aspell.conf) | weechat-aspell-info.c | Aspell info/infolists/hdata | weechat-aspell-speller.c | Spellers management | charset/ | Charset plugin @@ -191,7 +192,7 @@ Plugins | irc-color.c | Color functions | irc-command.c | IRC commands | irc-completion.c | IRC completions -| irc-config.c | IRC config options +| irc-config.c | IRC config options (file irc.conf) | irc-ctcp.c | IRC CTCP | irc-debug.c | IRC debug functions | irc-ignore.c | IRC Ignore @@ -211,7 +212,7 @@ Plugins | logger/ | Logger plugin | logger.c | Main logger functions | logger-buffer.c | Logger buffer list management -| logger-config.c | Logger config options +| logger-config.c | Logger config options (file logger.conf) | logger-info.c | Logger info/infolists/hdata | logger-tail.c | Return last lines of a file | lua/ | Lua plugin @@ -229,7 +230,7 @@ Plugins | relay-client.c | Clients of relay | relay-command.c | Relay commands | relay-completion.c | Relay completions -| relay-config.c | Relay config options +| relay-config.c | Relay config options (file relay.conf) | relay-info.c | Relay info/infolists/hdata | relay-network.c | Network functions for relay | relay-raw.c | Relay raw buffer @@ -247,7 +248,7 @@ Plugins | rmodifier.c | Main rmodifier functions | rmodifier-command.c | Rmodifier commands | rmodifier-completion.c | Rmodifier completions -| rmodifier-config.c | Rmodifier config options +| rmodifier-config.c | Rmodifier config options (file rmodifier.conf) | rmodifier-debug.c | Rmodifier debug functions | rmodifier-info.c | Rmodifier info/infolists/hdata | ruby/ | Ruby plugin @@ -259,7 +260,7 @@ Plugins | script-buffer.c | Buffer for scripts manager | script-command.c | Commands for scripts manager | script-completion.c | Completions for scripts manager -| script-config.c | Config options for scripts manager +| script-config.c | Config options for scripts manager (file script.conf) | script-info.c | Script manager info/infolists/hdata | script-repo.c | Download and read repository file | tcl/ | Tcl plugin @@ -271,7 +272,7 @@ Plugins | xfer-chat.c | Xfer DCC chat | xfer-command.c | Xfer commands | xfer-completion.c | Xfer completions -| xfer-config.c | Xfer config options +| xfer-config.c | Xfer config options (file xfer.conf) | xfer-dcc.c | Xfer DCC file | xfer-file.c | File functions for xfer | xfer-info.c | Xfer info/infolists/hdata diff --git a/po/POTFILES.in b/po/POTFILES.in index 00f21c3d7..2136481b1 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -28,6 +28,8 @@ ./src/core/wee-network.h ./src/core/wee-proxy.c ./src/core/wee-proxy.h +./src/core/wee-secure.c +./src/core/wee-secure.h ./src/core/wee-string.c ./src/core/wee-string.h ./src/core/wee-upgrade.c diff --git a/po/srcfiles.cmake b/po/srcfiles.cmake index 980c01df6..63d227c03 100644 --- a/po/srcfiles.cmake +++ b/po/srcfiles.cmake @@ -29,6 +29,8 @@ SET(WEECHAT_SOURCES ./src/core/wee-network.h ./src/core/wee-proxy.c ./src/core/wee-proxy.h +./src/core/wee-secure.c +./src/core/wee-secure.h ./src/core/wee-string.c ./src/core/wee-string.h ./src/core/wee-upgrade.c diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 9122f4234..0a4032e01 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -37,6 +37,7 @@ wee-list.c wee-list.h wee-log.c wee-log.h wee-network.c wee-network.h wee-proxy.c wee-proxy.h +wee-secure.c wee-secure.h wee-string.c wee-string.h wee-upgrade.c wee-upgrade.h wee-upgrade-file.c wee-upgrade-file.h diff --git a/src/core/Makefile.am b/src/core/Makefile.am index 297a044b5..46f6f3e51 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -55,6 +55,8 @@ lib_weechat_core_a_SOURCES = weechat.c \ wee-network.h \ wee-proxy.c \ wee-proxy.h \ + wee-secure.c \ + wee-secure.h \ wee-string.c \ wee-string.h \ wee-upgrade.c \ diff --git a/src/core/wee-command.c b/src/core/wee-command.c index 2bad83267..edcbc3818 100644 --- a/src/core/wee-command.c +++ b/src/core/wee-command.c @@ -45,6 +45,7 @@ #include "wee-list.h" #include "wee-log.h" #include "wee-proxy.h" +#include "wee-secure.h" #include "wee-string.h" #include "wee-upgrade.h" #include "wee-utf8.h" @@ -4465,6 +4466,125 @@ COMMAND_CALLBACK(save) return WEECHAT_RC_OK; } +/* + * Displays a secured data. + */ + +void +command_secure_display_data (void *data, + struct t_hashtable *hashtable, + const void *key, const void *value) +{ + /* make C compiler happy */ + (void) data; + (void) hashtable; + (void) value; + + if (key) + gui_chat_printf (NULL, " %s", key); +} + +/* + * Callback for command "/secure": manage secured data + */ + +COMMAND_CALLBACK(secure) +{ + int passphrase_was_set; + + /* make C compiler happy */ + (void) data; + (void) buffer; + + /* list of secured data */ + if (argc == 1) + { + secure_buffer_open (); + return WEECHAT_RC_OK; + } + + /* set the passphrase */ + if (string_strcasecmp (argv[1], "passphrase") == 0) + { + COMMAND_MIN_ARGS(3, "secure passphrase"); + passphrase_was_set = 0; + if (secure_passphrase) + { + free (secure_passphrase); + secure_passphrase = NULL; + passphrase_was_set = 1; + } + if (strcmp (argv[2], "-delete") == 0) + { + gui_chat_printf (NULL, + (passphrase_was_set) ? + _("Passphrase deleted") : _("Passphrase is not set")); + if (passphrase_was_set) + { + if (hashtable_get_integer (secure_hashtable_data, "items_count") > 0) + command_save_file (secure_config_file); + secure_buffer_display (); + } + } + else + { + secure_passphrase = strdup (argv_eol[2]); + gui_chat_printf (NULL, + (passphrase_was_set) ? + _("Passphrase changed") : _("Passphrase added")); + if (hashtable_get_integer (secure_hashtable_data, "items_count") > 0) + command_save_file (secure_config_file); + secure_buffer_display (); + } + return WEECHAT_RC_OK; + } + + /* set a secured data */ + if (string_strcasecmp (argv[1], "set") == 0) + { + COMMAND_MIN_ARGS(4, "secure set"); + hashtable_set (secure_hashtable_data, argv[2], argv_eol[3]); + gui_chat_printf (NULL, _("Secured data \"%s\" set"), argv[2]); + command_save_file (secure_config_file); + secure_buffer_display (); + return WEECHAT_RC_OK; + } + + /* delete a secured data */ + if (string_strcasecmp (argv[1], "del") == 0) + { + COMMAND_MIN_ARGS(3, "secure del"); + if (hashtable_has_key (secure_hashtable_data, argv[2])) + { + hashtable_remove (secure_hashtable_data, argv[2]); + gui_chat_printf (NULL, _("Secured data \"%s\" deleted"), argv[2]); + command_save_file (secure_config_file); + secure_buffer_display (); + } + else + { + gui_chat_printf (NULL, + _("%sSecured data \"%s\" not found"), + gui_chat_prefix[GUI_CHAT_PREFIX_ERROR], + argv[2]); + } + return WEECHAT_RC_OK; + } + + /* toggle values on secured data buffer */ + if (string_strcasecmp (argv[1], "toggle_values") == 0) + { + if (secure_buffer) + { + secure_buffer_display_values ^= 1; + secure_buffer_display (); + } + return WEECHAT_RC_OK; + } + + return WEECHAT_RC_OK; +} + /* * Displays a configuration section. */ @@ -5143,6 +5263,14 @@ COMMAND_CALLBACK(upgrade) return WEECHAT_RC_OK; } + /* + * set passphrase in environment var, so that it will not be asked to user + * when starting the new binary + */ + if (secure_passphrase) + setenv (SECURE_ENV_PASSPHRASE, secure_passphrase, 1); + + /* execute binary */ exec_args[0] = ptr_binary; exec_args[3] = strdup (weechat_home); execvp (exec_args[0], exec_args); @@ -5150,7 +5278,8 @@ COMMAND_CALLBACK(upgrade) /* this code should not be reached if execvp is OK */ string_iconv_fprintf (stderr, "\n\n*****\n"); string_iconv_fprintf (stderr, - _("***** Error: exec failed (program: \"%s\"), exiting WeeChat"), + _("***** Error: exec failed (program: \"%s\"), " + "exiting WeeChat"), exec_args[0]); string_iconv_fprintf (stderr, "\n*****\n\n"); @@ -6614,6 +6743,49 @@ command_init () "saved."), "%(config_files)|%*", &command_save, NULL); + hook_command (NULL, "secure", + N_("manage secured data (passwords or private data encrypted " + "in file sec.conf)"), + N_("passphrase |-delete" + " || set " + " || del "), + N_("passphrase: set or change the passphrase used for " + "encryption (without passphrase, data is stored as " + "plain text in file sec.conf)\n" + " -delete: delete passphrase\n" + " set: add or change secured data\n" + " del: delete secured data\n\n" + "Without argument, this command displays secured data " + "in a new buffer.\n\n" + "When a passphrase is used (data encrypted), it is asked " + "by WeeChat on startup.\n" + "It is possible to set environment variable \"" + SECURE_ENV_PASSPHRASE "\" to prevent the prompt (this same " + "variable is used by WeeChat on /upgrade).\n\n" + "Secured data with format ${sec.data.xxx} can be used in:\n" + " - command line argument \"--run-command\"\n" + " - irc server options: autojoin, command, password, " + "sasl_{username|password}\n" + " - options weechat.startup.command_{before|after}_plugins\n" + " - command /eval.\n\n" + "Examples:\n" + " set a passphrase:\n" + " /secure passphrase this is my passphrase\n" + " encrypt freenode SASL password:\n" + " /secure set freenode mypassword\n" + " /set irc.server.freenode.sasl_password " + "\"${sec.data.freenode}\"\n" + " encrypt oftc password for nickserv:\n" + " /secure set oftc mypassword\n" + " /set irc.server.oftc.command \"/msg nickserv identify " + "${sec.data.oftc}\"\n" + " alias to ghost \"mynick\":\n" + " /alias ghost /eval /msg -server freenode nickserv " + "ghost mynick ${sec.data.freenode}"), + "passphrase -delete" + " || set %(secured_data)" + " || del %(secured_data)", + &command_secure, NULL); hook_command (NULL, "set", N_("set config options"), N_("[