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