5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2000 Pekka Riikonen
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.
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.
23 * Revision 1.13 2000/07/20 10:17:25 priikone
24 * Added dynamic protocol registering/unregistering support. The
25 * patch was provided by cras.
27 * Revision 1.12 2000/07/19 07:07:34 priikone
28 * Save packet on private message's command context.
30 * Revision 1.11 2000/07/18 12:20:39 priikone
31 * Added ^U functionality, clears input line (patch form cras).
33 * Revision 1.10 2000/07/18 06:53:15 priikone
34 * Allow partial command strings in comparison.
36 * Revision 1.9 2000/07/14 06:13:19 priikone
37 * Moved all the generic packet sending, encryption, reception,
38 * decryption and processing functions to library as they were
39 * duplicated code with the server. Now client uses the generic
40 * routines which is a lot cleaner.
42 * Revision 1.8 2000/07/12 05:56:32 priikone
43 * Major rewrite of ID Cache system. Support added for the new
46 * Revision 1.7 2000/07/10 05:40:33 priikone
49 * Revision 1.6 2000/07/07 06:54:16 priikone
50 * Print channel name when receiving channel message to non-current
53 * Revision 1.5 2000/07/06 07:14:36 priikone
54 * Fixes to NAMES command handling.
55 * Fixes when leaving from channel.
57 * Revision 1.4 2000/07/05 06:12:05 priikone
58 * Global cosmetic changes.
60 * Revision 1.3 2000/07/04 08:29:12 priikone
61 * Added support for PING command. The ping times are calculated
62 * and showed to the user.
64 * Revision 1.2 2000/07/03 05:49:48 priikone
65 * Implemented LEAVE command. Minor bug fixes.
67 * Revision 1.1.1.1 2000/06/27 11:36:56 priikone
68 * Imported from internal CVS/Added Log headers.
73 #include "clientincludes.h"
75 /* Static function prototypes */
76 static int silc_client_bad_keys(unsigned char key);
77 static void silc_client_clear_input(SilcClient client);
78 static void silc_client_process_message(SilcClient client);
79 static char *silc_client_parse_command(unsigned char *buffer);
81 /* Static task callback prototypes */
82 SILC_TASK_CALLBACK(silc_client_update_clock);
83 SILC_TASK_CALLBACK(silc_client_run_commands);
84 SILC_TASK_CALLBACK(silc_client_process_key_press);
85 SILC_TASK_CALLBACK(silc_client_connect_to_server_start);
86 SILC_TASK_CALLBACK(silc_client_connect_to_server_second);
87 SILC_TASK_CALLBACK(silc_client_connect_to_server_final);
88 SILC_TASK_CALLBACK(silc_client_packet_process);
89 SILC_TASK_CALLBACK(silc_client_packet_parse_real);
91 SilcClientWindow silc_client_create_main_window(SilcClient client);
92 SilcClientWindow silc_client_add_window(SilcClient client,
94 void silc_client_packet_parse(SilcPacketParserContext *parser_context);
95 void silc_client_packet_parse_type(SilcClient client,
96 SilcSocketConnection sock,
97 SilcPacketContext *packet);
98 void silc_client_private_message_process(SilcClient client,
99 SilcSocketConnection sock,
100 SilcPacketContext *packet);
102 /* Definitions from version.h */
103 extern char *silc_version;
104 extern char *silc_name;
105 extern char *silc_fullname;
107 /* Allocates new client object. This has to be done before client may
108 work. After calling this one must call silc_client_init to initialize
111 int silc_client_alloc(SilcClient *new_client)
114 *new_client = silc_calloc(1, sizeof(**new_client));
115 (*new_client)->input_buffer = NULL;
116 (*new_client)->screen = NULL;
117 (*new_client)->windows = NULL;
118 (*new_client)->windows_count = 0;
119 (*new_client)->current_win = NULL;
124 /* Free's client object */
126 void silc_client_free(SilcClient client)
133 /* Initializes the client. This makes all the necessary steps to make
134 the client ready to be run. One must call silc_client_run to run the
137 int silc_client_init(SilcClient client)
140 SILC_LOG_DEBUG(("Initializing client"));
143 client->username = silc_get_username();
144 client->realname = silc_get_real_name();
146 /* Register all configured ciphers, PKCS and hash functions. */
147 client->config->client = (void *)client;
148 silc_client_config_register_ciphers(client->config);
149 silc_client_config_register_pkcs(client->config);
150 silc_client_config_register_hashfuncs(client->config);
152 /* Initialize hash functions for client to use */
153 silc_hash_alloc("md5", &client->md5hash);
154 silc_hash_alloc("sha1", &client->sha1hash);
156 /* Initialize none cipher */
157 silc_cipher_alloc("none", &client->none_cipher);
159 /* Initialize random number generator */
160 client->rng = silc_rng_alloc();
161 silc_rng_init(client->rng);
162 silc_math_primegen_init(); /* XXX */
164 /* Load public and private key */
165 if (silc_client_load_keys(client) == FALSE)
168 /* Register the task queues. In SILC we have by default three task queues.
169 One task queue for non-timeout tasks which perform different kind of
170 I/O on file descriptors, timeout task queue for timeout tasks, and,
171 generic non-timeout task queue whose tasks apply to all connections. */
172 silc_task_queue_alloc(&client->io_queue, TRUE);
173 if (!client->io_queue) {
176 silc_task_queue_alloc(&client->timeout_queue, TRUE);
177 if (!client->timeout_queue) {
180 silc_task_queue_alloc(&client->generic_queue, TRUE);
181 if (!client->generic_queue) {
185 /* Register protocols */
186 silc_client_protocols_register();
188 /* Initialize the scheduler */
189 silc_schedule_init(client->io_queue, client->timeout_queue,
190 client->generic_queue, 5000);
192 /* Register the main task that is used in client. This received
193 the key pressings. */
194 if (silc_task_register(client->io_queue, fileno(stdin),
195 silc_client_process_key_press,
196 (void *)client, 0, 0,
198 SILC_TASK_PRI_NORMAL) == NULL) {
202 /* Register timeout task that updates clock every minute. */
203 if (silc_task_register(client->timeout_queue, 0,
204 silc_client_update_clock,
206 silc_client_time_til_next_min(), 0,
208 SILC_TASK_PRI_LOW) == NULL) {
212 if (client->config->commands) {
213 /* Run user configured commands with timeout */
214 if (silc_task_register(client->timeout_queue, 0,
215 silc_client_run_commands,
216 (void *)client, 0, 1,
218 SILC_TASK_PRI_LOW) == NULL) {
223 /* Allocate the input buffer used to save typed characters */
224 client->input_buffer = silc_buffer_alloc(SILC_SCREEN_INPUT_WIN_SIZE);
225 silc_buffer_pull_tail(client->input_buffer,
226 SILC_BUFFER_END(client->input_buffer));
228 /* Initialize the screen */
229 client->screen = silc_screen_init();
230 silc_client_create_main_window(client);
231 client->screen->input_buffer = client->input_buffer->data;
232 silc_screen_print_coordinates(client->screen, 0);
237 silc_task_queue_free(client->timeout_queue);
239 silc_task_queue_free(client->io_queue);
244 /* Stops the client. This is called to stop the client and thus to stop
247 void silc_client_stop(SilcClient client)
249 SILC_LOG_DEBUG(("Stopping client"));
251 /* Stop the scheduler, although it might be already stopped. This
252 doesn't hurt anyone. This removes all the tasks and task queues,
254 silc_schedule_stop();
255 silc_schedule_uninit();
257 silc_client_protocols_unregister();
259 SILC_LOG_DEBUG(("Client client"));
262 /* Runs the client. */
264 void silc_client_run(SilcClient client)
266 SILC_LOG_DEBUG(("Running client"));
268 /* Start the scheduler, the heart of the SILC client. When this returns
269 the program will be terminated. */
273 /* Creates the main window used in SILC client. This is called always
274 at the initialization of the client. If user wants to create more
275 than one windows a new windows are always created by calling
276 silc_client_add_window. */
278 SilcClientWindow silc_client_create_main_window(SilcClient client)
280 SilcClientWindow win;
283 SILC_LOG_DEBUG(("Creating main window"));
285 assert(client->screen != NULL);
287 client->screen->u_stat_line.program_name = silc_name;
288 client->screen->u_stat_line.program_version = silc_version;
291 win = silc_calloc(1, sizeof(*win));
292 win->nickname = silc_get_username();
293 win->local_id = NULL;
294 win->local_id_data = NULL;
295 win->local_id_data_len = 0;
296 win->remote_host = NULL;
297 win->remote_port = -1;
300 /* Initialize ID caches */
301 win->client_cache = silc_idcache_alloc(0);
302 win->channel_cache = silc_idcache_alloc(0);
303 win->server_cache = silc_idcache_alloc(0);
305 /* Create the actual screen */
306 screen = (void *)silc_screen_create_output_window(client->screen);
307 silc_screen_create_input_window(client->screen);
308 silc_screen_init_upper_status_line(client->screen);
309 silc_screen_init_output_status_line(client->screen);
310 win->screen = screen;
312 client->screen->bottom_line->nickname = win->nickname;
313 silc_screen_print_bottom_line(client->screen, 0);
315 /* Add the window to windows table */
316 client->windows = silc_calloc(1, sizeof(*client->windows));
317 client->windows[client->windows_count] = win;
318 client->windows_count = 1;
320 /* Automatically becomes the current active window */
321 client->current_win = win;
326 /* Allocates and adds new window to the client. This allocates new
327 physical window and internal window for connection specific data.
328 All the connection specific data is always saved into a window
329 since connection is always associated to a active window. */
331 SilcClientWindow silc_client_add_window(SilcClient client,
334 SilcClientWindow win;
336 assert(client->screen != NULL);
338 win = silc_calloc(1, sizeof(*win));
340 /* Add the pointers */
341 win->screen = silc_screen_add_output_window(client->screen);
344 /* Initialize ID caches */
345 win->client_cache = silc_idcache_alloc(0);
346 win->channel_cache = silc_idcache_alloc(0);
347 win->server_cache = silc_idcache_alloc(0);
349 /* Add the window to windows table */
350 client->windows = silc_realloc(client->windows, sizeof(*client->windows)
351 * (client->windows_count + 1));
352 client->windows[client->windows_count] = win;
353 client->windows_count++;
355 if (is_current == TRUE)
356 client->current_win = win;
361 /* The main task on SILC client. This processes the key pressings user
364 SILC_TASK_CALLBACK(silc_client_process_key_press)
366 SilcClient client = (SilcClient)context;
369 /* There is data pending in stdin, this gets it directly */
370 c = wgetch(client->screen->input_win);
371 if (silc_client_bad_keys(c))
374 SILC_LOG_DEBUG(("Pressed key: %d", c));
378 * Special character handling
385 SILC_LOG_DEBUG(("RIGHT"));
386 silc_screen_input_cursor_right(client->screen);
390 SILC_LOG_DEBUG(("LEFT"));
391 silc_screen_input_cursor_left(client->screen);
398 silc_screen_input_backspace(client->screen);
404 /* Insert switch. Turns on/off insert on input window */
405 silc_screen_input_insert(client->screen);
409 /* Enter, Return. User pressed enter we are ready to
410 process the message. */
411 silc_client_process_message(client);
414 /* Refresh screen, Ctrl^l */
415 silc_screen_refresh_all(client->screen);
420 /* Beginning, Home */
421 silc_screen_input_cursor_home(client->screen);
426 silc_screen_input_cursor_end(client->screen);
438 silc_client_clear_input(client);
445 /* Control codes are printed as reversed */
447 wattron(client->screen->input_win, A_REVERSE);
448 silc_screen_input_print(client->screen, c);
449 wattroff(client->screen->input_win, A_REVERSE);
451 /* Normal character */
452 silc_screen_input_print(client->screen, c);
456 silc_screen_print_coordinates(client->screen, 0);
457 silc_screen_refresh_win(client->screen->input_win);
460 static int silc_client_bad_keys(unsigned char key)
462 /* these are explained in curses.h */
477 case '\E': /* we ignore ESC */
484 /* Clears input buffer */
486 static void silc_client_clear_input(SilcClient client)
488 silc_buffer_clear(client->input_buffer);
489 silc_buffer_pull_tail(client->input_buffer,
490 SILC_BUFFER_END(client->input_buffer));
491 silc_screen_input_reset(client->screen);
494 /* Processes messages user has typed on the screen. This either sends
495 a packet out to network or if command were written executes it. */
497 static void silc_client_process_message(SilcClient client)
502 SILC_LOG_DEBUG(("Start"));
504 data = client->input_buffer->data;
507 if (data[0] == '/' && data[1] != ' ') {
509 unsigned int argc = 0;
510 unsigned char **argv, *tmpcmd;
511 unsigned int *argv_lens, *argv_types;
512 SilcClientCommand *cmd;
513 SilcClientCommandContext ctx;
515 /* Get the command */
516 tmpcmd = silc_client_parse_command(data);
518 /* Find command match */
519 for (cmd = silc_command_list; cmd->name; cmd++) {
520 if (!strncmp(cmd->name, tmpcmd, strlen(tmpcmd)))
524 if (cmd->name == NULL) {
525 silc_say(client, "Invalid command: %s", tmpcmd);
530 /* Now parse all arguments */
531 silc_client_parse_command_line(data, &argv, &argv_lens,
532 &argv_types, &argc, cmd->max_args);
535 SILC_LOG_DEBUG(("Exeuting command: %s", cmd->name));
537 /* Allocate command context. This and its internals must be free'd
538 by the command routine receiving it. */
539 ctx = silc_calloc(1, sizeof(*ctx));
540 ctx->client = client;
541 ctx->sock = client->current_win->sock;
544 ctx->argv_lens = argv_lens;
545 ctx->argv_types = argv_types;
547 /* Execute command */
551 /* Normal message to a channel */
552 if (len && client->current_win->current_channel &&
553 client->current_win->current_channel->on_channel == TRUE) {
554 silc_print(client, "> %s", data);
555 silc_client_packet_send_to_channel(client,
556 client->current_win->sock,
557 client->current_win->current_channel,
558 data, strlen(data), TRUE);
563 /* Clear the input buffer */
564 silc_client_clear_input(client);
567 /* Returns the command fetched from user typed command line */
569 static char *silc_client_parse_command(unsigned char *buffer)
572 const char *cp = buffer;
575 len = strcspn(cp, " ");
576 ret = silc_to_upper((char *)++cp);
582 /* Parses user typed command line. At most `max_args' is taken. Rest
583 of the line will be allocated as the last argument if there are more
584 than `max_args' arguments in the line. Note that the command name
585 is counted as one argument and is saved. */
587 void silc_client_parse_command_line(unsigned char *buffer,
588 unsigned char ***parsed,
589 unsigned int **parsed_lens,
590 unsigned int **parsed_types,
591 unsigned int *parsed_num,
592 unsigned int max_args)
596 const char *cp = buffer;
598 /* Take the '/' away */
601 *parsed = silc_calloc(1, sizeof(**parsed));
602 *parsed_lens = silc_calloc(1, sizeof(**parsed_lens));
604 /* Get the command first */
605 len = strcspn(cp, " ");
606 (*parsed)[0] = silc_to_upper((char *)cp);
607 (*parsed_lens)[0] = len;
611 /* Parse arguments */
612 if (strchr(cp, ' ') || strlen(cp) != 0) {
613 for (i = 1; i < max_args; i++) {
615 if (i != max_args - 1)
616 len = strcspn(cp, " ");
620 *parsed = silc_realloc(*parsed, sizeof(**parsed) * (argc + 1));
621 *parsed_lens = silc_realloc(*parsed_lens,
622 sizeof(**parsed_lens) * (argc + 1));
623 (*parsed)[argc] = silc_calloc(len + 1, sizeof(char));
624 memcpy((*parsed)[argc], cp, len);
625 (*parsed_lens)[argc] = len;
636 /* Save argument types. Protocol defines all argument types but
637 this implementation makes sure that they are always in correct
638 order hence this simple code. */
639 *parsed_types = silc_calloc(argc, sizeof(**parsed_types));
640 for (i = 0; i < argc; i++)
641 (*parsed_types)[i] = i;
646 /* Updates clock on the screen every minute. */
648 SILC_TASK_CALLBACK(silc_client_update_clock)
650 SilcClient client = (SilcClient)context;
652 /* Update the clock on the screen */
653 silc_screen_print_clock(client->screen);
655 /* Re-register this same task */
656 silc_task_register(qptr, 0, silc_client_update_clock, context,
657 silc_client_time_til_next_min(), 0,
661 silc_screen_refresh_win(client->screen->input_win);
664 /* Runs commands user configured in configuration file. This is
665 called when initializing client. */
667 SILC_TASK_CALLBACK(silc_client_run_commands)
669 SilcClient client = (SilcClient)context;
670 SilcClientConfigSectionCommand *cs;
672 SILC_LOG_DEBUG(("Start"));
674 cs = client->config->commands;
676 unsigned int argc = 0;
677 unsigned char **argv, *tmpcmd;
678 unsigned int *argv_lens, *argv_types;
679 SilcClientCommand *cmd;
680 SilcClientCommandContext ctx;
682 /* Get the command */
683 tmpcmd = silc_client_parse_command(cs->command);
685 for (cmd = silc_command_list; cmd->name; cmd++) {
686 if (!strcmp(cmd->name, tmpcmd))
690 if (cmd->name == NULL) {
691 silc_say(client, "Invalid command: %s", tmpcmd);
696 /* Now parse all arguments */
697 silc_client_parse_command_line(cs->command, &argv, &argv_lens,
698 &argv_types, &argc, cmd->max_args);
701 SILC_LOG_DEBUG(("Exeuting command: %s", cmd->name));
703 /* Allocate command context. This and its internals must be free'd
704 by the command routine receiving it. */
705 ctx = silc_calloc(1, sizeof(*ctx));
706 ctx->client = client;
707 ctx->sock = client->current_win->sock;
710 ctx->argv_lens = argv_lens;
711 ctx->argv_types = argv_types;
713 /* Execute command */
720 /* Internal context for connection process. This is needed as we
721 doing asynchronous connecting. */
729 } SilcClientInternalConnectContext;
732 silc_client_connect_to_server_internal(SilcClientInternalConnectContext *ctx)
736 /* XXX In the future we should give up this non-blocking connect all
737 together and use threads instead. */
738 /* Create connection to server asynchronously */
739 sock = silc_net_create_connection_async(ctx->port, ctx->host);
743 /* Register task that will receive the async connect and will
745 ctx->task = silc_task_register(ctx->client->io_queue, sock,
746 silc_client_connect_to_server_start,
749 SILC_TASK_PRI_NORMAL);
750 silc_task_reset_iotype(ctx->task, SILC_TASK_WRITE);
751 silc_schedule_set_listen_fd(sock, ctx->task->iomask);
758 /* Connects to remote server */
760 int silc_client_connect_to_server(SilcClient client, int port,
763 SilcClientInternalConnectContext *ctx;
765 SILC_LOG_DEBUG(("Connecting to port %d of server %s",
768 silc_say(client, "Connecting to port %d of server %s", port, host);
770 client->current_win->remote_host = strdup(host);
771 client->current_win->remote_port = port;
773 /* Allocate internal context for connection process. This is
774 needed as we are doing async connecting. */
775 ctx = silc_calloc(1, sizeof(*ctx));
776 ctx->client = client;
777 ctx->host = strdup(host);
781 /* Do the actual connecting process */
782 return silc_client_connect_to_server_internal(ctx);
785 /* Start of the connection to the remote server. This is called after
786 succesful TCP/IP connection has been established to the remote host. */
788 SILC_TASK_CALLBACK(silc_client_connect_to_server_start)
790 SilcClientInternalConnectContext *ctx =
791 (SilcClientInternalConnectContext *)context;
792 SilcClient client = ctx->client;
793 SilcProtocol protocol;
794 SilcClientKEInternalContext *proto_ctx;
795 int opt, opt_len = sizeof(opt);
797 SILC_LOG_DEBUG(("Start"));
799 /* Check the socket status as it might be in error */
800 getsockopt(fd, SOL_SOCKET, SO_ERROR, &opt, &opt_len);
802 if (ctx->tries < 2) {
803 /* Connection failed but lets try again */
804 silc_say(ctx->client, "Could not connect to server %s: %s",
805 ctx->host, strerror(opt));
806 silc_say(client, "Connecting to port %d of server %s resumed",
807 ctx->port, ctx->host);
809 /* Unregister old connection try */
810 silc_schedule_unset_listen_fd(fd);
811 silc_net_close_connection(fd);
812 silc_task_unregister(client->io_queue, ctx->task);
815 silc_client_connect_to_server_internal(ctx);
818 /* Connection failed and we won't try anymore */
819 silc_say(ctx->client, "Could not connect to server %s: %s",
820 ctx->host, strerror(opt));
821 silc_schedule_unset_listen_fd(fd);
822 silc_net_close_connection(fd);
823 silc_task_unregister(client->io_queue, ctx->task);
829 silc_schedule_unset_listen_fd(fd);
830 silc_task_unregister(client->io_queue, ctx->task);
833 /* Allocate new socket connection object */
834 silc_socket_alloc(fd, SILC_SOCKET_TYPE_SERVER,
835 (void *)client->current_win,
836 &client->current_win->sock);
837 if (client->current_win->sock == NULL) {
838 silc_say(client, "Error: Could not allocate connection socket");
839 silc_net_close_connection(fd);
842 client->current_win->sock->hostname = client->current_win->remote_host;
843 client->current_win->sock->port = client->current_win->remote_port;
845 /* Allocate internal Key Exchange context. This is sent to the
846 protocol as context. */
847 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
848 proto_ctx->client = (void *)client;
849 proto_ctx->sock = client->current_win->sock;
850 proto_ctx->rng = client->rng;
851 proto_ctx->responder = FALSE;
853 /* Perform key exchange protocol. silc_client_connect_to_server_final
854 will be called after the protocol is finished. */
855 silc_protocol_alloc(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
856 &protocol, (void *)proto_ctx,
857 silc_client_connect_to_server_second);
859 silc_say(client, "Error: Could not start authentication protocol");
862 client->current_win->sock->protocol = protocol;
864 /* Register the connection for network input and output. This sets
865 that scheduler will listen for incoming packets for this connection
866 and sets that outgoing packets may be sent to this connection as well.
867 However, this doesn't set the scheduler for outgoing traffic, it will
868 be set separately by calling SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT,
869 later when outgoing data is available. */
870 context = (void *)client;
871 SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(fd);
873 /* Execute the protocol */
874 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0);
877 /* Second part of the connecting to the server. This executed
878 authentication protocol. */
880 SILC_TASK_CALLBACK(silc_client_connect_to_server_second)
882 SilcProtocol protocol = (SilcProtocol)context;
883 SilcClientKEInternalContext *ctx =
884 (SilcClientKEInternalContext *)protocol->context;
885 SilcClient client = (SilcClient)ctx->client;
886 SilcSocketConnection sock = NULL;
887 SilcClientConnAuthInternalContext *proto_ctx;
889 SILC_LOG_DEBUG(("Start"));
891 if (protocol->state == SILC_PROTOCOL_STATE_ERROR) {
892 /* Error occured during protocol */
893 SILC_LOG_DEBUG(("Error during KE protocol"));
894 silc_protocol_free(protocol);
896 silc_ske_free(ctx->ske);
898 silc_free(ctx->dest_id);
899 ctx->sock->protocol = NULL;
904 /* Allocate internal context for the authentication protocol. This
905 is sent as context for the protocol. */
906 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
907 proto_ctx->client = (void *)client;
908 proto_ctx->sock = sock = ctx->sock;
909 proto_ctx->ske = ctx->ske; /* Save SKE object from previous protocol */
910 proto_ctx->dest_id_type = ctx->dest_id_type;
911 proto_ctx->dest_id = ctx->dest_id;
913 /* Resolve the authentication method to be used in this connection */
914 proto_ctx->auth_meth = SILC_PROTOCOL_CONN_AUTH_NONE;
915 if (client->config->conns) {
916 SilcClientConfigSectionConnection *conn = NULL;
918 /* Check if we find a match from user configured connections */
919 conn = silc_client_config_find_connection(client->config,
923 /* Match found. Use the configured authentication method */
924 proto_ctx->auth_meth = conn->auth_meth;
925 if (conn->auth_data) {
926 proto_ctx->auth_data = strdup(conn->auth_data);
927 proto_ctx->auth_data_len = strlen(conn->auth_data);
930 /* No match found. Resolve by sending AUTH_REQUEST to server */
931 proto_ctx->auth_meth = SILC_PROTOCOL_CONN_AUTH_NONE;
934 /* XXX Resolve by sending AUTH_REQUEST to server */
935 proto_ctx->auth_meth = SILC_PROTOCOL_CONN_AUTH_NONE;
938 /* Free old protocol as it is finished now */
939 silc_protocol_free(protocol);
941 silc_buffer_free(ctx->packet);
943 /* silc_free(ctx->keymat....); */
944 sock->protocol = NULL;
946 /* Allocate the authentication protocol. This is allocated here
947 but we won't start it yet. We will be receiving party of this
948 protocol thus we will wait that connecting party will make
950 silc_protocol_alloc(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
951 &sock->protocol, (void *)proto_ctx,
952 silc_client_connect_to_server_final);
954 /* Execute the protocol */
955 sock->protocol->execute(client->timeout_queue, 0, sock->protocol, fd, 0, 0);
958 /* Finalizes the connection to the remote SILC server. This is called
959 after authentication protocol has been completed. This send our
960 user information to the server to receive our client ID from
963 SILC_TASK_CALLBACK(silc_client_connect_to_server_final)
965 SilcProtocol protocol = (SilcProtocol)context;
966 SilcClientConnAuthInternalContext *ctx =
967 (SilcClientConnAuthInternalContext *)protocol->context;
968 SilcClient client = (SilcClient)ctx->client;
969 SilcClientWindow win = (SilcClientWindow)ctx->sock->user_data;
972 SILC_LOG_DEBUG(("Start"));
974 if (protocol->state == SILC_PROTOCOL_STATE_ERROR) {
975 /* Error occured during protocol */
976 SILC_LOG_DEBUG(("Error during authentication protocol"));
977 silc_protocol_free(protocol);
979 silc_free(ctx->auth_data);
981 silc_ske_free(ctx->ske);
983 silc_free(ctx->dest_id);
985 win->sock->protocol = NULL;
989 /* Send NEW_CLIENT packet to the server. We will become registered
990 to the SILC network after sending this packet and we will receive
991 client ID from the server. */
992 packet = silc_buffer_alloc(2 + 2 + strlen(client->username) +
993 strlen(client->realname));
994 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
995 silc_buffer_format(packet,
996 SILC_STR_UI_SHORT(strlen(client->username)),
997 SILC_STR_UI_XNSTRING(client->username,
998 strlen(client->username)),
999 SILC_STR_UI_SHORT(strlen(client->realname)),
1000 SILC_STR_UI_XNSTRING(client->realname,
1001 strlen(client->realname)),
1004 /* Send the packet */
1005 silc_client_packet_send(client, ctx->sock, SILC_PACKET_NEW_CLIENT,
1006 NULL, 0, NULL, NULL,
1007 packet->data, packet->len, TRUE);
1008 silc_buffer_free(packet);
1010 /* Save remote ID. */
1011 win->remote_id = ctx->dest_id;
1012 win->remote_id_data = silc_id_id2str(ctx->dest_id, SILC_ID_CHANNEL);
1013 win->remote_id_data_len = SILC_ID_CHANNEL_LEN;
1015 silc_say(client, "Connected to port %d of host %s",
1016 win->remote_port, win->remote_host);
1018 client->screen->bottom_line->connection = win->remote_host;
1019 silc_screen_print_bottom_line(client->screen, 0);
1021 silc_protocol_free(protocol);
1023 silc_free(ctx->auth_data);
1025 silc_ske_free(ctx->ske);
1027 silc_free(ctx->dest_id);
1029 win->sock->protocol = NULL;
1032 /* Internal routine that sends packet or marks packet to be sent. This
1033 is used directly only in special cases. Normal cases should use
1034 silc_server_packet_send. Returns < 0 on error. */
1036 static int silc_client_packet_send_real(SilcClient client,
1037 SilcSocketConnection sock,
1042 /* Send the packet */
1043 ret = silc_packet_send(sock, force_send);
1047 /* Mark that there is some outgoing data available for this connection.
1048 This call sets the connection both for input and output (the input
1049 is set always and this call keeps the input setting, actually).
1050 Actual data sending is performed by silc_client_packet_process. */
1051 SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(sock->sock);
1053 /* Mark to socket that data is pending in outgoing buffer. This flag
1054 is needed if new data is added to the buffer before the earlier
1055 put data is sent to the network. */
1056 SILC_SET_OUTBUF_PENDING(sock);
1061 /* Packet processing callback. This is used to send and receive packets
1062 from network. This is generic task. */
1064 SILC_TASK_CALLBACK(silc_client_packet_process)
1066 SilcClient client = (SilcClient)context;
1067 SilcSocketConnection sock = NULL;
1068 SilcClientWindow win;
1071 SILC_LOG_DEBUG(("Processing packet"));
1073 SILC_CLIENT_GET_SOCK(client, fd, sock);
1077 win = (SilcClientWindow)sock->user_data;
1079 /* Packet sending */
1080 if (type == SILC_TASK_WRITE) {
1081 SILC_LOG_DEBUG(("Writing data to connection"));
1083 if (sock->outbuf->data - sock->outbuf->head)
1084 silc_buffer_push(sock->outbuf,
1085 sock->outbuf->data - sock->outbuf->head);
1087 ret = silc_client_packet_send_real(client, sock, TRUE);
1089 /* If returned -2 could not write to connection now, will do
1094 /* The packet has been sent and now it is time to set the connection
1095 back to only for input. When there is again some outgoing data
1096 available for this connection it will be set for output as well.
1097 This call clears the output setting and sets it only for input. */
1098 SILC_CLIENT_SET_CONNECTION_FOR_INPUT(fd);
1099 SILC_UNSET_OUTBUF_PENDING(sock);
1101 silc_buffer_clear(sock->outbuf);
1105 /* Packet receiving */
1106 if (type == SILC_TASK_READ) {
1107 SILC_LOG_DEBUG(("Reading data from connection"));
1109 /* Read data from network */
1110 ret = silc_packet_receive(sock);
1116 SILC_LOG_DEBUG(("Read EOF"));
1118 /* If connection is disconnecting already we will finally
1119 close the connection */
1120 if (SILC_IS_DISCONNECTING(sock)) {
1121 silc_client_close_connection(client, sock);
1125 silc_say(client, "Connection closed: premature EOF");
1126 SILC_LOG_DEBUG(("Premature EOF from connection %d", sock->sock));
1128 silc_client_close_connection(client, sock);
1132 /* Process the packet. This will call the parser that will then
1133 decrypt and parse the packet. */
1134 if (!silc_packet_receive_process(sock, win->receive_key, win->hmac,
1135 silc_client_packet_parse, client)) {
1136 silc_buffer_clear(sock->inbuf);
1142 /* Parses whole packet, received earlier. */
1144 SILC_TASK_CALLBACK(silc_client_packet_parse_real)
1146 SilcPacketParserContext *parse_ctx = (SilcPacketParserContext *)context;
1147 SilcClient client = (SilcClient)parse_ctx->context;
1148 SilcPacketContext *packet = parse_ctx->packet;
1149 SilcBuffer buffer = packet->buffer;
1150 SilcSocketConnection sock = parse_ctx->sock;
1151 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1154 SILC_LOG_DEBUG(("Start"));
1156 /* Decrypt the received packet */
1157 ret = silc_packet_decrypt(win->receive_key, win->hmac, buffer, packet);
1162 /* Parse the packet. Packet type is returned. */
1163 ret = silc_packet_parse(packet);
1165 /* Parse the packet header in special way as this is "special"
1167 ret = silc_packet_parse_special(packet);
1170 if (ret == SILC_PACKET_NONE)
1173 /* Parse the incoming packet type */
1174 silc_client_packet_parse_type(client, sock, packet);
1177 silc_buffer_clear(buffer);
1179 silc_free(parse_ctx);
1182 /* Parser callback called by silc_packet_receive_process. Thie merely
1183 registers timeout that will handle the actual parsing when appropriate. */
1185 void silc_client_packet_parse(SilcPacketParserContext *parser_context)
1187 SilcClient client = (SilcClient)parser_context->context;
1188 SilcClientWindow win = (SilcClientWindow)parser_context->sock->user_data;
1190 /* If this packet is for the current active connection we will
1191 parse the packet right away to get it quickly on the screen.
1192 Otherwise, it will be parsed with a timeout as the data is
1193 for inactive window (which might not be visible at all). */
1194 if (SILC_CLIENT_IS_CURRENT_WIN(client, win)) {
1195 /* Parse it real soon */
1196 silc_task_register(client->timeout_queue, parser_context->sock->sock,
1197 silc_client_packet_parse_real,
1198 (void *)parser_context, 0, 1,
1200 SILC_TASK_PRI_NORMAL);
1202 /* Parse the packet with timeout */
1203 silc_task_register(client->timeout_queue, parser_context->sock->sock,
1204 silc_client_packet_parse_real,
1205 (void *)parser_context, 0, 200000,
1207 SILC_TASK_PRI_NORMAL);
1211 /* Parses the packet type and calls what ever routines the packet type
1212 requires. This is done for all incoming packets. */
1214 void silc_client_packet_parse_type(SilcClient client,
1215 SilcSocketConnection sock,
1216 SilcPacketContext *packet)
1218 SilcBuffer buffer = packet->buffer;
1219 SilcPacketType type = packet->type;
1221 SILC_LOG_DEBUG(("Parsing packet type %d", type));
1223 /* Parse the packet type */
1225 case SILC_PACKET_DISCONNECT:
1226 silc_client_disconnected_by_server(client, sock, buffer);
1228 case SILC_PACKET_SUCCESS:
1230 * Success received for something. For now we can have only
1231 * one protocol for connection executing at once hence this
1232 * success message is for whatever protocol is executing currently.
1234 if (sock->protocol) {
1235 sock->protocol->execute(client->timeout_queue, 0,
1236 sock->protocol, sock->sock, 0, 0);
1239 case SILC_PACKET_FAILURE:
1241 * Failure received for some protocol. Set the protocol state to
1242 * error and call the protocol callback. This fill cause error on
1243 * protocol and it will call the final callback.
1245 if (sock->protocol) {
1246 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
1247 sock->protocol->execute(client->timeout_queue, 0,
1248 sock->protocol, sock->sock, 0, 0);
1251 case SILC_PACKET_REJECT:
1254 case SILC_PACKET_NOTIFY:
1256 * Received notify message
1258 silc_client_notify_by_server(client, sock, buffer);
1261 case SILC_PACKET_ERROR:
1263 * Received error message
1265 silc_client_error_by_server(client, sock, buffer);
1268 case SILC_PACKET_CHANNEL_MESSAGE:
1270 * Received message to (from, actually) a channel
1272 silc_client_channel_message(client, sock, packet);
1274 case SILC_PACKET_CHANNEL_KEY:
1276 * Received key for a channel. By receiving this key the client will be
1277 * able to talk to the channel it has just joined. This can also be
1278 * a new key for existing channel as keys expire peridiocally.
1280 silc_client_receive_channel_key(client, sock, buffer);
1283 case SILC_PACKET_PRIVATE_MESSAGE:
1285 * Received private message
1288 SilcClientCommandReplyContext ctx;
1289 ctx = silc_calloc(1, sizeof(*ctx));
1290 ctx->client = client;
1292 ctx->packet = packet;
1293 silc_client_command_reply_msg((void *)ctx);
1296 case SILC_PACKET_PRIVATE_MESSAGE_KEY:
1298 * Received private message key
1302 case SILC_PACKET_COMMAND_REPLY:
1304 * Recived reply for a command
1306 silc_client_command_reply_process(client, sock, packet);
1309 case SILC_PACKET_KEY_EXCHANGE:
1310 if (sock->protocol) {
1311 SilcClientKEInternalContext *proto_ctx =
1312 (SilcClientKEInternalContext *)sock->protocol->context;
1314 proto_ctx->packet = buffer;
1315 proto_ctx->dest_id_type = packet->src_id_type;
1316 proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_type);
1318 /* Let the protocol handle the packet */
1319 sock->protocol->execute(client->timeout_queue, 0,
1320 sock->protocol, sock->sock, 0, 0);
1322 SILC_LOG_ERROR(("Received Key Exchange packet but no key exchange "
1323 "protocol active, packet dropped."));
1325 /* XXX Trigger KE protocol?? Rekey actually! */
1329 case SILC_PACKET_KEY_EXCHANGE_1:
1330 if (sock->protocol) {
1333 SILC_LOG_ERROR(("Received Key Exchange 1 packet but no key exchange "
1334 "protocol active, packet dropped."));
1337 case SILC_PACKET_KEY_EXCHANGE_2:
1338 if (sock->protocol) {
1339 SilcClientKEInternalContext *proto_ctx =
1340 (SilcClientKEInternalContext *)sock->protocol->context;
1342 if (proto_ctx->packet)
1343 silc_buffer_free(proto_ctx->packet);
1345 proto_ctx->packet = buffer;
1346 proto_ctx->dest_id_type = packet->src_id_type;
1347 proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_type);
1349 /* Let the protocol handle the packet */
1350 sock->protocol->execute(client->timeout_queue, 0,
1351 sock->protocol, sock->sock, 0, 0);
1353 SILC_LOG_ERROR(("Received Key Exchange 2 packet but no key exchange "
1354 "protocol active, packet dropped."));
1358 case SILC_PACKET_NEW_ID:
1361 * Received new ID from server. This packet is received at
1362 * the connection to the server. New ID is also received when
1363 * user changes nickname but in that case the new ID is received
1364 * as command reply and not as this packet type.
1366 unsigned char *id_string;
1367 unsigned short id_type;
1369 silc_buffer_unformat(buffer,
1370 SILC_STR_UI_SHORT(&id_type),
1371 SILC_STR_UI16_STRING_ALLOC(&id_string),
1374 if ((SilcIdType)id_type != SILC_ID_CLIENT)
1377 silc_client_receive_new_id(client, sock, id_string);
1378 silc_free(id_string);
1383 SILC_LOG_DEBUG(("Incorrect packet type %d, packet dropped", type));
1388 /* Sends packet. This doesn't actually send the packet instead it assembles
1389 it and marks it to be sent. However, if force_send is TRUE the packet
1390 is sent immediately. if dst_id, cipher and hmac are NULL those parameters
1391 will be derived from sock argument. Otherwise the valid arguments sent
1394 void silc_client_packet_send(SilcClient client,
1395 SilcSocketConnection sock,
1396 SilcPacketType type,
1398 SilcIdType dst_id_type,
1401 unsigned char *data,
1402 unsigned int data_len,
1405 SilcPacketContext packetdata;
1407 SILC_LOG_DEBUG(("Sending packet, type %d", type));
1409 /* Get data used in the packet sending, keys and stuff */
1410 if ((!cipher || !hmac || !dst_id) && sock->user_data) {
1411 if (!cipher && ((SilcClientWindow)sock->user_data)->send_key)
1412 cipher = ((SilcClientWindow)sock->user_data)->send_key;
1414 if (!hmac && ((SilcClientWindow)sock->user_data)->hmac)
1415 hmac = ((SilcClientWindow)sock->user_data)->hmac;
1417 if (!dst_id && ((SilcClientWindow)sock->user_data)->remote_id) {
1418 dst_id = ((SilcClientWindow)sock->user_data)->remote_id;
1419 dst_id_type = SILC_ID_SERVER;
1423 /* Set the packet context pointers */
1424 packetdata.flags = 0;
1425 packetdata.type = type;
1426 if (((SilcClientWindow)sock->user_data)->local_id_data)
1427 packetdata.src_id = ((SilcClientWindow)sock->user_data)->local_id_data;
1429 packetdata.src_id = silc_calloc(SILC_ID_CLIENT_LEN, sizeof(unsigned char));
1430 packetdata.src_id_len = SILC_ID_CLIENT_LEN;
1431 packetdata.src_id_type = SILC_ID_CLIENT;
1433 packetdata.dst_id = silc_id_id2str(dst_id, dst_id_type);
1434 packetdata.dst_id_len = silc_id_get_len(dst_id_type);
1435 packetdata.dst_id_type = dst_id_type;
1437 packetdata.dst_id = NULL;
1438 packetdata.dst_id_len = 0;
1439 packetdata.dst_id_type = SILC_ID_NONE;
1441 packetdata.rng = client->rng;
1442 packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN +
1443 packetdata.src_id_len + packetdata.dst_id_len;
1444 packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen);
1446 /* Prepare outgoing data buffer for packet sending */
1447 silc_packet_send_prepare(sock,
1448 SILC_PACKET_HEADER_LEN +
1449 packetdata.src_id_len +
1450 packetdata.dst_id_len,
1454 SILC_LOG_DEBUG(("Putting data to outgoing buffer, len %d", data_len));
1456 packetdata.buffer = sock->outbuf;
1458 /* Put the data to the buffer */
1459 if (data && data_len)
1460 silc_buffer_put(sock->outbuf, data, data_len);
1462 /* Create the outgoing packet */
1463 silc_packet_assemble(&packetdata);
1465 /* Encrypt the packet */
1467 silc_packet_encrypt(cipher, hmac, sock->outbuf, sock->outbuf->len);
1469 SILC_LOG_HEXDUMP(("Packet, len %d", sock->outbuf->len),
1470 sock->outbuf->data, sock->outbuf->len);
1472 /* Now actually send the packet */
1473 silc_client_packet_send_real(client, sock, force_send);
1476 /* Sends packet to a channel. Packet to channel is always encrypted
1477 differently from "normal" packets. SILC header of the packet is
1478 encrypted with the next receiver's key and the rest of the packet is
1479 encrypted with the channel specific key. Padding and HMAC is computed
1480 with the next receiver's key. */
1482 void silc_client_packet_send_to_channel(SilcClient client,
1483 SilcSocketConnection sock,
1484 SilcChannelEntry channel,
1485 unsigned char *data,
1486 unsigned int data_len,
1490 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1492 SilcPacketContext packetdata;
1495 unsigned char *id_string;
1497 SILC_LOG_DEBUG(("Sending packet to channel"));
1499 if (!channel || !channel->key) {
1500 silc_say(client, "Cannot talk to channel: key does not exist");
1506 for (i = 0; i < 16; i++)
1507 channel->iv[i] = silc_rng_get_byte(client->rng);
1509 silc_hash_make(client->md5hash, channel->iv, 16, channel->iv);
1511 /* Encode the channel payload */
1512 payload = silc_channel_encode_payload(strlen(win->nickname), win->nickname,
1513 data_len, data, 16, channel->iv,
1517 "Error: Could not create packet to be sent to the channel");
1521 /* Get data used in packet header encryption, keys and stuff. Rest
1522 of the packet (the payload) is, however, encrypted with the
1523 specified channel key. */
1524 cipher = win->send_key;
1526 id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
1528 /* Set the packet context pointers. The destination ID is always
1529 the Channel ID of the channel. Server and router will handle the
1530 distribution of the packet. */
1531 packetdata.flags = 0;
1532 packetdata.type = SILC_PACKET_CHANNEL_MESSAGE;
1533 packetdata.src_id = win->local_id_data;
1534 packetdata.src_id_len = SILC_ID_CLIENT_LEN;
1535 packetdata.src_id_type = SILC_ID_CLIENT;
1536 packetdata.dst_id = id_string;
1537 packetdata.dst_id_len = SILC_ID_CHANNEL_LEN;
1538 packetdata.dst_id_type = SILC_ID_CHANNEL;
1539 packetdata.rng = client->rng;
1540 packetdata.truelen = payload->len + SILC_PACKET_HEADER_LEN +
1541 packetdata.src_id_len + packetdata.dst_id_len;
1542 packetdata.padlen = SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
1543 packetdata.src_id_len +
1544 packetdata.dst_id_len));
1546 /* Prepare outgoing data buffer for packet sending */
1547 silc_packet_send_prepare(sock,
1548 SILC_PACKET_HEADER_LEN +
1549 packetdata.src_id_len +
1550 packetdata.dst_id_len,
1554 packetdata.buffer = sock->outbuf;
1556 /* Encrypt payload of the packet. This is encrypted with the channel key. */
1557 channel->channel_key->cipher->encrypt(channel->channel_key->context,
1558 payload->data, payload->data,
1559 payload->len - 16, /* -IV_LEN */
1562 /* Put the actual encrypted payload data into the buffer. */
1563 silc_buffer_put(sock->outbuf, payload->data, payload->len);
1565 /* Create the outgoing packet */
1566 silc_packet_assemble(&packetdata);
1568 /* Encrypt the header and padding of the packet. This is encrypted
1569 with normal session key shared with our server. */
1570 silc_packet_encrypt(cipher, hmac, sock->outbuf, SILC_PACKET_HEADER_LEN +
1571 packetdata.src_id_len + packetdata.dst_id_len +
1574 SILC_LOG_HEXDUMP(("Packet to channel, len %d", sock->outbuf->len),
1575 sock->outbuf->data, sock->outbuf->len);
1577 /* Now actually send the packet */
1578 silc_client_packet_send_real(client, sock, force_send);
1579 silc_buffer_free(payload);
1580 silc_free(id_string);
1583 /* Sends private message to remote client. If private message key has
1584 not been set with this client then the message will be encrypted using
1585 normal session keys. Private messages are special packets in SILC
1586 network hence we need this own function for them. This is similiar
1587 to silc_client_packet_send_to_channel except that we send private
1590 void silc_client_packet_send_private_message(SilcClient client,
1591 SilcSocketConnection sock,
1592 SilcClientEntry client_entry,
1593 unsigned char *data,
1594 unsigned int data_len,
1597 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1599 SilcPacketContext packetdata;
1600 unsigned int nick_len;
1604 SILC_LOG_DEBUG(("Sending private message"));
1606 /* Create private message payload */
1607 nick_len = strlen(client->current_win->nickname);
1608 buffer = silc_buffer_alloc(2 + nick_len + data_len);
1609 silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer));
1610 silc_buffer_format(buffer,
1611 SILC_STR_UI_SHORT(nick_len),
1612 SILC_STR_UI_XNSTRING(client->current_win->nickname,
1614 SILC_STR_UI_XNSTRING(data, data_len),
1617 /* If we don't have private message specific key then private messages
1618 are just as any normal packet thus call normal packet sending. If
1619 the key exist then the encryption process is a bit different and
1620 will be done in the rest of this function. */
1621 if (!client_entry->send_key) {
1622 silc_client_packet_send(client, sock, SILC_PACKET_PRIVATE_MESSAGE,
1623 client_entry->id, SILC_ID_CLIENT, NULL, NULL,
1624 buffer->data, buffer->len, force_send);
1628 /* We have private message specific key */
1630 /* Get data used in the encryption */
1631 cipher = client_entry->send_key;
1634 /* Set the packet context pointers. */
1635 packetdata.flags = 0;
1636 packetdata.type = SILC_PACKET_PRIVATE_MESSAGE;
1637 packetdata.src_id = win->local_id_data;
1638 packetdata.src_id_len = SILC_ID_CLIENT_LEN;
1639 packetdata.src_id_type = SILC_ID_CLIENT;
1641 packetdata.dst_id = silc_id_id2str(client_entry->id, SILC_ID_CLIENT);
1643 packetdata.dst_id = win->local_id_data;
1644 packetdata.dst_id_len = SILC_ID_CLIENT_LEN;
1645 packetdata.dst_id_type = SILC_ID_CLIENT;
1646 packetdata.rng = client->rng;
1647 packetdata.truelen = buffer->len + SILC_PACKET_HEADER_LEN +
1648 packetdata.src_id_len + packetdata.dst_id_len;
1649 packetdata.padlen = SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
1650 packetdata.src_id_len +
1651 packetdata.dst_id_len));
1653 /* Prepare outgoing data buffer for packet sending */
1654 silc_packet_send_prepare(sock,
1655 SILC_PACKET_HEADER_LEN +
1656 packetdata.src_id_len +
1657 packetdata.dst_id_len,
1661 packetdata.buffer = sock->outbuf;
1663 /* Encrypt payload of the packet. Encrypt with private message specific
1664 key if it exist, otherwise with session key. */
1665 cipher->cipher->encrypt(cipher->context, buffer->data, buffer->data,
1666 buffer->len, cipher->iv);
1668 /* Put the actual encrypted payload data into the buffer. */
1669 silc_buffer_put(sock->outbuf, buffer->data, buffer->len);
1671 /* Create the outgoing packet */
1672 silc_packet_assemble(&packetdata);
1674 /* Encrypt the header and padding of the packet. */
1675 silc_packet_encrypt(cipher, hmac, sock->outbuf, SILC_PACKET_HEADER_LEN +
1676 packetdata.src_id_len + packetdata.dst_id_len +
1679 SILC_LOG_HEXDUMP(("Private message packet, len %d", sock->outbuf->len),
1680 sock->outbuf->data, sock->outbuf->len);
1682 /* Now actually send the packet */
1683 silc_client_packet_send_real(client, sock, force_send);
1684 silc_free(packetdata.dst_id);
1690 /* Closes connection to remote end. Free's all allocated data except
1691 for some information such as nickname etc. that are valid at all time. */
1693 void silc_client_close_connection(SilcClient client,
1694 SilcSocketConnection sock)
1696 SilcClientWindow win;
1698 /* We won't listen for this connection anymore */
1699 silc_schedule_unset_listen_fd(sock->sock);
1701 /* Unregister all tasks */
1702 silc_task_unregister_by_fd(client->io_queue, sock->sock);
1703 silc_task_unregister_by_fd(client->timeout_queue, sock->sock);
1705 /* Close the actual connection */
1706 silc_net_close_connection(sock->sock);
1708 silc_say(client, "Closed connection to host %s", sock->hostname ?
1709 sock->hostname : sock->ip);
1711 /* Free everything */
1712 if (sock->user_data) {
1713 win = (SilcClientWindow)sock->user_data;
1715 /* XXX Free all client entries and channel entries. */
1717 /* Clear ID caches */
1718 silc_idcache_del_all(win->client_cache);
1719 silc_idcache_del_all(win->channel_cache);
1722 if (win->remote_host)
1723 silc_free(win->remote_host);
1725 silc_free(win->local_id);
1726 if (win->local_id_data)
1727 silc_free(win->local_id_data);
1729 silc_cipher_free(win->send_key);
1730 if (win->receive_key)
1731 silc_cipher_free(win->receive_key);
1733 silc_hmac_free(win->hmac);
1734 if (win->hmac_key) {
1735 memset(win->hmac_key, 0, win->hmac_key_len);
1736 silc_free(win->hmac_key);
1740 win->remote_port = 0;
1741 win->remote_type = 0;
1742 win->send_key = NULL;
1743 win->receive_key = NULL;
1745 win->hmac_key = NULL;
1746 win->hmac_key_len = 0;
1747 win->local_id = NULL;
1748 win->local_id_data = NULL;
1749 win->remote_host = NULL;
1750 win->current_channel = NULL;
1753 if (sock->protocol) {
1754 silc_protocol_free(sock->protocol);
1755 sock->protocol = NULL;
1757 silc_socket_free(sock);
1760 /* Called when we receive disconnection packet from server. This
1761 closes our end properly and displays the reason of the disconnection
1764 void silc_client_disconnected_by_server(SilcClient client,
1765 SilcSocketConnection sock,
1770 SILC_LOG_DEBUG(("Server disconnected us, sock %d", sock->sock));
1772 msg = silc_calloc(message->len + 1, sizeof(char));
1773 memcpy(msg, message->data, message->len);
1774 silc_say(client, msg);
1777 SILC_SET_DISCONNECTED(sock);
1778 silc_client_close_connection(client, sock);
1781 /* Received error message from server. Display it on the screen.
1782 We don't take any action what so ever of the error message. */
1784 void silc_client_error_by_server(SilcClient client,
1785 SilcSocketConnection sock,
1790 msg = silc_calloc(message->len + 1, sizeof(char));
1791 memcpy(msg, message->data, message->len);
1792 silc_say(client, msg);
1796 /* Received notify message from server */
1798 void silc_client_notify_by_server(SilcClient client,
1799 SilcSocketConnection sock,
1804 msg = silc_calloc(message->len + 1, sizeof(char));
1805 memcpy(msg, message->data, message->len);
1806 silc_say(client, msg);
1810 /* Processes the received new Client ID from server. Old Client ID is
1811 deleted from cache and new one is added. */
1813 void silc_client_receive_new_id(SilcClient client,
1814 SilcSocketConnection sock,
1815 unsigned char *id_string)
1817 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1819 /* Delete old ID from ID cache */
1820 silc_idcache_del_by_id(win->client_cache, SILC_ID_CLIENT, win->local_id);
1822 /* Save the new ID */
1824 silc_free(win->local_id);
1825 win->local_id = silc_id_str2id(id_string, SILC_ID_CLIENT);
1826 if (win->local_id_data)
1827 silc_free(win->local_id_data);
1828 win->local_id_data =
1829 silc_calloc(SILC_ID_CLIENT_LEN, sizeof(unsigned char));
1830 memcpy(win->local_id_data, id_string, SILC_ID_CLIENT_LEN);
1831 win->local_id_data_len = SILC_ID_CLIENT_LEN;
1832 if (!win->local_entry)
1833 win->local_entry = silc_calloc(1, sizeof(*win->local_entry));
1834 win->local_entry->nickname = win->nickname;
1835 win->local_entry->id = win->local_id;
1837 /* Put it to the ID cache */
1838 silc_idcache_add(win->client_cache, win->nickname, SILC_ID_CLIENT,
1839 win->local_id, (void *)win->local_entry, TRUE);
1842 /* Processed received Channel ID for a channel. This is called when client
1843 joins to channel and server replies with channel ID. The ID is cached. */
1845 void silc_client_new_channel_id(SilcClient client,
1846 SilcSocketConnection sock,
1849 unsigned char *id_string)
1851 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1853 SilcChannelEntry channel;
1855 SILC_LOG_DEBUG(("New channel ID"));
1857 id = silc_id_str2id(id_string, SILC_ID_CHANNEL);
1858 channel = silc_calloc(1, sizeof(*channel));
1859 channel->channel_name = channel_name;
1861 channel->mode = mode;
1862 win->current_channel = channel;
1864 /* Put it to the ID cache */
1865 silc_idcache_add(win->channel_cache, channel_name, SILC_ID_CHANNEL,
1866 (void *)id, (void *)channel, TRUE);
1869 /* Processes received key for channel. The received key will be used
1870 to protect the traffic on the channel for now on. Client must receive
1871 the key to the channel before talking on the channel is possible.
1872 This is the key that server has generated, this is not the channel
1873 private key, it is entirely local setting. */
1875 void silc_client_receive_channel_key(SilcClient client,
1876 SilcSocketConnection sock,
1879 unsigned char *id_string, *key, *cipher;
1880 unsigned int key_len;
1881 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1883 SilcIDCacheEntry id_cache = NULL;
1884 SilcChannelEntry channel;
1885 SilcChannelKeyPayload payload;
1887 SILC_LOG_DEBUG(("Received key for channel"));
1889 payload = silc_channel_key_parse_payload(packet);
1893 id_string = silc_channel_key_get_id(payload, NULL);
1895 silc_channel_key_free_payload(payload);
1898 id = silc_id_str2id(id_string, SILC_ID_CHANNEL);
1901 if (!silc_idcache_find_by_id_one(win->channel_cache, (void *)id,
1902 SILC_ID_CHANNEL, &id_cache))
1906 key = silc_channel_key_get_key(payload, &key_len);
1907 cipher = silc_channel_key_get_cipher(payload, NULL);
1909 channel = (SilcChannelEntry)id_cache->context;
1910 channel->key_len = key_len;
1911 channel->key = silc_calloc(key_len, sizeof(*channel->key));
1912 memcpy(channel->key, key, key_len);
1914 silc_cipher_alloc(cipher, &channel->channel_key);
1915 if (!channel->channel_key) {
1916 silc_say(client, "Cannot talk to channel: unsupported cipher %s", cipher);
1919 channel->channel_key->cipher->set_key(channel->channel_key->context,
1922 /* Client is now joined to the channel */
1923 channel->on_channel = TRUE;
1927 silc_channel_key_free_payload(payload);
1930 /* Process received message to a channel (or from a channel, really). This
1931 decrypts the channel message with channel specific key and parses the
1932 channel payload. Finally it displays the message on the screen. */
1934 void silc_client_channel_message(SilcClient client,
1935 SilcSocketConnection sock,
1936 SilcPacketContext *packet)
1938 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1939 SilcBuffer buffer = packet->buffer;
1940 SilcChannelPayload payload = NULL;
1941 SilcChannelID *id = NULL;
1942 SilcChannelEntry channel;
1943 SilcIDCacheEntry id_cache = NULL;
1946 if (packet->dst_id_type != SILC_ID_CHANNEL)
1949 id = silc_id_str2id(packet->dst_id, SILC_ID_CHANNEL);
1951 /* Find the channel entry from channels on this window */
1952 if (!silc_idcache_find_by_id_one(win->channel_cache, (void *)id,
1953 SILC_ID_CHANNEL, &id_cache))
1956 channel = (SilcChannelEntry)id_cache->context;
1958 /* Decrypt the channel message payload. Push the IV out of the way,
1959 since it is not encrypted (after pushing buffer->tail has the IV). */
1960 silc_buffer_push_tail(buffer, 16);
1961 channel->channel_key->cipher->decrypt(channel->channel_key->context,
1962 buffer->data, buffer->data,
1963 buffer->len, buffer->tail);
1964 silc_buffer_pull_tail(buffer, 16);
1966 /* Parse the channel message payload */
1967 payload = silc_channel_parse_payload(buffer);
1971 /* Display the message on screen */
1972 if (packet->src_id_type == SILC_ID_CLIENT) {
1973 /* Message from client */
1974 if (channel == win->current_channel)
1975 silc_print(client, "<%s> %s",
1976 silc_channel_get_nickname(payload, NULL),
1977 silc_channel_get_data(payload, NULL));
1979 silc_print(client, "<%s:%s> %s",
1980 silc_channel_get_nickname(payload, NULL),
1981 channel->channel_name,
1982 silc_channel_get_data(payload, NULL));
1984 /* Message from server */
1985 silc_say(client, "%s", silc_channel_get_data(payload, NULL));
1992 silc_channel_free_payload(payload);