diff options
Diffstat (limited to 'plugins/fishlim')
-rw-r--r-- | plugins/fishlim/Makefile.am | 8 | ||||
-rw-r--r-- | plugins/fishlim/fish.c | 44 | ||||
-rw-r--r-- | plugins/fishlim/fish.h | 3 | ||||
-rw-r--r-- | plugins/fishlim/fishlim.vcxproj | 66 | ||||
-rw-r--r-- | plugins/fishlim/fishlim.vcxproj.filters | 6 | ||||
-rw-r--r-- | plugins/fishlim/irc.c | 54 | ||||
-rw-r--r-- | plugins/fishlim/irc.h | 5 | ||||
-rw-r--r-- | plugins/fishlim/keystore.c | 92 | ||||
-rw-r--r-- | plugins/fishlim/keystore.h | 9 | ||||
-rw-r--r-- | plugins/fishlim/misc.c | 54 | ||||
-rw-r--r-- | plugins/fishlim/misc.h | 36 | ||||
-rw-r--r-- | plugins/fishlim/plugin_hexchat.c | 137 | ||||
-rw-r--r-- | plugins/fishlim/plugin_hexchat.h | 1 | ||||
-rw-r--r-- | plugins/fishlim/test.c | 94 |
14 files changed, 172 insertions, 437 deletions
diff --git a/plugins/fishlim/Makefile.am b/plugins/fishlim/Makefile.am index 255ea0c3..df541396 100644 --- a/plugins/fishlim/Makefile.am +++ b/plugins/fishlim/Makefile.am @@ -3,7 +3,7 @@ EXTRA_DIST = INSTALL LICENSE libdir = $(hexchatlibdir) lib_LTLIBRARIES = fishlim.la -fishlim_la_SOURCES = fish.c irc.c keystore.c misc.c plugin_hexchat.c -fishlim_la_LDFLAGS = -avoid-version -module -fishlim_la_LIBADD = -AM_CPPFLAGS = $(COMMON_CFLAGS) -I$(srcdir)/../../src/common +fishlim_la_SOURCES = fish.c irc.c keystore.c plugin_hexchat.c +fishlim_la_LDFLAGS = $(PLUGIN_LDFLAGS) -module +fishlim_la_LIBADD = $(GLIB_LIBS) $(OPENSSL_LIBS) +fishlim_la_CFLAGS = $(GLIB_CFLAGS) $(OPENSSL_CFLAGS) -I$(top_srcdir)/src/common diff --git a/plugins/fishlim/fish.c b/plugins/fishlim/fish.c index 93420f23..00ecfbfa 100644 --- a/plugins/fishlim/fish.c +++ b/plugins/fishlim/fish.c @@ -39,17 +39,17 @@ static const char fish_base64[64] = "./0123456789abcdefghijklmnopqrstuvwxyzABCDE static const signed char fish_unbase64[256] = { IB,IB,IB,IB,IB,IB,IB,IB, IB,IB,IB,IB,IB,IB,IB,IB, IB,IB,IB,IB,IB,IB,IB,IB, IB,IB,IB,IB,IB,IB,IB,IB, -// ! " # $ % & ' ( ) * + , - . / +/* ! " # $ % & ' ( ) * + , - . / */ IB,IB,IB,IB,IB,IB,IB,IB, IB,IB,IB,IB,IB,IB, 0, 1, -// 0 1 2 3 4 5 6 7 8 9 : ; < = > ? +/* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */ 2, 3, 4, 5, 6, 7, 8, 9, 10,11,IB,IB,IB,IB,IB,IB, -// @ A B C D E F G H I J K L M N O +/* @ A B C D E F G H I J K L M N O */ IB,38,39,40,41,42,43,44, 45,46,47,48,49,50,51,52, -// P Q R S T U V W X Y Z [ \ ] ^ _ +/* P Q R S T U V W X Y Z [ \ ] ^ _*/ 53,54,55,56,57,58,59,60, 61,62,63,IB,IB,IB,IB,IB, -// ` a b c d e f g h i j k l m n o +/* ` a b c d e f g h i j k l m n o */ IB,12,13,14,15,16,17,18, 19,20,21,22,23,24,25,26, -// p q r s t u v w x y z { | } ~ <del> +/* p q r s t u v w x y z { | } ~ <del> */ 27,28,29,30,31,32,33,34, 35,36,37,IB,IB,IB,IB,IB, }; @@ -75,12 +75,11 @@ char *fish_encrypt(const char *key, size_t keylen, const char *message) { messagelen = strlen(message); if (messagelen == 0) return NULL; - encrypted = malloc(((messagelen-1)/8)*12 + 12 + 1); // each 8-byte block becomes 12 bytes + encrypted = g_malloc(((messagelen - 1) / 8) * 12 + 12 + 1); /* each 8-byte block becomes 12 bytes */ end = encrypted; - if (!encrypted) return NULL; while (*message) { - // Read 8 bytes (a Blowfish block) + /* Read 8 bytes (a Blowfish block) */ BF_LONG binary[2] = { 0, 0 }; unsigned char c; for (i = 0; i < 8; i++) { @@ -90,10 +89,10 @@ char *fish_encrypt(const char *key, size_t keylen, const char *message) { } message += 8; - // Encrypt block + /* Encrypt block */ BF_encrypt(binary, &bfkey); - // Emit FiSH-BASE64 + /* Emit FiSH-BASE64 */ bit = 0; word = 1; for (j = 0; j < 12; j++) { @@ -106,7 +105,7 @@ char *fish_encrypt(const char *key, size_t keylen, const char *message) { } } - // Stop if a null terminator was found + /* Stop if a null terminator was found */ if (c == '\0') break; } *end = '\0'; @@ -124,12 +123,11 @@ char *fish_decrypt(const char *key, size_t keylen, const char *data) { unsigned char d; BF_set_key(&bfkey, keylen, (const unsigned char*)key); - decrypted = malloc(strlen(data)+1); + decrypted = g_malloc(strlen(data) + 1); end = decrypted; - if (!decrypted) return NULL; while (*data) { - // Convert from FiSH-BASE64 + /* Convert from FiSH-BASE64 */ BF_LONG binary[2] = { 0, 0 }; bit = 0; word = 1; @@ -144,10 +142,10 @@ char *fish_decrypt(const char *key, size_t keylen, const char *data) { } } - // Decrypt block + /* Decrypt block */ BF_decrypt(binary, &bfkey); - // Copy to buffer + /* Copy to buffer */ GET_BYTES(end, binary[0]); GET_BYTES(end, binary[1]); } @@ -165,14 +163,14 @@ char *fish_encrypt_for_nick(const char *nick, const char *data) { char *key; char *encrypted; - // Look for key + /* Look for key */ key = keystore_get_key(nick); if (!key) return NULL; - // Encrypt + /* Encrypt */ encrypted = fish_encrypt(key, strlen(key), data); - free(key); + g_free(key); return encrypted; } @@ -183,14 +181,14 @@ char *fish_encrypt_for_nick(const char *nick, const char *data) { char *fish_decrypt_from_nick(const char *nick, const char *data) { char *key; char *decrypted; - // Look for key + /* Look for key */ key = keystore_get_key(nick); if (!key) return NULL; - // Decrypt + /* Decrypt */ decrypted = fish_decrypt(key, strlen(key), data); - free(key); + g_free(key); return decrypted; } diff --git a/plugins/fishlim/fish.h b/plugins/fishlim/fish.h index db471326..238f52e7 100644 --- a/plugins/fishlim/fish.h +++ b/plugins/fishlim/fish.h @@ -25,9 +25,10 @@ #ifndef FISH_H #define FISH_H -#include <stdbool.h> #include <stddef.h> +#include <glib.h> + char *fish_encrypt(const char *key, size_t keylen, const char *message); char *fish_decrypt(const char *key, size_t keylen, const char *data); char *fish_encrypt_for_nick(const char *nick, const char *data); diff --git a/plugins/fishlim/fishlim.vcxproj b/plugins/fishlim/fishlim.vcxproj index f1eb95ba..25492a82 100644 --- a/plugins/fishlim/fishlim.vcxproj +++ b/plugins/fishlim/fishlim.vcxproj @@ -2,6 +2,7 @@ <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup Label="Configuration"> <PlatformToolset>v120</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> </PropertyGroup> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Release|Win32"> @@ -19,57 +20,19 @@ <RootNamespace>fishlim</RootNamespace> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\win32\hexchat.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\win32\hexchat.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - <TargetName>hcfishlim</TargetName> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\win32\hexchat.props" /> + <PropertyGroup> <TargetName>hcfishlim</TargetName> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> + <OutDir>$(HexChatRel)plugins\</OutDir> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;FISHLIM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MultiProcessorCompilation>true</MultiProcessorCompilation> - <AdditionalIncludeDirectories>$(DepsRoot)\include;$(Glib);..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <AdditionalIncludeDirectories>$(DepsRoot)\include;$(Glib);..\..\src\common;$(HexChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> </ClCompile> <Link> - <SubSystem>Windows</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> <ModuleDefinitionFile>fishlim.def</ModuleDefinitionFile> <AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalDependencies>$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies> @@ -77,19 +40,10 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;FISHLIM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MultiProcessorCompilation>true</MultiProcessorCompilation> - <AdditionalIncludeDirectories>$(DepsRoot)\include;$(Glib);..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <AdditionalIncludeDirectories>$(DepsRoot)\include;$(Glib);..\..\src\common;$(HexChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> </ClCompile> <Link> - <SubSystem>Windows</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> <ModuleDefinitionFile>fishlim.def</ModuleDefinitionFile> <AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalDependencies>$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies> @@ -103,17 +57,13 @@ <ClInclude Include="fish.h" /> <ClInclude Include="irc.h" /> <ClInclude Include="keystore.h" /> - <ClInclude Include="misc.h" /> <ClInclude Include="plugin_hexchat.h" /> </ItemGroup> <ItemGroup> <ClCompile Include="fish.c" /> <ClCompile Include="irc.c" /> <ClCompile Include="keystore.c" /> - <ClCompile Include="misc.c" /> <ClCompile Include="plugin_hexchat.c" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> \ No newline at end of file +</Project> diff --git a/plugins/fishlim/fishlim.vcxproj.filters b/plugins/fishlim/fishlim.vcxproj.filters index 7c13733b..d8fbf454 100644 --- a/plugins/fishlim/fishlim.vcxproj.filters +++ b/plugins/fishlim/fishlim.vcxproj.filters @@ -32,9 +32,6 @@ <ClInclude Include="keystore.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="misc.h"> - <Filter>Header Files</Filter> - </ClInclude> <ClInclude Include="plugin_hexchat.h"> <Filter>Header Files</Filter> </ClInclude> @@ -49,9 +46,6 @@ <ClCompile Include="keystore.c"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="misc.c"> - <Filter>Source Files</Filter> - </ClCompile> <ClCompile Include="plugin_hexchat.c"> <Filter>Source Files</Filter> </ClCompile> diff --git a/plugins/fishlim/irc.c b/plugins/fishlim/irc.c index 3586921b..deba545b 100644 --- a/plugins/fishlim/irc.c +++ b/plugins/fishlim/irc.c @@ -22,8 +22,9 @@ */ -#include <stdlib.h> -#include <string.h> +#include "config.h" + +#include <glib.h> #include "irc.h" /** @@ -31,26 +32,26 @@ * at spaces. The prefix and command is extracted from the message, and * parameters_offset is set to the index of the first parameter. */ -bool irc_parse_message(const char *words[], +gboolean irc_parse_message(const char *words[], const char **prefix, const char **command, size_t *parameters_offset) { size_t w = 1; if (prefix) *prefix = NULL; if (command) *command = NULL; - // See if the message starts with a prefix (sender user) + /* See if the message starts with a prefix (sender user) */ if (words[w][0] == ':') { if (prefix) *prefix = &words[w][1]; w++; } - // Check command - if (words[w][0] == '\0') return false; + /* Check command */ + if (words[w][0] == '\0') return FALSE; if (command) *command = words[w]; w++; *parameters_offset = w; - return true; + return TRUE; } @@ -65,48 +66,15 @@ bool irc_parse_message(const char *words[], */ char *irc_prefix_get_nick(const char *prefix) { const char *end; - char *nick; size_t length; if (!prefix) return NULL; - // Find end of nick + /* Find end of nick */ end = prefix; while (*end != '\0' && *end != '!' && *end != '@') end++; - // Allocate string + /* Allocate string */ length = end - prefix; - nick = malloc(length+1); - if (!nick) return NULL; - - // Copy to string - memcpy(nick, prefix, length); - nick[length] = '\0'; - return nick; -} - - -/** - * Compares two nick names. Return 0 if equal. Otherwise the return value is - * less than zero if a is less than b or greater than zero if a is greater - * than b. - */ -int irc_nick_cmp(const char *a, const char *b) { - char ac; - char bc; - char diff; - for (;;) { - ac = *(a++); - bc = *(b++); - - // Change into IRC uppercase (see RFC 2812 section 2.2) - if (ac >= 'a' && ac <= '~') ac &= ~0x20; - if (bc >= 'a' && bc <= '~') bc &= ~0x20; - - diff = ac - bc; - if (diff) return diff; - if (!ac) return 0; - } + return g_strndup (prefix, length); } - - diff --git a/plugins/fishlim/irc.h b/plugins/fishlim/irc.h index 87317130..c5649233 100644 --- a/plugins/fishlim/irc.h +++ b/plugins/fishlim/irc.h @@ -25,14 +25,13 @@ #ifndef IRC_H #define IRC_H -#include <stdbool.h> #include <stddef.h> +#include <glib.h> -bool irc_parse_message(const char *words[], +gboolean irc_parse_message(const char *words[], const char **prefix, const char **command, size_t *parameters_offset); char *irc_prefix_get_nick(const char *prefix); -int irc_nick_cmp(const char *a, const char *b); #endif diff --git a/plugins/fishlim/keystore.c b/plugins/fishlim/keystore.c index 9f1c446e..84373996 100644 --- a/plugins/fishlim/keystore.c +++ b/plugins/fishlim/keystore.c @@ -22,12 +22,13 @@ */ +#include "config.h" + #include <glib.h> #include <stdlib.h> #include <string.h> #include "irc.h" #include "fish.h" -#include "misc.h" #include "keystore.h" #include "plugin_hexchat.h" @@ -57,7 +58,7 @@ static GKeyFile *getConfigFile() { static const char *get_keystore_password() { return (keystore_password != NULL ? keystore_password : - // Silly default value... + /* Silly default value... */ "blowinikey"); } @@ -87,17 +88,17 @@ static gchar *get_nick_value(GKeyFile *keyfile, const char *nick, const char *it * Extracts a key from the key store file. */ char *keystore_get_key(const char *nick) { - // Get the key + /* Get the key */ GKeyFile *keyfile = getConfigFile(); gchar *value = get_nick_value(keyfile, nick, "key"); g_key_file_free(keyfile); if (!value) return NULL; if (strncmp(value, "+OK ", 4) != 0) { - // Key is stored in plaintext - return import_glib_string(value); + /* Key is stored in plaintext */ + return value; } else { - // Key is encrypted + /* Key is encrypted */ const char *encrypted = value+4; const char *password = get_keystore_password(); char *decrypted = fish_decrypt(password, strlen(password), encrypted); @@ -109,10 +110,10 @@ char *keystore_get_key(const char *nick) { /** * Deletes a nick and the associated key in the key store file. */ -static bool delete_nick(GKeyFile *keyfile, const char *nick) { +static gboolean delete_nick(GKeyFile *keyfile, const char *nick) { gchar **group; gchar **groups = g_key_file_get_groups(keyfile, NULL); - bool ok = false; + gboolean ok = FALSE; for (group = groups; *group != NULL; group++) { if (!irc_nick_cmp(*group, nick)) { @@ -125,58 +126,77 @@ static bool delete_nick(GKeyFile *keyfile, const char *nick) { return ok; } +#if !GLIB_CHECK_VERSION(2,40,0) /** * Writes the key store file to disk. */ -static bool save_keystore(GKeyFile *keyfile) { - char *filename; - bool ok; - // Serialize +static gboolean keyfile_save_to_file (GKeyFile *keyfile, char *filename) { + gboolean ok; + + /* Serialize */ gsize file_length; gchar *file_data = g_key_file_to_data(keyfile, &file_length, NULL); - if (!file_data) return false; - - // Write to file - filename = get_config_filename(); - ok = g_file_set_contents(filename, file_data, file_length, NULL); - g_free(filename); + if (!file_data) + return FALSE; + + /* Write to file */ + ok = g_file_set_contents (filename, file_data, file_length, NULL); g_free(file_data); return ok; } +#endif + +/** + * Writes the key store file to disk. + */ +static gboolean save_keystore(GKeyFile *keyfile) { + char *filename; + gboolean ok; + + filename = get_config_filename(); +#if !GLIB_CHECK_VERSION(2,40,0) + ok = keyfile_save_to_file (keyfile, filename); +#else + ok = g_key_file_save_to_file (keyfile, filename, NULL); +#endif + g_free (filename); + + return ok; +} /** * Sets a key in the key store file. */ -bool keystore_store_key(const char *nick, const char *key) { +gboolean keystore_store_key(const char *nick, const char *key) { const char *password; char *encrypted; char *wrapped; - bool ok = false; + gboolean ok = FALSE; GKeyFile *keyfile = getConfigFile(); - // Remove old key + /* Remove old key */ delete_nick(keyfile, nick); - // Add new key + /* Add new key */ password = get_keystore_password(); if (password) { - // Encrypt the password + /* Encrypt the password */ encrypted = fish_encrypt(password, strlen(password), key); if (!encrypted) goto end; - // Prepend "+OK " + /* Prepend "+OK " */ wrapped = g_strconcat("+OK ", encrypted, NULL); g_free(encrypted); - // Store encrypted in file + /* Store encrypted in file */ g_key_file_set_string(keyfile, nick, "key", wrapped); - free(wrapped); + g_free(wrapped); } else { - // Store unencrypted in file + /* Store unencrypted in file */ g_key_file_set_string(keyfile, nick, "key", key); } - // Save key store file + /* Save key store file */ ok = save_keystore(keyfile); end: @@ -187,23 +207,15 @@ bool keystore_store_key(const char *nick, const char *key) { /** * Deletes a nick from the key store. */ -bool keystore_delete_nick(const char *nick) { +gboolean keystore_delete_nick(const char *nick) { GKeyFile *keyfile = getConfigFile(); - // Delete entry - bool ok = delete_nick(keyfile, nick); + /* Delete entry */ + gboolean ok = delete_nick(keyfile, nick); - // Save + /* Save */ if (ok) save_keystore(keyfile); g_key_file_free(keyfile); return ok; } - - -void keystore_secure_free(void *ptr, size_t size) { - secure_erase(ptr, size); - free(ptr); -} - - diff --git a/plugins/fishlim/keystore.h b/plugins/fishlim/keystore.h index a2c33f02..3d90606a 100644 --- a/plugins/fishlim/keystore.h +++ b/plugins/fishlim/keystore.h @@ -25,14 +25,13 @@ #ifndef KEYSTORE_H #define KEYSTORE_H -#include <stdbool.h> #include <stddef.h> -char *keystore_get_key(const char *nick); -bool keystore_store_key(const char *nick, const char *key); -bool keystore_delete_nick(const char *nick); +#include <glib.h> -void keystore_secure_free(void *ptr, size_t size); +char *keystore_get_key(const char *nick); +gboolean keystore_store_key(const char *nick, const char *key); +gboolean keystore_delete_nick(const char *nick); #endif diff --git a/plugins/fishlim/misc.c b/plugins/fishlim/misc.c deleted file mode 100644 index 2b78961d..00000000 --- a/plugins/fishlim/misc.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - - Copyright (c) 2010 Samuel Lidén Borell <samuel@kodafritt.se> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - -*/ - -#include <glib.h> -#include <stdlib.h> -#include <string.h> -#include "misc.h" - - -void secure_erase(void *ptr, size_t size) { - // "volatile" prevents this code from being optimized away - volatile char* volptr = ptr; - while (size--) *volptr++ = 0; -} - -/** - * Re-allocates a string with the native allocator. - */ -char *import_glib_string(gchar *gstr) { - size_t size; - char *native; - if (g_mem_is_system_malloc()) return gstr; - - size = strlen(gstr)+1; - native = malloc(size); - memcpy(native, gstr, size); - - secure_erase(gstr, size); - g_free(gstr); - return native; -} - - diff --git a/plugins/fishlim/misc.h b/plugins/fishlim/misc.h deleted file mode 100644 index ee4fc5b8..00000000 --- a/plugins/fishlim/misc.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - - Copyright (c) 2010 Samuel Lidén Borell <samuel@kodafritt.se> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - -*/ - -#ifndef MISC_H -#define MISC_H - -void secure_erase(void *ptr, size_t size); - -#ifdef __G_LIB_H__ -char *import_glib_string(gchar *gstr); -#endif - -#endif - - diff --git a/plugins/fishlim/plugin_hexchat.c b/plugins/fishlim/plugin_hexchat.c index f200ea8c..556a2f51 100644 --- a/plugins/fishlim/plugin_hexchat.c +++ b/plugins/fishlim/plugin_hexchat.c @@ -22,17 +22,14 @@ */ +#include "config.h" + #include <glib.h> #include <stdlib.h> #include <string.h> -// #pragma GCC visibility push(default) #include "hexchat-plugin.h" #define HEXCHAT_MAX_WORDS 32 -// #pragma GCC visibility pop - -//#define EXPORT __attribute((visibility("default"))) -//#define EXPORT #include "fish.h" #include "keystore.h" @@ -52,26 +49,18 @@ static hexchat_plugin *ph; * Returns the path to the key store file. */ gchar *get_config_filename() { - return g_build_filename(hexchat_get_info(ph, "configdir"), "addon_fishlim.conf", NULL); -} + char *filename_fs, *filename_utf8; -/** - * Appends data to a string. Returns true if there was sufficient memory. - * Frees *s and returns false if an error occurs. - */ -static bool append(char **s, size_t *length, const char *data) { - size_t datalen = strlen(data); - char *extended = realloc(*s, *length + datalen + 1); - if (!extended) { - free(*s); - return false; - } - memcpy(extended + *length, data, datalen + 1); - *s = extended; - *length += datalen; - return true; + filename_utf8 = g_build_filename(hexchat_get_info(ph, "configdir"), "addon_fishlim.conf", NULL); + filename_fs = g_filename_from_utf8 (filename_utf8, -1, NULL, NULL, NULL); + + g_free (filename_utf8); + return filename_fs; } +int irc_nick_cmp(const char *a, const char *b) { + return hexchat_nickcmp (ph, a, b); +} /*static int handle_debug(char *word[], char *word_eol[], void *userdata) { hexchat_printf(ph, "debug incoming: "); @@ -87,26 +76,26 @@ static bool append(char **s, size_t *length, const char *data) { */ static int handle_outgoing(char *word[], char *word_eol[], void *userdata) { const char *own_nick; - // Encrypt the message if possible + /* Encrypt the message if possible */ const char *channel = hexchat_get_info(ph, "channel"); char *encrypted = fish_encrypt_for_nick(channel, word_eol[1]); if (!encrypted) return HEXCHAT_EAT_NONE; - // Display message + /* Display message */ own_nick = hexchat_get_info(ph, "nick"); hexchat_emit_print(ph, "Your Message", own_nick, word_eol[1], NULL); - // Send message + /* Send message */ hexchat_commandf(ph, "PRIVMSG %s :+OK %s", channel, encrypted); - free(encrypted); + g_free(encrypted); return HEXCHAT_EAT_HEXCHAT; } /** * Called when a channel message or private message is received. */ -static int handle_incoming(char *word[], char *word_eol[], void *userdata) { +static int handle_incoming(char *word[], char *word_eol[], hexchat_event_attrs *attrs, void *userdata) { const char *prefix; const char *command; const char *recipient; @@ -114,20 +103,19 @@ static int handle_incoming(char *word[], char *word_eol[], void *userdata) { const char *peice; char *sender_nick; char *decrypted; - char *message; size_t w; size_t ew; size_t uw; - size_t length; char prefix_char = 0; + GString *message; if (!irc_parse_message((const char **)word, &prefix, &command, &w)) return HEXCHAT_EAT_NONE; - // Topic (command 332) has an extra parameter + /* Topic (command 332) has an extra parameter */ if (!strcmp(command, "332")) w++; - // Look for encrypted data + /* Look for encrypted data */ for (ew = w+1; ew < HEXCHAT_MAX_WORDS-1; ew++) { const char *s = (ew == w+1 ? word[ew]+1 : word[ew]); if (*s && (s[1] == '+' || s[1] == 'm')) { prefix_char = *(s++); } @@ -136,61 +124,70 @@ static int handle_incoming(char *word[], char *word_eol[], void *userdata) { } return HEXCHAT_EAT_NONE; has_encrypted_data: ; - // Extract sender nick and recipient nick/channel + /* Extract sender nick and recipient nick/channel */ sender_nick = irc_prefix_get_nick(prefix); recipient = word[w]; - // Try to decrypt with these (the keys are searched for in the key store) + /* Try to decrypt with these (the keys are searched for in the key store) */ encrypted = word[ew+1]; decrypted = fish_decrypt_from_nick(recipient, encrypted); if (!decrypted) decrypted = fish_decrypt_from_nick(sender_nick, encrypted); - // Check for error + /* Check for error */ if (!decrypted) goto decrypt_error; - // Build unecrypted message - message = NULL; - length = 0; - if (!append(&message, &length, "RECV")) goto decrypt_error; - + /* Build unecrypted message */ + message = g_string_sized_new (100); /* TODO: more accurate estimation of size */ + g_string_append (message, "RECV"); + + if (attrs->server_time_utc) + { + GTimeVal tv = { (glong)attrs->server_time_utc, 0 }; + char *timestamp = g_time_val_to_iso8601 (&tv); + + g_string_append (message, " @time="); + g_string_append (message, timestamp); + g_free (timestamp); + } + for (uw = 1; uw < HEXCHAT_MAX_WORDS; uw++) { - if (word[uw][0] != '\0' && !append(&message, &length, " ")) goto decrypt_error; + if (word[uw][0] != '\0') + g_string_append_c (message, ' '); if (uw == ew) { - // Add the encrypted data + /* Add the encrypted data */ peice = decrypted; - uw++; // Skip "OK+" + uw++; /* Skip "OK+" */ if (ew == w+1) { - // Prefix with colon, which gets stripped out otherwise - if (!append(&message, &length, ":")) goto decrypt_error; + /* Prefix with colon, which gets stripped out otherwise */ + g_string_append_c (message, ':'); } if (prefix_char) { - char prefix_str[2] = { prefix_char, '\0' }; - if (!append(&message, &length, prefix_str)) goto decrypt_error; + g_string_append_c (message, prefix_char); } } else { - // Add unencrypted data (for example, a prefix from a bouncer or bot) + /* Add unencrypted data (for example, a prefix from a bouncer or bot) */ peice = word[uw]; } - - if (!append(&message, &length, peice)) goto decrypt_error; + + g_string_append (message, peice); } - free(decrypted); + g_free(decrypted); - // Simulate unencrypted message - //hexchat_printf(ph, "simulating: %s\n", message); - hexchat_command(ph, message); - - free(message); - free(sender_nick); + /* Simulate unencrypted message */ + /* hexchat_printf(ph, "simulating: %s\n", message->str); */ + hexchat_command(ph, message->str); + + g_string_free (message, TRUE); + g_free(sender_nick); return HEXCHAT_EAT_HEXCHAT; decrypt_error: - free(decrypted); - free(sender_nick); + g_free(decrypted); + g_free(sender_nick); return HEXCHAT_EAT_NONE; } @@ -201,23 +198,23 @@ static int handle_setkey(char *word[], char *word_eol[], void *userdata) { const char *nick; const char *key; - // Check syntax + /* Check syntax */ if (*word[2] == '\0') { hexchat_printf(ph, "%s\n", usage_setkey); return HEXCHAT_EAT_HEXCHAT; } if (*word[3] == '\0') { - // /setkey password + /* /setkey password */ nick = hexchat_get_info(ph, "channel"); key = word_eol[2]; } else { - // /setkey #channel password + /* /setkey #channel password */ nick = word[2]; key = word_eol[3]; } - // Set password + /* Set password */ if (keystore_store_key(nick, key)) { hexchat_printf(ph, "Stored key for %s\n", nick); } else { @@ -233,15 +230,15 @@ static int handle_setkey(char *word[], char *word_eol[], void *userdata) { static int handle_delkey(char *word[], char *word_eol[], void *userdata) { const char *nick; - // Check syntax + /* Check syntax */ if (*word[2] == '\0' || *word[3] != '\0') { hexchat_printf(ph, "%s\n", usage_delkey); return HEXCHAT_EAT_HEXCHAT; } - nick = word_eol[2]; + nick = g_strstrip (word_eol[2]); - // Delete the given nick from the key store + /* Delete the given nick from the key store */ if (keystore_delete_nick(nick)) { hexchat_printf(ph, "Deleted key for %s\n", nick); } else { @@ -282,11 +279,11 @@ int hexchat_plugin_init(hexchat_plugin *plugin_handle, /* Add handlers */ hexchat_hook_command(ph, "", HEXCHAT_PRI_NORM, handle_outgoing, NULL, NULL); - hexchat_hook_server(ph, "NOTICE", HEXCHAT_PRI_NORM, handle_incoming, NULL); - hexchat_hook_server(ph, "PRIVMSG", HEXCHAT_PRI_NORM, handle_incoming, NULL); - //hexchat_hook_server(ph, "RAW LINE", HEXCHAT_PRI_NORM, handle_debug, NULL); - hexchat_hook_server(ph, "TOPIC", HEXCHAT_PRI_NORM, handle_incoming, NULL); - hexchat_hook_server(ph, "332", HEXCHAT_PRI_NORM, handle_incoming, NULL); + hexchat_hook_server_attrs(ph, "NOTICE", HEXCHAT_PRI_NORM, handle_incoming, NULL); + hexchat_hook_server_attrs(ph, "PRIVMSG", HEXCHAT_PRI_NORM, handle_incoming, NULL); + /* hexchat_hook_server(ph, "RAW LINE", HEXCHAT_PRI_NORM, handle_debug, NULL); */ + hexchat_hook_server_attrs(ph, "TOPIC", HEXCHAT_PRI_NORM, handle_incoming, NULL); + hexchat_hook_server_attrs(ph, "332", HEXCHAT_PRI_NORM, handle_incoming, NULL); hexchat_printf(ph, "%s plugin loaded\n", plugin_name); /* Return success */ diff --git a/plugins/fishlim/plugin_hexchat.h b/plugins/fishlim/plugin_hexchat.h index 04a1f4ff..f60522e6 100644 --- a/plugins/fishlim/plugin_hexchat.h +++ b/plugins/fishlim/plugin_hexchat.h @@ -26,6 +26,7 @@ #define PLUGIN_HEXCHAT_H gchar *get_config_filename(); +int irc_nick_cmp (const char *, const char *); #endif diff --git a/plugins/fishlim/test.c b/plugins/fishlim/test.c deleted file mode 100644 index b4dc8d91..00000000 --- a/plugins/fishlim/test.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - - Copyright (c) 2010 Samuel Lidén Borell <samuel@kodafritt.se> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - -*/ - -#include <glib.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "fish.h" - -// We can't use the HexChat plugin API from here... -gchar *get_config_filename() { - const gchar *homedir = g_get_home_dir(); - return g_build_filename(homedir, ".config", "hexchat", "blow.ini", NULL); -} - - -static int decrypt(int nick_count, char *nicks[]) { - char encrypted[8192]; - while (fgets(encrypted, sizeof(encrypted), stdin)) { - char *msg; - for (int i = 0; i < nick_count; i++) { - msg = fish_decrypt_from_nick(nicks[i], encrypted); - if (msg) goto success; - } - fprintf(stderr, "None of the recipients were found in the key store!\n"); - return 1; - success: - fprintf(stderr, "Decrypted text >>>%s<<<\n", msg); - free(msg); - } - return 0; -} - -static int encrypt(int nick_count, char *nicks[]) { - char message[8192]; - while (fgets(message, sizeof(message), stdin)) { - // Remove newline character - char *newline = strchr(message, '\n'); - if (newline) *newline = '\0'; - - bool error = false; - for (int i = 0; i < nick_count; i++) { - char *encrypted = fish_encrypt_for_nick(nicks[i], message); - if (encrypted) { - fprintf(stderr, "Encrypted [%s]: >>>%s<<<\n", nicks[i], encrypted); - free(encrypted); - } else { - error = true; - } - } - - if (error) { - fprintf(stderr, "Some of the recipients were't found in the key store!\n"); - return 1; - } - } - return 0; -} - -int main(int argc, char *argv[]) { - if (argc < 2) { - fprintf(stderr, "usage: %s [-e] nick...\n", argv[0]); - return 2; - } - - if (strcmp(argv[1], "-e") == 0) { - return encrypt(argc-2, &argv[2]); - } else { - return decrypt(argc-1, &argv[1]); - } -} - - |