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.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.
29 * Revision 1.8 2000/07/12 05:56:32 priikone
30 * Major rewrite of ID Cache system. Support added for the new
33 * Revision 1.7 2000/07/10 05:40:33 priikone
36 * Revision 1.6 2000/07/07 06:54:16 priikone
37 * Print channel name when receiving channel message to non-current
40 * Revision 1.5 2000/07/06 07:14:36 priikone
41 * Fixes to NAMES command handling.
42 * Fixes when leaving from channel.
44 * Revision 1.4 2000/07/05 06:12:05 priikone
45 * Global cosmetic changes.
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.
51 * Revision 1.2 2000/07/03 05:49:48 priikone
52 * Implemented LEAVE command. Minor bug fixes.
54 * Revision 1.1.1.1 2000/06/27 11:36:56 priikone
55 * Imported from internal CVS/Added Log headers.
60 #include "clientincludes.h"
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);
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);
77 SilcClientWindow silc_client_create_main_window(SilcClient client);
78 SilcClientWindow silc_client_add_window(SilcClient client,
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);
88 /* Definitions from version.h */
89 extern char *silc_version;
90 extern char *silc_name;
91 extern char *silc_fullname;
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
97 int silc_client_alloc(SilcClient *new_client)
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;
110 /* Free's client object */
112 void silc_client_free(SilcClient client)
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
123 int silc_client_init(SilcClient client)
126 SILC_LOG_DEBUG(("Initializing client"));
129 client->username = silc_get_username();
130 client->realname = silc_get_real_name();
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);
138 /* Initialize hash functions for client to use */
139 silc_hash_alloc("md5", &client->md5hash);
140 silc_hash_alloc("sha1", &client->sha1hash);
142 /* Initialize none cipher */
143 silc_cipher_alloc("none", &client->none_cipher);
145 /* Initialize random number generator */
146 client->rng = silc_rng_alloc();
147 silc_rng_init(client->rng);
148 silc_math_primegen_init(); /* XXX */
150 /* Load public and private key */
151 if (silc_client_load_keys(client) == FALSE)
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) {
162 silc_task_queue_alloc(&client->timeout_queue, TRUE);
163 if (!client->timeout_queue) {
166 silc_task_queue_alloc(&client->generic_queue, TRUE);
167 if (!client->generic_queue) {
171 /* Initialize the scheduler */
172 silc_schedule_init(client->io_queue, client->timeout_queue,
173 client->generic_queue, 5000);
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,
181 SILC_TASK_PRI_NORMAL) == NULL) {
185 /* Register timeout task that updates clock every minute. */
186 if (silc_task_register(client->timeout_queue, 0,
187 silc_client_update_clock,
189 silc_client_time_til_next_min(), 0,
191 SILC_TASK_PRI_LOW) == NULL) {
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,
201 SILC_TASK_PRI_LOW) == NULL) {
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));
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);
220 silc_task_queue_free(client->timeout_queue);
222 silc_task_queue_free(client->io_queue);
227 /* Stops the client. This is called to stop the client and thus to stop
230 void silc_client_stop(SilcClient client)
232 SILC_LOG_DEBUG(("Stopping client"));
234 /* Stop the scheduler, although it might be already stopped. This
235 doesn't hurt anyone. This removes all the tasks and task queues,
237 silc_schedule_stop();
238 silc_schedule_uninit();
240 SILC_LOG_DEBUG(("Client client"));
243 /* Runs the client. */
245 void silc_client_run(SilcClient client)
247 SILC_LOG_DEBUG(("Running client"));
249 /* Start the scheduler, the heart of the SILC client. When this returns
250 the program will be terminated. */
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. */
259 SilcClientWindow silc_client_create_main_window(SilcClient client)
261 SilcClientWindow win;
264 SILC_LOG_DEBUG(("Creating main window"));
266 assert(client->screen != NULL);
268 client->screen->u_stat_line.program_name = silc_name;
269 client->screen->u_stat_line.program_version = silc_version;
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;
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);
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;
293 client->screen->bottom_line->nickname = win->nickname;
294 silc_screen_print_bottom_line(client->screen, 0);
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;
301 /* Automatically becomes the current active window */
302 client->current_win = win;
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. */
312 SilcClientWindow silc_client_add_window(SilcClient client,
315 SilcClientWindow win;
317 assert(client->screen != NULL);
319 win = silc_calloc(1, sizeof(*win));
321 /* Add the pointers */
322 win->screen = silc_screen_add_output_window(client->screen);
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);
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++;
336 if (is_current == TRUE)
337 client->current_win = win;
342 /* The main task on SILC client. This processes the key pressings user
345 SILC_TASK_CALLBACK(silc_client_process_key_press)
347 SilcClient client = (SilcClient)context;
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))
355 SILC_LOG_DEBUG(("Pressed key: %d", c));
359 * Special character handling
366 SILC_LOG_DEBUG(("RIGHT"));
367 silc_screen_input_cursor_right(client->screen);
371 SILC_LOG_DEBUG(("LEFT"));
372 silc_screen_input_cursor_left(client->screen);
379 silc_screen_input_backspace(client->screen);
385 /* Insert switch. Turns on/off insert on input window */
386 silc_screen_input_insert(client->screen);
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);
396 /* Refresh screen, Ctrl^l */
397 silc_screen_refresh_all(client->screen);
402 /* Beginning, Home */
403 silc_screen_input_cursor_home(client->screen);
408 silc_screen_input_cursor_end(client->screen);
426 /* Control codes are printed as reversed */
428 wattron(client->screen->input_win, A_REVERSE);
429 silc_screen_input_print(client->screen, c);
430 wattroff(client->screen->input_win, A_REVERSE);
432 /* Normal character */
433 silc_screen_input_print(client->screen, c);
437 silc_screen_print_coordinates(client->screen, 0);
438 silc_screen_refresh_win(client->screen->input_win);
441 static int silc_client_bad_keys(unsigned char key)
443 /* these are explained in curses.h */
458 case '\E': /* we ignore ESC */
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. */
468 static void silc_client_process_message(SilcClient client)
473 SILC_LOG_DEBUG(("Start"));
475 data = client->input_buffer->data;
478 if (data[0] == '/' && data[1] != ' ') {
480 unsigned int argc = 0;
481 unsigned char **argv, *tmpcmd;
482 unsigned int *argv_lens, *argv_types;
483 SilcClientCommand *cmd;
484 SilcClientCommandContext ctx;
486 /* Get the command */
487 tmpcmd = silc_client_parse_command(data);
489 /* Find command match */
490 for (cmd = silc_command_list; cmd->name; cmd++) {
491 if (!strcmp(cmd->name, tmpcmd))
495 if (cmd->name == NULL) {
496 silc_say(client, "Invalid command: %s", tmpcmd);
501 /* Now parse all arguments */
502 silc_client_parse_command_line(data, &argv, &argv_lens,
503 &argv_types, &argc, cmd->max_args);
506 SILC_LOG_DEBUG(("Exeuting command: %s", cmd->name));
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;
515 ctx->argv_lens = argv_lens;
516 ctx->argv_types = argv_types;
518 /* Execute command */
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);
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));
540 /* Returns the command fetched from user typed command line */
542 static char *silc_client_parse_command(unsigned char *buffer)
545 const char *cp = buffer;
548 len = strcspn(cp, " ");
549 ret = silc_to_upper((char *)++cp);
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. */
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)
569 const char *cp = buffer;
571 /* Take the '/' away */
574 *parsed = silc_calloc(1, sizeof(**parsed));
575 *parsed_lens = silc_calloc(1, sizeof(**parsed_lens));
577 /* Get the command first */
578 len = strcspn(cp, " ");
579 (*parsed)[0] = silc_to_upper((char *)cp);
580 (*parsed_lens)[0] = len;
584 /* Parse arguments */
585 if (strchr(cp, ' ') || strlen(cp) != 0) {
586 for (i = 1; i < max_args; i++) {
588 if (i != max_args - 1)
589 len = strcspn(cp, " ");
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;
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;
619 /* Updates clock on the screen every minute. */
621 SILC_TASK_CALLBACK(silc_client_update_clock)
623 SilcClient client = (SilcClient)context;
625 /* Update the clock on the screen */
626 silc_screen_print_clock(client->screen);
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,
634 silc_screen_refresh_win(client->screen->input_win);
637 /* Runs commands user configured in configuration file. This is
638 called when initializing client. */
640 SILC_TASK_CALLBACK(silc_client_run_commands)
642 SilcClient client = (SilcClient)context;
643 SilcClientConfigSectionCommand *cs;
645 SILC_LOG_DEBUG(("Start"));
647 cs = client->config->commands;
649 unsigned int argc = 0;
650 unsigned char **argv, *tmpcmd;
651 unsigned int *argv_lens, *argv_types;
652 SilcClientCommand *cmd;
653 SilcClientCommandContext ctx;
655 /* Get the command */
656 tmpcmd = silc_client_parse_command(cs->command);
658 for (cmd = silc_command_list; cmd->name; cmd++) {
659 if (!strcmp(cmd->name, tmpcmd))
663 if (cmd->name == NULL) {
664 silc_say(client, "Invalid command: %s", tmpcmd);
669 /* Now parse all arguments */
670 silc_client_parse_command_line(cs->command, &argv, &argv_lens,
671 &argv_types, &argc, cmd->max_args);
674 SILC_LOG_DEBUG(("Exeuting command: %s", cmd->name));
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;
683 ctx->argv_lens = argv_lens;
684 ctx->argv_types = argv_types;
686 /* Execute command */
693 /* Internal context for connection process. This is needed as we
694 doing asynchronous connecting. */
702 } SilcClientInternalConnectContext;
705 silc_client_connect_to_server_internal(SilcClientInternalConnectContext *ctx)
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);
716 /* Register task that will receive the async connect and will
718 ctx->task = silc_task_register(ctx->client->io_queue, sock,
719 silc_client_connect_to_server_start,
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);
731 /* Connects to remote server */
733 int silc_client_connect_to_server(SilcClient client, int port,
736 SilcClientInternalConnectContext *ctx;
738 SILC_LOG_DEBUG(("Connecting to port %d of server %s",
741 silc_say(client, "Connecting to port %d of server %s", port, host);
743 client->current_win->remote_host = strdup(host);
744 client->current_win->remote_port = port;
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);
754 /* Do the actual connecting process */
755 return silc_client_connect_to_server_internal(ctx);
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. */
761 SILC_TASK_CALLBACK(silc_client_connect_to_server_start)
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);
770 SILC_LOG_DEBUG(("Start"));
772 /* Check the socket status as it might be in error */
773 getsockopt(fd, SOL_SOCKET, SO_ERROR, &opt, &opt_len);
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);
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);
788 silc_client_connect_to_server_internal(ctx);
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);
802 silc_schedule_unset_listen_fd(fd);
803 silc_task_unregister(client->io_queue, ctx->task);
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);
815 client->current_win->sock->hostname = client->current_win->remote_host;
816 client->current_win->sock->port = client->current_win->remote_port;
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;
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);
832 silc_say(client, "Error: Could not start authentication protocol");
835 client->current_win->sock->protocol = protocol;
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);
846 /* Execute the protocol */
847 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0);
850 /* Second part of the connecting to the server. This executed
851 authentication protocol. */
853 SILC_TASK_CALLBACK(silc_client_connect_to_server_second)
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;
862 SILC_LOG_DEBUG(("Start"));
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);
869 silc_ske_free(ctx->ske);
871 silc_free(ctx->dest_id);
872 ctx->sock->protocol = NULL;
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;
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;
891 /* Check if we find a match from user configured connections */
892 conn = silc_client_config_find_connection(client->config,
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);
903 /* No match found. Resolve by sending AUTH_REQUEST to server */
904 proto_ctx->auth_meth = SILC_PROTOCOL_CONN_AUTH_NONE;
907 /* XXX Resolve by sending AUTH_REQUEST to server */
908 proto_ctx->auth_meth = SILC_PROTOCOL_CONN_AUTH_NONE;
911 /* Free old protocol as it is finished now */
912 silc_protocol_free(protocol);
914 silc_buffer_free(ctx->packet);
916 /* silc_free(ctx->keymat....); */
917 sock->protocol = NULL;
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
923 silc_protocol_alloc(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
924 &sock->protocol, (void *)proto_ctx,
925 silc_client_connect_to_server_final);
927 /* Execute the protocol */
928 sock->protocol->execute(client->timeout_queue, 0, sock->protocol, fd, 0, 0);
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
936 SILC_TASK_CALLBACK(silc_client_connect_to_server_final)
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;
945 SILC_LOG_DEBUG(("Start"));
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);
952 silc_free(ctx->auth_data);
954 silc_ske_free(ctx->ske);
956 silc_free(ctx->dest_id);
958 win->sock->protocol = NULL;
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)),
977 /* Send the packet */
978 silc_client_packet_send(client, ctx->sock, SILC_PACKET_NEW_CLIENT,
980 packet->data, packet->len, TRUE);
981 silc_buffer_free(packet);
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;
988 silc_say(client, "Connected to port %d of host %s",
989 win->remote_port, win->remote_host);
991 client->screen->bottom_line->connection = win->remote_host;
992 silc_screen_print_bottom_line(client->screen, 0);
994 silc_protocol_free(protocol);
996 silc_free(ctx->auth_data);
998 silc_ske_free(ctx->ske);
1000 silc_free(ctx->dest_id);
1002 win->sock->protocol = NULL;
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. */
1009 static int silc_client_packet_send_real(SilcClient client,
1010 SilcSocketConnection sock,
1015 /* Send the packet */
1016 ret = silc_packet_send(sock, force_send);
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);
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);
1034 /* Packet processing callback. This is used to send and receive packets
1035 from network. This is generic task. */
1037 SILC_TASK_CALLBACK(silc_client_packet_process)
1039 SilcClient client = (SilcClient)context;
1040 SilcSocketConnection sock = NULL;
1041 SilcClientWindow win;
1044 SILC_LOG_DEBUG(("Processing packet"));
1046 SILC_CLIENT_GET_SOCK(client, fd, sock);
1050 win = (SilcClientWindow)sock->user_data;
1052 /* Packet sending */
1053 if (type == SILC_TASK_WRITE) {
1054 SILC_LOG_DEBUG(("Writing data to connection"));
1056 if (sock->outbuf->data - sock->outbuf->head)
1057 silc_buffer_push(sock->outbuf,
1058 sock->outbuf->data - sock->outbuf->head);
1060 ret = silc_client_packet_send_real(client, sock, TRUE);
1062 /* If returned -2 could not write to connection now, will do
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);
1074 silc_buffer_clear(sock->outbuf);
1078 /* Packet receiving */
1079 if (type == SILC_TASK_READ) {
1080 SILC_LOG_DEBUG(("Reading data from connection"));
1082 /* Read data from network */
1083 ret = silc_packet_receive(sock);
1089 SILC_LOG_DEBUG(("Read EOF"));
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);
1098 silc_say(client, "Connection closed: premature EOF");
1099 SILC_LOG_DEBUG(("Premature EOF from connection %d", sock->sock));
1101 silc_client_close_connection(client, sock);
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);
1115 /* Parses whole packet, received earlier. */
1117 SILC_TASK_CALLBACK(silc_client_packet_parse_real)
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;
1127 SILC_LOG_DEBUG(("Start"));
1129 /* Decrypt the received packet */
1130 ret = silc_packet_decrypt(win->receive_key, win->hmac, buffer, packet);
1135 /* Parse the packet. Packet type is returned. */
1136 ret = silc_packet_parse(packet);
1138 /* Parse the packet header in special way as this is "special"
1140 ret = silc_packet_parse_special(packet);
1143 if (ret == SILC_PACKET_NONE)
1146 /* Parse the incoming packet type */
1147 silc_client_packet_parse_type(client, sock, packet);
1150 silc_buffer_clear(buffer);
1152 silc_free(parse_ctx);
1155 /* Parser callback called by silc_packet_receive_process. Thie merely
1156 registers timeout that will handle the actual parsing when appropriate. */
1158 void silc_client_packet_parse(SilcPacketParserContext *parser_context)
1160 SilcClient client = (SilcClient)parser_context->context;
1161 SilcClientWindow win = (SilcClientWindow)parser_context->sock->user_data;
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,
1173 SILC_TASK_PRI_NORMAL);
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,
1180 SILC_TASK_PRI_NORMAL);
1184 /* Parses the packet type and calls what ever routines the packet type
1185 requires. This is done for all incoming packets. */
1187 void silc_client_packet_parse_type(SilcClient client,
1188 SilcSocketConnection sock,
1189 SilcPacketContext *packet)
1191 SilcBuffer buffer = packet->buffer;
1192 SilcPacketType type = packet->type;
1194 SILC_LOG_DEBUG(("Parsing packet type %d", type));
1196 /* Parse the packet type */
1198 case SILC_PACKET_DISCONNECT:
1199 silc_client_disconnected_by_server(client, sock, buffer);
1201 case SILC_PACKET_SUCCESS:
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.
1207 if (sock->protocol) {
1208 sock->protocol->execute(client->timeout_queue, 0,
1209 sock->protocol, sock->sock, 0, 0);
1212 case SILC_PACKET_FAILURE:
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.
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);
1224 case SILC_PACKET_REJECT:
1227 case SILC_PACKET_NOTIFY:
1229 * Received notify message
1231 silc_client_notify_by_server(client, sock, buffer);
1234 case SILC_PACKET_ERROR:
1236 * Received error message
1238 silc_client_error_by_server(client, sock, buffer);
1241 case SILC_PACKET_CHANNEL_MESSAGE:
1243 * Received message to (from, actually) a channel
1245 silc_client_channel_message(client, sock, packet);
1247 case SILC_PACKET_CHANNEL_KEY:
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.
1253 silc_client_receive_channel_key(client, sock, buffer);
1256 case SILC_PACKET_PRIVATE_MESSAGE:
1258 * Received private message
1261 SilcClientCommandReplyContext ctx;
1262 ctx = silc_calloc(1, sizeof(*ctx));
1263 ctx->client = client;
1265 ctx->context = buffer; /* kludge */
1266 silc_client_command_reply_msg((void *)ctx);
1269 case SILC_PACKET_PRIVATE_MESSAGE_KEY:
1271 * Received private message key
1275 case SILC_PACKET_COMMAND_REPLY:
1277 * Recived reply for a command
1279 silc_client_command_reply_process(client, sock, packet);
1282 case SILC_PACKET_KEY_EXCHANGE:
1283 if (sock->protocol) {
1284 SilcClientKEInternalContext *proto_ctx =
1285 (SilcClientKEInternalContext *)sock->protocol->context;
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);
1291 /* Let the protocol handle the packet */
1292 sock->protocol->execute(client->timeout_queue, 0,
1293 sock->protocol, sock->sock, 0, 0);
1295 SILC_LOG_ERROR(("Received Key Exchange packet but no key exchange "
1296 "protocol active, packet dropped."));
1298 /* XXX Trigger KE protocol?? Rekey actually! */
1302 case SILC_PACKET_KEY_EXCHANGE_1:
1303 if (sock->protocol) {
1306 SILC_LOG_ERROR(("Received Key Exchange 1 packet but no key exchange "
1307 "protocol active, packet dropped."));
1310 case SILC_PACKET_KEY_EXCHANGE_2:
1311 if (sock->protocol) {
1312 SilcClientKEInternalContext *proto_ctx =
1313 (SilcClientKEInternalContext *)sock->protocol->context;
1315 if (proto_ctx->packet)
1316 silc_buffer_free(proto_ctx->packet);
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);
1322 /* Let the protocol handle the packet */
1323 sock->protocol->execute(client->timeout_queue, 0,
1324 sock->protocol, sock->sock, 0, 0);
1326 SILC_LOG_ERROR(("Received Key Exchange 2 packet but no key exchange "
1327 "protocol active, packet dropped."));
1331 case SILC_PACKET_NEW_ID:
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.
1339 unsigned char *id_string;
1340 unsigned short id_type;
1342 silc_buffer_unformat(buffer,
1343 SILC_STR_UI_SHORT(&id_type),
1344 SILC_STR_UI16_STRING_ALLOC(&id_string),
1347 if ((SilcIdType)id_type != SILC_ID_CLIENT)
1350 silc_client_receive_new_id(client, sock, id_string);
1351 silc_free(id_string);
1356 SILC_LOG_DEBUG(("Incorrect packet type %d, packet dropped", type));
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
1367 void silc_client_packet_send(SilcClient client,
1368 SilcSocketConnection sock,
1369 SilcPacketType type,
1371 SilcIdType dst_id_type,
1374 unsigned char *data,
1375 unsigned int data_len,
1378 SilcPacketContext packetdata;
1380 SILC_LOG_DEBUG(("Sending packet, type %d", type));
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;
1387 if (!hmac && ((SilcClientWindow)sock->user_data)->hmac)
1388 hmac = ((SilcClientWindow)sock->user_data)->hmac;
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;
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;
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;
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;
1410 packetdata.dst_id = NULL;
1411 packetdata.dst_id_len = 0;
1412 packetdata.dst_id_type = SILC_ID_NONE;
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);
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,
1427 SILC_LOG_DEBUG(("Putting data to outgoing buffer, len %d", data_len));
1429 packetdata.buffer = sock->outbuf;
1431 /* Put the data to the buffer */
1432 if (data && data_len)
1433 silc_buffer_put(sock->outbuf, data, data_len);
1435 /* Create the outgoing packet */
1436 silc_packet_assemble(&packetdata);
1438 /* Encrypt the packet */
1440 silc_packet_encrypt(cipher, hmac, sock->outbuf, sock->outbuf->len);
1442 SILC_LOG_HEXDUMP(("Packet, len %d", sock->outbuf->len),
1443 sock->outbuf->data, sock->outbuf->len);
1445 /* Now actually send the packet */
1446 silc_client_packet_send_real(client, sock, force_send);
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. */
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,
1463 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1465 SilcPacketContext packetdata;
1468 unsigned char *id_string;
1470 SILC_LOG_DEBUG(("Sending packet to channel"));
1472 if (!channel || !channel->key) {
1473 silc_say(client, "Cannot talk to channel: key does not exist");
1479 for (i = 0; i < 16; i++)
1480 channel->iv[i] = silc_rng_get_byte(client->rng);
1482 silc_hash_make(client->md5hash, channel->iv, 16, channel->iv);
1484 /* Encode the channel payload */
1485 payload = silc_channel_encode_payload(strlen(win->nickname), win->nickname,
1486 data_len, data, 16, channel->iv,
1490 "Error: Could not create packet to be sent to the channel");
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;
1499 id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
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));
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,
1527 packetdata.buffer = sock->outbuf;
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 */
1535 /* Put the actual encrypted payload data into the buffer. */
1536 silc_buffer_put(sock->outbuf, payload->data, payload->len);
1538 /* Create the outgoing packet */
1539 silc_packet_assemble(&packetdata);
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 +
1547 SILC_LOG_HEXDUMP(("Packet to channel, len %d", sock->outbuf->len),
1548 sock->outbuf->data, sock->outbuf->len);
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);
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
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,
1570 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1572 SilcPacketContext packetdata;
1573 unsigned int nick_len;
1577 SILC_LOG_DEBUG(("Sending private message"));
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,
1587 SILC_STR_UI_XNSTRING(data, data_len),
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);
1601 /* We have private message specific key */
1603 /* Get data used in the encryption */
1604 cipher = client_entry->send_key;
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;
1614 packetdata.dst_id = silc_id_id2str(client_entry->id, SILC_ID_CLIENT);
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));
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,
1634 packetdata.buffer = sock->outbuf;
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);
1641 /* Put the actual encrypted payload data into the buffer. */
1642 silc_buffer_put(sock->outbuf, buffer->data, buffer->len);
1644 /* Create the outgoing packet */
1645 silc_packet_assemble(&packetdata);
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 +
1652 SILC_LOG_HEXDUMP(("Private message packet, len %d", sock->outbuf->len),
1653 sock->outbuf->data, sock->outbuf->len);
1655 /* Now actually send the packet */
1656 silc_client_packet_send_real(client, sock, force_send);
1657 silc_free(packetdata.dst_id);
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. */
1666 void silc_client_close_connection(SilcClient client,
1667 SilcSocketConnection sock)
1669 SilcClientWindow win;
1671 /* We won't listen for this connection anymore */
1672 silc_schedule_unset_listen_fd(sock->sock);
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);
1678 /* Close the actual connection */
1679 silc_net_close_connection(sock->sock);
1681 silc_say(client, "Closed connection to host %s", sock->hostname ?
1682 sock->hostname : sock->ip);
1684 /* Free everything */
1685 if (sock->user_data) {
1686 win = (SilcClientWindow)sock->user_data;
1688 /* XXX Free all client entries and channel entries. */
1690 /* Clear ID caches */
1691 silc_idcache_del_all(win->client_cache);
1692 silc_idcache_del_all(win->channel_cache);
1695 if (win->remote_host)
1696 silc_free(win->remote_host);
1698 silc_free(win->local_id);
1699 if (win->local_id_data)
1700 silc_free(win->local_id_data);
1702 silc_cipher_free(win->send_key);
1703 if (win->receive_key)
1704 silc_cipher_free(win->receive_key);
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);
1713 win->remote_port = 0;
1714 win->remote_type = 0;
1715 win->send_key = NULL;
1716 win->receive_key = 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;
1726 if (sock->protocol) {
1727 silc_protocol_free(sock->protocol);
1728 sock->protocol = NULL;
1730 silc_socket_free(sock);
1733 /* Called when we receive disconnection packet from server. This
1734 closes our end properly and displays the reason of the disconnection
1737 void silc_client_disconnected_by_server(SilcClient client,
1738 SilcSocketConnection sock,
1743 SILC_LOG_DEBUG(("Server disconnected us, sock %d", sock->sock));
1745 msg = silc_calloc(message->len + 1, sizeof(char));
1746 memcpy(msg, message->data, message->len);
1747 silc_say(client, msg);
1750 SILC_SET_DISCONNECTED(sock);
1751 silc_client_close_connection(client, sock);
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. */
1757 void silc_client_error_by_server(SilcClient client,
1758 SilcSocketConnection sock,
1763 msg = silc_calloc(message->len + 1, sizeof(char));
1764 memcpy(msg, message->data, message->len);
1765 silc_say(client, msg);
1769 /* Received notify message from server */
1771 void silc_client_notify_by_server(SilcClient client,
1772 SilcSocketConnection sock,
1777 msg = silc_calloc(message->len + 1, sizeof(char));
1778 memcpy(msg, message->data, message->len);
1779 silc_say(client, msg);
1783 /* Processes the received new Client ID from server. Old Client ID is
1784 deleted from cache and new one is added. */
1786 void silc_client_receive_new_id(SilcClient client,
1787 SilcSocketConnection sock,
1788 unsigned char *id_string)
1790 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1792 /* Delete old ID from ID cache */
1793 silc_idcache_del_by_id(win->client_cache, SILC_ID_CLIENT, win->local_id);
1795 /* Save the new 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;
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);
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. */
1818 void silc_client_new_channel_id(SilcClient client,
1819 SilcSocketConnection sock,
1822 unsigned char *id_string)
1824 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1826 SilcChannelEntry channel;
1828 SILC_LOG_DEBUG(("New channel ID"));
1830 id = silc_id_str2id(id_string, SILC_ID_CHANNEL);
1831 channel = silc_calloc(1, sizeof(*channel));
1832 channel->channel_name = channel_name;
1834 channel->mode = mode;
1835 win->current_channel = channel;
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);
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. */
1848 void silc_client_receive_channel_key(SilcClient client,
1849 SilcSocketConnection sock,
1852 unsigned char *id_string, *key, *cipher;
1853 unsigned int key_len;
1854 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1856 SilcIDCacheEntry id_cache = NULL;
1857 SilcChannelEntry channel;
1858 SilcChannelKeyPayload payload;
1860 SILC_LOG_DEBUG(("Received key for channel"));
1862 payload = silc_channel_key_parse_payload(packet);
1866 id_string = silc_channel_key_get_id(payload, NULL);
1868 silc_channel_key_free_payload(payload);
1871 id = silc_id_str2id(id_string, SILC_ID_CHANNEL);
1874 if (!silc_idcache_find_by_id_one(win->channel_cache, (void *)id,
1875 SILC_ID_CHANNEL, &id_cache))
1879 key = silc_channel_key_get_key(payload, &key_len);
1880 cipher = silc_channel_key_get_cipher(payload, NULL);
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);
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);
1892 channel->channel_key->cipher->set_key(channel->channel_key->context,
1895 /* Client is now joined to the channel */
1896 channel->on_channel = TRUE;
1900 silc_channel_key_free_payload(payload);
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. */
1907 void silc_client_channel_message(SilcClient client,
1908 SilcSocketConnection sock,
1909 SilcPacketContext *packet)
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;
1919 if (packet->dst_id_type != SILC_ID_CHANNEL)
1922 id = silc_id_str2id(packet->dst_id, SILC_ID_CHANNEL);
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))
1929 channel = (SilcChannelEntry)id_cache->context;
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);
1939 /* Parse the channel message payload */
1940 payload = silc_channel_parse_payload(buffer);
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));
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));
1957 /* Message from server */
1958 silc_say(client, "%s", silc_channel_get_data(payload, NULL));
1965 silc_channel_free_payload(payload);