ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/servlink/control.c
Revision: 33
Committed: Sun Oct 2 20:50:00 2005 UTC (18 years, 6 months ago) by knight
Content type: text/x-csrc
File size: 12273 byte(s)
Log Message:
- svn:keywords

File Contents

# Content
1 /************************************************************************
2 * IRC - Internet Relay Chat, servlink/servlink.c
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 1, or (at your option)
7 * any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 *
18 * $Id$
19 */
20
21 #include "stdinc.h"
22
23 #ifdef HAVE_LIBCRYPTO
24 #include <openssl/evp.h>
25 #include <openssl/err.h>
26 #endif
27 #ifdef HAVE_LIBZ
28 #include <zlib.h>
29 #endif
30
31 #include "servlink.h"
32 #include "io.h"
33 #include "control.h"
34
35 static cmd_handler cmd_set_zip_out_level;
36 static cmd_handler cmd_start_zip_out;
37 static cmd_handler cmd_start_zip_in;
38 static cmd_handler cmd_set_crypt_in_cipher;
39 static cmd_handler cmd_set_crypt_in_key;
40 static cmd_handler cmd_start_crypt_in;
41 static cmd_handler cmd_set_crypt_out_cipher;
42 static cmd_handler cmd_set_crypt_out_key;
43 static cmd_handler cmd_start_crypt_out;
44 static cmd_handler cmd_init;
45
46 struct command_def command_table[] =
47 {
48 { CMD_SET_ZIP_OUT_LEVEL, cmd_set_zip_out_level, COMMAND_FLAG_DATA },
49 { CMD_START_ZIP_OUT, cmd_start_zip_out, 0 },
50 { CMD_START_ZIP_IN, cmd_start_zip_in, 0 },
51 { CMD_SET_CRYPT_IN_CIPHER, cmd_set_crypt_in_cipher, COMMAND_FLAG_DATA },
52 { CMD_SET_CRYPT_IN_KEY, cmd_set_crypt_in_key, COMMAND_FLAG_DATA },
53 { CMD_START_CRYPT_IN, cmd_start_crypt_in, 0 },
54 { CMD_SET_CRYPT_OUT_CIPHER, cmd_set_crypt_out_cipher, COMMAND_FLAG_DATA },
55 { CMD_SET_CRYPT_OUT_KEY, cmd_set_crypt_out_key, COMMAND_FLAG_DATA },
56 { CMD_START_CRYPT_OUT, cmd_start_crypt_out, 0 },
57 { CMD_INJECT_RECVQ, process_recvq, COMMAND_FLAG_DATA },
58 { CMD_INJECT_SENDQ, process_sendq, COMMAND_FLAG_DATA },
59 { CMD_INIT, cmd_init, 0 },
60 { CMD_ZIPSTATS, send_zipstats, 0 },
61 { 0, 0, 0 }
62 };
63
64 void
65 cmd_set_zip_out_level(struct ctrl_command *cmd)
66 {
67 #ifdef HAVE_LIBZ
68 out_state.zip_state.level = *cmd->data;
69 if ((out_state.zip_state.level < -1) ||
70 (out_state.zip_state.level > 9))
71 send_error("invalid compression level %d",
72 out_state.zip_state.level);
73 #else
74 send_error("can't set compression level - no libz support!");
75 #endif
76 }
77
78 void
79 cmd_start_zip_out(struct ctrl_command *cmd)
80 {
81 #ifdef HAVE_LIBZ
82 int ret;
83
84 if (out_state.zip)
85 send_error("can't start compression - already started!");
86
87 out_state.zip_state.stream.total_in = 0;
88 out_state.zip_state.stream.total_out = 0;
89 out_state.zip_state.stream.zalloc = (alloc_func)0;
90 out_state.zip_state.stream.zfree = (free_func)0;
91 out_state.zip_state.stream.data_type = Z_ASCII;
92
93 if (out_state.zip_state.level <= 0)
94 out_state.zip_state.level = Z_DEFAULT_COMPRESSION;
95
96 if ((ret = deflateInit(&out_state.zip_state.stream,
97 out_state.zip_state.level)) != Z_OK)
98 send_error("deflateInit failed: %d (%s)", ret, zError(ret));
99
100 out_state.zip = 1;
101 #else
102 send_error("can't start compression - no libz support!");
103 #endif
104 }
105
106 void
107 cmd_start_zip_in(struct ctrl_command *cmd)
108 {
109 #ifdef HAVE_LIBZ
110 int ret;
111
112 if (in_state.zip)
113 send_error("can't start decompression - already started!");
114
115 in_state.zip_state.stream.total_in = 0;
116 in_state.zip_state.stream.total_out = 0;
117 in_state.zip_state.stream.zalloc = (alloc_func)0;
118 in_state.zip_state.stream.zfree = (free_func)0;
119 in_state.zip_state.stream.data_type = Z_ASCII;
120 if ((ret = inflateInit(&in_state.zip_state.stream)) != Z_OK)
121 send_error("inflateInit failed: %d (%s)", ret, zError(ret));
122 in_state.zip = 1;
123 #else
124 send_error("can't start decompression - no libz support!");
125 #endif
126 }
127
128 void
129 cmd_set_crypt_in_cipher(struct ctrl_command *cmd)
130 {
131 #ifdef HAVE_LIBCRYPTO
132 unsigned int cipher = *cmd->data;
133
134 if (in_state.crypt_state.cipher)
135 send_error("can't set decryption cipher - already set!");
136
137 switch (cipher)
138 {
139 #ifdef HAVE_EVP_BF_CFB
140 case CIPHER_BF:
141 in_state.crypt_state.cipher = EVP_bf_cfb();
142 break;
143 #endif
144 #ifdef HAVE_EVP_CAST5_CFB
145 case CIPHER_CAST:
146 in_state.crypt_state.cipher = EVP_cast5_cfb();
147 break;
148 #endif
149 #ifdef HAVE_EVP_DES_CFB
150 case CIPHER_DES:
151 in_state.crypt_state.cipher = EVP_des_cfb();
152 break;
153 #endif
154 #ifdef HAVE_EVP_DES_EDE3_CFB
155 case CIPHER_3DES:
156 in_state.crypt_state.cipher = EVP_des_ede3_cfb();
157 break;
158 #endif
159 #ifdef HAVE_EVP_IDEA_CFB
160 case CIPHER_IDEA:
161 in_state.crypt_state.cipher = EVP_idea_cfb();
162 break;
163 #endif
164 #ifdef HAVE_EVP_RC5_32_12_16_CFB
165 case CIPHER_RC5_8:
166 in_state.crypt_state.cipher = EVP_rc5_32_12_16_cfb();
167 in_state.crypt_state.rounds = 8;
168 break;
169 case CIPHER_RC5_12:
170 in_state.crypt_state.cipher = EVP_rc5_32_12_16_cfb();
171 in_state.crypt_state.rounds = 12;
172 break;
173 case CIPHER_RC5_16:
174 in_state.crypt_state.cipher = EVP_rc5_32_12_16_cfb();
175 in_state.crypt_state.rounds = 16;
176 break;
177 #endif
178 default:
179 send_error("can't set decryption cipher - invalid cipher: %d!",
180 cipher); /* invalid cipher */
181 break;
182 }
183 #else
184 send_error("can't set decryption cipher - no OpenSSL support!");
185 #endif
186 }
187
188 void
189 cmd_set_crypt_in_key(struct ctrl_command *cmd)
190 {
191 #ifdef HAVE_LIBCRYPTO
192 if (in_state.crypt_state.key)
193 send_error("can't set decryption key - already set!");
194
195 in_state.crypt_state.keylen = cmd->datalen;
196 in_state.crypt_state.key = malloc(cmd->datalen);
197
198 memcpy(in_state.crypt_state.key, cmd->data, cmd->datalen);
199 #else
200 send_error("can't set decryption key - no OpenSSL support!");
201 #endif
202 }
203
204 void
205 cmd_start_crypt_in(struct ctrl_command *cmd)
206 {
207 #ifdef HAVE_LIBCRYPTO
208 if (in_state.crypt)
209 send_error("can't start decryption - already started!");
210
211 if (!in_state.crypt_state.cipher)
212 send_error("can't start decryption - no cipher set!");
213
214 if (!in_state.crypt_state.key)
215 send_error("can't start decryption - no key set!");
216
217 in_state.crypt = 1;
218 if (!EVP_DecryptInit(&in_state.crypt_state.ctx,
219 in_state.crypt_state.cipher, NULL, NULL))
220 send_error("can't start decryption - DecryptInit (1) failed: %s!",
221 ERR_error_string(ERR_get_error(), NULL));
222
223 if (!EVP_CIPHER_CTX_set_key_length(&in_state.crypt_state.ctx,
224 in_state.crypt_state.keylen))
225 send_error("can't start decryption - set_key_length failed: %s!",
226 ERR_error_string(ERR_get_error(), NULL));
227
228 in_state.crypt_state.ivlen =
229 EVP_CIPHER_CTX_iv_length(&in_state.crypt_state.ctx);
230
231 if (in_state.crypt_state.ivlen)
232 in_state.crypt_state.iv = calloc(in_state.crypt_state.ivlen, 1);
233
234 if (in_state.crypt_state.rounds)
235 {
236 if (!EVP_CIPHER_CTX_ctrl(&in_state.crypt_state.ctx,
237 EVP_CTRL_SET_RC5_ROUNDS,
238 in_state.crypt_state.rounds,
239 NULL))
240 send_error("can't start decryption - SET_RC5_ROUNDS failed: %s!",
241 ERR_error_string(ERR_get_error(), NULL));
242 }
243
244 if (!EVP_DecryptInit(&in_state.crypt_state.ctx,
245 NULL,
246 in_state.crypt_state.key,
247 in_state.crypt_state.iv))
248 send_error("can't start decryption - DecryptInit (2) failed: %s!",
249 ERR_error_string(ERR_get_error(), NULL));
250 #else
251 send_error("can't start decryption - no OpenSSL support!");
252 #endif
253 }
254
255 void
256 cmd_set_crypt_out_cipher(struct ctrl_command *cmd)
257 {
258 #ifdef HAVE_LIBCRYPTO
259 unsigned int cipher = *cmd->data;
260
261 if (out_state.crypt_state.cipher)
262 send_error("can't set encryption cipher - already set!");
263
264 switch (cipher)
265 {
266 #ifdef HAVE_EVP_BF_CFB
267 case CIPHER_BF:
268 out_state.crypt_state.cipher = EVP_bf_cfb();
269 break;
270 #endif
271 #ifdef HAVE_EVP_CAST5_CFB
272 case CIPHER_CAST:
273 out_state.crypt_state.cipher = EVP_cast5_cfb();
274 break;
275 #endif
276 #ifdef HAVE_EVP_DES_CFB
277 case CIPHER_DES:
278 out_state.crypt_state.cipher = EVP_des_cfb();
279 break;
280 #endif
281 #ifdef HAVE_EVP_DES_EDE3_CFB
282 case CIPHER_3DES:
283 out_state.crypt_state.cipher = EVP_des_ede3_cfb();
284 break;
285 #endif
286 #ifdef HAVE_EVP_IDEA_CFB
287 case CIPHER_IDEA:
288 out_state.crypt_state.cipher = EVP_idea_cfb();
289 break;
290 #endif
291 #ifdef HAVE_EVP_RC5_32_12_16_CFB
292 case CIPHER_RC5_8:
293 out_state.crypt_state.cipher = EVP_rc5_32_12_16_cfb();
294 out_state.crypt_state.rounds = 8;
295 break;
296 case CIPHER_RC5_12:
297 out_state.crypt_state.cipher = EVP_rc5_32_12_16_cfb();
298 out_state.crypt_state.rounds = 12;
299 break;
300 case CIPHER_RC5_16:
301 out_state.crypt_state.cipher = EVP_rc5_32_12_16_cfb();
302 out_state.crypt_state.rounds = 16;
303 break;
304 #endif
305 default:
306 send_error("can't set encryption cipher - invalid cipher %d!",
307 cipher); /* invalid cipher */
308 }
309 #else
310 send_error("can't set encryption cipher - no OpenSSL support!");
311 #endif
312 }
313
314 void
315 cmd_set_crypt_out_key(struct ctrl_command *cmd)
316 {
317 #ifdef HAVE_LIBCRYPTO
318 if (out_state.crypt_state.key)
319 send_error("can't set encryption key - already set!");
320
321 out_state.crypt_state.keylen = cmd->datalen;
322 out_state.crypt_state.key = malloc(cmd->datalen);
323
324 memcpy(out_state.crypt_state.key, cmd->data, cmd->datalen);
325 #else
326 send_error("can't set encryption key - no OpenSSL support!");
327 #endif
328 }
329
330 void
331 cmd_start_crypt_out(struct ctrl_command *cmd)
332 {
333 #ifdef HAVE_LIBCRYPTO
334 if (out_state.crypt)
335 send_error("can't start encryption - already started!");
336
337 if (!out_state.crypt_state.cipher)
338 send_error("can't start encryption - no cipher set!");
339
340 if (!out_state.crypt_state.key)
341 send_error("can't start encryption - no key set!");
342
343 out_state.crypt = 1;
344 if (!EVP_EncryptInit(&out_state.crypt_state.ctx,
345 out_state.crypt_state.cipher, NULL, NULL))
346 send_error("can't start encryption - EncryptInit (1) failed: %s!",
347 ERR_error_string(ERR_get_error(), NULL));
348
349 if (!EVP_CIPHER_CTX_set_key_length(&out_state.crypt_state.ctx,
350 out_state.crypt_state.keylen))
351 send_error("can't start encryption - set_key_length failed: %s!",
352 ERR_error_string(ERR_get_error(), NULL));
353
354 out_state.crypt_state.ivlen =
355 EVP_CIPHER_CTX_iv_length(&out_state.crypt_state.ctx);
356
357 if (out_state.crypt_state.ivlen)
358 out_state.crypt_state.iv = calloc(out_state.crypt_state.ivlen, 1);
359
360 if (out_state.crypt_state.rounds)
361 {
362 if (!EVP_CIPHER_CTX_ctrl(&out_state.crypt_state.ctx,
363 EVP_CTRL_SET_RC5_ROUNDS,
364 out_state.crypt_state.rounds, NULL))
365 send_error("can't start encryption - SET_RC5_ROUNDS failed: %s!",
366 ERR_error_string(ERR_get_error(), NULL));
367 }
368
369 if (!EVP_EncryptInit(&out_state.crypt_state.ctx,
370 NULL,
371 out_state.crypt_state.key,
372 out_state.crypt_state.iv))
373 send_error("can't start encryption - EncryptInit (2) failed: %s!",
374 ERR_error_string(ERR_get_error(), NULL));
375 #else
376 send_error("can't start encryption - no OpenSSL suppport!");
377 #endif
378 }
379
380 void
381 cmd_init(struct ctrl_command *cmd)
382 {
383 if (in_state.active || out_state.active)
384 send_error("CMD_INIT sent twice!");
385
386 in_state.active = 1;
387 out_state.active = 1;
388 CONTROL_R.read_cb = read_ctrl;
389 CONTROL_W.write_cb = NULL;
390 LOCAL_R.read_cb = read_data;
391 LOCAL_W.write_cb = NULL;
392 REMOTE_R.read_cb = read_net;
393 REMOTE_W.write_cb = NULL;
394 }

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision