Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
BitchX
GitHub Repository: BitchX/BitchX1.3
Path: blob/master/source/encrypt.c
1069 views
1
/*
2
* crypt.c: handles some encryption of messages stuff.
3
*
4
* Written By Michael Sandrof
5
*
6
* Copyright(c) 1990
7
*
8
* See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT
9
*/
10
11
12
#include "irc.h"
13
static char cvsrevision[] = "$Id: encrypt.c 3 2008-02-25 09:49:14Z keaston $";
14
CVS_REVISION(encrypt_c)
15
#include "struct.h"
16
17
#include "encrypt.h"
18
#include "vars.h"
19
#include "ircaux.h"
20
#include "list.h"
21
#include "ctcp.h"
22
#include "output.h"
23
#include "newio.h"
24
#define MAIN_SOURCE
25
#include "modval.h"
26
27
static void add_to_crypt (char *, char *);
28
static int remove_crypt (char *);
29
static char *do_crypt (char *, char *, int);
30
31
#define CRYPT_BUFFER_SIZE (IRCD_BUFFER_SIZE - 50) /* Make this less than
32
* the trasmittable
33
* buffer */
34
/*
35
* Crypt: the crypt list structure, consists of the nickname, and the
36
* encryption key
37
*/
38
typedef struct CryptStru
39
{
40
struct CryptStru *next;
41
char *nick;
42
char *key;
43
} Crypt;
44
45
/* crypt_list: the list of nicknames and encryption keys */
46
static Crypt *crypt_list = NULL;
47
48
/*
49
* add_to_crypt: adds the nickname and key pair to the crypt_list. If the
50
* nickname is already in the list, then the key is changed the the supplied
51
* key.
52
*/
53
static void add_to_crypt(char *nick, char *key)
54
{
55
Crypt *new;
56
57
if ((new = (Crypt *) remove_from_list((List **) &crypt_list, nick)) != NULL)
58
{
59
new_free(&(new->nick));
60
new_free(&(new->key));
61
new_free((char **)&new);
62
}
63
new = (Crypt *) new_malloc(sizeof(Crypt));
64
malloc_strcpy(&(new->nick), nick);
65
malloc_strcpy(&(new->key), key);
66
add_to_list((List **) &crypt_list, (List *) new);
67
}
68
69
/*
70
* remove_crypt: removes the given nickname from the crypt_list, returning 0
71
* if successful, and 1 if not (because the nickname wasn't in the list)
72
*/
73
static int remove_crypt(char *nick)
74
{
75
Crypt *tmp;
76
77
if ((tmp = (Crypt *) list_lookup((List **) &crypt_list, nick, !USE_WILDCARDS, REMOVE_FROM_LIST)) != NULL)
78
{
79
new_free(&(tmp->nick));
80
new_free(&(tmp->key));
81
new_free((char **)&tmp);
82
return (0);
83
}
84
return (1);
85
}
86
87
/*
88
* is_crypted: looks up nick in the crypt_list and returns the encryption key
89
* if found in the list. If not found in the crypt_list, null is returned.
90
*/
91
char * is_crypted(char *nick)
92
{
93
Crypt *tmp;
94
95
if (!crypt_list)
96
return NULL;
97
if ((tmp = (Crypt *) list_lookup((List **) &crypt_list, nick, !USE_WILDCARDS, !REMOVE_FROM_LIST)) != NULL)
98
return (tmp->key);
99
return NULL;
100
}
101
102
/*
103
* encrypt_cmd: the ENCRYPT command. Adds the given nickname and key to the
104
* encrypt list, or removes it, or list the list, you know.
105
*/
106
BUILT_IN_COMMAND(encrypt_cmd)
107
{
108
char *nick,
109
*key;
110
111
if ((nick = next_arg(args, &args)) != NULL)
112
{
113
if ((key = next_arg(args, &args)) != NULL)
114
{
115
add_to_crypt(nick, key);
116
say("%s added to the crypt with key %s", nick, key);
117
}
118
else
119
{
120
if (remove_crypt(nick))
121
say("No such nickname in the crypt: %s", nick);
122
else
123
say("%s removed from the crypt", nick);
124
}
125
}
126
else
127
{
128
if (crypt_list)
129
{
130
Crypt *tmp;
131
132
say("The crypt:");
133
for (tmp = crypt_list; tmp; tmp = tmp->next)
134
put_it("%s with key %s", tmp->nick, tmp->key);
135
}
136
else
137
say("The crypt is empty");
138
}
139
}
140
141
extern void BX_my_encrypt (char *str, int len, char *key)
142
{
143
int key_len,
144
key_pos,
145
i;
146
char mix,
147
tmp;
148
149
if (!key)
150
return;
151
152
key_len = strlen(key);
153
key_pos = 0;
154
mix = 0;
155
for (i = 0; i < len; i++)
156
{
157
tmp = str[i];
158
str[i] = mix ^ tmp ^ key[key_pos];
159
mix ^= tmp;
160
key_pos = (key_pos + 1) % key_len;
161
}
162
str[i] = (char) 0;
163
}
164
165
extern void BX_my_decrypt(char *str, int len, char *key)
166
{
167
int key_len,
168
key_pos,
169
i;
170
char mix,
171
tmp;
172
173
if (!key)
174
return;
175
176
key_len = strlen(key);
177
key_pos = 0;
178
/* mix = key[key_len-1]; */
179
mix = 0;
180
for (i = 0; i < len; i++)
181
{
182
tmp = mix ^ str[i] ^ key[key_pos];
183
str[i] = tmp;
184
mix ^= tmp;
185
key_pos = (key_pos + 1) % key_len;
186
}
187
str[i] = (char) 0;
188
}
189
190
static char *do_crypt(char *str, char *key, int flag)
191
{
192
int c;
193
char *ptr = NULL;
194
195
c = strlen(str);
196
if (flag)
197
{
198
my_encrypt(str, c, key);
199
ptr = ctcp_quote_it(str, c);
200
}
201
else
202
{
203
ptr = ctcp_unquote_it(str, &c);
204
my_decrypt(ptr, c, key);
205
}
206
return (ptr);
207
}
208
209
/*
210
* crypt_msg: Executes the encryption program on the given string with the
211
* given key. If flag is true, the string is encrypted and the returned
212
* string is ready to be sent over irc. If flag is false, the string is
213
* decrypted and the returned string should be readable
214
*/
215
char *crypt_msg(char *str, char *key)
216
{
217
char buffer[CRYPT_BUFFER_SIZE + 1];
218
char thing[6] = "";
219
char *ptr;
220
221
sprintf(thing, "%cSED ", CTCP_DELIM_CHAR);
222
*buffer = (char) 0;
223
if ((ptr = do_crypt(str, key, 1)))
224
{
225
strmcat(buffer, thing, CRYPT_BUFFER_SIZE);
226
strmcat(buffer, ptr, CRYPT_BUFFER_SIZE-1);
227
strmcat(buffer, CTCP_DELIM_STR, CRYPT_BUFFER_SIZE);
228
new_free(&ptr);
229
}
230
else
231
strmcat(buffer, str, CRYPT_BUFFER_SIZE);
232
233
return (m_strdup(buffer));
234
}
235
236
/*
237
* Given a CTCP SED argument 'str', it attempts to unscramble the text
238
* into something more sane. If the 'key' is not the one used to scramble
239
* the text, the results are unpredictable. This is probably the point.
240
*
241
* Note that the retval MUST be at least 'BIG_BUFFER_SIZE + 1'. This is
242
* not an oversight -- the retval is passed is to do_ctcp() which requires
243
* a big buffer to scratch around (The decrypted text could be a CTCP UTC
244
* which could expand to a larger string of text.)
245
*/
246
char *decrypt_msg (char *str, char *key)
247
{
248
char *buffer = (char *)new_malloc(BIG_BUFFER_SIZE + 1);
249
char *ptr;
250
251
if ((ptr = do_crypt(str, key, 0)) != NULL)
252
{
253
strmcpy(buffer, ptr, CRYPT_BUFFER_SIZE);
254
new_free(&ptr);
255
}
256
else
257
strmcat(buffer, str, CRYPT_BUFFER_SIZE);
258
259
return buffer;
260
}
261
262