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