1 /*
2
3 serverconfig.c
4
5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
6
7 Copyright (C) 1997 - 2001 Pekka Riikonen
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 */
20 /* $Id: clientconfig.c,v 1.11 2001/05/01 16:25:14 priikone Exp $ */
21
22 #include "clientincludes.h"
23 #include "clientconfig.h"
24
25 /*
26 All possible configuration sections for SILC client.
27 */
28 SilcClientConfigSection silc_client_config_sections[] = {
29 { "[cipher]",
30 SILC_CLIENT_CONFIG_SECTION_TYPE_CIPHER, 4 },
31 { "[pkcs]",
32 SILC_CLIENT_CONFIG_SECTION_TYPE_PKCS, 1 },
33 { "[hash]",
34 SILC_CLIENT_CONFIG_SECTION_TYPE_HASH_FUNCTION, 4 },
35 { "[hmac]",
36 SILC_CLIENT_CONFIG_SECTION_TYPE_HMAC, 3 },
37 { "[connection]",
38 SILC_CLIENT_CONFIG_SECTION_TYPE_CONNECTION, 4 },
39 { "[commands]",
40 SILC_CLIENT_CONFIG_SECTION_TYPE_COMMAND, 0 },
41
42 { NULL, SILC_CLIENT_CONFIG_SECTION_TYPE_NONE, 0 }
43 };
44
45 /* Allocates a new configuration object, opens configuration file and
46 parses the file. The parsed data is returned to the newly allocated
47 configuration object. */
48
49 SilcClientConfig silc_client_config_alloc(char *filename)
50 {
51 SilcClientConfig new;
52 SilcBuffer buffer;
53 SilcClientConfigParse config_parse;
54
55 SILC_LOG_DEBUG(("Allocating new configuration object"));
56
57 new = silc_calloc(1, sizeof(*new));
58 new->filename = filename;
59
60 /* Open configuration file and parse it */
61 config_parse = NULL;
62 buffer = NULL;
63 silc_config_open(filename, &buffer);
64 if (!buffer)
65 goto fail;
66 if ((silc_client_config_parse(new, buffer, &config_parse)) == FALSE)
67 goto fail;
68 if ((silc_client_config_parse_lines(new, config_parse)) == FALSE)
69 goto fail;
70
71 silc_free(buffer);
72
73 return new;
74
75 fail:
76 silc_free(new);
77 return NULL;
78 }
79
80 /* Free's a configuration object. */
81
82 void silc_client_config_free(SilcClientConfig config)
83 {
84 if (config) {
85
86 silc_free(config);
87 }
88 }
89
90 /* Parses the the buffer and returns the parsed lines into return_config
91 argument. The return_config argument doesn't have to be initialized
92 before calling this. It will be initialized during the parsing. The
93 buffer sent as argument can be safely free'd after this function has
94 succesfully returned. */
95
96 int silc_client_config_parse(SilcClientConfig config, SilcBuffer buffer,
97 SilcClientConfigParse *return_config)
98 {
99 int i, begin;
100 int linenum;
101 char line[1024], *cp;
102 SilcClientConfigSection *cptr = NULL;
103 SilcClientConfigParse parse = *return_config, first = NULL;
104
105 SILC_LOG_DEBUG(("Parsing configuration file"));
106
107 begin = 0;
108 linenum = 0;
109 while((begin = silc_gets(line, sizeof(line),
110 buffer->data, buffer->len, begin)) != EOF) {
111 cp = line;
112 linenum++;
113
114 /* Check for bad line */
115 if (silc_check_line(cp))
116 continue;
117
118 /* Remove tabs and whitespaces from the line */
119 if (strchr(cp, '\t')) {
120 i = 0;
121 while(strchr(cp + i, '\t')) {
122 *strchr(cp + i, '\t') = ' ';
123 i++;
124 }
125 }
126 for (i = 0; i < strlen(cp); i++) {
127 if (cp[i] != ' ') {
128 if (i)
129 cp++;
130 break;
131 }
132 cp++;
133 }
134
135 /* Parse line */
136 switch(cp[0]) {
137 case '[':
138 /*
139 * Start of a section
140 */
141
142 /* Remove new line sign */
143 if (strchr(cp, '\n'))
144 *strchr(cp, '\n') = '\0';
145
146 /* Check for matching sections */
147 for (cptr = silc_client_config_sections; cptr->section; cptr++)
148 if (!strncasecmp(cp, cptr->section, strlen(cptr->section)))
149 break;
150
151 if (!cptr->section) {
152 fprintf(stderr, "%s:%d: Unknown section `%s'\n",
153 config->filename, linenum, cp);
154 return FALSE;
155 }
156
157 break;
158 default:
159 /*
160 * Start of a configuration line
161 */
162
163 /* Handle config section */
164 if (cptr->type != SILC_CLIENT_CONFIG_SECTION_TYPE_NONE) {
165
166 if (strchr(cp, '\n'))
167 *strchr(cp, '\n') = ':';
168
169 if (parse == NULL) {
170 parse = silc_calloc(1, sizeof(*parse));
171 parse->line = NULL;
172 parse->section = NULL;
173 parse->next = NULL;
174 parse->prev = NULL;
175 } else {
176 if (parse->next == NULL) {
177 parse->next = silc_calloc(1, sizeof(*parse->next));
178 parse->next->line = NULL;
179 parse->next->section = NULL;
180 parse->next->next = NULL;
181 parse->next->prev = parse;
182 parse = parse->next;
183 }
184 }
185
186 if (first == NULL)
187 first = parse;
188
189 /* Add the line to parsing structure for further parsing. */
190 if (parse) {
191 parse->section = cptr;
192 parse->line = silc_buffer_alloc(strlen(cp) + 1);
193 parse->linenum = linenum;
194 silc_buffer_pull_tail(parse->line, strlen(cp));
195 silc_buffer_put(parse->line, cp, strlen(cp));
196 }
197 }
198 break;
199 }
200 }
201
202 /* Set the return_config argument to its first value so that further
203 parsing can be started from the first line. */
204 *return_config = first;
205
206 return TRUE;
207 }
208
209 /* Parses the lines earlier read from configuration file. The config object
210 must not be initialized, it will be initialized in this function. The
211 parse_config argument is uninitialized automatically during this
212 function. */
213
214 int silc_client_config_parse_lines(SilcClientConfig config,
215 SilcClientConfigParse parse_config)
216 {
217 int ret, check = FALSE;
218 char *tmp;
219 SilcClientConfigParse pc = parse_config;
220 SilcBuffer line;
221
222 SILC_LOG_DEBUG(("Parsing configuration lines"));
223
224 if (!config)
225 return FALSE;
226
227 while(pc) {
228 check = FALSE;
229 line = pc->line;
230
231 /* Get number of tokens in line (command section is handeled
232 specially and has no tokens at all). */
233 ret = silc_config_check_num_token(line);
234 if (ret != pc->section->maxfields &&
235 pc->section->type != SILC_CLIENT_CONFIG_SECTION_TYPE_COMMAND) {
236 /* Bad line */
237 fprintf(stderr, "%s:%d: Missing tokens, %d tokens (should be %d)\n",
238 config->filename, pc->linenum, ret,
239 pc->section->maxfields);
240 break;
241 }
242
243 /* Parse the line */
244 switch(pc->section->type) {
245 case SILC_CLIENT_CONFIG_SECTION_TYPE_CIPHER:
246
247 if (!config->cipher) {
248 config->cipher = silc_calloc(1, sizeof(*config->cipher));
249 config->cipher->next = NULL;
250 config->cipher->prev = NULL;
251 } else {
252 if (!config->cipher->next) {
253 config->cipher->next =
254 silc_calloc(1, sizeof(*config->cipher->next));
255 config->cipher->next->next = NULL;
256 config->cipher->next->prev = config->cipher;
257 config->cipher = config->cipher->next;
258 }
259 }
260
261 /* Get cipher name */
262 ret = silc_config_get_token(line, &config->cipher->alg_name);
263 if (ret < 0)
264 break;
265 if (ret == 0) {
266 fprintf(stderr, "%s:%d: Cipher name not defined\n",
267 config->filename, pc->linenum);
268 break;
269 }
270
271 /* Get module name */
272 config->cipher->sim_name = NULL;
273 ret = silc_config_get_token(line, &config->cipher->sim_name);
274 if (ret < 0)
275 break;
276
277 /* Get key length */
278 ret = silc_config_get_token(line, &tmp);
279 if (ret < 0)
280 break;
281 if (ret == 0) {
282 fprintf(stderr, "%s:%d: Cipher key length not defined\n",
283 config->filename, pc->linenum);
284 break;
285 }
286 config->cipher->key_len = atoi(tmp);
287 silc_free(tmp);
288
289 /* Get block length */
290 ret = silc_config_get_token(line, &tmp);
291 if (ret < 0)
292 break;
293 if (ret == 0) {
294 fprintf(stderr, "%s:%d: Cipher block length not defined\n",
295 config->filename, pc->linenum);
296 break;
297 }
298 config->cipher->block_len = atoi(tmp);
299 silc_free(tmp);
300
301 check = TRUE;
302 break;
303
304 case SILC_CLIENT_CONFIG_SECTION_TYPE_PKCS:
305
306 if (!config->pkcs) {
307 config->pkcs = silc_calloc(1, sizeof(*config->pkcs));
308 config->pkcs->next = NULL;
309 config->pkcs->prev = NULL;
310 } else {
311 if (!config->pkcs->next) {
312 config->pkcs->next =
313 silc_calloc(1, sizeof(*config->pkcs->next));
314 config->pkcs->next->next = NULL;
315 config->pkcs->next->prev = config->pkcs;
316 config->pkcs = config->pkcs->next;
317 }
318 }
319
320 /* Get PKCS name */
321 ret = silc_config_get_token(line, &config->pkcs->alg_name);
322 if (ret < 0)
323 break;
324 if (ret == 0) {
325 fprintf(stderr, "%s:%d: PKCS name not defined\n",
326 config->filename, pc->linenum);
327 break;
328 }
329
330 check = TRUE;
331 break;
332
333 case SILC_CLIENT_CONFIG_SECTION_TYPE_HASH_FUNCTION:
334
335 if (!config->hash_func) {
336 config->hash_func = silc_calloc(1, sizeof(*config->hash_func));
337 config->hash_func->next = NULL;
338 config->hash_func->prev = NULL;
339 } else {
340 if (!config->hash_func->next) {
341 config->hash_func->next =
342 silc_calloc(1, sizeof(*config->hash_func->next));
343 config->hash_func->next->next = NULL;
344 config->hash_func->next->prev = config->hash_func;
345 config->hash_func = config->hash_func->next;
346 }
347 }
348
349 /* Get Hash function name */
350 ret = silc_config_get_token(line, &config->hash_func->alg_name);
351 if (ret < 0)
352 break;
353 if (ret == 0) {
354 fprintf(stderr, "%s:%d: Hash function name not defined\n",
355 config->filename, pc->linenum);
356 break;
357 }
358
359 /* Get Hash function module name */
360 config->hash_func->sim_name = NULL;
361 ret = silc_config_get_token(line, &config->hash_func->sim_name);
362 if (ret < 0)
363 break;
364
365 /* Get block length */
366 ret = silc_config_get_token(line, &tmp);
367 if (ret < 0)
368 break;
369 if (ret == 0) {
370 fprintf(stderr, "%s:%d: Hash function block length not defined\n",
371 config->filename, pc->linenum);
372 break;
373 }
374 config->hash_func->block_len = atoi(tmp);
375 silc_free(tmp);
376
377 /* Get hash length */
378 ret = silc_config_get_token(line, &tmp);
379 if (ret < 0)
380 break;
381 if (ret == 0) {
382 fprintf(stderr, "%s:%d: Hash function hash length not defined\n",
383 config->filename, pc->linenum);
384 break;
385 }
386 config->hash_func->key_len = atoi(tmp);
387 silc_free(tmp);
388
389 check = TRUE;
390 break;
391
392 case SILC_CLIENT_CONFIG_SECTION_TYPE_HMAC:
393
394 if (!config->hmac) {
395 config->hmac = silc_calloc(1, sizeof(*config->hmac));
396 config->hmac->next = NULL;
397 config->hmac->prev = NULL;
398 } else {
399 if (!config->hmac->next) {
400 config->hmac->next =
401 silc_calloc(1, sizeof(*config->hmac->next));
402 config->hmac->next->next = NULL;
403 config->hmac->next->prev = config->hmac;
404 config->hmac = config->hmac->next;
405 }
406 }
407
408 /* Get HMAC name */
409 ret = silc_config_get_token(line, &config->hmac->alg_name);
410 if (ret < 0)
411 break;
412 if (ret == 0) {
413 fprintf(stderr, "%s:%d: HMAC name not defined\n",
414 config->filename, pc->linenum);
415 break;
416 }
417
418 /* Get Hash function name */
419 ret = silc_config_get_token(line, &config->hmac->sim_name);
420 if (ret < 0)
421 break;
422 if (ret == 0) {
423 fprintf(stderr, "%s:%d: Hash function name not defined\n",
424 config->filename, pc->linenum);
425 break;
426 }
427
428 /* Get MAC length */
429 ret = silc_config_get_token(line, &tmp);
430 if (ret < 0)
431 break;
432 if (ret == 0) {
433 fprintf(stderr, "%s:%d: HMAC's MAC length not defined\n",
434 config->filename, pc->linenum);
435 break;
436 }
437 config->hmac->key_len = atoi(tmp);
438 silc_free(tmp);
439
440 check = TRUE;
441 break;
442
443 case SILC_CLIENT_CONFIG_SECTION_TYPE_CONNECTION:
444
445 if (!config->conns) {
446 config->conns = silc_calloc(1, sizeof(*config->conns));
447 config->conns->next = NULL;
448 config->conns->prev = NULL;
449 } else {
450 if (!config->conns->next) {
451 config->conns->next = silc_calloc(1, sizeof(*config->conns));
452 config->conns->next->next = NULL;
453 config->conns->next->prev = config->conns;
454 config->conns = config->conns->next;
455 }
456 }
457
458 /* Get host */
459 ret = silc_config_get_token(line, &config->conns->host);
460 if (ret < 0)
461 break;
462 if (ret == 0)
463 /* Any host */
464 config->conns->host = strdup("*");
465
466 /* Get authentication method */
467 ret = silc_config_get_token(line, &tmp);
468 if (ret < 0)
469 break;
470 if (ret) {
471 if (strcmp(tmp, SILC_CLIENT_CONFIG_AUTH_METH_PASSWD) &&
472 strcmp(tmp, SILC_CLIENT_CONFIG_AUTH_METH_PUBKEY)) {
473 fprintf(stderr, "%s:%d: Unknown authentication method '%s'\n",
474 config->filename, pc->linenum, tmp);
475 break;
476 }
477
478 if (!strcmp(tmp, SILC_CLIENT_CONFIG_AUTH_METH_PASSWD))
479 config->conns->auth_meth = SILC_AUTH_PASSWORD;
480
481 if (!strcmp(tmp, SILC_CLIENT_CONFIG_AUTH_METH_PUBKEY))
482 config->conns->auth_meth = SILC_AUTH_PUBLIC_KEY;
483
484 silc_free(tmp);
485 }
486
487 /* Get authentication data */
488 ret = silc_config_get_token(line, &config->conns->auth_data);
489 if (ret < 0)
490 break;
491
492 /* Get port */
493 ret = silc_config_get_token(line, &tmp);
494 if (ret < 0)
495 break;
496 if (ret) {
497 config->conns->port = atoi(tmp);
498 silc_free(tmp);
499 }
500
501 check = TRUE;
502 break;
503
504 case SILC_CLIENT_CONFIG_SECTION_TYPE_COMMAND:
505
506 if (!config->commands) {
507 config->commands = silc_calloc(1, sizeof(*config->commands));
508 config->commands->next = NULL;
509 config->commands->prev = NULL;
510 } else {
511 if (!config->commands->next) {
512 config->commands->next = silc_calloc(1, sizeof(*config->commands));
513 config->commands->next->next = NULL;
514 config->commands->next->prev = config->commands;
515 config->commands = config->commands->next;
516 }
517 }
518
519 /* Get command line (this may include parameters as well. They
520 will be parsed later with standard command parser when
521 executing particular command.) */
522 config->commands->command = silc_calloc(strlen(line->data),
523 sizeof(char));
524 memcpy(config->commands->command, line->data, strlen(line->data) - 1);
525 if (ret < 0)
526 break;
527
528 check = TRUE;
529 break;
530
531 case SILC_CLIENT_CONFIG_SECTION_TYPE_NONE:
532 default:
533 break;
534 }
535
536 /* Check for error */
537 if (check == FALSE) {
538 /* Line could not be parsed */
539 fprintf(stderr, "%s:%d: Parse error\n", config->filename, pc->linenum);
540 break;
541 }
542
543 pc = pc->next;
544 }
545
546 if (check == FALSE)
547 return FALSE;;
548
549 /* Before returning all the lists in the config object must be set
550 to their first values (the last value is first here). */
551 while (config->cipher && config->cipher->prev)
552 config->cipher = config->cipher->prev;
553 while (config->pkcs && config->pkcs->prev)
554 config->pkcs = config->pkcs->prev;
555 while (config->hash_func && config->hash_func->prev)
556 config->hash_func = config->hash_func->prev;
557 while (config->hmac && config->hmac->prev)
558 config->hmac = config->hmac->prev;
559 while (config->conns && config->conns->prev)
560 config->conns = config->conns->prev;
561 while (config->commands && config->commands->prev)
562 config->commands = config->commands->prev;
563
564 SILC_LOG_DEBUG(("Done"));
565
566 return TRUE;
567 }
568
569 /* Registers configured ciphers. These can then be allocated by the
570 client when needed. */
571
572 bool silc_client_config_register_ciphers(SilcClientConfig config)
573 {
574 SilcClientConfigSectionAlg *alg;
575 SilcClientInternal app = (SilcClientInternal)config->client;
576 SilcClient client = app->client;
577
578 SILC_LOG_DEBUG(("Registering configured ciphers"));
579
580 if (!config->cipher)
581 return FALSE;
582
583 alg = config->cipher;
584 while(alg) {
585
586 if (!alg->sim_name) {
587 /* Crypto module is supposed to be built in. Get the pointer to the
588 built in cipher and register it. */
589 int i;
590
591 for (i = 0; silc_default_ciphers[i].name; i++)
592 if (!strcmp(silc_default_ciphers[i].name, alg->alg_name)) {
593 silc_cipher_register(&silc_default_ciphers[i]);
594 break;
595 }
596
597 if (!silc_cipher_is_supported(alg->alg_name)) {
598 SILC_LOG_ERROR(("Unknown cipher `%s'", alg->alg_name));
599 silc_client_stop(client);
600 exit(1);
601 }
602
603 #ifdef SILC_SIM
604 } else {
605 /* Load (try at least) the crypto SIM module */
606 SilcCipherObject cipher;
607 SilcSimContext *sim;
608 char *alg_name;
609
610 memset(&cipher, 0, sizeof(cipher));
611 cipher.name = alg->alg_name;
612 cipher.block_len = alg->block_len;
613 cipher.key_len = alg->key_len * 8;
614
615 sim = silc_sim_alloc();
616 sim->type = SILC_SIM_CIPHER;
617 sim->libname = alg->sim_name;
618
619 alg_name = strdup(alg->alg_name);
620 if (strchr(alg_name, '-'))
621 *strchr(alg_name, '-') = '\0';
622
623 if ((silc_sim_load(sim))) {
624 cipher.set_key =
625 silc_sim_getsym(sim, silc_sim_symname(alg_name,
626 SILC_CIPHER_SIM_SET_KEY));
627 SILC_LOG_DEBUG(("set_key=%p", cipher.set_key));
628 cipher.set_key_with_string =
629 silc_sim_getsym(sim, silc_sim_symname(alg_name,
630 SILC_CIPHER_SIM_SET_KEY_WITH_STRING));
631 SILC_LOG_DEBUG(("set_key_with_string=%p", cipher.set_key_with_string));
632 cipher.encrypt =
633 silc_sim_getsym(sim, silc_sim_symname(alg_name,
634 SILC_CIPHER_SIM_ENCRYPT_CBC));
635 SILC_LOG_DEBUG(("encrypt_cbc=%p", cipher.encrypt));
636 cipher.decrypt =
637 silc_sim_getsym(sim, silc_sim_symname(alg_name,
638 SILC_CIPHER_SIM_DECRYPT_CBC));
639 SILC_LOG_DEBUG(("decrypt_cbc=%p", cipher.decrypt));
640 cipher.context_len =
641 silc_sim_getsym(sim, silc_sim_symname(alg_name,
642 SILC_CIPHER_SIM_CONTEXT_LEN));
643 SILC_LOG_DEBUG(("context_len=%p", cipher.context_len));
644
645 /* Put the SIM to the table of all SIM's in client */
646 app->sim = silc_realloc(app->sim,
647 sizeof(*app->sim) *
648 (app->sim_count + 1));
649 app->sim[app->sim_count] = sim;
650 app->sim_count++;
651
652 silc_free(alg_name);
653 } else {
654 SILC_LOG_ERROR(("Error configuring ciphers"));
655 silc_client_stop(client);
656 exit(1);
657 }
658
659 /* Register the cipher */
660 silc_cipher_register(&cipher);
661 #endif
662 }
663
664 alg = alg->next;
665 }
666
667 return TRUE;
668 }
669
670 /* Registers configured PKCS's. */
671
672 bool silc_client_config_register_pkcs(SilcClientConfig config)
673 {
674 SilcClientConfigSectionAlg *alg = config->pkcs;
675 SilcClientInternal app = (SilcClientInternal)config->client;
676 SilcClient client = app->client;
677
678 SILC_LOG_DEBUG(("Registering configured PKCS"));
679
680 if (!alg)
681 return FALSE;
682
683 while(alg) {
684 int i;
685
686 for (i = 0; silc_default_pkcs[i].name; i++)
687 if (!strcmp(silc_default_pkcs[i].name, alg->alg_name)) {
688 silc_pkcs_register(&silc_default_pkcs[i]);
689 break;
690 }
691
692 if (!silc_pkcs_is_supported(alg->alg_name)) {
693 SILC_LOG_ERROR(("Unknown PKCS `%s'", alg->alg_name));
694 silc_client_stop(client);
695 exit(1);
696 }
697
698 alg = alg->next;
699 }
700
701 return TRUE;
702 }
703
704 /* Registers configured hash funtions. These can then be allocated by the
705 client when needed. */
706
707 bool silc_client_config_register_hashfuncs(SilcClientConfig config)
708 {
709 SilcClientConfigSectionAlg *alg;
710 SilcClientInternal app = (SilcClientInternal)config->client;
711 SilcClient client = app->client;
712
713 SILC_LOG_DEBUG(("Registering configured hash functions"));
714
715 if (!config->hash_func)
716 return FALSE;
717
718 alg = config->hash_func;
719 while(alg) {
720 if (!alg->sim_name) {
721 int i;
722
723 for (i = 0; silc_default_hash[i].name; i++)
724 if (!strcmp(silc_default_hash[i].name, alg->alg_name)) {
725 silc_hash_register(&silc_default_hash[i]);
726 break;
727 }
728
729 if (!silc_hash_is_supported(alg->alg_name)) {
730 SILC_LOG_ERROR(("Unknown hash function `%s'", alg->alg_name));
731 silc_client_stop(client);
732 exit(1);
733 }
734 #ifdef SILC_SIM
735 } else {
736 /* Load (try at least) the hash SIM module */
737 SilcHashObject hash;
738 SilcSimContext *sim;
739
740 memset(&hash, 0, sizeof(hash));
741 hash.name = alg->alg_name;
742 hash.block_len = alg->block_len;
743 hash.hash_len = alg->key_len;
744
745 sim = silc_sim_alloc();
746 sim->type = SILC_SIM_HASH;
747 sim->libname = alg->sim_name;
748
749 if ((silc_sim_load(sim))) {
750 hash.init =
751 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
752 SILC_HASH_SIM_INIT));
753 SILC_LOG_DEBUG(("init=%p", hash.init));
754 hash.update =
755 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
756 SILC_HASH_SIM_UPDATE));
757 SILC_LOG_DEBUG(("update=%p", hash.update));
758 hash.final =
759 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
760 SILC_HASH_SIM_FINAL));
761 SILC_LOG_DEBUG(("final=%p", hash.final));
762 hash.context_len =
763 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
764 SILC_HASH_SIM_CONTEXT_LEN));
765 SILC_LOG_DEBUG(("context_len=%p", hash.context_len));
766
767 /* Put the SIM to the table of all SIM's in client */
768 app->sim = silc_realloc(app->sim,
769 sizeof(*app->sim) *
770 (app->sim_count + 1));
771 app->sim[app->sim_count] = sim;
772 app->sim_count++;
773 } else {
774 SILC_LOG_ERROR(("Error configuring hash functions"));
775 silc_client_stop(client);
776 exit(1);
777 }
778
779 /* Register the hash function */
780 silc_hash_register(&hash);
781 #endif
782 }
783 alg = alg->next;
784 }
785
786 return TRUE;
787 }
788
789 /* Registers configured HMACs. These can then be allocated by the
790 client when needed. */
791
792 bool silc_client_config_register_hmacs(SilcClientConfig config)
793 {
794 SilcClientConfigSectionAlg *alg;
795 SilcClientInternal app = (SilcClientInternal)config->client;
796 SilcClient client = app->client;
797
798 SILC_LOG_DEBUG(("Registering configured HMACs"));
799
800 if (!config->hmac)
801 return FALSE;
802
803 alg = config->hmac;
804 while(alg) {
805 SilcHmacObject hmac;
806
807 if (!silc_hash_is_supported(alg->sim_name)) {
808 SILC_LOG_ERROR(("Unknown hash function `%s' for HMAC `%s'",
809 alg->sim_name, alg->alg_name));
810 silc_client_stop(client);
811 exit(1);
812 }
813
814 /* Register the HMAC */
815 memset(&hmac, 0, sizeof(hmac));
816 hmac.name = alg->alg_name;
817 hmac.len = alg->key_len;
818 silc_hmac_register(&hmac);
819
820 alg = alg->next;
821 }
822
823 return TRUE;
824 }
825
826 SilcClientConfigSectionConnection *
827 silc_client_config_find_connection(SilcClientConfig config,
828 char *host, int port)
829 {
830 int i;
831 SilcClientConfigSectionConnection *conn = NULL;
832
833 SILC_LOG_DEBUG(("Finding connection"));
834
835 if (!host)
836 return NULL;
837
838 if (!config->conns)
839 return NULL;
840
841 conn = config->conns;
842 for (i = 0; conn; i++) {
843 if (silc_string_compare(conn->host, host))
844 break;
845 conn = conn->next;
846 }
847
848 if (!conn)
849 return NULL;
850
851 SILC_LOG_DEBUG(("Found match"));
852
853 return conn;
854 }
855
This page was automatically generated by the LXR engine.
Free-text search provided by Glimpse