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.4 2000/07/05 06:12:05 priikone
24 * Global cosmetic changes.
26 * Revision 1.3 2000/07/04 08:29:12 priikone
27 * Added support for PING command. The ping times are calculated
28 * and showed to the user.
30 * Revision 1.2 2000/07/03 05:49:48 priikone
31 * Implemented LEAVE command. Minor bug fixes.
33 * Revision 1.1.1.1 2000/06/27 11:36:56 priikone
34 * Imported from internal CVS/Added Log headers.
39 #include "clientincludes.h"
41 /* Static function prototypes */
42 static int silc_client_bad_keys(unsigned char key);
43 static void silc_client_process_message(SilcClient client);
44 static char *silc_client_parse_command(unsigned char *buffer);
46 /* Static task callback prototypes */
47 SILC_TASK_CALLBACK(silc_client_update_clock);
48 SILC_TASK_CALLBACK(silc_client_run_commands);
49 SILC_TASK_CALLBACK(silc_client_process_key_press);
50 SILC_TASK_CALLBACK(silc_client_connect_to_server_start);
51 SILC_TASK_CALLBACK(silc_client_connect_to_server_second);
52 SILC_TASK_CALLBACK(silc_client_connect_to_server_final);
53 SILC_TASK_CALLBACK(silc_client_packet_process);
54 SILC_TASK_CALLBACK(silc_client_packet_parse);
56 SilcClientWindow silc_client_create_main_window(SilcClient client);
57 SilcClientWindow silc_client_add_window(SilcClient client,
59 void silc_client_packet_parse_type(SilcClient client,
60 SilcSocketConnection sock,
61 SilcPacketContext *packet);
62 void silc_client_private_message_process(SilcClient client,
63 SilcSocketConnection sock,
64 SilcPacketContext *packet);
66 /* Definitions from version.h */
67 extern char *silc_version;
68 extern char *silc_name;
69 extern char *silc_fullname;
71 /* Allocates new client object. This has to be done before client may
72 work. After calling this one must call silc_client_init to initialize
75 int silc_client_alloc(SilcClient *new_client)
78 *new_client = silc_calloc(1, sizeof(**new_client));
79 (*new_client)->input_buffer = NULL;
80 (*new_client)->screen = NULL;
81 (*new_client)->windows = NULL;
82 (*new_client)->windows_count = 0;
83 (*new_client)->current_win = NULL;
88 /* Free's client object */
90 void silc_client_free(SilcClient client)
97 /* Initializes the client. This makes all the necessary steps to make
98 the client ready to be run. One must call silc_client_run to run the
101 int silc_client_init(SilcClient client)
104 SILC_LOG_DEBUG(("Initializing client"));
107 client->username = silc_get_username();
108 client->realname = silc_get_real_name();
110 /* Register all configured ciphers, PKCS and hash functions. */
111 client->config->client = (void *)client;
112 silc_client_config_register_ciphers(client->config);
113 silc_client_config_register_pkcs(client->config);
114 silc_client_config_register_hashfuncs(client->config);
116 /* Initialize hash functions for client to use */
117 silc_hash_alloc("md5", &client->md5hash);
118 silc_hash_alloc("sha1", &client->sha1hash);
120 /* Initialize none cipher */
121 silc_cipher_alloc("none", &client->none_cipher);
123 /* Initialize random number generator */
124 client->rng = silc_rng_alloc();
125 silc_rng_init(client->rng);
126 silc_math_primegen_init(); /* XXX */
128 /* Load public and private key */
129 if (silc_client_load_keys(client) == FALSE)
132 /* Register the task queues. In SILC we have by default three task queues.
133 One task queue for non-timeout tasks which perform different kind of
134 I/O on file descriptors, timeout task queue for timeout tasks, and,
135 generic non-timeout task queue whose tasks apply to all connections. */
136 silc_task_queue_alloc(&client->io_queue, TRUE);
137 if (!client->io_queue) {
140 silc_task_queue_alloc(&client->timeout_queue, TRUE);
141 if (!client->timeout_queue) {
144 silc_task_queue_alloc(&client->generic_queue, TRUE);
145 if (!client->generic_queue) {
149 /* Initialize the scheduler */
150 silc_schedule_init(client->io_queue, client->timeout_queue,
151 client->generic_queue, 5000);
153 /* Register the main task that is used in client. This received
154 the key pressings. */
155 if (silc_task_register(client->io_queue, fileno(stdin),
156 silc_client_process_key_press,
157 (void *)client, 0, 0,
159 SILC_TASK_PRI_NORMAL) == NULL) {
163 /* Register timeout task that updates clock every minute. */
164 if (silc_task_register(client->timeout_queue, 0,
165 silc_client_update_clock,
167 silc_client_time_til_next_min(), 0,
169 SILC_TASK_PRI_LOW) == NULL) {
173 if (client->config->commands) {
174 /* Run user configured commands with timeout */
175 if (silc_task_register(client->timeout_queue, 0,
176 silc_client_run_commands,
177 (void *)client, 0, 1,
179 SILC_TASK_PRI_LOW) == NULL) {
184 /* Allocate the input buffer used to save typed characters */
185 client->input_buffer = silc_buffer_alloc(SILC_SCREEN_INPUT_WIN_SIZE);
186 silc_buffer_pull_tail(client->input_buffer,
187 SILC_BUFFER_END(client->input_buffer));
189 /* Initialize the screen */
190 client->screen = silc_screen_init();
191 silc_client_create_main_window(client);
192 client->screen->input_buffer = client->input_buffer->data;
193 silc_screen_print_coordinates(client->screen, 0);
198 silc_task_queue_free(client->timeout_queue);
200 silc_task_queue_free(client->io_queue);
205 /* Stops the client. This is called to stop the client and thus to stop
208 void silc_client_stop(SilcClient client)
210 SILC_LOG_DEBUG(("Stopping client"));
212 /* Stop the scheduler, although it might be already stopped. This
213 doesn't hurt anyone. This removes all the tasks and task queues,
215 silc_schedule_stop();
216 silc_schedule_uninit();
218 SILC_LOG_DEBUG(("Client client"));
221 /* Runs the client. */
223 void silc_client_run(SilcClient client)
225 SILC_LOG_DEBUG(("Running client"));
227 /* Start the scheduler, the heart of the SILC client. When this returns
228 the program will be terminated. */
232 /* Creates the main window used in SILC client. This is called always
233 at the initialization of the client. If user wants to create more
234 than one windows a new windows are always created by calling
235 silc_client_add_window. */
237 SilcClientWindow silc_client_create_main_window(SilcClient client)
239 SilcClientWindow win;
242 SILC_LOG_DEBUG(("Creating main window"));
244 assert(client->screen != NULL);
246 win = silc_calloc(1, sizeof(*win));
248 client->screen->u_stat_line.program_name = silc_name;
249 client->screen->u_stat_line.program_version = silc_version;
251 /* Add the pointers */
252 win->nickname = silc_get_username();
253 win->local_id = NULL;
254 win->local_id_data = NULL;
255 win->local_id_data_len = 0;
256 win->remote_host = NULL;
257 win->remote_port = -1;
260 /* Create the actual screen */
261 screen = (void *)silc_screen_create_output_window(client->screen);
262 silc_screen_create_input_window(client->screen);
263 silc_screen_init_upper_status_line(client->screen);
264 silc_screen_init_output_status_line(client->screen);
265 win->screen = screen;
267 client->screen->bottom_line->nickname = win->nickname;
268 silc_screen_print_bottom_line(client->screen, 0);
270 /* Add the window to windows table */
271 client->windows = silc_calloc(1, sizeof(*client->windows));
272 client->windows[client->windows_count] = win;
273 client->windows_count = 1;
275 /* Automatically becomes the current active window */
276 client->current_win = win;
281 /* Allocates and adds new window to the client. This allocates new
282 physical window and internal window for connection specific data.
283 All the connection specific data is always saved into a window
284 since connection is always associated to a active window. */
286 SilcClientWindow silc_client_add_window(SilcClient client,
289 SilcClientWindow win;
291 assert(client->screen != NULL);
293 win = silc_calloc(1, sizeof(*win));
295 /* Add the pointers */
296 win->screen = silc_screen_add_output_window(client->screen);
299 /* Add the window to windows table */
300 client->windows = silc_realloc(client->windows, sizeof(*client->windows)
301 * (client->windows_count + 1));
302 client->windows[client->windows_count] = win;
303 client->windows_count++;
305 if (is_current == TRUE)
306 client->current_win = win;
311 /* The main task on SILC client. This processes the key pressings user
314 SILC_TASK_CALLBACK(silc_client_process_key_press)
316 SilcClient client = (SilcClient)context;
319 /* There is data pending in stdin, this gets it directly */
320 c = wgetch(client->screen->input_win);
321 if (silc_client_bad_keys(c))
324 SILC_LOG_DEBUG(("Pressed key: %d", c));
328 * Special character handling
335 SILC_LOG_DEBUG(("RIGHT"));
336 silc_screen_input_cursor_right(client->screen);
340 SILC_LOG_DEBUG(("LEFT"));
341 silc_screen_input_cursor_left(client->screen);
348 silc_screen_input_backspace(client->screen);
354 /* Insert switch. Turns on/off insert on input window */
355 silc_screen_input_insert(client->screen);
359 /* Enter, Return. User pressed enter we are ready to
360 process the message. */
361 silc_client_process_message(client);
362 silc_screen_input_reset(client->screen);
365 /* Refresh screen, Ctrl^l */
366 silc_screen_refresh_all(client->screen);
371 /* Beginning, Home */
372 silc_screen_input_cursor_home(client->screen);
377 silc_screen_input_cursor_end(client->screen);
395 /* Control codes are printed as reversed */
397 wattron(client->screen->input_win, A_REVERSE);
398 silc_screen_input_print(client->screen, c);
399 wattroff(client->screen->input_win, A_REVERSE);
401 /* Normal character */
402 silc_screen_input_print(client->screen, c);
406 silc_screen_print_coordinates(client->screen, 0);
407 silc_screen_refresh_win(client->screen->input_win);
410 static int silc_client_bad_keys(unsigned char key)
412 /* these are explained in curses.h */
427 case '\E': /* we ignore ESC */
434 /* Processes messages user has typed on the screen. This either sends
435 a packet out to network or if command were written executes it. */
437 static void silc_client_process_message(SilcClient client)
442 SILC_LOG_DEBUG(("Start"));
444 data = client->input_buffer->data;
447 if (data[0] == '/' && data[1] != ' ') {
449 unsigned int argc = 0;
450 unsigned char **argv, *tmpcmd;
451 unsigned int *argv_lens, *argv_types;
452 SilcClientCommand *cmd;
453 SilcClientCommandContext ctx;
455 /* Get the command */
456 tmpcmd = silc_client_parse_command(data);
458 /* Find command match */
459 for (cmd = silc_command_list; cmd->name; cmd++) {
460 if (!strcmp(cmd->name, tmpcmd))
464 if (cmd->name == NULL) {
465 silc_say(client, "Invalid command: %s", tmpcmd);
470 /* Now parse all arguments */
471 silc_client_parse_command_line(data, &argv, &argv_lens,
472 &argv_types, &argc, cmd->max_args);
475 SILC_LOG_DEBUG(("Exeuting command: %s", cmd->name));
477 /* Allocate command context. This and its internals must be free'd
478 by the command routine receiving it. */
479 ctx = silc_calloc(1, sizeof(*ctx));
480 ctx->client = client;
481 ctx->sock = client->current_win->sock;
484 ctx->argv_lens = argv_lens;
485 ctx->argv_types = argv_types;
487 /* Execute command */
491 /* Normal message to a channel */
492 if (len && client->current_win->current_channel &&
493 client->current_win->current_channel->on_channel == TRUE) {
494 silc_print(client, "> %s", data);
495 silc_client_packet_send_to_channel(client,
496 client->current_win->sock,
497 client->current_win->current_channel,
498 data, strlen(data), TRUE);
503 /* Clear the input buffer */
504 silc_buffer_clear(client->input_buffer);
505 silc_buffer_pull_tail(client->input_buffer,
506 SILC_BUFFER_END(client->input_buffer));
509 /* Returns the command fetched from user typed command line */
511 static char *silc_client_parse_command(unsigned char *buffer)
514 const char *cp = buffer;
517 len = strcspn(cp, " ");
518 ret = silc_to_upper((char *)++cp);
524 /* Parses user typed command line. At most `max_args' is taken. Rest
525 of the line will be allocated as the last argument if there are more
526 than `max_args' arguments in the line. Note that the command name
527 is counted as one argument and is saved. */
529 void silc_client_parse_command_line(unsigned char *buffer,
530 unsigned char ***parsed,
531 unsigned int **parsed_lens,
532 unsigned int **parsed_types,
533 unsigned int *parsed_num,
534 unsigned int max_args)
538 const char *cp = buffer;
540 /* Take the '/' away */
543 *parsed = silc_calloc(1, sizeof(**parsed));
544 *parsed_lens = silc_calloc(1, sizeof(**parsed_lens));
546 /* Get the command first */
547 len = strcspn(cp, " ");
548 (*parsed)[0] = silc_to_upper((char *)cp);
549 (*parsed_lens)[0] = len;
553 /* Parse arguments */
554 if (strchr(cp, ' ') || strlen(cp) != 0) {
555 for (i = 1; i < max_args; i++) {
557 if (i != max_args - 1)
558 len = strcspn(cp, " ");
562 *parsed = silc_realloc(*parsed, sizeof(**parsed) * (argc + 1));
563 *parsed_lens = silc_realloc(*parsed_lens,
564 sizeof(**parsed_lens) * (argc + 1));
565 (*parsed)[argc] = silc_calloc(len + 1, sizeof(char));
566 memcpy((*parsed)[argc], cp, len);
567 (*parsed_lens)[argc] = len;
578 /* Save argument types. Protocol defines all argument types but
579 this implementation makes sure that they are always in correct
580 order hence this simple code. */
581 *parsed_types = silc_calloc(argc, sizeof(**parsed_types));
582 for (i = 0; i < argc; i++)
583 (*parsed_types)[i] = i;
588 /* Updates clock on the screen every minute. */
590 SILC_TASK_CALLBACK(silc_client_update_clock)
592 SilcClient client = (SilcClient)context;
594 /* Update the clock on the screen */
595 silc_screen_print_clock(client->screen);
597 /* Re-register this same task */
598 silc_task_register(qptr, 0, silc_client_update_clock, context,
599 silc_client_time_til_next_min(), 0,
603 silc_screen_refresh_win(client->screen->input_win);
606 /* Runs commands user configured in configuration file. This is
607 called when initializing client. */
609 SILC_TASK_CALLBACK(silc_client_run_commands)
611 SilcClient client = (SilcClient)context;
612 SilcClientConfigSectionCommand *cs;
614 SILC_LOG_DEBUG(("Start"));
616 cs = client->config->commands;
618 unsigned int argc = 0;
619 unsigned char **argv, *tmpcmd;
620 unsigned int *argv_lens, *argv_types;
621 SilcClientCommand *cmd;
622 SilcClientCommandContext ctx;
624 /* Get the command */
625 tmpcmd = silc_client_parse_command(cs->command);
627 for (cmd = silc_command_list; cmd->name; cmd++) {
628 if (!strcmp(cmd->name, tmpcmd))
632 if (cmd->name == NULL) {
633 silc_say(client, "Invalid command: %s", tmpcmd);
638 /* Now parse all arguments */
639 silc_client_parse_command_line(cs->command, &argv, &argv_lens,
640 &argv_types, &argc, cmd->max_args);
643 SILC_LOG_DEBUG(("Exeuting command: %s", cmd->name));
645 /* Allocate command context. This and its internals must be free'd
646 by the command routine receiving it. */
647 ctx = silc_calloc(1, sizeof(*ctx));
648 ctx->client = client;
649 ctx->sock = client->current_win->sock;
652 ctx->argv_lens = argv_lens;
653 ctx->argv_types = argv_types;
655 /* Execute command */
662 /* Internal context for connection process. This is needed as we
663 doing asynchronous connecting. */
671 } SilcClientInternalConnectContext;
674 silc_client_connect_to_server_internal(SilcClientInternalConnectContext *ctx)
678 /* XXX In the future we should give up this non-blocking connect all
679 together and use threads instead. */
680 /* Create connection to server asynchronously */
681 sock = silc_net_create_connection_async(ctx->port, ctx->host);
685 /* Register task that will receive the async connect and will
687 ctx->task = silc_task_register(ctx->client->io_queue, sock,
688 silc_client_connect_to_server_start,
691 SILC_TASK_PRI_NORMAL);
692 silc_task_reset_iotype(ctx->task, SILC_TASK_WRITE);
693 silc_schedule_set_listen_fd(sock, ctx->task->iomask);
700 /* Connects to remote server */
702 int silc_client_connect_to_server(SilcClient client, int port,
705 SilcClientInternalConnectContext *ctx;
707 SILC_LOG_DEBUG(("Connecting to port %d of server %s",
710 silc_say(client, "Connecting to port %d of server %s", port, host);
712 client->current_win->remote_host = strdup(host);
713 client->current_win->remote_port = port;
715 /* Allocate internal context for connection process. This is
716 needed as we are doing async connecting. */
717 ctx = silc_calloc(1, sizeof(*ctx));
718 ctx->client = client;
719 ctx->host = strdup(host);
723 /* Do the actual connecting process */
724 return silc_client_connect_to_server_internal(ctx);
727 /* Start of the connection to the remote server. This is called after
728 succesful TCP/IP connection has been established to the remote host. */
730 SILC_TASK_CALLBACK(silc_client_connect_to_server_start)
732 SilcClientInternalConnectContext *ctx =
733 (SilcClientInternalConnectContext *)context;
734 SilcClient client = ctx->client;
735 SilcProtocol protocol;
736 SilcClientKEInternalContext *proto_ctx;
737 int opt, opt_len = sizeof(opt);
739 SILC_LOG_DEBUG(("Start"));
741 /* Check the socket status as it might be in error */
742 getsockopt(fd, SOL_SOCKET, SO_ERROR, &opt, &opt_len);
744 if (ctx->tries < 2) {
745 /* Connection failed but lets try again */
746 silc_say(ctx->client, "Could not connect to server %s: %s",
747 ctx->host, strerror(opt));
748 silc_say(client, "Connecting to port %d of server %s resumed",
749 ctx->port, ctx->host);
751 /* Unregister old connection try */
752 silc_schedule_unset_listen_fd(fd);
753 silc_net_close_connection(fd);
754 silc_task_unregister(client->io_queue, ctx->task);
757 silc_client_connect_to_server_internal(ctx);
760 /* Connection failed and we won't try anymore */
761 silc_say(ctx->client, "Could not connect to server %s: %s",
762 ctx->host, strerror(opt));
763 silc_schedule_unset_listen_fd(fd);
764 silc_net_close_connection(fd);
765 silc_task_unregister(client->io_queue, ctx->task);
771 silc_schedule_unset_listen_fd(fd);
772 silc_task_unregister(client->io_queue, ctx->task);
775 /* Allocate new socket connection object */
776 silc_socket_alloc(fd, SILC_SOCKET_TYPE_SERVER,
777 (void *)client->current_win,
778 &client->current_win->sock);
779 if (client->current_win->sock == NULL) {
780 silc_say(client, "Error: Could not allocate connection socket");
781 silc_net_close_connection(fd);
784 client->current_win->sock->hostname = client->current_win->remote_host;
785 client->current_win->sock->port = client->current_win->remote_port;
787 /* Allocate internal Key Exchange context. This is sent to the
788 protocol as context. */
789 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
790 proto_ctx->client = (void *)client;
791 proto_ctx->sock = client->current_win->sock;
792 proto_ctx->rng = client->rng;
793 proto_ctx->responder = FALSE;
795 /* Perform key exchange protocol. silc_client_connect_to_server_final
796 will be called after the protocol is finished. */
797 silc_protocol_alloc(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
798 &protocol, (void *)proto_ctx,
799 silc_client_connect_to_server_second);
801 silc_say(client, "Error: Could not start authentication protocol");
804 client->current_win->sock->protocol = protocol;
806 /* Register the connection for network input and output. This sets
807 that scheduler will listen for incoming packets for this connection
808 and sets that outgoing packets may be sent to this connection as well.
809 However, this doesn't set the scheduler for outgoing traffic, it will
810 be set separately by calling SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT,
811 later when outgoing data is available. */
812 context = (void *)client;
813 SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(fd);
815 /* Execute the protocol */
816 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0);
819 /* Second part of the connecting to the server. This executed
820 authentication protocol. */
822 SILC_TASK_CALLBACK(silc_client_connect_to_server_second)
824 SilcProtocol protocol = (SilcProtocol)context;
825 SilcClientKEInternalContext *ctx =
826 (SilcClientKEInternalContext *)protocol->context;
827 SilcClient client = (SilcClient)ctx->client;
828 SilcSocketConnection sock = NULL;
829 SilcClientConnAuthInternalContext *proto_ctx;
831 SILC_LOG_DEBUG(("Start"));
833 if (protocol->state == SILC_PROTOCOL_STATE_ERROR) {
834 /* Error occured during protocol */
835 SILC_LOG_DEBUG(("Error during KE protocol"));
836 silc_protocol_free(protocol);
838 silc_buffer_free(ctx->packet);
840 silc_ske_free(ctx->ske);
842 silc_free(ctx->dest_id);
844 sock->protocol = NULL;
848 /* Allocate internal context for the authentication protocol. This
849 is sent as context for the protocol. */
850 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
851 proto_ctx->client = (void *)client;
852 proto_ctx->sock = sock = ctx->sock;
853 proto_ctx->ske = ctx->ske; /* Save SKE object from previous protocol */
854 proto_ctx->dest_id_type = ctx->dest_id_type;
855 proto_ctx->dest_id = ctx->dest_id;
857 /* Resolve the authentication method to be used in this connection */
858 proto_ctx->auth_meth = SILC_PROTOCOL_CONN_AUTH_NONE;
859 if (client->config->conns) {
860 SilcClientConfigSectionConnection *conn = NULL;
862 /* Check if we find a match from user configured connections */
863 conn = silc_client_config_find_connection(client->config,
867 /* Match found. Use the configured authentication method */
868 proto_ctx->auth_meth = conn->auth_meth;
869 if (conn->auth_data) {
870 proto_ctx->auth_data = strdup(conn->auth_data);
871 proto_ctx->auth_data_len = strlen(conn->auth_data);
874 /* No match found. Resolve by sending AUTH_REQUEST to server */
875 proto_ctx->auth_meth = SILC_PROTOCOL_CONN_AUTH_NONE;
878 /* XXX Resolve by sending AUTH_REQUEST to server */
879 proto_ctx->auth_meth = SILC_PROTOCOL_CONN_AUTH_NONE;
882 /* Free old protocol as it is finished now */
883 silc_protocol_free(protocol);
885 silc_buffer_free(ctx->packet);
887 /* silc_free(ctx->keymat....); */
888 sock->protocol = NULL;
890 /* Allocate the authentication protocol. This is allocated here
891 but we won't start it yet. We will be receiving party of this
892 protocol thus we will wait that connecting party will make
894 silc_protocol_alloc(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
895 &sock->protocol, (void *)proto_ctx,
896 silc_client_connect_to_server_final);
898 /* Execute the protocol */
899 sock->protocol->execute(client->timeout_queue, 0, sock->protocol, fd, 0, 0);
902 /* Finalizes the connection to the remote SILC server. This is called
903 after authentication protocol has been completed. This send our
904 user information to the server to receive our client ID from
907 SILC_TASK_CALLBACK(silc_client_connect_to_server_final)
909 SilcProtocol protocol = (SilcProtocol)context;
910 SilcClientConnAuthInternalContext *ctx =
911 (SilcClientConnAuthInternalContext *)protocol->context;
912 SilcClient client = (SilcClient)ctx->client;
913 SilcClientWindow win = (SilcClientWindow)ctx->sock->user_data;
916 SILC_LOG_DEBUG(("Start"));
918 if (protocol->state == SILC_PROTOCOL_STATE_ERROR) {
919 /* Error occured during protocol */
920 SILC_LOG_DEBUG(("Error during authentication protocol"));
921 silc_protocol_free(protocol);
923 silc_free(ctx->auth_data);
925 silc_ske_free(ctx->ske);
927 silc_free(ctx->dest_id);
929 win->sock->protocol = NULL;
933 /* Send NEW_CLIENT packet to the server. We will become registered
934 to the SILC network after sending this packet and we will receive
935 client ID from the server. */
936 packet = silc_buffer_alloc(2 + 2 + strlen(client->username) +
937 strlen(client->realname));
938 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
939 silc_buffer_format(packet,
940 SILC_STR_UI_SHORT(strlen(client->username)),
941 SILC_STR_UI_XNSTRING(client->username,
942 strlen(client->username)),
943 SILC_STR_UI_SHORT(strlen(client->realname)),
944 SILC_STR_UI_XNSTRING(client->realname,
945 strlen(client->realname)),
948 /* Send the packet */
949 silc_client_packet_send(client, ctx->sock, SILC_PACKET_NEW_CLIENT,
951 packet->data, packet->len, TRUE);
952 silc_buffer_free(packet);
954 /* Save remote ID. */
955 win->remote_id = ctx->dest_id;
956 win->remote_id_data = silc_id_id2str(ctx->dest_id, SILC_ID_CHANNEL);
957 win->remote_id_data_len = SILC_ID_CHANNEL_LEN;
959 silc_say(client, "Connected to port %d of host %s",
960 win->remote_port, win->remote_host);
962 client->screen->bottom_line->connection = win->remote_host;
963 silc_screen_print_bottom_line(client->screen, 0);
965 silc_protocol_free(protocol);
967 silc_free(ctx->auth_data);
969 silc_ske_free(ctx->ske);
971 silc_free(ctx->dest_id);
973 win->sock->protocol = NULL;
977 SilcPacketContext *packetdata;
978 SilcSocketConnection sock;
980 } SilcClientInternalPacket;
982 SILC_TASK_CALLBACK(silc_client_packet_process)
984 SilcClient client = (SilcClient)context;
985 SilcSocketConnection sock = NULL;
986 int ret, packetlen, paddedlen;
988 SILC_LOG_DEBUG(("Processing packet"));
990 SILC_CLIENT_GET_SOCK(client, fd, sock);
995 if (type == SILC_TASK_WRITE) {
996 SILC_LOG_DEBUG(("Writing data to connection"));
998 if (sock->outbuf->data - sock->outbuf->head)
999 silc_buffer_push(sock->outbuf,
1000 sock->outbuf->data - sock->outbuf->head);
1002 /* Write the packet out to the connection */
1003 ret = silc_packet_write(fd, sock->outbuf);
1005 /* If returned -2 could not write to connection now, will do
1012 SILC_LOG_ERROR(("Packet dropped"));
1014 /* The packet has been sent and now it is time to set the connection
1015 back to only for input. When there is again some outgoing data
1016 available for this connection it will be set for output as well.
1017 This call clears the output setting and sets it only for input. */
1018 SILC_CLIENT_SET_CONNECTION_FOR_INPUT(fd);
1019 SILC_UNSET_OUTBUF_PENDING(sock);
1024 /* Packet receiving */
1025 if (type == SILC_TASK_READ) {
1026 SILC_LOG_DEBUG(("Reading data from connection"));
1028 /* Allocate the incoming data buffer if not done already. */
1030 sock->inbuf = silc_buffer_alloc(SILC_PACKET_DEFAULT_SIZE);
1032 /* Read some data from connection */
1033 ret = silc_packet_read(fd, sock->inbuf);
1035 /* If returned -2 data was not available now, will read it later. */
1041 SILC_LOG_ERROR(("Packet dropped"));
1047 SILC_LOG_DEBUG(("Read EOF"));
1049 /* If connection is disconnecting already we will finally
1050 close the connection */
1051 if (SILC_IS_DISCONNECTING(sock)) {
1052 silc_client_close_connection(client, sock);
1056 silc_say(client, "Connection closed: premature EOF");
1057 SILC_LOG_DEBUG(("Premature EOF from connection %d", sock->sock));
1059 silc_client_close_connection(client, sock);
1063 /* Check whether we received a whole packet. If reading went without
1064 errors we either read a whole packet or the read packet is
1065 incorrect and will be dropped. */
1066 SILC_PACKET_LENGTH(sock->inbuf, packetlen, paddedlen);
1067 if (sock->inbuf->len < paddedlen || (packetlen < SILC_PACKET_MIN_LEN)) {
1068 SILC_LOG_DEBUG(("Received incorrect packet, dropped"));
1069 silc_buffer_clear(sock->inbuf);
1073 /* Decrypt a packet coming from server connection */
1074 if (sock->type == SILC_SOCKET_TYPE_SERVER ||
1075 sock->type == SILC_SOCKET_TYPE_ROUTER) {
1076 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1077 SilcClientInternalPacket *packet;
1081 mac_len = win->hmac->hash->hash->hash_len;
1083 if (sock->inbuf->len - 2 > (paddedlen + mac_len)) {
1084 /* Received possibly many packets at once */
1086 while(sock->inbuf->len > 0) {
1087 SILC_PACKET_LENGTH(sock->inbuf, packetlen, paddedlen);
1088 if (sock->inbuf->len < paddedlen) {
1089 SILC_LOG_DEBUG(("Received incorrect packet, dropped"));
1094 packet = silc_calloc(1, sizeof(*packet));
1095 packet->client = client;
1096 packet->sock = sock;
1097 packet->packetdata = silc_calloc(1, sizeof(*packet->packetdata));
1098 packet->packetdata->buffer = silc_buffer_alloc(paddedlen + mac_len);
1099 silc_buffer_pull_tail(packet->packetdata->buffer,
1100 SILC_BUFFER_END(packet->packetdata->buffer));
1101 silc_buffer_put(packet->packetdata->buffer, sock->inbuf->data,
1102 paddedlen + mac_len);
1104 SILC_LOG_HEXDUMP(("Incoming packet, len %d",
1105 packet->packetdata->buffer->len),
1106 packet->packetdata->buffer->data,
1107 packet->packetdata->buffer->len);
1108 SILC_LOG_DEBUG(("Packet from server %s, "
1109 "server type %d, packet length %d",
1110 win->remote_host, win->remote_type, paddedlen));
1112 /* If this packet is for the current active connection we will
1113 parse the packet right away to get it quickly on the screen.
1114 Otherwise, it will be parsed with a timeout as the data is
1115 for inactive window (which might not be visible at all). */
1116 if (SILC_CLIENT_IS_CURRENT_WIN(client, win)) {
1117 /* Parse it real soon */
1118 silc_task_register(client->timeout_queue, fd,
1119 silc_client_packet_parse,
1120 (void *)packet, 0, 1,
1122 SILC_TASK_PRI_NORMAL);
1124 /* Parse the packet with timeout */
1125 silc_task_register(client->timeout_queue, fd,
1126 silc_client_packet_parse,
1127 (void *)packet, 0, 200000,
1129 SILC_TASK_PRI_NORMAL);
1132 /* Pull the packet from inbuf thus we'll get the next one
1134 silc_buffer_pull(sock->inbuf, paddedlen);
1136 silc_buffer_pull(sock->inbuf, mac_len);
1138 silc_buffer_clear(sock->inbuf);
1141 /* Received one packet */
1143 SILC_LOG_HEXDUMP(("An incoming packet, len %d", sock->inbuf->len),
1144 sock->inbuf->data, sock->inbuf->len);
1145 SILC_LOG_DEBUG(("Packet from server %s, "
1146 "server type %d, packet length %d",
1147 win->remote_host, win->remote_type, paddedlen));
1149 packet = silc_calloc(1, sizeof(*packet));
1150 packet->client = client;
1151 packet->sock = sock;
1152 packet->packetdata = silc_calloc(1, sizeof(*packet->packetdata));
1153 packet->packetdata->buffer = silc_buffer_copy(sock->inbuf);
1154 silc_buffer_clear(sock->inbuf);
1156 /* If this packet is for the current active connection we will
1157 parse the packet right away to get it quickly on the screen.
1158 Otherwise, it will be parsed with a timeout as the data is
1159 for inactive window (which might not be visible at all). */
1160 if (SILC_CLIENT_IS_CURRENT_WIN(client, win)) {
1161 /* Parse it real soon */
1162 silc_task_register(client->timeout_queue, fd,
1163 silc_client_packet_parse,
1164 (void *)packet, 0, 1,
1166 SILC_TASK_PRI_NORMAL);
1169 /* Parse the packet with timeout */
1170 silc_task_register(client->timeout_queue, fd,
1171 silc_client_packet_parse,
1172 (void *)packet, 0, 200000,
1174 SILC_TASK_PRI_NORMAL);
1181 SILC_LOG_ERROR(("Weird, nothing happened - ignoring"));
1184 /* Checks MAC in the packet. Returns TRUE if MAC is Ok. This is called
1185 after packet has been totally decrypted and parsed. */
1187 static int silc_client_packet_check_mac(SilcClient client,
1188 SilcSocketConnection sock,
1191 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1195 int headlen = buffer->data - buffer->head, mac_len;
1196 unsigned char *packet_mac, mac[32];
1198 SILC_LOG_DEBUG(("Verifying MAC"));
1200 mac_len = win->hmac->hash->hash->hash_len;
1202 silc_buffer_push(buffer, headlen);
1204 /* Take mac from packet */
1205 packet_mac = buffer->tail;
1207 /* Make MAC and compare */
1208 memset(mac, 0, sizeof(mac));
1209 silc_hmac_make_with_key(win->hmac,
1210 buffer->data, buffer->len,
1211 win->hmac_key, win->hmac_key_len, mac);
1213 SILC_LOG_HEXDUMP(("PMAC"), packet_mac, mac_len);
1214 SILC_LOG_HEXDUMP(("CMAC"), mac, mac_len);
1216 if (memcmp(mac, packet_mac, mac_len)) {
1217 SILC_LOG_DEBUG(("MAC failed"));
1221 SILC_LOG_DEBUG(("MAC is Ok"));
1222 memset(mac, 0, sizeof(mac));
1224 silc_buffer_pull(buffer, headlen);
1230 /* Decrypts rest of the packet (after decrypting just the SILC header).
1231 After calling this function the packet is ready to be parsed by calling
1232 silc_packet_parse. */
1234 static int silc_client_packet_decrypt_rest(SilcClient client,
1235 SilcSocketConnection sock,
1238 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1239 unsigned int mac_len = 0;
1242 if (win && win->receive_key) {
1244 /* Pull MAC from packet before decryption */
1246 mac_len = win->hmac->hash->hash->hash_len;
1247 if ((buffer->len - mac_len) > SILC_PACKET_MIN_LEN) {
1248 silc_buffer_push_tail(buffer, mac_len);
1250 SILC_LOG_DEBUG(("Bad MAC length in packet, packet dropped"));
1255 SILC_LOG_DEBUG(("Decrypting rest of the packet"));
1257 /* Decrypt rest of the packet */
1258 silc_buffer_pull(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
1259 silc_packet_decrypt(win->receive_key, buffer, buffer->len);
1260 silc_buffer_push(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
1262 SILC_LOG_HEXDUMP(("Fully decrypted packet, len %d", buffer->len),
1263 buffer->data, buffer->len);
1269 /* Decrypts rest of the SILC Packet header that has been decrypted partly
1270 already. This decrypts the padding of the packet also. After calling
1271 this function the packet is ready to be parsed by calling function
1272 silc_packet_parse. This is used in special packet reception. */
1274 static int silc_client_packet_decrypt_rest_special(SilcClient client,
1275 SilcSocketConnection sock,
1278 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1279 unsigned int mac_len = 0;
1281 /* Decrypt rest of the header plus padding */
1282 if (win && win->receive_key) {
1283 unsigned short truelen, len1, len2, padlen;
1285 /* Pull MAC from packet before decryption */
1287 mac_len = win->hmac->hash->hash->hash_len;
1288 if ((buffer->len - mac_len) > SILC_PACKET_MIN_LEN) {
1289 silc_buffer_push_tail(buffer, mac_len);
1291 SILC_LOG_DEBUG(("Bad MAC length in packet, packet dropped"));
1296 SILC_LOG_DEBUG(("Decrypting rest of the header"));
1298 SILC_GET16_MSB(len1, &buffer->data[4]);
1299 SILC_GET16_MSB(len2, &buffer->data[6]);
1301 truelen = SILC_PACKET_HEADER_LEN + len1 + len2;
1302 padlen = SILC_PACKET_PADLEN(truelen);
1303 len1 = (truelen + padlen) - (SILC_PACKET_MIN_HEADER_LEN - 2);
1305 silc_buffer_pull(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
1306 SILC_LOG_HEXDUMP(("XXX"), buffer->data, buffer->len);
1307 silc_packet_decrypt(win->receive_key, buffer, len1);
1308 silc_buffer_push(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
1309 SILC_LOG_HEXDUMP(("XXX"), buffer->data, buffer->len);
1315 /* Parses whole packet, received earlier. */
1317 SILC_TASK_CALLBACK(silc_client_packet_parse)
1319 SilcClientInternalPacket *packet = (SilcClientInternalPacket *)context;
1320 SilcBuffer buffer = packet->packetdata->buffer;
1321 SilcClient client = packet->client;
1322 SilcSocketConnection sock = packet->sock;
1323 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1326 SILC_LOG_DEBUG(("Start"));
1328 /* Decrypt start of the packet header */
1329 if (win && win->receive_key)
1330 silc_packet_decrypt(win->receive_key, buffer, SILC_PACKET_MIN_HEADER_LEN);
1332 /* If the packet type is not any special type lets decrypt rest
1333 of the packet here. */
1334 if (buffer->data[3] != SILC_PACKET_CHANNEL_MESSAGE &&
1335 buffer->data[3] != SILC_PACKET_PRIVATE_MESSAGE) {
1337 /* Normal packet, decrypt rest of the packet */
1338 if (!silc_client_packet_decrypt_rest(client, sock, buffer))
1341 /* Parse the packet. Packet type is returned. */
1342 ret = silc_packet_parse(packet->packetdata);
1343 if (ret == SILC_PACKET_NONE)
1347 if (!silc_client_packet_check_mac(client, sock, buffer))
1350 /* If private message key is not set for private message it is
1351 handled as normal packet. Go back up. */
1352 if (buffer->data[3] == SILC_PACKET_PRIVATE_MESSAGE &&
1353 !(buffer->data[2] & SILC_PACKET_FLAG_PRIVMSG_KEY))
1356 /* Packet requires special handling, decrypt rest of the header.
1357 This only decrypts. This does not do any MAC checking, it must
1358 be done individually later when doing the special processing. */
1359 silc_client_packet_decrypt_rest_special(client, sock, buffer);
1361 /* Parse the packet header in special way as this is "special"
1363 ret = silc_packet_parse_special(packet->packetdata);
1364 if (ret == SILC_PACKET_NONE)
1368 /* Parse the incoming packet type */
1369 silc_client_packet_parse_type(client, sock, packet->packetdata);
1372 silc_buffer_clear(packet->packetdata->buffer);
1373 silc_free(packet->packetdata);
1377 /* Parses the packet type and calls what ever routines the packet type
1378 requires. This is done for all incoming packets. */
1380 void silc_client_packet_parse_type(SilcClient client,
1381 SilcSocketConnection sock,
1382 SilcPacketContext *packet)
1384 SilcBuffer buffer = packet->buffer;
1385 SilcPacketType type = packet->type;
1387 SILC_LOG_DEBUG(("Parsing packet type %d", type));
1389 /* Parse the packet type */
1391 case SILC_PACKET_DISCONNECT:
1392 silc_client_disconnected_by_server(client, sock, buffer);
1394 case SILC_PACKET_SUCCESS:
1396 * Success received for something. For now we can have only
1397 * one protocol for connection executing at once hence this
1398 * success message is for whatever protocol is executing currently.
1400 if (sock->protocol) {
1401 sock->protocol->execute(client->timeout_queue, 0,
1402 sock->protocol, sock->sock, 0, 0);
1405 case SILC_PACKET_FAILURE:
1407 * Failure received for some protocol. Set the protocol state to
1408 * error and call the protocol callback. This fill cause error on
1409 * protocol and it will call the final callback.
1411 if (sock->protocol) {
1412 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
1413 sock->protocol->execute(client->timeout_queue, 0,
1414 sock->protocol, sock->sock, 0, 0);
1417 case SILC_PACKET_REJECT:
1420 case SILC_PACKET_NOTIFY:
1422 * Received notify message
1424 silc_client_notify_by_server(client, sock, buffer);
1427 case SILC_PACKET_ERROR:
1429 * Received error message
1431 silc_client_error_by_server(client, sock, buffer);
1434 case SILC_PACKET_CHANNEL_MESSAGE:
1436 * Received message to (from, actually) a channel
1438 silc_client_channel_message(client, sock, packet);
1440 case SILC_PACKET_CHANNEL_KEY:
1442 * Received key for a channel. By receiving this key the client will be
1443 * able to talk to the channel it has just joined. This can also be
1444 * a new key for existing channel as keys expire peridiocally.
1446 silc_client_receive_channel_key(client, sock, buffer);
1449 case SILC_PACKET_PRIVATE_MESSAGE:
1451 * Received private message
1454 SilcClientCommandReplyContext ctx;
1455 ctx = silc_calloc(1, sizeof(*ctx));
1456 ctx->client = client;
1458 ctx->context = buffer; /* kludge */
1459 silc_client_command_reply_msg((void *)ctx);
1462 case SILC_PACKET_PRIVATE_MESSAGE_KEY:
1464 * Received private message key
1468 case SILC_PACKET_COMMAND_REPLY:
1470 * Recived reply for a command
1472 silc_client_command_reply_process(client, sock, packet);
1475 case SILC_PACKET_KEY_EXCHANGE:
1476 if (sock->protocol) {
1477 SilcClientKEInternalContext *proto_ctx =
1478 (SilcClientKEInternalContext *)sock->protocol->context;
1480 proto_ctx->packet = buffer;
1481 proto_ctx->dest_id_type = packet->src_id_type;
1482 proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_type);
1484 /* Let the protocol handle the packet */
1485 sock->protocol->execute(client->timeout_queue, 0,
1486 sock->protocol, sock->sock, 0, 0);
1488 SILC_LOG_ERROR(("Received Key Exchange packet but no key exchange "
1489 "protocol active, packet dropped."));
1491 /* XXX Trigger KE protocol?? Rekey actually! */
1495 case SILC_PACKET_KEY_EXCHANGE_1:
1496 if (sock->protocol) {
1499 SILC_LOG_ERROR(("Received Key Exchange 1 packet but no key exchange "
1500 "protocol active, packet dropped."));
1503 case SILC_PACKET_KEY_EXCHANGE_2:
1504 if (sock->protocol) {
1505 SilcClientKEInternalContext *proto_ctx =
1506 (SilcClientKEInternalContext *)sock->protocol->context;
1508 if (proto_ctx->packet)
1509 silc_buffer_free(proto_ctx->packet);
1511 proto_ctx->packet = buffer;
1512 proto_ctx->dest_id_type = packet->src_id_type;
1513 proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_type);
1515 /* Let the protocol handle the packet */
1516 sock->protocol->execute(client->timeout_queue, 0,
1517 sock->protocol, sock->sock, 0, 0);
1519 SILC_LOG_ERROR(("Received Key Exchange 2 packet but no key exchange "
1520 "protocol active, packet dropped."));
1524 case SILC_PACKET_NEW_ID:
1527 * Received new ID from server. This packet is received at
1528 * the connection to the server. New ID is also received when
1529 * user changes nickname but in that case the new ID is received
1530 * as command reply and not as this packet type.
1532 unsigned char *id_string;
1533 unsigned short id_type;
1535 silc_buffer_unformat(buffer,
1536 SILC_STR_UI_SHORT(&id_type),
1537 SILC_STR_UI16_STRING_ALLOC(&id_string),
1540 if ((SilcIdType)id_type != SILC_ID_CLIENT)
1543 silc_client_receive_new_id(client, sock, id_string);
1544 silc_free(id_string);
1549 SILC_LOG_DEBUG(("Incorrect packet type %d, packet dropped", type));
1554 /* Internal routine that sends packet or marks packet to be sent. This
1555 is used directly only in special cases. Normal cases should use
1556 silc_server_packet_send. Returns < 0 on error. */
1558 static int silc_client_packet_send_real(SilcClient client,
1559 SilcSocketConnection sock,
1562 /* Send now if forced to do so */
1563 if (force_send == TRUE) {
1565 SILC_LOG_DEBUG(("Forcing packet send, packet sent immediately"));
1566 ret = silc_packet_write(sock->sock, sock->outbuf);
1569 SILC_LOG_ERROR(("Packet dropped"));
1573 SILC_LOG_DEBUG(("Could not force the send, packet put to queue"));
1576 SILC_LOG_DEBUG(("Packet in queue"));
1578 /* Mark that there is some outgoing data available for this connection.
1579 This call sets the connection both for input and output (the input
1580 is set always and this call keeps the input setting, actually).
1581 Actual data sending is performed by silc_client_packet_process. */
1582 SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(sock->sock);
1584 /* Mark to socket that data is pending in outgoing buffer. This flag
1585 is needed if new data is added to the buffer before the earlier
1586 put data is sent to the network. */
1587 SILC_SET_OUTBUF_PENDING(sock);
1592 /* Prepare outgoing data buffer for packet sending. */
1594 static void silc_client_packet_send_prepare(SilcClient client,
1595 SilcSocketConnection sock,
1596 unsigned int header_len,
1597 unsigned int padlen,
1598 unsigned int data_len)
1602 totlen = header_len + padlen + data_len;
1604 /* Prepare the outgoing buffer for packet sending. */
1605 if (!sock->outbuf) {
1606 /* Allocate new buffer. This is done only once per connection. */
1607 SILC_LOG_DEBUG(("Allocating outgoing data buffer"));
1609 sock->outbuf = silc_buffer_alloc(SILC_PACKET_DEFAULT_SIZE);
1610 silc_buffer_pull_tail(sock->outbuf, totlen);
1611 silc_buffer_pull(sock->outbuf, header_len + padlen);
1613 if (SILC_IS_OUTBUF_PENDING(sock)) {
1614 /* There is some pending data in the buffer. */
1616 if ((sock->outbuf->end - sock->outbuf->tail) < data_len) {
1617 SILC_LOG_DEBUG(("Reallocating outgoing data buffer"));
1618 /* XXX: not done yet */
1620 oldlen = sock->outbuf->len;
1621 silc_buffer_pull_tail(sock->outbuf, totlen);
1622 silc_buffer_pull(sock->outbuf, header_len + padlen + oldlen);
1624 /* Buffer is free for use */
1625 silc_buffer_clear(sock->outbuf);
1626 silc_buffer_pull_tail(sock->outbuf, totlen);
1627 silc_buffer_pull(sock->outbuf, header_len + padlen);
1632 /* Sends packet. This doesn't actually send the packet instead it assembles
1633 it and marks it to be sent. However, if force_send is TRUE the packet
1634 is sent immediately. if dst_id, cipher and hmac are NULL those parameters
1635 will be derived from sock argument. Otherwise the valid arguments sent
1638 void silc_client_packet_send(SilcClient client,
1639 SilcSocketConnection sock,
1640 SilcPacketType type,
1642 SilcIdType dst_id_type,
1645 unsigned char *data,
1646 unsigned int data_len,
1649 SilcPacketContext packetdata;
1650 unsigned char *hmac_key = NULL;
1651 unsigned int hmac_key_len = 0;
1652 unsigned char mac[32];
1653 unsigned int mac_len = 0;
1655 SILC_LOG_DEBUG(("Sending packet, type %d", type));
1657 /* Get data used in the packet sending, keys and stuff */
1658 if ((!cipher || !hmac || !dst_id) && sock->user_data) {
1659 if (!cipher && ((SilcClientWindow)sock->user_data)->send_key)
1660 cipher = ((SilcClientWindow)sock->user_data)->send_key;
1661 if (!hmac && ((SilcClientWindow)sock->user_data)->hmac) {
1662 hmac = ((SilcClientWindow)sock->user_data)->hmac;
1663 mac_len = hmac->hash->hash->hash_len;
1664 hmac_key = ((SilcClientWindow)sock->user_data)->hmac_key;
1665 hmac_key_len = ((SilcClientWindow)sock->user_data)->hmac_key_len;
1667 if (!dst_id && ((SilcClientWindow)sock->user_data)->remote_id) {
1668 dst_id = ((SilcClientWindow)sock->user_data)->remote_id;
1669 dst_id_type = SILC_ID_SERVER;
1673 /* Set the packet context pointers */
1674 packetdata.flags = 0;
1675 packetdata.type = type;
1676 if (((SilcClientWindow)sock->user_data)->local_id_data)
1677 packetdata.src_id = ((SilcClientWindow)sock->user_data)->local_id_data;
1679 packetdata.src_id = silc_calloc(SILC_ID_CLIENT_LEN, sizeof(unsigned char));
1680 packetdata.src_id_len = SILC_ID_CLIENT_LEN;
1681 packetdata.src_id_type = SILC_ID_CLIENT;
1683 packetdata.dst_id = silc_id_id2str(dst_id, dst_id_type);
1684 packetdata.dst_id_len = silc_id_get_len(dst_id_type);
1685 packetdata.dst_id_type = dst_id_type;
1687 packetdata.dst_id = NULL;
1688 packetdata.dst_id_len = 0;
1689 packetdata.dst_id_type = SILC_ID_NONE;
1691 packetdata.rng = client->rng;
1692 packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN +
1693 packetdata.src_id_len + packetdata.dst_id_len;
1694 packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen);
1696 /* Prepare outgoing data buffer for packet sending */
1697 silc_client_packet_send_prepare(client, sock,
1698 SILC_PACKET_HEADER_LEN +
1699 packetdata.src_id_len +
1700 packetdata.dst_id_len,
1704 SILC_LOG_DEBUG(("Putting data to outgoing buffer, len %d", data_len));
1706 packetdata.buffer = sock->outbuf;
1708 /* Put the data to the buffer */
1709 if (data && data_len)
1710 silc_buffer_put(sock->outbuf, data, data_len);
1712 /* Create the outgoing packet */
1713 silc_packet_assemble(&packetdata);
1715 /* Compute MAC of the packet */
1717 silc_hmac_make_with_key(hmac, sock->outbuf->data, sock->outbuf->len,
1718 hmac_key, hmac_key_len, mac);
1719 silc_buffer_put_tail(sock->outbuf, mac, mac_len);
1720 memset(mac, 0, sizeof(mac));
1723 /* Encrypt the packet */
1725 silc_packet_encrypt(cipher, sock->outbuf, sock->outbuf->len);
1727 /* Pull MAC into the visible data area */
1729 silc_buffer_pull_tail(sock->outbuf, mac_len);
1731 SILC_LOG_HEXDUMP(("Packet, len %d", sock->outbuf->len),
1732 sock->outbuf->data, sock->outbuf->len);
1734 /* Now actually send the packet */
1735 silc_client_packet_send_real(client, sock, force_send);
1738 /* Sends packet to a channel. Packet to channel is always encrypted
1739 differently from "normal" packets. SILC header of the packet is
1740 encrypted with the next receiver's key and the rest of the packet is
1741 encrypted with the channel specific key. Padding and HMAC is computed
1742 with the next receiver's key. */
1744 void silc_client_packet_send_to_channel(SilcClient client,
1745 SilcSocketConnection sock,
1746 SilcChannelEntry channel,
1747 unsigned char *data,
1748 unsigned int data_len,
1752 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1754 SilcPacketContext packetdata;
1755 unsigned char *hmac_key = NULL;
1756 unsigned int hmac_key_len = 0;
1757 unsigned char mac[32];
1758 unsigned int mac_len = 0;
1759 unsigned char *id_string;
1763 SILC_LOG_DEBUG(("Sending packet to channel"));
1765 if (!channel || !channel->key) {
1766 silc_say(client, "Cannot talk to channel: key does not exist");
1772 for (i = 0; i < 16; i++)
1773 channel->iv[i] = silc_rng_get_byte(client->rng);
1775 silc_hash_make(client->md5hash, channel->iv, 16, channel->iv);
1777 /* Encode the channel payload */
1778 payload = silc_channel_encode_payload(strlen(win->nickname), win->nickname,
1779 data_len, data, 16, channel->iv,
1783 "Error: Could not create packet to be sent to the channel");
1787 /* Get data used in packet header encryption, keys and stuff. Rest
1788 of the packet (the payload) is, however, encrypted with the
1789 specified channel key. */
1790 cipher = win->send_key;
1792 mac_len = hmac->hash->hash->hash_len;
1793 hmac_key = win->hmac_key;
1794 hmac_key_len = win->hmac_key_len;
1795 id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
1797 /* Set the packet context pointers. The destination ID is always
1798 the Channel ID of the channel. Server and router will handle the
1799 distribution of the packet. */
1800 packetdata.flags = 0;
1801 packetdata.type = SILC_PACKET_CHANNEL_MESSAGE;
1802 packetdata.src_id = win->local_id_data;
1803 packetdata.src_id_len = SILC_ID_CLIENT_LEN;
1804 packetdata.src_id_type = SILC_ID_CLIENT;
1805 packetdata.dst_id = id_string;
1806 packetdata.dst_id_len = SILC_ID_CHANNEL_LEN;
1807 packetdata.dst_id_type = SILC_ID_CHANNEL;
1808 packetdata.rng = client->rng;
1809 packetdata.truelen = payload->len + SILC_PACKET_HEADER_LEN +
1810 packetdata.src_id_len + packetdata.dst_id_len;
1811 packetdata.padlen = SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
1812 packetdata.src_id_len +
1813 packetdata.dst_id_len));
1815 /* Prepare outgoing data buffer for packet sending */
1816 silc_client_packet_send_prepare(client, sock,
1817 SILC_PACKET_HEADER_LEN +
1818 packetdata.src_id_len +
1819 packetdata.dst_id_len,
1823 packetdata.buffer = sock->outbuf;
1825 /* Encrypt payload of the packet. This is encrypted with the channel key. */
1826 channel->channel_key->cipher->encrypt(channel->channel_key->context,
1827 payload->data, payload->data,
1828 payload->len - 16, /* -IV_LEN */
1831 SILC_LOG_HEXDUMP(("XXX"), payload->data, payload->len);
1833 /* Put the actual encrypted payload data into the buffer. */
1834 silc_buffer_put(sock->outbuf, payload->data, payload->len);
1836 /* Create the outgoing packet */
1837 silc_packet_assemble(&packetdata);
1839 /* Compute MAC of the packet */
1840 silc_hmac_make_with_key(hmac, sock->outbuf->data, sock->outbuf->len,
1841 hmac_key, hmac_key_len, mac);
1842 silc_buffer_put_tail(sock->outbuf, mac, mac_len);
1843 memset(mac, 0, sizeof(mac));
1845 SILC_LOG_HEXDUMP(("XXX"), sock->outbuf->data, sock->outbuf->len);
1847 /* Encrypt the header and padding of the packet. This is encrypted
1848 with normal session key shared with our server. */
1849 silc_packet_encrypt(cipher, sock->outbuf, SILC_PACKET_HEADER_LEN +
1850 packetdata.src_id_len + packetdata.dst_id_len +
1853 /* Pull MAC into the visible data area */
1854 silc_buffer_pull_tail(sock->outbuf, mac_len);
1856 SILC_LOG_HEXDUMP(("Packet to channel, len %d", sock->outbuf->len),
1857 sock->outbuf->data, sock->outbuf->len);
1859 /* Now actually send the packet */
1860 silc_client_packet_send_real(client, sock, force_send);
1861 silc_buffer_free(payload);
1862 silc_free(id_string);
1865 /* Sends private message to remote client. If private message key has
1866 not been set with this client then the message will be encrypted using
1867 normal session keys. Private messages are special packets in SILC
1868 network hence we need this own function for them. This is similiar
1869 to silc_client_packet_send_to_channel except that we send private
1872 void silc_client_packet_send_private_message(SilcClient client,
1873 SilcSocketConnection sock,
1874 SilcClientEntry client_entry,
1875 unsigned char *data,
1876 unsigned int data_len,
1879 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1881 SilcPacketContext packetdata;
1882 unsigned char *hmac_key = NULL;
1883 unsigned int hmac_key_len = 0;
1884 unsigned char mac[32];
1885 unsigned int mac_len = 0;
1886 unsigned int nick_len;
1890 SILC_LOG_DEBUG(("Sending private message"));
1892 /* Create private message payload */
1893 nick_len = strlen(client->current_win->nickname);
1894 buffer = silc_buffer_alloc(2 + nick_len + data_len);
1895 silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer));
1896 silc_buffer_format(buffer,
1897 SILC_STR_UI_SHORT(nick_len),
1898 SILC_STR_UI_XNSTRING(client->current_win->nickname,
1900 SILC_STR_UI_XNSTRING(data, data_len),
1903 /* If we don't have private message specific key then private messages
1904 are just as any normal packet thus call normal packet sending. If
1905 the key exist then the encryption process is a bit different and
1906 will be done in the rest of this function. */
1907 if (!client_entry->send_key) {
1908 silc_client_packet_send(client, sock, SILC_PACKET_PRIVATE_MESSAGE,
1909 client_entry->id, SILC_ID_CLIENT, NULL, NULL,
1910 buffer->data, buffer->len, force_send);
1914 /* We have private message specific key */
1916 /* Get data used in the encryption */
1917 cipher = client_entry->send_key;
1919 mac_len = hmac->hash->hash->hash_len;
1920 hmac_key = win->hmac_key;
1921 hmac_key_len = win->hmac_key_len;
1923 /* Set the packet context pointers. */
1924 packetdata.flags = 0;
1925 packetdata.type = SILC_PACKET_PRIVATE_MESSAGE;
1926 packetdata.src_id = win->local_id_data;
1927 packetdata.src_id_len = SILC_ID_CLIENT_LEN;
1928 packetdata.src_id_type = SILC_ID_CLIENT;
1930 packetdata.dst_id = silc_id_id2str(client_entry->id, SILC_ID_CLIENT);
1932 packetdata.dst_id = win->local_id_data;
1933 packetdata.dst_id_len = SILC_ID_CLIENT_LEN;
1934 packetdata.dst_id_type = SILC_ID_CLIENT;
1935 packetdata.rng = client->rng;
1936 packetdata.truelen = buffer->len + SILC_PACKET_HEADER_LEN +
1937 packetdata.src_id_len + packetdata.dst_id_len;
1938 packetdata.padlen = SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
1939 packetdata.src_id_len +
1940 packetdata.dst_id_len));
1942 /* Prepare outgoing data buffer for packet sending */
1943 silc_client_packet_send_prepare(client, sock,
1944 SILC_PACKET_HEADER_LEN +
1945 packetdata.src_id_len +
1946 packetdata.dst_id_len,
1950 packetdata.buffer = sock->outbuf;
1952 /* Encrypt payload of the packet. Encrypt with private message specific
1953 key if it exist, otherwise with session key. */
1954 cipher->cipher->encrypt(cipher->context, buffer->data, buffer->data,
1955 buffer->len, cipher->iv);
1957 /* Put the actual encrypted payload data into the buffer. */
1958 silc_buffer_put(sock->outbuf, buffer->data, buffer->len);
1960 /* Create the outgoing packet */
1961 silc_packet_assemble(&packetdata);
1963 /* Compute MAC of the packet */
1964 silc_hmac_make_with_key(hmac, sock->outbuf->data, sock->outbuf->len,
1965 hmac_key, hmac_key_len, mac);
1966 silc_buffer_put_tail(sock->outbuf, mac, mac_len);
1967 memset(mac, 0, sizeof(mac));
1969 SILC_LOG_HEXDUMP(("XXX"), sock->outbuf->data, sock->outbuf->len);
1971 /* Encrypt the header and padding of the packet. */
1972 silc_packet_encrypt(cipher, sock->outbuf, SILC_PACKET_HEADER_LEN +
1973 packetdata.src_id_len + packetdata.dst_id_len +
1976 /* Pull MAC into the visible data area */
1977 silc_buffer_pull_tail(sock->outbuf, mac_len);
1979 SILC_LOG_HEXDUMP(("Private message packet, len %d", sock->outbuf->len),
1980 sock->outbuf->data, sock->outbuf->len);
1982 /* Now actually send the packet */
1983 silc_client_packet_send_real(client, sock, force_send);
1984 silc_free(packetdata.dst_id);
1990 /* Closes connection to remote end. Free's all allocated data except
1991 for some information such as nickname etc. that are valid at all time. */
1993 void silc_client_close_connection(SilcClient client,
1994 SilcSocketConnection sock)
1996 SilcClientWindow win;
1999 /* We won't listen for this connection anymore */
2000 silc_schedule_unset_listen_fd(sock->sock);
2002 /* Unregister all tasks */
2003 silc_task_unregister_by_fd(client->io_queue, sock->sock);
2004 silc_task_unregister_by_fd(client->timeout_queue, sock->sock);
2006 /* Close the actual connection */
2007 silc_net_close_connection(sock->sock);
2009 silc_say(client, "Closed connection to host %s", sock->hostname ?
2010 sock->hostname : sock->ip);
2012 /* Free everything */
2013 if (sock->user_data) {
2014 win = (SilcClientWindow)sock->user_data;
2016 /* Clear ID caches */
2017 for (i = 0; i < 96; i++)
2018 silc_idcache_del_all(&win->client_id_cache[i],
2019 win->client_id_cache_count[i]);
2020 for (i = 0; i < 96; i++)
2021 silc_idcache_del_all(&win->channel_id_cache[i],
2022 win->channel_id_cache_count[i]);
2025 if (win->remote_host)
2026 silc_free(win->remote_host);
2028 silc_free(win->local_id);
2029 if (win->local_id_data)
2030 silc_free(win->local_id_data);
2032 silc_cipher_free(win->send_key);
2033 if (win->receive_key)
2034 silc_cipher_free(win->receive_key);
2036 silc_hmac_free(win->hmac);
2037 if (win->hmac_key) {
2038 memset(win->hmac_key, 0, win->hmac_key_len);
2039 silc_free(win->hmac_key);
2043 win->remote_port = 0;
2044 win->remote_type = 0;
2045 win->send_key = NULL;
2046 win->receive_key = NULL;
2048 win->hmac_key = NULL;
2049 win->hmac_key_len = 0;
2050 win->local_id = NULL;
2051 win->local_id_data = NULL;
2052 win->remote_host = NULL;
2055 if (sock->protocol) {
2056 silc_protocol_free(sock->protocol);
2057 sock->protocol = NULL;
2059 silc_socket_free(sock);
2062 /* Called when we receive disconnection packet from server. This
2063 closes our end properly and displays the reason of the disconnection
2066 void silc_client_disconnected_by_server(SilcClient client,
2067 SilcSocketConnection sock,
2072 SILC_LOG_DEBUG(("Server disconnected us, sock %d", sock->sock));
2074 msg = silc_calloc(message->len + 1, sizeof(char));
2075 memcpy(msg, message->data, message->len);
2076 silc_say(client, msg);
2079 SILC_SET_DISCONNECTED(sock);
2080 silc_client_close_connection(client, sock);
2083 /* Received error message from server. Display it on the screen.
2084 We don't take any action what so ever of the error message. */
2086 void silc_client_error_by_server(SilcClient client,
2087 SilcSocketConnection sock,
2092 msg = silc_calloc(message->len + 1, sizeof(char));
2093 memcpy(msg, message->data, message->len);
2094 silc_say(client, msg);
2098 /* Received notify message from server */
2100 void silc_client_notify_by_server(SilcClient client,
2101 SilcSocketConnection sock,
2106 msg = silc_calloc(message->len + 1, sizeof(char));
2107 memcpy(msg, message->data, message->len);
2108 silc_say(client, msg);
2112 /* Processes the received new Client ID from server. Old Client ID is
2113 deleted from cache and new one is added. */
2115 void silc_client_receive_new_id(SilcClient client,
2116 SilcSocketConnection sock,
2117 unsigned char *id_string)
2119 SilcClientWindow win = (SilcClientWindow)sock->user_data;
2120 char *nickname = win->nickname;
2122 #define CIDC(x) win->client_id_cache[(x) - 32]
2123 #define CIDCC(x) win->client_id_cache_count[(x) - 32]
2125 /* Delete old ID from ID cache */
2126 silc_idcache_del_by_id(CIDC(nickname[0]), CIDCC(nickname[0]),
2127 SILC_ID_CLIENT, win->local_id);
2129 /* Save the new ID */
2131 silc_free(win->local_id);
2132 win->local_id = silc_id_str2id(id_string, SILC_ID_CLIENT);
2133 if (win->local_id_data)
2134 silc_free(win->local_id_data);
2135 win->local_id_data =
2136 silc_calloc(SILC_ID_CLIENT_LEN, sizeof(unsigned char));
2137 memcpy(win->local_id_data, id_string, SILC_ID_CLIENT_LEN);
2138 win->local_id_data_len = SILC_ID_CLIENT_LEN;
2139 if (!win->local_entry)
2140 win->local_entry = silc_calloc(1, sizeof(*win->local_entry));
2141 win->local_entry->nickname = win->nickname;
2142 win->local_entry->id = win->local_id;
2144 /* Put it to the ID cache */
2145 CIDCC(nickname[0]) = silc_idcache_add(&CIDC(nickname[0]),
2147 win->nickname, SILC_ID_CLIENT,
2149 (void *)win->local_entry);
2154 /* Processed received Channel ID for a channel. This is called when client
2155 joins to channel and server replies with channel ID. The ID is cached. */
2157 void silc_client_new_channel_id(SilcClient client,
2158 SilcSocketConnection sock,
2161 unsigned char *id_string)
2163 SilcClientWindow win = (SilcClientWindow)sock->user_data;
2165 SilcChannelEntry channel;
2167 SILC_LOG_DEBUG(("New channel ID"));
2169 #define CIDC(x) win->channel_id_cache[(x) - 32]
2170 #define CIDCC(x) win->channel_id_cache_count[(x) - 32]
2172 id = silc_id_str2id(id_string, SILC_ID_CHANNEL);
2173 channel = silc_calloc(1, sizeof(*channel));
2174 channel->channel_name = channel_name;
2176 channel->mode = mode;
2177 win->current_channel = channel;
2179 /* Put it to the ID cache */
2180 CIDCC(channel_name[0]) = silc_idcache_add(&CIDC(channel_name[0]),
2181 CIDCC(channel_name[0]),
2182 channel_name, SILC_ID_CHANNEL,
2183 id, (void *)channel);
2188 /* Processes received key for channel. The received key will be used
2189 to protect the traffic on the channel for now on. Client must receive
2190 the key to the channel before talking on the channel is possible.
2191 This is the key that server has generated, this is not the channel
2192 private key, it is entirely local setting. */
2194 void silc_client_receive_channel_key(SilcClient client,
2195 SilcSocketConnection sock,
2199 unsigned char *id_string, *key, *cipher;
2200 unsigned int key_len;
2201 SilcClientWindow win = (SilcClientWindow)sock->user_data;
2203 SilcIDCache *id_cache = NULL;
2204 SilcChannelEntry channel;
2205 SilcChannelKeyPayload payload;
2207 SILC_LOG_DEBUG(("Received key for channel"));
2209 #define CIDC(x) win->channel_id_cache[(x)]
2210 #define CIDCC(x) win->channel_id_cache_count[(x)]
2212 payload = silc_channel_key_parse_payload(packet);
2216 id_string = silc_channel_key_get_id(payload, NULL);
2218 silc_channel_key_free_payload(payload);
2221 id = silc_id_str2id(id_string, SILC_ID_CHANNEL);
2223 /* Find channel. XXX: This is bad and slow. */
2224 for (i = 0; i < 96; i++) {
2225 if (CIDC(i) == NULL)
2227 if (silc_idcache_find_by_id(CIDC(i), CIDCC(i), (void *)id,
2228 SILC_ID_CHANNEL, &id_cache))
2236 key = silc_channel_key_get_key(payload, &key_len);
2237 cipher = silc_channel_key_get_cipher(payload, NULL);
2239 channel = (SilcChannelEntry)id_cache->context;
2240 channel->key_len = key_len;
2241 channel->key = silc_calloc(key_len, sizeof(*channel->key));
2242 memcpy(channel->key, key, key_len);
2244 silc_cipher_alloc(cipher, &channel->channel_key);
2245 if (!channel->channel_key) {
2246 silc_say(client, "Cannot talk to channel: unsupported cipher %s", cipher);
2249 channel->channel_key->cipher->set_key(channel->channel_key->context,
2252 /* Client is now joined to the channel */
2253 channel->on_channel = TRUE;
2257 silc_channel_key_free_payload(payload);
2262 /* Process received message to a channel (or from a channel, really). This
2263 decrypts the channel message with channel specific key and parses the
2264 channel payload. Finally it displays the message on the screen. */
2266 void silc_client_channel_message(SilcClient client,
2267 SilcSocketConnection sock,
2268 SilcPacketContext *packet)
2271 SilcClientWindow win = (SilcClientWindow)sock->user_data;
2272 SilcBuffer buffer = packet->buffer;
2273 SilcChannelPayload payload = NULL;
2274 SilcChannelID *id = NULL;
2275 SilcChannelEntry channel;
2276 SilcIDCache *id_cache = NULL;
2278 #define CIDC(x) win->channel_id_cache[(x)]
2279 #define CIDCC(x) win->channel_id_cache_count[(x)]
2282 if (packet->dst_id_type != SILC_ID_CHANNEL)
2285 id = silc_id_str2id(packet->dst_id, SILC_ID_CHANNEL);
2287 /* Find the channel entry from channels on this window */
2288 for (i = 0; i < 96; i++) {
2289 if (CIDC(i) == NULL)
2291 if (silc_idcache_find_by_id(CIDC(i), CIDCC(i), (void *)id,
2292 SILC_ID_CHANNEL, &id_cache))
2299 channel = (SilcChannelEntry)id_cache->context;
2301 /* Decrypt the channel message payload. Push the IV out of the way,
2302 since it is not encrypted (after pushing buffer->tail has the IV). */
2303 silc_buffer_push_tail(buffer, 16);
2304 channel->channel_key->cipher->decrypt(channel->channel_key->context,
2305 buffer->data, buffer->data,
2306 buffer->len, buffer->tail);
2307 silc_buffer_pull_tail(buffer, 16);
2309 /* Parse the channel message payload */
2310 payload = silc_channel_parse_payload(buffer);
2314 /* Display the message on screen */
2315 if (packet->src_id_type == SILC_ID_CLIENT)
2316 /* Message from client */
2317 silc_print(client, "<%s> %s", silc_channel_get_nickname(payload, NULL),
2318 silc_channel_get_data(payload, NULL));
2320 /* Message from server */
2321 silc_say(client, "%s", silc_channel_get_data(payload, NULL));
2327 silc_channel_free_payload(payload);