diff -Nru irssi-0.8.12.orig/src/core/Makefile.am irssi-0.8.12/src/core/Makefile.am --- irssi-0.8.12.orig/src/core/Makefile.am 2008-07-28 18:32:03.000000000 +0100 +++ irssi-0.8.12/src/core/Makefile.am 2008-07-28 19:15:33.000000000 +0100 @@ -42,6 +42,7 @@ servers-setup.c \ session.c \ settings.c \ + sha1.c \ signals.c \ special-vars.c \ write-buffer.c @@ -91,6 +92,7 @@ servers-setup.h \ session.h \ settings.h \ + sha1.h \ signals.h \ special-vars.h \ window-item-def.h \ diff -Nru irssi-0.8.12.orig/src/core/Makefile.in irssi-0.8.12/src/core/Makefile.in --- irssi-0.8.12.orig/src/core/Makefile.in 2008-07-28 18:32:03.000000000 +0100 +++ irssi-0.8.12/src/core/Makefile.in 2008-07-28 19:15:33.000000000 +0100 @@ -65,7 +65,7 @@ nickmatch-cache.$(OBJEXT) pidwait.$(OBJEXT) queries.$(OBJEXT) \ rawlog.$(OBJEXT) recode.$(OBJEXT) servers.$(OBJEXT) \ servers-reconnect.$(OBJEXT) servers-setup.$(OBJEXT) \ - session.$(OBJEXT) settings.$(OBJEXT) signals.$(OBJEXT) \ + session.$(OBJEXT) settings.$(OBJEXT) sha1.$(OBJEXT) signals.$(OBJEXT) \ special-vars.$(OBJEXT) write-buffer.$(OBJEXT) libcore_a_OBJECTS = $(am_libcore_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) @@ -290,6 +290,7 @@ servers-setup.c \ session.c \ settings.c \ + sha1.c \ signals.c \ special-vars.c \ write-buffer.c @@ -339,6 +340,7 @@ servers-setup.h \ session.h \ settings.h \ + sha1.h \ signals.h \ special-vars.h \ window-item-def.h \ @@ -426,6 +428,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/servers.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/session.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/settings.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/signals.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/special-vars.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/write-buffer.Po@am__quote@ diff -Nru irssi-0.8.12.orig/src/core/settings.c irssi-0.8.12/src/core/settings.c --- irssi-0.8.12.orig/src/core/settings.c 2008-07-28 18:32:03.000000000 +0100 +++ irssi-0.8.12/src/core/settings.c 2008-07-28 19:15:33.000000000 +0100 @@ -28,6 +28,8 @@ #include "recode.h" #include "settings.h" #include "default-config.h" +#include "sha1.h" +#include "fe-common/core/printtext.h" #include @@ -329,7 +330,24 @@ void settings_set_str(const char *key, const char *value) { - iconfig_node_set_str(settings_get_node(key), key, value); + if (!strcmp(key, "irssiproxy_password") && settings_get_bool("irssiproxy_sha_passwords")) { + SHA1Context sha; + SHA1Reset(&sha); + SHA1Input(&sha, (const unsigned char *) value, strlen(value)); + if (SHA1Result(&sha)) { + char hashed_password[41]; + snprintf(hashed_password, 41, "%08x%08x%08x%08x%08x", + sha.Message_Digest[0], sha.Message_Digest[1], + sha.Message_Digest[2], sha.Message_Digest[3], + sha.Message_Digest[4]); + iconfig_node_set_str(settings_get_node(key), key, hashed_password); + } else { + iconfig_node_set_str(settings_get_node(key), key, value); + printtext(NULL, NULL, MSGLEVEL_CLIENTNOTICE, "SHA1 value could not be computed, plain-text password used."); + } + } else { + iconfig_node_set_str(settings_get_node(key), key, value); + } } void settings_set_int(const char *key, int value) diff -Nru irssi-0.8.12.orig/src/core/sha1.c irssi-0.8.12/src/core/sha1.c --- irssi-0.8.12.orig/src/core/sha1.c 1970-01-01 01:00:00.000000000 +0100 +++ irssi-0.8.12/src/core/sha1.c 2004-03-27 13:00:34.000000000 +0000 @@ -0,0 +1,371 @@ +/* + * sha1.c + * + * Copyright (C) 1998 + * Paul E. Jones + * All Rights Reserved + * + ***************************************************************************** + * $Id: sha1.c,v 1.2 2004/03/27 18:00:33 paulej Exp $ + ***************************************************************************** + * + * Description: + * This file implements the Secure Hashing Standard as defined + * in FIPS PUB 180-1 published April 17, 1995. + * + * The Secure Hashing Standard, which uses the Secure Hashing + * Algorithm (SHA), produces a 160-bit message digest for a + * given data stream. In theory, it is highly improbable that + * two messages will produce the same message digest. Therefore, + * this algorithm can serve as a means of providing a "fingerprint" + * for a message. + * + * Portability Issues: + * SHA-1 is defined in terms of 32-bit "words". This code was + * written with the expectation that the processor has at least + * a 32-bit machine word size. If the machine word size is larger, + * the code should still function properly. One caveat to that + * is that the input functions taking characters and character + * arrays assume that only 8 bits of information are stored in each + * character. + * + * Caveats: + * SHA-1 is designed to work with messages less than 2^64 bits + * long. Although SHA-1 allows a message digest to be generated for + * messages of any number of bits less than 2^64, this + * implementation only works with messages with a length that is a + * multiple of the size of an 8-bit character. + * + */ + +#include "sha1.h" + +/* + * Define the circular shift macro + */ +#define SHA1CircularShift(bits,word) \ + ((((word) << (bits)) & 0xFFFFFFFF) | \ + ((word) >> (32-(bits)))) + +/* Function prototypes */ +void SHA1ProcessMessageBlock(SHA1Context *); +void SHA1PadMessage(SHA1Context *); + +/* + * SHA1Reset + * + * Description: + * This function will initialize the SHA1Context in preparation + * for computing a new message digest. + * + * Parameters: + * context: [in/out] + * The context to reset. + * + * Returns: + * Nothing. + * + * Comments: + * + */ +void SHA1Reset(SHA1Context *context) +{ + context->Length_Low = 0; + context->Length_High = 0; + context->Message_Block_Index = 0; + + context->Message_Digest[0] = 0x67452301; + context->Message_Digest[1] = 0xEFCDAB89; + context->Message_Digest[2] = 0x98BADCFE; + context->Message_Digest[3] = 0x10325476; + context->Message_Digest[4] = 0xC3D2E1F0; + + context->Computed = 0; + context->Corrupted = 0; +} + +/* + * SHA1Result + * + * Description: + * This function will return the 160-bit message digest into the + * Message_Digest array within the SHA1Context provided + * + * Parameters: + * context: [in/out] + * The context to use to calculate the SHA-1 hash. + * + * Returns: + * 1 if successful, 0 if it failed. + * + * Comments: + * + */ +int SHA1Result(SHA1Context *context) +{ + + if (context->Corrupted) + { + return 0; + } + + if (!context->Computed) + { + SHA1PadMessage(context); + context->Computed = 1; + } + + return 1; +} + +/* + * SHA1Input + * + * Description: + * This function accepts an array of octets as the next portion of + * the message. + * + * Parameters: + * context: [in/out] + * The SHA-1 context to update + * message_array: [in] + * An array of characters representing the next portion of the + * message. + * length: [in] + * The length of the message in message_array + * + * Returns: + * Nothing. + * + * Comments: + * + */ +void SHA1Input( SHA1Context *context, + const unsigned char *message_array, + unsigned length) +{ + if (!length) + { + return; + } + + if (context->Computed || context->Corrupted) + { + context->Corrupted = 1; + return; + } + + while(length-- && !context->Corrupted) + { + context->Message_Block[context->Message_Block_Index++] = + (*message_array & 0xFF); + + context->Length_Low += 8; + /* Force it to 32 bits */ + context->Length_Low &= 0xFFFFFFFF; + if (context->Length_Low == 0) + { + context->Length_High++; + /* Force it to 32 bits */ + context->Length_High &= 0xFFFFFFFF; + if (context->Length_High == 0) + { + /* Message is too long */ + context->Corrupted = 1; + } + } + + if (context->Message_Block_Index == 64) + { + SHA1ProcessMessageBlock(context); + } + + message_array++; + } +} + +/* + * SHA1ProcessMessageBlock + * + * Description: + * This function will process the next 512 bits of the message + * stored in the Message_Block array. + * + * Parameters: + * None. + * + * Returns: + * Nothing. + * + * Comments: + * Many of the variable names in the SHAContext, especially the + * single character names, were used because those were the names + * used in the publication. + * + * + */ +void SHA1ProcessMessageBlock(SHA1Context *context) +{ + const unsigned K[] = /* Constants defined in SHA-1 */ + { + 0x5A827999, + 0x6ED9EBA1, + 0x8F1BBCDC, + 0xCA62C1D6 + }; + int t; /* Loop counter */ + unsigned temp; /* Temporary word value */ + unsigned W[80]; /* Word sequence */ + unsigned A, B, C, D, E; /* Word buffers */ + + /* + * Initialize the first 16 words in the array W + */ + for(t = 0; t < 16; t++) + { + W[t] = ((unsigned) context->Message_Block[t * 4]) << 24; + W[t] |= ((unsigned) context->Message_Block[t * 4 + 1]) << 16; + W[t] |= ((unsigned) context->Message_Block[t * 4 + 2]) << 8; + W[t] |= ((unsigned) context->Message_Block[t * 4 + 3]); + } + + for(t = 16; t < 80; t++) + { + W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); + } + + A = context->Message_Digest[0]; + B = context->Message_Digest[1]; + C = context->Message_Digest[2]; + D = context->Message_Digest[3]; + E = context->Message_Digest[4]; + + for(t = 0; t < 20; t++) + { + temp = SHA1CircularShift(5,A) + + ((B & C) | ((~B) & D)) + E + W[t] + K[0]; + temp &= 0xFFFFFFFF; + E = D; + D = C; + C = SHA1CircularShift(30,B); + B = A; + A = temp; + } + + for(t = 20; t < 40; t++) + { + temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1]; + temp &= 0xFFFFFFFF; + E = D; + D = C; + C = SHA1CircularShift(30,B); + B = A; + A = temp; + } + + for(t = 40; t < 60; t++) + { + temp = SHA1CircularShift(5,A) + + ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]; + temp &= 0xFFFFFFFF; + E = D; + D = C; + C = SHA1CircularShift(30,B); + B = A; + A = temp; + } + + for(t = 60; t < 80; t++) + { + temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3]; + temp &= 0xFFFFFFFF; + E = D; + D = C; + C = SHA1CircularShift(30,B); + B = A; + A = temp; + } + + context->Message_Digest[0] = + (context->Message_Digest[0] + A) & 0xFFFFFFFF; + context->Message_Digest[1] = + (context->Message_Digest[1] + B) & 0xFFFFFFFF; + context->Message_Digest[2] = + (context->Message_Digest[2] + C) & 0xFFFFFFFF; + context->Message_Digest[3] = + (context->Message_Digest[3] + D) & 0xFFFFFFFF; + context->Message_Digest[4] = + (context->Message_Digest[4] + E) & 0xFFFFFFFF; + + context->Message_Block_Index = 0; +} + +/* + * SHA1PadMessage + * + * Description: + * According to the standard, the message must be padded to an even + * 512 bits. The first padding bit must be a '1'. The last 64 + * bits represent the length of the original message. All bits in + * between should be 0. This function will pad the message + * according to those rules by filling the Message_Block array + * accordingly. It will also call SHA1ProcessMessageBlock() + * appropriately. When it returns, it can be assumed that the + * message digest has been computed. + * + * Parameters: + * context: [in/out] + * The context to pad + * + * Returns: + * Nothing. + * + * Comments: + * + */ +void SHA1PadMessage(SHA1Context *context) +{ + /* + * Check to see if the current message block is too small to hold + * the initial padding bits and length. If so, we will pad the + * block, process it, and then continue padding into a second + * block. + */ + if (context->Message_Block_Index > 55) + { + context->Message_Block[context->Message_Block_Index++] = 0x80; + while(context->Message_Block_Index < 64) + { + context->Message_Block[context->Message_Block_Index++] = 0; + } + + SHA1ProcessMessageBlock(context); + + while(context->Message_Block_Index < 56) + { + context->Message_Block[context->Message_Block_Index++] = 0; + } + } + else + { + context->Message_Block[context->Message_Block_Index++] = 0x80; + while(context->Message_Block_Index < 56) + { + context->Message_Block[context->Message_Block_Index++] = 0; + } + } + + /* + * Store the message length as the last 8 octets + */ + context->Message_Block[56] = (context->Length_High >> 24) & 0xFF; + context->Message_Block[57] = (context->Length_High >> 16) & 0xFF; + context->Message_Block[58] = (context->Length_High >> 8) & 0xFF; + context->Message_Block[59] = (context->Length_High) & 0xFF; + context->Message_Block[60] = (context->Length_Low >> 24) & 0xFF; + context->Message_Block[61] = (context->Length_Low >> 16) & 0xFF; + context->Message_Block[62] = (context->Length_Low >> 8) & 0xFF; + context->Message_Block[63] = (context->Length_Low) & 0xFF; + + SHA1ProcessMessageBlock(context); +} diff -Nru irssi-0.8.12.orig/src/core/sha1.h irssi-0.8.12/src/core/sha1.h --- irssi-0.8.12.orig/src/core/sha1.h 1970-01-01 01:00:00.000000000 +0100 +++ irssi-0.8.12/src/core/sha1.h 2004-03-27 13:00:34.000000000 +0000 @@ -0,0 +1,54 @@ +/* + * sha1.h + * + * Copyright (C) 1998 + * Paul E. Jones + * All Rights Reserved + * + ***************************************************************************** + * $Id: sha1.h,v 1.2 2004/03/27 18:00:33 paulej Exp $ + ***************************************************************************** + * + * Description: + * This class implements the Secure Hashing Standard as defined + * in FIPS PUB 180-1 published April 17, 1995. + * + * Many of the variable names in the SHA1Context, especially the + * single character names, were used because those were the names + * used in the publication. + * + * Please read the file sha1.c for more information. + * + */ + +#ifndef _SHA1_H_ +#define _SHA1_H_ + +/* + * This structure will hold context information for the hashing + * operation + */ +typedef struct SHA1Context +{ + unsigned Message_Digest[5]; /* Message Digest (output) */ + + unsigned Length_Low; /* Message length in bits */ + unsigned Length_High; /* Message length in bits */ + + unsigned char Message_Block[64]; /* 512-bit message blocks */ + int Message_Block_Index; /* Index into message block array */ + + int Computed; /* Is the digest computed? */ + int Corrupted; /* Is the message digest corruped? */ +} SHA1Context; + +/* + * Function Prototypes + */ +void SHA1Reset(SHA1Context *); +int SHA1Result(SHA1Context *); +void SHA1Input( SHA1Context *, + const unsigned char *, + unsigned); + +#endif diff -Nru irssi-0.8.12.orig/src/irc/proxy/listen.c irssi-0.8.12/src/irc/proxy/listen.c --- irssi-0.8.12.orig/src/irc/proxy/listen.c 2008-07-28 18:32:03.000000000 +0100 +++ irssi-0.8.12/src/irc/proxy/listen.c 2008-07-28 19:15:33.000000000 +0100 @@ -27,6 +27,7 @@ #include "irc.h" #include "irc-channels.h" +#include "sha1.h" #include "fe-common/core/printtext.h" /* FIXME: evil. need to do fe-proxy */ @@ -107,7 +108,24 @@ password = settings_get_str("irssiproxy_password"); if (password != NULL && strcmp(cmd, "PASS") == 0) { - if (strcmp(password, args) == 0) + int pass_comp_ret = -1; + if (!settings_get_bool("irssiproxy_sha_passwords")) + pass_comp_ret = strcmp(password, args); + else { + SHA1Context sha; + SHA1Reset(&sha); + SHA1Input(&sha, (const unsigned char *) args, strlen(args)); + if (SHA1Result(&sha)) { + char hashed_args[41]; + snprintf(hashed_args, 41, "%08x%08x%08x%08x%08x", + sha.Message_Digest[0], sha.Message_Digest[1], + sha.Message_Digest[2], sha.Message_Digest[3], + sha.Message_Digest[4]); + pass_comp_ret = strcasecmp(password, hashed_args); + } + } + + if (pass_comp_ret == 0) client->pass_sent = TRUE; else { /* wrong password! */ diff -Nru irssi-0.8.12.orig/src/irc/proxy/proxy.c irssi-0.8.12/src/irc/proxy/proxy.c --- irssi-0.8.12.orig/src/irc/proxy/proxy.c 2008-07-28 18:32:03.000000000 +0100 +++ irssi-0.8.12/src/irc/proxy/proxy.c 2008-07-28 19:15:33.000000000 +0100 @@ -28,6 +28,7 @@ settings_add_str("irssiproxy", "irssiproxy_ports", ""); settings_add_str("irssiproxy", "irssiproxy_password", ""); settings_add_str("irssiproxy", "irssiproxy_bind", ""); + settings_add_bool("irssiproxy", "irssiproxy_sha_passwords", FALSE); if (*settings_get_str("irssiproxy_password") == '\0') { /* no password - bad idea! */