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.7 2000/07/10 05:40:33 priikone
26 * Revision 1.6 2000/07/07 06:54:16 priikone
27 * Print channel name when receiving channel message to non-current
30 * Revision 1.5 2000/07/06 07:14:36 priikone
31 * Fixes to NAMES command handling.
32 * Fixes when leaving from channel.
34 * Revision 1.4 2000/07/05 06:12:05 priikone
35 * Global cosmetic changes.
37 * Revision 1.3 2000/07/04 08:29:12 priikone
38 * Added support for PING command. The ping times are calculated
39 * and showed to the user.
41 * Revision 1.2 2000/07/03 05:49:48 priikone
42 * Implemented LEAVE command. Minor bug fixes.
44 * Revision 1.1.1.1 2000/06/27 11:36:56 priikone
45 * Imported from internal CVS/Added Log headers.
50 #include "clientincludes.h"
52 /* Static function prototypes */
53 static int silc_client_bad_keys(unsigned char key);
54 static void silc_client_process_message(SilcClient client);
55 static char *silc_client_parse_command(unsigned char *buffer);
57 /* Static task callback prototypes */
58 SILC_TASK_CALLBACK(silc_client_update_clock);
59 SILC_TASK_CALLBACK(silc_client_run_commands);
60 SILC_TASK_CALLBACK(silc_client_process_key_press);
61 SILC_TASK_CALLBACK(silc_client_connect_to_server_start);
62 SILC_TASK_CALLBACK(silc_client_connect_to_server_second);
63 SILC_TASK_CALLBACK(silc_client_connect_to_server_final);
64 SILC_TASK_CALLBACK(silc_client_packet_process);
65 SILC_TASK_CALLBACK(silc_client_packet_parse);
67 SilcClientWindow silc_client_create_main_window(SilcClient client);
68 SilcClientWindow silc_client_add_window(SilcClient client,
70 void silc_client_packet_parse_type(SilcClient client,
71 SilcSocketConnection sock,
72 SilcPacketContext *packet);
73 void silc_client_private_message_process(SilcClient client,
74 SilcSocketConnection sock,
75 SilcPacketContext *packet);
77 /* Definitions from version.h */
78 extern char *silc_version;
79 extern char *silc_name;
80 extern char *silc_fullname;
82 /* Allocates new client object. This has to be done before client may
83 work. After calling this one must call silc_client_init to initialize
86 int silc_client_alloc(SilcClient *new_client)
89 *new_client = silc_calloc(1, sizeof(**new_client));
90 (*new_client)->input_buffer = NULL;
91 (*new_client)->screen = NULL;
92 (*new_client)->windows = NULL;
93 (*new_client)->windows_count = 0;
94 (*new_client)->current_win = NULL;
99 /* Free's client object */
101 void silc_client_free(SilcClient client)
108 /* Initializes the client. This makes all the necessary steps to make
109 the client ready to be run. One must call silc_client_run to run the
112 int silc_client_init(SilcClient client)
115 SILC_LOG_DEBUG(("Initializing client"));
118 client->username = silc_get_username();
119 client->realname = silc_get_real_name();
121 /* Register all configured ciphers, PKCS and hash functions. */
122 client->config->client = (void *)client;
123 silc_client_config_register_ciphers(client->config);
124 silc_client_config_register_pkcs(client->config);
125 silc_client_config_register_hashfuncs(client->config);
127 /* Initialize hash functions for client to use */
128 silc_hash_alloc("md5", &client->md5hash);
129 silc_hash_alloc("sha1", &client->sha1hash);
131 /* Initialize none cipher */
132 silc_cipher_alloc("none", &client->none_cipher);
134 /* Initialize random number generator */
135 client->rng = silc_rng_alloc();
136 silc_rng_init(client->rng);
137 silc_math_primegen_init(); /* XXX */
139 /* Load public and private key */
140 if (silc_client_load_keys(client) == FALSE)
143 /* Register the task queues. In SILC we have by default three task queues.
144 One task queue for non-timeout tasks which perform different kind of
145 I/O on file descriptors, timeout task queue for timeout tasks, and,
146 generic non-timeout task queue whose tasks apply to all connections. */
147 silc_task_queue_alloc(&client->io_queue, TRUE);
148 if (!client->io_queue) {
151 silc_task_queue_alloc(&client->timeout_queue, TRUE);
152 if (!client->timeout_queue) {
155 silc_task_queue_alloc(&client->generic_queue, TRUE);
156 if (!client->generic_queue) {
160 /* Initialize the scheduler */
161 silc_schedule_init(client->io_queue, client->timeout_queue,
162 client->generic_queue, 5000);
164 /* Register the main task that is used in client. This received
165 the key pressings. */
166 if (silc_task_register(client->io_queue, fileno(stdin),
167 silc_client_process_key_press,
168 (void *)client, 0, 0,
170 SILC_TASK_PRI_NORMAL) == NULL) {
174 /* Register timeout task that updates clock every minute. */
175 if (silc_task_register(client->timeout_queue, 0,
176 silc_client_update_clock,
178 silc_client_time_til_next_min(), 0,
180 SILC_TASK_PRI_LOW) == NULL) {
184 if (client->config->commands) {
185 /* Run user configured commands with timeout */
186 if (silc_task_register(client->timeout_queue, 0,
187 silc_client_run_commands,
188 (void *)client, 0, 1,
190 SILC_TASK_PRI_LOW) == NULL) {
195 /* Allocate the input buffer used to save typed characters */
196 client->input_buffer = silc_buffer_alloc(SILC_SCREEN_INPUT_WIN_SIZE);
197 silc_buffer_pull_tail(client->input_buffer,
198 SILC_BUFFER_END(client->input_buffer));
200 /* Initialize the screen */
201 client->screen = silc_screen_init();
202 silc_client_create_main_window(client);
203 client->screen->input_buffer = client->input_buffer->data;
204 silc_screen_print_coordinates(client->screen, 0);
209 silc_task_queue_free(client->timeout_queue);
211 silc_task_queue_free(client->io_queue);
216 /* Stops the client. This is called to stop the client and thus to stop
219 void silc_client_stop(SilcClient client)
221 SILC_LOG_DEBUG(("Stopping client"));
223 /* Stop the scheduler, although it might be already stopped. This
224 doesn't hurt anyone. This removes all the tasks and task queues,
226 silc_schedule_stop();
227 silc_schedule_uninit();
229 SILC_LOG_DEBUG(("Client client"));
232 /* Runs the client. */
234 void silc_client_run(SilcClient client)
236 SILC_LOG_DEBUG(("Running client"));
238 /* Start the scheduler, the heart of the SILC client. When this returns
239 the program will be terminated. */
243 /* Creates the main window used in SILC client. This is called always
244 at the initialization of the client. If user wants to create more
245 than one windows a new windows are always created by calling
246 silc_client_add_window. */
248 SilcClientWindow silc_client_create_main_window(SilcClient client)
250 SilcClientWindow win;
253 SILC_LOG_DEBUG(("Creating main window"));
255 assert(client->screen != NULL);
257 client->screen->u_stat_line.program_name = silc_name;
258 client->screen->u_stat_line.program_version = silc_version;
261 win = silc_calloc(1, sizeof(*win));
262 win->nickname = silc_get_username();
263 win->local_id = NULL;
264 win->local_id_data = NULL;
265 win->local_id_data_len = 0;
266 win->remote_host = NULL;
267 win->remote_port = -1;
270 /* Create the actual screen */
271 screen = (void *)silc_screen_create_output_window(client->screen);
272 silc_screen_create_input_window(client->screen);
273 silc_screen_init_upper_status_line(client->screen);
274 silc_screen_init_output_status_line(client->screen);
275 win->screen = screen;
277 client->screen->bottom_line->nickname = win->nickname;
278 silc_screen_print_bottom_line(client->screen, 0);
280 /* Add the window to windows table */
281 client->windows = silc_calloc(1, sizeof(*client->windows));
282 client->windows[client->windows_count] = win;
283 client->windows_count = 1;
285 /* Automatically becomes the current active window */
286 client->current_win = win;
291 /* Allocates and adds new window to the client. This allocates new
292 physical window and internal window for connection specific data.
293 All the connection specific data is always saved into a window
294 since connection is always associated to a active window. */
296 SilcClientWindow silc_client_add_window(SilcClient client,
299 SilcClientWindow win;
301 assert(client->screen != NULL);
303 win = silc_calloc(1, sizeof(*win));
305 /* Add the pointers */
306 win->screen = silc_screen_add_output_window(client->screen);
309 /* Add the window to windows table */
310 client->windows = silc_realloc(client->windows, sizeof(*client->windows)
311 * (client->windows_count + 1));
312 client->windows[client->windows_count] = win;
313 client->windows_count++;
315 if (is_current == TRUE)
316 client->current_win = win;
321 /* The main task on SILC client. This processes the key pressings user
324 SILC_TASK_CALLBACK(silc_client_process_key_press)
326 SilcClient client = (SilcClient)context;
329 /* There is data pending in stdin, this gets it directly */
330 c = wgetch(client->screen->input_win);
331 if (silc_client_bad_keys(c))
334 SILC_LOG_DEBUG(("Pressed key: %d", c));
338 * Special character handling
345 SILC_LOG_DEBUG(("RIGHT"));
346 silc_screen_input_cursor_right(client->screen);
350 SILC_LOG_DEBUG(("LEFT"));
351 silc_screen_input_cursor_left(client->screen);
358 silc_screen_input_backspace(client->screen);
364 /* Insert switch. Turns on/off insert on input window */
365 silc_screen_input_insert(client->screen);
369 /* Enter, Return. User pressed enter we are ready to
370 process the message. */
371 silc_client_process_message(client);
372 silc_screen_input_reset(client->screen);
375 /* Refresh screen, Ctrl^l */
376 silc_screen_refresh_all(client->screen);
381 /* Beginning, Home */
382 silc_screen_input_cursor_home(client->screen);
387 silc_screen_input_cursor_end(client->screen);
405 /* Control codes are printed as reversed */
407 wattron(client->screen->input_win, A_REVERSE);
408 silc_screen_input_print(client->screen, c);
409 wattroff(client->screen->input_win, A_REVERSE);
411 /* Normal character */
412 silc_screen_input_print(client->screen, c);
416 silc_screen_print_coordinates(client->screen, 0);
417 silc_screen_refresh_win(client->screen->input_win);
420 static int silc_client_bad_keys(unsigned char key)
422 /* these are explained in curses.h */
437 case '\E': /* we ignore ESC */
444 /* Processes messages user has typed on the screen. This either sends
445 a packet out to network or if command were written executes it. */
447 static void silc_client_process_message(SilcClient client)
452 SILC_LOG_DEBUG(("Start"));
454 data = client->input_buffer->data;
457 if (data[0] == '/' && data[1] != ' ') {
459 unsigned int argc = 0;
460 unsigned char **argv, *tmpcmd;
461 unsigned int *argv_lens, *argv_types;
462 SilcClientCommand *cmd;
463 SilcClientCommandContext ctx;
465 /* Get the command */
466 tmpcmd = silc_client_parse_command(data);
468 /* Find command match */
469 for (cmd = silc_command_list; cmd->name; cmd++) {
470 if (!strcmp(cmd->name, tmpcmd))
474 if (cmd->name == NULL) {
475 silc_say(client, "Invalid command: %s", tmpcmd);
480 /* Now parse all arguments */
481 silc_client_parse_command_line(data, &argv, &argv_lens,
482 &argv_types, &argc, cmd->max_args);
485 SILC_LOG_DEBUG(("Exeuting command: %s", cmd->name));
487 /* Allocate command context. This and its internals must be free'd
488 by the command routine receiving it. */
489 ctx = silc_calloc(1, sizeof(*ctx));
490 ctx->client = client;
491 ctx->sock = client->current_win->sock;
494 ctx->argv_lens = argv_lens;
495 ctx->argv_types = argv_types;
497 /* Execute command */
501 /* Normal message to a channel */
502 if (len && client->current_win->current_channel &&
503 client->current_win->current_channel->on_channel == TRUE) {
504 silc_print(client, "> %s", data);
505 silc_client_packet_send_to_channel(client,
506 client->current_win->sock,
507 client->current_win->current_channel,
508 data, strlen(data), TRUE);
513 /* Clear the input buffer */
514 silc_buffer_clear(client->input_buffer);
515 silc_buffer_pull_tail(client->input_buffer,
516 SILC_BUFFER_END(client->input_buffer));
519 /* Returns the command fetched from user typed command line */
521 static char *silc_client_parse_command(unsigned char *buffer)
524 const char *cp = buffer;
527 len = strcspn(cp, " ");
528 ret = silc_to_upper((char *)++cp);
534 /* Parses user typed command line. At most `max_args' is taken. Rest
535 of the line will be allocated as the last argument if there are more
536 than `max_args' arguments in the line. Note that the command name
537 is counted as one argument and is saved. */
539 void silc_client_parse_command_line(unsigned char *buffer,
540 unsigned char ***parsed,
541 unsigned int **parsed_lens,
542 unsigned int **parsed_types,
543 unsigned int *parsed_num,
544 unsigned int max_args)
548 const char *cp = buffer;
550 /* Take the '/' away */
553 *parsed = silc_calloc(1, sizeof(**parsed));
554 *parsed_lens = silc_calloc(1, sizeof(**parsed_lens));
556 /* Get the command first */
557 len = strcspn(cp, " ");
558 (*parsed)[0] = silc_to_upper((char *)cp);
559 (*parsed_lens)[0] = len;
563 /* Parse arguments */
564 if (strchr(cp, ' ') || strlen(cp) != 0) {
565 for (i = 1; i < max_args; i++) {
567 if (i != max_args - 1)
568 len = strcspn(cp, " ");
572 *parsed = silc_realloc(*parsed, sizeof(**parsed) * (argc + 1));
573 *parsed_lens = silc_realloc(*parsed_lens,
574 sizeof(**parsed_lens) * (argc + 1));
575 (*parsed)[argc] = silc_calloc(len + 1, sizeof(char));
576 memcpy((*parsed)[argc], cp, len);
577 (*parsed_lens)[argc] = len;
588 /* Save argument types. Protocol defines all argument types but
589 this implementation makes sure that they are always in correct
590 order hence this simple code. */
591 *parsed_types = silc_calloc(argc, sizeof(**parsed_types));
592 for (i = 0; i < argc; i++)
593 (*parsed_types)[i] = i;
598 /* Updates clock on the screen every minute. */
600 SILC_TASK_CALLBACK(silc_client_update_clock)
602 SilcClient client = (SilcClient)context;
604 /* Update the clock on the screen */
605 silc_screen_print_clock(client->screen);
607 /* Re-register this same task */
608 silc_task_register(qptr, 0, silc_client_update_clock, context,
609 silc_client_time_til_next_min(), 0,
613 silc_screen_refresh_win(client->screen->input_win);
616 /* Runs commands user configured in configuration file. This is
617 called when initializing client. */
619 SILC_TASK_CALLBACK(silc_client_run_commands)
621 SilcClient client = (SilcClient)context;
622 SilcClientConfigSectionCommand *cs;
624 SILC_LOG_DEBUG(("Start"));
626 cs = client->config->commands;
628 unsigned int argc = 0;
629 unsigned char **argv, *tmpcmd;
630 unsigned int *argv_lens, *argv_types;
631 SilcClientCommand *cmd;
632 SilcClientCommandContext ctx;
634 /* Get the command */
635 tmpcmd = silc_client_parse_command(cs->command);
637 for (cmd = silc_command_list; cmd->name; cmd++) {
638 if (!strcmp(cmd->name, tmpcmd))
642 if (cmd->name == NULL) {
643 silc_say(client, "Invalid command: %s", tmpcmd);
648 /* Now parse all arguments */
649 silc_client_parse_command_line(cs->command, &argv, &argv_lens,
650 &argv_types, &argc, cmd->max_args);
653 SILC_LOG_DEBUG(("Exeuting command: %s", cmd->name));
655 /* Allocate command context. This and its internals must be free'd
656 by the command routine receiving it. */
657 ctx = silc_calloc(1, sizeof(*ctx));
658 ctx->client = client;
659 ctx->sock = client->current_win->sock;
662 ctx->argv_lens = argv_lens;
663 ctx->argv_types = argv_types;
665 /* Execute command */
672 /* Internal context for connection process. This is needed as we
673 doing asynchronous connecting. */
681 } SilcClientInternalConnectContext;
684 silc_client_connect_to_server_internal(SilcClientInternalConnectContext *ctx)
688 /* XXX In the future we should give up this non-blocking connect all
689 together and use threads instead. */
690 /* Create connection to server asynchronously */
691 sock = silc_net_create_connection_async(ctx->port, ctx->host);
695 /* Register task that will receive the async connect and will
697 ctx->task = silc_task_register(ctx->client->io_queue, sock,
698 silc_client_connect_to_server_start,
701 SILC_TASK_PRI_NORMAL);
702 silc_task_reset_iotype(ctx->task, SILC_TASK_WRITE);
703 silc_schedule_set_listen_fd(sock, ctx->task->iomask);
710 /* Connects to remote server */
712 int silc_client_connect_to_server(SilcClient client, int port,
715 SilcClientInternalConnectContext *ctx;
717 SILC_LOG_DEBUG(("Connecting to port %d of server %s",
720 silc_say(client, "Connecting to port %d of server %s", port, host);
722 client->current_win->remote_host = strdup(host);
723 client->current_win->remote_port = port;
725 /* Allocate internal context for connection process. This is
726 needed as we are doing async connecting. */
727 ctx = silc_calloc(1, sizeof(*ctx));
728 ctx->client = client;
729 ctx->host = strdup(host);
733 /* Do the actual connecting process */
734 return silc_client_connect_to_server_internal(ctx);
737 /* Start of the connection to the remote server. This is called after
738 succesful TCP/IP connection has been established to the remote host. */
740 SILC_TASK_CALLBACK(silc_client_connect_to_server_start)
742 SilcClientInternalConnectContext *ctx =
743 (SilcClientInternalConnectContext *)context;
744 SilcClient client = ctx->client;
745 SilcProtocol protocol;
746 SilcClientKEInternalContext *proto_ctx;
747 int opt, opt_len = sizeof(opt);
749 SILC_LOG_DEBUG(("Start"));
751 /* Check the socket status as it might be in error */
752 getsockopt(fd, SOL_SOCKET, SO_ERROR, &opt, &opt_len);
754 if (ctx->tries < 2) {
755 /* Connection failed but lets try again */
756 silc_say(ctx->client, "Could not connect to server %s: %s",
757 ctx->host, strerror(opt));
758 silc_say(client, "Connecting to port %d of server %s resumed",
759 ctx->port, ctx->host);
761 /* Unregister old connection try */
762 silc_schedule_unset_listen_fd(fd);
763 silc_net_close_connection(fd);
764 silc_task_unregister(client->io_queue, ctx->task);
767 silc_client_connect_to_server_internal(ctx);
770 /* Connection failed and we won't try anymore */
771 silc_say(ctx->client, "Could not connect to server %s: %s",
772 ctx->host, strerror(opt));
773 silc_schedule_unset_listen_fd(fd);
774 silc_net_close_connection(fd);
775 silc_task_unregister(client->io_queue, ctx->task);
781 silc_schedule_unset_listen_fd(fd);
782 silc_task_unregister(client->io_queue, ctx->task);
785 /* Allocate new socket connection object */
786 silc_socket_alloc(fd, SILC_SOCKET_TYPE_SERVER,
787 (void *)client->current_win,
788 &client->current_win->sock);
789 if (client->current_win->sock == NULL) {
790 silc_say(client, "Error: Could not allocate connection socket");
791 silc_net_close_connection(fd);
794 client->current_win->sock->hostname = client->current_win->remote_host;
795 client->current_win->sock->port = client->current_win->remote_port;
797 /* Allocate internal Key Exchange context. This is sent to the
798 protocol as context. */
799 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
800 proto_ctx->client = (void *)client;
801 proto_ctx->sock = client->current_win->sock;
802 proto_ctx->rng = client->rng;
803 proto_ctx->responder = FALSE;
805 /* Perform key exchange protocol. silc_client_connect_to_server_final
806 will be called after the protocol is finished. */
807 silc_protocol_alloc(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
808 &protocol, (void *)proto_ctx,
809 silc_client_connect_to_server_second);
811 silc_say(client, "Error: Could not start authentication protocol");
814 client->current_win->sock->protocol = protocol;
816 /* Register the connection for network input and output. This sets
817 that scheduler will listen for incoming packets for this connection
818 and sets that outgoing packets may be sent to this connection as well.
819 However, this doesn't set the scheduler for outgoing traffic, it will
820 be set separately by calling SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT,
821 later when outgoing data is available. */
822 context = (void *)client;
823 SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(fd);
825 /* Execute the protocol */
826 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0);
829 /* Second part of the connecting to the server. This executed
830 authentication protocol. */
832 SILC_TASK_CALLBACK(silc_client_connect_to_server_second)
834 SilcProtocol protocol = (SilcProtocol)context;
835 SilcClientKEInternalContext *ctx =
836 (SilcClientKEInternalContext *)protocol->context;
837 SilcClient client = (SilcClient)ctx->client;
838 SilcSocketConnection sock = NULL;
839 SilcClientConnAuthInternalContext *proto_ctx;
841 SILC_LOG_DEBUG(("Start"));
843 if (protocol->state == SILC_PROTOCOL_STATE_ERROR) {
844 /* Error occured during protocol */
845 SILC_LOG_DEBUG(("Error during KE protocol"));
846 silc_protocol_free(protocol);
848 silc_ske_free(ctx->ske);
850 silc_free(ctx->dest_id);
851 ctx->sock->protocol = NULL;
856 /* Allocate internal context for the authentication protocol. This
857 is sent as context for the protocol. */
858 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
859 proto_ctx->client = (void *)client;
860 proto_ctx->sock = sock = ctx->sock;
861 proto_ctx->ske = ctx->ske; /* Save SKE object from previous protocol */
862 proto_ctx->dest_id_type = ctx->dest_id_type;
863 proto_ctx->dest_id = ctx->dest_id;
865 /* Resolve the authentication method to be used in this connection */
866 proto_ctx->auth_meth = SILC_PROTOCOL_CONN_AUTH_NONE;
867 if (client->config->conns) {
868 SilcClientConfigSectionConnection *conn = NULL;
870 /* Check if we find a match from user configured connections */
871 conn = silc_client_config_find_connection(client->config,
875 /* Match found. Use the configured authentication method */
876 proto_ctx->auth_meth = conn->auth_meth;
877 if (conn->auth_data) {
878 proto_ctx->auth_data = strdup(conn->auth_data);
879 proto_ctx->auth_data_len = strlen(conn->auth_data);
882 /* No match found. Resolve by sending AUTH_REQUEST to server */
883 proto_ctx->auth_meth = SILC_PROTOCOL_CONN_AUTH_NONE;
886 /* XXX Resolve by sending AUTH_REQUEST to server */
887 proto_ctx->auth_meth = SILC_PROTOCOL_CONN_AUTH_NONE;
890 /* Free old protocol as it is finished now */
891 silc_protocol_free(protocol);
893 silc_buffer_free(ctx->packet);
895 /* silc_free(ctx->keymat....); */
896 sock->protocol = NULL;
898 /* Allocate the authentication protocol. This is allocated here
899 but we won't start it yet. We will be receiving party of this
900 protocol thus we will wait that connecting party will make
902 silc_protocol_alloc(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
903 &sock->protocol, (void *)proto_ctx,
904 silc_client_connect_to_server_final);
906 /* Execute the protocol */
907 sock->protocol->execute(client->timeout_queue, 0, sock->protocol, fd, 0, 0);
910 /* Finalizes the connection to the remote SILC server. This is called
911 after authentication protocol has been completed. This send our
912 user information to the server to receive our client ID from
915 SILC_TASK_CALLBACK(silc_client_connect_to_server_final)
917 SilcProtocol protocol = (SilcProtocol)context;
918 SilcClientConnAuthInternalContext *ctx =
919 (SilcClientConnAuthInternalContext *)protocol->context;
920 SilcClient client = (SilcClient)ctx->client;
921 SilcClientWindow win = (SilcClientWindow)ctx->sock->user_data;
924 SILC_LOG_DEBUG(("Start"));
926 if (protocol->state == SILC_PROTOCOL_STATE_ERROR) {
927 /* Error occured during protocol */
928 SILC_LOG_DEBUG(("Error during authentication protocol"));
929 silc_protocol_free(protocol);
931 silc_free(ctx->auth_data);
933 silc_ske_free(ctx->ske);
935 silc_free(ctx->dest_id);
937 win->sock->protocol = NULL;
941 /* Send NEW_CLIENT packet to the server. We will become registered
942 to the SILC network after sending this packet and we will receive
943 client ID from the server. */
944 packet = silc_buffer_alloc(2 + 2 + strlen(client->username) +
945 strlen(client->realname));
946 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
947 silc_buffer_format(packet,
948 SILC_STR_UI_SHORT(strlen(client->username)),
949 SILC_STR_UI_XNSTRING(client->username,
950 strlen(client->username)),
951 SILC_STR_UI_SHORT(strlen(client->realname)),
952 SILC_STR_UI_XNSTRING(client->realname,
953 strlen(client->realname)),
956 /* Send the packet */
957 silc_client_packet_send(client, ctx->sock, SILC_PACKET_NEW_CLIENT,
959 packet->data, packet->len, TRUE);
960 silc_buffer_free(packet);
962 /* Save remote ID. */
963 win->remote_id = ctx->dest_id;
964 win->remote_id_data = silc_id_id2str(ctx->dest_id, SILC_ID_CHANNEL);
965 win->remote_id_data_len = SILC_ID_CHANNEL_LEN;
967 silc_say(client, "Connected to port %d of host %s",
968 win->remote_port, win->remote_host);
970 client->screen->bottom_line->connection = win->remote_host;
971 silc_screen_print_bottom_line(client->screen, 0);
973 silc_protocol_free(protocol);
975 silc_free(ctx->auth_data);
977 silc_ske_free(ctx->ske);
979 silc_free(ctx->dest_id);
981 win->sock->protocol = NULL;
985 SilcPacketContext *packetdata;
986 SilcSocketConnection sock;
988 } SilcClientInternalPacket;
990 SILC_TASK_CALLBACK(silc_client_packet_process)
992 SilcClient client = (SilcClient)context;
993 SilcSocketConnection sock = NULL;
994 int ret, packetlen, paddedlen;
996 SILC_LOG_DEBUG(("Processing packet"));
998 SILC_CLIENT_GET_SOCK(client, fd, sock);
1002 /* Packet sending */
1003 if (type == SILC_TASK_WRITE) {
1004 SILC_LOG_DEBUG(("Writing data to connection"));
1006 if (sock->outbuf->data - sock->outbuf->head)
1007 silc_buffer_push(sock->outbuf,
1008 sock->outbuf->data - sock->outbuf->head);
1010 /* Write the packet out to the connection */
1011 ret = silc_packet_write(fd, sock->outbuf);
1013 /* If returned -2 could not write to connection now, will do
1020 SILC_LOG_ERROR(("Packet dropped"));
1022 /* The packet has been sent and now it is time to set the connection
1023 back to only for input. When there is again some outgoing data
1024 available for this connection it will be set for output as well.
1025 This call clears the output setting and sets it only for input. */
1026 SILC_CLIENT_SET_CONNECTION_FOR_INPUT(fd);
1027 SILC_UNSET_OUTBUF_PENDING(sock);
1032 /* Packet receiving */
1033 if (type == SILC_TASK_READ) {
1034 SILC_LOG_DEBUG(("Reading data from connection"));
1036 /* Allocate the incoming data buffer if not done already. */
1038 sock->inbuf = silc_buffer_alloc(SILC_PACKET_DEFAULT_SIZE);
1040 /* Read some data from connection */
1041 ret = silc_packet_read(fd, sock->inbuf);
1043 /* If returned -2 data was not available now, will read it later. */
1049 SILC_LOG_ERROR(("Packet dropped"));
1055 SILC_LOG_DEBUG(("Read EOF"));
1057 /* If connection is disconnecting already we will finally
1058 close the connection */
1059 if (SILC_IS_DISCONNECTING(sock)) {
1060 silc_client_close_connection(client, sock);
1064 silc_say(client, "Connection closed: premature EOF");
1065 SILC_LOG_DEBUG(("Premature EOF from connection %d", sock->sock));
1067 silc_client_close_connection(client, sock);
1071 /* Check whether we received a whole packet. If reading went without
1072 errors we either read a whole packet or the read packet is
1073 incorrect and will be dropped. */
1074 SILC_PACKET_LENGTH(sock->inbuf, packetlen, paddedlen);
1075 if (sock->inbuf->len < paddedlen || (packetlen < SILC_PACKET_MIN_LEN)) {
1076 SILC_LOG_DEBUG(("Received incorrect packet, dropped"));
1077 silc_buffer_clear(sock->inbuf);
1081 /* Decrypt a packet coming from server connection */
1082 if (sock->type == SILC_SOCKET_TYPE_SERVER ||
1083 sock->type == SILC_SOCKET_TYPE_ROUTER) {
1084 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1085 SilcClientInternalPacket *packet;
1089 mac_len = win->hmac->hash->hash->hash_len;
1091 if (sock->inbuf->len - 2 > (paddedlen + mac_len)) {
1092 /* Received possibly many packets at once */
1094 while(sock->inbuf->len > 0) {
1095 SILC_PACKET_LENGTH(sock->inbuf, packetlen, paddedlen);
1096 if (sock->inbuf->len < paddedlen) {
1097 SILC_LOG_DEBUG(("Received incorrect packet, dropped"));
1102 packet = silc_calloc(1, sizeof(*packet));
1103 packet->client = client;
1104 packet->sock = sock;
1105 packet->packetdata = silc_calloc(1, sizeof(*packet->packetdata));
1106 packet->packetdata->buffer = silc_buffer_alloc(paddedlen + mac_len);
1107 silc_buffer_pull_tail(packet->packetdata->buffer,
1108 SILC_BUFFER_END(packet->packetdata->buffer));
1109 silc_buffer_put(packet->packetdata->buffer, sock->inbuf->data,
1110 paddedlen + mac_len);
1112 SILC_LOG_HEXDUMP(("Incoming packet, len %d",
1113 packet->packetdata->buffer->len),
1114 packet->packetdata->buffer->data,
1115 packet->packetdata->buffer->len);
1116 SILC_LOG_DEBUG(("Packet from server %s, "
1117 "server type %d, packet length %d",
1118 win->remote_host, win->remote_type, paddedlen));
1120 /* If this packet is for the current active connection we will
1121 parse the packet right away to get it quickly on the screen.
1122 Otherwise, it will be parsed with a timeout as the data is
1123 for inactive window (which might not be visible at all). */
1124 if (SILC_CLIENT_IS_CURRENT_WIN(client, win)) {
1125 /* Parse it real soon */
1126 silc_task_register(client->timeout_queue, fd,
1127 silc_client_packet_parse,
1128 (void *)packet, 0, 1,
1130 SILC_TASK_PRI_NORMAL);
1132 /* Parse the packet with timeout */
1133 silc_task_register(client->timeout_queue, fd,
1134 silc_client_packet_parse,
1135 (void *)packet, 0, 200000,
1137 SILC_TASK_PRI_NORMAL);
1140 /* Pull the packet from inbuf thus we'll get the next one
1142 silc_buffer_pull(sock->inbuf, paddedlen);
1144 silc_buffer_pull(sock->inbuf, mac_len);
1146 silc_buffer_clear(sock->inbuf);
1149 /* Received one packet */
1151 SILC_LOG_HEXDUMP(("An incoming packet, len %d", sock->inbuf->len),
1152 sock->inbuf->data, sock->inbuf->len);
1153 SILC_LOG_DEBUG(("Packet from server %s, "
1154 "server type %d, packet length %d",
1155 win->remote_host, win->remote_type, paddedlen));
1157 packet = silc_calloc(1, sizeof(*packet));
1158 packet->client = client;
1159 packet->sock = sock;
1160 packet->packetdata = silc_calloc(1, sizeof(*packet->packetdata));
1161 packet->packetdata->buffer = silc_buffer_copy(sock->inbuf);
1162 silc_buffer_clear(sock->inbuf);
1164 /* If this packet is for the current active connection we will
1165 parse the packet right away to get it quickly on the screen.
1166 Otherwise, it will be parsed with a timeout as the data is
1167 for inactive window (which might not be visible at all). */
1168 if (SILC_CLIENT_IS_CURRENT_WIN(client, win)) {
1169 /* Parse it real soon */
1170 silc_task_register(client->timeout_queue, fd,
1171 silc_client_packet_parse,
1172 (void *)packet, 0, 1,
1174 SILC_TASK_PRI_NORMAL);
1177 /* Parse the packet with timeout */
1178 silc_task_register(client->timeout_queue, fd,
1179 silc_client_packet_parse,
1180 (void *)packet, 0, 200000,
1182 SILC_TASK_PRI_NORMAL);
1189 SILC_LOG_ERROR(("Weird, nothing happened - ignoring"));
1192 /* Checks MAC in the packet. Returns TRUE if MAC is Ok. This is called
1193 after packet has been totally decrypted and parsed. */
1195 static int silc_client_packet_check_mac(SilcClient client,
1196 SilcSocketConnection sock,
1199 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1203 int headlen = buffer->data - buffer->head, mac_len;
1204 unsigned char *packet_mac, mac[32];
1206 SILC_LOG_DEBUG(("Verifying MAC"));
1208 mac_len = win->hmac->hash->hash->hash_len;
1210 silc_buffer_push(buffer, headlen);
1212 /* Take mac from packet */
1213 packet_mac = buffer->tail;
1215 /* Make MAC and compare */
1216 memset(mac, 0, sizeof(mac));
1217 silc_hmac_make_with_key(win->hmac,
1218 buffer->data, buffer->len,
1219 win->hmac_key, win->hmac_key_len, mac);
1221 SILC_LOG_HEXDUMP(("PMAC"), packet_mac, mac_len);
1222 SILC_LOG_HEXDUMP(("CMAC"), mac, mac_len);
1224 if (memcmp(mac, packet_mac, mac_len)) {
1225 SILC_LOG_DEBUG(("MAC failed"));
1229 SILC_LOG_DEBUG(("MAC is Ok"));
1230 memset(mac, 0, sizeof(mac));
1232 silc_buffer_pull(buffer, headlen);
1238 /* Decrypts rest of the packet (after decrypting just the SILC header).
1239 After calling this function the packet is ready to be parsed by calling
1240 silc_packet_parse. */
1242 static int silc_client_packet_decrypt_rest(SilcClient client,
1243 SilcSocketConnection sock,
1246 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1247 unsigned int mac_len = 0;
1250 if (win && win->receive_key) {
1252 /* Pull MAC from packet before decryption */
1254 mac_len = win->hmac->hash->hash->hash_len;
1255 if ((buffer->len - mac_len) > SILC_PACKET_MIN_LEN) {
1256 silc_buffer_push_tail(buffer, mac_len);
1258 SILC_LOG_DEBUG(("Bad MAC length in packet, packet dropped"));
1263 SILC_LOG_DEBUG(("Decrypting rest of the packet"));
1265 /* Decrypt rest of the packet */
1266 silc_buffer_pull(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
1267 silc_packet_decrypt(win->receive_key, buffer, buffer->len);
1268 silc_buffer_push(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
1270 SILC_LOG_HEXDUMP(("Fully decrypted packet, len %d", buffer->len),
1271 buffer->data, buffer->len);
1277 /* Decrypts rest of the SILC Packet header that has been decrypted partly
1278 already. This decrypts the padding of the packet also. After calling
1279 this function the packet is ready to be parsed by calling function
1280 silc_packet_parse. This is used in special packet reception. */
1282 static int silc_client_packet_decrypt_rest_special(SilcClient client,
1283 SilcSocketConnection sock,
1286 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1287 unsigned int mac_len = 0;
1289 /* Decrypt rest of the header plus padding */
1290 if (win && win->receive_key) {
1291 unsigned short truelen, len1, len2, padlen;
1293 /* Pull MAC from packet before decryption */
1295 mac_len = win->hmac->hash->hash->hash_len;
1296 if ((buffer->len - mac_len) > SILC_PACKET_MIN_LEN) {
1297 silc_buffer_push_tail(buffer, mac_len);
1299 SILC_LOG_DEBUG(("Bad MAC length in packet, packet dropped"));
1304 SILC_LOG_DEBUG(("Decrypting rest of the header"));
1306 SILC_GET16_MSB(len1, &buffer->data[4]);
1307 SILC_GET16_MSB(len2, &buffer->data[6]);
1309 truelen = SILC_PACKET_HEADER_LEN + len1 + len2;
1310 padlen = SILC_PACKET_PADLEN(truelen);
1311 len1 = (truelen + padlen) - (SILC_PACKET_MIN_HEADER_LEN - 2);
1313 silc_buffer_pull(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
1314 SILC_LOG_HEXDUMP(("XXX"), buffer->data, buffer->len);
1315 silc_packet_decrypt(win->receive_key, buffer, len1);
1316 silc_buffer_push(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
1317 SILC_LOG_HEXDUMP(("XXX"), buffer->data, buffer->len);
1323 /* Parses whole packet, received earlier. */
1325 SILC_TASK_CALLBACK(silc_client_packet_parse)
1327 SilcClientInternalPacket *packet = (SilcClientInternalPacket *)context;
1328 SilcBuffer buffer = packet->packetdata->buffer;
1329 SilcClient client = packet->client;
1330 SilcSocketConnection sock = packet->sock;
1331 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1334 SILC_LOG_DEBUG(("Start"));
1336 /* Decrypt start of the packet header */
1337 if (win && win->receive_key)
1338 silc_packet_decrypt(win->receive_key, buffer, SILC_PACKET_MIN_HEADER_LEN);
1340 /* If the packet type is not any special type lets decrypt rest
1341 of the packet here. */
1342 if (buffer->data[3] != SILC_PACKET_CHANNEL_MESSAGE &&
1343 buffer->data[3] != SILC_PACKET_PRIVATE_MESSAGE) {
1345 /* Normal packet, decrypt rest of the packet */
1346 if (!silc_client_packet_decrypt_rest(client, sock, buffer))
1349 /* Parse the packet. Packet type is returned. */
1350 ret = silc_packet_parse(packet->packetdata);
1351 if (ret == SILC_PACKET_NONE)
1355 if (!silc_client_packet_check_mac(client, sock, buffer))
1358 /* If private message key is not set for private message it is
1359 handled as normal packet. Go back up. */
1360 if (buffer->data[3] == SILC_PACKET_PRIVATE_MESSAGE &&
1361 !(buffer->data[2] & SILC_PACKET_FLAG_PRIVMSG_KEY))
1364 /* Packet requires special handling, decrypt rest of the header.
1365 This only decrypts. This does not do any MAC checking, it must
1366 be done individually later when doing the special processing. */
1367 silc_client_packet_decrypt_rest_special(client, sock, buffer);
1369 /* Parse the packet header in special way as this is "special"
1371 ret = silc_packet_parse_special(packet->packetdata);
1372 if (ret == SILC_PACKET_NONE)
1376 /* Parse the incoming packet type */
1377 silc_client_packet_parse_type(client, sock, packet->packetdata);
1380 silc_buffer_clear(packet->packetdata->buffer);
1381 silc_free(packet->packetdata);
1385 /* Parses the packet type and calls what ever routines the packet type
1386 requires. This is done for all incoming packets. */
1388 void silc_client_packet_parse_type(SilcClient client,
1389 SilcSocketConnection sock,
1390 SilcPacketContext *packet)
1392 SilcBuffer buffer = packet->buffer;
1393 SilcPacketType type = packet->type;
1395 SILC_LOG_DEBUG(("Parsing packet type %d", type));
1397 /* Parse the packet type */
1399 case SILC_PACKET_DISCONNECT:
1400 silc_client_disconnected_by_server(client, sock, buffer);
1402 case SILC_PACKET_SUCCESS:
1404 * Success received for something. For now we can have only
1405 * one protocol for connection executing at once hence this
1406 * success message is for whatever protocol is executing currently.
1408 if (sock->protocol) {
1409 sock->protocol->execute(client->timeout_queue, 0,
1410 sock->protocol, sock->sock, 0, 0);
1413 case SILC_PACKET_FAILURE:
1415 * Failure received for some protocol. Set the protocol state to
1416 * error and call the protocol callback. This fill cause error on
1417 * protocol and it will call the final callback.
1419 if (sock->protocol) {
1420 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
1421 sock->protocol->execute(client->timeout_queue, 0,
1422 sock->protocol, sock->sock, 0, 0);
1425 case SILC_PACKET_REJECT:
1428 case SILC_PACKET_NOTIFY:
1430 * Received notify message
1432 silc_client_notify_by_server(client, sock, buffer);
1435 case SILC_PACKET_ERROR:
1437 * Received error message
1439 silc_client_error_by_server(client, sock, buffer);
1442 case SILC_PACKET_CHANNEL_MESSAGE:
1444 * Received message to (from, actually) a channel
1446 silc_client_channel_message(client, sock, packet);
1448 case SILC_PACKET_CHANNEL_KEY:
1450 * Received key for a channel. By receiving this key the client will be
1451 * able to talk to the channel it has just joined. This can also be
1452 * a new key for existing channel as keys expire peridiocally.
1454 silc_client_receive_channel_key(client, sock, buffer);
1457 case SILC_PACKET_PRIVATE_MESSAGE:
1459 * Received private message
1462 SilcClientCommandReplyContext ctx;
1463 ctx = silc_calloc(1, sizeof(*ctx));
1464 ctx->client = client;
1466 ctx->context = buffer; /* kludge */
1467 silc_client_command_reply_msg((void *)ctx);
1470 case SILC_PACKET_PRIVATE_MESSAGE_KEY:
1472 * Received private message key
1476 case SILC_PACKET_COMMAND_REPLY:
1478 * Recived reply for a command
1480 silc_client_command_reply_process(client, sock, packet);
1483 case SILC_PACKET_KEY_EXCHANGE:
1484 if (sock->protocol) {
1485 SilcClientKEInternalContext *proto_ctx =
1486 (SilcClientKEInternalContext *)sock->protocol->context;
1488 proto_ctx->packet = buffer;
1489 proto_ctx->dest_id_type = packet->src_id_type;
1490 proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_type);
1492 /* Let the protocol handle the packet */
1493 sock->protocol->execute(client->timeout_queue, 0,
1494 sock->protocol, sock->sock, 0, 0);
1496 SILC_LOG_ERROR(("Received Key Exchange packet but no key exchange "
1497 "protocol active, packet dropped."));
1499 /* XXX Trigger KE protocol?? Rekey actually! */
1503 case SILC_PACKET_KEY_EXCHANGE_1:
1504 if (sock->protocol) {
1507 SILC_LOG_ERROR(("Received Key Exchange 1 packet but no key exchange "
1508 "protocol active, packet dropped."));
1511 case SILC_PACKET_KEY_EXCHANGE_2:
1512 if (sock->protocol) {
1513 SilcClientKEInternalContext *proto_ctx =
1514 (SilcClientKEInternalContext *)sock->protocol->context;
1516 if (proto_ctx->packet)
1517 silc_buffer_free(proto_ctx->packet);
1519 proto_ctx->packet = buffer;
1520 proto_ctx->dest_id_type = packet->src_id_type;
1521 proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_type);
1523 /* Let the protocol handle the packet */
1524 sock->protocol->execute(client->timeout_queue, 0,
1525 sock->protocol, sock->sock, 0, 0);
1527 SILC_LOG_ERROR(("Received Key Exchange 2 packet but no key exchange "
1528 "protocol active, packet dropped."));
1532 case SILC_PACKET_NEW_ID:
1535 * Received new ID from server. This packet is received at
1536 * the connection to the server. New ID is also received when
1537 * user changes nickname but in that case the new ID is received
1538 * as command reply and not as this packet type.
1540 unsigned char *id_string;
1541 unsigned short id_type;
1543 silc_buffer_unformat(buffer,
1544 SILC_STR_UI_SHORT(&id_type),
1545 SILC_STR_UI16_STRING_ALLOC(&id_string),
1548 if ((SilcIdType)id_type != SILC_ID_CLIENT)
1551 silc_client_receive_new_id(client, sock, id_string);
1552 silc_free(id_string);
1557 SILC_LOG_DEBUG(("Incorrect packet type %d, packet dropped", type));
1562 /* Internal routine that sends packet or marks packet to be sent. This
1563 is used directly only in special cases. Normal cases should use
1564 silc_server_packet_send. Returns < 0 on error. */
1566 static int silc_client_packet_send_real(SilcClient client,
1567 SilcSocketConnection sock,
1570 /* Send now if forced to do so */
1571 if (force_send == TRUE) {
1573 SILC_LOG_DEBUG(("Forcing packet send, packet sent immediately"));
1574 ret = silc_packet_write(sock->sock, sock->outbuf);
1577 SILC_LOG_ERROR(("Packet dropped"));
1581 SILC_LOG_DEBUG(("Could not force the send, packet put to queue"));
1584 SILC_LOG_DEBUG(("Packet in queue"));
1586 /* Mark that there is some outgoing data available for this connection.
1587 This call sets the connection both for input and output (the input
1588 is set always and this call keeps the input setting, actually).
1589 Actual data sending is performed by silc_client_packet_process. */
1590 SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(sock->sock);
1592 /* Mark to socket that data is pending in outgoing buffer. This flag
1593 is needed if new data is added to the buffer before the earlier
1594 put data is sent to the network. */
1595 SILC_SET_OUTBUF_PENDING(sock);
1600 /* Prepare outgoing data buffer for packet sending. */
1602 static void silc_client_packet_send_prepare(SilcClient client,
1603 SilcSocketConnection sock,
1604 unsigned int header_len,
1605 unsigned int padlen,
1606 unsigned int data_len)
1610 totlen = header_len + padlen + data_len;
1612 /* Prepare the outgoing buffer for packet sending. */
1613 if (!sock->outbuf) {
1614 /* Allocate new buffer. This is done only once per connection. */
1615 SILC_LOG_DEBUG(("Allocating outgoing data buffer"));
1617 sock->outbuf = silc_buffer_alloc(SILC_PACKET_DEFAULT_SIZE);
1618 silc_buffer_pull_tail(sock->outbuf, totlen);
1619 silc_buffer_pull(sock->outbuf, header_len + padlen);
1621 if (SILC_IS_OUTBUF_PENDING(sock)) {
1622 /* There is some pending data in the buffer. */
1624 if ((sock->outbuf->end - sock->outbuf->tail) < data_len) {
1625 SILC_LOG_DEBUG(("Reallocating outgoing data buffer"));
1626 /* XXX: not done yet */
1628 oldlen = sock->outbuf->len;
1629 silc_buffer_pull_tail(sock->outbuf, totlen);
1630 silc_buffer_pull(sock->outbuf, header_len + padlen + oldlen);
1632 /* Buffer is free for use */
1633 silc_buffer_clear(sock->outbuf);
1634 silc_buffer_pull_tail(sock->outbuf, totlen);
1635 silc_buffer_pull(sock->outbuf, header_len + padlen);
1640 /* Sends packet. This doesn't actually send the packet instead it assembles
1641 it and marks it to be sent. However, if force_send is TRUE the packet
1642 is sent immediately. if dst_id, cipher and hmac are NULL those parameters
1643 will be derived from sock argument. Otherwise the valid arguments sent
1646 void silc_client_packet_send(SilcClient client,
1647 SilcSocketConnection sock,
1648 SilcPacketType type,
1650 SilcIdType dst_id_type,
1653 unsigned char *data,
1654 unsigned int data_len,
1657 SilcPacketContext packetdata;
1658 unsigned char *hmac_key = NULL;
1659 unsigned int hmac_key_len = 0;
1660 unsigned char mac[32];
1661 unsigned int mac_len = 0;
1663 SILC_LOG_DEBUG(("Sending packet, type %d", type));
1665 /* Get data used in the packet sending, keys and stuff */
1666 if ((!cipher || !hmac || !dst_id) && sock->user_data) {
1667 if (!cipher && ((SilcClientWindow)sock->user_data)->send_key)
1668 cipher = ((SilcClientWindow)sock->user_data)->send_key;
1669 if (!hmac && ((SilcClientWindow)sock->user_data)->hmac) {
1670 hmac = ((SilcClientWindow)sock->user_data)->hmac;
1671 mac_len = hmac->hash->hash->hash_len;
1672 hmac_key = ((SilcClientWindow)sock->user_data)->hmac_key;
1673 hmac_key_len = ((SilcClientWindow)sock->user_data)->hmac_key_len;
1675 if (!dst_id && ((SilcClientWindow)sock->user_data)->remote_id) {
1676 dst_id = ((SilcClientWindow)sock->user_data)->remote_id;
1677 dst_id_type = SILC_ID_SERVER;
1681 /* Set the packet context pointers */
1682 packetdata.flags = 0;
1683 packetdata.type = type;
1684 if (((SilcClientWindow)sock->user_data)->local_id_data)
1685 packetdata.src_id = ((SilcClientWindow)sock->user_data)->local_id_data;
1687 packetdata.src_id = silc_calloc(SILC_ID_CLIENT_LEN, sizeof(unsigned char));
1688 packetdata.src_id_len = SILC_ID_CLIENT_LEN;
1689 packetdata.src_id_type = SILC_ID_CLIENT;
1691 packetdata.dst_id = silc_id_id2str(dst_id, dst_id_type);
1692 packetdata.dst_id_len = silc_id_get_len(dst_id_type);
1693 packetdata.dst_id_type = dst_id_type;
1695 packetdata.dst_id = NULL;
1696 packetdata.dst_id_len = 0;
1697 packetdata.dst_id_type = SILC_ID_NONE;
1699 packetdata.rng = client->rng;
1700 packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN +
1701 packetdata.src_id_len + packetdata.dst_id_len;
1702 packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen);
1704 /* Prepare outgoing data buffer for packet sending */
1705 silc_client_packet_send_prepare(client, sock,
1706 SILC_PACKET_HEADER_LEN +
1707 packetdata.src_id_len +
1708 packetdata.dst_id_len,
1712 SILC_LOG_DEBUG(("Putting data to outgoing buffer, len %d", data_len));
1714 packetdata.buffer = sock->outbuf;
1716 /* Put the data to the buffer */
1717 if (data && data_len)
1718 silc_buffer_put(sock->outbuf, data, data_len);
1720 /* Create the outgoing packet */
1721 silc_packet_assemble(&packetdata);
1723 /* Compute MAC of the packet */
1725 silc_hmac_make_with_key(hmac, sock->outbuf->data, sock->outbuf->len,
1726 hmac_key, hmac_key_len, mac);
1727 silc_buffer_put_tail(sock->outbuf, mac, mac_len);
1728 memset(mac, 0, sizeof(mac));
1731 /* Encrypt the packet */
1733 silc_packet_encrypt(cipher, sock->outbuf, sock->outbuf->len);
1735 /* Pull MAC into the visible data area */
1737 silc_buffer_pull_tail(sock->outbuf, mac_len);
1739 SILC_LOG_HEXDUMP(("Packet, len %d", sock->outbuf->len),
1740 sock->outbuf->data, sock->outbuf->len);
1742 /* Now actually send the packet */
1743 silc_client_packet_send_real(client, sock, force_send);
1746 /* Sends packet to a channel. Packet to channel is always encrypted
1747 differently from "normal" packets. SILC header of the packet is
1748 encrypted with the next receiver's key and the rest of the packet is
1749 encrypted with the channel specific key. Padding and HMAC is computed
1750 with the next receiver's key. */
1752 void silc_client_packet_send_to_channel(SilcClient client,
1753 SilcSocketConnection sock,
1754 SilcChannelEntry channel,
1755 unsigned char *data,
1756 unsigned int data_len,
1760 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1762 SilcPacketContext packetdata;
1763 unsigned char *hmac_key = NULL;
1764 unsigned int hmac_key_len = 0;
1765 unsigned char mac[32];
1766 unsigned int mac_len = 0;
1767 unsigned char *id_string;
1771 SILC_LOG_DEBUG(("Sending packet to channel"));
1773 if (!channel || !channel->key) {
1774 silc_say(client, "Cannot talk to channel: key does not exist");
1780 for (i = 0; i < 16; i++)
1781 channel->iv[i] = silc_rng_get_byte(client->rng);
1783 silc_hash_make(client->md5hash, channel->iv, 16, channel->iv);
1785 /* Encode the channel payload */
1786 payload = silc_channel_encode_payload(strlen(win->nickname), win->nickname,
1787 data_len, data, 16, channel->iv,
1791 "Error: Could not create packet to be sent to the channel");
1795 /* Get data used in packet header encryption, keys and stuff. Rest
1796 of the packet (the payload) is, however, encrypted with the
1797 specified channel key. */
1798 cipher = win->send_key;
1800 mac_len = hmac->hash->hash->hash_len;
1801 hmac_key = win->hmac_key;
1802 hmac_key_len = win->hmac_key_len;
1803 id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
1805 /* Set the packet context pointers. The destination ID is always
1806 the Channel ID of the channel. Server and router will handle the
1807 distribution of the packet. */
1808 packetdata.flags = 0;
1809 packetdata.type = SILC_PACKET_CHANNEL_MESSAGE;
1810 packetdata.src_id = win->local_id_data;
1811 packetdata.src_id_len = SILC_ID_CLIENT_LEN;
1812 packetdata.src_id_type = SILC_ID_CLIENT;
1813 packetdata.dst_id = id_string;
1814 packetdata.dst_id_len = SILC_ID_CHANNEL_LEN;
1815 packetdata.dst_id_type = SILC_ID_CHANNEL;
1816 packetdata.rng = client->rng;
1817 packetdata.truelen = payload->len + SILC_PACKET_HEADER_LEN +
1818 packetdata.src_id_len + packetdata.dst_id_len;
1819 packetdata.padlen = SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
1820 packetdata.src_id_len +
1821 packetdata.dst_id_len));
1823 /* Prepare outgoing data buffer for packet sending */
1824 silc_client_packet_send_prepare(client, sock,
1825 SILC_PACKET_HEADER_LEN +
1826 packetdata.src_id_len +
1827 packetdata.dst_id_len,
1831 packetdata.buffer = sock->outbuf;
1833 /* Encrypt payload of the packet. This is encrypted with the channel key. */
1834 channel->channel_key->cipher->encrypt(channel->channel_key->context,
1835 payload->data, payload->data,
1836 payload->len - 16, /* -IV_LEN */
1839 SILC_LOG_HEXDUMP(("XXX"), payload->data, payload->len);
1841 /* Put the actual encrypted payload data into the buffer. */
1842 silc_buffer_put(sock->outbuf, payload->data, payload->len);
1844 /* Create the outgoing packet */
1845 silc_packet_assemble(&packetdata);
1847 /* Compute MAC of the packet */
1848 silc_hmac_make_with_key(hmac, sock->outbuf->data, sock->outbuf->len,
1849 hmac_key, hmac_key_len, mac);
1850 silc_buffer_put_tail(sock->outbuf, mac, mac_len);
1851 memset(mac, 0, sizeof(mac));
1853 SILC_LOG_HEXDUMP(("XXX"), sock->outbuf->data, sock->outbuf->len);
1855 /* Encrypt the header and padding of the packet. This is encrypted
1856 with normal session key shared with our server. */
1857 silc_packet_encrypt(cipher, sock->outbuf, SILC_PACKET_HEADER_LEN +
1858 packetdata.src_id_len + packetdata.dst_id_len +
1861 /* Pull MAC into the visible data area */
1862 silc_buffer_pull_tail(sock->outbuf, mac_len);
1864 SILC_LOG_HEXDUMP(("Packet to channel, len %d", sock->outbuf->len),
1865 sock->outbuf->data, sock->outbuf->len);
1867 /* Now actually send the packet */
1868 silc_client_packet_send_real(client, sock, force_send);
1869 silc_buffer_free(payload);
1870 silc_free(id_string);
1873 /* Sends private message to remote client. If private message key has
1874 not been set with this client then the message will be encrypted using
1875 normal session keys. Private messages are special packets in SILC
1876 network hence we need this own function for them. This is similiar
1877 to silc_client_packet_send_to_channel except that we send private
1880 void silc_client_packet_send_private_message(SilcClient client,
1881 SilcSocketConnection sock,
1882 SilcClientEntry client_entry,
1883 unsigned char *data,
1884 unsigned int data_len,
1887 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1889 SilcPacketContext packetdata;
1890 unsigned char *hmac_key = NULL;
1891 unsigned int hmac_key_len = 0;
1892 unsigned char mac[32];
1893 unsigned int mac_len = 0;
1894 unsigned int nick_len;
1898 SILC_LOG_DEBUG(("Sending private message"));
1900 /* Create private message payload */
1901 nick_len = strlen(client->current_win->nickname);
1902 buffer = silc_buffer_alloc(2 + nick_len + data_len);
1903 silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer));
1904 silc_buffer_format(buffer,
1905 SILC_STR_UI_SHORT(nick_len),
1906 SILC_STR_UI_XNSTRING(client->current_win->nickname,
1908 SILC_STR_UI_XNSTRING(data, data_len),
1911 /* If we don't have private message specific key then private messages
1912 are just as any normal packet thus call normal packet sending. If
1913 the key exist then the encryption process is a bit different and
1914 will be done in the rest of this function. */
1915 if (!client_entry->send_key) {
1916 silc_client_packet_send(client, sock, SILC_PACKET_PRIVATE_MESSAGE,
1917 client_entry->id, SILC_ID_CLIENT, NULL, NULL,
1918 buffer->data, buffer->len, force_send);
1922 /* We have private message specific key */
1924 /* Get data used in the encryption */
1925 cipher = client_entry->send_key;
1927 mac_len = hmac->hash->hash->hash_len;
1928 hmac_key = win->hmac_key;
1929 hmac_key_len = win->hmac_key_len;
1931 /* Set the packet context pointers. */
1932 packetdata.flags = 0;
1933 packetdata.type = SILC_PACKET_PRIVATE_MESSAGE;
1934 packetdata.src_id = win->local_id_data;
1935 packetdata.src_id_len = SILC_ID_CLIENT_LEN;
1936 packetdata.src_id_type = SILC_ID_CLIENT;
1938 packetdata.dst_id = silc_id_id2str(client_entry->id, SILC_ID_CLIENT);
1940 packetdata.dst_id = win->local_id_data;
1941 packetdata.dst_id_len = SILC_ID_CLIENT_LEN;
1942 packetdata.dst_id_type = SILC_ID_CLIENT;
1943 packetdata.rng = client->rng;
1944 packetdata.truelen = buffer->len + SILC_PACKET_HEADER_LEN +
1945 packetdata.src_id_len + packetdata.dst_id_len;
1946 packetdata.padlen = SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
1947 packetdata.src_id_len +
1948 packetdata.dst_id_len));
1950 /* Prepare outgoing data buffer for packet sending */
1951 silc_client_packet_send_prepare(client, sock,
1952 SILC_PACKET_HEADER_LEN +
1953 packetdata.src_id_len +
1954 packetdata.dst_id_len,
1958 packetdata.buffer = sock->outbuf;
1960 /* Encrypt payload of the packet. Encrypt with private message specific
1961 key if it exist, otherwise with session key. */
1962 cipher->cipher->encrypt(cipher->context, buffer->data, buffer->data,
1963 buffer->len, cipher->iv);
1965 /* Put the actual encrypted payload data into the buffer. */
1966 silc_buffer_put(sock->outbuf, buffer->data, buffer->len);
1968 /* Create the outgoing packet */
1969 silc_packet_assemble(&packetdata);
1971 /* Compute MAC of the packet */
1972 silc_hmac_make_with_key(hmac, sock->outbuf->data, sock->outbuf->len,
1973 hmac_key, hmac_key_len, mac);
1974 silc_buffer_put_tail(sock->outbuf, mac, mac_len);
1975 memset(mac, 0, sizeof(mac));
1977 SILC_LOG_HEXDUMP(("XXX"), sock->outbuf->data, sock->outbuf->len);
1979 /* Encrypt the header and padding of the packet. */
1980 silc_packet_encrypt(cipher, sock->outbuf, SILC_PACKET_HEADER_LEN +
1981 packetdata.src_id_len + packetdata.dst_id_len +
1984 /* Pull MAC into the visible data area */
1985 silc_buffer_pull_tail(sock->outbuf, mac_len);
1987 SILC_LOG_HEXDUMP(("Private message packet, len %d", sock->outbuf->len),
1988 sock->outbuf->data, sock->outbuf->len);
1990 /* Now actually send the packet */
1991 silc_client_packet_send_real(client, sock, force_send);
1992 silc_free(packetdata.dst_id);
1998 /* Closes connection to remote end. Free's all allocated data except
1999 for some information such as nickname etc. that are valid at all time. */
2001 void silc_client_close_connection(SilcClient client,
2002 SilcSocketConnection sock)
2004 SilcClientWindow win;
2007 /* We won't listen for this connection anymore */
2008 silc_schedule_unset_listen_fd(sock->sock);
2010 /* Unregister all tasks */
2011 silc_task_unregister_by_fd(client->io_queue, sock->sock);
2012 silc_task_unregister_by_fd(client->timeout_queue, sock->sock);
2014 /* Close the actual connection */
2015 silc_net_close_connection(sock->sock);
2017 silc_say(client, "Closed connection to host %s", sock->hostname ?
2018 sock->hostname : sock->ip);
2020 /* Free everything */
2021 if (sock->user_data) {
2022 win = (SilcClientWindow)sock->user_data;
2024 /* XXX Free all client entries and channel entries. */
2026 /* Clear ID caches */
2027 for (i = 0; i < 96; i++)
2028 silc_idcache_del_all(&win->client_id_cache[i],
2029 win->client_id_cache_count[i]);
2030 for (i = 0; i < 96; i++)
2031 silc_idcache_del_all(&win->channel_id_cache[i],
2032 win->channel_id_cache_count[i]);
2035 if (win->remote_host)
2036 silc_free(win->remote_host);
2038 silc_free(win->local_id);
2039 if (win->local_id_data)
2040 silc_free(win->local_id_data);
2042 silc_cipher_free(win->send_key);
2043 if (win->receive_key)
2044 silc_cipher_free(win->receive_key);
2046 silc_hmac_free(win->hmac);
2047 if (win->hmac_key) {
2048 memset(win->hmac_key, 0, win->hmac_key_len);
2049 silc_free(win->hmac_key);
2053 win->remote_port = 0;
2054 win->remote_type = 0;
2055 win->send_key = NULL;
2056 win->receive_key = NULL;
2058 win->hmac_key = NULL;
2059 win->hmac_key_len = 0;
2060 win->local_id = NULL;
2061 win->local_id_data = NULL;
2062 win->remote_host = NULL;
2063 win->current_channel = NULL;
2066 if (sock->protocol) {
2067 silc_protocol_free(sock->protocol);
2068 sock->protocol = NULL;
2070 silc_socket_free(sock);
2073 /* Called when we receive disconnection packet from server. This
2074 closes our end properly and displays the reason of the disconnection
2077 void silc_client_disconnected_by_server(SilcClient client,
2078 SilcSocketConnection sock,
2083 SILC_LOG_DEBUG(("Server disconnected us, sock %d", sock->sock));
2085 msg = silc_calloc(message->len + 1, sizeof(char));
2086 memcpy(msg, message->data, message->len);
2087 silc_say(client, msg);
2090 SILC_SET_DISCONNECTED(sock);
2091 silc_client_close_connection(client, sock);
2094 /* Received error message from server. Display it on the screen.
2095 We don't take any action what so ever of the error message. */
2097 void silc_client_error_by_server(SilcClient client,
2098 SilcSocketConnection sock,
2103 msg = silc_calloc(message->len + 1, sizeof(char));
2104 memcpy(msg, message->data, message->len);
2105 silc_say(client, msg);
2109 /* Received notify message from server */
2111 void silc_client_notify_by_server(SilcClient client,
2112 SilcSocketConnection sock,
2117 msg = silc_calloc(message->len + 1, sizeof(char));
2118 memcpy(msg, message->data, message->len);
2119 silc_say(client, msg);
2123 /* Processes the received new Client ID from server. Old Client ID is
2124 deleted from cache and new one is added. */
2126 void silc_client_receive_new_id(SilcClient client,
2127 SilcSocketConnection sock,
2128 unsigned char *id_string)
2130 SilcClientWindow win = (SilcClientWindow)sock->user_data;
2131 char *nickname = win->nickname;
2133 #define CIDC(x) win->client_id_cache[(x) - 32]
2134 #define CIDCC(x) win->client_id_cache_count[(x) - 32]
2136 /* Delete old ID from ID cache */
2137 silc_idcache_del_by_id(CIDC(nickname[0]), CIDCC(nickname[0]),
2138 SILC_ID_CLIENT, win->local_id);
2140 /* Save the new ID */
2142 silc_free(win->local_id);
2143 win->local_id = silc_id_str2id(id_string, SILC_ID_CLIENT);
2144 if (win->local_id_data)
2145 silc_free(win->local_id_data);
2146 win->local_id_data =
2147 silc_calloc(SILC_ID_CLIENT_LEN, sizeof(unsigned char));
2148 memcpy(win->local_id_data, id_string, SILC_ID_CLIENT_LEN);
2149 win->local_id_data_len = SILC_ID_CLIENT_LEN;
2150 if (!win->local_entry)
2151 win->local_entry = silc_calloc(1, sizeof(*win->local_entry));
2152 win->local_entry->nickname = win->nickname;
2153 win->local_entry->id = win->local_id;
2155 /* Put it to the ID cache */
2156 CIDCC(nickname[0]) = silc_idcache_add(&CIDC(nickname[0]),
2158 win->nickname, SILC_ID_CLIENT,
2160 (void *)win->local_entry);
2165 /* Processed received Channel ID for a channel. This is called when client
2166 joins to channel and server replies with channel ID. The ID is cached. */
2168 void silc_client_new_channel_id(SilcClient client,
2169 SilcSocketConnection sock,
2172 unsigned char *id_string)
2174 SilcClientWindow win = (SilcClientWindow)sock->user_data;
2176 SilcChannelEntry channel;
2178 SILC_LOG_DEBUG(("New channel ID"));
2180 #define CIDC(x) win->channel_id_cache[(x) - 32]
2181 #define CIDCC(x) win->channel_id_cache_count[(x) - 32]
2183 id = silc_id_str2id(id_string, SILC_ID_CHANNEL);
2184 channel = silc_calloc(1, sizeof(*channel));
2185 channel->channel_name = channel_name;
2187 channel->mode = mode;
2188 win->current_channel = channel;
2190 /* Put it to the ID cache */
2191 CIDCC(channel_name[0]) = silc_idcache_add(&CIDC(channel_name[0]),
2192 CIDCC(channel_name[0]),
2193 channel_name, SILC_ID_CHANNEL,
2194 id, (void *)channel);
2199 /* Processes received key for channel. The received key will be used
2200 to protect the traffic on the channel for now on. Client must receive
2201 the key to the channel before talking on the channel is possible.
2202 This is the key that server has generated, this is not the channel
2203 private key, it is entirely local setting. */
2205 void silc_client_receive_channel_key(SilcClient client,
2206 SilcSocketConnection sock,
2210 unsigned char *id_string, *key, *cipher;
2211 unsigned int key_len;
2212 SilcClientWindow win = (SilcClientWindow)sock->user_data;
2214 SilcIDCache *id_cache = NULL;
2215 SilcChannelEntry channel;
2216 SilcChannelKeyPayload payload;
2218 SILC_LOG_DEBUG(("Received key for channel"));
2220 #define CIDC(x) win->channel_id_cache[(x)]
2221 #define CIDCC(x) win->channel_id_cache_count[(x)]
2223 payload = silc_channel_key_parse_payload(packet);
2227 id_string = silc_channel_key_get_id(payload, NULL);
2229 silc_channel_key_free_payload(payload);
2232 id = silc_id_str2id(id_string, SILC_ID_CHANNEL);
2234 /* Find channel. XXX: This is bad and slow. */
2235 for (i = 0; i < 96; i++) {
2236 if (CIDC(i) == NULL)
2238 if (silc_idcache_find_by_id(CIDC(i), CIDCC(i), (void *)id,
2239 SILC_ID_CHANNEL, &id_cache))
2247 key = silc_channel_key_get_key(payload, &key_len);
2248 cipher = silc_channel_key_get_cipher(payload, NULL);
2250 channel = (SilcChannelEntry)id_cache->context;
2251 channel->key_len = key_len;
2252 channel->key = silc_calloc(key_len, sizeof(*channel->key));
2253 memcpy(channel->key, key, key_len);
2255 silc_cipher_alloc(cipher, &channel->channel_key);
2256 if (!channel->channel_key) {
2257 silc_say(client, "Cannot talk to channel: unsupported cipher %s", cipher);
2260 channel->channel_key->cipher->set_key(channel->channel_key->context,
2263 /* Client is now joined to the channel */
2264 channel->on_channel = TRUE;
2268 silc_channel_key_free_payload(payload);
2273 /* Process received message to a channel (or from a channel, really). This
2274 decrypts the channel message with channel specific key and parses the
2275 channel payload. Finally it displays the message on the screen. */
2277 void silc_client_channel_message(SilcClient client,
2278 SilcSocketConnection sock,
2279 SilcPacketContext *packet)
2282 SilcClientWindow win = (SilcClientWindow)sock->user_data;
2283 SilcBuffer buffer = packet->buffer;
2284 SilcChannelPayload payload = NULL;
2285 SilcChannelID *id = NULL;
2286 SilcChannelEntry channel;
2287 SilcIDCache *id_cache = NULL;
2289 #define CIDC(x) win->channel_id_cache[(x)]
2290 #define CIDCC(x) win->channel_id_cache_count[(x)]
2293 if (packet->dst_id_type != SILC_ID_CHANNEL)
2296 id = silc_id_str2id(packet->dst_id, SILC_ID_CHANNEL);
2298 /* Find the channel entry from channels on this window */
2299 for (i = 0; i < 96; i++) {
2300 if (CIDC(i) == NULL)
2302 if (silc_idcache_find_by_id(CIDC(i), CIDCC(i), (void *)id,
2303 SILC_ID_CHANNEL, &id_cache))
2310 channel = (SilcChannelEntry)id_cache->context;
2312 /* Decrypt the channel message payload. Push the IV out of the way,
2313 since it is not encrypted (after pushing buffer->tail has the IV). */
2314 silc_buffer_push_tail(buffer, 16);
2315 channel->channel_key->cipher->decrypt(channel->channel_key->context,
2316 buffer->data, buffer->data,
2317 buffer->len, buffer->tail);
2318 silc_buffer_pull_tail(buffer, 16);
2320 /* Parse the channel message payload */
2321 payload = silc_channel_parse_payload(buffer);
2325 /* Display the message on screen */
2326 if (packet->src_id_type == SILC_ID_CLIENT) {
2327 /* Message from client */
2328 if (channel == win->current_channel)
2329 silc_print(client, "<%s> %s",
2330 silc_channel_get_nickname(payload, NULL),
2331 silc_channel_get_data(payload, NULL));
2333 silc_print(client, "<%s:%s> %s",
2334 silc_channel_get_nickname(payload, NULL),
2335 channel->channel_name,
2336 silc_channel_get_data(payload, NULL));
2338 /* Message from server */
2339 silc_say(client, "%s", silc_channel_get_data(payload, NULL));
2346 silc_channel_free_payload(payload);