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.11 2000/07/18 12:20:39 priikone
24 * Added ^U functionality, clears input line (patch form cras).
26 * Revision 1.10 2000/07/18 06:53:15 priikone
27 * Allow partial command strings in comparison.
29 * Revision 1.9 2000/07/14 06:13:19 priikone
30 * Moved all the generic packet sending, encryption, reception,
31 * decryption and processing functions to library as they were
32 * duplicated code with the server. Now client uses the generic
33 * routines which is a lot cleaner.
35 * Revision 1.8 2000/07/12 05:56:32 priikone
36 * Major rewrite of ID Cache system. Support added for the new
39 * Revision 1.7 2000/07/10 05:40:33 priikone
42 * Revision 1.6 2000/07/07 06:54:16 priikone
43 * Print channel name when receiving channel message to non-current
46 * Revision 1.5 2000/07/06 07:14:36 priikone
47 * Fixes to NAMES command handling.
48 * Fixes when leaving from channel.
50 * Revision 1.4 2000/07/05 06:12:05 priikone
51 * Global cosmetic changes.
53 * Revision 1.3 2000/07/04 08:29:12 priikone
54 * Added support for PING command. The ping times are calculated
55 * and showed to the user.
57 * Revision 1.2 2000/07/03 05:49:48 priikone
58 * Implemented LEAVE command. Minor bug fixes.
60 * Revision 1.1.1.1 2000/06/27 11:36:56 priikone
61 * Imported from internal CVS/Added Log headers.
66 #include "clientincludes.h"
68 /* Static function prototypes */
69 static int silc_client_bad_keys(unsigned char key);
70 static void silc_client_clear_input(SilcClient client);
71 static void silc_client_process_message(SilcClient client);
72 static char *silc_client_parse_command(unsigned char *buffer);
74 /* Static task callback prototypes */
75 SILC_TASK_CALLBACK(silc_client_update_clock);
76 SILC_TASK_CALLBACK(silc_client_run_commands);
77 SILC_TASK_CALLBACK(silc_client_process_key_press);
78 SILC_TASK_CALLBACK(silc_client_connect_to_server_start);
79 SILC_TASK_CALLBACK(silc_client_connect_to_server_second);
80 SILC_TASK_CALLBACK(silc_client_connect_to_server_final);
81 SILC_TASK_CALLBACK(silc_client_packet_process);
82 SILC_TASK_CALLBACK(silc_client_packet_parse_real);
84 SilcClientWindow silc_client_create_main_window(SilcClient client);
85 SilcClientWindow silc_client_add_window(SilcClient client,
87 void silc_client_packet_parse(SilcPacketParserContext *parser_context);
88 void silc_client_packet_parse_type(SilcClient client,
89 SilcSocketConnection sock,
90 SilcPacketContext *packet);
91 void silc_client_private_message_process(SilcClient client,
92 SilcSocketConnection sock,
93 SilcPacketContext *packet);
95 /* Definitions from version.h */
96 extern char *silc_version;
97 extern char *silc_name;
98 extern char *silc_fullname;
100 /* Allocates new client object. This has to be done before client may
101 work. After calling this one must call silc_client_init to initialize
104 int silc_client_alloc(SilcClient *new_client)
107 *new_client = silc_calloc(1, sizeof(**new_client));
108 (*new_client)->input_buffer = NULL;
109 (*new_client)->screen = NULL;
110 (*new_client)->windows = NULL;
111 (*new_client)->windows_count = 0;
112 (*new_client)->current_win = NULL;
117 /* Free's client object */
119 void silc_client_free(SilcClient client)
126 /* Initializes the client. This makes all the necessary steps to make
127 the client ready to be run. One must call silc_client_run to run the
130 int silc_client_init(SilcClient client)
133 SILC_LOG_DEBUG(("Initializing client"));
136 client->username = silc_get_username();
137 client->realname = silc_get_real_name();
139 /* Register all configured ciphers, PKCS and hash functions. */
140 client->config->client = (void *)client;
141 silc_client_config_register_ciphers(client->config);
142 silc_client_config_register_pkcs(client->config);
143 silc_client_config_register_hashfuncs(client->config);
145 /* Initialize hash functions for client to use */
146 silc_hash_alloc("md5", &client->md5hash);
147 silc_hash_alloc("sha1", &client->sha1hash);
149 /* Initialize none cipher */
150 silc_cipher_alloc("none", &client->none_cipher);
152 /* Initialize random number generator */
153 client->rng = silc_rng_alloc();
154 silc_rng_init(client->rng);
155 silc_math_primegen_init(); /* XXX */
157 /* Load public and private key */
158 if (silc_client_load_keys(client) == FALSE)
161 /* Register the task queues. In SILC we have by default three task queues.
162 One task queue for non-timeout tasks which perform different kind of
163 I/O on file descriptors, timeout task queue for timeout tasks, and,
164 generic non-timeout task queue whose tasks apply to all connections. */
165 silc_task_queue_alloc(&client->io_queue, TRUE);
166 if (!client->io_queue) {
169 silc_task_queue_alloc(&client->timeout_queue, TRUE);
170 if (!client->timeout_queue) {
173 silc_task_queue_alloc(&client->generic_queue, TRUE);
174 if (!client->generic_queue) {
178 /* Initialize the scheduler */
179 silc_schedule_init(client->io_queue, client->timeout_queue,
180 client->generic_queue, 5000);
182 /* Register the main task that is used in client. This received
183 the key pressings. */
184 if (silc_task_register(client->io_queue, fileno(stdin),
185 silc_client_process_key_press,
186 (void *)client, 0, 0,
188 SILC_TASK_PRI_NORMAL) == NULL) {
192 /* Register timeout task that updates clock every minute. */
193 if (silc_task_register(client->timeout_queue, 0,
194 silc_client_update_clock,
196 silc_client_time_til_next_min(), 0,
198 SILC_TASK_PRI_LOW) == NULL) {
202 if (client->config->commands) {
203 /* Run user configured commands with timeout */
204 if (silc_task_register(client->timeout_queue, 0,
205 silc_client_run_commands,
206 (void *)client, 0, 1,
208 SILC_TASK_PRI_LOW) == NULL) {
213 /* Allocate the input buffer used to save typed characters */
214 client->input_buffer = silc_buffer_alloc(SILC_SCREEN_INPUT_WIN_SIZE);
215 silc_buffer_pull_tail(client->input_buffer,
216 SILC_BUFFER_END(client->input_buffer));
218 /* Initialize the screen */
219 client->screen = silc_screen_init();
220 silc_client_create_main_window(client);
221 client->screen->input_buffer = client->input_buffer->data;
222 silc_screen_print_coordinates(client->screen, 0);
227 silc_task_queue_free(client->timeout_queue);
229 silc_task_queue_free(client->io_queue);
234 /* Stops the client. This is called to stop the client and thus to stop
237 void silc_client_stop(SilcClient client)
239 SILC_LOG_DEBUG(("Stopping client"));
241 /* Stop the scheduler, although it might be already stopped. This
242 doesn't hurt anyone. This removes all the tasks and task queues,
244 silc_schedule_stop();
245 silc_schedule_uninit();
247 SILC_LOG_DEBUG(("Client client"));
250 /* Runs the client. */
252 void silc_client_run(SilcClient client)
254 SILC_LOG_DEBUG(("Running client"));
256 /* Start the scheduler, the heart of the SILC client. When this returns
257 the program will be terminated. */
261 /* Creates the main window used in SILC client. This is called always
262 at the initialization of the client. If user wants to create more
263 than one windows a new windows are always created by calling
264 silc_client_add_window. */
266 SilcClientWindow silc_client_create_main_window(SilcClient client)
268 SilcClientWindow win;
271 SILC_LOG_DEBUG(("Creating main window"));
273 assert(client->screen != NULL);
275 client->screen->u_stat_line.program_name = silc_name;
276 client->screen->u_stat_line.program_version = silc_version;
279 win = silc_calloc(1, sizeof(*win));
280 win->nickname = silc_get_username();
281 win->local_id = NULL;
282 win->local_id_data = NULL;
283 win->local_id_data_len = 0;
284 win->remote_host = NULL;
285 win->remote_port = -1;
288 /* Initialize ID caches */
289 win->client_cache = silc_idcache_alloc(0);
290 win->channel_cache = silc_idcache_alloc(0);
291 win->server_cache = silc_idcache_alloc(0);
293 /* Create the actual screen */
294 screen = (void *)silc_screen_create_output_window(client->screen);
295 silc_screen_create_input_window(client->screen);
296 silc_screen_init_upper_status_line(client->screen);
297 silc_screen_init_output_status_line(client->screen);
298 win->screen = screen;
300 client->screen->bottom_line->nickname = win->nickname;
301 silc_screen_print_bottom_line(client->screen, 0);
303 /* Add the window to windows table */
304 client->windows = silc_calloc(1, sizeof(*client->windows));
305 client->windows[client->windows_count] = win;
306 client->windows_count = 1;
308 /* Automatically becomes the current active window */
309 client->current_win = win;
314 /* Allocates and adds new window to the client. This allocates new
315 physical window and internal window for connection specific data.
316 All the connection specific data is always saved into a window
317 since connection is always associated to a active window. */
319 SilcClientWindow silc_client_add_window(SilcClient client,
322 SilcClientWindow win;
324 assert(client->screen != NULL);
326 win = silc_calloc(1, sizeof(*win));
328 /* Add the pointers */
329 win->screen = silc_screen_add_output_window(client->screen);
332 /* Initialize ID caches */
333 win->client_cache = silc_idcache_alloc(0);
334 win->channel_cache = silc_idcache_alloc(0);
335 win->server_cache = silc_idcache_alloc(0);
337 /* Add the window to windows table */
338 client->windows = silc_realloc(client->windows, sizeof(*client->windows)
339 * (client->windows_count + 1));
340 client->windows[client->windows_count] = win;
341 client->windows_count++;
343 if (is_current == TRUE)
344 client->current_win = win;
349 /* The main task on SILC client. This processes the key pressings user
352 SILC_TASK_CALLBACK(silc_client_process_key_press)
354 SilcClient client = (SilcClient)context;
357 /* There is data pending in stdin, this gets it directly */
358 c = wgetch(client->screen->input_win);
359 if (silc_client_bad_keys(c))
362 SILC_LOG_DEBUG(("Pressed key: %d", c));
366 * Special character handling
373 SILC_LOG_DEBUG(("RIGHT"));
374 silc_screen_input_cursor_right(client->screen);
378 SILC_LOG_DEBUG(("LEFT"));
379 silc_screen_input_cursor_left(client->screen);
386 silc_screen_input_backspace(client->screen);
392 /* Insert switch. Turns on/off insert on input window */
393 silc_screen_input_insert(client->screen);
397 /* Enter, Return. User pressed enter we are ready to
398 process the message. */
399 silc_client_process_message(client);
402 /* Refresh screen, Ctrl^l */
403 silc_screen_refresh_all(client->screen);
408 /* Beginning, Home */
409 silc_screen_input_cursor_home(client->screen);
414 silc_screen_input_cursor_end(client->screen);
426 silc_client_clear_input(client);
433 /* Control codes are printed as reversed */
435 wattron(client->screen->input_win, A_REVERSE);
436 silc_screen_input_print(client->screen, c);
437 wattroff(client->screen->input_win, A_REVERSE);
439 /* Normal character */
440 silc_screen_input_print(client->screen, c);
444 silc_screen_print_coordinates(client->screen, 0);
445 silc_screen_refresh_win(client->screen->input_win);
448 static int silc_client_bad_keys(unsigned char key)
450 /* these are explained in curses.h */
465 case '\E': /* we ignore ESC */
472 /* Clears input buffer */
474 static void silc_client_clear_input(SilcClient client)
476 silc_buffer_clear(client->input_buffer);
477 silc_buffer_pull_tail(client->input_buffer,
478 SILC_BUFFER_END(client->input_buffer));
479 silc_screen_input_reset(client->screen);
482 /* Processes messages user has typed on the screen. This either sends
483 a packet out to network or if command were written executes it. */
485 static void silc_client_process_message(SilcClient client)
490 SILC_LOG_DEBUG(("Start"));
492 data = client->input_buffer->data;
495 if (data[0] == '/' && data[1] != ' ') {
497 unsigned int argc = 0;
498 unsigned char **argv, *tmpcmd;
499 unsigned int *argv_lens, *argv_types;
500 SilcClientCommand *cmd;
501 SilcClientCommandContext ctx;
503 /* Get the command */
504 tmpcmd = silc_client_parse_command(data);
506 /* Find command match */
507 for (cmd = silc_command_list; cmd->name; cmd++) {
508 if (!strncmp(cmd->name, tmpcmd, strlen(tmpcmd)))
512 if (cmd->name == NULL) {
513 silc_say(client, "Invalid command: %s", tmpcmd);
518 /* Now parse all arguments */
519 silc_client_parse_command_line(data, &argv, &argv_lens,
520 &argv_types, &argc, cmd->max_args);
523 SILC_LOG_DEBUG(("Exeuting command: %s", cmd->name));
525 /* Allocate command context. This and its internals must be free'd
526 by the command routine receiving it. */
527 ctx = silc_calloc(1, sizeof(*ctx));
528 ctx->client = client;
529 ctx->sock = client->current_win->sock;
532 ctx->argv_lens = argv_lens;
533 ctx->argv_types = argv_types;
535 /* Execute command */
539 /* Normal message to a channel */
540 if (len && client->current_win->current_channel &&
541 client->current_win->current_channel->on_channel == TRUE) {
542 silc_print(client, "> %s", data);
543 silc_client_packet_send_to_channel(client,
544 client->current_win->sock,
545 client->current_win->current_channel,
546 data, strlen(data), TRUE);
551 /* Clear the input buffer */
552 silc_client_clear_input(client);
555 /* Returns the command fetched from user typed command line */
557 static char *silc_client_parse_command(unsigned char *buffer)
560 const char *cp = buffer;
563 len = strcspn(cp, " ");
564 ret = silc_to_upper((char *)++cp);
570 /* Parses user typed command line. At most `max_args' is taken. Rest
571 of the line will be allocated as the last argument if there are more
572 than `max_args' arguments in the line. Note that the command name
573 is counted as one argument and is saved. */
575 void silc_client_parse_command_line(unsigned char *buffer,
576 unsigned char ***parsed,
577 unsigned int **parsed_lens,
578 unsigned int **parsed_types,
579 unsigned int *parsed_num,
580 unsigned int max_args)
584 const char *cp = buffer;
586 /* Take the '/' away */
589 *parsed = silc_calloc(1, sizeof(**parsed));
590 *parsed_lens = silc_calloc(1, sizeof(**parsed_lens));
592 /* Get the command first */
593 len = strcspn(cp, " ");
594 (*parsed)[0] = silc_to_upper((char *)cp);
595 (*parsed_lens)[0] = len;
599 /* Parse arguments */
600 if (strchr(cp, ' ') || strlen(cp) != 0) {
601 for (i = 1; i < max_args; i++) {
603 if (i != max_args - 1)
604 len = strcspn(cp, " ");
608 *parsed = silc_realloc(*parsed, sizeof(**parsed) * (argc + 1));
609 *parsed_lens = silc_realloc(*parsed_lens,
610 sizeof(**parsed_lens) * (argc + 1));
611 (*parsed)[argc] = silc_calloc(len + 1, sizeof(char));
612 memcpy((*parsed)[argc], cp, len);
613 (*parsed_lens)[argc] = len;
624 /* Save argument types. Protocol defines all argument types but
625 this implementation makes sure that they are always in correct
626 order hence this simple code. */
627 *parsed_types = silc_calloc(argc, sizeof(**parsed_types));
628 for (i = 0; i < argc; i++)
629 (*parsed_types)[i] = i;
634 /* Updates clock on the screen every minute. */
636 SILC_TASK_CALLBACK(silc_client_update_clock)
638 SilcClient client = (SilcClient)context;
640 /* Update the clock on the screen */
641 silc_screen_print_clock(client->screen);
643 /* Re-register this same task */
644 silc_task_register(qptr, 0, silc_client_update_clock, context,
645 silc_client_time_til_next_min(), 0,
649 silc_screen_refresh_win(client->screen->input_win);
652 /* Runs commands user configured in configuration file. This is
653 called when initializing client. */
655 SILC_TASK_CALLBACK(silc_client_run_commands)
657 SilcClient client = (SilcClient)context;
658 SilcClientConfigSectionCommand *cs;
660 SILC_LOG_DEBUG(("Start"));
662 cs = client->config->commands;
664 unsigned int argc = 0;
665 unsigned char **argv, *tmpcmd;
666 unsigned int *argv_lens, *argv_types;
667 SilcClientCommand *cmd;
668 SilcClientCommandContext ctx;
670 /* Get the command */
671 tmpcmd = silc_client_parse_command(cs->command);
673 for (cmd = silc_command_list; cmd->name; cmd++) {
674 if (!strcmp(cmd->name, tmpcmd))
678 if (cmd->name == NULL) {
679 silc_say(client, "Invalid command: %s", tmpcmd);
684 /* Now parse all arguments */
685 silc_client_parse_command_line(cs->command, &argv, &argv_lens,
686 &argv_types, &argc, cmd->max_args);
689 SILC_LOG_DEBUG(("Exeuting command: %s", cmd->name));
691 /* Allocate command context. This and its internals must be free'd
692 by the command routine receiving it. */
693 ctx = silc_calloc(1, sizeof(*ctx));
694 ctx->client = client;
695 ctx->sock = client->current_win->sock;
698 ctx->argv_lens = argv_lens;
699 ctx->argv_types = argv_types;
701 /* Execute command */
708 /* Internal context for connection process. This is needed as we
709 doing asynchronous connecting. */
717 } SilcClientInternalConnectContext;
720 silc_client_connect_to_server_internal(SilcClientInternalConnectContext *ctx)
724 /* XXX In the future we should give up this non-blocking connect all
725 together and use threads instead. */
726 /* Create connection to server asynchronously */
727 sock = silc_net_create_connection_async(ctx->port, ctx->host);
731 /* Register task that will receive the async connect and will
733 ctx->task = silc_task_register(ctx->client->io_queue, sock,
734 silc_client_connect_to_server_start,
737 SILC_TASK_PRI_NORMAL);
738 silc_task_reset_iotype(ctx->task, SILC_TASK_WRITE);
739 silc_schedule_set_listen_fd(sock, ctx->task->iomask);
746 /* Connects to remote server */
748 int silc_client_connect_to_server(SilcClient client, int port,
751 SilcClientInternalConnectContext *ctx;
753 SILC_LOG_DEBUG(("Connecting to port %d of server %s",
756 silc_say(client, "Connecting to port %d of server %s", port, host);
758 client->current_win->remote_host = strdup(host);
759 client->current_win->remote_port = port;
761 /* Allocate internal context for connection process. This is
762 needed as we are doing async connecting. */
763 ctx = silc_calloc(1, sizeof(*ctx));
764 ctx->client = client;
765 ctx->host = strdup(host);
769 /* Do the actual connecting process */
770 return silc_client_connect_to_server_internal(ctx);
773 /* Start of the connection to the remote server. This is called after
774 succesful TCP/IP connection has been established to the remote host. */
776 SILC_TASK_CALLBACK(silc_client_connect_to_server_start)
778 SilcClientInternalConnectContext *ctx =
779 (SilcClientInternalConnectContext *)context;
780 SilcClient client = ctx->client;
781 SilcProtocol protocol;
782 SilcClientKEInternalContext *proto_ctx;
783 int opt, opt_len = sizeof(opt);
785 SILC_LOG_DEBUG(("Start"));
787 /* Check the socket status as it might be in error */
788 getsockopt(fd, SOL_SOCKET, SO_ERROR, &opt, &opt_len);
790 if (ctx->tries < 2) {
791 /* Connection failed but lets try again */
792 silc_say(ctx->client, "Could not connect to server %s: %s",
793 ctx->host, strerror(opt));
794 silc_say(client, "Connecting to port %d of server %s resumed",
795 ctx->port, ctx->host);
797 /* Unregister old connection try */
798 silc_schedule_unset_listen_fd(fd);
799 silc_net_close_connection(fd);
800 silc_task_unregister(client->io_queue, ctx->task);
803 silc_client_connect_to_server_internal(ctx);
806 /* Connection failed and we won't try anymore */
807 silc_say(ctx->client, "Could not connect to server %s: %s",
808 ctx->host, strerror(opt));
809 silc_schedule_unset_listen_fd(fd);
810 silc_net_close_connection(fd);
811 silc_task_unregister(client->io_queue, ctx->task);
817 silc_schedule_unset_listen_fd(fd);
818 silc_task_unregister(client->io_queue, ctx->task);
821 /* Allocate new socket connection object */
822 silc_socket_alloc(fd, SILC_SOCKET_TYPE_SERVER,
823 (void *)client->current_win,
824 &client->current_win->sock);
825 if (client->current_win->sock == NULL) {
826 silc_say(client, "Error: Could not allocate connection socket");
827 silc_net_close_connection(fd);
830 client->current_win->sock->hostname = client->current_win->remote_host;
831 client->current_win->sock->port = client->current_win->remote_port;
833 /* Allocate internal Key Exchange context. This is sent to the
834 protocol as context. */
835 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
836 proto_ctx->client = (void *)client;
837 proto_ctx->sock = client->current_win->sock;
838 proto_ctx->rng = client->rng;
839 proto_ctx->responder = FALSE;
841 /* Perform key exchange protocol. silc_client_connect_to_server_final
842 will be called after the protocol is finished. */
843 silc_protocol_alloc(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
844 &protocol, (void *)proto_ctx,
845 silc_client_connect_to_server_second);
847 silc_say(client, "Error: Could not start authentication protocol");
850 client->current_win->sock->protocol = protocol;
852 /* Register the connection for network input and output. This sets
853 that scheduler will listen for incoming packets for this connection
854 and sets that outgoing packets may be sent to this connection as well.
855 However, this doesn't set the scheduler for outgoing traffic, it will
856 be set separately by calling SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT,
857 later when outgoing data is available. */
858 context = (void *)client;
859 SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(fd);
861 /* Execute the protocol */
862 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0);
865 /* Second part of the connecting to the server. This executed
866 authentication protocol. */
868 SILC_TASK_CALLBACK(silc_client_connect_to_server_second)
870 SilcProtocol protocol = (SilcProtocol)context;
871 SilcClientKEInternalContext *ctx =
872 (SilcClientKEInternalContext *)protocol->context;
873 SilcClient client = (SilcClient)ctx->client;
874 SilcSocketConnection sock = NULL;
875 SilcClientConnAuthInternalContext *proto_ctx;
877 SILC_LOG_DEBUG(("Start"));
879 if (protocol->state == SILC_PROTOCOL_STATE_ERROR) {
880 /* Error occured during protocol */
881 SILC_LOG_DEBUG(("Error during KE protocol"));
882 silc_protocol_free(protocol);
884 silc_ske_free(ctx->ske);
886 silc_free(ctx->dest_id);
887 ctx->sock->protocol = NULL;
892 /* Allocate internal context for the authentication protocol. This
893 is sent as context for the protocol. */
894 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
895 proto_ctx->client = (void *)client;
896 proto_ctx->sock = sock = ctx->sock;
897 proto_ctx->ske = ctx->ske; /* Save SKE object from previous protocol */
898 proto_ctx->dest_id_type = ctx->dest_id_type;
899 proto_ctx->dest_id = ctx->dest_id;
901 /* Resolve the authentication method to be used in this connection */
902 proto_ctx->auth_meth = SILC_PROTOCOL_CONN_AUTH_NONE;
903 if (client->config->conns) {
904 SilcClientConfigSectionConnection *conn = NULL;
906 /* Check if we find a match from user configured connections */
907 conn = silc_client_config_find_connection(client->config,
911 /* Match found. Use the configured authentication method */
912 proto_ctx->auth_meth = conn->auth_meth;
913 if (conn->auth_data) {
914 proto_ctx->auth_data = strdup(conn->auth_data);
915 proto_ctx->auth_data_len = strlen(conn->auth_data);
918 /* No match found. Resolve by sending AUTH_REQUEST to server */
919 proto_ctx->auth_meth = SILC_PROTOCOL_CONN_AUTH_NONE;
922 /* XXX Resolve by sending AUTH_REQUEST to server */
923 proto_ctx->auth_meth = SILC_PROTOCOL_CONN_AUTH_NONE;
926 /* Free old protocol as it is finished now */
927 silc_protocol_free(protocol);
929 silc_buffer_free(ctx->packet);
931 /* silc_free(ctx->keymat....); */
932 sock->protocol = NULL;
934 /* Allocate the authentication protocol. This is allocated here
935 but we won't start it yet. We will be receiving party of this
936 protocol thus we will wait that connecting party will make
938 silc_protocol_alloc(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
939 &sock->protocol, (void *)proto_ctx,
940 silc_client_connect_to_server_final);
942 /* Execute the protocol */
943 sock->protocol->execute(client->timeout_queue, 0, sock->protocol, fd, 0, 0);
946 /* Finalizes the connection to the remote SILC server. This is called
947 after authentication protocol has been completed. This send our
948 user information to the server to receive our client ID from
951 SILC_TASK_CALLBACK(silc_client_connect_to_server_final)
953 SilcProtocol protocol = (SilcProtocol)context;
954 SilcClientConnAuthInternalContext *ctx =
955 (SilcClientConnAuthInternalContext *)protocol->context;
956 SilcClient client = (SilcClient)ctx->client;
957 SilcClientWindow win = (SilcClientWindow)ctx->sock->user_data;
960 SILC_LOG_DEBUG(("Start"));
962 if (protocol->state == SILC_PROTOCOL_STATE_ERROR) {
963 /* Error occured during protocol */
964 SILC_LOG_DEBUG(("Error during authentication protocol"));
965 silc_protocol_free(protocol);
967 silc_free(ctx->auth_data);
969 silc_ske_free(ctx->ske);
971 silc_free(ctx->dest_id);
973 win->sock->protocol = NULL;
977 /* Send NEW_CLIENT packet to the server. We will become registered
978 to the SILC network after sending this packet and we will receive
979 client ID from the server. */
980 packet = silc_buffer_alloc(2 + 2 + strlen(client->username) +
981 strlen(client->realname));
982 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
983 silc_buffer_format(packet,
984 SILC_STR_UI_SHORT(strlen(client->username)),
985 SILC_STR_UI_XNSTRING(client->username,
986 strlen(client->username)),
987 SILC_STR_UI_SHORT(strlen(client->realname)),
988 SILC_STR_UI_XNSTRING(client->realname,
989 strlen(client->realname)),
992 /* Send the packet */
993 silc_client_packet_send(client, ctx->sock, SILC_PACKET_NEW_CLIENT,
995 packet->data, packet->len, TRUE);
996 silc_buffer_free(packet);
998 /* Save remote ID. */
999 win->remote_id = ctx->dest_id;
1000 win->remote_id_data = silc_id_id2str(ctx->dest_id, SILC_ID_CHANNEL);
1001 win->remote_id_data_len = SILC_ID_CHANNEL_LEN;
1003 silc_say(client, "Connected to port %d of host %s",
1004 win->remote_port, win->remote_host);
1006 client->screen->bottom_line->connection = win->remote_host;
1007 silc_screen_print_bottom_line(client->screen, 0);
1009 silc_protocol_free(protocol);
1011 silc_free(ctx->auth_data);
1013 silc_ske_free(ctx->ske);
1015 silc_free(ctx->dest_id);
1017 win->sock->protocol = NULL;
1020 /* Internal routine that sends packet or marks packet to be sent. This
1021 is used directly only in special cases. Normal cases should use
1022 silc_server_packet_send. Returns < 0 on error. */
1024 static int silc_client_packet_send_real(SilcClient client,
1025 SilcSocketConnection sock,
1030 /* Send the packet */
1031 ret = silc_packet_send(sock, force_send);
1035 /* Mark that there is some outgoing data available for this connection.
1036 This call sets the connection both for input and output (the input
1037 is set always and this call keeps the input setting, actually).
1038 Actual data sending is performed by silc_client_packet_process. */
1039 SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(sock->sock);
1041 /* Mark to socket that data is pending in outgoing buffer. This flag
1042 is needed if new data is added to the buffer before the earlier
1043 put data is sent to the network. */
1044 SILC_SET_OUTBUF_PENDING(sock);
1049 /* Packet processing callback. This is used to send and receive packets
1050 from network. This is generic task. */
1052 SILC_TASK_CALLBACK(silc_client_packet_process)
1054 SilcClient client = (SilcClient)context;
1055 SilcSocketConnection sock = NULL;
1056 SilcClientWindow win;
1059 SILC_LOG_DEBUG(("Processing packet"));
1061 SILC_CLIENT_GET_SOCK(client, fd, sock);
1065 win = (SilcClientWindow)sock->user_data;
1067 /* Packet sending */
1068 if (type == SILC_TASK_WRITE) {
1069 SILC_LOG_DEBUG(("Writing data to connection"));
1071 if (sock->outbuf->data - sock->outbuf->head)
1072 silc_buffer_push(sock->outbuf,
1073 sock->outbuf->data - sock->outbuf->head);
1075 ret = silc_client_packet_send_real(client, sock, TRUE);
1077 /* If returned -2 could not write to connection now, will do
1082 /* The packet has been sent and now it is time to set the connection
1083 back to only for input. When there is again some outgoing data
1084 available for this connection it will be set for output as well.
1085 This call clears the output setting and sets it only for input. */
1086 SILC_CLIENT_SET_CONNECTION_FOR_INPUT(fd);
1087 SILC_UNSET_OUTBUF_PENDING(sock);
1089 silc_buffer_clear(sock->outbuf);
1093 /* Packet receiving */
1094 if (type == SILC_TASK_READ) {
1095 SILC_LOG_DEBUG(("Reading data from connection"));
1097 /* Read data from network */
1098 ret = silc_packet_receive(sock);
1104 SILC_LOG_DEBUG(("Read EOF"));
1106 /* If connection is disconnecting already we will finally
1107 close the connection */
1108 if (SILC_IS_DISCONNECTING(sock)) {
1109 silc_client_close_connection(client, sock);
1113 silc_say(client, "Connection closed: premature EOF");
1114 SILC_LOG_DEBUG(("Premature EOF from connection %d", sock->sock));
1116 silc_client_close_connection(client, sock);
1120 /* Process the packet. This will call the parser that will then
1121 decrypt and parse the packet. */
1122 if (!silc_packet_receive_process(sock, win->receive_key, win->hmac,
1123 silc_client_packet_parse, client)) {
1124 silc_buffer_clear(sock->inbuf);
1130 /* Parses whole packet, received earlier. */
1132 SILC_TASK_CALLBACK(silc_client_packet_parse_real)
1134 SilcPacketParserContext *parse_ctx = (SilcPacketParserContext *)context;
1135 SilcClient client = (SilcClient)parse_ctx->context;
1136 SilcPacketContext *packet = parse_ctx->packet;
1137 SilcBuffer buffer = packet->buffer;
1138 SilcSocketConnection sock = parse_ctx->sock;
1139 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1142 SILC_LOG_DEBUG(("Start"));
1144 /* Decrypt the received packet */
1145 ret = silc_packet_decrypt(win->receive_key, win->hmac, buffer, packet);
1150 /* Parse the packet. Packet type is returned. */
1151 ret = silc_packet_parse(packet);
1153 /* Parse the packet header in special way as this is "special"
1155 ret = silc_packet_parse_special(packet);
1158 if (ret == SILC_PACKET_NONE)
1161 /* Parse the incoming packet type */
1162 silc_client_packet_parse_type(client, sock, packet);
1165 silc_buffer_clear(buffer);
1167 silc_free(parse_ctx);
1170 /* Parser callback called by silc_packet_receive_process. Thie merely
1171 registers timeout that will handle the actual parsing when appropriate. */
1173 void silc_client_packet_parse(SilcPacketParserContext *parser_context)
1175 SilcClient client = (SilcClient)parser_context->context;
1176 SilcClientWindow win = (SilcClientWindow)parser_context->sock->user_data;
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, parser_context->sock->sock,
1185 silc_client_packet_parse_real,
1186 (void *)parser_context, 0, 1,
1188 SILC_TASK_PRI_NORMAL);
1190 /* Parse the packet with timeout */
1191 silc_task_register(client->timeout_queue, parser_context->sock->sock,
1192 silc_client_packet_parse_real,
1193 (void *)parser_context, 0, 200000,
1195 SILC_TASK_PRI_NORMAL);
1199 /* Parses the packet type and calls what ever routines the packet type
1200 requires. This is done for all incoming packets. */
1202 void silc_client_packet_parse_type(SilcClient client,
1203 SilcSocketConnection sock,
1204 SilcPacketContext *packet)
1206 SilcBuffer buffer = packet->buffer;
1207 SilcPacketType type = packet->type;
1209 SILC_LOG_DEBUG(("Parsing packet type %d", type));
1211 /* Parse the packet type */
1213 case SILC_PACKET_DISCONNECT:
1214 silc_client_disconnected_by_server(client, sock, buffer);
1216 case SILC_PACKET_SUCCESS:
1218 * Success received for something. For now we can have only
1219 * one protocol for connection executing at once hence this
1220 * success message is for whatever protocol is executing currently.
1222 if (sock->protocol) {
1223 sock->protocol->execute(client->timeout_queue, 0,
1224 sock->protocol, sock->sock, 0, 0);
1227 case SILC_PACKET_FAILURE:
1229 * Failure received for some protocol. Set the protocol state to
1230 * error and call the protocol callback. This fill cause error on
1231 * protocol and it will call the final callback.
1233 if (sock->protocol) {
1234 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
1235 sock->protocol->execute(client->timeout_queue, 0,
1236 sock->protocol, sock->sock, 0, 0);
1239 case SILC_PACKET_REJECT:
1242 case SILC_PACKET_NOTIFY:
1244 * Received notify message
1246 silc_client_notify_by_server(client, sock, buffer);
1249 case SILC_PACKET_ERROR:
1251 * Received error message
1253 silc_client_error_by_server(client, sock, buffer);
1256 case SILC_PACKET_CHANNEL_MESSAGE:
1258 * Received message to (from, actually) a channel
1260 silc_client_channel_message(client, sock, packet);
1262 case SILC_PACKET_CHANNEL_KEY:
1264 * Received key for a channel. By receiving this key the client will be
1265 * able to talk to the channel it has just joined. This can also be
1266 * a new key for existing channel as keys expire peridiocally.
1268 silc_client_receive_channel_key(client, sock, buffer);
1271 case SILC_PACKET_PRIVATE_MESSAGE:
1273 * Received private message
1276 SilcClientCommandReplyContext ctx;
1277 ctx = silc_calloc(1, sizeof(*ctx));
1278 ctx->client = client;
1280 ctx->context = buffer; /* kludge */
1281 silc_client_command_reply_msg((void *)ctx);
1284 case SILC_PACKET_PRIVATE_MESSAGE_KEY:
1286 * Received private message key
1290 case SILC_PACKET_COMMAND_REPLY:
1292 * Recived reply for a command
1294 silc_client_command_reply_process(client, sock, packet);
1297 case SILC_PACKET_KEY_EXCHANGE:
1298 if (sock->protocol) {
1299 SilcClientKEInternalContext *proto_ctx =
1300 (SilcClientKEInternalContext *)sock->protocol->context;
1302 proto_ctx->packet = buffer;
1303 proto_ctx->dest_id_type = packet->src_id_type;
1304 proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_type);
1306 /* Let the protocol handle the packet */
1307 sock->protocol->execute(client->timeout_queue, 0,
1308 sock->protocol, sock->sock, 0, 0);
1310 SILC_LOG_ERROR(("Received Key Exchange packet but no key exchange "
1311 "protocol active, packet dropped."));
1313 /* XXX Trigger KE protocol?? Rekey actually! */
1317 case SILC_PACKET_KEY_EXCHANGE_1:
1318 if (sock->protocol) {
1321 SILC_LOG_ERROR(("Received Key Exchange 1 packet but no key exchange "
1322 "protocol active, packet dropped."));
1325 case SILC_PACKET_KEY_EXCHANGE_2:
1326 if (sock->protocol) {
1327 SilcClientKEInternalContext *proto_ctx =
1328 (SilcClientKEInternalContext *)sock->protocol->context;
1330 if (proto_ctx->packet)
1331 silc_buffer_free(proto_ctx->packet);
1333 proto_ctx->packet = buffer;
1334 proto_ctx->dest_id_type = packet->src_id_type;
1335 proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_type);
1337 /* Let the protocol handle the packet */
1338 sock->protocol->execute(client->timeout_queue, 0,
1339 sock->protocol, sock->sock, 0, 0);
1341 SILC_LOG_ERROR(("Received Key Exchange 2 packet but no key exchange "
1342 "protocol active, packet dropped."));
1346 case SILC_PACKET_NEW_ID:
1349 * Received new ID from server. This packet is received at
1350 * the connection to the server. New ID is also received when
1351 * user changes nickname but in that case the new ID is received
1352 * as command reply and not as this packet type.
1354 unsigned char *id_string;
1355 unsigned short id_type;
1357 silc_buffer_unformat(buffer,
1358 SILC_STR_UI_SHORT(&id_type),
1359 SILC_STR_UI16_STRING_ALLOC(&id_string),
1362 if ((SilcIdType)id_type != SILC_ID_CLIENT)
1365 silc_client_receive_new_id(client, sock, id_string);
1366 silc_free(id_string);
1371 SILC_LOG_DEBUG(("Incorrect packet type %d, packet dropped", type));
1376 /* Sends packet. This doesn't actually send the packet instead it assembles
1377 it and marks it to be sent. However, if force_send is TRUE the packet
1378 is sent immediately. if dst_id, cipher and hmac are NULL those parameters
1379 will be derived from sock argument. Otherwise the valid arguments sent
1382 void silc_client_packet_send(SilcClient client,
1383 SilcSocketConnection sock,
1384 SilcPacketType type,
1386 SilcIdType dst_id_type,
1389 unsigned char *data,
1390 unsigned int data_len,
1393 SilcPacketContext packetdata;
1395 SILC_LOG_DEBUG(("Sending packet, type %d", type));
1397 /* Get data used in the packet sending, keys and stuff */
1398 if ((!cipher || !hmac || !dst_id) && sock->user_data) {
1399 if (!cipher && ((SilcClientWindow)sock->user_data)->send_key)
1400 cipher = ((SilcClientWindow)sock->user_data)->send_key;
1402 if (!hmac && ((SilcClientWindow)sock->user_data)->hmac)
1403 hmac = ((SilcClientWindow)sock->user_data)->hmac;
1405 if (!dst_id && ((SilcClientWindow)sock->user_data)->remote_id) {
1406 dst_id = ((SilcClientWindow)sock->user_data)->remote_id;
1407 dst_id_type = SILC_ID_SERVER;
1411 /* Set the packet context pointers */
1412 packetdata.flags = 0;
1413 packetdata.type = type;
1414 if (((SilcClientWindow)sock->user_data)->local_id_data)
1415 packetdata.src_id = ((SilcClientWindow)sock->user_data)->local_id_data;
1417 packetdata.src_id = silc_calloc(SILC_ID_CLIENT_LEN, sizeof(unsigned char));
1418 packetdata.src_id_len = SILC_ID_CLIENT_LEN;
1419 packetdata.src_id_type = SILC_ID_CLIENT;
1421 packetdata.dst_id = silc_id_id2str(dst_id, dst_id_type);
1422 packetdata.dst_id_len = silc_id_get_len(dst_id_type);
1423 packetdata.dst_id_type = dst_id_type;
1425 packetdata.dst_id = NULL;
1426 packetdata.dst_id_len = 0;
1427 packetdata.dst_id_type = SILC_ID_NONE;
1429 packetdata.rng = client->rng;
1430 packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN +
1431 packetdata.src_id_len + packetdata.dst_id_len;
1432 packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen);
1434 /* Prepare outgoing data buffer for packet sending */
1435 silc_packet_send_prepare(sock,
1436 SILC_PACKET_HEADER_LEN +
1437 packetdata.src_id_len +
1438 packetdata.dst_id_len,
1442 SILC_LOG_DEBUG(("Putting data to outgoing buffer, len %d", data_len));
1444 packetdata.buffer = sock->outbuf;
1446 /* Put the data to the buffer */
1447 if (data && data_len)
1448 silc_buffer_put(sock->outbuf, data, data_len);
1450 /* Create the outgoing packet */
1451 silc_packet_assemble(&packetdata);
1453 /* Encrypt the packet */
1455 silc_packet_encrypt(cipher, hmac, sock->outbuf, sock->outbuf->len);
1457 SILC_LOG_HEXDUMP(("Packet, len %d", sock->outbuf->len),
1458 sock->outbuf->data, sock->outbuf->len);
1460 /* Now actually send the packet */
1461 silc_client_packet_send_real(client, sock, force_send);
1464 /* Sends packet to a channel. Packet to channel is always encrypted
1465 differently from "normal" packets. SILC header of the packet is
1466 encrypted with the next receiver's key and the rest of the packet is
1467 encrypted with the channel specific key. Padding and HMAC is computed
1468 with the next receiver's key. */
1470 void silc_client_packet_send_to_channel(SilcClient client,
1471 SilcSocketConnection sock,
1472 SilcChannelEntry channel,
1473 unsigned char *data,
1474 unsigned int data_len,
1478 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1480 SilcPacketContext packetdata;
1483 unsigned char *id_string;
1485 SILC_LOG_DEBUG(("Sending packet to channel"));
1487 if (!channel || !channel->key) {
1488 silc_say(client, "Cannot talk to channel: key does not exist");
1494 for (i = 0; i < 16; i++)
1495 channel->iv[i] = silc_rng_get_byte(client->rng);
1497 silc_hash_make(client->md5hash, channel->iv, 16, channel->iv);
1499 /* Encode the channel payload */
1500 payload = silc_channel_encode_payload(strlen(win->nickname), win->nickname,
1501 data_len, data, 16, channel->iv,
1505 "Error: Could not create packet to be sent to the channel");
1509 /* Get data used in packet header encryption, keys and stuff. Rest
1510 of the packet (the payload) is, however, encrypted with the
1511 specified channel key. */
1512 cipher = win->send_key;
1514 id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
1516 /* Set the packet context pointers. The destination ID is always
1517 the Channel ID of the channel. Server and router will handle the
1518 distribution of the packet. */
1519 packetdata.flags = 0;
1520 packetdata.type = SILC_PACKET_CHANNEL_MESSAGE;
1521 packetdata.src_id = win->local_id_data;
1522 packetdata.src_id_len = SILC_ID_CLIENT_LEN;
1523 packetdata.src_id_type = SILC_ID_CLIENT;
1524 packetdata.dst_id = id_string;
1525 packetdata.dst_id_len = SILC_ID_CHANNEL_LEN;
1526 packetdata.dst_id_type = SILC_ID_CHANNEL;
1527 packetdata.rng = client->rng;
1528 packetdata.truelen = payload->len + SILC_PACKET_HEADER_LEN +
1529 packetdata.src_id_len + packetdata.dst_id_len;
1530 packetdata.padlen = SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
1531 packetdata.src_id_len +
1532 packetdata.dst_id_len));
1534 /* Prepare outgoing data buffer for packet sending */
1535 silc_packet_send_prepare(sock,
1536 SILC_PACKET_HEADER_LEN +
1537 packetdata.src_id_len +
1538 packetdata.dst_id_len,
1542 packetdata.buffer = sock->outbuf;
1544 /* Encrypt payload of the packet. This is encrypted with the channel key. */
1545 channel->channel_key->cipher->encrypt(channel->channel_key->context,
1546 payload->data, payload->data,
1547 payload->len - 16, /* -IV_LEN */
1550 /* Put the actual encrypted payload data into the buffer. */
1551 silc_buffer_put(sock->outbuf, payload->data, payload->len);
1553 /* Create the outgoing packet */
1554 silc_packet_assemble(&packetdata);
1556 /* Encrypt the header and padding of the packet. This is encrypted
1557 with normal session key shared with our server. */
1558 silc_packet_encrypt(cipher, hmac, sock->outbuf, SILC_PACKET_HEADER_LEN +
1559 packetdata.src_id_len + packetdata.dst_id_len +
1562 SILC_LOG_HEXDUMP(("Packet to channel, len %d", sock->outbuf->len),
1563 sock->outbuf->data, sock->outbuf->len);
1565 /* Now actually send the packet */
1566 silc_client_packet_send_real(client, sock, force_send);
1567 silc_buffer_free(payload);
1568 silc_free(id_string);
1571 /* Sends private message to remote client. If private message key has
1572 not been set with this client then the message will be encrypted using
1573 normal session keys. Private messages are special packets in SILC
1574 network hence we need this own function for them. This is similiar
1575 to silc_client_packet_send_to_channel except that we send private
1578 void silc_client_packet_send_private_message(SilcClient client,
1579 SilcSocketConnection sock,
1580 SilcClientEntry client_entry,
1581 unsigned char *data,
1582 unsigned int data_len,
1585 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1587 SilcPacketContext packetdata;
1588 unsigned int nick_len;
1592 SILC_LOG_DEBUG(("Sending private message"));
1594 /* Create private message payload */
1595 nick_len = strlen(client->current_win->nickname);
1596 buffer = silc_buffer_alloc(2 + nick_len + data_len);
1597 silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer));
1598 silc_buffer_format(buffer,
1599 SILC_STR_UI_SHORT(nick_len),
1600 SILC_STR_UI_XNSTRING(client->current_win->nickname,
1602 SILC_STR_UI_XNSTRING(data, data_len),
1605 /* If we don't have private message specific key then private messages
1606 are just as any normal packet thus call normal packet sending. If
1607 the key exist then the encryption process is a bit different and
1608 will be done in the rest of this function. */
1609 if (!client_entry->send_key) {
1610 silc_client_packet_send(client, sock, SILC_PACKET_PRIVATE_MESSAGE,
1611 client_entry->id, SILC_ID_CLIENT, NULL, NULL,
1612 buffer->data, buffer->len, force_send);
1616 /* We have private message specific key */
1618 /* Get data used in the encryption */
1619 cipher = client_entry->send_key;
1622 /* Set the packet context pointers. */
1623 packetdata.flags = 0;
1624 packetdata.type = SILC_PACKET_PRIVATE_MESSAGE;
1625 packetdata.src_id = win->local_id_data;
1626 packetdata.src_id_len = SILC_ID_CLIENT_LEN;
1627 packetdata.src_id_type = SILC_ID_CLIENT;
1629 packetdata.dst_id = silc_id_id2str(client_entry->id, SILC_ID_CLIENT);
1631 packetdata.dst_id = win->local_id_data;
1632 packetdata.dst_id_len = SILC_ID_CLIENT_LEN;
1633 packetdata.dst_id_type = SILC_ID_CLIENT;
1634 packetdata.rng = client->rng;
1635 packetdata.truelen = buffer->len + SILC_PACKET_HEADER_LEN +
1636 packetdata.src_id_len + packetdata.dst_id_len;
1637 packetdata.padlen = SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
1638 packetdata.src_id_len +
1639 packetdata.dst_id_len));
1641 /* Prepare outgoing data buffer for packet sending */
1642 silc_packet_send_prepare(sock,
1643 SILC_PACKET_HEADER_LEN +
1644 packetdata.src_id_len +
1645 packetdata.dst_id_len,
1649 packetdata.buffer = sock->outbuf;
1651 /* Encrypt payload of the packet. Encrypt with private message specific
1652 key if it exist, otherwise with session key. */
1653 cipher->cipher->encrypt(cipher->context, buffer->data, buffer->data,
1654 buffer->len, cipher->iv);
1656 /* Put the actual encrypted payload data into the buffer. */
1657 silc_buffer_put(sock->outbuf, buffer->data, buffer->len);
1659 /* Create the outgoing packet */
1660 silc_packet_assemble(&packetdata);
1662 /* Encrypt the header and padding of the packet. */
1663 silc_packet_encrypt(cipher, hmac, sock->outbuf, SILC_PACKET_HEADER_LEN +
1664 packetdata.src_id_len + packetdata.dst_id_len +
1667 SILC_LOG_HEXDUMP(("Private message packet, len %d", sock->outbuf->len),
1668 sock->outbuf->data, sock->outbuf->len);
1670 /* Now actually send the packet */
1671 silc_client_packet_send_real(client, sock, force_send);
1672 silc_free(packetdata.dst_id);
1678 /* Closes connection to remote end. Free's all allocated data except
1679 for some information such as nickname etc. that are valid at all time. */
1681 void silc_client_close_connection(SilcClient client,
1682 SilcSocketConnection sock)
1684 SilcClientWindow win;
1686 /* We won't listen for this connection anymore */
1687 silc_schedule_unset_listen_fd(sock->sock);
1689 /* Unregister all tasks */
1690 silc_task_unregister_by_fd(client->io_queue, sock->sock);
1691 silc_task_unregister_by_fd(client->timeout_queue, sock->sock);
1693 /* Close the actual connection */
1694 silc_net_close_connection(sock->sock);
1696 silc_say(client, "Closed connection to host %s", sock->hostname ?
1697 sock->hostname : sock->ip);
1699 /* Free everything */
1700 if (sock->user_data) {
1701 win = (SilcClientWindow)sock->user_data;
1703 /* XXX Free all client entries and channel entries. */
1705 /* Clear ID caches */
1706 silc_idcache_del_all(win->client_cache);
1707 silc_idcache_del_all(win->channel_cache);
1710 if (win->remote_host)
1711 silc_free(win->remote_host);
1713 silc_free(win->local_id);
1714 if (win->local_id_data)
1715 silc_free(win->local_id_data);
1717 silc_cipher_free(win->send_key);
1718 if (win->receive_key)
1719 silc_cipher_free(win->receive_key);
1721 silc_hmac_free(win->hmac);
1722 if (win->hmac_key) {
1723 memset(win->hmac_key, 0, win->hmac_key_len);
1724 silc_free(win->hmac_key);
1728 win->remote_port = 0;
1729 win->remote_type = 0;
1730 win->send_key = NULL;
1731 win->receive_key = NULL;
1733 win->hmac_key = NULL;
1734 win->hmac_key_len = 0;
1735 win->local_id = NULL;
1736 win->local_id_data = NULL;
1737 win->remote_host = NULL;
1738 win->current_channel = NULL;
1741 if (sock->protocol) {
1742 silc_protocol_free(sock->protocol);
1743 sock->protocol = NULL;
1745 silc_socket_free(sock);
1748 /* Called when we receive disconnection packet from server. This
1749 closes our end properly and displays the reason of the disconnection
1752 void silc_client_disconnected_by_server(SilcClient client,
1753 SilcSocketConnection sock,
1758 SILC_LOG_DEBUG(("Server disconnected us, sock %d", sock->sock));
1760 msg = silc_calloc(message->len + 1, sizeof(char));
1761 memcpy(msg, message->data, message->len);
1762 silc_say(client, msg);
1765 SILC_SET_DISCONNECTED(sock);
1766 silc_client_close_connection(client, sock);
1769 /* Received error message from server. Display it on the screen.
1770 We don't take any action what so ever of the error message. */
1772 void silc_client_error_by_server(SilcClient client,
1773 SilcSocketConnection sock,
1778 msg = silc_calloc(message->len + 1, sizeof(char));
1779 memcpy(msg, message->data, message->len);
1780 silc_say(client, msg);
1784 /* Received notify message from server */
1786 void silc_client_notify_by_server(SilcClient client,
1787 SilcSocketConnection sock,
1792 msg = silc_calloc(message->len + 1, sizeof(char));
1793 memcpy(msg, message->data, message->len);
1794 silc_say(client, msg);
1798 /* Processes the received new Client ID from server. Old Client ID is
1799 deleted from cache and new one is added. */
1801 void silc_client_receive_new_id(SilcClient client,
1802 SilcSocketConnection sock,
1803 unsigned char *id_string)
1805 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1807 /* Delete old ID from ID cache */
1808 silc_idcache_del_by_id(win->client_cache, SILC_ID_CLIENT, win->local_id);
1810 /* Save the new ID */
1812 silc_free(win->local_id);
1813 win->local_id = silc_id_str2id(id_string, SILC_ID_CLIENT);
1814 if (win->local_id_data)
1815 silc_free(win->local_id_data);
1816 win->local_id_data =
1817 silc_calloc(SILC_ID_CLIENT_LEN, sizeof(unsigned char));
1818 memcpy(win->local_id_data, id_string, SILC_ID_CLIENT_LEN);
1819 win->local_id_data_len = SILC_ID_CLIENT_LEN;
1820 if (!win->local_entry)
1821 win->local_entry = silc_calloc(1, sizeof(*win->local_entry));
1822 win->local_entry->nickname = win->nickname;
1823 win->local_entry->id = win->local_id;
1825 /* Put it to the ID cache */
1826 silc_idcache_add(win->client_cache, win->nickname, SILC_ID_CLIENT,
1827 win->local_id, (void *)win->local_entry, TRUE);
1830 /* Processed received Channel ID for a channel. This is called when client
1831 joins to channel and server replies with channel ID. The ID is cached. */
1833 void silc_client_new_channel_id(SilcClient client,
1834 SilcSocketConnection sock,
1837 unsigned char *id_string)
1839 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1841 SilcChannelEntry channel;
1843 SILC_LOG_DEBUG(("New channel ID"));
1845 id = silc_id_str2id(id_string, SILC_ID_CHANNEL);
1846 channel = silc_calloc(1, sizeof(*channel));
1847 channel->channel_name = channel_name;
1849 channel->mode = mode;
1850 win->current_channel = channel;
1852 /* Put it to the ID cache */
1853 silc_idcache_add(win->channel_cache, channel_name, SILC_ID_CHANNEL,
1854 (void *)id, (void *)channel, TRUE);
1857 /* Processes received key for channel. The received key will be used
1858 to protect the traffic on the channel for now on. Client must receive
1859 the key to the channel before talking on the channel is possible.
1860 This is the key that server has generated, this is not the channel
1861 private key, it is entirely local setting. */
1863 void silc_client_receive_channel_key(SilcClient client,
1864 SilcSocketConnection sock,
1867 unsigned char *id_string, *key, *cipher;
1868 unsigned int key_len;
1869 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1871 SilcIDCacheEntry id_cache = NULL;
1872 SilcChannelEntry channel;
1873 SilcChannelKeyPayload payload;
1875 SILC_LOG_DEBUG(("Received key for channel"));
1877 payload = silc_channel_key_parse_payload(packet);
1881 id_string = silc_channel_key_get_id(payload, NULL);
1883 silc_channel_key_free_payload(payload);
1886 id = silc_id_str2id(id_string, SILC_ID_CHANNEL);
1889 if (!silc_idcache_find_by_id_one(win->channel_cache, (void *)id,
1890 SILC_ID_CHANNEL, &id_cache))
1894 key = silc_channel_key_get_key(payload, &key_len);
1895 cipher = silc_channel_key_get_cipher(payload, NULL);
1897 channel = (SilcChannelEntry)id_cache->context;
1898 channel->key_len = key_len;
1899 channel->key = silc_calloc(key_len, sizeof(*channel->key));
1900 memcpy(channel->key, key, key_len);
1902 silc_cipher_alloc(cipher, &channel->channel_key);
1903 if (!channel->channel_key) {
1904 silc_say(client, "Cannot talk to channel: unsupported cipher %s", cipher);
1907 channel->channel_key->cipher->set_key(channel->channel_key->context,
1910 /* Client is now joined to the channel */
1911 channel->on_channel = TRUE;
1915 silc_channel_key_free_payload(payload);
1918 /* Process received message to a channel (or from a channel, really). This
1919 decrypts the channel message with channel specific key and parses the
1920 channel payload. Finally it displays the message on the screen. */
1922 void silc_client_channel_message(SilcClient client,
1923 SilcSocketConnection sock,
1924 SilcPacketContext *packet)
1926 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1927 SilcBuffer buffer = packet->buffer;
1928 SilcChannelPayload payload = NULL;
1929 SilcChannelID *id = NULL;
1930 SilcChannelEntry channel;
1931 SilcIDCacheEntry id_cache = NULL;
1934 if (packet->dst_id_type != SILC_ID_CHANNEL)
1937 id = silc_id_str2id(packet->dst_id, SILC_ID_CHANNEL);
1939 /* Find the channel entry from channels on this window */
1940 if (!silc_idcache_find_by_id_one(win->channel_cache, (void *)id,
1941 SILC_ID_CHANNEL, &id_cache))
1944 channel = (SilcChannelEntry)id_cache->context;
1946 /* Decrypt the channel message payload. Push the IV out of the way,
1947 since it is not encrypted (after pushing buffer->tail has the IV). */
1948 silc_buffer_push_tail(buffer, 16);
1949 channel->channel_key->cipher->decrypt(channel->channel_key->context,
1950 buffer->data, buffer->data,
1951 buffer->len, buffer->tail);
1952 silc_buffer_pull_tail(buffer, 16);
1954 /* Parse the channel message payload */
1955 payload = silc_channel_parse_payload(buffer);
1959 /* Display the message on screen */
1960 if (packet->src_id_type == SILC_ID_CLIENT) {
1961 /* Message from client */
1962 if (channel == win->current_channel)
1963 silc_print(client, "<%s> %s",
1964 silc_channel_get_nickname(payload, NULL),
1965 silc_channel_get_data(payload, NULL));
1967 silc_print(client, "<%s:%s> %s",
1968 silc_channel_get_nickname(payload, NULL),
1969 channel->channel_name,
1970 silc_channel_get_data(payload, NULL));
1972 /* Message from server */
1973 silc_say(client, "%s", silc_channel_get_data(payload, NULL));
1980 silc_channel_free_payload(payload);