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