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