diff options
Diffstat (limited to 'crypting.c')
| -rw-r--r-- | crypting.c | 244 | 
1 files changed, 244 insertions, 0 deletions
diff --git a/crypting.c b/crypting.c new file mode 100644 index 00000000..b2e523ff --- /dev/null +++ b/crypting.c @@ -0,0 +1,244 @@ +  /********************************************************************\ +  * BitlBee -- An IRC to other IM-networks gateway                     * +  *                                                                    * +  * Copyright 2002-2004 Sjoerd Hemminga and others                     * +  \********************************************************************/ + +/* A little bit of encryption for the users' passwords                  */ + +/* +  This program is free software; you can redistribute it and/or modify +  it under the terms of the GNU General Public License as published by +  the Free Software Foundation; either version 2 of the License, or +  (at your option) any later version. + +  This program is distributed in the hope that it will be useful, +  but WITHOUT ANY WARRANTY; without even the implied warranty of +  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +  GNU General Public License for more details. + +  You should have received a copy of the GNU General Public License with +  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL; +  if not, write to the Free Software Foundation, Inc., 59 Temple Place, +  Suite 330, Boston, MA  02111-1307  USA +*/ + +/* [WvG] This file can also be compiled into a stand-alone program +   which can encode/decode BitlBee account files. The main() will be +   included if CRYPTING_MAIN is defined. Or just do "make decode" and +   the programs will be built. */ + +#ifndef CRYPTING_MAIN +#define BITLBEE_CORE +#include "bitlbee.h" +#include "irc.h" +#include "md5.h" +#include "crypting.h" +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +#else + +typedef struct irc +{ +	char *password; +} irc_t; + +#define set_add( a, b, c, d ) +#define set_find( a, b ) NULL + +#include "md5.h" +#include "crypting.h" +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +#endif + +/*\ + * [SH] Do _not_ call this if it's not entirely sure that it will not cause + * harm to another users file, since this does not check the password for + * correctness. +\*/ + +/* USE WITH CAUTION! +   Sets pass without checking */ +void setpassnc (irc_t *irc, char *pass) { +	if (!set_find (irc, "password")) +		set_add (irc, "password", NULL, passchange); +	 +	if (irc->password) g_free (irc->password); +	 +	if (pass) { +		irc->password = g_strdup (pass); +		irc_usermsg (irc, "Password successfully changed"); +	} else { +		irc->password = NULL; +	} +} + +char *passchange (irc_t *irc, void *set, char *value) { +	setpassnc (irc, value); +	return (NULL); +} + +int setpass (irc_t *irc, char *pass, char* md5sum) { +	md5_state_t md5state; +	md5_byte_t digest[16]; +	int i, j; +	char digits[3]; +	 +	md5_init (&md5state); +	md5_append (&md5state, (unsigned char *)pass, strlen (pass)); +	md5_finish (&md5state, digest); +	 +	for (i = 0, j = 0; i < 16; i++, j += 2) { +		/* Check password for correctness */ +		g_snprintf (digits, sizeof (digits), "%02x\n", digest[i]); +		 +		if (digits[0] != md5sum[j]) return (-1); +		if (digits[1] != md5sum[j + 1]) return (-1); +	} +	 +	/* If pass is correct, we end up here and we set the pass */ +	setpassnc (irc, pass); +	 +	return (0); +} + +char *hashpass (irc_t *irc) { +	md5_state_t md5state; +	md5_byte_t digest[16]; +	int i; +	char digits[3]; +	char *rv; +	 +	if (irc->password == NULL) return (NULL); +	 +	rv = (char *)g_malloc (33); +	memset (rv, 0, 33); +	 +	md5_init (&md5state); +	md5_append (&md5state, (unsigned char *)irc->password, strlen (irc->password)); +	md5_finish (&md5state, digest); +	 +	for (i = 0; i < 16; i++) { +		/* Build a hash of the pass */ +		g_snprintf (digits, sizeof (digits), "%02x", digest[i]); +		strcat (rv, digits); +	} +	 +	return (rv); +} + +char *obfucrypt (irc_t *irc, char *line) { +	int i, j; +	char *rv; +	 +	if (irc->password == NULL) return (NULL); +	 +	rv = (char *)g_malloc (strlen (line) + 1); +	memset (rv, '\0', strlen (line) + 1); +	 +	i = j = 0; +	while (*line) { +		/* Encrypt/obfuscate the line, using the password */ +		if (*(signed char*)line < 0) *line = - (*line); +		if (((signed char*)irc->password)[i] < 0) irc->password[i] = - irc->password[i]; +		 +		rv[j] = *line + irc->password[i]; /* Overflow intended */ +		 +		line++; +		if (!irc->password[++i]) i = 0; +		j++; +	} +	 +	return (rv); +} + +char *deobfucrypt (irc_t *irc, char *line) { +	int i, j; +	char *rv; +	 +	if (irc->password == NULL) return (NULL); +	 +	rv = (char *)g_malloc (strlen (line) + 1); +	memset (rv, '\0', strlen (line) + 1); +	 +	i = j = 0; +	while (*line) { +		/* Decrypt/deobfuscate the line, using the pass */ +		rv[j] = *line - irc->password[i]; /* Overflow intended */ +		 +		line++; +		if (!irc->password[++i]) i = 0; +		j++; +	} +	 +	return (rv); +} + +#ifdef CRYPTING_MAIN + +/* A little main() function for people who want a stand-alone program to +   encode/decode BitlCrypted files. */ + +int main( int argc, char *argv[] ) +{ +	irc_t *irc = g_malloc( sizeof( irc_t ) ); +	char *hash, *action, line[256]; +	char* (*func)( irc_t *, char * ); +	 +	if( argc < 2 ) +	{ +		fprintf( stderr, "Usage: %s <password>\n\n" +		                 "Reads from stdin, writes to stdout.\n" +		                 "Call as \"encode\" to encode, \"decode\" to decode.\n", argv[0] ); +		return( 1 ); +	} +	 +	memset( irc, 0, sizeof( irc_t ) ); +	irc->password = g_strdup( argv[1] ); +	 +	hash = hashpass( irc ); +	action = argv[0] + strlen( argv[0] ) - strlen( "encode" ); +	 +	if( strcmp( action, "encode" ) == 0 ) +	{ +		fwrite( hash, 32, 1, stdout ); +		func = obfucrypt; +	} +	else if( strcmp( action, "decode" ) == 0 ) +	{ +		char hash2[32]; +		 +		fread( hash2, 32, 1, stdin ); +		if( memcmp( hash, hash2, 32 ) != 0 ) +		{ +			fprintf( stderr, "Passwords don't match. Can't decode.\n" ); +			return( 1 ); +		} +		func = deobfucrypt; +	} +	else +	{ +		return( main( 0, NULL ) ); +	} +	 +	while( fscanf( stdin, "%[^\n]255s", line ) > 0 ) +	{ +		char *out; +		 +		/* Flush the newline */ +		fgetc( stdin ); +		 +		out = func( irc, line ); +		printf( "%s\n", out ); +		g_free( out ); +	} +	 +	return( 0 ); +} + +#endif  | 
