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.6 2000/07/07 06:54:16 priikone
24 * Print channel name when receiving channel message to non-current
27 * Revision 1.5 2000/07/06 07:14:36 priikone
28 * Fixes to NAMES command handling.
29 * Fixes when leaving from channel.
31 * Revision 1.4 2000/07/05 06:12:05 priikone
32 * Global cosmetic changes.
34 * Revision 1.3 2000/07/04 08:29:12 priikone
35 * Added support for PING command. The ping times are calculated
36 * and showed to the user.
38 * Revision 1.2 2000/07/03 05:49:48 priikone
39 * Implemented LEAVE command. Minor bug fixes.
41 * Revision 1.1.1.1 2000/06/27 11:36:56 priikone
42 * Imported from internal CVS/Added Log headers.
47 #include "clientincludes.h"
49 /* Static function prototypes */
50 static int silc_client_bad_keys(unsigned char key);
51 static void silc_client_process_message(SilcClient client);
52 static char *silc_client_parse_command(unsigned char *buffer);
54 /* Static task callback prototypes */
55 SILC_TASK_CALLBACK(silc_client_update_clock);
56 SILC_TASK_CALLBACK(silc_client_run_commands);
57 SILC_TASK_CALLBACK(silc_client_process_key_press);
58 SILC_TASK_CALLBACK(silc_client_connect_to_server_start);
59 SILC_TASK_CALLBACK(silc_client_connect_to_server_second);
60 SILC_TASK_CALLBACK(silc_client_connect_to_server_final);
61 SILC_TASK_CALLBACK(silc_client_packet_process);
62 SILC_TASK_CALLBACK(silc_client_packet_parse);
64 SilcClientWindow silc_client_create_main_window(SilcClient client);
65 SilcClientWindow silc_client_add_window(SilcClient client,
67 void silc_client_packet_parse_type(SilcClient client,
68 SilcSocketConnection sock,
69 SilcPacketContext *packet);
70 void silc_client_private_message_process(SilcClient client,
71 SilcSocketConnection sock,
72 SilcPacketContext *packet);
74 /* Definitions from version.h */
75 extern char *silc_version;
76 extern char *silc_name;
77 extern char *silc_fullname;
79 /* Allocates new client object. This has to be done before client may
80 work. After calling this one must call silc_client_init to initialize
83 int silc_client_alloc(SilcClient *new_client)
86 *new_client = silc_calloc(1, sizeof(**new_client));
87 (*new_client)->input_buffer = NULL;
88 (*new_client)->screen = NULL;
89 (*new_client)->windows = NULL;
90 (*new_client)->windows_count = 0;
91 (*new_client)->current_win = NULL;
96 /* Free's client object */
98 void silc_client_free(SilcClient client)
105 /* Initializes the client. This makes all the necessary steps to make
106 the client ready to be run. One must call silc_client_run to run the
109 int silc_client_init(SilcClient client)
112 SILC_LOG_DEBUG(("Initializing client"));
115 client->username = silc_get_username();
116 client->realname = silc_get_real_name();
118 /* Register all configured ciphers, PKCS and hash functions. */
119 client->config->client = (void *)client;
120 silc_client_config_register_ciphers(client->config);
121 silc_client_config_register_pkcs(client->config);
122 silc_client_config_register_hashfuncs(client->config);
124 /* Initialize hash functions for client to use */
125 silc_hash_alloc("md5", &client->md5hash);
126 silc_hash_alloc("sha1", &client->sha1hash);
128 /* Initialize none cipher */
129 silc_cipher_alloc("none", &client->none_cipher);
131 /* Initialize random number generator */
132 client->rng = silc_rng_alloc();
133 silc_rng_init(client->rng);
134 silc_math_primegen_init(); /* XXX */
136 /* Load public and private key */
137 if (silc_client_load_keys(client) == FALSE)
140 /* Register the task queues. In SILC we have by default three task queues.
141 One task queue for non-timeout tasks which perform different kind of
142 I/O on file descriptors, timeout task queue for timeout tasks, and,
143 generic non-timeout task queue whose tasks apply to all connections. */
144 silc_task_queue_alloc(&client->io_queue, TRUE);
145 if (!client->io_queue) {
148 silc_task_queue_alloc(&client->timeout_queue, TRUE);
149 if (!client->timeout_queue) {
152 silc_task_queue_alloc(&client->generic_queue, TRUE);
153 if (!client->generic_queue) {
157 /* Initialize the scheduler */
158 silc_schedule_init(client->io_queue, client->timeout_queue,
159 client->generic_queue, 5000);
161 /* Register the main task that is used in client. This received
162 the key pressings. */
163 if (silc_task_register(client->io_queue, fileno(stdin),
164 silc_client_process_key_press,
165 (void *)client, 0, 0,
167 SILC_TASK_PRI_NORMAL) == NULL) {
171 /* Register timeout task that updates clock every minute. */
172 if (silc_task_register(client->timeout_queue, 0,
173 silc_client_update_clock,
175 silc_client_time_til_next_min(), 0,
177 SILC_TASK_PRI_LOW) == NULL) {
181 if (client->config->commands) {
182 /* Run user configured commands with timeout */
183 if (silc_task_register(client->timeout_queue, 0,
184 silc_client_run_commands,
185 (void *)client, 0, 1,
187 SILC_TASK_PRI_LOW) == NULL) {
192 /* Allocate the input buffer used to save typed characters */
193 client->input_buffer = silc_buffer_alloc(SILC_SCREEN_INPUT_WIN_SIZE);
194 silc_buffer_pull_tail(client->input_buffer,
195 SILC_BUFFER_END(client->input_buffer));
197 /* Initialize the screen */
198 client->screen = silc_screen_init();
199 silc_client_create_main_window(client);
200 client->screen->input_buffer = client->input_buffer->data;
201 silc_screen_print_coordinates(client->screen, 0);
206 silc_task_queue_free(client->timeout_queue);
208 silc_task_queue_free(client->io_queue);
213 /* Stops the client. This is called to stop the client and thus to stop
216 void silc_client_stop(SilcClient client)
218 SILC_LOG_DEBUG(("Stopping client"));
220 /* Stop the scheduler, although it might be already stopped. This
221 doesn't hurt anyone. This removes all the tasks and task queues,
223 silc_schedule_stop();
224 silc_schedule_uninit();
226 SILC_LOG_DEBUG(("Client client"));
229 /* Runs the client. */
231 void silc_client_run(SilcClient client)
233 SILC_LOG_DEBUG(("Running client"));
235 /* Start the scheduler, the heart of the SILC client. When this returns
236 the program will be terminated. */
240 /* Creates the main window used in SILC client. This is called always
241 at the initialization of the client. If user wants to create more
242 than one windows a new windows are always created by calling
243 silc_client_add_window. */
245 SilcClientWindow silc_client_create_main_window(SilcClient client)
247 SilcClientWindow win;
250 SILC_LOG_DEBUG(("Creating main window"));
252 assert(client->screen != NULL);
254 win = silc_calloc(1, sizeof(*win));
256 client->screen->u_stat_line.program_name = silc_name;
257 client->screen->u_stat_line.program_version = silc_version;
259 /* Add the pointers */
260 win->nickname = silc_get_username();
261 win->local_id = NULL;
262 win->local_id_data = NULL;
263 win->local_id_data_len = 0;
264 win->remote_host = NULL;
265 win->remote_port = -1;
268 /* Create the actual screen */
269 screen = (void *)silc_screen_create_output_window(client->screen);
270 silc_screen_create_input_window(client->screen);
271 silc_screen_init_upper_status_line(client->screen);
272 silc_screen_init_output_status_line(client->screen);
273 win->screen = screen;
275 client->screen->bottom_line->nickname = win->nickname;
276 silc_screen_print_bottom_line(client->screen, 0);
278 /* Add the window to windows table */
279 client->windows = silc_calloc(1, sizeof(*client->windows));
280 client->windows[client->windows_count] = win;
281 client->windows_count = 1;
283 /* Automatically becomes the current active window */
284 client->current_win = win;
289 /* Allocates and adds new window to the client. This allocates new
290 physical window and internal window for connection specific data.
291 All the connection specific data is always saved into a window
292 since connection is always associated to a active window. */
294 SilcClientWindow silc_client_add_window(SilcClient client,
297 SilcClientWindow win;
299 assert(client->screen != NULL);
301 win = silc_calloc(1, sizeof(*win));
303 /* Add the pointers */
304 win->screen = silc_screen_add_output_window(client->screen);
307 /* Add the window to windows table */
308 client->windows = silc_realloc(client->windows, sizeof(*client->windows)
309 * (client->windows_count + 1));
310 client->windows[client->windows_count] = win;
311 client->windows_count++;
313 if (is_current == TRUE)
314 client->current_win = win;
319 /* The main task on SILC client. This processes the key pressings user
322 SILC_TASK_CALLBACK(silc_client_process_key_press)
324 SilcClient client = (SilcClient)context;
327 /* There is data pending in stdin, this gets it directly */
328 c = wgetch(client->screen->input_win);
329 if (silc_client_bad_keys(c))
332 SILC_LOG_DEBUG(("Pressed key: %d", c));
336 * Special character handling
343 SILC_LOG_DEBUG(("RIGHT"));
344 silc_screen_input_cursor_right(client->screen);
348 SILC_LOG_DEBUG(("LEFT"));
349 silc_screen_input_cursor_left(client->screen);
356 silc_screen_input_backspace(client->screen);
362 /* Insert switch. Turns on/off insert on input window */
363 silc_screen_input_insert(client->screen);
367 /* Enter, Return. User pressed enter we are ready to
368 process the message. */
369 silc_client_process_message(client);
370 silc_screen_input_reset(client->screen);
373 /* Refresh screen, Ctrl^l */
374 silc_screen_refresh_all(client->screen);
379 /* Beginning, Home */
380 silc_screen_input_cursor_home(client->screen);
385 silc_screen_input_cursor_end(client->screen);
403 /* Control codes are printed as reversed */
405 wattron(client->screen->input_win, A_REVERSE);
406 silc_screen_input_print(client->screen, c);
407 wattroff(client->screen->input_win, A_REVERSE);
409 /* Normal character */
410 silc_screen_input_print(client->screen, c);
414 silc_screen_print_coordinates(client->screen, 0);
415 silc_screen_refresh_win(client->screen->input_win);
418 static int silc_client_bad_keys(unsigned char key)
420 /* these are explained in curses.h */
435 case '\E': /* we ignore ESC */
442 /* Processes messages user has typed on the screen. This either sends
443 a packet out to network or if command were written executes it. */
445 static void silc_client_process_message(SilcClient client)
450 SILC_LOG_DEBUG(("Start"));
452 data = client->input_buffer->data;
455 if (data[0] == '/' && data[1] != ' ') {
457 unsigned int argc = 0;
458 unsigned char **argv, *tmpcmd;
459 unsigned int *argv_lens, *argv_types;
460 SilcClientCommand *cmd;
461 SilcClientCommandContext ctx;
463 /* Get the command */
464 tmpcmd = silc_client_parse_command(data);
466 /* Find command match */
467 for (cmd = silc_command_list; cmd->name; cmd++) {
468 if (!strcmp(cmd->name, tmpcmd))
472 if (cmd->name == NULL) {
473 silc_say(client, "Invalid command: %s", tmpcmd);
478 /* Now parse all arguments */
479 silc_client_parse_command_line(data, &argv, &argv_lens,
480 &argv_types, &argc, cmd->max_args);
483 SILC_LOG_DEBUG(("Exeuting command: %s", cmd->name));
485 /* Allocate command context. This and its internals must be free'd
486 by the command routine receiving it. */
487 ctx = silc_calloc(1, sizeof(*ctx));
488 ctx->client = client;
489 ctx->sock = client->current_win->sock;
492 ctx->argv_lens = argv_lens;
493 ctx->argv_types = argv_types;
495 /* Execute command */
499 /* Normal message to a channel */
500 if (len && client->current_win->current_channel &&
501 client->current_win->current_channel->on_channel == TRUE) {
502 silc_print(client, "> %s", data);
503 silc_client_packet_send_to_channel(client,
504 client->current_win->sock,
505 client->current_win->current_channel,
506 data, strlen(data), TRUE);
511 /* Clear the input buffer */
512 silc_buffer_clear(client->input_buffer);
513 silc_buffer_pull_tail(client->input_buffer,
514 SILC_BUFFER_END(client->input_buffer));
517 /* Returns the command fetched from user typed command line */
519 static char *silc_client_parse_command(unsigned char *buffer)
522 const char *cp = buffer;
525 len = strcspn(cp, " ");
526 ret = silc_to_upper((char *)++cp);
532 /* Parses user typed command line. At most `max_args' is taken. Rest
533 of the line will be allocated as the last argument if there are more
534 than `max_args' arguments in the line. Note that the command name
535 is counted as one argument and is saved. */
537 void silc_client_parse_command_line(unsigned char *buffer,
538 unsigned char ***parsed,
539 unsigned int **parsed_lens,
540 unsigned int **parsed_types,
541 unsigned int *parsed_num,
542 unsigned int max_args)
546 const char *cp = buffer;
548 /* Take the '/' away */
551 *parsed = silc_calloc(1, sizeof(**parsed));
552 *parsed_lens = silc_calloc(1, sizeof(**parsed_lens));
554 /* Get the command first */
555 len = strcspn(cp, " ");
556 (*parsed)[0] = silc_to_upper((char *)cp);
557 (*parsed_lens)[0] = len;
561 /* Parse arguments */
562 if (strchr(cp, ' ') || strlen(cp) != 0) {
563 for (i = 1; i < max_args; i++) {
565 if (i != max_args - 1)
566 len = strcspn(cp, " ");
570 *parsed = silc_realloc(*parsed, sizeof(**parsed) * (argc + 1));
571 *parsed_lens = silc_realloc(*parsed_lens,
572 sizeof(**parsed_lens) * (argc + 1));
573 (*parsed)[argc] = silc_calloc(len + 1, sizeof(char));
574 memcpy((*parsed)[argc], cp, len);
575 (*parsed_lens)[argc] = len;
586 /* Save argument types. Protocol defines all argument types but
587 this implementation makes sure that they are always in correct
588 order hence this simple code. */
589 *parsed_types = silc_calloc(argc, sizeof(**parsed_types));
590 for (i = 0; i < argc; i++)
591 (*parsed_types)[i] = i;
596 /* Updates clock on the screen every minute. */
598 SILC_TASK_CALLBACK(silc_client_update_clock)
600 SilcClient client = (SilcClient)context;
602 /* Update the clock on the screen */
603 silc_screen_print_clock(client->screen);
605 /* Re-register this same task */
606 silc_task_register(qptr, 0, silc_client_update_clock, context,
607 silc_client_time_til_next_min(), 0,
611 silc_screen_refresh_win(client->screen->input_win);
614 /* Runs commands user configured in configuration file. This is
615 called when initializing client. */
617 SILC_TASK_CALLBACK(silc_client_run_commands)
619 SilcClient client = (SilcClient)context;
620 SilcClientConfigSectionCommand *cs;
622 SILC_LOG_DEBUG(("Start"));
624 cs = client->config->commands;
626 unsigned int argc = 0;
627 unsigned char **argv, *tmpcmd;
628 unsigned int *argv_lens, *argv_types;
629 SilcClientCommand *cmd;
630 SilcClientCommandContext ctx;
632 /* Get the command */
633 tmpcmd = silc_client_parse_command(cs->command);
635 for (cmd = silc_command_list; cmd->name; cmd++) {
636 if (!strcmp(cmd->name, tmpcmd))
640 if (cmd->name == NULL) {
641 silc_say(client, "Invalid command: %s", tmpcmd);
646 /* Now parse all arguments */
647 silc_client_parse_command_line(cs->command, &argv, &argv_lens,
648 &argv_types, &argc, cmd->max_args);
651 SILC_LOG_DEBUG(("Exeuting command: %s", cmd->name));
653 /* Allocate command context. This and its internals must be free'd
654 by the command routine receiving it. */
655 ctx = silc_calloc(1, sizeof(*ctx));
656 ctx->client = client;
657 ctx->sock = client->current_win->sock;
660 ctx->argv_lens = argv_lens;
661 ctx->argv_types = argv_types;
663 /* Execute command */
670 /* Internal context for connection process. This is needed as we
671 doing asynchronous connecting. */
679 } SilcClientInternalConnectContext;
682 silc_client_connect_to_server_internal(SilcClientInternalConnectContext *ctx)
686 /* XXX In the future we should give up this non-blocking connect all
687 together and use threads instead. */
688 /* Create connection to server asynchronously */
689 sock = silc_net_create_connection_async(ctx->port, ctx->host);
693 /* Register task that will receive the async connect and will
695 ctx->task = silc_task_register(ctx->client->io_queue, sock,
696 silc_client_connect_to_server_start,
699 SILC_TASK_PRI_NORMAL);
700 silc_task_reset_iotype(ctx->task, SILC_TASK_WRITE);
701 silc_schedule_set_listen_fd(sock, ctx->task->iomask);
708 /* Connects to remote server */
710 int silc_client_connect_to_server(SilcClient client, int port,
713 SilcClientInternalConnectContext *ctx;
715 SILC_LOG_DEBUG(("Connecting to port %d of server %s",
718 silc_say(client, "Connecting to port %d of server %s", port, host);
720 client->current_win->remote_host = strdup(host);
721 client->current_win->remote_port = port;
723 /* Allocate internal context for connection process. This is
724 needed as we are doing async connecting. */
725 ctx = silc_calloc(1, sizeof(*ctx));
726 ctx->client = client;
727 ctx->host = strdup(host);
731 /* Do the actual connecting process */
732 return silc_client_connect_to_server_internal(ctx);
735 /* Start of the connection to the remote server. This is called after
736 succesful TCP/IP connection has been established to the remote host. */
738 SILC_TASK_CALLBACK(silc_client_connect_to_server_start)
740 SilcClientInternalConnectContext *ctx =
741 (SilcClientInternalConnectContext *)context;
742 SilcClient client = ctx->client;
743 SilcProtocol protocol;
744 SilcClientKEInternalContext *proto_ctx;
745 int opt, opt_len = sizeof(opt);
747 SILC_LOG_DEBUG(("Start"));
749 /* Check the socket status as it might be in error */
750 getsockopt(fd, SOL_SOCKET, SO_ERROR, &opt, &opt_len);
752 if (ctx->tries < 2) {
753 /* Connection failed but lets try again */
754 silc_say(ctx->client, "Could not connect to server %s: %s",
755 ctx->host, strerror(opt));
756 silc_say(client, "Connecting to port %d of server %s resumed",
757 ctx->port, ctx->host);
759 /* Unregister old connection try */
760 silc_schedule_unset_listen_fd(fd);
761 silc_net_close_connection(fd);
762 silc_task_unregister(client->io_queue, ctx->task);
765 silc_client_connect_to_server_internal(ctx);
768 /* Connection failed and we won't try anymore */
769 silc_say(ctx->client, "Could not connect to server %s: %s",
770 ctx->host, strerror(opt));
771 silc_schedule_unset_listen_fd(fd);
772 silc_net_close_connection(fd);
773 silc_task_unregister(client->io_queue, ctx->task);
779 silc_schedule_unset_listen_fd(fd);
780 silc_task_unregister(client->io_queue, ctx->task);
783 /* Allocate new socket connection object */
784 silc_socket_alloc(fd, SILC_SOCKET_TYPE_SERVER,
785 (void *)client->current_win,
786 &client->current_win->sock);
787 if (client->current_win->sock == NULL) {
788 silc_say(client, "Error: Could not allocate connection socket");
789 silc_net_close_connection(fd);
792 client->current_win->sock->hostname = client->current_win->remote_host;
793 client->current_win->sock->port = client->current_win->remote_port;
795 /* Allocate internal Key Exchange context. This is sent to the
796 protocol as context. */
797 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
798 proto_ctx->client = (void *)client;
799 proto_ctx->sock = client->current_win->sock;
800 proto_ctx->rng = client->rng;
801 proto_ctx->responder = FALSE;
803 /* Perform key exchange protocol. silc_client_connect_to_server_final
804 will be called after the protocol is finished. */
805 silc_protocol_alloc(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
806 &protocol, (void *)proto_ctx,
807 silc_client_connect_to_server_second);
809 silc_say(client, "Error: Could not start authentication protocol");
812 client->current_win->sock->protocol = protocol;
814 /* Register the connection for network input and output. This sets
815 that scheduler will listen for incoming packets for this connection
816 and sets that outgoing packets may be sent to this connection as well.
817 However, this doesn't set the scheduler for outgoing traffic, it will
818 be set separately by calling SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT,
819 later when outgoing data is available. */
820 context = (void *)client;
821 SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(fd);
823 /* Execute the protocol */
824 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0);
827 /* Second part of the connecting to the server. This executed
828 authentication protocol. */
830 SILC_TASK_CALLBACK(silc_client_connect_to_server_second)
832 SilcProtocol protocol = (SilcProtocol)context;
833 SilcClientKEInternalContext *ctx =
834 (SilcClientKEInternalContext *)protocol->context;
835 SilcClient client = (SilcClient)ctx->client;
836 SilcSocketConnection sock = NULL;
837 SilcClientConnAuthInternalContext *proto_ctx;
839 SILC_LOG_DEBUG(("Start"));
841 if (protocol->state == SILC_PROTOCOL_STATE_ERROR) {
842 /* Error occured during protocol */
843 SILC_LOG_DEBUG(("Error during KE protocol"));
844 silc_protocol_free(protocol);
846 silc_ske_free(ctx->ske);
848 silc_free(ctx->dest_id);
849 ctx->sock->protocol = NULL;
854 /* Allocate internal context for the authentication protocol. This
855 is sent as context for the protocol. */
856 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
857 proto_ctx->client = (void *)client;
858 proto_ctx->sock = sock = ctx->sock;
859 proto_ctx->ske = ctx->ske; /* Save SKE object from previous protocol */
860 proto_ctx->dest_id_type = ctx->dest_id_type;
861 proto_ctx->dest_id = ctx->dest_id;
863 /* Resolve the authentication method to be used in this connection */
864 proto_ctx->auth_meth = SILC_PROTOCOL_CONN_AUTH_NONE;
865 if (client->config->conns) {
866 SilcClientConfigSectionConnection *conn = NULL;
868 /* Check if we find a match from user configured connections */
869 conn = silc_client_config_find_connection(client->config,
873 /* Match found. Use the configured authentication method */
874 proto_ctx->auth_meth = conn->auth_meth;
875 if (conn->auth_data) {
876 proto_ctx->auth_data = strdup(conn->auth_data);
877 proto_ctx->auth_data_len = strlen(conn->auth_data);
880 /* No match found. Resolve by sending AUTH_REQUEST to server */
881 proto_ctx->auth_meth = SILC_PROTOCOL_CONN_AUTH_NONE;
884 /* XXX Resolve by sending AUTH_REQUEST to server */
885 proto_ctx->auth_meth = SILC_PROTOCOL_CONN_AUTH_NONE;
888 /* Free old protocol as it is finished now */
889 silc_protocol_free(protocol);
891 silc_buffer_free(ctx->packet);
893 /* silc_free(ctx->keymat....); */
894 sock->protocol = NULL;
896 /* Allocate the authentication protocol. This is allocated here
897 but we won't start it yet. We will be receiving party of this
898 protocol thus we will wait that connecting party will make
900 silc_protocol_alloc(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
901 &sock->protocol, (void *)proto_ctx,
902 silc_client_connect_to_server_final);
904 /* Execute the protocol */
905 sock->protocol->execute(client->timeout_queue, 0, sock->protocol, fd, 0, 0);
908 /* Finalizes the connection to the remote SILC server. This is called
909 after authentication protocol has been completed. This send our
910 user information to the server to receive our client ID from
913 SILC_TASK_CALLBACK(silc_client_connect_to_server_final)
915 SilcProtocol protocol = (SilcProtocol)context;
916 SilcClientConnAuthInternalContext *ctx =
917 (SilcClientConnAuthInternalContext *)protocol->context;
918 SilcClient client = (SilcClient)ctx->client;
919 SilcClientWindow win = (SilcClientWindow)ctx->sock->user_data;
922 SILC_LOG_DEBUG(("Start"));
924 if (protocol->state == SILC_PROTOCOL_STATE_ERROR) {
925 /* Error occured during protocol */
926 SILC_LOG_DEBUG(("Error during authentication protocol"));
927 silc_protocol_free(protocol);
929 silc_free(ctx->auth_data);
931 silc_ske_free(ctx->ske);
933 silc_free(ctx->dest_id);
935 win->sock->protocol = NULL;
939 /* Send NEW_CLIENT packet to the server. We will become registered
940 to the SILC network after sending this packet and we will receive
941 client ID from the server. */
942 packet = silc_buffer_alloc(2 + 2 + strlen(client->username) +
943 strlen(client->realname));
944 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
945 silc_buffer_format(packet,
946 SILC_STR_UI_SHORT(strlen(client->username)),
947 SILC_STR_UI_XNSTRING(client->username,
948 strlen(client->username)),
949 SILC_STR_UI_SHORT(strlen(client->realname)),
950 SILC_STR_UI_XNSTRING(client->realname,
951 strlen(client->realname)),
954 /* Send the packet */
955 silc_client_packet_send(client, ctx->sock, SILC_PACKET_NEW_CLIENT,
957 packet->data, packet->len, TRUE);
958 silc_buffer_free(packet);
960 /* Save remote ID. */
961 win->remote_id = ctx->dest_id;
962 win->remote_id_data = silc_id_id2str(ctx->dest_id, SILC_ID_CHANNEL);
963 win->remote_id_data_len = SILC_ID_CHANNEL_LEN;
965 silc_say(client, "Connected to port %d of host %s",
966 win->remote_port, win->remote_host);
968 client->screen->bottom_line->connection = win->remote_host;
969 silc_screen_print_bottom_line(client->screen, 0);
971 silc_protocol_free(protocol);
973 silc_free(ctx->auth_data);
975 silc_ske_free(ctx->ske);
977 silc_free(ctx->dest_id);
979 win->sock->protocol = NULL;
983 SilcPacketContext *packetdata;
984 SilcSocketConnection sock;
986 } SilcClientInternalPacket;
988 SILC_TASK_CALLBACK(silc_client_packet_process)
990 SilcClient client = (SilcClient)context;
991 SilcSocketConnection sock = NULL;
992 int ret, packetlen, paddedlen;
994 SILC_LOG_DEBUG(("Processing packet"));
996 SILC_CLIENT_GET_SOCK(client, fd, sock);
1000 /* Packet sending */
1001 if (type == SILC_TASK_WRITE) {
1002 SILC_LOG_DEBUG(("Writing data to connection"));
1004 if (sock->outbuf->data - sock->outbuf->head)
1005 silc_buffer_push(sock->outbuf,
1006 sock->outbuf->data - sock->outbuf->head);
1008 /* Write the packet out to the connection */
1009 ret = silc_packet_write(fd, sock->outbuf);
1011 /* If returned -2 could not write to connection now, will do
1018 SILC_LOG_ERROR(("Packet dropped"));
1020 /* The packet has been sent and now it is time to set the connection
1021 back to only for input. When there is again some outgoing data
1022 available for this connection it will be set for output as well.
1023 This call clears the output setting and sets it only for input. */
1024 SILC_CLIENT_SET_CONNECTION_FOR_INPUT(fd);
1025 SILC_UNSET_OUTBUF_PENDING(sock);
1030 /* Packet receiving */
1031 if (type == SILC_TASK_READ) {
1032 SILC_LOG_DEBUG(("Reading data from connection"));
1034 /* Allocate the incoming data buffer if not done already. */
1036 sock->inbuf = silc_buffer_alloc(SILC_PACKET_DEFAULT_SIZE);
1038 /* Read some data from connection */
1039 ret = silc_packet_read(fd, sock->inbuf);
1041 /* If returned -2 data was not available now, will read it later. */
1047 SILC_LOG_ERROR(("Packet dropped"));
1053 SILC_LOG_DEBUG(("Read EOF"));
1055 /* If connection is disconnecting already we will finally
1056 close the connection */
1057 if (SILC_IS_DISCONNECTING(sock)) {
1058 silc_client_close_connection(client, sock);
1062 silc_say(client, "Connection closed: premature EOF");
1063 SILC_LOG_DEBUG(("Premature EOF from connection %d", sock->sock));
1065 silc_client_close_connection(client, sock);
1069 /* Check whether we received a whole packet. If reading went without
1070 errors we either read a whole packet or the read packet is
1071 incorrect and will be dropped. */
1072 SILC_PACKET_LENGTH(sock->inbuf, packetlen, paddedlen);
1073 if (sock->inbuf->len < paddedlen || (packetlen < SILC_PACKET_MIN_LEN)) {
1074 SILC_LOG_DEBUG(("Received incorrect packet, dropped"));
1075 silc_buffer_clear(sock->inbuf);
1079 /* Decrypt a packet coming from server connection */
1080 if (sock->type == SILC_SOCKET_TYPE_SERVER ||
1081 sock->type == SILC_SOCKET_TYPE_ROUTER) {
1082 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1083 SilcClientInternalPacket *packet;
1087 mac_len = win->hmac->hash->hash->hash_len;
1089 if (sock->inbuf->len - 2 > (paddedlen + mac_len)) {
1090 /* Received possibly many packets at once */
1092 while(sock->inbuf->len > 0) {
1093 SILC_PACKET_LENGTH(sock->inbuf, packetlen, paddedlen);
1094 if (sock->inbuf->len < paddedlen) {
1095 SILC_LOG_DEBUG(("Received incorrect packet, dropped"));
1100 packet = silc_calloc(1, sizeof(*packet));
1101 packet->client = client;
1102 packet->sock = sock;
1103 packet->packetdata = silc_calloc(1, sizeof(*packet->packetdata));
1104 packet->packetdata->buffer = silc_buffer_alloc(paddedlen + mac_len);
1105 silc_buffer_pull_tail(packet->packetdata->buffer,
1106 SILC_BUFFER_END(packet->packetdata->buffer));
1107 silc_buffer_put(packet->packetdata->buffer, sock->inbuf->data,
1108 paddedlen + mac_len);
1110 SILC_LOG_HEXDUMP(("Incoming packet, len %d",
1111 packet->packetdata->buffer->len),
1112 packet->packetdata->buffer->data,
1113 packet->packetdata->buffer->len);
1114 SILC_LOG_DEBUG(("Packet from server %s, "
1115 "server type %d, packet length %d",
1116 win->remote_host, win->remote_type, paddedlen));
1118 /* If this packet is for the current active connection we will
1119 parse the packet right away to get it quickly on the screen.
1120 Otherwise, it will be parsed with a timeout as the data is
1121 for inactive window (which might not be visible at all). */
1122 if (SILC_CLIENT_IS_CURRENT_WIN(client, win)) {
1123 /* Parse it real soon */
1124 silc_task_register(client->timeout_queue, fd,
1125 silc_client_packet_parse,
1126 (void *)packet, 0, 1,
1128 SILC_TASK_PRI_NORMAL);
1130 /* Parse the packet with timeout */
1131 silc_task_register(client->timeout_queue, fd,
1132 silc_client_packet_parse,
1133 (void *)packet, 0, 200000,
1135 SILC_TASK_PRI_NORMAL);
1138 /* Pull the packet from inbuf thus we'll get the next one
1140 silc_buffer_pull(sock->inbuf, paddedlen);
1142 silc_buffer_pull(sock->inbuf, mac_len);
1144 silc_buffer_clear(sock->inbuf);
1147 /* Received one packet */
1149 SILC_LOG_HEXDUMP(("An incoming packet, len %d", sock->inbuf->len),
1150 sock->inbuf->data, sock->inbuf->len);
1151 SILC_LOG_DEBUG(("Packet from server %s, "
1152 "server type %d, packet length %d",
1153 win->remote_host, win->remote_type, paddedlen));
1155 packet = silc_calloc(1, sizeof(*packet));
1156 packet->client = client;
1157 packet->sock = sock;
1158 packet->packetdata = silc_calloc(1, sizeof(*packet->packetdata));
1159 packet->packetdata->buffer = silc_buffer_copy(sock->inbuf);
1160 silc_buffer_clear(sock->inbuf);
1162 /* If this packet is for the current active connection we will
1163 parse the packet right away to get it quickly on the screen.
1164 Otherwise, it will be parsed with a timeout as the data is
1165 for inactive window (which might not be visible at all). */
1166 if (SILC_CLIENT_IS_CURRENT_WIN(client, win)) {
1167 /* Parse it real soon */
1168 silc_task_register(client->timeout_queue, fd,
1169 silc_client_packet_parse,
1170 (void *)packet, 0, 1,
1172 SILC_TASK_PRI_NORMAL);
1175 /* Parse the packet with timeout */
1176 silc_task_register(client->timeout_queue, fd,
1177 silc_client_packet_parse,
1178 (void *)packet, 0, 200000,
1180 SILC_TASK_PRI_NORMAL);
1187 SILC_LOG_ERROR(("Weird, nothing happened - ignoring"));
1190 /* Checks MAC in the packet. Returns TRUE if MAC is Ok. This is called
1191 after packet has been totally decrypted and parsed. */
1193 static int silc_client_packet_check_mac(SilcClient client,
1194 SilcSocketConnection sock,
1197 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1201 int headlen = buffer->data - buffer->head, mac_len;
1202 unsigned char *packet_mac, mac[32];
1204 SILC_LOG_DEBUG(("Verifying MAC"));
1206 mac_len = win->hmac->hash->hash->hash_len;
1208 silc_buffer_push(buffer, headlen);
1210 /* Take mac from packet */
1211 packet_mac = buffer->tail;
1213 /* Make MAC and compare */
1214 memset(mac, 0, sizeof(mac));
1215 silc_hmac_make_with_key(win->hmac,
1216 buffer->data, buffer->len,
1217 win->hmac_key, win->hmac_key_len, mac);
1219 SILC_LOG_HEXDUMP(("PMAC"), packet_mac, mac_len);
1220 SILC_LOG_HEXDUMP(("CMAC"), mac, mac_len);
1222 if (memcmp(mac, packet_mac, mac_len)) {
1223 SILC_LOG_DEBUG(("MAC failed"));
1227 SILC_LOG_DEBUG(("MAC is Ok"));
1228 memset(mac, 0, sizeof(mac));
1230 silc_buffer_pull(buffer, headlen);
1236 /* Decrypts rest of the packet (after decrypting just the SILC header).
1237 After calling this function the packet is ready to be parsed by calling
1238 silc_packet_parse. */
1240 static int silc_client_packet_decrypt_rest(SilcClient client,
1241 SilcSocketConnection sock,
1244 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1245 unsigned int mac_len = 0;
1248 if (win && win->receive_key) {
1250 /* Pull MAC from packet before decryption */
1252 mac_len = win->hmac->hash->hash->hash_len;
1253 if ((buffer->len - mac_len) > SILC_PACKET_MIN_LEN) {
1254 silc_buffer_push_tail(buffer, mac_len);
1256 SILC_LOG_DEBUG(("Bad MAC length in packet, packet dropped"));
1261 SILC_LOG_DEBUG(("Decrypting rest of the packet"));
1263 /* Decrypt rest of the packet */
1264 silc_buffer_pull(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
1265 silc_packet_decrypt(win->receive_key, buffer, buffer->len);
1266 silc_buffer_push(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
1268 SILC_LOG_HEXDUMP(("Fully decrypted packet, len %d", buffer->len),
1269 buffer->data, buffer->len);
1275 /* Decrypts rest of the SILC Packet header that has been decrypted partly
1276 already. This decrypts the padding of the packet also. After calling
1277 this function the packet is ready to be parsed by calling function
1278 silc_packet_parse. This is used in special packet reception. */
1280 static int silc_client_packet_decrypt_rest_special(SilcClient client,
1281 SilcSocketConnection sock,
1284 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1285 unsigned int mac_len = 0;
1287 /* Decrypt rest of the header plus padding */
1288 if (win && win->receive_key) {
1289 unsigned short truelen, len1, len2, padlen;
1291 /* Pull MAC from packet before decryption */
1293 mac_len = win->hmac->hash->hash->hash_len;
1294 if ((buffer->len - mac_len) > SILC_PACKET_MIN_LEN) {
1295 silc_buffer_push_tail(buffer, mac_len);
1297 SILC_LOG_DEBUG(("Bad MAC length in packet, packet dropped"));
1302 SILC_LOG_DEBUG(("Decrypting rest of the header"));
1304 SILC_GET16_MSB(len1, &buffer->data[4]);
1305 SILC_GET16_MSB(len2, &buffer->data[6]);
1307 truelen = SILC_PACKET_HEADER_LEN + len1 + len2;
1308 padlen = SILC_PACKET_PADLEN(truelen);
1309 len1 = (truelen + padlen) - (SILC_PACKET_MIN_HEADER_LEN - 2);
1311 silc_buffer_pull(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
1312 SILC_LOG_HEXDUMP(("XXX"), buffer->data, buffer->len);
1313 silc_packet_decrypt(win->receive_key, buffer, len1);
1314 silc_buffer_push(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
1315 SILC_LOG_HEXDUMP(("XXX"), buffer->data, buffer->len);
1321 /* Parses whole packet, received earlier. */
1323 SILC_TASK_CALLBACK(silc_client_packet_parse)
1325 SilcClientInternalPacket *packet = (SilcClientInternalPacket *)context;
1326 SilcBuffer buffer = packet->packetdata->buffer;
1327 SilcClient client = packet->client;
1328 SilcSocketConnection sock = packet->sock;
1329 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1332 SILC_LOG_DEBUG(("Start"));
1334 /* Decrypt start of the packet header */
1335 if (win && win->receive_key)
1336 silc_packet_decrypt(win->receive_key, buffer, SILC_PACKET_MIN_HEADER_LEN);
1338 /* If the packet type is not any special type lets decrypt rest
1339 of the packet here. */
1340 if (buffer->data[3] != SILC_PACKET_CHANNEL_MESSAGE &&
1341 buffer->data[3] != SILC_PACKET_PRIVATE_MESSAGE) {
1343 /* Normal packet, decrypt rest of the packet */
1344 if (!silc_client_packet_decrypt_rest(client, sock, buffer))
1347 /* Parse the packet. Packet type is returned. */
1348 ret = silc_packet_parse(packet->packetdata);
1349 if (ret == SILC_PACKET_NONE)
1353 if (!silc_client_packet_check_mac(client, sock, buffer))
1356 /* If private message key is not set for private message it is
1357 handled as normal packet. Go back up. */
1358 if (buffer->data[3] == SILC_PACKET_PRIVATE_MESSAGE &&
1359 !(buffer->data[2] & SILC_PACKET_FLAG_PRIVMSG_KEY))
1362 /* Packet requires special handling, decrypt rest of the header.
1363 This only decrypts. This does not do any MAC checking, it must
1364 be done individually later when doing the special processing. */
1365 silc_client_packet_decrypt_rest_special(client, sock, buffer);
1367 /* Parse the packet header in special way as this is "special"
1369 ret = silc_packet_parse_special(packet->packetdata);
1370 if (ret == SILC_PACKET_NONE)
1374 /* Parse the incoming packet type */
1375 silc_client_packet_parse_type(client, sock, packet->packetdata);
1378 silc_buffer_clear(packet->packetdata->buffer);
1379 silc_free(packet->packetdata);
1383 /* Parses the packet type and calls what ever routines the packet type
1384 requires. This is done for all incoming packets. */
1386 void silc_client_packet_parse_type(SilcClient client,
1387 SilcSocketConnection sock,
1388 SilcPacketContext *packet)
1390 SilcBuffer buffer = packet->buffer;
1391 SilcPacketType type = packet->type;
1393 SILC_LOG_DEBUG(("Parsing packet type %d", type));
1395 /* Parse the packet type */
1397 case SILC_PACKET_DISCONNECT:
1398 silc_client_disconnected_by_server(client, sock, buffer);
1400 case SILC_PACKET_SUCCESS:
1402 * Success received for something. For now we can have only
1403 * one protocol for connection executing at once hence this
1404 * success message is for whatever protocol is executing currently.
1406 if (sock->protocol) {
1407 sock->protocol->execute(client->timeout_queue, 0,
1408 sock->protocol, sock->sock, 0, 0);
1411 case SILC_PACKET_FAILURE:
1413 * Failure received for some protocol. Set the protocol state to
1414 * error and call the protocol callback. This fill cause error on
1415 * protocol and it will call the final callback.
1417 if (sock->protocol) {
1418 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
1419 sock->protocol->execute(client->timeout_queue, 0,
1420 sock->protocol, sock->sock, 0, 0);
1423 case SILC_PACKET_REJECT:
1426 case SILC_PACKET_NOTIFY:
1428 * Received notify message
1430 silc_client_notify_by_server(client, sock, buffer);
1433 case SILC_PACKET_ERROR:
1435 * Received error message
1437 silc_client_error_by_server(client, sock, buffer);
1440 case SILC_PACKET_CHANNEL_MESSAGE:
1442 * Received message to (from, actually) a channel
1444 silc_client_channel_message(client, sock, packet);
1446 case SILC_PACKET_CHANNEL_KEY:
1448 * Received key for a channel. By receiving this key the client will be
1449 * able to talk to the channel it has just joined. This can also be
1450 * a new key for existing channel as keys expire peridiocally.
1452 silc_client_receive_channel_key(client, sock, buffer);
1455 case SILC_PACKET_PRIVATE_MESSAGE:
1457 * Received private message
1460 SilcClientCommandReplyContext ctx;
1461 ctx = silc_calloc(1, sizeof(*ctx));
1462 ctx->client = client;
1464 ctx->context = buffer; /* kludge */
1465 silc_client_command_reply_msg((void *)ctx);
1468 case SILC_PACKET_PRIVATE_MESSAGE_KEY:
1470 * Received private message key
1474 case SILC_PACKET_COMMAND_REPLY:
1476 * Recived reply for a command
1478 silc_client_command_reply_process(client, sock, packet);
1481 case SILC_PACKET_KEY_EXCHANGE:
1482 if (sock->protocol) {
1483 SilcClientKEInternalContext *proto_ctx =
1484 (SilcClientKEInternalContext *)sock->protocol->context;
1486 proto_ctx->packet = buffer;
1487 proto_ctx->dest_id_type = packet->src_id_type;
1488 proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_type);
1490 /* Let the protocol handle the packet */
1491 sock->protocol->execute(client->timeout_queue, 0,
1492 sock->protocol, sock->sock, 0, 0);
1494 SILC_LOG_ERROR(("Received Key Exchange packet but no key exchange "
1495 "protocol active, packet dropped."));
1497 /* XXX Trigger KE protocol?? Rekey actually! */
1501 case SILC_PACKET_KEY_EXCHANGE_1:
1502 if (sock->protocol) {
1505 SILC_LOG_ERROR(("Received Key Exchange 1 packet but no key exchange "
1506 "protocol active, packet dropped."));
1509 case SILC_PACKET_KEY_EXCHANGE_2:
1510 if (sock->protocol) {
1511 SilcClientKEInternalContext *proto_ctx =
1512 (SilcClientKEInternalContext *)sock->protocol->context;
1514 if (proto_ctx->packet)
1515 silc_buffer_free(proto_ctx->packet);
1517 proto_ctx->packet = buffer;
1518 proto_ctx->dest_id_type = packet->src_id_type;
1519 proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_type);
1521 /* Let the protocol handle the packet */
1522 sock->protocol->execute(client->timeout_queue, 0,
1523 sock->protocol, sock->sock, 0, 0);
1525 SILC_LOG_ERROR(("Received Key Exchange 2 packet but no key exchange "
1526 "protocol active, packet dropped."));
1530 case SILC_PACKET_NEW_ID:
1533 * Received new ID from server. This packet is received at
1534 * the connection to the server. New ID is also received when
1535 * user changes nickname but in that case the new ID is received
1536 * as command reply and not as this packet type.
1538 unsigned char *id_string;
1539 unsigned short id_type;
1541 silc_buffer_unformat(buffer,
1542 SILC_STR_UI_SHORT(&id_type),
1543 SILC_STR_UI16_STRING_ALLOC(&id_string),
1546 if ((SilcIdType)id_type != SILC_ID_CLIENT)
1549 silc_client_receive_new_id(client, sock, id_string);
1550 silc_free(id_string);
1555 SILC_LOG_DEBUG(("Incorrect packet type %d, packet dropped", type));
1560 /* Internal routine that sends packet or marks packet to be sent. This
1561 is used directly only in special cases. Normal cases should use
1562 silc_server_packet_send. Returns < 0 on error. */
1564 static int silc_client_packet_send_real(SilcClient client,
1565 SilcSocketConnection sock,
1568 /* Send now if forced to do so */
1569 if (force_send == TRUE) {
1571 SILC_LOG_DEBUG(("Forcing packet send, packet sent immediately"));
1572 ret = silc_packet_write(sock->sock, sock->outbuf);
1575 SILC_LOG_ERROR(("Packet dropped"));
1579 SILC_LOG_DEBUG(("Could not force the send, packet put to queue"));
1582 SILC_LOG_DEBUG(("Packet in queue"));
1584 /* Mark that there is some outgoing data available for this connection.
1585 This call sets the connection both for input and output (the input
1586 is set always and this call keeps the input setting, actually).
1587 Actual data sending is performed by silc_client_packet_process. */
1588 SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(sock->sock);
1590 /* Mark to socket that data is pending in outgoing buffer. This flag
1591 is needed if new data is added to the buffer before the earlier
1592 put data is sent to the network. */
1593 SILC_SET_OUTBUF_PENDING(sock);
1598 /* Prepare outgoing data buffer for packet sending. */
1600 static void silc_client_packet_send_prepare(SilcClient client,
1601 SilcSocketConnection sock,
1602 unsigned int header_len,
1603 unsigned int padlen,
1604 unsigned int data_len)
1608 totlen = header_len + padlen + data_len;
1610 /* Prepare the outgoing buffer for packet sending. */
1611 if (!sock->outbuf) {
1612 /* Allocate new buffer. This is done only once per connection. */
1613 SILC_LOG_DEBUG(("Allocating outgoing data buffer"));
1615 sock->outbuf = silc_buffer_alloc(SILC_PACKET_DEFAULT_SIZE);
1616 silc_buffer_pull_tail(sock->outbuf, totlen);
1617 silc_buffer_pull(sock->outbuf, header_len + padlen);
1619 if (SILC_IS_OUTBUF_PENDING(sock)) {
1620 /* There is some pending data in the buffer. */
1622 if ((sock->outbuf->end - sock->outbuf->tail) < data_len) {
1623 SILC_LOG_DEBUG(("Reallocating outgoing data buffer"));
1624 /* XXX: not done yet */
1626 oldlen = sock->outbuf->len;
1627 silc_buffer_pull_tail(sock->outbuf, totlen);
1628 silc_buffer_pull(sock->outbuf, header_len + padlen + oldlen);
1630 /* Buffer is free for use */
1631 silc_buffer_clear(sock->outbuf);
1632 silc_buffer_pull_tail(sock->outbuf, totlen);
1633 silc_buffer_pull(sock->outbuf, header_len + padlen);
1638 /* Sends packet. This doesn't actually send the packet instead it assembles
1639 it and marks it to be sent. However, if force_send is TRUE the packet
1640 is sent immediately. if dst_id, cipher and hmac are NULL those parameters
1641 will be derived from sock argument. Otherwise the valid arguments sent
1644 void silc_client_packet_send(SilcClient client,
1645 SilcSocketConnection sock,
1646 SilcPacketType type,
1648 SilcIdType dst_id_type,
1651 unsigned char *data,
1652 unsigned int data_len,
1655 SilcPacketContext packetdata;
1656 unsigned char *hmac_key = NULL;
1657 unsigned int hmac_key_len = 0;
1658 unsigned char mac[32];
1659 unsigned int mac_len = 0;
1661 SILC_LOG_DEBUG(("Sending packet, type %d", type));
1663 /* Get data used in the packet sending, keys and stuff */
1664 if ((!cipher || !hmac || !dst_id) && sock->user_data) {
1665 if (!cipher && ((SilcClientWindow)sock->user_data)->send_key)
1666 cipher = ((SilcClientWindow)sock->user_data)->send_key;
1667 if (!hmac && ((SilcClientWindow)sock->user_data)->hmac) {
1668 hmac = ((SilcClientWindow)sock->user_data)->hmac;
1669 mac_len = hmac->hash->hash->hash_len;
1670 hmac_key = ((SilcClientWindow)sock->user_data)->hmac_key;
1671 hmac_key_len = ((SilcClientWindow)sock->user_data)->hmac_key_len;
1673 if (!dst_id && ((SilcClientWindow)sock->user_data)->remote_id) {
1674 dst_id = ((SilcClientWindow)sock->user_data)->remote_id;
1675 dst_id_type = SILC_ID_SERVER;
1679 /* Set the packet context pointers */
1680 packetdata.flags = 0;
1681 packetdata.type = type;
1682 if (((SilcClientWindow)sock->user_data)->local_id_data)
1683 packetdata.src_id = ((SilcClientWindow)sock->user_data)->local_id_data;
1685 packetdata.src_id = silc_calloc(SILC_ID_CLIENT_LEN, sizeof(unsigned char));
1686 packetdata.src_id_len = SILC_ID_CLIENT_LEN;
1687 packetdata.src_id_type = SILC_ID_CLIENT;
1689 packetdata.dst_id = silc_id_id2str(dst_id, dst_id_type);
1690 packetdata.dst_id_len = silc_id_get_len(dst_id_type);
1691 packetdata.dst_id_type = dst_id_type;
1693 packetdata.dst_id = NULL;
1694 packetdata.dst_id_len = 0;
1695 packetdata.dst_id_type = SILC_ID_NONE;
1697 packetdata.rng = client->rng;
1698 packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN +
1699 packetdata.src_id_len + packetdata.dst_id_len;
1700 packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen);
1702 /* Prepare outgoing data buffer for packet sending */
1703 silc_client_packet_send_prepare(client, sock,
1704 SILC_PACKET_HEADER_LEN +
1705 packetdata.src_id_len +
1706 packetdata.dst_id_len,
1710 SILC_LOG_DEBUG(("Putting data to outgoing buffer, len %d", data_len));
1712 packetdata.buffer = sock->outbuf;
1714 /* Put the data to the buffer */
1715 if (data && data_len)
1716 silc_buffer_put(sock->outbuf, data, data_len);
1718 /* Create the outgoing packet */
1719 silc_packet_assemble(&packetdata);
1721 /* Compute MAC of the packet */
1723 silc_hmac_make_with_key(hmac, sock->outbuf->data, sock->outbuf->len,
1724 hmac_key, hmac_key_len, mac);
1725 silc_buffer_put_tail(sock->outbuf, mac, mac_len);
1726 memset(mac, 0, sizeof(mac));
1729 /* Encrypt the packet */
1731 silc_packet_encrypt(cipher, sock->outbuf, sock->outbuf->len);
1733 /* Pull MAC into the visible data area */
1735 silc_buffer_pull_tail(sock->outbuf, mac_len);
1737 SILC_LOG_HEXDUMP(("Packet, len %d", sock->outbuf->len),
1738 sock->outbuf->data, sock->outbuf->len);
1740 /* Now actually send the packet */
1741 silc_client_packet_send_real(client, sock, force_send);
1744 /* Sends packet to a channel. Packet to channel is always encrypted
1745 differently from "normal" packets. SILC header of the packet is
1746 encrypted with the next receiver's key and the rest of the packet is
1747 encrypted with the channel specific key. Padding and HMAC is computed
1748 with the next receiver's key. */
1750 void silc_client_packet_send_to_channel(SilcClient client,
1751 SilcSocketConnection sock,
1752 SilcChannelEntry channel,
1753 unsigned char *data,
1754 unsigned int data_len,
1758 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1760 SilcPacketContext packetdata;
1761 unsigned char *hmac_key = NULL;
1762 unsigned int hmac_key_len = 0;
1763 unsigned char mac[32];
1764 unsigned int mac_len = 0;
1765 unsigned char *id_string;
1769 SILC_LOG_DEBUG(("Sending packet to channel"));
1771 if (!channel || !channel->key) {
1772 silc_say(client, "Cannot talk to channel: key does not exist");
1778 for (i = 0; i < 16; i++)
1779 channel->iv[i] = silc_rng_get_byte(client->rng);
1781 silc_hash_make(client->md5hash, channel->iv, 16, channel->iv);
1783 /* Encode the channel payload */
1784 payload = silc_channel_encode_payload(strlen(win->nickname), win->nickname,
1785 data_len, data, 16, channel->iv,
1789 "Error: Could not create packet to be sent to the channel");
1793 /* Get data used in packet header encryption, keys and stuff. Rest
1794 of the packet (the payload) is, however, encrypted with the
1795 specified channel key. */
1796 cipher = win->send_key;
1798 mac_len = hmac->hash->hash->hash_len;
1799 hmac_key = win->hmac_key;
1800 hmac_key_len = win->hmac_key_len;
1801 id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
1803 /* Set the packet context pointers. The destination ID is always
1804 the Channel ID of the channel. Server and router will handle the
1805 distribution of the packet. */
1806 packetdata.flags = 0;
1807 packetdata.type = SILC_PACKET_CHANNEL_MESSAGE;
1808 packetdata.src_id = win->local_id_data;
1809 packetdata.src_id_len = SILC_ID_CLIENT_LEN;
1810 packetdata.src_id_type = SILC_ID_CLIENT;
1811 packetdata.dst_id = id_string;
1812 packetdata.dst_id_len = SILC_ID_CHANNEL_LEN;
1813 packetdata.dst_id_type = SILC_ID_CHANNEL;
1814 packetdata.rng = client->rng;
1815 packetdata.truelen = payload->len + SILC_PACKET_HEADER_LEN +
1816 packetdata.src_id_len + packetdata.dst_id_len;
1817 packetdata.padlen = SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
1818 packetdata.src_id_len +
1819 packetdata.dst_id_len));
1821 /* Prepare outgoing data buffer for packet sending */
1822 silc_client_packet_send_prepare(client, sock,
1823 SILC_PACKET_HEADER_LEN +
1824 packetdata.src_id_len +
1825 packetdata.dst_id_len,
1829 packetdata.buffer = sock->outbuf;
1831 /* Encrypt payload of the packet. This is encrypted with the channel key. */
1832 channel->channel_key->cipher->encrypt(channel->channel_key->context,
1833 payload->data, payload->data,
1834 payload->len - 16, /* -IV_LEN */
1837 SILC_LOG_HEXDUMP(("XXX"), payload->data, payload->len);
1839 /* Put the actual encrypted payload data into the buffer. */
1840 silc_buffer_put(sock->outbuf, payload->data, payload->len);
1842 /* Create the outgoing packet */
1843 silc_packet_assemble(&packetdata);
1845 /* Compute MAC of the packet */
1846 silc_hmac_make_with_key(hmac, sock->outbuf->data, sock->outbuf->len,
1847 hmac_key, hmac_key_len, mac);
1848 silc_buffer_put_tail(sock->outbuf, mac, mac_len);
1849 memset(mac, 0, sizeof(mac));
1851 SILC_LOG_HEXDUMP(("XXX"), sock->outbuf->data, sock->outbuf->len);
1853 /* Encrypt the header and padding of the packet. This is encrypted
1854 with normal session key shared with our server. */
1855 silc_packet_encrypt(cipher, sock->outbuf, SILC_PACKET_HEADER_LEN +
1856 packetdata.src_id_len + packetdata.dst_id_len +
1859 /* Pull MAC into the visible data area */
1860 silc_buffer_pull_tail(sock->outbuf, mac_len);
1862 SILC_LOG_HEXDUMP(("Packet to channel, len %d", sock->outbuf->len),
1863 sock->outbuf->data, sock->outbuf->len);
1865 /* Now actually send the packet */
1866 silc_client_packet_send_real(client, sock, force_send);
1867 silc_buffer_free(payload);
1868 silc_free(id_string);
1871 /* Sends private message to remote client. If private message key has
1872 not been set with this client then the message will be encrypted using
1873 normal session keys. Private messages are special packets in SILC
1874 network hence we need this own function for them. This is similiar
1875 to silc_client_packet_send_to_channel except that we send private
1878 void silc_client_packet_send_private_message(SilcClient client,
1879 SilcSocketConnection sock,
1880 SilcClientEntry client_entry,
1881 unsigned char *data,
1882 unsigned int data_len,
1885 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1887 SilcPacketContext packetdata;
1888 unsigned char *hmac_key = NULL;
1889 unsigned int hmac_key_len = 0;
1890 unsigned char mac[32];
1891 unsigned int mac_len = 0;
1892 unsigned int nick_len;
1896 SILC_LOG_DEBUG(("Sending private message"));
1898 /* Create private message payload */
1899 nick_len = strlen(client->current_win->nickname);
1900 buffer = silc_buffer_alloc(2 + nick_len + data_len);
1901 silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer));
1902 silc_buffer_format(buffer,
1903 SILC_STR_UI_SHORT(nick_len),
1904 SILC_STR_UI_XNSTRING(client->current_win->nickname,
1906 SILC_STR_UI_XNSTRING(data, data_len),
1909 /* If we don't have private message specific key then private messages
1910 are just as any normal packet thus call normal packet sending. If
1911 the key exist then the encryption process is a bit different and
1912 will be done in the rest of this function. */
1913 if (!client_entry->send_key) {
1914 silc_client_packet_send(client, sock, SILC_PACKET_PRIVATE_MESSAGE,
1915 client_entry->id, SILC_ID_CLIENT, NULL, NULL,
1916 buffer->data, buffer->len, force_send);
1920 /* We have private message specific key */
1922 /* Get data used in the encryption */
1923 cipher = client_entry->send_key;
1925 mac_len = hmac->hash->hash->hash_len;
1926 hmac_key = win->hmac_key;
1927 hmac_key_len = win->hmac_key_len;
1929 /* Set the packet context pointers. */
1930 packetdata.flags = 0;
1931 packetdata.type = SILC_PACKET_PRIVATE_MESSAGE;
1932 packetdata.src_id = win->local_id_data;
1933 packetdata.src_id_len = SILC_ID_CLIENT_LEN;
1934 packetdata.src_id_type = SILC_ID_CLIENT;
1936 packetdata.dst_id = silc_id_id2str(client_entry->id, SILC_ID_CLIENT);
1938 packetdata.dst_id = win->local_id_data;
1939 packetdata.dst_id_len = SILC_ID_CLIENT_LEN;
1940 packetdata.dst_id_type = SILC_ID_CLIENT;
1941 packetdata.rng = client->rng;
1942 packetdata.truelen = buffer->len + SILC_PACKET_HEADER_LEN +
1943 packetdata.src_id_len + packetdata.dst_id_len;
1944 packetdata.padlen = SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
1945 packetdata.src_id_len +
1946 packetdata.dst_id_len));
1948 /* Prepare outgoing data buffer for packet sending */
1949 silc_client_packet_send_prepare(client, sock,
1950 SILC_PACKET_HEADER_LEN +
1951 packetdata.src_id_len +
1952 packetdata.dst_id_len,
1956 packetdata.buffer = sock->outbuf;
1958 /* Encrypt payload of the packet. Encrypt with private message specific
1959 key if it exist, otherwise with session key. */
1960 cipher->cipher->encrypt(cipher->context, buffer->data, buffer->data,
1961 buffer->len, cipher->iv);
1963 /* Put the actual encrypted payload data into the buffer. */
1964 silc_buffer_put(sock->outbuf, buffer->data, buffer->len);
1966 /* Create the outgoing packet */
1967 silc_packet_assemble(&packetdata);
1969 /* Compute MAC of the packet */
1970 silc_hmac_make_with_key(hmac, sock->outbuf->data, sock->outbuf->len,
1971 hmac_key, hmac_key_len, mac);
1972 silc_buffer_put_tail(sock->outbuf, mac, mac_len);
1973 memset(mac, 0, sizeof(mac));
1975 SILC_LOG_HEXDUMP(("XXX"), sock->outbuf->data, sock->outbuf->len);
1977 /* Encrypt the header and padding of the packet. */
1978 silc_packet_encrypt(cipher, sock->outbuf, SILC_PACKET_HEADER_LEN +
1979 packetdata.src_id_len + packetdata.dst_id_len +
1982 /* Pull MAC into the visible data area */
1983 silc_buffer_pull_tail(sock->outbuf, mac_len);
1985 SILC_LOG_HEXDUMP(("Private message packet, len %d", sock->outbuf->len),
1986 sock->outbuf->data, sock->outbuf->len);
1988 /* Now actually send the packet */
1989 silc_client_packet_send_real(client, sock, force_send);
1990 silc_free(packetdata.dst_id);
1996 /* Closes connection to remote end. Free's all allocated data except
1997 for some information such as nickname etc. that are valid at all time. */
1999 void silc_client_close_connection(SilcClient client,
2000 SilcSocketConnection sock)
2002 SilcClientWindow win;
2005 /* We won't listen for this connection anymore */
2006 silc_schedule_unset_listen_fd(sock->sock);
2008 /* Unregister all tasks */
2009 silc_task_unregister_by_fd(client->io_queue, sock->sock);
2010 silc_task_unregister_by_fd(client->timeout_queue, sock->sock);
2012 /* Close the actual connection */
2013 silc_net_close_connection(sock->sock);
2015 silc_say(client, "Closed connection to host %s", sock->hostname ?
2016 sock->hostname : sock->ip);
2018 /* Free everything */
2019 if (sock->user_data) {
2020 win = (SilcClientWindow)sock->user_data;
2022 /* XXX Free all client entries and channel entries. */
2024 /* Clear ID caches */
2025 for (i = 0; i < 96; i++)
2026 silc_idcache_del_all(&win->client_id_cache[i],
2027 win->client_id_cache_count[i]);
2028 for (i = 0; i < 96; i++)
2029 silc_idcache_del_all(&win->channel_id_cache[i],
2030 win->channel_id_cache_count[i]);
2033 if (win->remote_host)
2034 silc_free(win->remote_host);
2036 silc_free(win->local_id);
2037 if (win->local_id_data)
2038 silc_free(win->local_id_data);
2040 silc_cipher_free(win->send_key);
2041 if (win->receive_key)
2042 silc_cipher_free(win->receive_key);
2044 silc_hmac_free(win->hmac);
2045 if (win->hmac_key) {
2046 memset(win->hmac_key, 0, win->hmac_key_len);
2047 silc_free(win->hmac_key);
2051 win->remote_port = 0;
2052 win->remote_type = 0;
2053 win->send_key = NULL;
2054 win->receive_key = NULL;
2056 win->hmac_key = NULL;
2057 win->hmac_key_len = 0;
2058 win->local_id = NULL;
2059 win->local_id_data = NULL;
2060 win->remote_host = NULL;
2061 win->current_channel = NULL;
2064 if (sock->protocol) {
2065 silc_protocol_free(sock->protocol);
2066 sock->protocol = NULL;
2068 silc_socket_free(sock);
2071 /* Called when we receive disconnection packet from server. This
2072 closes our end properly and displays the reason of the disconnection
2075 void silc_client_disconnected_by_server(SilcClient client,
2076 SilcSocketConnection sock,
2081 SILC_LOG_DEBUG(("Server disconnected us, sock %d", sock->sock));
2083 msg = silc_calloc(message->len + 1, sizeof(char));
2084 memcpy(msg, message->data, message->len);
2085 silc_say(client, msg);
2088 SILC_SET_DISCONNECTED(sock);
2089 silc_client_close_connection(client, sock);
2092 /* Received error message from server. Display it on the screen.
2093 We don't take any action what so ever of the error message. */
2095 void silc_client_error_by_server(SilcClient client,
2096 SilcSocketConnection sock,
2101 msg = silc_calloc(message->len + 1, sizeof(char));
2102 memcpy(msg, message->data, message->len);
2103 silc_say(client, msg);
2107 /* Received notify message from server */
2109 void silc_client_notify_by_server(SilcClient client,
2110 SilcSocketConnection sock,
2115 msg = silc_calloc(message->len + 1, sizeof(char));
2116 memcpy(msg, message->data, message->len);
2117 silc_say(client, msg);
2121 /* Processes the received new Client ID from server. Old Client ID is
2122 deleted from cache and new one is added. */
2124 void silc_client_receive_new_id(SilcClient client,
2125 SilcSocketConnection sock,
2126 unsigned char *id_string)
2128 SilcClientWindow win = (SilcClientWindow)sock->user_data;
2129 char *nickname = win->nickname;
2131 #define CIDC(x) win->client_id_cache[(x) - 32]
2132 #define CIDCC(x) win->client_id_cache_count[(x) - 32]
2134 /* Delete old ID from ID cache */
2135 silc_idcache_del_by_id(CIDC(nickname[0]), CIDCC(nickname[0]),
2136 SILC_ID_CLIENT, win->local_id);
2138 /* Save the new ID */
2140 silc_free(win->local_id);
2141 win->local_id = silc_id_str2id(id_string, SILC_ID_CLIENT);
2142 if (win->local_id_data)
2143 silc_free(win->local_id_data);
2144 win->local_id_data =
2145 silc_calloc(SILC_ID_CLIENT_LEN, sizeof(unsigned char));
2146 memcpy(win->local_id_data, id_string, SILC_ID_CLIENT_LEN);
2147 win->local_id_data_len = SILC_ID_CLIENT_LEN;
2148 if (!win->local_entry)
2149 win->local_entry = silc_calloc(1, sizeof(*win->local_entry));
2150 win->local_entry->nickname = win->nickname;
2151 win->local_entry->id = win->local_id;
2153 /* Put it to the ID cache */
2154 CIDCC(nickname[0]) = silc_idcache_add(&CIDC(nickname[0]),
2156 win->nickname, SILC_ID_CLIENT,
2158 (void *)win->local_entry);
2163 /* Processed received Channel ID for a channel. This is called when client
2164 joins to channel and server replies with channel ID. The ID is cached. */
2166 void silc_client_new_channel_id(SilcClient client,
2167 SilcSocketConnection sock,
2170 unsigned char *id_string)
2172 SilcClientWindow win = (SilcClientWindow)sock->user_data;
2174 SilcChannelEntry channel;
2176 SILC_LOG_DEBUG(("New channel ID"));
2178 #define CIDC(x) win->channel_id_cache[(x) - 32]
2179 #define CIDCC(x) win->channel_id_cache_count[(x) - 32]
2181 id = silc_id_str2id(id_string, SILC_ID_CHANNEL);
2182 channel = silc_calloc(1, sizeof(*channel));
2183 channel->channel_name = channel_name;
2185 channel->mode = mode;
2186 win->current_channel = channel;
2188 /* Put it to the ID cache */
2189 CIDCC(channel_name[0]) = silc_idcache_add(&CIDC(channel_name[0]),
2190 CIDCC(channel_name[0]),
2191 channel_name, SILC_ID_CHANNEL,
2192 id, (void *)channel);
2197 /* Processes received key for channel. The received key will be used
2198 to protect the traffic on the channel for now on. Client must receive
2199 the key to the channel before talking on the channel is possible.
2200 This is the key that server has generated, this is not the channel
2201 private key, it is entirely local setting. */
2203 void silc_client_receive_channel_key(SilcClient client,
2204 SilcSocketConnection sock,
2208 unsigned char *id_string, *key, *cipher;
2209 unsigned int key_len;
2210 SilcClientWindow win = (SilcClientWindow)sock->user_data;
2212 SilcIDCache *id_cache = NULL;
2213 SilcChannelEntry channel;
2214 SilcChannelKeyPayload payload;
2216 SILC_LOG_DEBUG(("Received key for channel"));
2218 #define CIDC(x) win->channel_id_cache[(x)]
2219 #define CIDCC(x) win->channel_id_cache_count[(x)]
2221 payload = silc_channel_key_parse_payload(packet);
2225 id_string = silc_channel_key_get_id(payload, NULL);
2227 silc_channel_key_free_payload(payload);
2230 id = silc_id_str2id(id_string, SILC_ID_CHANNEL);
2232 /* Find channel. XXX: This is bad and slow. */
2233 for (i = 0; i < 96; i++) {
2234 if (CIDC(i) == NULL)
2236 if (silc_idcache_find_by_id(CIDC(i), CIDCC(i), (void *)id,
2237 SILC_ID_CHANNEL, &id_cache))
2245 key = silc_channel_key_get_key(payload, &key_len);
2246 cipher = silc_channel_key_get_cipher(payload, NULL);
2248 channel = (SilcChannelEntry)id_cache->context;
2249 channel->key_len = key_len;
2250 channel->key = silc_calloc(key_len, sizeof(*channel->key));
2251 memcpy(channel->key, key, key_len);
2253 silc_cipher_alloc(cipher, &channel->channel_key);
2254 if (!channel->channel_key) {
2255 silc_say(client, "Cannot talk to channel: unsupported cipher %s", cipher);
2258 channel->channel_key->cipher->set_key(channel->channel_key->context,
2261 /* Client is now joined to the channel */
2262 channel->on_channel = TRUE;
2266 silc_channel_key_free_payload(payload);
2271 /* Process received message to a channel (or from a channel, really). This
2272 decrypts the channel message with channel specific key and parses the
2273 channel payload. Finally it displays the message on the screen. */
2275 void silc_client_channel_message(SilcClient client,
2276 SilcSocketConnection sock,
2277 SilcPacketContext *packet)
2280 SilcClientWindow win = (SilcClientWindow)sock->user_data;
2281 SilcBuffer buffer = packet->buffer;
2282 SilcChannelPayload payload = NULL;
2283 SilcChannelID *id = NULL;
2284 SilcChannelEntry channel;
2285 SilcIDCache *id_cache = NULL;
2287 #define CIDC(x) win->channel_id_cache[(x)]
2288 #define CIDCC(x) win->channel_id_cache_count[(x)]
2291 if (packet->dst_id_type != SILC_ID_CHANNEL)
2294 id = silc_id_str2id(packet->dst_id, SILC_ID_CHANNEL);
2296 /* Find the channel entry from channels on this window */
2297 for (i = 0; i < 96; i++) {
2298 if (CIDC(i) == NULL)
2300 if (silc_idcache_find_by_id(CIDC(i), CIDCC(i), (void *)id,
2301 SILC_ID_CHANNEL, &id_cache))
2308 channel = (SilcChannelEntry)id_cache->context;
2310 /* Decrypt the channel message payload. Push the IV out of the way,
2311 since it is not encrypted (after pushing buffer->tail has the IV). */
2312 silc_buffer_push_tail(buffer, 16);
2313 channel->channel_key->cipher->decrypt(channel->channel_key->context,
2314 buffer->data, buffer->data,
2315 buffer->len, buffer->tail);
2316 silc_buffer_pull_tail(buffer, 16);
2318 /* Parse the channel message payload */
2319 payload = silc_channel_parse_payload(buffer);
2323 /* Display the message on screen */
2324 if (packet->src_id_type == SILC_ID_CLIENT) {
2325 /* Message from client */
2326 if (channel == win->current_channel)
2327 silc_print(client, "<%s> %s",
2328 silc_channel_get_nickname(payload, NULL),
2329 silc_channel_get_data(payload, NULL));
2331 silc_print(client, "<%s:%s> %s",
2332 silc_channel_get_nickname(payload, NULL),
2333 channel->channel_name,
2334 silc_channel_get_data(payload, NULL));
2336 /* Message from server */
2337 silc_say(client, "%s", silc_channel_get_data(payload, NULL));
2344 silc_channel_free_payload(payload);