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