5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2002 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; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
21 #include "silcincludes.h"
22 #include "silcclient.h"
23 #include "client_internal.h"
25 /* Static task callback prototypes */
26 SILC_TASK_CALLBACK(silc_client_connect_to_server_start);
27 SILC_TASK_CALLBACK(silc_client_connect_to_server_second);
28 SILC_TASK_CALLBACK(silc_client_connect_to_server_final);
29 SILC_TASK_CALLBACK(silc_client_rekey_callback);
30 SILC_TASK_CALLBACK(silc_client_rekey_final);
32 static bool silc_client_packet_parse(SilcPacketParserContext *parser_context,
34 static void silc_client_packet_parse_type(SilcClient client,
35 SilcSocketConnection sock,
36 SilcPacketContext *packet);
37 void silc_client_resolve_auth_method(bool success,
38 SilcProtocolAuthMeth auth_meth,
39 const unsigned char *auth_data,
40 SilcUInt32 auth_data_len, void *context);
42 /* Allocates new client object. This has to be done before client may
43 work. After calling this one must call silc_client_init to initialize
44 the client. The `application' is application specific user data pointer
45 and caller must free it. */
47 SilcClient silc_client_alloc(SilcClientOperations *ops,
48 SilcClientParams *params,
50 const char *silc_version)
52 SilcClient new_client;
54 new_client = silc_calloc(1, sizeof(*new_client));
55 new_client->application = application;
57 new_client->internal = silc_calloc(1, sizeof(*new_client->internal));
58 new_client->internal->ops = ops;
59 new_client->internal->params =
60 silc_calloc(1, sizeof(*new_client->internal->params));
61 new_client->internal->silc_client_version = strdup(silc_version);
64 memcpy(new_client->internal->params, params, sizeof(*params));
66 if (!new_client->internal->params->task_max)
67 new_client->internal->params->task_max = 200;
69 if (!new_client->internal->params->rekey_secs)
70 new_client->internal->params->rekey_secs = 3600;
72 if (!new_client->internal->params->connauth_request_secs)
73 new_client->internal->params->connauth_request_secs = 2;
75 new_client->internal->params->
76 nickname_format[sizeof(new_client->internal->
77 params->nickname_format) - 1] = 0;
82 /* Frees client object and its internals. */
84 void silc_client_free(SilcClient client)
88 silc_rng_free(client->rng);
90 silc_free(client->internal->params);
91 silc_free(client->internal->silc_client_version);
92 silc_free(client->internal);
97 /* Initializes the client. This makes all the necessary steps to make
98 the client ready to be run. One must call silc_client_run to run the
99 client. Returns FALSE if error occured, TRUE otherwise. */
101 int silc_client_init(SilcClient client)
103 SILC_LOG_DEBUG(("Initializing client"));
105 /* Initialize hash functions for client to use */
106 silc_hash_alloc("md5", &client->md5hash);
107 silc_hash_alloc("sha1", &client->sha1hash);
109 /* Initialize none cipher */
110 silc_cipher_alloc("none", &client->internal->none_cipher);
112 /* Initialize random number generator */
113 client->rng = silc_rng_alloc();
114 silc_rng_init(client->rng);
115 silc_rng_global_init(client->rng);
117 /* Register protocols */
118 silc_client_protocols_register();
120 /* Initialize the scheduler */
122 silc_schedule_init(client->internal->params->task_max ?
123 client->internal->params->task_max : 200, client);
124 if (!client->schedule)
127 /* Register commands */
128 silc_client_commands_register(client);
133 /* Stops the client. This is called to stop the client and thus to stop
136 void silc_client_stop(SilcClient client)
138 SILC_LOG_DEBUG(("Stopping client"));
140 silc_schedule_stop(client->schedule);
141 silc_schedule_uninit(client->schedule);
143 silc_client_protocols_unregister();
144 silc_client_commands_unregister(client);
146 SILC_LOG_DEBUG(("Client stopped"));
149 /* Runs the client. This starts the scheduler from the utility library.
150 When this functions returns the execution of the appliation is over. */
152 void silc_client_run(SilcClient client)
154 SILC_LOG_DEBUG(("Running client"));
156 /* Start the scheduler, the heart of the SILC client. When this returns
157 the program will be terminated. */
158 silc_schedule(client->schedule);
161 /* Runs the client and returns immeadiately. This function is used when
162 the SILC Client object indicated by the `client' is run under some
163 other scheduler, or event loop or main loop. On GUI applications,
164 for example this may be desired to use to run the client under the
165 GUI application's main loop. Typically the GUI application would
166 register an idle task that calls this function multiple times in
167 a second to quickly process the SILC specific data. */
169 void silc_client_run_one(SilcClient client)
171 /* Run the scheduler once. */
172 silc_schedule_one(client->schedule, 0);
175 static void silc_client_entry_destructor(SilcIDCache cache,
176 SilcIDCacheEntry entry)
178 silc_free(entry->name);
181 /* Allocates and adds new connection to the client. This adds the allocated
182 connection to the connection table and returns a pointer to it. A client
183 can have multiple connections to multiple servers. Every connection must
184 be added to the client using this function. User data `context' may
185 be sent as argument. This function is normally used only if the
186 application performed the connecting outside the library. The library
187 however may use this internally. */
190 silc_client_add_connection(SilcClient client,
191 SilcClientConnectionParams *params,
192 char *hostname, int port, void *context)
194 SilcClientConnection conn;
197 SILC_LOG_DEBUG(("Adding new connection to %s:%d", hostname, port));
199 conn = silc_calloc(1, sizeof(*conn));
201 /* Initialize ID caches */
202 conn->client_cache = silc_idcache_alloc(0, SILC_ID_CLIENT,
203 silc_client_entry_destructor);
204 conn->channel_cache = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
205 conn->server_cache = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
206 conn->client = client;
207 conn->remote_host = strdup(hostname);
208 conn->remote_port = port;
209 conn->context = context;
210 conn->pending_commands = silc_dlist_init();
211 conn->ftp_sessions = silc_dlist_init();
214 if (params->detach_data)
215 conn->params.detach_data = silc_memdup(params->detach_data,
216 params->detach_data_len);
217 conn->params.detach_data_len = params->detach_data_len;
220 /* Add the connection to connections table */
221 for (i = 0; i < client->internal->conns_count; i++)
222 if (client->internal->conns && !client->internal->conns[i]) {
223 client->internal->conns[i] = conn;
227 client->internal->conns =
228 silc_realloc(client->internal->conns, sizeof(*client->internal->conns)
229 * (client->internal->conns_count + 1));
230 client->internal->conns[client->internal->conns_count] = conn;
231 client->internal->conns_count++;
236 /* Removes connection from client. Frees all memory. */
238 void silc_client_del_connection(SilcClient client, SilcClientConnection conn)
242 for (i = 0; i < client->internal->conns_count; i++)
243 if (client->internal->conns[i] == conn) {
245 silc_idcache_free(conn->client_cache);
246 silc_idcache_free(conn->channel_cache);
247 silc_idcache_free(conn->server_cache);
248 if (conn->pending_commands)
249 silc_dlist_uninit(conn->pending_commands);
250 silc_free(conn->remote_host);
251 if (conn->ftp_sessions)
252 silc_dlist_uninit(conn->ftp_sessions);
255 client->internal->conns[i] = NULL;
259 /* Adds listener socket to the listener sockets table. This function is
260 used to add socket objects that are listeners to the client. This should
261 not be used to add other connection objects. */
263 void silc_client_add_socket(SilcClient client, SilcSocketConnection sock)
267 if (!client->internal->sockets) {
268 client->internal->sockets =
269 silc_calloc(1, sizeof(*client->internal->sockets));
270 client->internal->sockets[0] = silc_socket_dup(sock);
271 client->internal->sockets_count = 1;
275 for (i = 0; i < client->internal->sockets_count; i++) {
276 if (client->internal->sockets[i] == NULL) {
277 client->internal->sockets[i] = silc_socket_dup(sock);
282 client->internal->sockets =
283 silc_realloc(client->internal->sockets,
284 sizeof(*client->internal->sockets) *
285 (client->internal->sockets_count + 1));
286 client->internal->sockets[client->internal->sockets_count] =
287 silc_socket_dup(sock);
288 client->internal->sockets_count++;
291 /* Deletes listener socket from the listener sockets table. */
293 void silc_client_del_socket(SilcClient client, SilcSocketConnection sock)
297 if (!client->internal->sockets)
300 for (i = 0; i < client->internal->sockets_count; i++) {
301 if (client->internal->sockets[i] == sock) {
302 silc_socket_free(sock);
303 client->internal->sockets[i] = NULL;
310 silc_client_connect_to_server_internal(SilcClientInternalConnectContext *ctx)
314 /* XXX In the future we should give up this non-blocking connect all
315 together and use threads instead. */
316 /* Create connection to server asynchronously */
317 sock = silc_net_create_connection_async(NULL, ctx->port, ctx->host);
321 /* Register task that will receive the async connect and will
323 ctx->task = silc_schedule_task_add(ctx->client->schedule, sock,
324 silc_client_connect_to_server_start,
327 SILC_TASK_PRI_NORMAL);
328 silc_schedule_set_listen_fd(ctx->client->schedule, sock, SILC_TASK_WRITE);
335 /* Connects to remote server. This is the main routine used to connect
336 to SILC server. Returns -1 on error and the created socket otherwise.
337 The `context' is user context that is saved into the SilcClientConnection
338 that is created after the connection is created. Note that application
339 may handle the connecting process outside the library. If this is the
340 case then this function is not used at all. When the connecting is
341 done the `connect' client operation is called. */
343 int silc_client_connect_to_server(SilcClient client,
344 SilcClientConnectionParams *params,
345 int port, char *host, void *context)
347 SilcClientInternalConnectContext *ctx;
348 SilcClientConnection conn;
351 SILC_LOG_DEBUG(("Connecting to port %d of server %s",
354 conn = silc_client_add_connection(client, params, host, port, context);
356 client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
357 "Connecting to port %d of server %s", port, host);
359 /* Allocate internal context for connection process. This is
360 needed as we are doing async connecting. */
361 ctx = silc_calloc(1, sizeof(*ctx));
362 ctx->client = client;
364 ctx->host = strdup(host);
368 /* Do the actual connecting process */
369 sock = silc_client_connect_to_server_internal(ctx);
371 silc_client_del_connection(client, conn);
375 /* Socket hostname and IP lookup callback that is called before actually
376 starting the key exchange. The lookup is called from the function
377 silc_client_start_key_exchange. */
379 static void silc_client_start_key_exchange_cb(SilcSocketConnection sock,
382 SilcClientConnection conn = (SilcClientConnection)context;
383 SilcClient client = conn->client;
384 SilcProtocol protocol;
385 SilcClientKEInternalContext *proto_ctx;
387 SILC_LOG_DEBUG(("Start"));
389 if (conn->sock->hostname) {
390 silc_free(conn->remote_host);
391 conn->remote_host = strdup(conn->sock->hostname);
393 conn->sock->hostname = strdup(conn->remote_host);
396 conn->sock->ip = strdup(conn->sock->hostname);
397 conn->sock->port = conn->remote_port;
399 /* Allocate internal Key Exchange context. This is sent to the
400 protocol as context. */
401 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
402 proto_ctx->client = (void *)client;
403 proto_ctx->sock = silc_socket_dup(conn->sock);
404 proto_ctx->rng = client->rng;
405 proto_ctx->responder = FALSE;
406 proto_ctx->send_packet = silc_client_protocol_ke_send_packet;
407 proto_ctx->verify = silc_client_protocol_ke_verify_key;
409 /* Perform key exchange protocol. silc_client_connect_to_server_final
410 will be called after the protocol is finished. */
411 silc_protocol_alloc(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
412 &protocol, (void *)proto_ctx,
413 silc_client_connect_to_server_second);
415 client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
416 "Error: Could not start key exchange protocol");
417 silc_net_close_connection(conn->sock->sock);
418 client->internal->ops->connect(client, conn, SILC_CLIENT_CONN_ERROR);
421 conn->sock->protocol = protocol;
423 /* Register the connection for network input and output. This sets
424 that scheduler will listen for incoming packets for this connection
425 and sets that outgoing packets may be sent to this connection as well.
426 However, this doesn't set the scheduler for outgoing traffic, it will
427 be set separately by calling SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT,
428 later when outgoing data is available. */
429 context = (void *)client;
430 SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(conn->sock->sock);
432 /* Execute the protocol */
433 silc_protocol_execute(protocol, client->schedule, 0, 0);
436 /* Start SILC Key Exchange (SKE) protocol to negotiate shared secret
437 key material between client and server. This function can be called
438 directly if application is performing its own connecting and does not
439 use the connecting provided by this library. This function is normally
440 used only if the application performed the connecting outside the library.
441 The library however may use this internally. */
443 void silc_client_start_key_exchange(SilcClient client,
444 SilcClientConnection conn,
447 /* Allocate new socket connection object */
448 silc_socket_alloc(fd, SILC_SOCKET_TYPE_SERVER, (void *)conn, &conn->sock);
450 /* Sometimes when doing quick reconnects the new socket may be same as
451 the old one and there might be pending stuff for the old socket.
452 If new one is same then those pending sutff might cause problems.
453 Make sure they do not do that. */
454 silc_schedule_task_del_by_fd(client->schedule, fd);
456 conn->nickname = (client->nickname ? strdup(client->nickname) :
457 strdup(client->username));
459 /* Resolve the remote hostname and IP address for our socket connection */
460 silc_socket_host_lookup(conn->sock, FALSE, silc_client_start_key_exchange_cb,
461 conn, client->schedule);
464 /* Callback called when error has occurred during connecting (KE) to
465 the server. The `connect' client operation will be called. */
467 SILC_TASK_CALLBACK(silc_client_connect_failure)
469 SilcClientKEInternalContext *ctx =
470 (SilcClientKEInternalContext *)context;
471 SilcClient client = (SilcClient)ctx->client;
473 client->internal->ops->connect(client, ctx->sock->user_data,
474 SILC_CLIENT_CONN_ERROR);
476 silc_packet_context_free(ctx->packet);
480 /* Callback called when error has occurred during connecting (auth) to
481 the server. The `connect' client operation will be called. */
483 SILC_TASK_CALLBACK(silc_client_connect_failure_auth)
485 SilcClientConnAuthInternalContext *ctx =
486 (SilcClientConnAuthInternalContext *)context;
487 SilcClient client = (SilcClient)ctx->client;
489 client->internal->ops->connect(client, ctx->sock->user_data,
490 SILC_CLIENT_CONN_ERROR);
494 /* Start of the connection to the remote server. This is called after
495 succesful TCP/IP connection has been established to the remote host. */
497 SILC_TASK_CALLBACK(silc_client_connect_to_server_start)
499 SilcClientInternalConnectContext *ctx =
500 (SilcClientInternalConnectContext *)context;
501 SilcClient client = ctx->client;
502 SilcClientConnection conn = ctx->conn;
503 int opt, opt_len = sizeof(opt);
505 SILC_LOG_DEBUG(("Start"));
507 /* Check the socket status as it might be in error */
508 silc_net_get_socket_opt(fd, SOL_SOCKET, SO_ERROR, &opt, &opt_len);
510 if (ctx->tries < 2) {
511 /* Connection failed but lets try again */
512 client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
513 "Could not connect to server %s: %s",
514 ctx->host, strerror(opt));
515 client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
516 "Connecting to port %d of server %s resumed",
517 ctx->port, ctx->host);
519 /* Unregister old connection try */
520 silc_schedule_unset_listen_fd(client->schedule, fd);
521 silc_net_close_connection(fd);
522 silc_schedule_task_del(client->schedule, ctx->task);
525 silc_client_connect_to_server_internal(ctx);
528 /* Connection failed and we won't try anymore */
529 client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
530 "Could not connect to server %s: %s",
531 ctx->host, strerror(opt));
532 silc_schedule_unset_listen_fd(client->schedule, fd);
533 silc_net_close_connection(fd);
534 silc_schedule_task_del(client->schedule, ctx->task);
537 /* Notify application of failure */
538 client->internal->ops->connect(client, conn, SILC_CLIENT_CONN_ERROR);
539 silc_client_del_connection(client, conn);
544 silc_schedule_unset_listen_fd(client->schedule, fd);
545 silc_schedule_task_del(client->schedule, ctx->task);
548 silc_client_start_key_exchange(client, conn, fd);
551 /* Second part of the connecting to the server. This executed
552 authentication protocol. */
554 SILC_TASK_CALLBACK(silc_client_connect_to_server_second)
556 SilcProtocol protocol = (SilcProtocol)context;
557 SilcClientKEInternalContext *ctx =
558 (SilcClientKEInternalContext *)protocol->context;
559 SilcClient client = (SilcClient)ctx->client;
560 SilcSocketConnection sock = NULL;
561 SilcClientConnAuthInternalContext *proto_ctx;
563 SILC_LOG_DEBUG(("Start"));
565 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
566 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
567 /* Error occured during protocol */
568 SILC_LOG_DEBUG(("Error during KE protocol"));
569 silc_protocol_free(protocol);
570 silc_ske_free_key_material(ctx->keymat);
572 silc_ske_free(ctx->ske);
574 silc_free(ctx->dest_id);
575 ctx->sock->protocol = NULL;
576 silc_socket_free(ctx->sock);
578 /* Notify application of failure */
579 silc_schedule_task_add(client->schedule, ctx->sock->sock,
580 silc_client_connect_failure, ctx,
581 0, 1, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
585 /* We now have the key material as the result of the key exchange
586 protocol. Take the key material into use. Free the raw key material
587 as soon as we've set them into use. */
588 silc_client_protocol_ke_set_keys(ctx->ske, ctx->sock, ctx->keymat,
589 ctx->ske->prop->cipher,
590 ctx->ske->prop->pkcs,
591 ctx->ske->prop->hash,
592 ctx->ske->prop->hmac,
593 ctx->ske->prop->group,
595 silc_ske_free_key_material(ctx->keymat);
597 /* Allocate internal context for the authentication protocol. This
598 is sent as context for the protocol. */
599 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
600 proto_ctx->client = (void *)client;
601 proto_ctx->sock = sock = ctx->sock;
602 proto_ctx->ske = ctx->ske; /* Save SKE object from previous protocol */
603 proto_ctx->dest_id_type = ctx->dest_id_type;
604 proto_ctx->dest_id = ctx->dest_id;
606 /* Free old protocol as it is finished now */
607 silc_protocol_free(protocol);
609 silc_packet_context_free(ctx->packet);
612 sock->protocol = NULL;
614 /* Resolve the authentication method to be used in this connection. The
615 completion callback is called after the application has resolved
616 the authentication method. */
617 client->internal->ops->get_auth_method(client, sock->user_data,
620 silc_client_resolve_auth_method,
624 /* Authentication method resolving callback. Application calls this function
625 after we've called the client->internal->ops->get_auth_method
626 client operation to resolve the authentication method. We will continue
627 the executiong of the protocol in this function. */
629 void silc_client_resolve_auth_method(bool success,
630 SilcProtocolAuthMeth auth_meth,
631 const unsigned char *auth_data,
632 SilcUInt32 auth_data_len, void *context)
634 SilcClientConnAuthInternalContext *proto_ctx =
635 (SilcClientConnAuthInternalContext *)context;
636 SilcClient client = (SilcClient)proto_ctx->client;
639 auth_meth = SILC_AUTH_NONE;
641 proto_ctx->auth_meth = auth_meth;
643 if (success && auth_data && auth_data_len) {
645 /* Passphrase must be UTF-8 encoded, if it isn't encode it */
646 if (auth_meth == SILC_AUTH_PASSWORD &&
647 !silc_utf8_valid(auth_data, auth_data_len)) {
649 unsigned char *autf8 = NULL;
650 payload_len = silc_utf8_encoded_len(auth_data, auth_data_len,
652 autf8 = silc_calloc(payload_len, sizeof(*autf8));
653 auth_data_len = silc_utf8_encode(auth_data, auth_data_len,
654 SILC_STRING_ASCII, autf8, payload_len);
658 proto_ctx->auth_data = silc_memdup(auth_data, auth_data_len);
659 proto_ctx->auth_data_len = auth_data_len;
662 /* Allocate the authenteication protocol and execute it. */
663 silc_protocol_alloc(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
664 &proto_ctx->sock->protocol, (void *)proto_ctx,
665 silc_client_connect_to_server_final);
667 /* Execute the protocol */
668 silc_protocol_execute(proto_ctx->sock->protocol, client->schedule, 0, 0);
671 /* Finalizes the connection to the remote SILC server. This is called
672 after authentication protocol has been completed. This send our
673 user information to the server to receive our client ID from
676 SILC_TASK_CALLBACK(silc_client_connect_to_server_final)
678 SilcProtocol protocol = (SilcProtocol)context;
679 SilcClientConnAuthInternalContext *ctx =
680 (SilcClientConnAuthInternalContext *)protocol->context;
681 SilcClient client = (SilcClient)ctx->client;
682 SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
685 SILC_LOG_DEBUG(("Start"));
687 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
688 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
689 /* Error occured during protocol */
690 SILC_LOG_DEBUG(("Error during authentication protocol"));
694 if (conn->params.detach_data) {
695 /* Send RESUME_CLIENT packet to the server, which is used to resume
696 old detached session back. */
698 SilcClientID *old_client_id;
699 unsigned char *old_id;
700 SilcUInt16 old_id_len;
702 if (!silc_client_process_detach_data(client, conn, &old_id, &old_id_len))
705 old_client_id = silc_id_str2id(old_id, old_id_len, SILC_ID_CLIENT);
706 if (!old_client_id) {
711 /* Generate authentication data that server will verify */
712 auth = silc_auth_public_key_auth_generate(client->public_key,
714 client->rng, conn->hash,
715 old_client_id, SILC_ID_CLIENT);
717 silc_free(old_client_id);
722 packet = silc_buffer_alloc_size(2 + old_id_len + auth->len);
723 silc_buffer_format(packet,
724 SILC_STR_UI_SHORT(old_id_len),
725 SILC_STR_UI_XNSTRING(old_id, old_id_len),
726 SILC_STR_UI_XNSTRING(auth->data, auth->len),
729 /* Send the packet */
730 silc_client_packet_send(client, ctx->sock, SILC_PACKET_RESUME_CLIENT,
732 packet->data, packet->len, TRUE);
733 silc_buffer_free(packet);
734 silc_buffer_free(auth);
735 silc_free(old_client_id);
738 /* Send NEW_CLIENT packet to the server. We will become registered
739 to the SILC network after sending this packet and we will receive
740 client ID from the server. */
741 packet = silc_buffer_alloc(2 + 2 + strlen(client->username) +
742 strlen(client->realname));
743 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
744 silc_buffer_format(packet,
745 SILC_STR_UI_SHORT(strlen(client->username)),
746 SILC_STR_UI_XNSTRING(client->username,
747 strlen(client->username)),
748 SILC_STR_UI_SHORT(strlen(client->realname)),
749 SILC_STR_UI_XNSTRING(client->realname,
750 strlen(client->realname)),
753 /* Send the packet */
754 silc_client_packet_send(client, ctx->sock, SILC_PACKET_NEW_CLIENT,
756 packet->data, packet->len, TRUE);
757 silc_buffer_free(packet);
760 /* Save remote ID. */
761 conn->remote_id = ctx->dest_id;
762 conn->remote_id_data = silc_id_id2str(ctx->dest_id, SILC_ID_SERVER);
763 conn->remote_id_data_len = silc_id_get_len(ctx->dest_id, SILC_ID_SERVER);
765 /* Register re-key timeout */
766 conn->rekey->timeout = client->internal->params->rekey_secs;
767 conn->rekey->context = (void *)client;
768 silc_schedule_task_add(client->schedule, conn->sock->sock,
769 silc_client_rekey_callback,
770 (void *)conn->sock, conn->rekey->timeout, 0,
771 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
773 silc_protocol_free(protocol);
774 silc_free(ctx->auth_data);
776 silc_ske_free(ctx->ske);
777 silc_socket_free(ctx->sock);
779 conn->sock->protocol = NULL;
783 silc_protocol_free(protocol);
784 silc_free(ctx->auth_data);
785 silc_free(ctx->dest_id);
787 silc_ske_free(ctx->ske);
788 conn->sock->protocol = NULL;
789 silc_socket_free(ctx->sock);
791 /* Notify application of failure */
792 silc_schedule_task_add(client->schedule, ctx->sock->sock,
793 silc_client_connect_failure_auth, ctx,
794 0, 1, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
797 /* Internal routine that sends packet or marks packet to be sent. This
798 is used directly only in special cases. Normal cases should use
799 silc_server_packet_send. Returns < 0 on error. */
801 int silc_client_packet_send_real(SilcClient client,
802 SilcSocketConnection sock,
807 /* If rekey protocol is active we must assure that all packets are
808 sent through packet queue. */
809 if (SILC_CLIENT_IS_REKEY(sock))
812 /* If outbound data is already pending do not force send */
813 if (SILC_IS_OUTBUF_PENDING(sock))
816 /* Send the packet */
817 ret = silc_packet_send(sock, force_send);
821 /* Mark that there is some outgoing data available for this connection.
822 This call sets the connection both for input and output (the input
823 is set always and this call keeps the input setting, actually).
824 Actual data sending is performed by silc_client_packet_process. */
825 SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(client->schedule, sock->sock);
827 /* Mark to socket that data is pending in outgoing buffer. This flag
828 is needed if new data is added to the buffer before the earlier
829 put data is sent to the network. */
830 SILC_SET_OUTBUF_PENDING(sock);
835 /* Packet processing callback. This is used to send and receive packets
836 from network. This is generic task. */
838 SILC_TASK_CALLBACK_GLOBAL(silc_client_packet_process)
840 SilcClient client = (SilcClient)context;
841 SilcSocketConnection sock = NULL;
842 SilcClientConnection conn;
845 SILC_LOG_DEBUG(("Processing packet"));
847 SILC_CLIENT_GET_SOCK(client, fd, sock);
851 conn = (SilcClientConnection)sock->user_data;
854 if (type == SILC_TASK_WRITE) {
855 /* Do not send data to disconnected connection */
856 if (SILC_IS_DISCONNECTED(sock))
859 ret = silc_packet_send(sock, TRUE);
861 /* If returned -2 could not write to connection now, will do
870 /* The packet has been sent and now it is time to set the connection
871 back to only for input. When there is again some outgoing data
872 available for this connection it will be set for output as well.
873 This call clears the output setting and sets it only for input. */
874 SILC_CLIENT_SET_CONNECTION_FOR_INPUT(client->schedule, fd);
875 SILC_UNSET_OUTBUF_PENDING(sock);
877 silc_buffer_clear(sock->outbuf);
881 /* Packet receiving */
882 if (type == SILC_TASK_READ) {
883 /* Read data from network */
884 ret = silc_packet_receive(sock);
890 SILC_LOG_DEBUG(("Read EOF"));
892 /* If connection is disconnecting already we will finally
893 close the connection */
894 if (SILC_IS_DISCONNECTING(sock)) {
895 if (sock == conn->sock && sock->type != SILC_SOCKET_TYPE_CLIENT)
896 client->internal->ops->disconnect(client, conn, 0, NULL);
897 silc_client_close_connection_real(client, sock, conn);
901 SILC_LOG_DEBUG(("EOF from connection %d", sock->sock));
902 if (sock == conn->sock && sock->type != SILC_SOCKET_TYPE_CLIENT)
903 client->internal->ops->disconnect(client, conn, 0, NULL);
904 silc_client_close_connection_real(client, sock, conn);
908 /* Process the packet. This will call the parser that will then
909 decrypt and parse the packet. */
910 if (sock->type != SILC_SOCKET_TYPE_UNKNOWN)
911 silc_packet_receive_process(sock, FALSE, conn->receive_key,
912 conn->hmac_receive, conn->psn_receive,
913 silc_client_packet_parse, client);
915 silc_packet_receive_process(sock, FALSE, NULL, NULL, 0,
916 silc_client_packet_parse, client);
920 /* Parser callback called by silc_packet_receive_process. Thie merely
921 registers timeout that will handle the actual parsing when appropriate. */
923 static bool silc_client_packet_parse(SilcPacketParserContext *parser_context,
926 SilcClient client = (SilcClient)context;
927 SilcSocketConnection sock = parser_context->sock;
928 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
929 SilcPacketContext *packet = parser_context->packet;
932 if (conn && conn->hmac_receive && conn->sock == sock)
933 conn->psn_receive = parser_context->packet->sequence + 1;
935 /* Parse the packet immediately */
936 if (parser_context->normal)
937 ret = silc_packet_parse(packet, conn->receive_key);
939 ret = silc_packet_parse_special(packet, conn->receive_key);
941 if (ret == SILC_PACKET_NONE) {
942 silc_packet_context_free(packet);
943 silc_free(parser_context);
947 /* If protocol for this connection is key exchange or rekey then we'll
948 process all packets synchronously, since there might be packets in
949 queue that we are not able to decrypt without first processing the
950 packets before them. */
951 if ((ret == SILC_PACKET_REKEY || ret == SILC_PACKET_REKEY_DONE) ||
952 (sock->protocol && sock->protocol->protocol &&
953 (sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE ||
954 sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY))) {
956 /* Parse the incoming packet type */
957 silc_client_packet_parse_type(client, sock, packet);
958 silc_packet_context_free(packet);
959 silc_free(parser_context);
961 /* Reprocess the buffer since we'll return FALSE. This is because
962 the `conn->receive_key' might have become valid by processing
963 the previous packet */
964 if (sock->type != SILC_SOCKET_TYPE_UNKNOWN)
965 silc_packet_receive_process(sock, FALSE, conn->receive_key,
966 conn->hmac_receive, conn->psn_receive,
967 silc_client_packet_parse, client);
969 silc_packet_receive_process(sock, FALSE, NULL, NULL, 0,
970 silc_client_packet_parse, client);
975 /* Parse the incoming packet type */
976 silc_client_packet_parse_type(client, sock, packet);
977 silc_packet_context_free(packet);
978 silc_free(parser_context);
982 /* Parses the packet type and calls what ever routines the packet type
983 requires. This is done for all incoming packets. */
985 void silc_client_packet_parse_type(SilcClient client,
986 SilcSocketConnection sock,
987 SilcPacketContext *packet)
989 SilcBuffer buffer = packet->buffer;
990 SilcPacketType type = packet->type;
992 SILC_LOG_DEBUG(("Parsing %s packet", silc_get_packet_name(type)));
994 /* Parse the packet type */
997 case SILC_PACKET_DISCONNECT:
998 silc_client_disconnected_by_server(client, sock, buffer);
1001 case SILC_PACKET_SUCCESS:
1003 * Success received for something. For now we can have only
1004 * one protocol for connection executing at once hence this
1005 * success message is for whatever protocol is executing currently.
1008 silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
1011 case SILC_PACKET_FAILURE:
1013 * Failure received for some protocol. Set the protocol state to
1014 * error and call the protocol callback. This fill cause error on
1015 * protocol and it will call the final callback.
1017 silc_client_process_failure(client, sock, packet);
1020 case SILC_PACKET_REJECT:
1023 case SILC_PACKET_NOTIFY:
1025 * Received notify message
1027 silc_client_notify_by_server(client, sock, packet);
1030 case SILC_PACKET_ERROR:
1032 * Received error message
1034 silc_client_error_by_server(client, sock, buffer);
1037 case SILC_PACKET_CHANNEL_MESSAGE:
1039 * Received message to (from, actually) a channel
1041 silc_client_channel_message(client, sock, packet);
1044 case SILC_PACKET_CHANNEL_KEY:
1046 * Received key for a channel. By receiving this key the client will be
1047 * able to talk to the channel it has just joined. This can also be
1048 * a new key for existing channel as keys expire peridiocally.
1050 silc_client_receive_channel_key(client, sock, buffer);
1053 case SILC_PACKET_PRIVATE_MESSAGE:
1055 * Received private message
1057 silc_client_private_message(client, sock, packet);
1060 case SILC_PACKET_PRIVATE_MESSAGE_KEY:
1062 * Received private message key
1066 case SILC_PACKET_COMMAND:
1068 * Received command packet, a special case since normally client
1069 * does not receive commands.
1071 silc_client_command_process(client, sock, packet);
1074 case SILC_PACKET_COMMAND_REPLY:
1076 * Recived reply for a command
1078 silc_client_command_reply_process(client, sock, packet);
1081 case SILC_PACKET_KEY_EXCHANGE:
1082 if (sock->protocol && sock->protocol->protocol &&
1083 sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE) {
1084 SilcClientKEInternalContext *proto_ctx =
1085 (SilcClientKEInternalContext *)sock->protocol->context;
1087 proto_ctx->packet = silc_packet_context_dup(packet);
1088 proto_ctx->dest_id_type = packet->src_id_type;
1089 proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1090 packet->src_id_type);
1091 if (!proto_ctx->dest_id)
1094 /* Let the protocol handle the packet */
1095 silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
1097 SILC_LOG_ERROR(("Received Key Exchange packet but no key exchange "
1098 "protocol active, packet dropped."));
1102 case SILC_PACKET_KEY_EXCHANGE_1:
1103 if (sock->protocol && sock->protocol->protocol &&
1104 (sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE ||
1105 sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY)) {
1107 if (sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY) {
1108 SilcClientRekeyInternalContext *proto_ctx =
1109 (SilcClientRekeyInternalContext *)sock->protocol->context;
1111 if (proto_ctx->packet)
1112 silc_packet_context_free(proto_ctx->packet);
1114 proto_ctx->packet = silc_packet_context_dup(packet);
1116 /* Let the protocol handle the packet */
1117 silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
1119 SilcClientKEInternalContext *proto_ctx =
1120 (SilcClientKEInternalContext *)sock->protocol->context;
1122 if (proto_ctx->packet)
1123 silc_packet_context_free(proto_ctx->packet);
1125 proto_ctx->packet = silc_packet_context_dup(packet);
1126 proto_ctx->dest_id_type = packet->src_id_type;
1127 proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1128 packet->src_id_type);
1129 if (!proto_ctx->dest_id)
1132 /* Let the protocol handle the packet */
1133 silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
1136 SILC_LOG_ERROR(("Received Key Exchange 1 packet but no key exchange "
1137 "protocol active, packet dropped."));
1141 case SILC_PACKET_KEY_EXCHANGE_2:
1142 if (sock->protocol && sock->protocol->protocol &&
1143 (sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE ||
1144 sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY)) {
1146 if (sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY) {
1147 SilcClientRekeyInternalContext *proto_ctx =
1148 (SilcClientRekeyInternalContext *)sock->protocol->context;
1150 if (proto_ctx->packet)
1151 silc_packet_context_free(proto_ctx->packet);
1153 proto_ctx->packet = silc_packet_context_dup(packet);
1155 /* Let the protocol handle the packet */
1156 silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
1158 SilcClientKEInternalContext *proto_ctx =
1159 (SilcClientKEInternalContext *)sock->protocol->context;
1161 if (proto_ctx->packet)
1162 silc_packet_context_free(proto_ctx->packet);
1163 if (proto_ctx->dest_id)
1164 silc_free(proto_ctx->dest_id);
1165 proto_ctx->packet = silc_packet_context_dup(packet);
1166 proto_ctx->dest_id_type = packet->src_id_type;
1167 proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1168 packet->src_id_type);
1169 if (!proto_ctx->dest_id)
1172 /* Let the protocol handle the packet */
1173 silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
1176 SILC_LOG_ERROR(("Received Key Exchange 2 packet but no key exchange "
1177 "protocol active, packet dropped."));
1181 case SILC_PACKET_NEW_ID:
1184 * Received new ID from server. This packet is received at
1185 * the connection to the server. New ID is also received when
1186 * user changes nickname but in that case the new ID is received
1187 * as command reply and not as this packet type.
1191 idp = silc_id_payload_parse(buffer->data, buffer->len);
1194 if (silc_id_payload_get_type(idp) != SILC_ID_CLIENT)
1197 silc_client_receive_new_id(client, sock, idp);
1198 silc_id_payload_free(idp);
1202 case SILC_PACKET_HEARTBEAT:
1204 * Received heartbeat packet
1206 SILC_LOG_DEBUG(("Heartbeat packet"));
1209 case SILC_PACKET_KEY_AGREEMENT:
1211 * Received key agreement packet
1213 SILC_LOG_DEBUG(("Key agreement packet"));
1214 silc_client_key_agreement(client, sock, packet);
1217 case SILC_PACKET_REKEY:
1218 SILC_LOG_DEBUG(("Re-key packet"));
1219 /* We ignore this for now */
1222 case SILC_PACKET_REKEY_DONE:
1223 SILC_LOG_DEBUG(("Re-key done packet"));
1225 if (sock->protocol && sock->protocol->protocol &&
1226 sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY) {
1228 SilcClientRekeyInternalContext *proto_ctx =
1229 (SilcClientRekeyInternalContext *)sock->protocol->context;
1231 if (proto_ctx->packet)
1232 silc_packet_context_free(proto_ctx->packet);
1234 proto_ctx->packet = silc_packet_context_dup(packet);
1236 /* Let the protocol handle the packet */
1237 if (proto_ctx->responder == FALSE)
1238 silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
1240 /* Let the protocol handle the packet */
1241 silc_protocol_execute(sock->protocol, client->schedule,
1244 SILC_LOG_ERROR(("Received Re-key done packet but no re-key "
1245 "protocol active, packet dropped."));
1249 case SILC_PACKET_CONNECTION_AUTH_REQUEST:
1251 * Reveived reply to our connection authentication method request
1252 * packet. This is used to resolve the authentication method for the
1253 * current session from the server if the client does not know it.
1255 silc_client_connection_auth_request(client, sock, packet);
1258 case SILC_PACKET_FTP:
1259 /* Received file transfer packet. */
1260 silc_client_ftp(client, sock, packet);
1264 SILC_LOG_DEBUG(("Incorrect packet type %d, packet dropped", type));
1269 /* Sends packet. This doesn't actually send the packet instead it assembles
1270 it and marks it to be sent. However, if force_send is TRUE the packet
1271 is sent immediately. if dst_id, cipher and hmac are NULL those parameters
1272 will be derived from sock argument. Otherwise the valid arguments sent
1275 void silc_client_packet_send(SilcClient client,
1276 SilcSocketConnection sock,
1277 SilcPacketType type,
1279 SilcIdType dst_id_type,
1282 unsigned char *data,
1283 SilcUInt32 data_len,
1286 SilcPacketContext packetdata;
1287 const SilcBufferStruct packet;
1289 SilcUInt32 sequence = 0;
1294 SILC_LOG_DEBUG(("Sending packet, type %d", type));
1296 /* Get data used in the packet sending, keys and stuff */
1297 if ((!cipher || !hmac || !dst_id) && sock->user_data) {
1298 if (!cipher && ((SilcClientConnection)sock->user_data)->send_key)
1299 cipher = ((SilcClientConnection)sock->user_data)->send_key;
1301 if (!hmac && ((SilcClientConnection)sock->user_data)->hmac_send)
1302 hmac = ((SilcClientConnection)sock->user_data)->hmac_send;
1304 if (!dst_id && ((SilcClientConnection)sock->user_data)->remote_id) {
1305 dst_id = ((SilcClientConnection)sock->user_data)->remote_id;
1306 dst_id_type = SILC_ID_SERVER;
1310 sequence = ((SilcClientConnection)sock->user_data)->psn_send++;
1313 block_len = cipher ? silc_cipher_get_block_len(cipher) : 0;
1315 /* Set the packet context pointers */
1316 packetdata.flags = 0;
1317 packetdata.type = type;
1318 if (sock->user_data &&
1319 ((SilcClientConnection)sock->user_data)->local_id_data) {
1320 packetdata.src_id = ((SilcClientConnection)sock->user_data)->local_id_data;
1321 packetdata.src_id_len =
1322 silc_id_get_len(((SilcClientConnection)sock->user_data)->local_id,
1325 packetdata.src_id = silc_calloc(SILC_ID_CLIENT_LEN, sizeof(unsigned char));
1326 packetdata.src_id_len = SILC_ID_CLIENT_LEN;
1328 packetdata.src_id_type = SILC_ID_CLIENT;
1330 packetdata.dst_id = silc_id_id2str(dst_id, dst_id_type);
1331 packetdata.dst_id_len = silc_id_get_len(dst_id, dst_id_type);
1332 packetdata.dst_id_type = dst_id_type;
1334 packetdata.dst_id = NULL;
1335 packetdata.dst_id_len = 0;
1336 packetdata.dst_id_type = SILC_ID_NONE;
1338 data_len = SILC_PACKET_DATALEN(data_len, (SILC_PACKET_HEADER_LEN +
1339 packetdata.src_id_len +
1340 packetdata.dst_id_len));
1341 packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN +
1342 packetdata.src_id_len + packetdata.dst_id_len;
1343 packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen, block_len);
1345 /* Create the outgoing packet */
1346 if (!silc_packet_assemble(&packetdata, client->rng, cipher, hmac, sock,
1347 data, data_len, (const SilcBuffer)&packet)) {
1348 SILC_LOG_ERROR(("Error assembling packet"));
1352 /* Encrypt the packet */
1354 silc_packet_encrypt(cipher, hmac, sequence, (SilcBuffer)&packet,
1357 SILC_LOG_HEXDUMP(("Packet (%d), len %d", sequence, packet.len),
1358 packet.data, packet.len);
1360 /* Now actually send the packet */
1361 silc_client_packet_send_real(client, sock, force_send);
1364 void silc_client_packet_queue_purge(SilcClient client,
1365 SilcSocketConnection sock)
1367 if (sock && SILC_IS_OUTBUF_PENDING(sock) &&
1368 (SILC_IS_DISCONNECTED(sock) == FALSE)) {
1369 silc_packet_send(sock, TRUE);
1370 SILC_CLIENT_SET_CONNECTION_FOR_INPUT(client->schedule, sock->sock);
1371 SILC_UNSET_OUTBUF_PENDING(sock);
1372 silc_buffer_clear(sock->outbuf);
1376 /* Closes connection to remote end. Free's all allocated data except
1377 for some information such as nickname etc. that are valid at all time.
1378 If the `sock' is NULL then the conn->sock will be used. If `sock' is
1379 provided it will be checked whether the sock and `conn->sock' are the
1380 same (they can be different, ie. a socket can use `conn' as its
1381 connection but `conn->sock' might be actually a different connection
1382 than the `sock'). */
1384 void silc_client_close_connection_real(SilcClient client,
1385 SilcSocketConnection sock,
1386 SilcClientConnection conn)
1390 SILC_LOG_DEBUG(("Start"));
1395 if (!sock || (sock && conn->sock == sock))
1400 /* We won't listen for this connection anymore */
1401 silc_schedule_unset_listen_fd(client->schedule, sock->sock);
1403 /* Unregister all tasks */
1404 silc_schedule_task_del_by_fd(client->schedule, sock->sock);
1406 /* Close the actual connection */
1407 silc_net_close_connection(sock->sock);
1409 /* Cancel any active protocol */
1410 if (sock->protocol) {
1411 if (sock->protocol->protocol->type ==
1412 SILC_PROTOCOL_CLIENT_KEY_EXCHANGE ||
1413 sock->protocol->protocol->type ==
1414 SILC_PROTOCOL_CLIENT_CONNECTION_AUTH) {
1415 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
1416 silc_protocol_execute_final(sock->protocol, client->schedule);
1417 /* The application will recall this function with these protocols
1418 (the ops->connect client operation). */
1421 sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
1422 silc_protocol_execute_final(sock->protocol, client->schedule);
1423 sock->protocol = NULL;
1427 /* Free everything */
1428 if (del && sock->user_data) {
1429 /* Free all cache entries */
1430 SilcIDCacheList list;
1431 SilcIDCacheEntry entry;
1432 SilcClientCommandPending *r;
1435 if (silc_idcache_get_all(conn->client_cache, &list)) {
1436 ret = silc_idcache_list_first(list, &entry);
1438 silc_client_del_client(client, conn, entry->context);
1439 ret = silc_idcache_list_next(list, &entry);
1441 silc_idcache_list_free(list);
1444 if (silc_idcache_get_all(conn->channel_cache, &list)) {
1445 ret = silc_idcache_list_first(list, &entry);
1447 silc_client_del_channel(client, conn, entry->context);
1448 ret = silc_idcache_list_next(list, &entry);
1450 silc_idcache_list_free(list);
1453 if (silc_idcache_get_all(conn->server_cache, &list)) {
1454 ret = silc_idcache_list_first(list, &entry);
1456 silc_client_del_server(client, conn, entry->context);
1457 ret = silc_idcache_list_next(list, &entry);
1459 silc_idcache_list_free(list);
1462 /* Clear ID caches */
1463 if (conn->client_cache)
1464 silc_idcache_free(conn->client_cache);
1465 if (conn->channel_cache)
1466 silc_idcache_free(conn->channel_cache);
1467 if (conn->server_cache)
1468 silc_idcache_free(conn->server_cache);
1470 /* Free data (my ID is freed in above silc_client_del_client).
1471 conn->nickname is freed when freeing the local_entry->nickname. */
1472 if (conn->remote_host)
1473 silc_free(conn->remote_host);
1474 if (conn->local_id_data)
1475 silc_free(conn->local_id_data);
1477 silc_cipher_free(conn->send_key);
1478 if (conn->receive_key)
1479 silc_cipher_free(conn->receive_key);
1480 if (conn->hmac_send)
1481 silc_hmac_free(conn->hmac_send);
1482 if (conn->hmac_receive)
1483 silc_hmac_free(conn->hmac_receive);
1485 silc_free(conn->rekey);
1487 if (conn->active_session) {
1488 sock->user_data = NULL;
1489 silc_client_ftp_session_free(conn->active_session);
1490 conn->active_session = NULL;
1493 silc_client_ftp_free_sessions(client, conn);
1495 silc_dlist_start(conn->pending_commands);
1496 while ((r = silc_dlist_get(conn->pending_commands)) != SILC_LIST_END)
1497 silc_dlist_del(conn->pending_commands, r);
1498 if (conn->pending_commands)
1499 silc_dlist_uninit(conn->pending_commands);
1501 memset(conn, 0, sizeof(*conn));
1502 silc_client_del_connection(client, conn);
1505 silc_socket_free(sock);
1508 /* Closes the connection to the remote end */
1510 void silc_client_close_connection(SilcClient client,
1511 SilcClientConnection conn)
1513 silc_client_close_connection_real(client, NULL, conn);
1516 /* Called when we receive disconnection packet from server. This
1517 closes our end properly and displays the reason of the disconnection
1520 SILC_TASK_CALLBACK(silc_client_disconnected_by_server_later)
1522 SilcClient client = (SilcClient)context;
1523 SilcSocketConnection sock;
1525 SILC_CLIENT_GET_SOCK(client, fd, sock);
1529 silc_client_close_connection_real(client, sock, sock->user_data);
1532 /* Called when we receive disconnection packet from server. This
1533 closes our end properly and displays the reason of the disconnection
1536 void silc_client_disconnected_by_server(SilcClient client,
1537 SilcSocketConnection sock,
1540 SilcClientConnection conn;
1542 char *message = NULL;
1544 SILC_LOG_DEBUG(("Server disconnected us, sock %d", sock->sock));
1546 if (packet->len < 1)
1549 status = (SilcStatus)packet->data[0];
1551 if (packet->len > 1 &&
1552 silc_utf8_valid(packet->data + 1, packet->len - 1))
1553 message = silc_memdup(packet->data + 1, packet->len - 1);
1555 conn = (SilcClientConnection)sock->user_data;
1556 if (sock == conn->sock && sock->type != SILC_SOCKET_TYPE_CLIENT)
1557 client->internal->ops->disconnect(client, conn, status, message);
1561 SILC_SET_DISCONNECTED(sock);
1563 /* Close connection through scheduler. */
1564 silc_schedule_task_add(client->schedule, sock->sock,
1565 silc_client_disconnected_by_server_later,
1566 client, 0, 1, SILC_TASK_TIMEOUT,
1567 SILC_TASK_PRI_NORMAL);
1570 /* Received error message from server. Display it on the screen.
1571 We don't take any action what so ever of the error message. */
1573 void silc_client_error_by_server(SilcClient client,
1574 SilcSocketConnection sock,
1579 msg = silc_memdup(message->data, message->len);
1580 client->internal->ops->say(client, sock->user_data,
1581 SILC_CLIENT_MESSAGE_AUDIT, msg);
1585 /* Auto-nicking callback to send NICK command to server. */
1587 SILC_TASK_CALLBACK(silc_client_send_auto_nick)
1589 SilcClientConnection conn = (SilcClientConnection)context;
1590 SilcClient client = conn->client;
1592 silc_client_command_send(client, conn, SILC_COMMAND_NICK,
1593 ++conn->cmd_ident, 1, 1,
1594 client->nickname, strlen(client->nickname));
1597 /* Client session resuming callback. If the session was resumed
1598 this callback is called after the resuming is completed. This
1599 will call the `connect' client operation to the application
1600 since it has not been called yet. */
1602 static void silc_client_resume_session_cb(SilcClient client,
1603 SilcClientConnection conn,
1609 /* Notify application that connection is created to server */
1610 client->internal->ops->connect(client, conn, success ?
1611 SILC_CLIENT_CONN_SUCCESS_RESUME :
1612 SILC_CLIENT_CONN_ERROR);
1615 /* Issue INFO command to fetch the real server name and server
1616 information and other stuff. */
1617 silc_client_command_register(client, SILC_COMMAND_INFO, NULL, NULL,
1618 silc_client_command_reply_info_i, 0,
1620 sidp = silc_id_payload_encode(conn->remote_id, SILC_ID_SERVER);
1621 silc_client_command_send(client, conn, SILC_COMMAND_INFO,
1622 conn->cmd_ident, 1, 2, sidp->data, sidp->len);
1623 silc_buffer_free(sidp);
1627 /* Processes the received new Client ID from server. Old Client ID is
1628 deleted from cache and new one is added. */
1630 void silc_client_receive_new_id(SilcClient client,
1631 SilcSocketConnection sock,
1634 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
1635 int connecting = FALSE;
1636 SilcClientID *client_id = silc_id_payload_get_id(idp);
1638 if (!conn->local_entry)
1641 /* Delete old ID from ID cache */
1642 if (conn->local_id) {
1643 /* Check whether they are different */
1644 if (SILC_ID_CLIENT_COMPARE(conn->local_id, client_id)) {
1645 silc_free(client_id);
1649 silc_idcache_del_by_context(conn->client_cache, conn->local_entry);
1650 silc_free(conn->local_id);
1653 /* Save the new ID */
1655 if (conn->local_id_data)
1656 silc_free(conn->local_id_data);
1658 conn->local_id = client_id;
1659 conn->local_id_data = silc_id_payload_get_data(idp);
1660 conn->local_id_data_len = silc_id_payload_get_len(idp);;
1662 if (!conn->local_entry)
1663 conn->local_entry = silc_calloc(1, sizeof(*conn->local_entry));
1665 conn->local_entry->nickname = conn->nickname;
1666 if (!conn->local_entry->username)
1667 conn->local_entry->username = strdup(client->username);
1668 if (!conn->local_entry->server)
1669 conn->local_entry->server = strdup(conn->remote_host);
1670 conn->local_entry->id = conn->local_id;
1671 conn->local_entry->valid = TRUE;
1672 if (!conn->local_entry->channels)
1673 conn->local_entry->channels = silc_hash_table_alloc(1, silc_hash_ptr,
1678 /* Put it to the ID cache */
1679 silc_idcache_add(conn->client_cache, strdup(conn->nickname), conn->local_id,
1680 (void *)conn->local_entry, 0, NULL);
1685 /* Issue IDENTIFY command for itself to get resolved hostname
1686 correctly from server. */
1687 silc_client_command_register(client, SILC_COMMAND_IDENTIFY, NULL, NULL,
1688 silc_client_command_reply_identify_i, 0,
1690 sidp = silc_id_payload_encode(conn->local_entry->id, SILC_ID_CLIENT);
1691 silc_client_command_send(client, conn, SILC_COMMAND_IDENTIFY,
1692 conn->cmd_ident, 1, 5, sidp->data, sidp->len);
1693 silc_buffer_free(sidp);
1695 if (!conn->params.detach_data) {
1696 /* Send NICK command if the nickname was set by the application (and is
1697 not same as the username). Send this with little timeout. */
1698 if (client->nickname && strcmp(client->nickname, client->username))
1699 silc_schedule_task_add(client->schedule, 0,
1700 silc_client_send_auto_nick, conn,
1701 1, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
1703 /* Notify application of successful connection. We do it here now that
1704 we've received the Client ID and are allowed to send traffic. */
1705 client->internal->ops->connect(client, conn, SILC_CLIENT_CONN_SUCCESS);
1707 /* Issue INFO command to fetch the real server name and server
1708 information and other stuff. */
1709 silc_client_command_register(client, SILC_COMMAND_INFO, NULL, NULL,
1710 silc_client_command_reply_info_i, 0,
1712 sidp = silc_id_payload_encode(conn->remote_id, SILC_ID_SERVER);
1713 silc_client_command_send(client, conn, SILC_COMMAND_INFO,
1714 conn->cmd_ident, 1, 2, sidp->data, sidp->len);
1715 silc_buffer_free(sidp);
1717 /* We are resuming session. Start resolving informations from the
1718 server we need to set the client libary in the state before
1719 detaching the session. The connect client operation is called
1720 after this is successfully completed */
1721 silc_client_resume_session(client, conn, silc_client_resume_session_cb,
1727 /* Removes a client entry from all channels it has joined. */
1729 void silc_client_remove_from_channels(SilcClient client,
1730 SilcClientConnection conn,
1731 SilcClientEntry client_entry)
1733 SilcHashTableList htl;
1734 SilcChannelUser chu;
1736 silc_hash_table_list(client_entry->channels, &htl);
1737 while (silc_hash_table_get(&htl, NULL, (void **)&chu)) {
1738 silc_hash_table_del(chu->client->channels, chu->channel);
1739 silc_hash_table_del(chu->channel->user_list, chu->client);
1743 silc_hash_table_list_reset(&htl);
1746 /* Replaces `old' client entries from all channels to `new' client entry.
1747 This can be called for example when nickname changes and old ID entry
1748 is replaced from ID cache with the new one. If the old ID entry is only
1749 updated, then this fucntion needs not to be called. */
1751 void silc_client_replace_from_channels(SilcClient client,
1752 SilcClientConnection conn,
1753 SilcClientEntry old,
1754 SilcClientEntry new)
1756 SilcHashTableList htl;
1757 SilcChannelUser chu;
1759 silc_hash_table_list(old->channels, &htl);
1760 while (silc_hash_table_get(&htl, NULL, (void **)&chu)) {
1761 /* Replace client entry */
1762 silc_hash_table_del(chu->client->channels, chu->channel);
1763 silc_hash_table_del(chu->channel->user_list, chu->client);
1766 silc_hash_table_add(chu->channel->user_list, chu->client, chu);
1767 silc_hash_table_add(chu->client->channels, chu->channel, chu);
1769 silc_hash_table_list_reset(&htl);
1772 /* Registers failure timeout to process the received failure packet
1775 void silc_client_process_failure(SilcClient client,
1776 SilcSocketConnection sock,
1777 SilcPacketContext *packet)
1779 SilcUInt32 failure = 0;
1781 if (sock->protocol) {
1782 if (packet->buffer->len >= 4)
1783 SILC_GET32_MSB(failure, packet->buffer->data);
1785 /* Notify application */
1786 client->internal->ops->failure(client, sock->user_data, sock->protocol,
1791 /* A timeout callback for the re-key. We will be the initiator of the
1794 SILC_TASK_CALLBACK(silc_client_rekey_callback)
1796 SilcSocketConnection sock = (SilcSocketConnection)context;
1797 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
1798 SilcClient client = (SilcClient)conn->rekey->context;
1799 SilcProtocol protocol;
1800 SilcClientRekeyInternalContext *proto_ctx;
1802 SILC_LOG_DEBUG(("Start"));
1804 /* Allocate internal protocol context. This is sent as context
1806 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
1807 proto_ctx->client = (void *)client;
1808 proto_ctx->sock = silc_socket_dup(sock);
1809 proto_ctx->responder = FALSE;
1810 proto_ctx->pfs = conn->rekey->pfs;
1812 /* Perform rekey protocol. Will call the final callback after the
1813 protocol is over. */
1814 silc_protocol_alloc(SILC_PROTOCOL_CLIENT_REKEY,
1815 &protocol, proto_ctx, silc_client_rekey_final);
1816 sock->protocol = protocol;
1818 /* Run the protocol */
1819 silc_protocol_execute(protocol, client->schedule, 0, 0);
1821 /* Re-register re-key timeout */
1822 silc_schedule_task_add(client->schedule, sock->sock,
1823 silc_client_rekey_callback,
1824 context, conn->rekey->timeout, 0,
1825 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
1828 /* The final callback for the REKEY protocol. This will actually take the
1829 new key material into use. */
1831 SILC_TASK_CALLBACK(silc_client_rekey_final)
1833 SilcProtocol protocol = (SilcProtocol)context;
1834 SilcClientRekeyInternalContext *ctx =
1835 (SilcClientRekeyInternalContext *)protocol->context;
1836 SilcClient client = (SilcClient)ctx->client;
1837 SilcSocketConnection sock = ctx->sock;
1839 SILC_LOG_DEBUG(("Start"));
1841 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
1842 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
1843 /* Error occured during protocol */
1844 silc_protocol_cancel(protocol, client->schedule);
1845 silc_protocol_free(protocol);
1846 sock->protocol = NULL;
1848 silc_packet_context_free(ctx->packet);
1850 silc_ske_free(ctx->ske);
1851 silc_socket_free(ctx->sock);
1856 /* Purge the outgoing data queue to assure that all rekey packets really
1857 go to the network before we quit the protocol. */
1858 silc_client_packet_queue_purge(client, sock);
1861 silc_protocol_free(protocol);
1862 sock->protocol = NULL;
1864 silc_packet_context_free(ctx->packet);
1866 silc_ske_free(ctx->ske);
1867 silc_socket_free(ctx->sock);
1871 /* Processes incoming connection authentication method request packet.
1872 It is a reply to our previously sent request. The packet can be used
1873 to resolve the authentication method for the current session if the
1874 client does not know it beforehand. */
1876 void silc_client_connection_auth_request(SilcClient client,
1877 SilcSocketConnection sock,
1878 SilcPacketContext *packet)
1880 SilcClientConnection conn = (SilcClientConnection)sock->user_data;
1881 SilcUInt16 conn_type, auth_meth;
1884 /* If we haven't send our request then ignore this one. */
1885 if (!conn->connauth)
1888 /* Parse the payload */
1889 ret = silc_buffer_unformat(packet->buffer,
1890 SILC_STR_UI_SHORT(&conn_type),
1891 SILC_STR_UI_SHORT(&auth_meth),
1894 auth_meth = SILC_AUTH_NONE;
1896 /* Call the request callback to notify application for received
1897 authentication method information. */
1898 if (conn->connauth->callback)
1899 (*conn->connauth->callback)(client, conn, auth_meth,
1900 conn->connauth->context);
1902 silc_schedule_task_del(client->schedule, conn->connauth->timeout);
1904 silc_free(conn->connauth);
1905 conn->connauth = NULL;
1908 /* Timeout task callback called if the server does not reply to our
1909 connection authentication method request in the specified time interval. */
1911 SILC_TASK_CALLBACK(silc_client_request_authentication_method_timeout)
1913 SilcClientConnection conn = (SilcClientConnection)context;
1914 SilcClient client = conn->client;
1916 if (!conn->connauth)
1919 /* Call the request callback to notify application */
1920 if (conn->connauth->callback)
1921 (*conn->connauth->callback)(client, conn, SILC_AUTH_NONE,
1922 conn->connauth->context);
1924 silc_free(conn->connauth);
1925 conn->connauth = NULL;
1928 /* This function can be used to request the current authentication method
1929 from the server. This may be called when connecting to the server
1930 and the client library requests the authentication data from the
1931 application. If the application does not know the current authentication
1932 method it can request it from the server using this function.
1933 The `callback' with `context' will be called after the server has
1934 replied back with the current authentication method. */
1937 silc_client_request_authentication_method(SilcClient client,
1938 SilcClientConnection conn,
1939 SilcConnectionAuthRequest callback,
1942 SilcClientConnAuthRequest connauth;
1945 connauth = silc_calloc(1, sizeof(*connauth));
1946 connauth->callback = callback;
1947 connauth->context = context;
1950 silc_free(conn->connauth);
1952 conn->connauth = connauth;
1954 /* Assemble the request packet and send it to the server */
1955 packet = silc_buffer_alloc(4);
1956 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
1957 silc_buffer_format(packet,
1958 SILC_STR_UI_SHORT(SILC_SOCKET_TYPE_CLIENT),
1959 SILC_STR_UI_SHORT(SILC_AUTH_NONE),
1961 silc_client_packet_send(client, conn->sock,
1962 SILC_PACKET_CONNECTION_AUTH_REQUEST,
1963 NULL, 0, NULL, NULL,
1964 packet->data, packet->len, FALSE);
1965 silc_buffer_free(packet);
1967 /* Register a timeout in case server does not reply anything back. */
1969 silc_schedule_task_add(client->schedule, conn->sock->sock,
1970 silc_client_request_authentication_method_timeout,
1972 client->internal->params->connauth_request_secs, 0,
1973 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);