summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Lidén Borell <samuel@kodafritt.se>2015-06-21 12:58:05 (GMT)
committerSamuel Lidén Borell <samuel@kodafritt.se>2015-06-21 12:58:05 (GMT)
commit18a06d21042ca7598fa0903a1297d9e57393828d (patch)
treeaff03db258a663f7478d42342805f3cb5653d6fb
parentded0ae803a802876b23520c4ce9ce4ad2070434c (diff)
downloadfishlim-18a06d21042ca7598fa0903a1297d9e57393828d.zip
fishlim-18a06d21042ca7598fa0903a1297d9e57393828d.tar.gz
fishlim-18a06d21042ca7598fa0903a1297d9e57393828d.tar.bz2
Add /copykey command
-rw-r--r--README14
-rw-r--r--plugin_xchat.c55
2 files changed, 67 insertions, 2 deletions
diff --git a/README b/README
index f710e0f..5cab819 100644
--- a/README
+++ b/README
@@ -37,11 +37,11 @@ Commands
Sets the encryption key for the nick or channel to password. The keys
are stored in the configuration file in ~/.config/hexchat/blow.ini
-
+
Optionally, the block cipher mode for outgoing messages may be specified.
If unspecified it will be ECB for backwards compatibility, but for
greater security, please use CBC mode if possible.
-
+
For incoming messages, the block cipher mode is auto-detected, regardless
of which mode was configured with this command.
@@ -51,6 +51,16 @@ Commands
Sets the cipher mode to ECB or CBC. See /setkey.
+/copykey from [to]
+
+ Copies the key from the given channel or nick. If no "to" nick or channel
+ is given, then it copies to the one which is currently open.
+
+ This command can be used to use an existing channel key when chatting
+ with a single user. To do so, open a dialog with the user and type
+ /copykey #nameofchannel
+
+
/delkey nick-or-#channel
Deletes the given nick or channel from the configuration file.
diff --git a/plugin_xchat.c b/plugin_xchat.c
index 8e6197b..9f10a05 100644
--- a/plugin_xchat.c
+++ b/plugin_xchat.c
@@ -41,12 +41,14 @@
#include "fish.h"
#include "keystore.h"
#include "irc.h"
+#include "misc.h"
static const char plugin_name[] = "FiSHLiM";
static const char plugin_desc[] = "Encryption plugin for the FiSH protocol. Less is More!";
static const char plugin_version[] = "0.0.19";
static const char usage_setkey[] = "Usage: SETKEY [<nick or #channel>] [<mode>:]<password>, sets the key for a channel or nick. Modes: ECB, CBC";
+static const char usage_copykey[] = "Usage: COPYKEY <from nick or #channel> [<to nick or #channel>], copies the key from another channel or nick.";
static const char usage_ciphermode[] = "Usage: CIPHERMODE [<nick or #channel>] <mode>, sets the cipher mode for a channel or nick to ECB or CBC";
static const char usage_delkey[] = "Usage: DELKEY <nick or #channel>, deletes the key for a channel or nick";
@@ -241,6 +243,58 @@ static int handle_setkey(char *word[], char *word_eol[], void *userdata) {
}
/**
+ * Command handler for /copykey
+ */
+static int handle_copykey(char *word[], char *word_eol[], void *userdata) {
+ const char *from, *to;
+ bool is_cbc;
+
+ // Check syntax
+ if (*word[2] == '\0') {
+ hexchat_printf(ph, "%s\n", usage_copykey);
+ return HEXCHAT_EAT_HEXCHAT;
+ }
+
+ if (*word[3] == '\0') {
+ // /copykey #from
+ from = word_eol[2];
+ to = hexchat_get_info(ph, "channel");
+ } else {
+ // /copykey #from #to
+ from = word[2];
+ to = word_eol[3];
+ }
+
+ // Get the key of the old nick/channel
+ char *key = keystore_get_key(from, &is_cbc);
+ if (!key) {
+ hexchat_printf(ph, "\00305Could not get key of %s\n", from);
+ return HEXCHAT_EAT_HEXCHAT;
+ }
+
+ // Prevent accidental overwites
+ char *existingkey = keystore_get_key(to, NULL);
+ if (existingkey) {
+ secure_erase(existingkey, strlen(existingkey));
+ free(existingkey);
+ hexchat_printf(ph, "\00305A key already exists for %s. "
+ "You can use /delkey to delete it.\n", to);
+ return HEXCHAT_EAT_HEXCHAT;
+ }
+
+ // Set the key of the new nick/channel
+ if (keystore_store_key(to, key, is_cbc)) {
+ hexchat_printf(ph, "Copied key from %s to %s (%s)\n", from, to, is_cbc ? "CBC mode" : "old insecure ECB mode");
+ } else {
+ hexchat_printf(ph, "\00305Failed to store key in blow.ini\n");
+ }
+
+ secure_erase(key, strlen(key));
+ free(key);
+ return HEXCHAT_EAT_HEXCHAT;
+}
+
+/**
* Command handler for /ciphermode
*/
static int handle_ciphermode(char *word[], char *word_eol[], void *userdata) {
@@ -334,6 +388,7 @@ int hexchat_plugin_init(hexchat_plugin *plugin_handle,
/* Register commands */
hexchat_hook_command(ph, "SETKEY", HEXCHAT_PRI_NORM, handle_setkey, usage_setkey, NULL);
+ hexchat_hook_command(ph, "COPYKEY", HEXCHAT_PRI_NORM, handle_copykey, usage_copykey, NULL);
hexchat_hook_command(ph, "CIPHERMODE", HEXCHAT_PRI_NORM, handle_ciphermode, usage_ciphermode, NULL);
hexchat_hook_command(ph, "DELKEY", HEXCHAT_PRI_NORM, handle_delkey, usage_delkey, NULL);