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