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