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.1 2000/06/27 11:36:56 priikone
29 #include "clientincludes.h"
31 /* Static function prototypes */
32 static int silc_client_bad_keys(unsigned char key);
33 static void silc_client_process_message(SilcClient client);
34 static char *silc_client_parse_command(unsigned char *buffer);
36 /* Static task callback prototypes */
37 SILC_TASK_CALLBACK(silc_client_update_clock);
38 SILC_TASK_CALLBACK(silc_client_run_commands);
39 SILC_TASK_CALLBACK(silc_client_process_key_press);
40 SILC_TASK_CALLBACK(silc_client_connect_to_server_start);
41 SILC_TASK_CALLBACK(silc_client_connect_to_server_second);
42 SILC_TASK_CALLBACK(silc_client_connect_to_server_final);
43 SILC_TASK_CALLBACK(silc_client_packet_process);
44 SILC_TASK_CALLBACK(silc_client_packet_parse);
46 SilcClientWindow silc_client_create_main_window(SilcClient client);
47 SilcClientWindow silc_client_add_window(SilcClient client,
49 void silc_client_packet_parse_type(SilcClient client,
50 SilcSocketConnection sock,
51 SilcPacketContext *packet);
52 void silc_client_private_message_process(SilcClient client,
53 SilcSocketConnection sock,
54 SilcPacketContext *packet);
56 /* Definitions from version.h */
57 extern char *silc_version;
58 extern char *silc_name;
59 extern char *silc_fullname;
61 /* Allocates new client object. This has to be done before client may
62 work. After calling this one must call silc_client_init to initialize
65 int silc_client_alloc(SilcClient *new_client)
68 *new_client = silc_calloc(1, sizeof(**new_client));
69 if (*new_client == NULL) {
70 SILC_LOG_ERROR(("Could not allocate new client object"));
74 (*new_client)->input_buffer = NULL;
75 (*new_client)->screen = NULL;
76 (*new_client)->windows = NULL;
77 (*new_client)->windows_count = 0;
78 (*new_client)->current_win = NULL;
83 /* Free's client object */
85 void silc_client_free(SilcClient client)
92 /* Initializes the client. This makes all the necessary steps to make
93 the client ready to be run. One must call silc_client_run to run the
96 int silc_client_init(SilcClient client)
99 SILC_LOG_DEBUG(("Initializing client"));
102 client->username = silc_get_username();
103 client->realname = silc_get_real_name();
105 /* Register all configured ciphers, PKCS and hash functions. */
106 client->config->client = (void *)client;
107 silc_client_config_register_ciphers(client->config);
108 silc_client_config_register_pkcs(client->config);
109 silc_client_config_register_hashfuncs(client->config);
111 /* Initialize hash functions for client to use */
112 silc_hash_alloc("md5", &client->md5hash);
113 silc_hash_alloc("sha1", &client->sha1hash);
115 /* Initialize none cipher */
116 silc_cipher_alloc("none", &client->none_cipher);
118 /* Initialize random number generator */
119 client->rng = silc_rng_alloc();
120 silc_rng_init(client->rng);
121 silc_math_primegen_init(); /* XXX */
126 unsigned char *src, *dst, *dec;
130 payload_len = 4 + strlen("pekka riikonen");
131 packet = silc_buffer_alloc(payload_len);
132 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
133 silc_buffer_format(packet,
134 SILC_STR_UI_SHORT(payload_len),
135 SILC_STR_UI_SHORT(SILC_SOCKET_TYPE_CLIENT),
136 SILC_STR_UI_XNSTRING("pekka riikonen",
137 strlen("pekka riikonen")),
140 silc_cipher_alloc("twofish", &twofish);
141 twofish->cipher->set_key(twofish->context, "1234567890123456", 16);
142 twofish->set_iv(twofish, "6543210987654321");
143 SILC_LOG_HEXDUMP(("source: len %d", packet->len),
144 packet->data, packet->len );
145 silc_packet_encrypt(twofish, packet, packet->len);
146 SILC_LOG_HEXDUMP(("encrypted"), packet->data, packet->len);
147 silc_packet_decrypt(twofish, packet, packet->len);
148 SILC_LOG_HEXDUMP(("decrypted"), packet->data, packet->len);
153 SilcCipher cipher1, cipher2;
154 unsigned char *src, *dst, *dec;
155 int len = strlen("12345678901234561234567890123456123456789012345612345678901234561234567890123456");
157 src = silc_calloc(len + 1, sizeof(unsigned char));
158 dst = silc_calloc(len + 1, sizeof(unsigned char));
159 dec = silc_calloc(len + 1, sizeof(unsigned char));
161 memcpy(src, "12345678901234561234567890123456123456789012345612345678901234561234567890123456", len);
163 silc_cipher_alloc("twofish", &cipher1);
164 cipher1->cipher->set_key(cipher1->context, "1234567890123456", 128);
165 cipher1->set_iv(cipher1, "6543210987654321");
167 silc_cipher_alloc("twofish", &cipher2);
168 cipher2->cipher->set_key(cipher2->context, "1234567890123456", 128);
169 cipher2->set_iv(cipher2, "6543210987654321");
171 SILC_LOG_HEXDUMP(("source: %d", len), src, len);
172 cipher1->cipher->encrypt(cipher1->context, src, src, len, cipher1->iv);
173 SILC_LOG_HEXDUMP(("encrypted"), src, len);
174 cipher2->set_iv(cipher2, "6543210987654321");
175 cipher2->cipher->decrypt(cipher2->context, src, src, len, cipher2->iv);
176 SILC_LOG_HEXDUMP(("decrypted"), src, len);
181 /* Register the task queues. In SILC we have by default three task queues.
182 One task queue for non-timeout tasks which perform different kind of
183 I/O on file descriptors, timeout task queue for timeout tasks, and,
184 generic non-timeout task queue whose tasks apply to all connections. */
185 silc_task_queue_alloc(&client->io_queue, TRUE);
186 if (!client->io_queue) {
189 silc_task_queue_alloc(&client->timeout_queue, TRUE);
190 if (!client->timeout_queue) {
193 silc_task_queue_alloc(&client->generic_queue, TRUE);
194 if (!client->generic_queue) {
198 /* Initialize the scheduler */
199 silc_schedule_init(client->io_queue, client->timeout_queue,
200 client->generic_queue, 5000);
202 /* Register the main task that is used in client. This received
203 the key pressings. */
204 if (silc_task_register(client->io_queue, fileno(stdin),
205 silc_client_process_key_press,
206 (void *)client, 0, 0,
208 SILC_TASK_PRI_NORMAL) == NULL) {
212 /* Register timeout task that updates clock every minute. */
213 if (silc_task_register(client->timeout_queue, 0,
214 silc_client_update_clock,
216 silc_client_time_til_next_min(), 0,
218 SILC_TASK_PRI_LOW) == NULL) {
222 if (client->config->commands) {
223 /* Run user configured commands with timeout */
224 if (silc_task_register(client->timeout_queue, 0,
225 silc_client_run_commands,
226 (void *)client, 0, 1,
228 SILC_TASK_PRI_LOW) == NULL) {
233 /* Allocate the input buffer used to save typed characters */
234 client->input_buffer = silc_buffer_alloc(SILC_SCREEN_INPUT_WIN_SIZE);
235 silc_buffer_pull_tail(client->input_buffer,
236 SILC_BUFFER_END(client->input_buffer));
238 /* Initialize the screen */
239 client->screen = silc_screen_init();
240 silc_client_create_main_window(client);
241 client->screen->input_buffer = client->input_buffer->data;
242 silc_screen_print_coordinates(client->screen, 0);
247 silc_task_queue_free(client->timeout_queue);
249 silc_task_queue_free(client->io_queue);
254 /* Stops the client. This is called to stop the client and thus to stop
257 void silc_client_stop(SilcClient client)
259 SILC_LOG_DEBUG(("Stopping client"));
261 /* Stop the scheduler, although it might be already stopped. This
262 doesn't hurt anyone. This removes all the tasks and task queues,
264 silc_schedule_stop();
265 silc_schedule_uninit();
267 SILC_LOG_DEBUG(("Client client"));
270 /* Runs the client. */
272 void silc_client_run(SilcClient client)
274 SILC_LOG_DEBUG(("Running client"));
276 /* Start the scheduler, the heart of the SILC client. When this returns
277 the program will be terminated. */
281 /* Creates the main window used in SILC client. This is called always
282 at the initialization of the client. If user wants to create more
283 than one windows a new windows are always created by calling
284 silc_client_add_window. */
286 SilcClientWindow silc_client_create_main_window(SilcClient client)
288 SilcClientWindow win;
291 SILC_LOG_DEBUG(("Creating main window"));
293 assert(client->screen != NULL);
295 win = silc_calloc(1, sizeof(*win));
297 SILC_LOG_ERROR(("Could not allocate new window"));
301 client->screen->u_stat_line.program_name = silc_name;
302 client->screen->u_stat_line.program_version = silc_version;
304 /* Add the pointers */
305 win->nickname = silc_get_username();
306 win->local_id = NULL;
307 win->local_id_data = NULL;
308 win->local_id_data_len = 0;
309 win->remote_host = NULL;
310 win->remote_port = -1;
313 /* Create the actual screen */
314 screen = (void *)silc_screen_create_output_window(client->screen);
315 silc_screen_create_input_window(client->screen);
316 silc_screen_init_upper_status_line(client->screen);
317 silc_screen_init_output_status_line(client->screen);
318 win->screen = screen;
320 client->screen->bottom_line->nickname = win->nickname;
321 silc_screen_print_bottom_line(client->screen, 0);
323 /* Add the window to windows table */
324 client->windows = silc_calloc(1, sizeof(*client->windows));
325 client->windows[client->windows_count] = win;
326 client->windows_count = 1;
328 /* Automatically becomes the current active window */
329 client->current_win = win;
334 /* Allocates and adds new window to the client. This allocates new
335 physical window and internal window for connection specific data.
336 All the connection specific data is always saved into a window
337 since connection is always associated to a active window. */
339 SilcClientWindow silc_client_add_window(SilcClient client,
342 SilcClientWindow win;
344 assert(client->screen != NULL);
346 win = silc_calloc(1, sizeof(*win));
348 SILC_LOG_ERROR(("Could not allocate new window"));
352 /* Add the pointers */
353 win->screen = silc_screen_add_output_window(client->screen);
356 /* Add the window to windows table */
357 client->windows = silc_realloc(client->windows, sizeof(*client->windows)
358 * (client->windows_count + 1));
359 client->windows[client->windows_count] = win;
360 client->windows_count++;
362 if (is_current == TRUE)
363 client->current_win = win;
368 /* The main task on SILC client. This processes the key pressings user
371 SILC_TASK_CALLBACK(silc_client_process_key_press)
373 SilcClient client = (SilcClient)context;
376 /* There is data pending in stdin, this gets it directly */
377 c = wgetch(client->screen->input_win);
378 if (silc_client_bad_keys(c))
381 SILC_LOG_DEBUG(("Pressed key: %d", c));
385 * Special character handling
392 SILC_LOG_DEBUG(("RIGHT"));
393 silc_screen_input_cursor_right(client->screen);
397 SILC_LOG_DEBUG(("LEFT"));
398 silc_screen_input_cursor_left(client->screen);
405 silc_screen_input_backspace(client->screen);
411 /* Insert switch. Turns on/off insert on input window */
412 silc_screen_input_insert(client->screen);
416 /* Enter, Return. User pressed enter we are ready to
417 process the message. */
418 silc_client_process_message(client);
419 silc_screen_input_reset(client->screen);
422 /* Refresh screen, Ctrl^l */
423 silc_screen_refresh_all(client->screen);
428 /* Beginning, Home */
429 silc_screen_input_cursor_home(client->screen);
434 silc_screen_input_cursor_end(client->screen);
452 /* Control codes are printed as reversed */
454 wattron(client->screen->input_win, A_REVERSE);
455 silc_screen_input_print(client->screen, c);
456 wattroff(client->screen->input_win, A_REVERSE);
458 /* Normal character */
459 silc_screen_input_print(client->screen, c);
463 silc_screen_print_coordinates(client->screen, 0);
464 silc_screen_refresh_win(client->screen->input_win);
467 static int silc_client_bad_keys(unsigned char key)
469 /* these are explained in curses.h */
484 case '\E': /* we ignore ESC */
491 /* Processes messages user has typed on the screen. This either sends
492 a packet out to network or if command were written executes it. */
494 static void silc_client_process_message(SilcClient client)
499 SILC_LOG_DEBUG(("Start"));
501 data = client->input_buffer->data;
504 if (data[0] == '/' && data[1] != ' ') {
506 unsigned int argc = 0;
507 unsigned char **argv, *tmpcmd;
508 unsigned int *argv_lens, *argv_types;
509 SilcClientCommand *cmd;
510 SilcClientCommandContext ctx;
512 /* Get the command */
513 tmpcmd = silc_client_parse_command(data);
515 /* Find command match */
516 for (cmd = silc_command_list; cmd->name; cmd++) {
517 if (!strcmp(cmd->name, tmpcmd))
521 if (cmd->name == NULL) {
522 silc_say(client, "Invalid command: %s", tmpcmd);
527 /* Now parse all arguments */
528 silc_client_parse_command_line(data, &argv, &argv_lens,
529 &argv_types, &argc, cmd->max_args);
532 SILC_LOG_DEBUG(("Exeuting command: %s", cmd->name));
534 /* Allocate command context. This and its internals must be free'd
535 by the command routine receiving it. */
536 ctx = silc_calloc(1, sizeof(*ctx));
537 ctx->client = client;
538 ctx->sock = client->current_win->sock;
541 ctx->argv_lens = argv_lens;
542 ctx->argv_types = argv_types;
544 /* Execute command */
548 /* Normal message to a channel */
549 if (len && client->current_win->current_channel &&
550 client->current_win->current_channel->on_channel == TRUE) {
551 silc_print(client, "> %s", data);
552 silc_client_packet_send_to_channel(client,
553 client->current_win->sock,
554 client->current_win->current_channel,
555 data, strlen(data), TRUE);
560 /* Clear the input buffer */
561 silc_buffer_clear(client->input_buffer);
562 silc_buffer_pull_tail(client->input_buffer,
563 SILC_BUFFER_END(client->input_buffer));
566 /* Returns the command fetched from user typed command line */
568 static char *silc_client_parse_command(unsigned char *buffer)
571 const char *cp = buffer;
574 len = strcspn(cp, " ");
575 ret = silc_to_upper((char *)++cp);
581 /* Parses user typed command line. At most `max_args' is taken. Rest
582 of the line will be allocated as the last argument if there are more
583 than `max_args' arguments in the line. Note that the command name
584 is counted as one argument and is saved. */
586 void silc_client_parse_command_line(unsigned char *buffer,
587 unsigned char ***parsed,
588 unsigned int **parsed_lens,
589 unsigned int **parsed_types,
590 unsigned int *parsed_num,
591 unsigned int max_args)
595 const char *cp = buffer;
597 /* Take the '/' away */
600 *parsed = silc_calloc(1, sizeof(**parsed));
601 *parsed_lens = silc_calloc(1, sizeof(**parsed_lens));
603 /* Get the command first */
604 len = strcspn(cp, " ");
605 (*parsed)[0] = silc_to_upper((char *)cp);
606 (*parsed_lens)[0] = len;
610 /* Parse arguments */
611 if (strchr(cp, ' ') || strlen(cp) != 0) {
612 for (i = 1; i < max_args; i++) {
614 if (i != max_args - 1)
615 len = strcspn(cp, " ");
619 *parsed = silc_realloc(*parsed, sizeof(**parsed) * (argc + 1));
620 *parsed_lens = silc_realloc(*parsed_lens,
621 sizeof(**parsed_lens) * (argc + 1));
622 (*parsed)[argc] = silc_calloc(len + 1, sizeof(char));
623 memcpy((*parsed)[argc], cp, len);
624 (*parsed_lens)[argc] = len;
635 /* Save argument types. Protocol defines all argument types but
636 this implementation makes sure that they are always in correct
637 order hence this simple code. */
638 *parsed_types = silc_calloc(argc, sizeof(**parsed_types));
639 for (i = 0; i < argc; i++)
640 (*parsed_types)[i] = i;
645 /* Updates clock on the screen every minute. */
647 SILC_TASK_CALLBACK(silc_client_update_clock)
649 SilcClient client = (SilcClient)context;
651 /* Update the clock on the screen */
652 silc_screen_print_clock(client->screen);
654 /* Re-register this same task */
655 silc_task_register(qptr, 0, silc_client_update_clock, context,
656 silc_client_time_til_next_min(), 0,
660 silc_screen_refresh_win(client->screen->input_win);
663 /* Runs commands user configured in configuration file. This is
664 called when initializing client. */
666 SILC_TASK_CALLBACK(silc_client_run_commands)
668 SilcClient client = (SilcClient)context;
669 SilcClientConfigSectionCommand *cs;
671 SILC_LOG_DEBUG(("Start"));
673 cs = client->config->commands;
675 unsigned int argc = 0;
676 unsigned char **argv, *tmpcmd;
677 unsigned int *argv_lens, *argv_types;
678 SilcClientCommand *cmd;
679 SilcClientCommandContext ctx;
681 /* Get the command */
682 tmpcmd = silc_client_parse_command(cs->command);
684 for (cmd = silc_command_list; cmd->name; cmd++) {
685 if (!strcmp(cmd->name, tmpcmd))
689 if (cmd->name == NULL) {
690 silc_say(client, "Invalid command: %s", tmpcmd);
695 /* Now parse all arguments */
696 silc_client_parse_command_line(cs->command, &argv, &argv_lens,
697 &argv_types, &argc, cmd->max_args);
700 SILC_LOG_DEBUG(("Exeuting command: %s", cmd->name));
702 /* Allocate command context. This and its internals must be free'd
703 by the command routine receiving it. */
704 ctx = silc_calloc(1, sizeof(*ctx));
705 ctx->client = client;
706 ctx->sock = client->current_win->sock;
709 ctx->argv_lens = argv_lens;
710 ctx->argv_types = argv_types;
712 /* Execute command */
719 /* Internal context for connection process. This is needed as we
720 doing asynchronous connecting. */
728 } SilcClientInternalConnectContext;
731 silc_client_connect_to_server_internal(SilcClientInternalConnectContext *ctx)
735 /* XXX In the future we should give up this non-blocking connect all
736 together and use threads instead. */
737 /* Create connection to server asynchronously */
738 sock = silc_net_create_connection_async(ctx->port, ctx->host);
742 /* Register task that will receive the async connect and will
744 ctx->task = silc_task_register(ctx->client->io_queue, sock,
745 silc_client_connect_to_server_start,
748 SILC_TASK_PRI_NORMAL);
749 silc_task_reset_iotype(ctx->task, SILC_TASK_WRITE);
750 silc_schedule_set_listen_fd(sock, ctx->task->iomask);
757 /* Connects to remote server */
759 int silc_client_connect_to_server(SilcClient client, int port,
762 SilcClientInternalConnectContext *ctx;
764 SILC_LOG_DEBUG(("Connecting to port %d of server %s",
767 silc_say(client, "Connecting to port %d of server %s", port, host);
769 client->current_win->remote_host = strdup(host);
770 client->current_win->remote_port = port;
772 /* Allocate internal context for connection process. This is
773 needed as we are doing async connecting. */
774 ctx = silc_calloc(1, sizeof(*ctx));
775 ctx->client = client;
776 ctx->host = strdup(host);
780 /* Do the actual connecting process */
781 return silc_client_connect_to_server_internal(ctx);
784 /* Start of the connection to the remote server. This is called after
785 succesful TCP/IP connection has been established to the remote host. */
787 SILC_TASK_CALLBACK(silc_client_connect_to_server_start)
789 SilcClientInternalConnectContext *ctx =
790 (SilcClientInternalConnectContext *)context;
791 SilcClient client = ctx->client;
792 SilcProtocol protocol;
793 SilcClientKEInternalContext *proto_ctx;
794 int opt, opt_len = sizeof(opt);
796 SILC_LOG_DEBUG(("Start"));
798 /* Check the socket status as it might be in error */
799 getsockopt(fd, SOL_SOCKET, SO_ERROR, &opt, &opt_len);
801 if (ctx->tries < 2) {
802 /* Connection failed but lets try again */
803 silc_say(ctx->client, "Could not connect to server %s: %s",
804 ctx->host, strerror(opt));
805 silc_say(client, "Connecting to port %d of server %s resumed",
806 ctx->port, ctx->host);
808 /* Unregister old connection try */
809 silc_schedule_unset_listen_fd(fd);
810 silc_net_close_connection(fd);
811 silc_task_unregister(client->io_queue, ctx->task);
814 silc_client_connect_to_server_internal(ctx);
817 /* Connection failed and we won't try anymore */
818 silc_say(ctx->client, "Could not connect to server %s: %s",
819 ctx->host, strerror(opt));
820 silc_schedule_unset_listen_fd(fd);
821 silc_net_close_connection(fd);
822 silc_task_unregister(client->io_queue, ctx->task);
828 silc_schedule_unset_listen_fd(fd);
829 silc_task_unregister(client->io_queue, ctx->task);
832 /* Allocate new socket connection object */
833 silc_socket_alloc(fd, SILC_SOCKET_TYPE_SERVER,
834 (void *)client->current_win,
835 &client->current_win->sock);
836 if (client->current_win->sock == NULL) {
837 silc_say(client, "Error: Could not allocate connection socket");
838 silc_net_close_connection(fd);
841 client->current_win->sock->hostname = client->current_win->remote_host;
842 client->current_win->sock->port = client->current_win->remote_port;
844 /* Allocate internal Key Exchange context. This is sent to the
845 protocol as context. */
846 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
847 proto_ctx->client = (void *)client;
848 proto_ctx->sock = client->current_win->sock;
849 proto_ctx->rng = client->rng;
850 proto_ctx->responder = FALSE;
852 /* Perform key exchange protocol. silc_client_connect_to_server_final
853 will be called after the protocol is finished. */
854 silc_protocol_alloc(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
855 &protocol, (void *)proto_ctx,
856 silc_client_connect_to_server_second);
858 silc_say(client, "Error: Could not start authentication protocol");
861 client->current_win->sock->protocol = protocol;
863 /* Register the connection for network input and output. This sets
864 that scheduler will listen for incoming packets for this connection
865 and sets that outgoing packets may be sent to this connection as well.
866 However, this doesn't set the scheduler for outgoing traffic, it will
867 be set separately by calling SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT,
868 later when outgoing data is available. */
869 context = (void *)client;
870 SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(fd);
872 /* Execute the protocol */
873 protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0);
876 /* Second part of the connecting to the server. This executed
877 authentication protocol. */
879 SILC_TASK_CALLBACK(silc_client_connect_to_server_second)
881 SilcProtocol protocol = (SilcProtocol)context;
882 SilcClientKEInternalContext *ctx =
883 (SilcClientKEInternalContext *)protocol->context;
884 SilcClient client = (SilcClient)ctx->client;
885 SilcSocketConnection sock = NULL;
886 SilcClientConnAuthInternalContext *proto_ctx;
888 SILC_LOG_DEBUG(("Start"));
890 if (protocol->state == SILC_PROTOCOL_STATE_ERROR) {
891 /* Error occured during protocol */
892 SILC_LOG_DEBUG(("Error during KE protocol"));
893 silc_protocol_free(protocol);
895 silc_buffer_free(ctx->packet);
897 silc_ske_free(ctx->ske);
899 sock->protocol = NULL;
903 /* Allocate internal context for the authentication protocol. This
904 is sent as context for the protocol. */
905 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
906 proto_ctx->client = (void *)client;
907 proto_ctx->sock = sock = ctx->sock;
908 proto_ctx->ske = ctx->ske; /* Save SKE object from previous protocol */
910 /* Resolve the authentication method to be used in this connection */
911 proto_ctx->auth_meth = SILC_PROTOCOL_CONN_AUTH_NONE;
912 if (client->config->conns) {
913 SilcClientConfigSectionConnection *conn = NULL;
915 /* Check if we find a match from user configured connections */
916 conn = silc_client_config_find_connection(client->config,
920 /* Match found. Use the configured authentication method */
921 proto_ctx->auth_meth = conn->auth_meth;
922 if (conn->auth_data) {
923 proto_ctx->auth_data = strdup(conn->auth_data);
924 proto_ctx->auth_data_len = strlen(conn->auth_data);
927 /* No match found. Resolve by sending AUTH_REQUEST to server */
928 proto_ctx->auth_meth = SILC_PROTOCOL_CONN_AUTH_NONE;
931 /* XXX Resolve by sending AUTH_REQUEST to server */
932 proto_ctx->auth_meth = SILC_PROTOCOL_CONN_AUTH_NONE;
935 /* Free old protocol as it is finished now */
936 silc_protocol_free(protocol);
938 silc_buffer_free(ctx->packet);
940 /* silc_free(ctx->keymat....); */
941 sock->protocol = NULL;
943 /* Allocate the authentication protocol. This is allocated here
944 but we won't start it yet. We will be receiving party of this
945 protocol thus we will wait that connecting party will make
947 silc_protocol_alloc(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
948 &sock->protocol, (void *)proto_ctx,
949 silc_client_connect_to_server_final);
951 /* Execute the protocol */
952 sock->protocol->execute(client->timeout_queue, 0, sock->protocol, fd, 0, 0);
955 /* Finalizes the connection to the remote SILC server. This is called
956 after authentication protocol has been completed. This send our
957 user information to the server to receive our client ID from
960 SILC_TASK_CALLBACK(silc_client_connect_to_server_final)
962 SilcProtocol protocol = (SilcProtocol)context;
963 SilcClientConnAuthInternalContext *ctx =
964 (SilcClientConnAuthInternalContext *)protocol->context;
965 SilcClient client = (SilcClient)ctx->client;
966 SilcClientWindow win = (SilcClientWindow)ctx->sock->user_data;
969 SILC_LOG_DEBUG(("Start"));
971 if (protocol->state == SILC_PROTOCOL_STATE_ERROR) {
972 /* Error occured during protocol */
973 SILC_LOG_DEBUG(("Error during authentication protocol"));
974 silc_protocol_free(protocol);
976 silc_free(ctx->auth_data);
978 silc_ske_free(ctx->ske);
980 win->sock->protocol = NULL;
984 /* Send NEW_CLIENT packet to the server. We will become registered
985 to the SILC network after sending this packet and we will receive
986 client ID from the server. */
987 packet = silc_buffer_alloc(2 + 2 + strlen(client->username) +
988 strlen(client->realname));
989 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
990 silc_buffer_format(packet,
991 SILC_STR_UI_SHORT(strlen(client->username)),
992 SILC_STR_UI_XNSTRING(client->username,
993 strlen(client->username)),
994 SILC_STR_UI_SHORT(strlen(client->realname)),
995 SILC_STR_UI_XNSTRING(client->realname,
996 strlen(client->realname)),
999 /* Send the packet */
1000 silc_client_packet_send(client, ctx->sock, SILC_PACKET_NEW_CLIENT,
1001 NULL, 0, NULL, NULL,
1002 packet->data, packet->len, TRUE);
1003 silc_buffer_free(packet);
1005 silc_say(client, "Connected to port %d of host %s",
1006 win->remote_port, win->remote_host);
1008 client->screen->bottom_line->connection = win->remote_host;
1009 silc_screen_print_bottom_line(client->screen, 0);
1011 silc_protocol_free(protocol);
1013 silc_free(ctx->auth_data);
1015 silc_ske_free(ctx->ske);
1017 win->sock->protocol = NULL;
1021 SilcPacketContext *packetdata;
1022 SilcSocketConnection sock;
1024 } SilcClientInternalPacket;
1026 SILC_TASK_CALLBACK(silc_client_packet_process)
1028 SilcClient client = (SilcClient)context;
1029 SilcSocketConnection sock = NULL;
1030 int ret, packetlen, paddedlen;
1032 SILC_LOG_DEBUG(("Processing packet"));
1034 SILC_CLIENT_GET_SOCK(client, fd, sock);
1038 /* Packet sending */
1039 if (type == SILC_TASK_WRITE) {
1040 SILC_LOG_DEBUG(("Writing data to connection"));
1042 if (sock->outbuf->data - sock->outbuf->head)
1043 silc_buffer_push(sock->outbuf,
1044 sock->outbuf->data - sock->outbuf->head);
1046 /* Write the packet out to the connection */
1047 ret = silc_packet_write(fd, sock->outbuf);
1049 /* If returned -2 could not write to connection now, will do
1056 SILC_LOG_ERROR(("Packet dropped"));
1058 /* The packet has been sent and now it is time to set the connection
1059 back to only for input. When there is again some outgoing data
1060 available for this connection it will be set for output as well.
1061 This call clears the output setting and sets it only for input. */
1062 SILC_CLIENT_SET_CONNECTION_FOR_INPUT(fd);
1063 SILC_UNSET_OUTBUF_PENDING(sock);
1068 /* Packet receiving */
1069 if (type == SILC_TASK_READ) {
1070 SILC_LOG_DEBUG(("Reading data from connection"));
1072 /* Allocate the incoming data buffer if not done already. */
1074 sock->inbuf = silc_buffer_alloc(SILC_PACKET_DEFAULT_SIZE);
1076 /* Read some data from connection */
1077 ret = silc_packet_read(fd, sock->inbuf);
1079 /* If returned -2 data was not available now, will read it later. */
1085 SILC_LOG_ERROR(("Packet dropped"));
1091 SILC_LOG_DEBUG(("Read EOF"));
1093 /* If connection is disconnecting already we will finally
1094 close the connection */
1095 if (SILC_IS_DISCONNECTING(sock)) {
1096 silc_client_close_connection(client, sock);
1100 silc_say(client, "Connection closed: premature EOF");
1101 SILC_LOG_DEBUG(("Premature EOF from connection %d", sock->sock));
1103 silc_client_close_connection(client, sock);
1107 /* Check whether we received a whole packet. If reading went without
1108 errors we either read a whole packet or the read packet is
1109 incorrect and will be dropped. */
1110 SILC_PACKET_LENGTH(sock->inbuf, packetlen, paddedlen);
1111 if (sock->inbuf->len < paddedlen || (packetlen < SILC_PACKET_MIN_LEN)) {
1112 SILC_LOG_DEBUG(("Received incorrect packet, dropped"));
1113 silc_buffer_clear(sock->inbuf);
1117 /* Decrypt a packet coming from server connection */
1118 if (sock->type == SILC_SOCKET_TYPE_SERVER ||
1119 sock->type == SILC_SOCKET_TYPE_ROUTER) {
1120 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1121 SilcClientInternalPacket *packet;
1125 mac_len = win->hmac->hash->hash->hash_len;
1127 if (sock->inbuf->len - 2 > (paddedlen + mac_len)) {
1128 /* Received possibly many packets at once */
1130 while(sock->inbuf->len > 0) {
1131 SILC_PACKET_LENGTH(sock->inbuf, packetlen, paddedlen);
1132 if (sock->inbuf->len < paddedlen) {
1133 SILC_LOG_DEBUG(("Received incorrect packet, dropped"));
1138 packet = silc_calloc(1, sizeof(*packet));
1139 packet->client = client;
1140 packet->sock = sock;
1141 packet->packetdata = silc_calloc(1, sizeof(*packet->packetdata));
1142 packet->packetdata->buffer = silc_buffer_alloc(paddedlen + mac_len);
1143 silc_buffer_pull_tail(packet->packetdata->buffer,
1144 SILC_BUFFER_END(packet->packetdata->buffer));
1145 silc_buffer_put(packet->packetdata->buffer, sock->inbuf->data,
1146 paddedlen + mac_len);
1148 SILC_LOG_HEXDUMP(("Incoming packet, len %d",
1149 packet->packetdata->buffer->len),
1150 packet->packetdata->buffer->data,
1151 packet->packetdata->buffer->len);
1152 SILC_LOG_DEBUG(("Packet from server %s, "
1153 "server type %d, packet length %d",
1154 win->remote_host, win->remote_type, paddedlen));
1156 /* If this packet is for the current active connection we will
1157 parse the packet right away to get it quickly on the screen.
1158 Otherwise, it will be parsed with a timeout as the data is
1159 for inactive window (which might not be visible at all). */
1160 if (SILC_CLIENT_IS_CURRENT_WIN(client, win)) {
1161 /* Parse it real soon */
1162 silc_task_register(client->timeout_queue, fd,
1163 silc_client_packet_parse,
1164 (void *)packet, 0, 1,
1166 SILC_TASK_PRI_NORMAL);
1168 /* Parse the packet with timeout */
1169 silc_task_register(client->timeout_queue, fd,
1170 silc_client_packet_parse,
1171 (void *)packet, 0, 200000,
1173 SILC_TASK_PRI_NORMAL);
1176 /* Pull the packet from inbuf thus we'll get the next one
1178 silc_buffer_pull(sock->inbuf, paddedlen);
1180 silc_buffer_pull(sock->inbuf, mac_len);
1182 silc_buffer_clear(sock->inbuf);
1185 /* Received one packet */
1187 SILC_LOG_HEXDUMP(("An incoming packet, len %d", sock->inbuf->len),
1188 sock->inbuf->data, sock->inbuf->len);
1189 SILC_LOG_DEBUG(("Packet from server %s, "
1190 "server type %d, packet length %d",
1191 win->remote_host, win->remote_type, paddedlen));
1193 packet = silc_calloc(1, sizeof(*packet));
1194 packet->client = client;
1195 packet->sock = sock;
1196 packet->packetdata = silc_calloc(1, sizeof(*packet->packetdata));
1197 packet->packetdata->buffer = silc_buffer_copy(sock->inbuf);
1198 silc_buffer_clear(sock->inbuf);
1200 /* If this packet is for the current active connection we will
1201 parse the packet right away to get it quickly on the screen.
1202 Otherwise, it will be parsed with a timeout as the data is
1203 for inactive window (which might not be visible at all). */
1204 if (SILC_CLIENT_IS_CURRENT_WIN(client, win)) {
1205 /* Parse it real soon */
1206 silc_task_register(client->timeout_queue, fd,
1207 silc_client_packet_parse,
1208 (void *)packet, 0, 1,
1210 SILC_TASK_PRI_NORMAL);
1213 /* Parse the packet with timeout */
1214 silc_task_register(client->timeout_queue, fd,
1215 silc_client_packet_parse,
1216 (void *)packet, 0, 200000,
1218 SILC_TASK_PRI_NORMAL);
1225 SILC_LOG_ERROR(("Weird, nothing happened - ignoring"));
1228 /* Checks MAC in the packet. Returns TRUE if MAC is Ok. This is called
1229 after packet has been totally decrypted and parsed. */
1231 static int silc_client_packet_check_mac(SilcClient client,
1232 SilcSocketConnection sock,
1235 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1239 int headlen = buffer->data - buffer->head, mac_len;
1240 unsigned char *packet_mac, mac[32];
1242 SILC_LOG_DEBUG(("Verifying MAC"));
1244 mac_len = win->hmac->hash->hash->hash_len;
1246 silc_buffer_push(buffer, headlen);
1248 /* Take mac from packet */
1249 packet_mac = buffer->tail;
1251 /* Make MAC and compare */
1252 memset(mac, 0, sizeof(mac));
1253 silc_hmac_make_with_key(win->hmac,
1254 buffer->data, buffer->len,
1255 win->hmac_key, win->hmac_key_len, mac);
1257 SILC_LOG_HEXDUMP(("PMAC"), packet_mac, mac_len);
1258 SILC_LOG_HEXDUMP(("CMAC"), mac, mac_len);
1260 if (memcmp(mac, packet_mac, mac_len)) {
1261 SILC_LOG_DEBUG(("MAC failed"));
1265 SILC_LOG_DEBUG(("MAC is Ok"));
1266 memset(mac, 0, sizeof(mac));
1268 silc_buffer_pull(buffer, headlen);
1274 /* Decrypts rest of the packet (after decrypting just the SILC header).
1275 After calling this function the packet is ready to be parsed by calling
1276 silc_packet_parse. */
1278 static int silc_client_packet_decrypt_rest(SilcClient client,
1279 SilcSocketConnection sock,
1282 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1283 unsigned int mac_len = 0;
1286 if (win && win->receive_key) {
1288 /* Pull MAC from packet before decryption */
1290 mac_len = win->hmac->hash->hash->hash_len;
1291 if ((buffer->len - mac_len) > SILC_PACKET_MIN_LEN) {
1292 silc_buffer_push_tail(buffer, mac_len);
1294 SILC_LOG_DEBUG(("Bad MAC length in packet, packet dropped"));
1299 SILC_LOG_DEBUG(("Decrypting rest of the packet"));
1301 /* Decrypt rest of the packet */
1302 silc_buffer_pull(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
1303 silc_packet_decrypt(win->receive_key, buffer, buffer->len);
1304 silc_buffer_push(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
1306 SILC_LOG_HEXDUMP(("Fully decrypted packet, len %d", buffer->len),
1307 buffer->data, buffer->len);
1313 /* Decrypts rest of the SILC Packet header that has been decrypted partly
1314 already. This decrypts the padding of the packet also. After calling
1315 this function the packet is ready to be parsed by calling function
1316 silc_packet_parse. This is used in special packet reception. */
1318 static int silc_client_packet_decrypt_rest_special(SilcClient client,
1319 SilcSocketConnection sock,
1322 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1323 unsigned int mac_len = 0;
1325 /* Decrypt rest of the header plus padding */
1326 if (win && win->receive_key) {
1327 unsigned short truelen, len1, len2, padlen;
1329 /* Pull MAC from packet before decryption */
1331 mac_len = win->hmac->hash->hash->hash_len;
1332 if ((buffer->len - mac_len) > SILC_PACKET_MIN_LEN) {
1333 silc_buffer_push_tail(buffer, mac_len);
1335 SILC_LOG_DEBUG(("Bad MAC length in packet, packet dropped"));
1340 SILC_LOG_DEBUG(("Decrypting rest of the header"));
1342 SILC_GET16_MSB(len1, &buffer->data[4]);
1343 SILC_GET16_MSB(len2, &buffer->data[6]);
1345 truelen = SILC_PACKET_HEADER_LEN + len1 + len2;
1346 padlen = SILC_PACKET_PADLEN(truelen);
1347 len1 = (truelen + padlen) - (SILC_PACKET_MIN_HEADER_LEN - 2);
1349 silc_buffer_pull(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
1350 SILC_LOG_HEXDUMP(("XXX"), buffer->data, buffer->len);
1351 silc_packet_decrypt(win->receive_key, buffer, len1);
1352 silc_buffer_push(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
1353 SILC_LOG_HEXDUMP(("XXX"), buffer->data, buffer->len);
1359 /* Parses whole packet, received earlier. */
1361 SILC_TASK_CALLBACK(silc_client_packet_parse)
1363 SilcClientInternalPacket *packet = (SilcClientInternalPacket *)context;
1364 SilcBuffer buffer = packet->packetdata->buffer;
1365 SilcClient client = packet->client;
1366 SilcSocketConnection sock = packet->sock;
1367 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1370 SILC_LOG_DEBUG(("Start"));
1372 /* Decrypt start of the packet header */
1373 if (win && win->receive_key)
1374 silc_packet_decrypt(win->receive_key, buffer, SILC_PACKET_MIN_HEADER_LEN);
1376 /* If the packet type is not any special type lets decrypt rest
1377 of the packet here. */
1378 if (buffer->data[3] != SILC_PACKET_CHANNEL_MESSAGE &&
1379 buffer->data[3] != SILC_PACKET_PRIVATE_MESSAGE) {
1381 /* Normal packet, decrypt rest of the packet */
1382 if (!silc_client_packet_decrypt_rest(client, sock, buffer))
1385 /* Parse the packet. Packet type is returned. */
1386 ret = silc_packet_parse(packet->packetdata);
1387 if (ret == SILC_PACKET_NONE)
1391 if (!silc_client_packet_check_mac(client, sock, buffer))
1394 /* If private message key is not set for private message it is
1395 handled as normal packet. Go back up. */
1396 if (buffer->data[3] == SILC_PACKET_PRIVATE_MESSAGE &&
1397 !(buffer->data[2] & SILC_PACKET_FLAG_PRIVMSG_KEY))
1400 /* Packet requires special handling, decrypt rest of the header.
1401 This only decrypts. This does not do any MAC checking, it must
1402 be done individually later when doing the special processing. */
1403 silc_client_packet_decrypt_rest_special(client, sock, buffer);
1405 /* Parse the packet header in special way as this is "special"
1407 ret = silc_packet_parse_special(packet->packetdata);
1408 if (ret == SILC_PACKET_NONE)
1412 /* Parse the incoming packet type */
1413 silc_client_packet_parse_type(client, sock, packet->packetdata);
1416 silc_buffer_clear(packet->packetdata->buffer);
1417 silc_free(packet->packetdata);
1421 /* Parses the packet type and calls what ever routines the packet type
1422 requires. This is done for all incoming packets. */
1424 void silc_client_packet_parse_type(SilcClient client,
1425 SilcSocketConnection sock,
1426 SilcPacketContext *packet)
1428 SilcBuffer buffer = packet->buffer;
1429 SilcPacketType type = packet->type;
1431 SILC_LOG_DEBUG(("Parsing packet type %d", type));
1433 /* Parse the packet type */
1435 case SILC_PACKET_DISCONNECT:
1436 silc_client_disconnected_by_server(client, sock, buffer);
1438 case SILC_PACKET_SUCCESS:
1440 * Success received for something. For now we can have only
1441 * one protocol for connection executing at once hence this
1442 * success message is for whatever protocol is executing currently.
1444 if (sock->protocol) {
1445 sock->protocol->execute(client->timeout_queue, 0,
1446 sock->protocol, sock->sock, 0, 0);
1449 case SILC_PACKET_FAILURE:
1451 * Failure received for some protocol. Set the protocol state to
1452 * error and call the protocol callback. This fill cause error on
1453 * protocol and it will call the final callback.
1455 if (sock->protocol) {
1456 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
1457 sock->protocol->execute(client->timeout_queue, 0,
1458 sock->protocol, sock->sock, 0, 0);
1461 case SILC_PACKET_REJECT:
1464 case SILC_PACKET_NOTIFY:
1466 * Received notify message
1468 silc_client_notify_by_server(client, sock, buffer);
1471 case SILC_PACKET_ERROR:
1473 * Received error message
1475 silc_client_error_by_server(client, sock, buffer);
1478 case SILC_PACKET_CHANNEL_MESSAGE:
1480 * Received message to (from, actually) a channel
1482 silc_client_channel_message(client, sock, packet);
1484 case SILC_PACKET_CHANNEL_KEY:
1486 * Received key for a channel. By receiving this key the client will be
1487 * able to talk to the channel it has just joined. This can also be
1488 * a new key for existing channel as keys expire peridiocally.
1490 silc_client_receive_channel_key(client, sock, buffer);
1493 case SILC_PACKET_PRIVATE_MESSAGE:
1495 * Received private message
1498 SilcClientCommandReplyContext ctx;
1499 ctx = silc_calloc(1, sizeof(*ctx));
1500 ctx->client = client;
1502 ctx->context = buffer; /* kludge */
1503 silc_client_command_reply_msg((void *)ctx);
1506 case SILC_PACKET_PRIVATE_MESSAGE_KEY:
1508 * Received private message key
1512 case SILC_PACKET_COMMAND_REPLY:
1514 * Recived reply for a command
1516 silc_client_command_reply_process(client, sock, buffer);
1519 case SILC_PACKET_KEY_EXCHANGE:
1520 if (sock->protocol) {
1521 SilcClientKEInternalContext *proto_ctx =
1522 (SilcClientKEInternalContext *)sock->protocol->context;
1524 proto_ctx->packet = buffer;
1526 /* Let the protocol handle the packet */
1527 sock->protocol->execute(client->timeout_queue, 0,
1528 sock->protocol, sock->sock, 0, 0);
1530 SILC_LOG_ERROR(("Received Key Exchange packet but no key exchange "
1531 "protocol active, packet dropped."));
1533 /* XXX Trigger KE protocol?? Rekey actually! */
1537 case SILC_PACKET_KEY_EXCHANGE_1:
1538 if (sock->protocol) {
1541 SILC_LOG_ERROR(("Received Key Exchange 1 packet but no key exchange "
1542 "protocol active, packet dropped."));
1545 case SILC_PACKET_KEY_EXCHANGE_2:
1546 if (sock->protocol) {
1547 SilcClientKEInternalContext *proto_ctx =
1548 (SilcClientKEInternalContext *)sock->protocol->context;
1550 if (proto_ctx->packet)
1551 silc_buffer_free(proto_ctx->packet);
1553 proto_ctx->packet = buffer;
1555 /* Let the protocol handle the packet */
1556 sock->protocol->execute(client->timeout_queue, 0,
1557 sock->protocol, sock->sock, 0, 0);
1559 SILC_LOG_ERROR(("Received Key Exchange 2 packet but no key exchange "
1560 "protocol active, packet dropped."));
1564 case SILC_PACKET_NEW_ID:
1567 * Received new ID from server. This packet is received at
1568 * the connection to the server. New ID is also received when
1569 * user changes nickname but in that case the new ID is received
1570 * as command reply and not as this packet type.
1572 unsigned char *id_string;
1573 unsigned short id_type;
1575 silc_buffer_unformat(buffer,
1576 SILC_STR_UI_SHORT(&id_type),
1577 SILC_STR_UI16_STRING_ALLOC(&id_string),
1580 if ((SilcIdType)id_type != SILC_ID_CLIENT)
1583 silc_client_receive_new_id(client, sock, id_string);
1584 silc_free(id_string);
1589 SILC_LOG_DEBUG(("Incorrect packet type %d, packet dropped", type));
1594 /* Internal routine that sends packet or marks packet to be sent. This
1595 is used directly only in special cases. Normal cases should use
1596 silc_server_packet_send. Returns < 0 on error. */
1598 static int silc_client_packet_send_real(SilcClient client,
1599 SilcSocketConnection sock,
1602 /* Send now if forced to do so */
1603 if (force_send == TRUE) {
1605 SILC_LOG_DEBUG(("Forcing packet send, packet sent immediately"));
1606 ret = silc_packet_write(sock->sock, sock->outbuf);
1609 SILC_LOG_ERROR(("Packet dropped"));
1613 SILC_LOG_DEBUG(("Could not force the send, packet put to queue"));
1616 SILC_LOG_DEBUG(("Packet in queue"));
1618 /* Mark that there is some outgoing data available for this connection.
1619 This call sets the connection both for input and output (the input
1620 is set always and this call keeps the input setting, actually).
1621 Actual data sending is performed by silc_client_packet_process. */
1622 SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(sock->sock);
1624 /* Mark to socket that data is pending in outgoing buffer. This flag
1625 is needed if new data is added to the buffer before the earlier
1626 put data is sent to the network. */
1627 SILC_SET_OUTBUF_PENDING(sock);
1632 /* Prepare outgoing data buffer for packet sending. */
1634 static void silc_client_packet_send_prepare(SilcClient client,
1635 SilcSocketConnection sock,
1636 unsigned int header_len,
1637 unsigned int padlen,
1638 unsigned int data_len)
1642 totlen = header_len + padlen + data_len;
1644 /* Prepare the outgoing buffer for packet sending. */
1645 if (!sock->outbuf) {
1646 /* Allocate new buffer. This is done only once per connection. */
1647 SILC_LOG_DEBUG(("Allocating outgoing data buffer"));
1649 sock->outbuf = silc_buffer_alloc(SILC_PACKET_DEFAULT_SIZE);
1650 silc_buffer_pull_tail(sock->outbuf, totlen);
1651 silc_buffer_pull(sock->outbuf, header_len + padlen);
1653 if (SILC_IS_OUTBUF_PENDING(sock)) {
1654 /* There is some pending data in the buffer. */
1656 if ((sock->outbuf->end - sock->outbuf->tail) < data_len) {
1657 SILC_LOG_DEBUG(("Reallocating outgoing data buffer"));
1658 /* XXX: not done yet */
1660 oldlen = sock->outbuf->len;
1661 silc_buffer_pull_tail(sock->outbuf, totlen);
1662 silc_buffer_pull(sock->outbuf, header_len + padlen + oldlen);
1664 /* Buffer is free for use */
1665 silc_buffer_clear(sock->outbuf);
1666 silc_buffer_pull_tail(sock->outbuf, totlen);
1667 silc_buffer_pull(sock->outbuf, header_len + padlen);
1672 /* Sends packet. This doesn't actually send the packet instead it assembles
1673 it and marks it to be sent. However, if force_send is TRUE the packet
1674 is sent immediately. if dst_id, cipher and hmac are NULL those parameters
1675 will be derived from sock argument. Otherwise the valid arguments sent
1678 void silc_client_packet_send(SilcClient client,
1679 SilcSocketConnection sock,
1680 SilcPacketType type,
1682 SilcIdType dst_id_type,
1685 unsigned char *data,
1686 unsigned int data_len,
1689 SilcPacketContext packetdata;
1690 unsigned char *hmac_key = NULL;
1691 unsigned int hmac_key_len = 0;
1692 unsigned char mac[32];
1693 unsigned int mac_len = 0;
1695 SILC_LOG_DEBUG(("Sending packet, type %d", type));
1697 /* Get data used in the packet sending, keys and stuff */
1698 if ((!cipher || !hmac || !dst_id) && sock->user_data) {
1699 if (!cipher && ((SilcClientWindow)sock->user_data)->send_key)
1700 cipher = ((SilcClientWindow)sock->user_data)->send_key;
1701 if (!hmac && ((SilcClientWindow)sock->user_data)->hmac) {
1702 hmac = ((SilcClientWindow)sock->user_data)->hmac;
1703 mac_len = hmac->hash->hash->hash_len;
1704 hmac_key = ((SilcClientWindow)sock->user_data)->hmac_key;
1705 hmac_key_len = ((SilcClientWindow)sock->user_data)->hmac_key_len;
1707 if (!dst_id && ((SilcClientWindow)sock->user_data)->remote_id) {
1708 dst_id = ((SilcClientWindow)sock->user_data)->remote_id;
1709 dst_id_type = SILC_ID_SERVER;
1713 /* Set the packet context pointers */
1714 packetdata.flags = 0;
1715 packetdata.type = type;
1716 if (((SilcClientWindow)sock->user_data)->local_id_data)
1717 packetdata.src_id = ((SilcClientWindow)sock->user_data)->local_id_data;
1719 packetdata.src_id = silc_calloc(SILC_ID_CLIENT_LEN, sizeof(unsigned char));
1720 packetdata.src_id_len = SILC_ID_CLIENT_LEN;
1721 packetdata.src_id_type = SILC_ID_CLIENT;
1723 packetdata.dst_id = silc_id_id2str(dst_id, dst_id_type);
1724 packetdata.dst_id_len = silc_id_get_len(dst_id_type);
1725 packetdata.dst_id_type = dst_id_type;
1727 packetdata.dst_id = NULL;
1728 packetdata.dst_id_len = 0;
1729 packetdata.dst_id_type = SILC_ID_NONE;
1731 packetdata.rng = client->rng;
1732 packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN +
1733 packetdata.src_id_len + packetdata.dst_id_len;
1734 packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen);
1736 /* Prepare outgoing data buffer for packet sending */
1737 silc_client_packet_send_prepare(client, sock,
1738 SILC_PACKET_HEADER_LEN +
1739 packetdata.src_id_len +
1740 packetdata.dst_id_len,
1744 SILC_LOG_DEBUG(("Putting data to outgoing buffer, len %d", data_len));
1746 packetdata.buffer = sock->outbuf;
1748 /* Put the data to the buffer */
1749 if (data && data_len)
1750 silc_buffer_put(sock->outbuf, data, data_len);
1752 /* Create the outgoing packet */
1753 silc_packet_assemble(&packetdata);
1755 /* Compute MAC of the packet */
1757 silc_hmac_make_with_key(hmac, sock->outbuf->data, sock->outbuf->len,
1758 hmac_key, hmac_key_len, mac);
1759 silc_buffer_put_tail(sock->outbuf, mac, mac_len);
1760 memset(mac, 0, sizeof(mac));
1763 /* Encrypt the packet */
1765 silc_packet_encrypt(cipher, sock->outbuf, sock->outbuf->len);
1767 /* Pull MAC into the visible data area */
1769 silc_buffer_pull_tail(sock->outbuf, mac_len);
1771 SILC_LOG_HEXDUMP(("Packet, len %d", sock->outbuf->len),
1772 sock->outbuf->data, sock->outbuf->len);
1774 /* Now actually send the packet */
1775 silc_client_packet_send_real(client, sock, force_send);
1778 /* Sends packet to a channel. Packet to channel is always encrypted
1779 differently from "normal" packets. SILC header of the packet is
1780 encrypted with the next receiver's key and the rest of the packet is
1781 encrypted with the channel specific key. Padding and HMAC is computed
1782 with the next receiver's key. */
1784 void silc_client_packet_send_to_channel(SilcClient client,
1785 SilcSocketConnection sock,
1786 SilcChannelEntry channel,
1787 unsigned char *data,
1788 unsigned int data_len,
1792 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1794 SilcPacketContext packetdata;
1795 unsigned char *hmac_key = NULL;
1796 unsigned int hmac_key_len = 0;
1797 unsigned char mac[32];
1798 unsigned int mac_len = 0;
1799 unsigned char *id_string;
1803 SILC_LOG_DEBUG(("Sending packet to channel"));
1805 if (!channel || !channel->key) {
1806 silc_say(client, "Cannot talk to channel: key does not exist");
1812 for (i = 0; i < 16; i++)
1813 channel->iv[i] = silc_rng_get_byte(client->rng);
1815 silc_hash_make(client->md5hash, channel->iv, 16, channel->iv);
1817 /* Encode the channel payload */
1818 payload = silc_channel_encode_payload(strlen(win->nickname), win->nickname,
1819 data_len, data, 16, channel->iv,
1823 "Error: Could not create packet to be sent to the channel");
1827 /* Get data used in packet header encryption, keys and stuff. Rest
1828 of the packet (the payload) is, however, encrypted with the
1829 specified channel key. */
1830 cipher = win->send_key;
1832 mac_len = hmac->hash->hash->hash_len;
1833 hmac_key = win->hmac_key;
1834 hmac_key_len = win->hmac_key_len;
1835 id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
1837 /* Set the packet context pointers. The destination ID is always
1838 the Channel ID of the channel. Server and router will handle the
1839 distribution of the packet. */
1840 packetdata.flags = 0;
1841 packetdata.type = SILC_PACKET_CHANNEL_MESSAGE;
1842 packetdata.src_id = win->local_id_data;
1843 packetdata.src_id_len = SILC_ID_CLIENT_LEN;
1844 packetdata.src_id_type = SILC_ID_CLIENT;
1845 packetdata.dst_id = id_string;
1846 packetdata.dst_id_len = SILC_ID_CHANNEL_LEN;
1847 packetdata.dst_id_type = SILC_ID_CHANNEL;
1848 packetdata.rng = client->rng;
1849 packetdata.truelen = payload->len + SILC_PACKET_HEADER_LEN +
1850 packetdata.src_id_len + packetdata.dst_id_len;
1851 packetdata.padlen = SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
1852 packetdata.src_id_len +
1853 packetdata.dst_id_len));
1855 /* Prepare outgoing data buffer for packet sending */
1856 silc_client_packet_send_prepare(client, sock,
1857 SILC_PACKET_HEADER_LEN +
1858 packetdata.src_id_len +
1859 packetdata.dst_id_len,
1863 packetdata.buffer = sock->outbuf;
1865 /* Encrypt payload of the packet. This is encrypted with the channel key. */
1866 channel->channel_key->cipher->encrypt(channel->channel_key->context,
1867 payload->data, payload->data,
1868 payload->len - 16, /* -IV_LEN */
1871 SILC_LOG_HEXDUMP(("XXX"), payload->data, payload->len);
1873 /* Put the actual encrypted payload data into the buffer. */
1874 silc_buffer_put(sock->outbuf, payload->data, payload->len);
1876 /* Create the outgoing packet */
1877 silc_packet_assemble(&packetdata);
1879 /* Compute MAC of the packet */
1880 silc_hmac_make_with_key(hmac, sock->outbuf->data, sock->outbuf->len,
1881 hmac_key, hmac_key_len, mac);
1882 silc_buffer_put_tail(sock->outbuf, mac, mac_len);
1883 memset(mac, 0, sizeof(mac));
1885 SILC_LOG_HEXDUMP(("XXX"), sock->outbuf->data, sock->outbuf->len);
1887 /* Encrypt the header and padding of the packet. This is encrypted
1888 with normal session key shared with our server. */
1889 silc_packet_encrypt(cipher, sock->outbuf, SILC_PACKET_HEADER_LEN +
1890 packetdata.src_id_len + packetdata.dst_id_len +
1893 /* Pull MAC into the visible data area */
1894 silc_buffer_pull_tail(sock->outbuf, mac_len);
1896 SILC_LOG_HEXDUMP(("Packet to channel, len %d", sock->outbuf->len),
1897 sock->outbuf->data, sock->outbuf->len);
1899 /* Now actually send the packet */
1900 silc_client_packet_send_real(client, sock, force_send);
1901 silc_buffer_free(payload);
1902 silc_free(id_string);
1905 /* Sends private message to remote client. If private message key has
1906 not been set with this client then the message will be encrypted using
1907 normal session keys. Private messages are special packets in SILC
1908 network hence we need this own function for them. This is similiar
1909 to silc_client_packet_send_to_channel except that we send private
1912 void silc_client_packet_send_private_message(SilcClient client,
1913 SilcSocketConnection sock,
1914 SilcClientEntry client_entry,
1915 unsigned char *data,
1916 unsigned int data_len,
1919 SilcClientWindow win = (SilcClientWindow)sock->user_data;
1921 SilcPacketContext packetdata;
1922 unsigned char *hmac_key = NULL;
1923 unsigned int hmac_key_len = 0;
1924 unsigned char mac[32];
1925 unsigned int mac_len = 0;
1926 unsigned int nick_len;
1930 SILC_LOG_DEBUG(("Sending private message"));
1932 /* Create private message payload */
1933 nick_len = strlen(client->current_win->nickname);
1934 buffer = silc_buffer_alloc(2 + nick_len + data_len);
1935 silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer));
1936 silc_buffer_format(buffer,
1937 SILC_STR_UI_SHORT(nick_len),
1938 SILC_STR_UI_XNSTRING(client->current_win->nickname,
1940 SILC_STR_UI_XNSTRING(data, data_len),
1943 /* If we don't have private message specific key then private messages
1944 are just as any normal packet thus call normal packet sending. If
1945 the key exist then the encryption process is a bit different and
1946 will be done in the rest of this function. */
1947 if (!client_entry->send_key) {
1948 silc_client_packet_send(client, sock, SILC_PACKET_PRIVATE_MESSAGE,
1949 client_entry->id, SILC_ID_CLIENT, NULL, NULL,
1950 buffer->data, buffer->len, force_send);
1954 /* We have private message specific key */
1956 /* Get data used in the encryption */
1957 cipher = client_entry->send_key;
1959 mac_len = hmac->hash->hash->hash_len;
1960 hmac_key = win->hmac_key;
1961 hmac_key_len = win->hmac_key_len;
1963 /* Set the packet context pointers. */
1964 packetdata.flags = 0;
1965 packetdata.type = SILC_PACKET_PRIVATE_MESSAGE;
1966 packetdata.src_id = win->local_id_data;
1967 packetdata.src_id_len = SILC_ID_CLIENT_LEN;
1968 packetdata.src_id_type = SILC_ID_CLIENT;
1970 packetdata.dst_id = silc_id_id2str(client_entry->id, SILC_ID_CLIENT);
1972 packetdata.dst_id = win->local_id_data;
1973 packetdata.dst_id_len = SILC_ID_CLIENT_LEN;
1974 packetdata.dst_id_type = SILC_ID_CLIENT;
1975 packetdata.rng = client->rng;
1976 packetdata.truelen = buffer->len + SILC_PACKET_HEADER_LEN +
1977 packetdata.src_id_len + packetdata.dst_id_len;
1978 packetdata.padlen = SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
1979 packetdata.src_id_len +
1980 packetdata.dst_id_len));
1982 /* Prepare outgoing data buffer for packet sending */
1983 silc_client_packet_send_prepare(client, sock,
1984 SILC_PACKET_HEADER_LEN +
1985 packetdata.src_id_len +
1986 packetdata.dst_id_len,
1990 packetdata.buffer = sock->outbuf;
1992 /* Encrypt payload of the packet. Encrypt with private message specific
1993 key if it exist, otherwise with session key. */
1994 cipher->cipher->encrypt(cipher->context, buffer->data, buffer->data,
1995 buffer->len, cipher->iv);
1997 /* Put the actual encrypted payload data into the buffer. */
1998 silc_buffer_put(sock->outbuf, buffer->data, buffer->len);
2000 /* Create the outgoing packet */
2001 silc_packet_assemble(&packetdata);
2003 /* Compute MAC of the packet */
2004 silc_hmac_make_with_key(hmac, sock->outbuf->data, sock->outbuf->len,
2005 hmac_key, hmac_key_len, mac);
2006 silc_buffer_put_tail(sock->outbuf, mac, mac_len);
2007 memset(mac, 0, sizeof(mac));
2009 SILC_LOG_HEXDUMP(("XXX"), sock->outbuf->data, sock->outbuf->len);
2011 /* Encrypt the header and padding of the packet. */
2012 silc_packet_encrypt(cipher, sock->outbuf, SILC_PACKET_HEADER_LEN +
2013 packetdata.src_id_len + packetdata.dst_id_len +
2016 /* Pull MAC into the visible data area */
2017 silc_buffer_pull_tail(sock->outbuf, mac_len);
2019 SILC_LOG_HEXDUMP(("Private message packet, len %d", sock->outbuf->len),
2020 sock->outbuf->data, sock->outbuf->len);
2022 /* Now actually send the packet */
2023 silc_client_packet_send_real(client, sock, force_send);
2024 silc_free(packetdata.dst_id);
2030 /* Closes connection to remote end. Free's all allocated data except
2031 for some information such as nickname etc. that are valid at all time. */
2033 void silc_client_close_connection(SilcClient client,
2034 SilcSocketConnection sock)
2036 SilcClientWindow win;
2039 /* We won't listen for this connection anymore */
2040 silc_schedule_unset_listen_fd(sock->sock);
2042 /* Unregister all tasks */
2043 silc_task_unregister_by_fd(client->io_queue, sock->sock);
2044 silc_task_unregister_by_fd(client->timeout_queue, sock->sock);
2046 /* Close the actual connection */
2047 silc_net_close_connection(sock->sock);
2049 silc_say(client, "Closed connection to host %s", sock->hostname ?
2050 sock->hostname : sock->ip);
2052 /* Free everything */
2053 if (sock->user_data) {
2054 win = (SilcClientWindow)sock->user_data;
2056 /* Clear ID caches */
2057 for (i = 0; i < 96; i++)
2058 silc_idcache_del_all(&win->client_id_cache[i],
2059 win->client_id_cache_count[i]);
2060 for (i = 0; i < 96; i++)
2061 silc_idcache_del_all(&win->channel_id_cache[i],
2062 win->channel_id_cache_count[i]);
2065 if (win->remote_host)
2066 silc_free(win->remote_host);
2068 silc_free(win->local_id);
2069 if (win->local_id_data)
2070 silc_free(win->local_id_data);
2072 silc_cipher_free(win->send_key);
2073 if (win->receive_key)
2074 silc_cipher_free(win->receive_key);
2075 if (win->public_key)
2076 silc_pkcs_free(win->public_key);
2078 silc_hmac_free(win->hmac);
2079 if (win->hmac_key) {
2080 memset(win->hmac_key, 0, win->hmac_key_len);
2081 silc_free(win->hmac_key);
2085 win->remote_port = 0;
2086 win->remote_type = 0;
2087 win->send_key = NULL;
2088 win->receive_key = NULL;
2089 win->public_key = NULL;
2091 win->hmac_key = NULL;
2092 win->hmac_key_len = 0;
2093 win->local_id = NULL;
2094 win->local_id_data = NULL;
2095 win->remote_host = NULL;
2098 if (sock->protocol) {
2099 silc_protocol_free(sock->protocol);
2100 sock->protocol = NULL;
2102 silc_socket_free(sock);
2105 /* Called when we receive disconnection packet from server. This
2106 closes our end properly and displays the reason of the disconnection
2109 void silc_client_disconnected_by_server(SilcClient client,
2110 SilcSocketConnection sock,
2115 SILC_LOG_DEBUG(("Server disconnected us, sock %d", sock->sock));
2117 msg = silc_calloc(message->len + 1, sizeof(char));
2118 memcpy(msg, message->data, message->len);
2119 silc_say(client, msg);
2122 SILC_SET_DISCONNECTED(sock);
2123 silc_client_close_connection(client, sock);
2126 /* Received error message from server. Display it on the screen.
2127 We don't take any action what so ever of the error message. */
2129 void silc_client_error_by_server(SilcClient client,
2130 SilcSocketConnection sock,
2135 msg = silc_calloc(message->len + 1, sizeof(char));
2136 memcpy(msg, message->data, message->len);
2137 silc_say(client, msg);
2141 /* Received notify message from server */
2143 void silc_client_notify_by_server(SilcClient client,
2144 SilcSocketConnection sock,
2149 msg = silc_calloc(message->len + 1, sizeof(char));
2150 memcpy(msg, message->data, message->len);
2151 silc_say(client, msg);
2155 /* Processes the received new Client ID from server. Old Client ID is
2156 deleted from cache and new one is added. */
2158 void silc_client_receive_new_id(SilcClient client,
2159 SilcSocketConnection sock,
2160 unsigned char *id_string)
2162 SilcClientWindow win = (SilcClientWindow)sock->user_data;
2163 char *nickname = win->nickname;
2165 #define CIDC(x) win->client_id_cache[(x) - 32]
2166 #define CIDCC(x) win->client_id_cache_count[(x) - 32]
2168 /* Delete old ID from ID cache */
2169 silc_idcache_del_by_id(CIDC(nickname[0]), CIDCC(nickname[0]),
2170 SILC_ID_CLIENT, win->local_id);
2172 /* Save the new ID */
2174 silc_free(win->local_id);
2175 win->local_id = silc_id_str2id(id_string, SILC_ID_CLIENT);
2176 if (win->local_id_data)
2177 silc_free(win->local_id_data);
2178 win->local_id_data =
2179 silc_calloc(SILC_ID_CLIENT_LEN, sizeof(unsigned char));
2180 memcpy(win->local_id_data, id_string, SILC_ID_CLIENT_LEN);
2181 win->local_id_data_len = SILC_ID_CLIENT_LEN;
2182 if (!win->local_entry)
2183 win->local_entry = silc_calloc(1, sizeof(*win->local_entry));
2184 win->local_entry->nickname = win->nickname;
2185 win->local_entry->id = win->local_id;
2187 /* Put it to the ID cache */
2188 CIDCC(nickname[0]) = silc_idcache_add(&CIDC(nickname[0]),
2190 win->nickname, SILC_ID_CLIENT,
2192 (void *)win->local_entry);
2197 /* Processed received Channel ID for a channel. This is called when client
2198 joins to channel and server replies with channel ID. The ID is cached. */
2200 void silc_client_new_channel_id(SilcClient client,
2201 SilcSocketConnection sock,
2203 unsigned char *id_string)
2205 SilcClientWindow win = (SilcClientWindow)sock->user_data;
2207 SilcChannelEntry channel;
2209 SILC_LOG_DEBUG(("New channel ID"));
2211 #define CIDC(x) win->channel_id_cache[(x) - 32]
2212 #define CIDCC(x) win->channel_id_cache_count[(x) - 32]
2214 id = silc_id_str2id(id_string, SILC_ID_CHANNEL);
2215 channel = silc_calloc(1, sizeof(*channel));
2216 channel->channel_name = channel_name;
2218 win->current_channel = channel;
2220 /* Put it to the ID cache */
2221 CIDCC(channel_name[0]) = silc_idcache_add(&CIDC(channel_name[0]),
2222 CIDCC(channel_name[0]),
2223 channel_name, SILC_ID_CHANNEL,
2224 id, (void *)channel);
2229 /* Processes received key for channel. The received key will be used
2230 to protect the traffic on the channel for now on. Client must receive
2231 the key to the channel before talking on the channel is possible.
2232 This is the key that server has generated, this is not the channel
2233 private key, it is entirely local setting. */
2235 void silc_client_receive_channel_key(SilcClient client,
2236 SilcSocketConnection sock,
2240 unsigned char *id_string, *key, *cipher;
2241 unsigned int key_len;
2242 SilcClientWindow win = (SilcClientWindow)sock->user_data;
2244 SilcIDCache *id_cache = NULL;
2245 SilcChannelEntry channel;
2246 SilcChannelKeyPayload payload;
2248 SILC_LOG_DEBUG(("Received key for channel"));
2250 #define CIDC(x) win->channel_id_cache[(x)]
2251 #define CIDCC(x) win->channel_id_cache_count[(x)]
2253 payload = silc_channel_key_parse_payload(packet);
2257 id_string = silc_channel_key_get_id(payload, NULL);
2259 silc_channel_key_free_payload(payload);
2262 id = silc_id_str2id(id_string, SILC_ID_CHANNEL);
2264 /* Find channel. XXX: This is bad and slow. */
2265 for (i = 0; i < 96; i++) {
2266 if (CIDC(i) == NULL)
2268 if (silc_idcache_find_by_id(CIDC(i), CIDCC(i), (void *)id,
2269 SILC_ID_CHANNEL, &id_cache))
2277 key = silc_channel_key_get_key(payload, &key_len);
2278 cipher = silc_channel_key_get_cipher(payload, NULL);
2280 channel = (SilcChannelEntry)id_cache->context;
2281 channel->key_len = key_len;
2282 channel->key = silc_calloc(key_len, sizeof(*channel->key));
2283 memcpy(channel->key, key, key_len);
2285 silc_cipher_alloc(cipher, &channel->channel_key);
2286 if (!channel->channel_key) {
2287 silc_say(client, "Cannot talk to channel: unsupported cipher %s", cipher);
2290 channel->channel_key->cipher->set_key(channel->channel_key->context,
2293 /* Client is now joined to the channel */
2294 channel->on_channel = TRUE;
2298 silc_channel_key_free_payload(payload);
2303 /* Process received message to a channel (or from a channel, really). This
2304 decrypts the channel message with channel specific key and parses the
2305 channel payload. Finally it displays the message on the screen. */
2307 void silc_client_channel_message(SilcClient client,
2308 SilcSocketConnection sock,
2309 SilcPacketContext *packet)
2312 SilcClientWindow win = (SilcClientWindow)sock->user_data;
2313 SilcBuffer buffer = packet->buffer;
2314 SilcChannelPayload payload = NULL;
2315 SilcChannelID *id = NULL;
2316 SilcChannelEntry channel;
2317 SilcIDCache *id_cache = NULL;
2319 #define CIDC(x) win->channel_id_cache[(x)]
2320 #define CIDCC(x) win->channel_id_cache_count[(x)]
2323 if (packet->dst_id_type != SILC_ID_CHANNEL)
2326 id = silc_id_str2id(packet->dst_id, SILC_ID_CHANNEL);
2328 /* Find the channel entry from channels on this window */
2329 for (i = 0; i < 96; i++) {
2330 if (CIDC(i) == NULL)
2332 if (silc_idcache_find_by_id(CIDC(i), CIDCC(i), (void *)id,
2333 SILC_ID_CHANNEL, &id_cache))
2340 channel = (SilcChannelEntry)id_cache->context;
2342 /* Decrypt the channel message payload. Push the IV out of the way,
2343 since it is not encrypted (after pushing buffer->tail has the IV). */
2344 silc_buffer_push_tail(buffer, 16);
2345 channel->channel_key->cipher->decrypt(channel->channel_key->context,
2346 buffer->data, buffer->data,
2347 buffer->len, buffer->tail);
2348 silc_buffer_pull_tail(buffer, 16);
2350 /* Parse the channel message payload */
2351 payload = silc_channel_parse_payload(buffer);
2355 /* Display the message on screen */
2356 if (packet->src_id_type == SILC_ID_CLIENT)
2357 /* Message from client */
2358 silc_print(client, "<%s> %s", silc_channel_get_nickname(payload, NULL),
2359 silc_channel_get_data(payload, NULL));
2361 /* Message from server */
2362 silc_say(client, "%s", silc_channel_get_data(payload, NULL));
2368 silc_channel_free_payload(payload);