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