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