e4f79fd9ce4c057bd69589082f5533a275d6ba84
[silc.git] / apps / silc / client.c
1 /*
2
3   client.c
4
5   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
6
7   Copyright (C) 1997 - 2000 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 /*
21  * $Id$
22  * $Log$
23  * Revision 1.3  2000/07/04 08:29:12  priikone
24  *      Added support for PING command. The ping times are calculated
25  *      and showed to the user.
26  *
27  * Revision 1.2  2000/07/03 05:49:48  priikone
28  *      Implemented LEAVE command.  Minor bug fixes.
29  *
30  * Revision 1.1.1.1  2000/06/27 11:36:56  priikone
31  *      Importet from internal CVS/Added Log headers.
32  *
33  *
34  */
35
36 #include "clientincludes.h"
37
38 /* Static function prototypes */
39 static int silc_client_bad_keys(unsigned char key);
40 static void silc_client_process_message(SilcClient client);
41 static char *silc_client_parse_command(unsigned char *buffer);
42
43 /* Static task callback prototypes */
44 SILC_TASK_CALLBACK(silc_client_update_clock);
45 SILC_TASK_CALLBACK(silc_client_run_commands);
46 SILC_TASK_CALLBACK(silc_client_process_key_press);
47 SILC_TASK_CALLBACK(silc_client_connect_to_server_start);
48 SILC_TASK_CALLBACK(silc_client_connect_to_server_second);
49 SILC_TASK_CALLBACK(silc_client_connect_to_server_final);
50 SILC_TASK_CALLBACK(silc_client_packet_process);
51 SILC_TASK_CALLBACK(silc_client_packet_parse);
52
53 SilcClientWindow silc_client_create_main_window(SilcClient client);
54 SilcClientWindow silc_client_add_window(SilcClient client,
55                                         int is_current);
56 void silc_client_packet_parse_type(SilcClient client, 
57                                    SilcSocketConnection sock,
58                                    SilcPacketContext *packet);
59 void silc_client_private_message_process(SilcClient client,
60                                          SilcSocketConnection sock,
61                                          SilcPacketContext *packet);
62
63 /* Definitions from version.h */
64 extern char *silc_version;
65 extern char *silc_name;
66 extern char *silc_fullname;
67
68 /* Allocates new client object. This has to be done before client may
69    work. After calling this one must call silc_client_init to initialize
70    the client. */
71
72 int silc_client_alloc(SilcClient *new_client)
73 {
74
75   *new_client = silc_calloc(1, sizeof(**new_client));
76   if (*new_client == NULL) {
77     SILC_LOG_ERROR(("Could not allocate new client object"));
78     return FALSE;
79   }
80
81   (*new_client)->input_buffer = NULL;
82   (*new_client)->screen = NULL;
83   (*new_client)->windows = NULL;
84   (*new_client)->windows_count = 0;
85   (*new_client)->current_win = NULL;
86
87   return TRUE;
88 }
89
90 /* Free's client object */
91
92 void silc_client_free(SilcClient client)
93 {
94   if (client) {
95     silc_free(client);
96   }
97 }
98
99 /* Initializes the client. This makes all the necessary steps to make
100    the client ready to be run. One must call silc_client_run to run the
101    client. */
102
103 int silc_client_init(SilcClient client)
104 {
105
106   SILC_LOG_DEBUG(("Initializing client"));
107   assert(client);
108
109   client->username = silc_get_username();
110   client->realname = silc_get_real_name();
111
112   /* Register all configured ciphers, PKCS and hash functions. */
113   client->config->client = (void *)client;
114   silc_client_config_register_ciphers(client->config);
115   silc_client_config_register_pkcs(client->config);
116   silc_client_config_register_hashfuncs(client->config);
117
118   /* Initialize hash functions for client to use */
119   silc_hash_alloc("md5", &client->md5hash);
120   silc_hash_alloc("sha1", &client->sha1hash);
121
122   /* Initialize none cipher */
123   silc_cipher_alloc("none", &client->none_cipher);
124
125   /* Initialize random number generator */
126   client->rng = silc_rng_alloc();
127   silc_rng_init(client->rng);
128   silc_math_primegen_init(); /* XXX */
129
130 #if 0
131   {
132     SilcCipher twofish;
133     unsigned char *src, *dst, *dec;
134     SilcBuffer packet;
135     int payload_len;
136
137     payload_len = 4 + strlen("pekka riikonen");
138     packet = silc_buffer_alloc(payload_len);
139     silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
140     silc_buffer_format(packet,
141                        SILC_STR_UI_SHORT(payload_len),
142                        SILC_STR_UI_SHORT(SILC_SOCKET_TYPE_CLIENT),
143                        SILC_STR_UI_XNSTRING("pekka riikonen", 
144                                             strlen("pekka riikonen")),
145                        SILC_STR_END);
146
147     silc_cipher_alloc("twofish", &twofish);
148     twofish->cipher->set_key(twofish->context, "1234567890123456", 16);
149     twofish->set_iv(twofish, "6543210987654321");
150     SILC_LOG_HEXDUMP(("source: len %d", packet->len), 
151                      packet->data, packet->len );
152     silc_packet_encrypt(twofish, packet, packet->len);
153     SILC_LOG_HEXDUMP(("encrypted"), packet->data, packet->len);
154     silc_packet_decrypt(twofish, packet, packet->len);
155     SILC_LOG_HEXDUMP(("decrypted"), packet->data, packet->len);
156
157   }
158
159   {
160     SilcCipher cipher1, cipher2;
161     unsigned char *src, *dst, *dec;
162     int len = strlen("12345678901234561234567890123456123456789012345612345678901234561234567890123456");
163
164     src = silc_calloc(len + 1, sizeof(unsigned char));
165     dst = silc_calloc(len + 1, sizeof(unsigned char));
166     dec = silc_calloc(len + 1, sizeof(unsigned char));
167
168     memcpy(src, "12345678901234561234567890123456123456789012345612345678901234561234567890123456", len);
169     
170     silc_cipher_alloc("twofish", &cipher1);
171     cipher1->cipher->set_key(cipher1->context, "1234567890123456", 128);
172     cipher1->set_iv(cipher1, "6543210987654321");
173
174     silc_cipher_alloc("twofish", &cipher2);
175     cipher2->cipher->set_key(cipher2->context, "1234567890123456", 128);
176     cipher2->set_iv(cipher2, "6543210987654321");
177
178     SILC_LOG_HEXDUMP(("source: %d", len), src, len);
179     cipher1->cipher->encrypt(cipher1->context, src, src, len, cipher1->iv);
180     SILC_LOG_HEXDUMP(("encrypted"), src, len);
181     cipher2->set_iv(cipher2, "6543210987654321");
182     cipher2->cipher->decrypt(cipher2->context, src, src, len, cipher2->iv);
183     SILC_LOG_HEXDUMP(("decrypted"), src, len);
184
185   }
186 #endif
187
188   /* Register the task queues. In SILC we have by default three task queues. 
189      One task queue for non-timeout tasks which perform different kind of 
190      I/O on file descriptors, timeout task queue for timeout tasks, and,
191      generic non-timeout task queue whose tasks apply to all connections. */
192   silc_task_queue_alloc(&client->io_queue, TRUE);
193   if (!client->io_queue) {
194     goto err0;
195   }
196   silc_task_queue_alloc(&client->timeout_queue, TRUE);
197   if (!client->timeout_queue) {
198     goto err1;
199   }
200   silc_task_queue_alloc(&client->generic_queue, TRUE);
201   if (!client->generic_queue) {
202     goto err1;
203   }
204
205   /* Initialize the scheduler */
206   silc_schedule_init(client->io_queue, client->timeout_queue, 
207                      client->generic_queue, 5000);
208
209   /* Register the main task that is used in client. This received
210      the key pressings. */
211   if (silc_task_register(client->io_queue, fileno(stdin), 
212                          silc_client_process_key_press,
213                          (void *)client, 0, 0, 
214                          SILC_TASK_FD,
215                          SILC_TASK_PRI_NORMAL) == NULL) {
216     goto err2;
217   }
218
219   /* Register timeout task that updates clock every minute. */
220   if (silc_task_register(client->timeout_queue, 0,
221                          silc_client_update_clock,
222                          (void *)client, 
223                          silc_client_time_til_next_min(), 0,
224                          SILC_TASK_TIMEOUT,
225                          SILC_TASK_PRI_LOW) == NULL) {
226     goto err2;
227   }
228
229   if (client->config->commands) {
230     /* Run user configured commands with timeout */
231     if (silc_task_register(client->timeout_queue, 0,
232                            silc_client_run_commands,
233                            (void *)client, 0, 1,
234                            SILC_TASK_TIMEOUT,
235                            SILC_TASK_PRI_LOW) == NULL) {
236       goto err2;
237     }
238   }
239
240   /* Allocate the input buffer used to save typed characters */
241   client->input_buffer = silc_buffer_alloc(SILC_SCREEN_INPUT_WIN_SIZE);
242   silc_buffer_pull_tail(client->input_buffer, 
243                         SILC_BUFFER_END(client->input_buffer));
244
245   /* Initialize the screen */
246   client->screen = silc_screen_init();
247   silc_client_create_main_window(client);
248   client->screen->input_buffer = client->input_buffer->data;
249   silc_screen_print_coordinates(client->screen, 0);
250
251   return TRUE;
252
253  err0:
254   silc_task_queue_free(client->timeout_queue);
255  err1:
256   silc_task_queue_free(client->io_queue);
257  err2:
258   return FALSE;
259 }
260
261 /* Stops the client. This is called to stop the client and thus to stop
262    the program. */
263
264 void silc_client_stop(SilcClient client)
265 {
266   SILC_LOG_DEBUG(("Stopping client"));
267
268   /* Stop the scheduler, although it might be already stopped. This
269      doesn't hurt anyone. This removes all the tasks and task queues,
270      as well. */
271   silc_schedule_stop();
272   silc_schedule_uninit();
273
274   SILC_LOG_DEBUG(("Client client"));
275 }
276
277 /* Runs the client. */
278
279 void silc_client_run(SilcClient client)
280 {
281   SILC_LOG_DEBUG(("Running client"));
282
283   /* Start the scheduler, the heart of the SILC client. When this returns
284      the program will be terminated. */
285   silc_schedule();
286 }
287
288 /* Creates the main window used in SILC client. This is called always
289    at the initialization of the client. If user wants to create more
290    than one windows a new windows are always created by calling 
291    silc_client_add_window. */
292
293 SilcClientWindow silc_client_create_main_window(SilcClient client)
294 {
295   SilcClientWindow win;
296   void *screen;
297
298   SILC_LOG_DEBUG(("Creating main window"));
299
300   assert(client->screen != NULL);
301
302   win = silc_calloc(1, sizeof(*win));
303   if (win == NULL) {
304     SILC_LOG_ERROR(("Could not allocate new window"));
305     return NULL;
306   }
307
308   client->screen->u_stat_line.program_name = silc_name;
309   client->screen->u_stat_line.program_version = silc_version;
310
311   /* Add the pointers */
312   win->nickname = silc_get_username();
313   win->local_id = NULL;
314   win->local_id_data = NULL;
315   win->local_id_data_len = 0;
316   win->remote_host = NULL;
317   win->remote_port = -1;
318   win->sock = NULL;
319
320   /* Create the actual screen */
321   screen = (void *)silc_screen_create_output_window(client->screen);
322   silc_screen_create_input_window(client->screen);
323   silc_screen_init_upper_status_line(client->screen);
324   silc_screen_init_output_status_line(client->screen);
325   win->screen = screen;
326
327   client->screen->bottom_line->nickname = win->nickname;
328   silc_screen_print_bottom_line(client->screen, 0);
329
330   /* Add the window to windows table */
331   client->windows = silc_calloc(1, sizeof(*client->windows));
332   client->windows[client->windows_count] = win;
333   client->windows_count = 1;
334
335   /* Automatically becomes the current active window */
336   client->current_win = win;
337
338   return win;
339 }
340
341 /* Allocates and adds new window to the client. This allocates new
342    physical window and internal window for connection specific data. 
343    All the connection specific data is always saved into a window
344    since connection is always associated to a active window. */
345
346 SilcClientWindow silc_client_add_window(SilcClient client,
347                                         int is_current)
348 {
349   SilcClientWindow win;
350
351   assert(client->screen != NULL);
352
353   win = silc_calloc(1, sizeof(*win));
354   if (win == NULL) {
355     SILC_LOG_ERROR(("Could not allocate new window"));
356     return NULL;
357   }
358
359   /* Add the pointers */
360   win->screen = silc_screen_add_output_window(client->screen);
361   win->sock = NULL;
362
363   /* Add the window to windows table */
364   client->windows = silc_realloc(client->windows, sizeof(*client->windows)
365                                  * (client->windows_count + 1));
366   client->windows[client->windows_count] = win;
367   client->windows_count++;
368
369   if (is_current == TRUE)
370     client->current_win = win;
371
372   return win;
373 }
374
375 /* The main task on SILC client. This processes the key pressings user
376    has made. */
377
378 SILC_TASK_CALLBACK(silc_client_process_key_press)
379 {
380   SilcClient client = (SilcClient)context;
381   int c;
382
383   /* There is data pending in stdin, this gets it directly */
384   c = wgetch(client->screen->input_win);
385   if (silc_client_bad_keys(c))
386     return;
387
388   SILC_LOG_DEBUG(("Pressed key: %d", c));
389
390   switch(c) {
391     /* 
392      * Special character handling
393      */
394   case KEY_UP: 
395   case KEY_DOWN:
396     break;
397   case KEY_RIGHT:
398     /* Right arrow */
399     SILC_LOG_DEBUG(("RIGHT"));
400     silc_screen_input_cursor_right(client->screen);
401     break;
402   case KEY_LEFT:
403     /* Left arrow */
404     SILC_LOG_DEBUG(("LEFT"));
405     silc_screen_input_cursor_left(client->screen);
406     break;
407   case KEY_BACKSPACE:
408   case KEY_DC:
409   case '\177':
410   case '\b':
411     /* Backspace */
412     silc_screen_input_backspace(client->screen);
413     break;
414   case '\011':
415     /* Tabulator */
416     break;
417   case KEY_IC:
418     /* Insert switch. Turns on/off insert on input window */
419     silc_screen_input_insert(client->screen);
420     break;
421   case CTRL('j'):
422   case '\r':
423     /* Enter, Return. User pressed enter we are ready to
424        process the message. */
425     silc_client_process_message(client);
426     silc_screen_input_reset(client->screen);
427     break;
428   case CTRL('l'):
429     /* Refresh screen, Ctrl^l */
430     silc_screen_refresh_all(client->screen);
431     break;
432   case CTRL('a'):
433   case KEY_HOME:
434   case KEY_BEG:
435     /* Beginning, Home */
436     silc_screen_input_cursor_home(client->screen);
437     break;
438   case CTRL('e'):
439   case KEY_END:
440     /* End */
441     silc_screen_input_cursor_end(client->screen);
442     break;
443   case KEY_LL:
444     /* End */
445     break;
446   case CTRL('g'):
447     /* Bell, Ctrl^g */
448     beep();
449     break;
450   case KEY_DL:
451   case CTRL('u'):
452     /* Delete line */
453     break;
454   default:
455     /* 
456      * Other characters 
457      */
458     if (c < 32) {
459       /* Control codes are printed as reversed */
460       c = (c & 127) | 64;
461       wattron(client->screen->input_win, A_REVERSE);
462       silc_screen_input_print(client->screen, c);
463       wattroff(client->screen->input_win, A_REVERSE);
464     } else  {
465       /* Normal character */
466       silc_screen_input_print(client->screen, c);
467     }
468   }
469
470   silc_screen_print_coordinates(client->screen, 0);
471   silc_screen_refresh_win(client->screen->input_win);
472 }
473
474 static int silc_client_bad_keys(unsigned char key)
475 {
476   /* these are explained in curses.h */
477   switch(key) {
478   case KEY_SF:
479   case KEY_SR:
480   case KEY_NPAGE:
481   case KEY_PPAGE:
482   case KEY_PRINT:
483   case KEY_A1:
484   case KEY_A3:
485   case KEY_B2:
486   case KEY_C1:
487   case KEY_C3:
488   case KEY_UNDO:
489   case KEY_EXIT:
490   case '\v':           /* VT */
491   case '\E':           /* we ignore ESC */
492     return TRUE;
493   default: 
494     return FALSE; 
495   }
496 }
497
498 /* Processes messages user has typed on the screen. This either sends
499    a packet out to network or if command were written executes it. */
500
501 static void silc_client_process_message(SilcClient client)
502 {
503   unsigned char *data;
504   unsigned int len;
505
506   SILC_LOG_DEBUG(("Start"));
507
508   data = client->input_buffer->data;
509   len = strlen(data);
510
511   if (data[0] == '/' && data[1] != ' ') {
512     /* Command */
513     unsigned int argc = 0;
514     unsigned char **argv, *tmpcmd;
515     unsigned int *argv_lens, *argv_types;
516     SilcClientCommand *cmd;
517     SilcClientCommandContext ctx;
518
519     /* Get the command */
520     tmpcmd = silc_client_parse_command(data);
521
522     /* Find command match */
523     for (cmd = silc_command_list; cmd->name; cmd++) {
524       if (!strcmp(cmd->name, tmpcmd))
525         break;
526     }
527
528     if (cmd->name == NULL) {
529       silc_say(client, "Invalid command: %s", tmpcmd);
530       silc_free(tmpcmd);
531       goto out;
532     }
533
534     /* Now parse all arguments */
535     silc_client_parse_command_line(data, &argv, &argv_lens, 
536                                    &argv_types, &argc, cmd->max_args);
537     silc_free(tmpcmd);
538
539     SILC_LOG_DEBUG(("Exeuting command: %s", cmd->name));
540
541     /* Allocate command context. This and its internals must be free'd 
542        by the command routine receiving it. */
543     ctx = silc_calloc(1, sizeof(*ctx));
544     ctx->client = client;
545     ctx->sock = client->current_win->sock;
546     ctx->argc = argc;
547     ctx->argv = argv;
548     ctx->argv_lens = argv_lens;
549     ctx->argv_types = argv_types;
550
551     /* Execute command */
552     (*cmd->cb)(ctx);
553
554   } else {
555     /* Normal message to a channel */
556     if (len && client->current_win->current_channel &&
557         client->current_win->current_channel->on_channel == TRUE) {
558       silc_print(client, "> %s", data);
559       silc_client_packet_send_to_channel(client, 
560                                          client->current_win->sock,
561                                          client->current_win->current_channel,
562                                          data, strlen(data), TRUE);
563     }
564   }
565
566  out:
567   /* Clear the input buffer */
568   silc_buffer_clear(client->input_buffer);
569   silc_buffer_pull_tail(client->input_buffer, 
570                         SILC_BUFFER_END(client->input_buffer));
571 }
572
573 /* Returns the command fetched from user typed command line */
574
575 static char *silc_client_parse_command(unsigned char *buffer)
576 {
577   char *ret;
578   const char *cp = buffer;
579   int len;
580
581   len = strcspn(cp, " ");
582   ret = silc_to_upper((char *)++cp);
583   ret[len - 1] = 0;
584
585   return ret;
586 }
587
588 /* Parses user typed command line. At most `max_args' is taken. Rest
589    of the line will be allocated as the last argument if there are more
590    than `max_args' arguments in the line. Note that the command name
591    is counted as one argument and is saved. */
592
593 void silc_client_parse_command_line(unsigned char *buffer, 
594                                     unsigned char ***parsed,
595                                     unsigned int **parsed_lens,
596                                     unsigned int **parsed_types,
597                                     unsigned int *parsed_num,
598                                     unsigned int max_args)
599 {
600   int i, len = 0;
601   int argc = 0;
602   const char *cp = buffer;
603
604   /* Take the '/' away */
605   cp++;
606
607   *parsed = silc_calloc(1, sizeof(**parsed));
608   *parsed_lens = silc_calloc(1, sizeof(**parsed_lens));
609
610   /* Get the command first */
611   len = strcspn(cp, " ");
612   (*parsed)[0] = silc_to_upper((char *)cp);
613   (*parsed_lens)[0] = len;
614   cp += len + 1;
615   argc++;
616
617   /* Parse arguments */
618   if (strchr(cp, ' ') || strlen(cp) != 0) {
619     for (i = 1; i < max_args; i++) {
620
621       if (i != max_args - 1)
622         len = strcspn(cp, " ");
623       else
624         len = strlen(cp);
625       
626       *parsed = silc_realloc(*parsed, sizeof(**parsed) * (argc + 1));
627       *parsed_lens = silc_realloc(*parsed_lens, 
628                                   sizeof(**parsed_lens) * (argc + 1));
629       (*parsed)[argc] = silc_calloc(len + 1, sizeof(char));
630       memcpy((*parsed)[argc], cp, len);
631       (*parsed_lens)[argc] = len;
632       argc++;
633
634       cp += len;
635       if (strlen(cp) == 0)
636         break;
637       else
638         cp++;
639     }
640   }
641
642   /* Save argument types. Protocol defines all argument types but
643      this implementation makes sure that they are always in correct
644      order hence this simple code. */
645   *parsed_types = silc_calloc(argc, sizeof(**parsed_types));
646   for (i = 0; i < argc; i++)
647     (*parsed_types)[i] = i;
648
649   *parsed_num = argc;
650 }
651
652 /* Updates clock on the screen every minute. */
653
654 SILC_TASK_CALLBACK(silc_client_update_clock)
655 {
656   SilcClient client = (SilcClient)context;
657
658   /* Update the clock on the screen */
659   silc_screen_print_clock(client->screen);
660
661   /* Re-register this same task */
662   silc_task_register(qptr, 0, silc_client_update_clock, context, 
663                      silc_client_time_til_next_min(), 0,
664                      SILC_TASK_TIMEOUT,
665                      SILC_TASK_PRI_LOW);
666
667   silc_screen_refresh_win(client->screen->input_win);
668 }
669
670 /* Runs commands user configured in configuration file. This is
671    called when initializing client. */
672
673 SILC_TASK_CALLBACK(silc_client_run_commands)
674 {
675   SilcClient client = (SilcClient)context;
676   SilcClientConfigSectionCommand *cs;
677
678   SILC_LOG_DEBUG(("Start"));
679
680   cs = client->config->commands;
681   while(cs) {
682     unsigned int argc = 0;
683     unsigned char **argv, *tmpcmd;
684     unsigned int *argv_lens, *argv_types;
685     SilcClientCommand *cmd;
686     SilcClientCommandContext ctx;
687
688     /* Get the command */
689     tmpcmd = silc_client_parse_command(cs->command);
690
691     for (cmd = silc_command_list; cmd->name; cmd++) {
692       if (!strcmp(cmd->name, tmpcmd))
693         break;
694     }
695     
696     if (cmd->name == NULL) {
697       silc_say(client, "Invalid command: %s", tmpcmd);
698       silc_free(tmpcmd);
699       continue;
700     }
701     
702     /* Now parse all arguments */
703     silc_client_parse_command_line(cs->command, &argv, &argv_lens, 
704                                    &argv_types, &argc, cmd->max_args);
705     silc_free(tmpcmd);
706
707     SILC_LOG_DEBUG(("Exeuting command: %s", cmd->name));
708
709     /* Allocate command context. This and its internals must be free'd 
710        by the command routine receiving it. */
711     ctx = silc_calloc(1, sizeof(*ctx));
712     ctx->client = client;
713     ctx->sock = client->current_win->sock;
714     ctx->argc = argc;
715     ctx->argv = argv;
716     ctx->argv_lens = argv_lens;
717     ctx->argv_types = argv_types;
718
719     /* Execute command */
720     (*cmd->cb)(ctx);
721
722     cs = cs->next;
723   }
724 }
725
726 /* Internal context for connection process. This is needed as we
727    doing asynchronous connecting. */
728 typedef struct {
729   SilcClient client;
730   SilcTask task;
731   int sock;
732   char *host;
733   int port;
734   int tries;
735 } SilcClientInternalConnectContext;
736
737 static int 
738 silc_client_connect_to_server_internal(SilcClientInternalConnectContext *ctx)
739 {
740   int sock;
741
742   /* XXX In the future we should give up this non-blocking connect all
743      together and use threads instead. */
744   /* Create connection to server asynchronously */
745   sock = silc_net_create_connection_async(ctx->port, ctx->host);
746   if (sock < 0)
747     return -1;
748
749   /* Register task that will receive the async connect and will
750      read the result. */
751   ctx->task = silc_task_register(ctx->client->io_queue, sock, 
752                                  silc_client_connect_to_server_start,
753                                  (void *)ctx, 0, 0, 
754                                  SILC_TASK_FD,
755                                  SILC_TASK_PRI_NORMAL);
756   silc_task_reset_iotype(ctx->task, SILC_TASK_WRITE);
757   silc_schedule_set_listen_fd(sock, ctx->task->iomask);
758
759   ctx->sock = sock;
760
761   return sock;
762 }
763
764 /* Connects to remote server */
765
766 int silc_client_connect_to_server(SilcClient client, int port,
767                                   char *host)
768 {
769   SilcClientInternalConnectContext *ctx;
770
771   SILC_LOG_DEBUG(("Connecting to port %d of server %s",
772                   port, host));
773
774   silc_say(client, "Connecting to port %d of server %s", port, host);
775
776   client->current_win->remote_host = strdup(host);
777   client->current_win->remote_port = port;
778
779   /* Allocate internal context for connection process. This is
780      needed as we are doing async connecting. */
781   ctx = silc_calloc(1, sizeof(*ctx));
782   ctx->client = client;
783   ctx->host = strdup(host);
784   ctx->port = port;
785   ctx->tries = 0;
786
787   /* Do the actual connecting process */
788   return silc_client_connect_to_server_internal(ctx);
789 }
790
791 /* Start of the connection to the remote server. This is called after
792    succesful TCP/IP connection has been established to the remote host. */
793
794 SILC_TASK_CALLBACK(silc_client_connect_to_server_start)
795 {
796   SilcClientInternalConnectContext *ctx =
797     (SilcClientInternalConnectContext *)context;
798   SilcClient client = ctx->client;
799   SilcProtocol protocol;
800   SilcClientKEInternalContext *proto_ctx;
801   int opt, opt_len = sizeof(opt);
802
803   SILC_LOG_DEBUG(("Start"));
804
805   /* Check the socket status as it might be in error */
806   getsockopt(fd, SOL_SOCKET, SO_ERROR, &opt, &opt_len);
807   if (opt != 0) {
808     if (ctx->tries < 2) {
809       /* Connection failed but lets try again */
810       silc_say(ctx->client, "Could not connect to server %s: %s",
811                ctx->host, strerror(opt));
812       silc_say(client, "Connecting to port %d of server %s resumed", 
813                ctx->port, ctx->host);
814
815       /* Unregister old connection try */
816       silc_schedule_unset_listen_fd(fd);
817       silc_net_close_connection(fd);
818       silc_task_unregister(client->io_queue, ctx->task);
819
820       /* Try again */
821       silc_client_connect_to_server_internal(ctx);
822       ctx->tries++;
823     } else {
824       /* Connection failed and we won't try anymore */
825       silc_say(ctx->client, "Could not connect to server %s: %s",
826                ctx->host, strerror(opt));
827       silc_schedule_unset_listen_fd(fd);
828       silc_net_close_connection(fd);
829       silc_task_unregister(client->io_queue, ctx->task);
830       silc_free(ctx);
831     }
832     return;
833   }
834
835   silc_schedule_unset_listen_fd(fd);
836   silc_task_unregister(client->io_queue, ctx->task);
837   silc_free(ctx);
838
839   /* Allocate new socket connection object */
840   silc_socket_alloc(fd, SILC_SOCKET_TYPE_SERVER, 
841                     (void *)client->current_win, 
842                     &client->current_win->sock);
843   if (client->current_win->sock == NULL) {
844     silc_say(client, "Error: Could not allocate connection socket");
845     silc_net_close_connection(fd);
846     return;
847   }
848   client->current_win->sock->hostname = client->current_win->remote_host;
849   client->current_win->sock->port = client->current_win->remote_port;
850
851   /* Allocate internal Key Exchange context. This is sent to the
852      protocol as context. */
853   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
854   proto_ctx->client = (void *)client;
855   proto_ctx->sock = client->current_win->sock;
856   proto_ctx->rng = client->rng;
857   proto_ctx->responder = FALSE;
858
859   /* Perform key exchange protocol. silc_client_connect_to_server_final
860      will be called after the protocol is finished. */
861   silc_protocol_alloc(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE, 
862                       &protocol, (void *)proto_ctx,
863                       silc_client_connect_to_server_second);
864   if (!protocol) {
865     silc_say(client, "Error: Could not start authentication protocol");
866     return;
867   }
868   client->current_win->sock->protocol = protocol;
869
870   /* Register the connection for network input and output. This sets
871      that scheduler will listen for incoming packets for this connection 
872      and sets that outgoing packets may be sent to this connection as well.
873      However, this doesn't set the scheduler for outgoing traffic, it will 
874      be set separately by calling SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT,
875      later when outgoing data is available. */
876   context = (void *)client;
877   SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(fd);
878
879   /* Execute the protocol */
880   protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0);
881 }
882
883 /* Second part of the connecting to the server. This executed 
884    authentication protocol. */
885
886 SILC_TASK_CALLBACK(silc_client_connect_to_server_second)
887 {
888   SilcProtocol protocol = (SilcProtocol)context;
889   SilcClientKEInternalContext *ctx = 
890     (SilcClientKEInternalContext *)protocol->context;
891   SilcClient client = (SilcClient)ctx->client;
892   SilcSocketConnection sock = NULL;
893   SilcClientConnAuthInternalContext *proto_ctx;
894
895   SILC_LOG_DEBUG(("Start"));
896
897   if (protocol->state == SILC_PROTOCOL_STATE_ERROR) {
898     /* Error occured during protocol */
899     SILC_LOG_DEBUG(("Error during KE protocol"));
900     silc_protocol_free(protocol);
901     if (ctx->packet)
902       silc_buffer_free(ctx->packet);
903     if (ctx->ske)
904       silc_ske_free(ctx->ske);
905     if (ctx->dest_id)
906       silc_free(ctx->dest_id);
907     silc_free(ctx);
908     sock->protocol = NULL;
909     return;
910   }
911
912   /* Allocate internal context for the authentication protocol. This
913      is sent as context for the protocol. */
914   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
915   proto_ctx->client = (void *)client;
916   proto_ctx->sock = sock = ctx->sock;
917   proto_ctx->ske = ctx->ske;    /* Save SKE object from previous protocol */
918   proto_ctx->dest_id_type = ctx->dest_id_type;
919   proto_ctx->dest_id = ctx->dest_id;
920
921   /* Resolve the authentication method to be used in this connection */
922   proto_ctx->auth_meth = SILC_PROTOCOL_CONN_AUTH_NONE;
923   if (client->config->conns) {
924     SilcClientConfigSectionConnection *conn = NULL;
925
926     /* Check if we find a match from user configured connections */
927     conn = silc_client_config_find_connection(client->config,
928                                               sock->hostname,
929                                               sock->port);
930     if (conn) {
931       /* Match found. Use the configured authentication method */
932       proto_ctx->auth_meth = conn->auth_meth;
933       if (conn->auth_data) {
934         proto_ctx->auth_data = strdup(conn->auth_data);
935         proto_ctx->auth_data_len = strlen(conn->auth_data);
936       }
937     } else {
938       /* No match found. Resolve by sending AUTH_REQUEST to server */
939       proto_ctx->auth_meth = SILC_PROTOCOL_CONN_AUTH_NONE;
940     }
941   } else {
942     /* XXX Resolve by sending AUTH_REQUEST to server */
943     proto_ctx->auth_meth = SILC_PROTOCOL_CONN_AUTH_NONE;
944   }
945
946   /* Free old protocol as it is finished now */
947   silc_protocol_free(protocol);
948   if (ctx->packet)
949     silc_buffer_free(ctx->packet);
950   silc_free(ctx);
951   /* silc_free(ctx->keymat....); */
952   sock->protocol = NULL;
953
954   /* Allocate the authentication protocol. This is allocated here
955      but we won't start it yet. We will be receiving party of this
956      protocol thus we will wait that connecting party will make
957      their first move. */
958   silc_protocol_alloc(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH, 
959                       &sock->protocol, (void *)proto_ctx, 
960                       silc_client_connect_to_server_final);
961
962   /* Execute the protocol */
963   sock->protocol->execute(client->timeout_queue, 0, sock->protocol, fd, 0, 0);
964 }
965
966 /* Finalizes the connection to the remote SILC server. This is called
967    after authentication protocol has been completed. This send our
968    user information to the server to receive our client ID from
969    server. */
970
971 SILC_TASK_CALLBACK(silc_client_connect_to_server_final)
972 {
973   SilcProtocol protocol = (SilcProtocol)context;
974   SilcClientConnAuthInternalContext *ctx = 
975     (SilcClientConnAuthInternalContext *)protocol->context;
976   SilcClient client = (SilcClient)ctx->client;
977   SilcClientWindow win = (SilcClientWindow)ctx->sock->user_data;
978   SilcBuffer packet;
979
980   SILC_LOG_DEBUG(("Start"));
981
982   if (protocol->state == SILC_PROTOCOL_STATE_ERROR) {
983     /* Error occured during protocol */
984     SILC_LOG_DEBUG(("Error during authentication protocol"));
985     silc_protocol_free(protocol);
986     if (ctx->auth_data)
987       silc_free(ctx->auth_data);
988     if (ctx->ske)
989       silc_ske_free(ctx->ske);
990     if (ctx->dest_id)
991       silc_free(ctx->dest_id);
992     silc_free(ctx);
993     win->sock->protocol = NULL;
994     return;
995   }
996
997   /* Send NEW_CLIENT packet to the server. We will become registered
998      to the SILC network after sending this packet and we will receive
999      client ID from the server. */
1000   packet = silc_buffer_alloc(2 + 2 + strlen(client->username) + 
1001                              strlen(client->realname));
1002   silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
1003   silc_buffer_format(packet,
1004                      SILC_STR_UI_SHORT(strlen(client->username)),
1005                      SILC_STR_UI_XNSTRING(client->username,
1006                                           strlen(client->username)),
1007                      SILC_STR_UI_SHORT(strlen(client->realname)),
1008                      SILC_STR_UI_XNSTRING(client->realname,
1009                                           strlen(client->realname)),
1010                      SILC_STR_END);
1011
1012   /* Send the packet */
1013   silc_client_packet_send(client, ctx->sock, SILC_PACKET_NEW_CLIENT,
1014                           NULL, 0, NULL, NULL, 
1015                           packet->data, packet->len, TRUE);
1016   silc_buffer_free(packet);
1017
1018   /* Save remote ID. */
1019   win->remote_id = ctx->dest_id;
1020   win->remote_id_data = silc_id_id2str(ctx->dest_id, SILC_ID_CHANNEL);
1021   win->remote_id_data_len = SILC_ID_CHANNEL_LEN;
1022
1023   silc_say(client, "Connected to port %d of host %s",
1024            win->remote_port, win->remote_host);
1025
1026   client->screen->bottom_line->connection = win->remote_host;
1027   silc_screen_print_bottom_line(client->screen, 0);
1028
1029   silc_protocol_free(protocol);
1030   if (ctx->auth_data)
1031     silc_free(ctx->auth_data);
1032   if (ctx->ske)
1033     silc_ske_free(ctx->ske);
1034   if (ctx->dest_id)
1035     silc_free(ctx->dest_id);
1036   silc_free(ctx);
1037   win->sock->protocol = NULL;
1038 }
1039
1040 typedef struct {
1041   SilcPacketContext *packetdata;
1042   SilcSocketConnection sock;
1043   SilcClient client;
1044 } SilcClientInternalPacket;
1045
1046 SILC_TASK_CALLBACK(silc_client_packet_process)
1047 {
1048   SilcClient client = (SilcClient)context;
1049   SilcSocketConnection sock = NULL;
1050   int ret, packetlen, paddedlen;
1051
1052   SILC_LOG_DEBUG(("Processing packet"));
1053
1054   SILC_CLIENT_GET_SOCK(client, fd, sock);
1055   if (sock == NULL)
1056     return;
1057
1058   /* Packet sending */
1059   if (type == SILC_TASK_WRITE) {
1060     SILC_LOG_DEBUG(("Writing data to connection"));
1061
1062     if (sock->outbuf->data - sock->outbuf->head)
1063       silc_buffer_push(sock->outbuf, 
1064                        sock->outbuf->data - sock->outbuf->head);
1065
1066     /* Write the packet out to the connection */
1067     ret = silc_packet_write(fd, sock->outbuf);
1068
1069     /* If returned -2 could not write to connection now, will do
1070        it later. */
1071     if (ret == -2)
1072       return;
1073     
1074     /* Error */
1075     if (ret == -1)
1076       SILC_LOG_ERROR(("Packet dropped"));
1077
1078     /* The packet has been sent and now it is time to set the connection
1079        back to only for input. When there is again some outgoing data 
1080        available for this connection it will be set for output as well. 
1081        This call clears the output setting and sets it only for input. */
1082     SILC_CLIENT_SET_CONNECTION_FOR_INPUT(fd);
1083     SILC_UNSET_OUTBUF_PENDING(sock);
1084
1085     return;
1086   }
1087
1088   /* Packet receiving */
1089   if (type == SILC_TASK_READ) {
1090     SILC_LOG_DEBUG(("Reading data from connection"));
1091
1092     /* Allocate the incoming data buffer if not done already. */
1093     if (!sock->inbuf)
1094       sock->inbuf = silc_buffer_alloc(SILC_PACKET_DEFAULT_SIZE);
1095
1096     /* Read some data from connection */
1097     ret = silc_packet_read(fd, sock->inbuf);
1098     
1099     /* If returned -2 data was not available now, will read it later. */
1100     if (ret == -2)
1101       return;
1102     
1103     /* Error */
1104     if (ret == -1) {
1105       SILC_LOG_ERROR(("Packet dropped"));
1106       return;
1107     }
1108     
1109     /* EOF */
1110     if (ret == 0) {
1111       SILC_LOG_DEBUG(("Read EOF"));
1112
1113       /* If connection is disconnecting already we will finally
1114          close the connection */
1115       if (SILC_IS_DISCONNECTING(sock)) {
1116         silc_client_close_connection(client, sock);
1117         return;
1118       }
1119       
1120       silc_say(client, "Connection closed: premature EOF");
1121       SILC_LOG_DEBUG(("Premature EOF from connection %d", sock->sock));
1122
1123       silc_client_close_connection(client, sock);
1124       return;
1125     }
1126
1127     /* Check whether we received a whole packet. If reading went without
1128        errors we either read a whole packet or the read packet is 
1129        incorrect and will be dropped. */
1130     SILC_PACKET_LENGTH(sock->inbuf, packetlen, paddedlen);
1131     if (sock->inbuf->len < paddedlen || (packetlen < SILC_PACKET_MIN_LEN)) {
1132       SILC_LOG_DEBUG(("Received incorrect packet, dropped"));
1133       silc_buffer_clear(sock->inbuf);
1134       return;
1135     }
1136     
1137     /* Decrypt a packet coming from server connection */
1138     if (sock->type == SILC_SOCKET_TYPE_SERVER ||
1139         sock->type == SILC_SOCKET_TYPE_ROUTER) {
1140       SilcClientWindow win = (SilcClientWindow)sock->user_data;
1141       SilcClientInternalPacket *packet;
1142       int mac_len = 0;
1143
1144       if (win->hmac)
1145         mac_len = win->hmac->hash->hash->hash_len;
1146
1147       if (sock->inbuf->len - 2 > (paddedlen + mac_len)) {
1148         /* Received possibly many packets at once */
1149
1150         while(sock->inbuf->len > 0) {
1151           SILC_PACKET_LENGTH(sock->inbuf, packetlen, paddedlen);
1152           if (sock->inbuf->len < paddedlen) {
1153             SILC_LOG_DEBUG(("Received incorrect packet, dropped"));
1154             return;
1155           }
1156
1157           paddedlen += 2;
1158           packet = silc_calloc(1, sizeof(*packet));
1159           packet->client = client;
1160           packet->sock = sock;
1161           packet->packetdata = silc_calloc(1, sizeof(*packet->packetdata));
1162           packet->packetdata->buffer = silc_buffer_alloc(paddedlen + mac_len);
1163           silc_buffer_pull_tail(packet->packetdata->buffer, 
1164                                 SILC_BUFFER_END(packet->packetdata->buffer));
1165           silc_buffer_put(packet->packetdata->buffer, sock->inbuf->data, 
1166                           paddedlen + mac_len);
1167
1168           SILC_LOG_HEXDUMP(("Incoming packet, len %d", 
1169                             packet->packetdata->buffer->len),
1170                            packet->packetdata->buffer->data, 
1171                            packet->packetdata->buffer->len);
1172           SILC_LOG_DEBUG(("Packet from server %s, "
1173                           "server type %d, packet length %d", 
1174                           win->remote_host, win->remote_type, paddedlen));
1175
1176           /* If this packet is for the current active connection we will
1177              parse the packet right away to get it quickly on the screen.
1178              Otherwise, it will be parsed with a timeout as the data is
1179              for inactive window (which might not be visible at all). */
1180           if (SILC_CLIENT_IS_CURRENT_WIN(client, win)) {
1181             /* Parse it real soon */
1182             silc_task_register(client->timeout_queue, fd, 
1183                                silc_client_packet_parse,
1184                                (void *)packet, 0, 1, 
1185                                SILC_TASK_TIMEOUT,
1186                                SILC_TASK_PRI_NORMAL);
1187           } else {
1188             /* Parse the packet with timeout */
1189             silc_task_register(client->timeout_queue, fd, 
1190                                silc_client_packet_parse,
1191                                (void *)packet, 0, 200000, 
1192                                SILC_TASK_TIMEOUT,
1193                                SILC_TASK_PRI_NORMAL);
1194           }
1195
1196           /* Pull the packet from inbuf thus we'll get the next one
1197              in the inbuf. */
1198           silc_buffer_pull(sock->inbuf, paddedlen);
1199           if (win->hmac)
1200             silc_buffer_pull(sock->inbuf, mac_len);
1201         }
1202         silc_buffer_clear(sock->inbuf);
1203         return;
1204       } else {
1205         /* Received one packet */
1206         
1207         SILC_LOG_HEXDUMP(("An incoming packet, len %d", sock->inbuf->len),
1208                          sock->inbuf->data, sock->inbuf->len);
1209         SILC_LOG_DEBUG(("Packet from server %s, "
1210                         "server type %d, packet length %d", 
1211                         win->remote_host, win->remote_type, paddedlen));
1212         
1213         packet = silc_calloc(1, sizeof(*packet));
1214         packet->client = client;
1215         packet->sock = sock;
1216         packet->packetdata = silc_calloc(1, sizeof(*packet->packetdata));
1217         packet->packetdata->buffer = silc_buffer_copy(sock->inbuf);
1218         silc_buffer_clear(sock->inbuf);
1219
1220         /* If this packet is for the current active connection we will
1221            parse the packet right away to get it quickly on the screen.
1222            Otherwise, it will be parsed with a timeout as the data is
1223            for inactive window (which might not be visible at all). */
1224         if (SILC_CLIENT_IS_CURRENT_WIN(client, win)) {
1225           /* Parse it real soon */
1226           silc_task_register(client->timeout_queue, fd, 
1227                              silc_client_packet_parse,
1228                              (void *)packet, 0, 1, 
1229                              SILC_TASK_TIMEOUT,
1230                              SILC_TASK_PRI_NORMAL);
1231           return;
1232         } else {
1233           /* Parse the packet with timeout */
1234           silc_task_register(client->timeout_queue, fd, 
1235                              silc_client_packet_parse,
1236                              (void *)packet, 0, 200000, 
1237                              SILC_TASK_TIMEOUT,
1238                              SILC_TASK_PRI_NORMAL);
1239           return;
1240         }
1241       }
1242     }
1243   }
1244   
1245   SILC_LOG_ERROR(("Weird, nothing happened - ignoring"));
1246 }
1247
1248 /* Checks MAC in the packet. Returns TRUE if MAC is Ok. This is called
1249    after packet has been totally decrypted and parsed. */
1250
1251 static int silc_client_packet_check_mac(SilcClient client,
1252                                         SilcSocketConnection sock,
1253                                         SilcBuffer buffer)
1254 {
1255   SilcClientWindow win = (SilcClientWindow)sock->user_data;
1256
1257   /* Check MAC */
1258   if (win->hmac) {
1259     int headlen = buffer->data - buffer->head, mac_len;
1260     unsigned char *packet_mac, mac[32];
1261     
1262     SILC_LOG_DEBUG(("Verifying MAC"));
1263
1264     mac_len = win->hmac->hash->hash->hash_len;
1265
1266     silc_buffer_push(buffer, headlen);
1267
1268     /* Take mac from packet */
1269     packet_mac = buffer->tail;
1270     
1271     /* Make MAC and compare */
1272     memset(mac, 0, sizeof(mac));
1273     silc_hmac_make_with_key(win->hmac, 
1274                             buffer->data, buffer->len,
1275                             win->hmac_key, win->hmac_key_len, mac);
1276 #if 0
1277     SILC_LOG_HEXDUMP(("PMAC"), packet_mac, mac_len);
1278     SILC_LOG_HEXDUMP(("CMAC"), mac, mac_len);
1279 #endif
1280     if (memcmp(mac, packet_mac, mac_len)) {
1281       SILC_LOG_DEBUG(("MAC failed"));
1282       return FALSE;
1283     }
1284     
1285     SILC_LOG_DEBUG(("MAC is Ok"));
1286     memset(mac, 0, sizeof(mac));
1287
1288     silc_buffer_pull(buffer, headlen);
1289   }
1290   
1291   return TRUE;
1292 }
1293
1294 /* Decrypts rest of the packet (after decrypting just the SILC header).
1295    After calling this function the packet is ready to be parsed by calling 
1296    silc_packet_parse. */
1297
1298 static int silc_client_packet_decrypt_rest(SilcClient client, 
1299                                            SilcSocketConnection sock,
1300                                            SilcBuffer buffer)
1301 {
1302   SilcClientWindow win = (SilcClientWindow)sock->user_data;
1303   unsigned int mac_len = 0;
1304   
1305   /* Decrypt */
1306   if (win && win->receive_key) {
1307
1308     /* Pull MAC from packet before decryption */
1309     if (win->hmac) {
1310       mac_len = win->hmac->hash->hash->hash_len;
1311       if ((buffer->len - mac_len) > SILC_PACKET_MIN_LEN) {
1312         silc_buffer_push_tail(buffer, mac_len);
1313       } else {
1314         SILC_LOG_DEBUG(("Bad MAC length in packet, packet dropped"));
1315         return FALSE;
1316       }
1317     }
1318
1319     SILC_LOG_DEBUG(("Decrypting rest of the packet"));
1320
1321     /* Decrypt rest of the packet */
1322     silc_buffer_pull(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
1323     silc_packet_decrypt(win->receive_key, buffer, buffer->len);
1324     silc_buffer_push(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
1325
1326     SILC_LOG_HEXDUMP(("Fully decrypted packet, len %d", buffer->len),
1327                      buffer->data, buffer->len);
1328   }
1329
1330   return TRUE;
1331 }
1332
1333 /* Decrypts rest of the SILC Packet header that has been decrypted partly
1334    already. This decrypts the padding of the packet also.  After calling 
1335    this function the packet is ready to be parsed by calling function 
1336    silc_packet_parse. This is used in special packet reception. */
1337
1338 static int silc_client_packet_decrypt_rest_special(SilcClient client, 
1339                                                   SilcSocketConnection sock,
1340                                                   SilcBuffer buffer)
1341 {
1342   SilcClientWindow win = (SilcClientWindow)sock->user_data;
1343   unsigned int mac_len = 0;
1344
1345   /* Decrypt rest of the header plus padding */
1346   if (win && win->receive_key) {
1347     unsigned short truelen, len1, len2, padlen;
1348
1349     /* Pull MAC from packet before decryption */
1350     if (win->hmac) {
1351       mac_len = win->hmac->hash->hash->hash_len;
1352       if ((buffer->len - mac_len) > SILC_PACKET_MIN_LEN) {
1353         silc_buffer_push_tail(buffer, mac_len);
1354       } else {
1355         SILC_LOG_DEBUG(("Bad MAC length in packet, packet dropped"));
1356         return FALSE;
1357       }
1358     }
1359   
1360     SILC_LOG_DEBUG(("Decrypting rest of the header"));
1361
1362     SILC_GET16_MSB(len1, &buffer->data[4]);
1363     SILC_GET16_MSB(len2, &buffer->data[6]);
1364
1365     truelen = SILC_PACKET_HEADER_LEN + len1 + len2;
1366     padlen = SILC_PACKET_PADLEN(truelen);
1367     len1 = (truelen + padlen) - (SILC_PACKET_MIN_HEADER_LEN - 2);
1368
1369     silc_buffer_pull(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
1370     SILC_LOG_HEXDUMP(("XXX"), buffer->data, buffer->len);
1371     silc_packet_decrypt(win->receive_key, buffer, len1);
1372     silc_buffer_push(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
1373     SILC_LOG_HEXDUMP(("XXX"), buffer->data, buffer->len);
1374   }
1375
1376   return TRUE;
1377 }
1378
1379 /* Parses whole packet, received earlier. */
1380
1381 SILC_TASK_CALLBACK(silc_client_packet_parse)
1382 {
1383   SilcClientInternalPacket *packet = (SilcClientInternalPacket *)context;
1384   SilcBuffer buffer = packet->packetdata->buffer;
1385   SilcClient client = packet->client;
1386   SilcSocketConnection sock = packet->sock;
1387   SilcClientWindow win = (SilcClientWindow)sock->user_data;
1388   int ret;
1389
1390   SILC_LOG_DEBUG(("Start"));
1391
1392   /* Decrypt start of the packet header */
1393   if (win && win->receive_key)
1394     silc_packet_decrypt(win->receive_key, buffer, SILC_PACKET_MIN_HEADER_LEN);
1395
1396   /* If the packet type is not any special type lets decrypt rest
1397      of the packet here. */
1398   if (buffer->data[3] != SILC_PACKET_CHANNEL_MESSAGE &&
1399       buffer->data[3] != SILC_PACKET_PRIVATE_MESSAGE) {
1400   normal:
1401     /* Normal packet, decrypt rest of the packet */
1402     if (!silc_client_packet_decrypt_rest(client, sock, buffer))
1403       goto out;
1404
1405     /* Parse the packet. Packet type is returned. */
1406     ret = silc_packet_parse(packet->packetdata);
1407     if (ret == SILC_PACKET_NONE)
1408       goto out;
1409
1410     /* Check MAC */
1411     if (!silc_client_packet_check_mac(client, sock, buffer))
1412       goto out;
1413   } else {
1414     /* If private message key is not set for private message it is
1415        handled as normal packet. Go back up. */
1416     if (buffer->data[3] == SILC_PACKET_PRIVATE_MESSAGE &&
1417         !(buffer->data[2] & SILC_PACKET_FLAG_PRIVMSG_KEY))
1418       goto normal;
1419
1420     /* Packet requires special handling, decrypt rest of the header.
1421        This only decrypts. This does not do any MAC checking, it must
1422        be done individually later when doing the special processing. */
1423     silc_client_packet_decrypt_rest_special(client, sock, buffer);
1424
1425     /* Parse the packet header in special way as this is "special"
1426        packet type. */
1427     ret = silc_packet_parse_special(packet->packetdata);
1428     if (ret == SILC_PACKET_NONE)
1429       goto out;
1430   }
1431
1432   /* Parse the incoming packet type */
1433   silc_client_packet_parse_type(client, sock, packet->packetdata);
1434
1435  out:
1436   silc_buffer_clear(packet->packetdata->buffer);
1437   silc_free(packet->packetdata);
1438   silc_free(packet);
1439 }
1440
1441 /* Parses the packet type and calls what ever routines the packet type
1442    requires. This is done for all incoming packets. */
1443
1444 void silc_client_packet_parse_type(SilcClient client, 
1445                                    SilcSocketConnection sock,
1446                                    SilcPacketContext *packet)
1447 {
1448   SilcBuffer buffer = packet->buffer;
1449   SilcPacketType type = packet->type;
1450
1451   SILC_LOG_DEBUG(("Parsing packet type %d", type));
1452
1453   /* Parse the packet type */
1454   switch(type) {
1455   case SILC_PACKET_DISCONNECT:
1456     silc_client_disconnected_by_server(client, sock, buffer);
1457     break;
1458   case SILC_PACKET_SUCCESS:
1459     /*
1460      * Success received for something. For now we can have only
1461      * one protocol for connection executing at once hence this
1462      * success message is for whatever protocol is executing currently.
1463      */
1464     if (sock->protocol) {
1465       sock->protocol->execute(client->timeout_queue, 0,
1466                               sock->protocol, sock->sock, 0, 0);
1467     }
1468     break;
1469   case SILC_PACKET_FAILURE:
1470     /*
1471      * Failure received for some protocol. Set the protocol state to 
1472      * error and call the protocol callback. This fill cause error on
1473      * protocol and it will call the final callback.
1474      */
1475     if (sock->protocol) {
1476       sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
1477       sock->protocol->execute(client->timeout_queue, 0,
1478                               sock->protocol, sock->sock, 0, 0);
1479     }
1480     break;
1481   case SILC_PACKET_REJECT:
1482     break;
1483
1484   case SILC_PACKET_NOTIFY:
1485     /*
1486      * Received notify message 
1487      */
1488     silc_client_notify_by_server(client, sock, buffer);
1489     break;
1490
1491   case SILC_PACKET_ERROR:
1492     /*
1493      * Received error message
1494      */
1495     silc_client_error_by_server(client, sock, buffer);
1496     break;
1497
1498   case SILC_PACKET_CHANNEL_MESSAGE:
1499     /*
1500      * Received message to (from, actually) a channel
1501      */
1502     silc_client_channel_message(client, sock, packet);
1503     break;
1504   case SILC_PACKET_CHANNEL_KEY:
1505     /*
1506      * Received key for a channel. By receiving this key the client will be
1507      * able to talk to the channel it has just joined. This can also be
1508      * a new key for existing channel as keys expire peridiocally.
1509      */
1510     silc_client_receive_channel_key(client, sock, buffer);
1511     break;
1512
1513   case SILC_PACKET_PRIVATE_MESSAGE:
1514     /*
1515      * Received private message
1516      */
1517     {
1518       SilcClientCommandReplyContext ctx;
1519       ctx = silc_calloc(1, sizeof(*ctx));
1520       ctx->client = client;
1521       ctx->sock = sock;
1522       ctx->context = buffer;    /* kludge */
1523       silc_client_command_reply_msg((void *)ctx);
1524     }
1525     break;
1526   case SILC_PACKET_PRIVATE_MESSAGE_KEY:
1527     /*
1528      * Received private message key
1529      */
1530     break;
1531
1532   case SILC_PACKET_COMMAND_REPLY:
1533     /*
1534      * Recived reply for a command
1535      */
1536     silc_client_command_reply_process(client, sock, packet);
1537     break;
1538
1539   case SILC_PACKET_KEY_EXCHANGE:
1540     if (sock->protocol) {
1541       SilcClientKEInternalContext *proto_ctx = 
1542         (SilcClientKEInternalContext *)sock->protocol->context;
1543
1544       proto_ctx->packet = buffer;
1545       proto_ctx->dest_id_type = packet->src_id_type;
1546       proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_type);
1547
1548       /* Let the protocol handle the packet */
1549       sock->protocol->execute(client->timeout_queue, 0,
1550                               sock->protocol, sock->sock, 0, 0);
1551     } else {
1552       SILC_LOG_ERROR(("Received Key Exchange packet but no key exchange "
1553                       "protocol active, packet dropped."));
1554
1555       /* XXX Trigger KE protocol?? Rekey actually! */
1556     }
1557     break;
1558
1559   case SILC_PACKET_KEY_EXCHANGE_1:
1560     if (sock->protocol) {
1561
1562     } else {
1563       SILC_LOG_ERROR(("Received Key Exchange 1 packet but no key exchange "
1564                       "protocol active, packet dropped."));
1565     }
1566     break;
1567   case SILC_PACKET_KEY_EXCHANGE_2:
1568     if (sock->protocol) {
1569       SilcClientKEInternalContext *proto_ctx = 
1570         (SilcClientKEInternalContext *)sock->protocol->context;
1571
1572       if (proto_ctx->packet)
1573         silc_buffer_free(proto_ctx->packet);
1574
1575       proto_ctx->packet = buffer;
1576       proto_ctx->dest_id_type = packet->src_id_type;
1577       proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_type);
1578
1579       /* Let the protocol handle the packet */
1580       sock->protocol->execute(client->timeout_queue, 0,
1581                               sock->protocol, sock->sock, 0, 0);
1582     } else {
1583       SILC_LOG_ERROR(("Received Key Exchange 2 packet but no key exchange "
1584                       "protocol active, packet dropped."));
1585     }
1586     break;
1587
1588   case SILC_PACKET_NEW_ID:
1589     {
1590       /*
1591        * Received new ID from server. This packet is received at
1592        * the connection to the server.  New ID is also received when 
1593        * user changes nickname but in that case the new ID is received
1594        * as command reply and not as this packet type.
1595        */
1596       unsigned char *id_string;
1597       unsigned short id_type;
1598       
1599       silc_buffer_unformat(buffer,
1600                            SILC_STR_UI_SHORT(&id_type),
1601                            SILC_STR_UI16_STRING_ALLOC(&id_string),
1602                            SILC_STR_END);
1603       
1604       if ((SilcIdType)id_type != SILC_ID_CLIENT)
1605         break;
1606
1607       silc_client_receive_new_id(client, sock, id_string);
1608       silc_free(id_string);
1609       break;
1610     }
1611
1612   default:
1613     SILC_LOG_DEBUG(("Incorrect packet type %d, packet dropped", type));
1614     break;
1615   }
1616 }
1617
1618 /* Internal routine that sends packet or marks packet to be sent. This
1619    is used directly only in special cases. Normal cases should use
1620    silc_server_packet_send. Returns < 0 on error. */
1621
1622 static int silc_client_packet_send_real(SilcClient client,
1623                                         SilcSocketConnection sock,
1624                                         int force_send)
1625 {
1626   /* Send now if forced to do so */
1627   if (force_send == TRUE) {
1628     int ret;
1629     SILC_LOG_DEBUG(("Forcing packet send, packet sent immediately"));
1630     ret = silc_packet_write(sock->sock, sock->outbuf);
1631
1632     if (ret == -1)
1633       SILC_LOG_ERROR(("Packet dropped"));
1634     if (ret != -2)
1635       return ret;
1636
1637     SILC_LOG_DEBUG(("Could not force the send, packet put to queue"));
1638   }  
1639
1640   SILC_LOG_DEBUG(("Packet in queue"));
1641
1642   /* Mark that there is some outgoing data available for this connection. 
1643      This call sets the connection both for input and output (the input
1644      is set always and this call keeps the input setting, actually). 
1645      Actual data sending is performed by silc_client_packet_process. */
1646   SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(sock->sock);
1647
1648   /* Mark to socket that data is pending in outgoing buffer. This flag
1649      is needed if new data is added to the buffer before the earlier
1650      put data is sent to the network. */
1651   SILC_SET_OUTBUF_PENDING(sock);
1652
1653   return 0;
1654 }
1655
1656 /* Prepare outgoing data buffer for packet sending. */
1657
1658 static void silc_client_packet_send_prepare(SilcClient client,
1659                                             SilcSocketConnection sock,
1660                                             unsigned int header_len,
1661                                             unsigned int padlen,
1662                                             unsigned int data_len)
1663 {
1664   int totlen, oldlen;
1665
1666   totlen = header_len + padlen + data_len;
1667
1668   /* Prepare the outgoing buffer for packet sending. */
1669   if (!sock->outbuf) {
1670     /* Allocate new buffer. This is done only once per connection. */
1671     SILC_LOG_DEBUG(("Allocating outgoing data buffer"));
1672     
1673     sock->outbuf = silc_buffer_alloc(SILC_PACKET_DEFAULT_SIZE);
1674     silc_buffer_pull_tail(sock->outbuf, totlen);
1675     silc_buffer_pull(sock->outbuf, header_len + padlen);
1676   } else {
1677     if (SILC_IS_OUTBUF_PENDING(sock)) {
1678       /* There is some pending data in the buffer. */
1679
1680       if ((sock->outbuf->end - sock->outbuf->tail) < data_len) {
1681         SILC_LOG_DEBUG(("Reallocating outgoing data buffer"));
1682         /* XXX: not done yet */
1683       }
1684       oldlen = sock->outbuf->len;
1685       silc_buffer_pull_tail(sock->outbuf, totlen);
1686       silc_buffer_pull(sock->outbuf, header_len + padlen + oldlen);
1687     } else {
1688       /* Buffer is free for use */
1689       silc_buffer_clear(sock->outbuf);
1690       silc_buffer_pull_tail(sock->outbuf, totlen);
1691       silc_buffer_pull(sock->outbuf, header_len + padlen);
1692     }
1693   }
1694 }
1695
1696 /* Sends packet. This doesn't actually send the packet instead it assembles
1697    it and marks it to be sent. However, if force_send is TRUE the packet
1698    is sent immediately. if dst_id, cipher and hmac are NULL those parameters
1699    will be derived from sock argument. Otherwise the valid arguments sent
1700    are used. */
1701
1702 void silc_client_packet_send(SilcClient client, 
1703                              SilcSocketConnection sock,
1704                              SilcPacketType type, 
1705                              void *dst_id,
1706                              SilcIdType dst_id_type,
1707                              SilcCipher cipher,
1708                              SilcHmac hmac,
1709                              unsigned char *data, 
1710                              unsigned int data_len, 
1711                              int force_send)
1712 {
1713   SilcPacketContext packetdata;
1714   unsigned char *hmac_key = NULL;
1715   unsigned int hmac_key_len = 0;
1716   unsigned char mac[32];
1717   unsigned int mac_len = 0;
1718
1719   SILC_LOG_DEBUG(("Sending packet, type %d", type));
1720
1721   /* Get data used in the packet sending, keys and stuff */
1722   if ((!cipher || !hmac || !dst_id) && sock->user_data) {
1723     if (!cipher && ((SilcClientWindow)sock->user_data)->send_key)
1724       cipher = ((SilcClientWindow)sock->user_data)->send_key;
1725     if (!hmac && ((SilcClientWindow)sock->user_data)->hmac) {
1726       hmac = ((SilcClientWindow)sock->user_data)->hmac;
1727       mac_len = hmac->hash->hash->hash_len;
1728       hmac_key = ((SilcClientWindow)sock->user_data)->hmac_key;
1729       hmac_key_len = ((SilcClientWindow)sock->user_data)->hmac_key_len;
1730     }
1731     if (!dst_id && ((SilcClientWindow)sock->user_data)->remote_id) {
1732       dst_id = ((SilcClientWindow)sock->user_data)->remote_id;
1733       dst_id_type = SILC_ID_SERVER;
1734     }
1735   }
1736
1737   /* Set the packet context pointers */
1738   packetdata.flags = 0;
1739   packetdata.type = type;
1740   if (((SilcClientWindow)sock->user_data)->local_id_data)
1741     packetdata.src_id = ((SilcClientWindow)sock->user_data)->local_id_data;
1742   else 
1743     packetdata.src_id = silc_calloc(SILC_ID_CLIENT_LEN, sizeof(unsigned char));
1744   packetdata.src_id_len = SILC_ID_CLIENT_LEN;
1745   packetdata.src_id_type = SILC_ID_CLIENT;
1746   if (dst_id) {
1747     packetdata.dst_id = silc_id_id2str(dst_id, dst_id_type);
1748     packetdata.dst_id_len = silc_id_get_len(dst_id_type);
1749     packetdata.dst_id_type = dst_id_type;
1750   } else {
1751     packetdata.dst_id = NULL;
1752     packetdata.dst_id_len = 0;
1753     packetdata.dst_id_type = SILC_ID_NONE;
1754   }
1755   packetdata.rng = client->rng;
1756   packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN + 
1757     packetdata.src_id_len + packetdata.dst_id_len;
1758   packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen);
1759
1760   /* Prepare outgoing data buffer for packet sending */
1761   silc_client_packet_send_prepare(client, sock, 
1762                                   SILC_PACKET_HEADER_LEN +
1763                                   packetdata.src_id_len + 
1764                                   packetdata.dst_id_len,
1765                                   packetdata.padlen,
1766                                   data_len);
1767
1768   SILC_LOG_DEBUG(("Putting data to outgoing buffer, len %d", data_len));
1769
1770   packetdata.buffer = sock->outbuf;
1771
1772   /* Put the data to the buffer */
1773   if (data && data_len)
1774     silc_buffer_put(sock->outbuf, data, data_len);
1775
1776   /* Create the outgoing packet */
1777   silc_packet_assemble(&packetdata);
1778
1779   /* Compute MAC of the packet */
1780   if (hmac) {
1781     silc_hmac_make_with_key(hmac, sock->outbuf->data, sock->outbuf->len,
1782                             hmac_key, hmac_key_len, mac);
1783     silc_buffer_put_tail(sock->outbuf, mac, mac_len);
1784     memset(mac, 0, sizeof(mac));
1785   }
1786
1787   /* Encrypt the packet */
1788   if (cipher)
1789     silc_packet_encrypt(cipher, sock->outbuf, sock->outbuf->len);
1790
1791   /* Pull MAC into the visible data area */
1792   if (hmac)
1793     silc_buffer_pull_tail(sock->outbuf, mac_len);
1794
1795   SILC_LOG_HEXDUMP(("Packet, len %d", sock->outbuf->len),
1796                    sock->outbuf->data, sock->outbuf->len);
1797
1798   /* Now actually send the packet */
1799   silc_client_packet_send_real(client, sock, force_send);
1800 }
1801
1802 /* Sends packet to a channel. Packet to channel is always encrypted
1803    differently from "normal" packets. SILC header of the packet is 
1804    encrypted with the next receiver's key and the rest of the packet is
1805    encrypted with the channel specific key. Padding and HMAC is computed
1806    with the next receiver's key. */
1807
1808 void silc_client_packet_send_to_channel(SilcClient client, 
1809                                         SilcSocketConnection sock,
1810                                         SilcChannelEntry channel,
1811                                         unsigned char *data, 
1812                                         unsigned int data_len, 
1813                                         int force_send)
1814 {
1815   int i;
1816   SilcClientWindow win = (SilcClientWindow)sock->user_data;
1817   SilcBuffer payload;
1818   SilcPacketContext packetdata;
1819   unsigned char *hmac_key = NULL;
1820   unsigned int hmac_key_len = 0;
1821   unsigned char mac[32];
1822   unsigned int mac_len = 0;
1823   unsigned char *id_string;
1824   SilcCipher cipher;
1825   SilcHmac hmac;
1826
1827   SILC_LOG_DEBUG(("Sending packet to channel"));
1828
1829   if (!channel || !channel->key) {
1830     silc_say(client, "Cannot talk to channel: key does not exist");
1831     return;
1832   }
1833
1834   /* Generate IV */
1835   if (!channel->iv)
1836     for (i = 0; i < 16; i++)
1837       channel->iv[i] = silc_rng_get_byte(client->rng);
1838   else
1839     silc_hash_make(client->md5hash, channel->iv, 16, channel->iv);
1840
1841   /* Encode the channel payload */
1842   payload = silc_channel_encode_payload(strlen(win->nickname), win->nickname,
1843                                         data_len, data, 16, channel->iv, 
1844                                         client->rng);
1845   if (!payload) {
1846     silc_say(client, 
1847              "Error: Could not create packet to be sent to the channel");
1848     return;
1849   }
1850
1851   /* Get data used in packet header encryption, keys and stuff. Rest
1852      of the packet (the payload) is, however, encrypted with the 
1853      specified channel key. */
1854   cipher = win->send_key;
1855   hmac = win->hmac;
1856   mac_len = hmac->hash->hash->hash_len;
1857   hmac_key = win->hmac_key;
1858   hmac_key_len = win->hmac_key_len;
1859   id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
1860
1861   /* Set the packet context pointers. The destination ID is always
1862      the Channel ID of the channel. Server and router will handle the
1863      distribution of the packet. */
1864   packetdata.flags = 0;
1865   packetdata.type = SILC_PACKET_CHANNEL_MESSAGE;
1866   packetdata.src_id = win->local_id_data;
1867   packetdata.src_id_len = SILC_ID_CLIENT_LEN;
1868   packetdata.src_id_type = SILC_ID_CLIENT;
1869   packetdata.dst_id = id_string;
1870   packetdata.dst_id_len = SILC_ID_CHANNEL_LEN;
1871   packetdata.dst_id_type = SILC_ID_CHANNEL;
1872   packetdata.rng = client->rng;
1873   packetdata.truelen = payload->len + SILC_PACKET_HEADER_LEN + 
1874     packetdata.src_id_len + packetdata.dst_id_len;
1875   packetdata.padlen = SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
1876                                           packetdata.src_id_len +
1877                                           packetdata.dst_id_len));
1878
1879   /* Prepare outgoing data buffer for packet sending */
1880   silc_client_packet_send_prepare(client, sock, 
1881                                   SILC_PACKET_HEADER_LEN +
1882                                   packetdata.src_id_len + 
1883                                   packetdata.dst_id_len,
1884                                   packetdata.padlen,
1885                                   payload->len);
1886
1887   packetdata.buffer = sock->outbuf;
1888
1889   /* Encrypt payload of the packet. This is encrypted with the channel key. */
1890   channel->channel_key->cipher->encrypt(channel->channel_key->context,
1891                                         payload->data, payload->data,
1892                                         payload->len - 16, /* -IV_LEN */
1893                                         channel->iv);
1894
1895   SILC_LOG_HEXDUMP(("XXX"), payload->data, payload->len);
1896       
1897   /* Put the actual encrypted payload data into the buffer. */
1898   silc_buffer_put(sock->outbuf, payload->data, payload->len);
1899
1900   /* Create the outgoing packet */
1901   silc_packet_assemble(&packetdata);
1902
1903   /* Compute MAC of the packet */
1904   silc_hmac_make_with_key(hmac, sock->outbuf->data, sock->outbuf->len,
1905                           hmac_key, hmac_key_len, mac);
1906   silc_buffer_put_tail(sock->outbuf, mac, mac_len);
1907   memset(mac, 0, sizeof(mac));
1908
1909       SILC_LOG_HEXDUMP(("XXX"), sock->outbuf->data, sock->outbuf->len);
1910       
1911   /* Encrypt the header and padding of the packet. This is encrypted 
1912      with normal session key shared with our server. */
1913   silc_packet_encrypt(cipher, sock->outbuf, SILC_PACKET_HEADER_LEN + 
1914                       packetdata.src_id_len + packetdata.dst_id_len +
1915                       packetdata.padlen);
1916
1917   /* Pull MAC into the visible data area */
1918   silc_buffer_pull_tail(sock->outbuf, mac_len);
1919
1920   SILC_LOG_HEXDUMP(("Packet to channel, len %d", sock->outbuf->len),
1921                    sock->outbuf->data, sock->outbuf->len);
1922
1923   /* Now actually send the packet */
1924   silc_client_packet_send_real(client, sock, force_send);
1925   silc_buffer_free(payload);
1926   silc_free(id_string);
1927 }
1928
1929 /* Sends private message to remote client. If private message key has
1930    not been set with this client then the message will be encrypted using
1931    normal session keys. Private messages are special packets in SILC
1932    network hence we need this own function for them. This is similiar
1933    to silc_client_packet_send_to_channel except that we send private
1934    message. */
1935
1936 void silc_client_packet_send_private_message(SilcClient client,
1937                                              SilcSocketConnection sock,
1938                                              SilcClientEntry client_entry,
1939                                              unsigned char *data, 
1940                                              unsigned int data_len, 
1941                                              int force_send)
1942 {
1943   SilcClientWindow win = (SilcClientWindow)sock->user_data;
1944   SilcBuffer buffer;
1945   SilcPacketContext packetdata;
1946   unsigned char *hmac_key = NULL;
1947   unsigned int hmac_key_len = 0;
1948   unsigned char mac[32];
1949   unsigned int mac_len = 0;
1950   unsigned int nick_len;
1951   SilcCipher cipher;
1952   SilcHmac hmac;
1953
1954   SILC_LOG_DEBUG(("Sending private message"));
1955
1956   /* Create private message payload */
1957   nick_len = strlen(client->current_win->nickname);
1958   buffer = silc_buffer_alloc(2 + nick_len + data_len);
1959   silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer));
1960   silc_buffer_format(buffer,
1961                      SILC_STR_UI_SHORT(nick_len),
1962                      SILC_STR_UI_XNSTRING(client->current_win->nickname,
1963                                           nick_len),
1964                      SILC_STR_UI_XNSTRING(data, data_len),
1965                      SILC_STR_END);
1966
1967   /* If we don't have private message specific key then private messages
1968      are just as any normal packet thus call normal packet sending.  If
1969      the key exist then the encryption process is a bit different and
1970      will be done in the rest of this function. */
1971   if (!client_entry->send_key) {
1972     silc_client_packet_send(client, sock, SILC_PACKET_PRIVATE_MESSAGE,
1973                             client_entry->id, SILC_ID_CLIENT, NULL, NULL,
1974                             buffer->data, buffer->len, force_send);
1975     goto out;
1976   }
1977
1978   /* We have private message specific key */
1979
1980   /* Get data used in the encryption */
1981   cipher = client_entry->send_key;
1982   hmac = win->hmac;
1983   mac_len = hmac->hash->hash->hash_len;
1984   hmac_key = win->hmac_key;
1985   hmac_key_len = win->hmac_key_len;
1986
1987   /* Set the packet context pointers. */
1988   packetdata.flags = 0;
1989   packetdata.type = SILC_PACKET_PRIVATE_MESSAGE;
1990   packetdata.src_id = win->local_id_data;
1991   packetdata.src_id_len = SILC_ID_CLIENT_LEN;
1992   packetdata.src_id_type = SILC_ID_CLIENT;
1993   if (client_entry)
1994     packetdata.dst_id = silc_id_id2str(client_entry->id, SILC_ID_CLIENT);
1995   else
1996     packetdata.dst_id = win->local_id_data;
1997   packetdata.dst_id_len = SILC_ID_CLIENT_LEN;
1998   packetdata.dst_id_type = SILC_ID_CLIENT;
1999   packetdata.rng = client->rng;
2000   packetdata.truelen = buffer->len + SILC_PACKET_HEADER_LEN + 
2001     packetdata.src_id_len + packetdata.dst_id_len;
2002   packetdata.padlen = SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
2003                                           packetdata.src_id_len +
2004                                           packetdata.dst_id_len));
2005
2006   /* Prepare outgoing data buffer for packet sending */
2007   silc_client_packet_send_prepare(client, sock, 
2008                                   SILC_PACKET_HEADER_LEN +
2009                                   packetdata.src_id_len + 
2010                                   packetdata.dst_id_len,
2011                                   packetdata.padlen,
2012                                   buffer->len);
2013
2014   packetdata.buffer = sock->outbuf;
2015
2016   /* Encrypt payload of the packet. Encrypt with private message specific
2017      key if it exist, otherwise with session key. */
2018   cipher->cipher->encrypt(cipher->context, buffer->data, buffer->data,
2019                           buffer->len, cipher->iv);
2020       
2021   /* Put the actual encrypted payload data into the buffer. */
2022   silc_buffer_put(sock->outbuf, buffer->data, buffer->len);
2023
2024   /* Create the outgoing packet */
2025   silc_packet_assemble(&packetdata);
2026
2027   /* Compute MAC of the packet */
2028   silc_hmac_make_with_key(hmac, sock->outbuf->data, sock->outbuf->len,
2029                           hmac_key, hmac_key_len, mac);
2030   silc_buffer_put_tail(sock->outbuf, mac, mac_len);
2031   memset(mac, 0, sizeof(mac));
2032
2033   SILC_LOG_HEXDUMP(("XXX"), sock->outbuf->data, sock->outbuf->len);
2034       
2035   /* Encrypt the header and padding of the packet. */
2036   silc_packet_encrypt(cipher, sock->outbuf, SILC_PACKET_HEADER_LEN + 
2037                       packetdata.src_id_len + packetdata.dst_id_len +
2038                       packetdata.padlen);
2039
2040   /* Pull MAC into the visible data area */
2041   silc_buffer_pull_tail(sock->outbuf, mac_len);
2042
2043   SILC_LOG_HEXDUMP(("Private message packet, len %d", sock->outbuf->len),
2044                    sock->outbuf->data, sock->outbuf->len);
2045
2046   /* Now actually send the packet */
2047   silc_client_packet_send_real(client, sock, force_send);
2048   silc_free(packetdata.dst_id);
2049
2050  out:
2051   silc_free(buffer);
2052 }     
2053
2054 /* Closes connection to remote end. Free's all allocated data except
2055    for some information such as nickname etc. that are valid at all time. */
2056
2057 void silc_client_close_connection(SilcClient client,
2058                                   SilcSocketConnection sock)
2059 {
2060   SilcClientWindow win;
2061   int i;
2062
2063   /* We won't listen for this connection anymore */
2064   silc_schedule_unset_listen_fd(sock->sock);
2065
2066   /* Unregister all tasks */
2067   silc_task_unregister_by_fd(client->io_queue, sock->sock);
2068   silc_task_unregister_by_fd(client->timeout_queue, sock->sock);
2069
2070   /* Close the actual connection */
2071   silc_net_close_connection(sock->sock);
2072
2073   silc_say(client, "Closed connection to host %s", sock->hostname ?
2074            sock->hostname : sock->ip);
2075
2076   /* Free everything */
2077   if (sock->user_data) {
2078     win = (SilcClientWindow)sock->user_data;
2079
2080     /* Clear ID caches */
2081     for (i = 0; i < 96; i++)
2082       silc_idcache_del_all(&win->client_id_cache[i], 
2083                            win->client_id_cache_count[i]);
2084     for (i = 0; i < 96; i++)
2085       silc_idcache_del_all(&win->channel_id_cache[i], 
2086                            win->channel_id_cache_count[i]);
2087
2088     /* Free data */
2089     if (win->remote_host)
2090       silc_free(win->remote_host);
2091     if (win->local_id)
2092       silc_free(win->local_id);
2093     if (win->local_id_data)
2094       silc_free(win->local_id_data);
2095     if (win->send_key)
2096       silc_cipher_free(win->send_key);
2097     if (win->receive_key)
2098       silc_cipher_free(win->receive_key);
2099     if (win->public_key)
2100       silc_pkcs_free(win->public_key);
2101     if (win->hmac)
2102       silc_hmac_free(win->hmac);
2103     if (win->hmac_key) {
2104       memset(win->hmac_key, 0, win->hmac_key_len);
2105       silc_free(win->hmac_key);
2106     }
2107
2108     win->sock = NULL;
2109     win->remote_port = 0;
2110     win->remote_type = 0;
2111     win->send_key = NULL;
2112     win->receive_key = NULL;
2113     win->public_key = NULL;
2114     win->hmac = NULL;
2115     win->hmac_key = NULL;
2116     win->hmac_key_len = 0;
2117     win->local_id = NULL;
2118     win->local_id_data = NULL;
2119     win->remote_host = NULL;
2120   }
2121
2122   if (sock->protocol) {
2123     silc_protocol_free(sock->protocol);
2124     sock->protocol = NULL;
2125   }
2126   silc_socket_free(sock);
2127 }
2128
2129 /* Called when we receive disconnection packet from server. This 
2130    closes our end properly and displays the reason of the disconnection
2131    on the screen. */
2132
2133 void silc_client_disconnected_by_server(SilcClient client,
2134                                         SilcSocketConnection sock,
2135                                         SilcBuffer message)
2136 {
2137   char *msg;
2138
2139   SILC_LOG_DEBUG(("Server disconnected us, sock %d", sock->sock));
2140
2141   msg = silc_calloc(message->len + 1, sizeof(char));
2142   memcpy(msg, message->data, message->len);
2143   silc_say(client, msg);
2144   silc_free(msg);
2145
2146   SILC_SET_DISCONNECTED(sock);
2147   silc_client_close_connection(client, sock);
2148 }
2149
2150 /* Received error message from server. Display it on the screen. 
2151    We don't take any action what so ever of the error message. */
2152
2153 void silc_client_error_by_server(SilcClient client,
2154                                  SilcSocketConnection sock,
2155                                  SilcBuffer message)
2156 {
2157   char *msg;
2158
2159   msg = silc_calloc(message->len + 1, sizeof(char));
2160   memcpy(msg, message->data, message->len);
2161   silc_say(client, msg);
2162   silc_free(msg);
2163 }
2164
2165 /* Received notify message from server */
2166
2167 void silc_client_notify_by_server(SilcClient client,
2168                                   SilcSocketConnection sock,
2169                                   SilcBuffer message)
2170 {
2171   char *msg;
2172
2173   msg = silc_calloc(message->len + 1, sizeof(char));
2174   memcpy(msg, message->data, message->len);
2175   silc_say(client, msg);
2176   silc_free(msg);
2177 }
2178
2179 /* Processes the received new Client ID from server. Old Client ID is
2180    deleted from cache and new one is added. */
2181
2182 void silc_client_receive_new_id(SilcClient client,
2183                                 SilcSocketConnection sock,
2184                                 unsigned char *id_string)
2185 {
2186   SilcClientWindow win = (SilcClientWindow)sock->user_data;
2187   char *nickname = win->nickname;
2188
2189 #define CIDC(x) win->client_id_cache[(x) - 32]
2190 #define CIDCC(x) win->client_id_cache_count[(x) - 32]
2191
2192   /* Delete old ID from ID cache */
2193   silc_idcache_del_by_id(CIDC(nickname[0]), CIDCC(nickname[0]),
2194                          SILC_ID_CLIENT, win->local_id);
2195   
2196   /* Save the new ID */
2197   if (win->local_id)
2198     silc_free(win->local_id);
2199   win->local_id = silc_id_str2id(id_string, SILC_ID_CLIENT);
2200   if (win->local_id_data)
2201     silc_free(win->local_id_data);
2202   win->local_id_data = 
2203     silc_calloc(SILC_ID_CLIENT_LEN, sizeof(unsigned char));
2204   memcpy(win->local_id_data, id_string, SILC_ID_CLIENT_LEN);
2205   win->local_id_data_len = SILC_ID_CLIENT_LEN;
2206   if (!win->local_entry)
2207     win->local_entry = silc_calloc(1, sizeof(*win->local_entry));
2208   win->local_entry->nickname = win->nickname;
2209   win->local_entry->id = win->local_id;
2210   
2211   /* Put it to the ID cache */
2212   CIDCC(nickname[0]) = silc_idcache_add(&CIDC(nickname[0]), 
2213                                         CIDCC(nickname[0]),
2214                                         win->nickname, SILC_ID_CLIENT, 
2215                                         win->local_id, 
2216                                         (void *)win->local_entry);
2217 #undef CIDC
2218 #undef CIDCC
2219 }
2220
2221 /* Processed received Channel ID for a channel. This is called when client
2222    joins to channel and server replies with channel ID. The ID is cached. */
2223
2224 void silc_client_new_channel_id(SilcClient client,
2225                                 SilcSocketConnection sock,
2226                                 char *channel_name,
2227                                 unsigned int mode,
2228                                 unsigned char *id_string)
2229 {
2230   SilcClientWindow win = (SilcClientWindow)sock->user_data;
2231   SilcChannelID *id;
2232   SilcChannelEntry channel;
2233
2234   SILC_LOG_DEBUG(("New channel ID"));
2235
2236 #define CIDC(x) win->channel_id_cache[(x) - 32]
2237 #define CIDCC(x) win->channel_id_cache_count[(x) - 32]
2238
2239   id = silc_id_str2id(id_string, SILC_ID_CHANNEL);
2240   channel = silc_calloc(1, sizeof(*channel));
2241   channel->channel_name = channel_name;
2242   channel->id = id;
2243   channel->mode = mode;
2244   win->current_channel = channel;
2245   
2246   /* Put it to the ID cache */
2247   CIDCC(channel_name[0]) = silc_idcache_add(&CIDC(channel_name[0]), 
2248                                             CIDCC(channel_name[0]),
2249                                             channel_name, SILC_ID_CHANNEL, 
2250                                             id, (void *)channel);
2251 #undef CIDC
2252 #undef CIDCC
2253 }
2254
2255 /* Processes received key for channel. The received key will be used
2256    to protect the traffic on the channel for now on. Client must receive
2257    the key to the channel before talking on the channel is possible. 
2258    This is the key that server has generated, this is not the channel
2259    private key, it is entirely local setting. */
2260
2261 void silc_client_receive_channel_key(SilcClient client,
2262                                      SilcSocketConnection sock,
2263                                      SilcBuffer packet)
2264 {
2265   int i;
2266   unsigned char *id_string, *key, *cipher;
2267   unsigned int key_len;
2268   SilcClientWindow win = (SilcClientWindow)sock->user_data;
2269   SilcChannelID *id;
2270   SilcIDCache *id_cache = NULL;
2271   SilcChannelEntry channel;
2272   SilcChannelKeyPayload payload;
2273
2274   SILC_LOG_DEBUG(("Received key for channel"));
2275   
2276 #define CIDC(x) win->channel_id_cache[(x)]
2277 #define CIDCC(x) win->channel_id_cache_count[(x)]
2278
2279   payload = silc_channel_key_parse_payload(packet);
2280   if (!payload)
2281     return;
2282
2283   id_string = silc_channel_key_get_id(payload, NULL);
2284   if (!id_string) {
2285     silc_channel_key_free_payload(payload);
2286     return;
2287   }
2288   id = silc_id_str2id(id_string, SILC_ID_CHANNEL);
2289
2290   /* Find channel. XXX: This is bad and slow. */ 
2291   for (i = 0; i < 96; i++) {
2292     if (CIDC(i) == NULL)
2293       continue;
2294     if (silc_idcache_find_by_id(CIDC(i), CIDCC(i), (void *)id, 
2295                                 SILC_ID_CHANNEL, &id_cache))
2296       break;
2297   }
2298
2299  if (!id_cache)
2300     goto out;
2301
2302   /* Save the key */
2303   key = silc_channel_key_get_key(payload, &key_len);
2304   cipher = silc_channel_key_get_cipher(payload, NULL);
2305
2306   channel = (SilcChannelEntry)id_cache->context;
2307   channel->key_len = key_len;
2308   channel->key = silc_calloc(key_len, sizeof(*channel->key));
2309   memcpy(channel->key, key, key_len);
2310
2311   silc_cipher_alloc(cipher, &channel->channel_key);
2312   if (!channel->channel_key) {
2313     silc_say(client, "Cannot talk to channel: unsupported cipher %s", cipher);
2314     goto out;
2315   }
2316   channel->channel_key->cipher->set_key(channel->channel_key->context, 
2317                                         key, key_len);
2318
2319   /* Client is now joined to the channel */
2320   channel->on_channel = TRUE;
2321
2322  out:
2323   silc_free(id);
2324   silc_channel_key_free_payload(payload);
2325 #undef CIDC
2326 #undef CIDCC
2327 }
2328
2329 /* Process received message to a channel (or from a channel, really). This
2330    decrypts the channel message with channel specific key and parses the
2331    channel payload. Finally it displays the message on the screen. */
2332
2333 void silc_client_channel_message(SilcClient client, 
2334                                  SilcSocketConnection sock, 
2335                                  SilcPacketContext *packet)
2336 {
2337   int i;
2338   SilcClientWindow win = (SilcClientWindow)sock->user_data;
2339   SilcBuffer buffer = packet->buffer;
2340   SilcChannelPayload payload = NULL;
2341   SilcChannelID *id = NULL;
2342   SilcChannelEntry channel;
2343   SilcIDCache *id_cache = NULL;
2344
2345 #define CIDC(x) win->channel_id_cache[(x)]
2346 #define CIDCC(x) win->channel_id_cache_count[(x)]
2347
2348   /* Sanity checks */
2349   if (packet->dst_id_type != SILC_ID_CHANNEL)
2350     goto out;
2351
2352   id = silc_id_str2id(packet->dst_id, SILC_ID_CHANNEL);
2353
2354   /* Find the channel entry from channels on this window */
2355   for (i = 0; i < 96; i++) {
2356     if (CIDC(i) == NULL)
2357       continue;
2358     if (silc_idcache_find_by_id(CIDC(i), CIDCC(i), (void *)id, 
2359                                 SILC_ID_CHANNEL, &id_cache))
2360       break;
2361   }
2362
2363   if (!id_cache)
2364     goto out;
2365
2366   channel = (SilcChannelEntry)id_cache->context;
2367
2368   /* Decrypt the channel message payload. Push the IV out of the way,
2369      since it is not encrypted (after pushing buffer->tail has the IV). */
2370   silc_buffer_push_tail(buffer, 16);
2371   channel->channel_key->cipher->decrypt(channel->channel_key->context,
2372                                         buffer->data, buffer->data,
2373                                         buffer->len, buffer->tail);
2374   silc_buffer_pull_tail(buffer, 16);
2375
2376   /* Parse the channel message payload */
2377   payload = silc_channel_parse_payload(buffer);
2378   if (!payload)
2379     goto out;
2380
2381   /* Display the message on screen */
2382   if (packet->src_id_type == SILC_ID_CLIENT)
2383     /* Message from client */
2384     silc_print(client, "<%s> %s", silc_channel_get_nickname(payload, NULL),
2385                silc_channel_get_data(payload, NULL));
2386   else
2387     /* Message from server */
2388     silc_say(client, "%s", silc_channel_get_data(payload, NULL));
2389
2390  out:
2391   if (id)
2392     silc_free(id);
2393   if (payload)
2394     silc_channel_free_payload(payload);
2395 #undef CIDC
2396 #undef CIDCC
2397 }