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.8 2000/07/12 05:56:32 priikone
24 * Major rewrite of ID Cache system. Support added for the new
27 * Revision 1.7 2000/07/10 05:40:33 priikone
30 * Revision 1.6 2000/07/07 06:54:16 priikone
31 * Print channel name when receiving channel message to non-current
34 * Revision 1.5 2000/07/06 07:14:36 priikone
35 * Fixes to NAMES command handling.
36 * Fixes when leaving from channel.
38 * Revision 1.4 2000/07/05 06:12:05 priikone
39 * Global cosmetic changes.
41 * Revision 1.3 2000/07/04 08:29:12 priikone
42 * Added support for PING command. The ping times are calculated
43 * and showed to the user.
45 * Revision 1.2 2000/07/03 05:49:48 priikone
46 * Implemented LEAVE command. Minor bug fixes.
48 * Revision 1.1.1.1 2000/06/27 11:36:56 priikone
49 * Imported from internal CVS/Added Log headers.
54 #include "clientincludes.h"
56 /* Static function prototypes */
57 static int silc_client_bad_keys(unsigned char key);
58 static void silc_client_process_message(SilcClient client);
59 static char *silc_client_parse_command(unsigned char *buffer);
61 /* Static task callback prototypes */
62 SILC_TASK_CALLBACK(silc_client_update_clock);
63 SILC_TASK_CALLBACK(silc_client_run_commands);
64 SILC_TASK_CALLBACK(silc_client_process_key_press);
65 SILC_TASK_CALLBACK(silc_client_connect_to_server_start);
66 SILC_TASK_CALLBACK(silc_client_connect_to_server_second);
67 SILC_TASK_CALLBACK(silc_client_connect_to_server_final);
68 SILC_TASK_CALLBACK(silc_client_packet_process);
69 SILC_TASK_CALLBACK(silc_client_packet_parse);
71 SilcClientWindow silc_client_create_main_window(SilcClient client);
72 SilcClientWindow silc_client_add_window(SilcClient client,
74 void silc_client_packet_parse_type(SilcClient client,
75 SilcSocketConnection sock,
76 SilcPacketContext *packet);
77 void silc_client_private_message_process(SilcClient client,
78 SilcSocketConnection sock,
79 SilcPacketContext *packet);
81 /* Definitions from version.h */
82 extern char *silc_version;
83 extern char *silc_name;
84 extern char *silc_fullname;
86 /* Allocates new client object. This has to be done before client may
87 work. After calling this one must call silc_client_init to initialize
90 int silc_client_alloc(SilcClient *new_client)
93 *new_client = silc_calloc(1, sizeof(**new_client));
94 (*new_client)->input_buffer = NULL;
95 (*new_client)->screen = NULL;
96 (*new_client)->windows = NULL;
97 (*new_client)->windows_count = 0;
98 (*new_client)->current_win = NULL;
103 /* Free's client object */
105 void silc_client_free(SilcClient client)
112 /* Initializes the client. This makes all the necessary steps to make
113 the client ready to be run. One must call silc_client_run to run the
116 int silc_client_init(SilcClient client)
119 SILC_LOG_DEBUG(("Initializing client"));
122 client->username = silc_get_username();
123 client->realname = silc_get_real_name();
125 /* Register all configured ciphers, PKCS and hash functions. */
126 client->config->client = (void *)client;
127 silc_client_config_register_ciphers(client->config);
128 silc_client_config_register_pkcs(client->config);
129 silc_client_config_register_hashfuncs(client->config);
131 /* Initialize hash functions for client to use */
132 silc_hash_alloc("md5", &client->md5hash);
133 silc_hash_alloc("sha1", &client->sha1hash);
135 /* Initialize none cipher */
136 silc_cipher_alloc("none", &client->none_cipher);
138 /* Initialize random number generator */
139 client->rng = silc_rng_alloc();
140 silc_rng_init(client->rng);
141 silc_math_primegen_init(); /* XXX */
143 /* Load public and private key */
144 if (silc_client_load_keys(client) == FALSE)
147 /* Register the task queues. In SILC we have by default three task queues.
148 One task queue for non-timeout tasks which perform different kind of
149 I/O on file descriptors, timeout task queue for timeout tasks, and,
150 generic non-timeout task queue whose tasks apply to all connections. */
151 silc_task_queue_alloc(&client->io_queue, TRUE);
152 if (!client->io_queue) {
155 silc_task_queue_alloc(&client->timeout_queue, TRUE);
156 if (!client->timeout_queue) {
159 silc_task_queue_alloc(&client->generic_queue, TRUE);
160 if (!client->generic_queue) {
164 /* Initialize the scheduler */
165 silc_schedule_init(client->io_queue, client->timeout_queue,
166 client->generic_queue, 5000);
168 /* Register the main task that is used in client. This received
169 the key pressings. */
170 if (silc_task_register(client->io_queue, fileno(stdin),
171 silc_client_process_key_press,
172 (void *)client, 0, 0,
174 SILC_TASK_PRI_NORMAL) == NULL) {
178 /* Register timeout task that updates clock every minute. */
179 if (silc_task_register(client->timeout_queue, 0,
180 silc_client_update_clock,
182 silc_client_time_til_next_min(), 0,
184 SILC_TASK_PRI_LOW) == NULL) {
188 if (client->config->commands) {
189 /* Run user configured commands with timeout */
190 if (silc_task_register(client->timeout_queue, 0,
191 silc_client_run_commands,
192 (void *)client, 0, 1,
194 SILC_TASK_PRI_LOW) == NULL) {
199 /* Allocate the input buffer used to save typed characters */
200 client->input_buffer = silc_buffer_alloc(SILC_SCREEN_INPUT_WIN_SIZE);
201 silc_buffer_pull_tail(client->input_buffer,
202 SILC_BUFFER_END(client->input_buffer));
204 /* Initialize the screen */
205 client->screen = silc_screen_init();
206 silc_client_create_main_window(client);
207 client->screen->input_buffer = client->input_buffer->data;
208 silc_screen_print_coordinates(client->screen, 0);
213 silc_task_queue_free(client->timeout_queue);
215 silc_task_queue_free(client->io_queue);
220 /* Stops the client. This is called to stop the client and thus to stop
223 void silc_client_stop(SilcClient client)
225 SILC_LOG_DEBUG(("Stopping client"));
227 /* Stop the scheduler, although it might be already stopped. This
228 doesn't hurt anyone. This removes all the tasks and task queues,
230 silc_schedule_stop();
231 silc_schedule_uninit();
233 SILC_LOG_DEBUG(("Client client"));
236 /* Runs the client. */
238 void silc_client_run(SilcClient client)
240 SILC_LOG_DEBUG(("Running client"));
242 /* Start the scheduler, the heart of the SILC client. When this returns
243 the program will be terminated. */
247 /* Creates the main window used in SILC client. This is called always
248 at the initialization of the client. If user wants to create more
249 than one windows a new windows are always created by calling
250 silc_client_add_window. */
252 SilcClientWindow silc_client_create_main_window(SilcClient client)
254 SilcClientWindow win;
257 SILC_LOG_DEBUG(("Creating main window"));
259 assert(client->screen != NULL);
261 client->screen->u_stat_line.program_name = silc_name;
262 client->screen->u_stat_line.program_version = silc_version;
265 win = silc_calloc(1, sizeof(*win));
266 win->nickname = silc_get_username();
267 win->local_id = NULL;
268 win->local_id_data = NULL;
269 win->local_id_data_len = 0;
270 win->remote_host = NULL;
271 win->remote_port = -1;
274 /* Initialize ID caches */
275 win->client_cache = silc_idcache_alloc(0);
276 win->channel_cache = silc_idcache_alloc(0);
277 win->server_cache = silc_idcache_alloc(0);
279 /* Create the actual screen */
280 screen = (void *)silc_screen_create_output_window(client->screen);
281 silc_screen_create_input_window(client->screen);
282 silc_screen_init_upper_status_line(client->screen);
283 silc_screen_init_output_status_line(client->screen);
284 win->screen = screen;
286 client->screen->bottom_line->nickname = win->nickname;
287 silc_screen_print_bottom_line(client->screen, 0);
289 /* Add the window to windows table */
290 client->windows = silc_calloc(1, sizeof(*client->windows));
291 client->windows[client->windows_count] = win;
292 client->windows_count = 1;
294 /* Automatically becomes the current active window */
295 client->current_win = win;
300 /* Allocates and adds new window to the client. This allocates new
301 physical window and internal window for connection specific data.
302 All the connection specific data is always saved into a window
303 since connection is always associated to a active window. */
305 SilcClientWindow silc_client_add_window(SilcClient client,
308 SilcClientWindow win;
310 assert(client->screen != NULL);
312 win = silc_calloc(1, sizeof(*win));
314 /* Add the pointers */
315 win->screen = silc_screen_add_output_window(client->screen);
318 /* Initialize ID caches */
319 win->client_cache = silc_idcache_alloc(0);
320 win->channel_cache = silc_idcache_alloc(0);
321 win->server_cache = silc_idcache_alloc(0);
323 /* Add the window to windows table */
324 client->windows = silc_realloc(client->windows, sizeof(*client->windows)
325 * (client->windows_count + 1));
326 client->windows[client->windows_count] = win;
327 client->windows_count++;
329 if (is_current == TRUE)
330 client->current_win = win;
335 /* The main task on SILC client. This processes the key pressings user
338 SILC_TASK_CALLBACK(silc_client_process_key_press)
340 SilcClient client = (SilcClient)context;
343 /* There is data pending in stdin, this gets it directly */
344 c = wgetch(client->screen->input_win);
345 if (silc_client_bad_keys(c))
348 SILC_LOG_DEBUG(("Pressed key: %d", c));
352 * Special character handling
359 SILC_LOG_DEBUG(("RIGHT"));
360 silc_screen_input_cursor_right(client->screen);
364 SILC_LOG_DEBUG(("LEFT"));
365 silc_screen_input_cursor_left(client->screen);
372 silc_screen_input_backspace(client->screen);
378 /* Insert switch. Turns on/off insert on input window */
379 silc_screen_input_insert(client->screen);
383 /* Enter, Return. User pressed enter we are ready to
384 process the message. */
385 silc_client_process_message(client);
386 silc_screen_input_reset(client->screen);
389 /* Refresh screen, Ctrl^l */
390 silc_screen_refresh_all(client->screen);
395 /* Beginning, Home */
396 silc_screen_input_cursor_home(client->screen);
401 silc_screen_input_cursor_end(client->screen);
419 /* Control codes are printed as reversed */
421 wattron(client->screen->input_win, A_REVERSE);
422 silc_screen_input_print(client->screen, c);
423 wattroff(client->screen->input_win, A_REVERSE);
425 /* Normal character */
426 silc_screen_input_print(client->screen, c);
430 silc_screen_print_coordinates(client->screen, 0);
431 silc_screen_refresh_win(client->screen->input_win);
434 static int silc_client_bad_keys(unsigned char key)
436 /* these are explained in curses.h */
451 case '\E': /* we ignore ESC */
458 /* Processes messages user has typed on the screen. This either sends
459 a packet out to network or if command were written executes it. */
461 static void silc_client_process_message(SilcClient client)
466 SILC_LOG_DEBUG(("Start"));
468 data = client->input_buffer->data;
471 if (data[0] == '/' && data[1] != ' ') {
473 unsigned int argc = 0;
474 unsigned char **argv, *tmpcmd;
475 unsigned int *argv_lens, *argv_types;
476 SilcClientCommand *cmd;
477 SilcClientCommandContext ctx;
479 /* Get the command */
480 tmpcmd = silc_client_parse_command(data);
482 /* Find command match */
483 for (cmd = silc_command_list; cmd->name; cmd++) {
484 if (!strcmp(cmd->name, tmpcmd))
488 if (cmd->name == NULL) {
489 silc_say(client, "Invalid command: %s", tmpcmd);
494 /* Now parse all arguments */
495 silc_client_parse_command_line(data, &argv, &argv_lens,
496 &argv_types, &argc, cmd->max_args);
499 SILC_LOG_DEBUG(("Exeuting command: %s", cmd->name));
501 /* Allocate command context. This and its internals must be free'd
502 by the command routine receiving it. */
503 ctx = silc_calloc(1, sizeof(*ctx));
504 ctx->client = client;
505 ctx->sock = client->current_win->sock;
508 ctx->argv_lens = argv_lens;
509 ctx->argv_types = argv_types;
511 /* Execute command */
515 /* Normal message to a channel */
516 if (len && client->current_win->current_channel &&
517 client->current_win->current_channel->on_channel == TRUE) {
518 silc_print(client, "> %s", data);
519 silc_client_packet_send_to_channel(client,
520 client->current_win->sock,
521 client->current_win->current_channel,
522 data, strlen(data), TRUE);
527 /* Clear the input buffer */
528 silc_buffer_clear(client->input_buffer);
529 silc_buffer_pull_tail(client->input_buffer,
530 SILC_BUFFER_END(client->input_buffer));
533 /* Returns the command fetched from user typed command line */
535 static char *silc_client_parse_command(unsigned char *buffer)
538 const char *cp = buffer;
541 len = strcspn(cp, " ");
542 ret = silc_to_upper((char *)++cp);
548 /* Parses user typed command line. At most `max_args' is taken. Rest
549 of the line will be allocated as the last argument if there are more
550 than `max_args' arguments in the line. Note that the command name
551 is counted as one argument and is saved. */
553 void silc_client_parse_command_line(unsigned char *buffer,
554 unsigned char ***parsed,
555 unsigned int **parsed_lens,
556 unsigned int **parsed_types,
557 unsigned int *parsed_num,
558 unsigned int max_args)
562 const char *cp = buffer;
564 /* Take the '/' away */
567 *parsed = silc_calloc(1, sizeof(**parsed));
568 *parsed_lens = silc_calloc(1, sizeof(**parsed_lens));
570 /* Get the command first */
571 len = strcspn(cp, " ");
572 (*parsed)[0] = silc_to_upper((char *)cp);
573 (*parsed_lens)[0] = len;
577 /* Parse arguments */
578 if (strchr(cp, ' ') || strlen(cp) != 0) {
579 for (i = 1; i < max_args; i++) {
581 if (i != max_args - 1)
582 len = strcspn(cp, " ");
586 *parsed = silc_realloc(*parsed, sizeof(**parsed) * (argc + 1));
587 *parsed_lens = silc_realloc(*parsed_lens,
588 sizeof(**parsed_lens) * (argc + 1));
589 (*parsed)[argc] = silc_calloc(len + 1, sizeof(char));
590 memcpy((*parsed)[argc], cp, len);
591 (*parsed_lens)[argc] = len;
602 /* Save argument types. Protocol defines all argument types but
603 this implementation makes sure that they are always in correct
604 order hence this simple code. */
605 *parsed_types = silc_calloc(argc, sizeof(**parsed_types));
606 for (i = 0; i < argc; i++)
607 (*parsed_types)[i] = i;
612 /* Updates clock on the screen every minute. */
614 SILC_TASK_CALLBACK(silc_client_update_clock)
616 SilcClient client = (SilcClient)context;
618 /* Update the clock on the screen */
619 silc_screen_print_clock(client->screen);
621 /* Re-register this same task */
622 silc_task_register(qptr, 0, silc_client_update_clock, context,
623 silc_client_time_til_next_min(), 0,
627 silc_screen_refresh_win(client->screen->input_win);
630 /* Runs commands user configured in configuration file. This is
631 called when initializing client. */
633 SILC_TASK_CALLBACK(silc_client_run_commands)
635 SilcClient client = (SilcClient)context;
636 SilcClientConfigSectionCommand *cs;
638 SILC_LOG_DEBUG(("Start"));
640 cs = client->config->commands;
642 unsigned int argc = 0;
643 unsigned char **argv, *tmpcmd;
644 unsigned int *argv_lens, *argv_types;
645 SilcClientCommand *cmd;
646 SilcClientCommandContext ctx;
648 /* Get the command */
649 tmpcmd = silc_client_parse_command(cs->command);
651 for (cmd = silc_command_list; cmd->name; cmd++) {
652 if (!strcmp(cmd->name, tmpcmd))
656 if (cmd->name == NULL) {
657 silc_say(client, "Invalid command: %s", tmpcmd);
662 /* Now parse all arguments */
663 silc_client_parse_command_line(cs->command, &argv, &argv_lens,
664 &argv_types, &argc, cmd->max_args);
667 SILC_LOG_DEBUG(("Exeuting command: %s", cmd->name));
669 /* Allocate command context. This and its internals must be free'd
670 by the command routine receiving it. */
671 ctx = silc_calloc(1, sizeof(*ctx));
672 ctx->client = client;
673 ctx->sock = client->current_win->sock;
676 ctx->argv_lens = argv_lens;
677 ctx->argv_types = argv_types;
679 /* Execute command */
686 /* Internal context for connection process. This is needed as we
687 doing asynchronous connecting. */
695 } SilcClientInternalConnectContext;
698 silc_client_connect_to_server_internal(SilcClientInternalConnectContext *ctx)
702 /* XXX In the future we should give up this non-blocking connect all
703 together and use threads instead. */
704 /* Create connection to server asynchronously */
705 sock = silc_net_create_connection_async(ctx->port, ctx->host);
709 /* Register task that will receive the async connect and will
711 ctx->task = silc_task_register(ctx->client->io_queue, sock,
712 silc_client_connect_to_server_start,
715 SILC_TASK_PRI_NORMAL);
716 silc_task_reset_iotype(ctx->task, SILC_TASK_WRITE);
717 silc_schedule_set_listen_fd(sock, ctx->task->iomask);
724 /* Connects to remote server */
726 int silc_client_connect_to_server(SilcClient client, int port,
729 SilcClientInternalConnectContext *ctx;
731 SILC_LOG_DEBUG(("Connecting to port %d of server %s",
734 silc_say(client, "Connecting to port %d of server %s", port, host);
736 client->current_win->remote_host = strdup(host);
737 client->current_win->remote_port = port;
739 /* Allocate internal context for connection process. This is
740 needed as we are doing async connecting. */
741 ctx = silc_calloc(1, sizeof(*ctx));
742 ctx->client = client;
743 ctx->host = strdup(host);
747 /* Do the actual connecting process */
748 return silc_client_connect_to_server_internal(ctx);
751 /* Start of the connection to the remote server. This is called after
752 succesful TCP/IP connection has been established to the remote host. */
754 SILC_TASK_CALLBACK(silc_client_connect_to_server_start)
756 SilcClientInternalConnectContext *ctx =
757 (SilcClientInternalConnectContext *)context;
758 SilcClient client = ctx->client;
759 SilcProtocol protocol;
760 SilcClientKEInternalContext *proto_ctx;
761 int opt, opt_len = sizeof(opt);
763 SILC_LOG_DEBUG(("Start"));
765 /* Check the socket status as it might be in error */
766 getsockopt(fd, SOL_SOCKET, SO_ERROR, &opt, &opt_len);
768 if (ctx->tries < 2) {
769 /* Connection failed but lets try again */
770 silc_say(ctx->client, "Could not connect to server %s: %s",
771 ctx->host, strerror(opt));
772 silc_say(client, "Connecting to port %d of server %s resumed",
773 ctx->port, ctx->host);
775 /* Unregister old connection try */
776 silc_schedule_unset_listen_fd(fd);
777 silc_net_close_connection(fd);
778 silc_task_unregister(client->io_queue, ctx->task);
781 silc_client_connect_to_server_internal(ctx);
784 /* Connection failed and we won't try anymore */
785 silc_say(ctx->client, "Could not connect to server %s: %s",
786 ctx->host, strerror(opt));
787 silc_schedule_unset_listen_fd(fd);
788 silc_net_close_connection(fd);
789 silc_task_unregister(client->io_queue, ctx->task);
795 silc_schedule_unset_listen_fd(fd);
796 silc_task_unregister(client->io_queue, ctx->task);
799 /* Allocate new socket connection object */
800 silc_socket_alloc(fd, SILC_SOCKET_TYPE_SERVER,
801 (void *)client->current_win,
802 &client->current_win->sock);
803 if (client->current_win->sock == NULL) {
804 silc_say(client, "Error: Could not allocate connection socket");
805 silc_net_close_connection(fd);
808 client->current_win->sock->hostname = client->current_win->remote_host;
809 client->current_win->sock->port = client->current_win->remote_port;
811 /* Allocate internal Key Exchange context. This is sent to the
812 protocol as context. */
813 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
814 proto_ctx->client = (void *)client;
815 proto_ctx->sock = client->current_win->sock;
816 proto_ctx->rng = client->rng;
817 proto_ctx->responder = FALSE;
819 /* Perform key exchange protocol. silc_client_connect_to_server_final
820 will be called after the protocol is finished. */
821 silc_protocol_alloc(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
822 &protocol, (void *)proto_ctx,
823 silc_client_connect_to_server_second);
825 silc_say(client, "Error: Could not start authentication protocol");
828 client->current_win->sock->protocol = protocol;
830 /* Register the connection for network input and output. This sets
831 that scheduler will listen for incoming packets for this connection
832 and sets that outgoing packets may be sent to this connection as well.
833 However, this doesn't set the scheduler for outgoing traffic, it will
834 be set separately by calling SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT,
835 later when outgoing data is available. */
836 context = (void *)client;
837 SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(fd);
839 /* Execute the protocol */
840 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0);
843 /* Second part of the connecting to the server. This executed
844 authentication protocol. */
846 SILC_TASK_CALLBACK(silc_client_connect_to_server_second)
848 SilcProtocol protocol = (SilcProtocol)context;
849 SilcClientKEInternalContext *ctx =
850 (SilcClientKEInternalContext *)protocol->context;
851 SilcClient client = (SilcClient)ctx->client;
852 SilcSocketConnection sock = NULL;
853 SilcClientConnAuthInternalContext *proto_ctx;
855 SILC_LOG_DEBUG(("Start"));
857 if (protocol->state == SILC_PROTOCOL_STATE_ERROR) {
858 /* Error occured during protocol */
859 SILC_LOG_DEBUG(("Error during KE protocol"));
860 silc_protocol_free(protocol);
862 silc_ske_free(ctx->ske);
864 silc_free(ctx->dest_id);
865 ctx->sock->protocol = NULL;
870 /* Allocate internal context for the authentication protocol. This
871 is sent as context for the protocol. */
872 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
873 proto_ctx->client = (void *)client;
874 proto_ctx->sock = sock = ctx->sock;
875 proto_ctx->ske = ctx->ske; /* Save SKE object from previous protocol */
876 proto_ctx->dest_id_type = ctx->dest_id_type;
877 proto_ctx->dest_id = ctx->dest_id;
879 /* Resolve the authentication method to be used in this connection */
880 proto_ctx->auth_meth = SILC_PROTOCOL_CONN_AUTH_NONE;
881 if (client->config->conns) {
882 SilcClientConfigSectionConnection *conn = NULL;
884 /* Check if we find a match from user configured connections */
885 conn = silc_client_config_find_connection(client->config,
889 /* Match found. Use the configured authentication method */
890 proto_ctx->auth_meth = conn->auth_meth;
891 if (conn->auth_data) {
892 proto_ctx->auth_data = strdup(conn->auth_data);
893 proto_ctx->auth_data_len = strlen(conn->auth_data);
896 /* No match found. Resolve by sending AUTH_REQUEST to server */
897 proto_ctx->auth_meth = SILC_PROTOCOL_CONN_AUTH_NONE;
900 /* XXX Resolve by sending AUTH_REQUEST to server */
901 proto_ctx->auth_meth = SILC_PROTOCOL_CONN_AUTH_NONE;
904 /* Free old protocol as it is finished now */
905 silc_protocol_free(protocol);
907 silc_buffer_free(ctx->packet);
909 /* silc_free(ctx->keymat....); */
910 sock->protocol = NULL;
912 /* Allocate the authentication protocol. This is allocated here
913 but we won't start it yet. We will be receiving party of this
914 protocol thus we will wait that connecting party will make
916 silc_protocol_alloc(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
917 &sock->protocol, (void *)proto_ctx,
918 silc_client_connect_to_server_final);
920 /* Execute the protocol */
921 sock->protocol->execute(client->timeout_queue, 0, sock->protocol, fd, 0, 0);
924 /* Finalizes the connection to the remote SILC server. This is called
925 after authentication protocol has been completed. This send our
926 user information to the server to receive our client ID from
929 SILC_TASK_CALLBACK(silc_client_connect_to_server_final)
931 SilcProtocol protocol = (SilcProtocol)context;
932 SilcClientConnAuthInternalContext *ctx =
933 (SilcClientConnAuthInternalContext *)protocol->context;
934 SilcClient client = (SilcClient)ctx->client;
935 SilcClientWindow win = (SilcClientWindow)ctx->sock->user_data;
938 SILC_LOG_DEBUG(("Start"));
940 if (protocol->state == SILC_PROTOCOL_STATE_ERROR) {
941 /* Error occured during protocol */
942 SILC_LOG_DEBUG(("Error during authentication protocol"));
943 silc_protocol_free(protocol);
945 silc_free(ctx->auth_data);
947 silc_ske_free(ctx->ske);
949 silc_free(ctx->dest_id);
951 win->sock->protocol = NULL;
955 /* Send NEW_CLIENT packet to the server. We will become registered
956 to the SILC network after sending this packet and we will receive
957 client ID from the server. */
958 packet = silc_buffer_alloc(2 + 2 + strlen(client->username) +
959 strlen(client->realname));
960 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
961 silc_buffer_format(packet,
962 SILC_STR_UI_SHORT(strlen(client->username)),
963 SILC_STR_UI_XNSTRING(client->username,
964 strlen(client->username)),
965 SILC_STR_UI_SHORT(strlen(client->realname)),
966 SILC_STR_UI_XNSTRING(client->realname,
967 strlen(client->realname)),
970 /* Send the packet */
971 silc_client_packet_send(client, ctx->sock, SILC_PACKET_NEW_CLIENT,
973 packet->data, packet->len, TRUE);
974 silc_buffer_free(packet);
976 /* Save remote ID. */
977 win->remote_id = ctx->dest_id;
978 win->remote_id_data = silc_id_id2str(ctx->dest_id, SILC_ID_CHANNEL);
979 win->remote_id_data_len = SILC_ID_CHANNEL_LEN;
981 silc_say(client, "Connected to port %d of host %s",
982 win->remote_port, win->remote_host);
984 client->screen->bottom_line->connection = win->remote_host;
985 silc_screen_print_bottom_line(client->screen, 0);
987 silc_protocol_free(protocol);
989 silc_free(ctx->auth_data);
991 silc_ske_free(ctx->ske);
993 silc_free(ctx->dest_id);
995 win->sock->protocol = NULL;
999 SilcPacketContext *packetdata;
1000 SilcSocketConnection sock;
1002 } SilcClientInternalPacket;
1004 SILC_TASK_CALLBACK(silc_client_packet_process)
1006 SilcClient client = (SilcClient)context;
1007 SilcSocketConnection sock = NULL;
1008 int ret, packetlen, paddedlen;
1010 SILC_LOG_DEBUG(("Processing packet"));
1012 SILC_CLIENT_GET_SOCK(client, fd, sock);
1016 /* Packet sending */
1017 if (type == SILC_TASK_WRITE) {
1018 SILC_LOG_DEBUG(("Writing data to connection"));
1020 if (sock->outbuf->data - sock->outbuf->head)
1021 silc_buffer_push(sock->outbuf,
1022 sock->outbuf->data - sock->outbuf->head);
1024 /* Write the packet out to the connection */
1025 ret = silc_packet_write(fd, sock->outbuf);
1027 /* If returned -2 could not write to connection now, will do
1034 SILC_LOG_ERROR(("Packet dropped"));
1036 /* The packet has been sent and now it is time to set the connection
1037 back to only for input. When there is again some outgoing data
1038 available for this connection it will be set for output as well.
1039 This call clears the output setting and sets it only for input. */
1040 SILC_CLIENT_SET_CONNECTION_FOR_INPUT(fd);
1041 SILC_UNSET_OUTBUF_PENDING(sock);
1046 /* Packet receiving */
1047 if (type == SILC_TASK_READ) {
1048 SILC_LOG_DEBUG(("Reading data from connection"));
1050 /* Allocate the incoming data buffer if not done already. */
1052 sock->inbuf = silc_buffer_alloc(SILC_PACKET_DEFAULT_SIZE);
1054 /* Read some data from connection */
1055 ret = silc_packet_read(fd, sock->inbuf);
1057 /* If returned -2 data was not available now, will read it later. */
1063 SILC_LOG_ERROR(("Packet dropped"));
1069 SILC_LOG_DEBUG(("Read EOF"));
1071 /* If connection is disconnecting already we will finally
1072 close the connection */
1073 if (SILC_IS_DISCONNECTING(sock)) {
1074 silc_client_close_connection(client, sock);
1078 silc_say(client, "Connection closed: premature EOF");
1079 SILC_LOG_DEBUG(("Premature EOF from connection %d", sock->sock));
1081 silc_client_close_connection(client, sock);
1085 /* Check whether we received a whole packet. If reading went without
1086 errors we either read a whole packet or the read packet is
1087 incorrect and will be dropped. */
1088 SILC_PACKET_LENGTH(sock->inbuf, packetlen, paddedlen);
1089 if (sock->inbuf->len < paddedlen || (packetlen < SILC_PACKET_MIN_LEN)) {
1090 SILC_LOG_DEBUG(("Received incorrect packet, dropped"));
1091 silc_buffer_clear(sock->inbuf);
1095 /* Decrypt a packet coming from server connection */
1096 if (sock->type == SILC_SOCKET_TYPE_SERVER ||
1097 sock->type == SILC_SOCKET_TYPE_ROUTER) {
1098 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1099 SilcClientInternalPacket *packet;
1103 mac_len = win->hmac->hash->hash->hash_len;
1105 if (sock->inbuf->len - 2 > (paddedlen + mac_len)) {
1106 /* Received possibly many packets at once */
1108 while(sock->inbuf->len > 0) {
1109 SILC_PACKET_LENGTH(sock->inbuf, packetlen, paddedlen);
1110 if (sock->inbuf->len < paddedlen) {
1111 SILC_LOG_DEBUG(("Received incorrect packet, dropped"));
1116 packet = silc_calloc(1, sizeof(*packet));
1117 packet->client = client;
1118 packet->sock = sock;
1119 packet->packetdata = silc_calloc(1, sizeof(*packet->packetdata));
1120 packet->packetdata->buffer = silc_buffer_alloc(paddedlen + mac_len);
1121 silc_buffer_pull_tail(packet->packetdata->buffer,
1122 SILC_BUFFER_END(packet->packetdata->buffer));
1123 silc_buffer_put(packet->packetdata->buffer, sock->inbuf->data,
1124 paddedlen + mac_len);
1126 SILC_LOG_HEXDUMP(("Incoming packet, len %d",
1127 packet->packetdata->buffer->len),
1128 packet->packetdata->buffer->data,
1129 packet->packetdata->buffer->len);
1130 SILC_LOG_DEBUG(("Packet from server %s, "
1131 "server type %d, packet length %d",
1132 win->remote_host, win->remote_type, paddedlen));
1134 /* If this packet is for the current active connection we will
1135 parse the packet right away to get it quickly on the screen.
1136 Otherwise, it will be parsed with a timeout as the data is
1137 for inactive window (which might not be visible at all). */
1138 if (SILC_CLIENT_IS_CURRENT_WIN(client, win)) {
1139 /* Parse it real soon */
1140 silc_task_register(client->timeout_queue, fd,
1141 silc_client_packet_parse,
1142 (void *)packet, 0, 1,
1144 SILC_TASK_PRI_NORMAL);
1146 /* Parse the packet with timeout */
1147 silc_task_register(client->timeout_queue, fd,
1148 silc_client_packet_parse,
1149 (void *)packet, 0, 200000,
1151 SILC_TASK_PRI_NORMAL);
1154 /* Pull the packet from inbuf thus we'll get the next one
1156 silc_buffer_pull(sock->inbuf, paddedlen);
1158 silc_buffer_pull(sock->inbuf, mac_len);
1160 silc_buffer_clear(sock->inbuf);
1163 /* Received one packet */
1165 SILC_LOG_HEXDUMP(("An incoming packet, len %d", sock->inbuf->len),
1166 sock->inbuf->data, sock->inbuf->len);
1167 SILC_LOG_DEBUG(("Packet from server %s, "
1168 "server type %d, packet length %d",
1169 win->remote_host, win->remote_type, paddedlen));
1171 packet = silc_calloc(1, sizeof(*packet));
1172 packet->client = client;
1173 packet->sock = sock;
1174 packet->packetdata = silc_calloc(1, sizeof(*packet->packetdata));
1175 packet->packetdata->buffer = silc_buffer_copy(sock->inbuf);
1176 silc_buffer_clear(sock->inbuf);
1178 /* If this packet is for the current active connection we will
1179 parse the packet right away to get it quickly on the screen.
1180 Otherwise, it will be parsed with a timeout as the data is
1181 for inactive window (which might not be visible at all). */
1182 if (SILC_CLIENT_IS_CURRENT_WIN(client, win)) {
1183 /* Parse it real soon */
1184 silc_task_register(client->timeout_queue, fd,
1185 silc_client_packet_parse,
1186 (void *)packet, 0, 1,
1188 SILC_TASK_PRI_NORMAL);
1191 /* Parse the packet with timeout */
1192 silc_task_register(client->timeout_queue, fd,
1193 silc_client_packet_parse,
1194 (void *)packet, 0, 200000,
1196 SILC_TASK_PRI_NORMAL);
1203 SILC_LOG_ERROR(("Weird, nothing happened - ignoring"));
1206 /* Checks MAC in the packet. Returns TRUE if MAC is Ok. This is called
1207 after packet has been totally decrypted and parsed. */
1209 static int silc_client_packet_check_mac(SilcClient client,
1210 SilcSocketConnection sock,
1213 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1217 int headlen = buffer->data - buffer->head, mac_len;
1218 unsigned char *packet_mac, mac[32];
1220 SILC_LOG_DEBUG(("Verifying MAC"));
1222 mac_len = win->hmac->hash->hash->hash_len;
1224 silc_buffer_push(buffer, headlen);
1226 /* Take mac from packet */
1227 packet_mac = buffer->tail;
1229 /* Make MAC and compare */
1230 memset(mac, 0, sizeof(mac));
1231 silc_hmac_make_with_key(win->hmac,
1232 buffer->data, buffer->len,
1233 win->hmac_key, win->hmac_key_len, mac);
1235 SILC_LOG_HEXDUMP(("PMAC"), packet_mac, mac_len);
1236 SILC_LOG_HEXDUMP(("CMAC"), mac, mac_len);
1238 if (memcmp(mac, packet_mac, mac_len)) {
1239 SILC_LOG_DEBUG(("MAC failed"));
1243 SILC_LOG_DEBUG(("MAC is Ok"));
1244 memset(mac, 0, sizeof(mac));
1246 silc_buffer_pull(buffer, headlen);
1252 /* Decrypts rest of the packet (after decrypting just the SILC header).
1253 After calling this function the packet is ready to be parsed by calling
1254 silc_packet_parse. */
1256 static int silc_client_packet_decrypt_rest(SilcClient client,
1257 SilcSocketConnection sock,
1260 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1261 unsigned int mac_len = 0;
1264 if (win && win->receive_key) {
1266 /* Pull MAC from packet before decryption */
1268 mac_len = win->hmac->hash->hash->hash_len;
1269 if ((buffer->len - mac_len) > SILC_PACKET_MIN_LEN) {
1270 silc_buffer_push_tail(buffer, mac_len);
1272 SILC_LOG_DEBUG(("Bad MAC length in packet, packet dropped"));
1277 SILC_LOG_DEBUG(("Decrypting rest of the packet"));
1279 /* Decrypt rest of the packet */
1280 silc_buffer_pull(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
1281 silc_packet_decrypt(win->receive_key, buffer, buffer->len);
1282 silc_buffer_push(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
1284 SILC_LOG_HEXDUMP(("Fully decrypted packet, len %d", buffer->len),
1285 buffer->data, buffer->len);
1291 /* Decrypts rest of the SILC Packet header that has been decrypted partly
1292 already. This decrypts the padding of the packet also. After calling
1293 this function the packet is ready to be parsed by calling function
1294 silc_packet_parse. This is used in special packet reception. */
1296 static int silc_client_packet_decrypt_rest_special(SilcClient client,
1297 SilcSocketConnection sock,
1300 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1301 unsigned int mac_len = 0;
1303 /* Decrypt rest of the header plus padding */
1304 if (win && win->receive_key) {
1305 unsigned short truelen, len1, len2, padlen;
1307 /* Pull MAC from packet before decryption */
1309 mac_len = win->hmac->hash->hash->hash_len;
1310 if ((buffer->len - mac_len) > SILC_PACKET_MIN_LEN) {
1311 silc_buffer_push_tail(buffer, mac_len);
1313 SILC_LOG_DEBUG(("Bad MAC length in packet, packet dropped"));
1318 SILC_LOG_DEBUG(("Decrypting rest of the header"));
1320 SILC_GET16_MSB(len1, &buffer->data[4]);
1321 SILC_GET16_MSB(len2, &buffer->data[6]);
1323 truelen = SILC_PACKET_HEADER_LEN + len1 + len2;
1324 padlen = SILC_PACKET_PADLEN(truelen);
1325 len1 = (truelen + padlen) - (SILC_PACKET_MIN_HEADER_LEN - 2);
1327 silc_buffer_pull(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
1328 SILC_LOG_HEXDUMP(("XXX"), buffer->data, buffer->len);
1329 silc_packet_decrypt(win->receive_key, buffer, len1);
1330 silc_buffer_push(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
1331 SILC_LOG_HEXDUMP(("XXX"), buffer->data, buffer->len);
1337 /* Parses whole packet, received earlier. */
1339 SILC_TASK_CALLBACK(silc_client_packet_parse)
1341 SilcClientInternalPacket *packet = (SilcClientInternalPacket *)context;
1342 SilcBuffer buffer = packet->packetdata->buffer;
1343 SilcClient client = packet->client;
1344 SilcSocketConnection sock = packet->sock;
1345 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1348 SILC_LOG_DEBUG(("Start"));
1350 /* Decrypt start of the packet header */
1351 if (win && win->receive_key)
1352 silc_packet_decrypt(win->receive_key, buffer, SILC_PACKET_MIN_HEADER_LEN);
1354 /* If the packet type is not any special type lets decrypt rest
1355 of the packet here. */
1356 if (buffer->data[3] != SILC_PACKET_CHANNEL_MESSAGE &&
1357 buffer->data[3] != SILC_PACKET_PRIVATE_MESSAGE) {
1359 /* Normal packet, decrypt rest of the packet */
1360 if (!silc_client_packet_decrypt_rest(client, sock, buffer))
1363 /* Parse the packet. Packet type is returned. */
1364 ret = silc_packet_parse(packet->packetdata);
1365 if (ret == SILC_PACKET_NONE)
1369 if (!silc_client_packet_check_mac(client, sock, buffer))
1372 /* If private message key is not set for private message it is
1373 handled as normal packet. Go back up. */
1374 if (buffer->data[3] == SILC_PACKET_PRIVATE_MESSAGE &&
1375 !(buffer->data[2] & SILC_PACKET_FLAG_PRIVMSG_KEY))
1378 /* Packet requires special handling, decrypt rest of the header.
1379 This only decrypts. This does not do any MAC checking, it must
1380 be done individually later when doing the special processing. */
1381 silc_client_packet_decrypt_rest_special(client, sock, buffer);
1383 /* Parse the packet header in special way as this is "special"
1385 ret = silc_packet_parse_special(packet->packetdata);
1386 if (ret == SILC_PACKET_NONE)
1390 /* Parse the incoming packet type */
1391 silc_client_packet_parse_type(client, sock, packet->packetdata);
1394 silc_buffer_clear(packet->packetdata->buffer);
1395 silc_free(packet->packetdata);
1399 /* Parses the packet type and calls what ever routines the packet type
1400 requires. This is done for all incoming packets. */
1402 void silc_client_packet_parse_type(SilcClient client,
1403 SilcSocketConnection sock,
1404 SilcPacketContext *packet)
1406 SilcBuffer buffer = packet->buffer;
1407 SilcPacketType type = packet->type;
1409 SILC_LOG_DEBUG(("Parsing packet type %d", type));
1411 /* Parse the packet type */
1413 case SILC_PACKET_DISCONNECT:
1414 silc_client_disconnected_by_server(client, sock, buffer);
1416 case SILC_PACKET_SUCCESS:
1418 * Success received for something. For now we can have only
1419 * one protocol for connection executing at once hence this
1420 * success message is for whatever protocol is executing currently.
1422 if (sock->protocol) {
1423 sock->protocol->execute(client->timeout_queue, 0,
1424 sock->protocol, sock->sock, 0, 0);
1427 case SILC_PACKET_FAILURE:
1429 * Failure received for some protocol. Set the protocol state to
1430 * error and call the protocol callback. This fill cause error on
1431 * protocol and it will call the final callback.
1433 if (sock->protocol) {
1434 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
1435 sock->protocol->execute(client->timeout_queue, 0,
1436 sock->protocol, sock->sock, 0, 0);
1439 case SILC_PACKET_REJECT:
1442 case SILC_PACKET_NOTIFY:
1444 * Received notify message
1446 silc_client_notify_by_server(client, sock, buffer);
1449 case SILC_PACKET_ERROR:
1451 * Received error message
1453 silc_client_error_by_server(client, sock, buffer);
1456 case SILC_PACKET_CHANNEL_MESSAGE:
1458 * Received message to (from, actually) a channel
1460 silc_client_channel_message(client, sock, packet);
1462 case SILC_PACKET_CHANNEL_KEY:
1464 * Received key for a channel. By receiving this key the client will be
1465 * able to talk to the channel it has just joined. This can also be
1466 * a new key for existing channel as keys expire peridiocally.
1468 silc_client_receive_channel_key(client, sock, buffer);
1471 case SILC_PACKET_PRIVATE_MESSAGE:
1473 * Received private message
1476 SilcClientCommandReplyContext ctx;
1477 ctx = silc_calloc(1, sizeof(*ctx));
1478 ctx->client = client;
1480 ctx->context = buffer; /* kludge */
1481 silc_client_command_reply_msg((void *)ctx);
1484 case SILC_PACKET_PRIVATE_MESSAGE_KEY:
1486 * Received private message key
1490 case SILC_PACKET_COMMAND_REPLY:
1492 * Recived reply for a command
1494 silc_client_command_reply_process(client, sock, packet);
1497 case SILC_PACKET_KEY_EXCHANGE:
1498 if (sock->protocol) {
1499 SilcClientKEInternalContext *proto_ctx =
1500 (SilcClientKEInternalContext *)sock->protocol->context;
1502 proto_ctx->packet = buffer;
1503 proto_ctx->dest_id_type = packet->src_id_type;
1504 proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_type);
1506 /* Let the protocol handle the packet */
1507 sock->protocol->execute(client->timeout_queue, 0,
1508 sock->protocol, sock->sock, 0, 0);
1510 SILC_LOG_ERROR(("Received Key Exchange packet but no key exchange "
1511 "protocol active, packet dropped."));
1513 /* XXX Trigger KE protocol?? Rekey actually! */
1517 case SILC_PACKET_KEY_EXCHANGE_1:
1518 if (sock->protocol) {
1521 SILC_LOG_ERROR(("Received Key Exchange 1 packet but no key exchange "
1522 "protocol active, packet dropped."));
1525 case SILC_PACKET_KEY_EXCHANGE_2:
1526 if (sock->protocol) {
1527 SilcClientKEInternalContext *proto_ctx =
1528 (SilcClientKEInternalContext *)sock->protocol->context;
1530 if (proto_ctx->packet)
1531 silc_buffer_free(proto_ctx->packet);
1533 proto_ctx->packet = buffer;
1534 proto_ctx->dest_id_type = packet->src_id_type;
1535 proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_type);
1537 /* Let the protocol handle the packet */
1538 sock->protocol->execute(client->timeout_queue, 0,
1539 sock->protocol, sock->sock, 0, 0);
1541 SILC_LOG_ERROR(("Received Key Exchange 2 packet but no key exchange "
1542 "protocol active, packet dropped."));
1546 case SILC_PACKET_NEW_ID:
1549 * Received new ID from server. This packet is received at
1550 * the connection to the server. New ID is also received when
1551 * user changes nickname but in that case the new ID is received
1552 * as command reply and not as this packet type.
1554 unsigned char *id_string;
1555 unsigned short id_type;
1557 silc_buffer_unformat(buffer,
1558 SILC_STR_UI_SHORT(&id_type),
1559 SILC_STR_UI16_STRING_ALLOC(&id_string),
1562 if ((SilcIdType)id_type != SILC_ID_CLIENT)
1565 silc_client_receive_new_id(client, sock, id_string);
1566 silc_free(id_string);
1571 SILC_LOG_DEBUG(("Incorrect packet type %d, packet dropped", type));
1576 /* Internal routine that sends packet or marks packet to be sent. This
1577 is used directly only in special cases. Normal cases should use
1578 silc_server_packet_send. Returns < 0 on error. */
1580 static int silc_client_packet_send_real(SilcClient client,
1581 SilcSocketConnection sock,
1584 /* Send now if forced to do so */
1585 if (force_send == TRUE) {
1587 SILC_LOG_DEBUG(("Forcing packet send, packet sent immediately"));
1588 ret = silc_packet_write(sock->sock, sock->outbuf);
1591 SILC_LOG_ERROR(("Packet dropped"));
1595 SILC_LOG_DEBUG(("Could not force the send, packet put to queue"));
1598 SILC_LOG_DEBUG(("Packet in queue"));
1600 /* Mark that there is some outgoing data available for this connection.
1601 This call sets the connection both for input and output (the input
1602 is set always and this call keeps the input setting, actually).
1603 Actual data sending is performed by silc_client_packet_process. */
1604 SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(sock->sock);
1606 /* Mark to socket that data is pending in outgoing buffer. This flag
1607 is needed if new data is added to the buffer before the earlier
1608 put data is sent to the network. */
1609 SILC_SET_OUTBUF_PENDING(sock);
1614 /* Prepare outgoing data buffer for packet sending. */
1616 static void silc_client_packet_send_prepare(SilcClient client,
1617 SilcSocketConnection sock,
1618 unsigned int header_len,
1619 unsigned int padlen,
1620 unsigned int data_len)
1624 totlen = header_len + padlen + data_len;
1626 /* Prepare the outgoing buffer for packet sending. */
1627 if (!sock->outbuf) {
1628 /* Allocate new buffer. This is done only once per connection. */
1629 SILC_LOG_DEBUG(("Allocating outgoing data buffer"));
1631 sock->outbuf = silc_buffer_alloc(SILC_PACKET_DEFAULT_SIZE);
1632 silc_buffer_pull_tail(sock->outbuf, totlen);
1633 silc_buffer_pull(sock->outbuf, header_len + padlen);
1635 if (SILC_IS_OUTBUF_PENDING(sock)) {
1636 /* There is some pending data in the buffer. */
1638 if ((sock->outbuf->end - sock->outbuf->tail) < data_len) {
1639 SILC_LOG_DEBUG(("Reallocating outgoing data buffer"));
1640 /* XXX: not done yet */
1642 oldlen = sock->outbuf->len;
1643 silc_buffer_pull_tail(sock->outbuf, totlen);
1644 silc_buffer_pull(sock->outbuf, header_len + padlen + oldlen);
1646 /* Buffer is free for use */
1647 silc_buffer_clear(sock->outbuf);
1648 silc_buffer_pull_tail(sock->outbuf, totlen);
1649 silc_buffer_pull(sock->outbuf, header_len + padlen);
1654 /* Sends packet. This doesn't actually send the packet instead it assembles
1655 it and marks it to be sent. However, if force_send is TRUE the packet
1656 is sent immediately. if dst_id, cipher and hmac are NULL those parameters
1657 will be derived from sock argument. Otherwise the valid arguments sent
1660 void silc_client_packet_send(SilcClient client,
1661 SilcSocketConnection sock,
1662 SilcPacketType type,
1664 SilcIdType dst_id_type,
1667 unsigned char *data,
1668 unsigned int data_len,
1671 SilcPacketContext packetdata;
1672 unsigned char *hmac_key = NULL;
1673 unsigned int hmac_key_len = 0;
1674 unsigned char mac[32];
1675 unsigned int mac_len = 0;
1677 SILC_LOG_DEBUG(("Sending packet, type %d", type));
1679 /* Get data used in the packet sending, keys and stuff */
1680 if ((!cipher || !hmac || !dst_id) && sock->user_data) {
1681 if (!cipher && ((SilcClientWindow)sock->user_data)->send_key)
1682 cipher = ((SilcClientWindow)sock->user_data)->send_key;
1683 if (!hmac && ((SilcClientWindow)sock->user_data)->hmac) {
1684 hmac = ((SilcClientWindow)sock->user_data)->hmac;
1685 mac_len = hmac->hash->hash->hash_len;
1686 hmac_key = ((SilcClientWindow)sock->user_data)->hmac_key;
1687 hmac_key_len = ((SilcClientWindow)sock->user_data)->hmac_key_len;
1689 if (!dst_id && ((SilcClientWindow)sock->user_data)->remote_id) {
1690 dst_id = ((SilcClientWindow)sock->user_data)->remote_id;
1691 dst_id_type = SILC_ID_SERVER;
1695 /* Set the packet context pointers */
1696 packetdata.flags = 0;
1697 packetdata.type = type;
1698 if (((SilcClientWindow)sock->user_data)->local_id_data)
1699 packetdata.src_id = ((SilcClientWindow)sock->user_data)->local_id_data;
1701 packetdata.src_id = silc_calloc(SILC_ID_CLIENT_LEN, sizeof(unsigned char));
1702 packetdata.src_id_len = SILC_ID_CLIENT_LEN;
1703 packetdata.src_id_type = SILC_ID_CLIENT;
1705 packetdata.dst_id = silc_id_id2str(dst_id, dst_id_type);
1706 packetdata.dst_id_len = silc_id_get_len(dst_id_type);
1707 packetdata.dst_id_type = dst_id_type;
1709 packetdata.dst_id = NULL;
1710 packetdata.dst_id_len = 0;
1711 packetdata.dst_id_type = SILC_ID_NONE;
1713 packetdata.rng = client->rng;
1714 packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN +
1715 packetdata.src_id_len + packetdata.dst_id_len;
1716 packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen);
1718 /* Prepare outgoing data buffer for packet sending */
1719 silc_client_packet_send_prepare(client, sock,
1720 SILC_PACKET_HEADER_LEN +
1721 packetdata.src_id_len +
1722 packetdata.dst_id_len,
1726 SILC_LOG_DEBUG(("Putting data to outgoing buffer, len %d", data_len));
1728 packetdata.buffer = sock->outbuf;
1730 /* Put the data to the buffer */
1731 if (data && data_len)
1732 silc_buffer_put(sock->outbuf, data, data_len);
1734 /* Create the outgoing packet */
1735 silc_packet_assemble(&packetdata);
1737 /* Compute MAC of the packet */
1739 silc_hmac_make_with_key(hmac, sock->outbuf->data, sock->outbuf->len,
1740 hmac_key, hmac_key_len, mac);
1741 silc_buffer_put_tail(sock->outbuf, mac, mac_len);
1742 memset(mac, 0, sizeof(mac));
1745 /* Encrypt the packet */
1747 silc_packet_encrypt(cipher, sock->outbuf, sock->outbuf->len);
1749 /* Pull MAC into the visible data area */
1751 silc_buffer_pull_tail(sock->outbuf, mac_len);
1753 SILC_LOG_HEXDUMP(("Packet, len %d", sock->outbuf->len),
1754 sock->outbuf->data, sock->outbuf->len);
1756 /* Now actually send the packet */
1757 silc_client_packet_send_real(client, sock, force_send);
1760 /* Sends packet to a channel. Packet to channel is always encrypted
1761 differently from "normal" packets. SILC header of the packet is
1762 encrypted with the next receiver's key and the rest of the packet is
1763 encrypted with the channel specific key. Padding and HMAC is computed
1764 with the next receiver's key. */
1766 void silc_client_packet_send_to_channel(SilcClient client,
1767 SilcSocketConnection sock,
1768 SilcChannelEntry channel,
1769 unsigned char *data,
1770 unsigned int data_len,
1774 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1776 SilcPacketContext packetdata;
1777 unsigned char *hmac_key = NULL;
1778 unsigned int hmac_key_len = 0;
1779 unsigned char mac[32];
1780 unsigned int mac_len = 0;
1781 unsigned char *id_string;
1785 SILC_LOG_DEBUG(("Sending packet to channel"));
1787 if (!channel || !channel->key) {
1788 silc_say(client, "Cannot talk to channel: key does not exist");
1794 for (i = 0; i < 16; i++)
1795 channel->iv[i] = silc_rng_get_byte(client->rng);
1797 silc_hash_make(client->md5hash, channel->iv, 16, channel->iv);
1799 /* Encode the channel payload */
1800 payload = silc_channel_encode_payload(strlen(win->nickname), win->nickname,
1801 data_len, data, 16, channel->iv,
1805 "Error: Could not create packet to be sent to the channel");
1809 /* Get data used in packet header encryption, keys and stuff. Rest
1810 of the packet (the payload) is, however, encrypted with the
1811 specified channel key. */
1812 cipher = win->send_key;
1814 mac_len = hmac->hash->hash->hash_len;
1815 hmac_key = win->hmac_key;
1816 hmac_key_len = win->hmac_key_len;
1817 id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
1819 /* Set the packet context pointers. The destination ID is always
1820 the Channel ID of the channel. Server and router will handle the
1821 distribution of the packet. */
1822 packetdata.flags = 0;
1823 packetdata.type = SILC_PACKET_CHANNEL_MESSAGE;
1824 packetdata.src_id = win->local_id_data;
1825 packetdata.src_id_len = SILC_ID_CLIENT_LEN;
1826 packetdata.src_id_type = SILC_ID_CLIENT;
1827 packetdata.dst_id = id_string;
1828 packetdata.dst_id_len = SILC_ID_CHANNEL_LEN;
1829 packetdata.dst_id_type = SILC_ID_CHANNEL;
1830 packetdata.rng = client->rng;
1831 packetdata.truelen = payload->len + SILC_PACKET_HEADER_LEN +
1832 packetdata.src_id_len + packetdata.dst_id_len;
1833 packetdata.padlen = SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
1834 packetdata.src_id_len +
1835 packetdata.dst_id_len));
1837 /* Prepare outgoing data buffer for packet sending */
1838 silc_client_packet_send_prepare(client, sock,
1839 SILC_PACKET_HEADER_LEN +
1840 packetdata.src_id_len +
1841 packetdata.dst_id_len,
1845 packetdata.buffer = sock->outbuf;
1847 /* Encrypt payload of the packet. This is encrypted with the channel key. */
1848 channel->channel_key->cipher->encrypt(channel->channel_key->context,
1849 payload->data, payload->data,
1850 payload->len - 16, /* -IV_LEN */
1853 SILC_LOG_HEXDUMP(("XXX"), payload->data, payload->len);
1855 /* Put the actual encrypted payload data into the buffer. */
1856 silc_buffer_put(sock->outbuf, payload->data, payload->len);
1858 /* Create the outgoing packet */
1859 silc_packet_assemble(&packetdata);
1861 /* Compute MAC of the packet */
1862 silc_hmac_make_with_key(hmac, sock->outbuf->data, sock->outbuf->len,
1863 hmac_key, hmac_key_len, mac);
1864 silc_buffer_put_tail(sock->outbuf, mac, mac_len);
1865 memset(mac, 0, sizeof(mac));
1867 SILC_LOG_HEXDUMP(("XXX"), sock->outbuf->data, sock->outbuf->len);
1869 /* Encrypt the header and padding of the packet. This is encrypted
1870 with normal session key shared with our server. */
1871 silc_packet_encrypt(cipher, sock->outbuf, SILC_PACKET_HEADER_LEN +
1872 packetdata.src_id_len + packetdata.dst_id_len +
1875 /* Pull MAC into the visible data area */
1876 silc_buffer_pull_tail(sock->outbuf, mac_len);
1878 SILC_LOG_HEXDUMP(("Packet to channel, len %d", sock->outbuf->len),
1879 sock->outbuf->data, sock->outbuf->len);
1881 /* Now actually send the packet */
1882 silc_client_packet_send_real(client, sock, force_send);
1883 silc_buffer_free(payload);
1884 silc_free(id_string);
1887 /* Sends private message to remote client. If private message key has
1888 not been set with this client then the message will be encrypted using
1889 normal session keys. Private messages are special packets in SILC
1890 network hence we need this own function for them. This is similiar
1891 to silc_client_packet_send_to_channel except that we send private
1894 void silc_client_packet_send_private_message(SilcClient client,
1895 SilcSocketConnection sock,
1896 SilcClientEntry client_entry,
1897 unsigned char *data,
1898 unsigned int data_len,
1901 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1903 SilcPacketContext packetdata;
1904 unsigned char *hmac_key = NULL;
1905 unsigned int hmac_key_len = 0;
1906 unsigned char mac[32];
1907 unsigned int mac_len = 0;
1908 unsigned int nick_len;
1912 SILC_LOG_DEBUG(("Sending private message"));
1914 /* Create private message payload */
1915 nick_len = strlen(client->current_win->nickname);
1916 buffer = silc_buffer_alloc(2 + nick_len + data_len);
1917 silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer));
1918 silc_buffer_format(buffer,
1919 SILC_STR_UI_SHORT(nick_len),
1920 SILC_STR_UI_XNSTRING(client->current_win->nickname,
1922 SILC_STR_UI_XNSTRING(data, data_len),
1925 /* If we don't have private message specific key then private messages
1926 are just as any normal packet thus call normal packet sending. If
1927 the key exist then the encryption process is a bit different and
1928 will be done in the rest of this function. */
1929 if (!client_entry->send_key) {
1930 silc_client_packet_send(client, sock, SILC_PACKET_PRIVATE_MESSAGE,
1931 client_entry->id, SILC_ID_CLIENT, NULL, NULL,
1932 buffer->data, buffer->len, force_send);
1936 /* We have private message specific key */
1938 /* Get data used in the encryption */
1939 cipher = client_entry->send_key;
1941 mac_len = hmac->hash->hash->hash_len;
1942 hmac_key = win->hmac_key;
1943 hmac_key_len = win->hmac_key_len;
1945 /* Set the packet context pointers. */
1946 packetdata.flags = 0;
1947 packetdata.type = SILC_PACKET_PRIVATE_MESSAGE;
1948 packetdata.src_id = win->local_id_data;
1949 packetdata.src_id_len = SILC_ID_CLIENT_LEN;
1950 packetdata.src_id_type = SILC_ID_CLIENT;
1952 packetdata.dst_id = silc_id_id2str(client_entry->id, SILC_ID_CLIENT);
1954 packetdata.dst_id = win->local_id_data;
1955 packetdata.dst_id_len = SILC_ID_CLIENT_LEN;
1956 packetdata.dst_id_type = SILC_ID_CLIENT;
1957 packetdata.rng = client->rng;
1958 packetdata.truelen = buffer->len + SILC_PACKET_HEADER_LEN +
1959 packetdata.src_id_len + packetdata.dst_id_len;
1960 packetdata.padlen = SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
1961 packetdata.src_id_len +
1962 packetdata.dst_id_len));
1964 /* Prepare outgoing data buffer for packet sending */
1965 silc_client_packet_send_prepare(client, sock,
1966 SILC_PACKET_HEADER_LEN +
1967 packetdata.src_id_len +
1968 packetdata.dst_id_len,
1972 packetdata.buffer = sock->outbuf;
1974 /* Encrypt payload of the packet. Encrypt with private message specific
1975 key if it exist, otherwise with session key. */
1976 cipher->cipher->encrypt(cipher->context, buffer->data, buffer->data,
1977 buffer->len, cipher->iv);
1979 /* Put the actual encrypted payload data into the buffer. */
1980 silc_buffer_put(sock->outbuf, buffer->data, buffer->len);
1982 /* Create the outgoing packet */
1983 silc_packet_assemble(&packetdata);
1985 /* Compute MAC of the packet */
1986 silc_hmac_make_with_key(hmac, sock->outbuf->data, sock->outbuf->len,
1987 hmac_key, hmac_key_len, mac);
1988 silc_buffer_put_tail(sock->outbuf, mac, mac_len);
1989 memset(mac, 0, sizeof(mac));
1991 SILC_LOG_HEXDUMP(("XXX"), sock->outbuf->data, sock->outbuf->len);
1993 /* Encrypt the header and padding of the packet. */
1994 silc_packet_encrypt(cipher, sock->outbuf, SILC_PACKET_HEADER_LEN +
1995 packetdata.src_id_len + packetdata.dst_id_len +
1998 /* Pull MAC into the visible data area */
1999 silc_buffer_pull_tail(sock->outbuf, mac_len);
2001 SILC_LOG_HEXDUMP(("Private message packet, len %d", sock->outbuf->len),
2002 sock->outbuf->data, sock->outbuf->len);
2004 /* Now actually send the packet */
2005 silc_client_packet_send_real(client, sock, force_send);
2006 silc_free(packetdata.dst_id);
2012 /* Closes connection to remote end. Free's all allocated data except
2013 for some information such as nickname etc. that are valid at all time. */
2015 void silc_client_close_connection(SilcClient client,
2016 SilcSocketConnection sock)
2018 SilcClientWindow win;
2020 /* We won't listen for this connection anymore */
2021 silc_schedule_unset_listen_fd(sock->sock);
2023 /* Unregister all tasks */
2024 silc_task_unregister_by_fd(client->io_queue, sock->sock);
2025 silc_task_unregister_by_fd(client->timeout_queue, sock->sock);
2027 /* Close the actual connection */
2028 silc_net_close_connection(sock->sock);
2030 silc_say(client, "Closed connection to host %s", sock->hostname ?
2031 sock->hostname : sock->ip);
2033 /* Free everything */
2034 if (sock->user_data) {
2035 win = (SilcClientWindow)sock->user_data;
2037 /* XXX Free all client entries and channel entries. */
2039 /* Clear ID caches */
2040 silc_idcache_del_all(win->client_cache);
2041 silc_idcache_del_all(win->channel_cache);
2044 if (win->remote_host)
2045 silc_free(win->remote_host);
2047 silc_free(win->local_id);
2048 if (win->local_id_data)
2049 silc_free(win->local_id_data);
2051 silc_cipher_free(win->send_key);
2052 if (win->receive_key)
2053 silc_cipher_free(win->receive_key);
2055 silc_hmac_free(win->hmac);
2056 if (win->hmac_key) {
2057 memset(win->hmac_key, 0, win->hmac_key_len);
2058 silc_free(win->hmac_key);
2062 win->remote_port = 0;
2063 win->remote_type = 0;
2064 win->send_key = NULL;
2065 win->receive_key = NULL;
2067 win->hmac_key = NULL;
2068 win->hmac_key_len = 0;
2069 win->local_id = NULL;
2070 win->local_id_data = NULL;
2071 win->remote_host = NULL;
2072 win->current_channel = NULL;
2075 if (sock->protocol) {
2076 silc_protocol_free(sock->protocol);
2077 sock->protocol = NULL;
2079 silc_socket_free(sock);
2082 /* Called when we receive disconnection packet from server. This
2083 closes our end properly and displays the reason of the disconnection
2086 void silc_client_disconnected_by_server(SilcClient client,
2087 SilcSocketConnection sock,
2092 SILC_LOG_DEBUG(("Server disconnected us, sock %d", sock->sock));
2094 msg = silc_calloc(message->len + 1, sizeof(char));
2095 memcpy(msg, message->data, message->len);
2096 silc_say(client, msg);
2099 SILC_SET_DISCONNECTED(sock);
2100 silc_client_close_connection(client, sock);
2103 /* Received error message from server. Display it on the screen.
2104 We don't take any action what so ever of the error message. */
2106 void silc_client_error_by_server(SilcClient client,
2107 SilcSocketConnection sock,
2112 msg = silc_calloc(message->len + 1, sizeof(char));
2113 memcpy(msg, message->data, message->len);
2114 silc_say(client, msg);
2118 /* Received notify message from server */
2120 void silc_client_notify_by_server(SilcClient client,
2121 SilcSocketConnection sock,
2126 msg = silc_calloc(message->len + 1, sizeof(char));
2127 memcpy(msg, message->data, message->len);
2128 silc_say(client, msg);
2132 /* Processes the received new Client ID from server. Old Client ID is
2133 deleted from cache and new one is added. */
2135 void silc_client_receive_new_id(SilcClient client,
2136 SilcSocketConnection sock,
2137 unsigned char *id_string)
2139 SilcClientWindow win = (SilcClientWindow)sock->user_data;
2141 /* Delete old ID from ID cache */
2142 silc_idcache_del_by_id(win->client_cache, SILC_ID_CLIENT, win->local_id);
2144 /* Save the new ID */
2146 silc_free(win->local_id);
2147 win->local_id = silc_id_str2id(id_string, SILC_ID_CLIENT);
2148 if (win->local_id_data)
2149 silc_free(win->local_id_data);
2150 win->local_id_data =
2151 silc_calloc(SILC_ID_CLIENT_LEN, sizeof(unsigned char));
2152 memcpy(win->local_id_data, id_string, SILC_ID_CLIENT_LEN);
2153 win->local_id_data_len = SILC_ID_CLIENT_LEN;
2154 if (!win->local_entry)
2155 win->local_entry = silc_calloc(1, sizeof(*win->local_entry));
2156 win->local_entry->nickname = win->nickname;
2157 win->local_entry->id = win->local_id;
2159 /* Put it to the ID cache */
2160 silc_idcache_add(win->client_cache, win->nickname, SILC_ID_CLIENT,
2161 win->local_id, (void *)win->local_entry, TRUE);
2164 /* Processed received Channel ID for a channel. This is called when client
2165 joins to channel and server replies with channel ID. The ID is cached. */
2167 void silc_client_new_channel_id(SilcClient client,
2168 SilcSocketConnection sock,
2171 unsigned char *id_string)
2173 SilcClientWindow win = (SilcClientWindow)sock->user_data;
2175 SilcChannelEntry channel;
2177 SILC_LOG_DEBUG(("New channel ID"));
2179 id = silc_id_str2id(id_string, SILC_ID_CHANNEL);
2180 channel = silc_calloc(1, sizeof(*channel));
2181 channel->channel_name = channel_name;
2183 channel->mode = mode;
2184 win->current_channel = channel;
2186 /* Put it to the ID cache */
2187 silc_idcache_add(win->channel_cache, channel_name, SILC_ID_CHANNEL,
2188 (void *)id, (void *)channel, TRUE);
2191 /* Processes received key for channel. The received key will be used
2192 to protect the traffic on the channel for now on. Client must receive
2193 the key to the channel before talking on the channel is possible.
2194 This is the key that server has generated, this is not the channel
2195 private key, it is entirely local setting. */
2197 void silc_client_receive_channel_key(SilcClient client,
2198 SilcSocketConnection sock,
2201 unsigned char *id_string, *key, *cipher;
2202 unsigned int key_len;
2203 SilcClientWindow win = (SilcClientWindow)sock->user_data;
2205 SilcIDCacheEntry id_cache = NULL;
2206 SilcChannelEntry channel;
2207 SilcChannelKeyPayload payload;
2209 SILC_LOG_DEBUG(("Received key for channel"));
2211 payload = silc_channel_key_parse_payload(packet);
2215 id_string = silc_channel_key_get_id(payload, NULL);
2217 silc_channel_key_free_payload(payload);
2220 id = silc_id_str2id(id_string, SILC_ID_CHANNEL);
2223 if (!silc_idcache_find_by_id_one(win->channel_cache, (void *)id,
2224 SILC_ID_CHANNEL, &id_cache))
2228 key = silc_channel_key_get_key(payload, &key_len);
2229 cipher = silc_channel_key_get_cipher(payload, NULL);
2231 channel = (SilcChannelEntry)id_cache->context;
2232 channel->key_len = key_len;
2233 channel->key = silc_calloc(key_len, sizeof(*channel->key));
2234 memcpy(channel->key, key, key_len);
2236 silc_cipher_alloc(cipher, &channel->channel_key);
2237 if (!channel->channel_key) {
2238 silc_say(client, "Cannot talk to channel: unsupported cipher %s", cipher);
2241 channel->channel_key->cipher->set_key(channel->channel_key->context,
2244 /* Client is now joined to the channel */
2245 channel->on_channel = TRUE;
2249 silc_channel_key_free_payload(payload);
2252 /* Process received message to a channel (or from a channel, really). This
2253 decrypts the channel message with channel specific key and parses the
2254 channel payload. Finally it displays the message on the screen. */
2256 void silc_client_channel_message(SilcClient client,
2257 SilcSocketConnection sock,
2258 SilcPacketContext *packet)
2260 SilcClientWindow win = (SilcClientWindow)sock->user_data;
2261 SilcBuffer buffer = packet->buffer;
2262 SilcChannelPayload payload = NULL;
2263 SilcChannelID *id = NULL;
2264 SilcChannelEntry channel;
2265 SilcIDCacheEntry id_cache = NULL;
2268 if (packet->dst_id_type != SILC_ID_CHANNEL)
2271 id = silc_id_str2id(packet->dst_id, SILC_ID_CHANNEL);
2273 /* Find the channel entry from channels on this window */
2274 if (!silc_idcache_find_by_id_one(win->channel_cache, (void *)id,
2275 SILC_ID_CHANNEL, &id_cache))
2278 channel = (SilcChannelEntry)id_cache->context;
2280 /* Decrypt the channel message payload. Push the IV out of the way,
2281 since it is not encrypted (after pushing buffer->tail has the IV). */
2282 silc_buffer_push_tail(buffer, 16);
2283 channel->channel_key->cipher->decrypt(channel->channel_key->context,
2284 buffer->data, buffer->data,
2285 buffer->len, buffer->tail);
2286 silc_buffer_pull_tail(buffer, 16);
2288 /* Parse the channel message payload */
2289 payload = silc_channel_parse_payload(buffer);
2293 /* Display the message on screen */
2294 if (packet->src_id_type == SILC_ID_CLIENT) {
2295 /* Message from client */
2296 if (channel == win->current_channel)
2297 silc_print(client, "<%s> %s",
2298 silc_channel_get_nickname(payload, NULL),
2299 silc_channel_get_data(payload, NULL));
2301 silc_print(client, "<%s:%s> %s",
2302 silc_channel_get_nickname(payload, NULL),
2303 channel->channel_name,
2304 silc_channel_get_data(payload, NULL));
2306 /* Message from server */
2307 silc_say(client, "%s", silc_channel_get_data(payload, NULL));
2314 silc_channel_free_payload(payload);