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