#include "irc.h"
static char cvsrevision[] = "$Id: encrypt.c 3 2008-02-25 09:49:14Z keaston $";
CVS_REVISION(encrypt_c)
#include "struct.h"
#include "encrypt.h"
#include "vars.h"
#include "ircaux.h"
#include "list.h"
#include "ctcp.h"
#include "output.h"
#include "newio.h"
#define MAIN_SOURCE
#include "modval.h"
static void add_to_crypt (char *, char *);
static int remove_crypt (char *);
static char *do_crypt (char *, char *, int);
#define CRYPT_BUFFER_SIZE (IRCD_BUFFER_SIZE - 50)
typedef struct CryptStru
{
struct CryptStru *next;
char *nick;
char *key;
} Crypt;
static Crypt *crypt_list = NULL;
static void add_to_crypt(char *nick, char *key)
{
Crypt *new;
if ((new = (Crypt *) remove_from_list((List **) &crypt_list, nick)) != NULL)
{
new_free(&(new->nick));
new_free(&(new->key));
new_free((char **)&new);
}
new = (Crypt *) new_malloc(sizeof(Crypt));
malloc_strcpy(&(new->nick), nick);
malloc_strcpy(&(new->key), key);
add_to_list((List **) &crypt_list, (List *) new);
}
static int remove_crypt(char *nick)
{
Crypt *tmp;
if ((tmp = (Crypt *) list_lookup((List **) &crypt_list, nick, !USE_WILDCARDS, REMOVE_FROM_LIST)) != NULL)
{
new_free(&(tmp->nick));
new_free(&(tmp->key));
new_free((char **)&tmp);
return (0);
}
return (1);
}
char * is_crypted(char *nick)
{
Crypt *tmp;
if (!crypt_list)
return NULL;
if ((tmp = (Crypt *) list_lookup((List **) &crypt_list, nick, !USE_WILDCARDS, !REMOVE_FROM_LIST)) != NULL)
return (tmp->key);
return NULL;
}
BUILT_IN_COMMAND(encrypt_cmd)
{
char *nick,
*key;
if ((nick = next_arg(args, &args)) != NULL)
{
if ((key = next_arg(args, &args)) != NULL)
{
add_to_crypt(nick, key);
say("%s added to the crypt with key %s", nick, key);
}
else
{
if (remove_crypt(nick))
say("No such nickname in the crypt: %s", nick);
else
say("%s removed from the crypt", nick);
}
}
else
{
if (crypt_list)
{
Crypt *tmp;
say("The crypt:");
for (tmp = crypt_list; tmp; tmp = tmp->next)
put_it("%s with key %s", tmp->nick, tmp->key);
}
else
say("The crypt is empty");
}
}
extern void BX_my_encrypt (char *str, int len, char *key)
{
int key_len,
key_pos,
i;
char mix,
tmp;
if (!key)
return;
key_len = strlen(key);
key_pos = 0;
mix = 0;
for (i = 0; i < len; i++)
{
tmp = str[i];
str[i] = mix ^ tmp ^ key[key_pos];
mix ^= tmp;
key_pos = (key_pos + 1) % key_len;
}
str[i] = (char) 0;
}
extern void BX_my_decrypt(char *str, int len, char *key)
{
int key_len,
key_pos,
i;
char mix,
tmp;
if (!key)
return;
key_len = strlen(key);
key_pos = 0;
mix = 0;
for (i = 0; i < len; i++)
{
tmp = mix ^ str[i] ^ key[key_pos];
str[i] = tmp;
mix ^= tmp;
key_pos = (key_pos + 1) % key_len;
}
str[i] = (char) 0;
}
static char *do_crypt(char *str, char *key, int flag)
{
int c;
char *ptr = NULL;
c = strlen(str);
if (flag)
{
my_encrypt(str, c, key);
ptr = ctcp_quote_it(str, c);
}
else
{
ptr = ctcp_unquote_it(str, &c);
my_decrypt(ptr, c, key);
}
return (ptr);
}
char *crypt_msg(char *str, char *key)
{
char buffer[CRYPT_BUFFER_SIZE + 1];
char thing[6] = "";
char *ptr;
sprintf(thing, "%cSED ", CTCP_DELIM_CHAR);
*buffer = (char) 0;
if ((ptr = do_crypt(str, key, 1)))
{
strmcat(buffer, thing, CRYPT_BUFFER_SIZE);
strmcat(buffer, ptr, CRYPT_BUFFER_SIZE-1);
strmcat(buffer, CTCP_DELIM_STR, CRYPT_BUFFER_SIZE);
new_free(&ptr);
}
else
strmcat(buffer, str, CRYPT_BUFFER_SIZE);
return (m_strdup(buffer));
}
char *decrypt_msg (char *str, char *key)
{
char *buffer = (char *)new_malloc(BIG_BUFFER_SIZE + 1);
char *ptr;
if ((ptr = do_crypt(str, key, 0)) != NULL)
{
strmcpy(buffer, ptr, CRYPT_BUFFER_SIZE);
new_free(&ptr);
}
else
strmcat(buffer, str, CRYPT_BUFFER_SIZE);
return buffer;
}