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