5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2001 - 2006 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 "silcclient.h"
22 #include "client_internal.h"
24 /************************** Types and definitions ***************************/
26 /* Key agreement context */
27 struct SilcClientKeyAgreementStruct {
28 SilcClient client; /* Client */
29 SilcClientConnection conn; /* Server connection */
30 SilcKeyAgreementCallback completion; /* Key agreement completion */
31 void *context; /* User context */
34 SilcNetListener listener; /* TCP listener */
35 SilcStream stream; /* Remote connection (TCP or UDP) */
38 SilcClientConnection client_conn; /* Connection to remote client */
41 /************************ Static utility functions **************************/
43 /* TCP network listener callback. Accepts new key agreement connection */
45 static void silc_client_tcp_accept(SilcNetStatus status,
49 SilcClientEntry client_entry = context;
50 SilcClientKeyAgreement ke = client_entry->ke;
53 silc_client_process_key_agreement(ke->client, ke->conn, ke);
56 /* UDP network callback. All UDP packets are read from here. */
58 static void silc_client_udp_accept(SilcStream stream,
59 SilcStreamStatus status,
66 /* Packet sending function used by the SKE in the key agreement process. */
68 static void silc_client_key_agreement_send_packet(SilcSKE ske,
73 SilcProtocol protocol = (SilcProtocol)context;
74 SilcClientKEInternalContext *ctx =
75 (SilcClientKEInternalContext *)protocol->context;
78 /* Send the packet immediately. We will assure that the packet is not
79 encrypted by setting the socket's user_data pointer to NULL. The
80 silc_client_packet_send would take the keys (wrong keys that is,
81 because user_data is the current SilcClientConnection) from it and
82 we cannot allow that. The packets are never encrypted when doing SKE
83 with another client. */
84 tmp = ske->sock->user_data;
85 ske->sock->user_data = NULL;
86 silc_client_packet_send(ctx->client, ske->sock, type, NULL, 0, NULL, NULL,
87 packet->data, packet->len, TRUE);
88 ske->sock->user_data = tmp;
91 /* Timeout callback that is called to close the connection and free the
92 socket connection data. */
94 SILC_TASK_CALLBACK(silc_client_key_agreement_close)
96 SilcClientKeyAgreement ke = (SilcClientKeyAgreement)context;
98 silc_schedule_unset_listen_fd(ke->client->schedule, ke->sock->sock);
99 silc_schedule_unset_listen_fd(ke->client->schedule, ke->fd);
100 silc_net_close_connection(ke->sock->sock);
101 silc_net_close_connection(ke->fd);
102 silc_socket_free(ke->sock);
106 /* This callback is called after the key agreement protocol has been
107 performed. This calls the final completion callback for the application. */
109 SILC_TASK_CALLBACK(silc_client_key_agreement_final)
111 SilcProtocol protocol = (SilcProtocol)context;
112 SilcClientKEInternalContext *ctx =
113 (SilcClientKEInternalContext *)protocol->context;
114 SilcClient client = (SilcClient)ctx->client;
115 SilcClientKeyAgreement ke = (SilcClientKeyAgreement)ctx->context;
117 SILC_LOG_DEBUG(("Start"));
119 if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
120 protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
121 /* Error occured during protocol */
122 ke->client_entry->ke = NULL;
123 ke->completion(ke->client, ke->conn, ke->client_entry,
124 SILC_KEY_AGREEMENT_ERROR, NULL, ke->context);
125 silc_ske_free_key_material(ctx->keymat);
129 /* Pass the negotiated key material to the application. The application
130 is responsible of freeing the key material. */
131 ke->client_entry->ke = NULL;
132 ke->completion(ke->client, ke->conn, ke->client_entry,
133 SILC_KEY_AGREEMENT_OK, ctx->keymat, ke->context);
136 silc_protocol_free(protocol);
138 silc_ske_free(ctx->ske);
140 silc_free(ctx->dest_id);
141 silc_schedule_task_del_by_fd(client->schedule, ke->fd);
142 silc_schedule_unset_listen_fd(ke->client->schedule, ke->fd);
143 silc_net_close_connection(ke->fd);
145 silc_schedule_task_del(client->schedule, ke->timeout);
146 silc_client_del_socket(ke->client, ke->sock);
148 silc_schedule_task_add(client->schedule, 0,
149 silc_client_key_agreement_close,
151 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
156 /* Key agreement callback that is called when remote end has initiated
157 the key agreement protocol. This accepts the incoming TCP/IP connection
158 for the key agreement protocol. */
160 SILC_TASK_CALLBACK(silc_client_process_key_agreement)
162 SilcClientKeyAgreement ke = (SilcClientKeyAgreement)context;
163 SilcClient client = ke->client;
164 SilcClientConnection conn = ke->conn;
165 SilcSocketConnection newsocket;
166 SilcClientKEInternalContext *proto_ctx;
169 SILC_LOG_DEBUG(("Start"));
171 sock = silc_net_accept_connection(ke->fd);
173 client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
174 "Could not accept key agreement connection: ",
176 ke->client_entry->ke = NULL;
177 ke->completion(ke->client, ke->conn, ke->client_entry,
178 SILC_KEY_AGREEMENT_ERROR, NULL, ke->context);
179 silc_schedule_task_del_by_fd(client->schedule, ke->fd);
180 silc_schedule_unset_listen_fd(ke->client->schedule, ke->fd);
181 silc_net_close_connection(ke->fd);
183 silc_schedule_task_del(client->schedule, ke->timeout);
188 /* Set socket options */
189 silc_net_set_socket_nonblock(sock);
190 silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
192 /* Create socket for this connection (it is of type UNKNOWN since this
193 really is not a real SILC connection. It is only for the key
194 agreement protocol). */
195 silc_socket_alloc(sock, SILC_SOCKET_TYPE_UNKNOWN, (void *)conn, &newsocket);
196 ke->sock = newsocket;
198 /* Perform name and address lookups for the remote host. */
199 silc_net_check_host_by_sock(sock, &newsocket->hostname, &newsocket->ip);
200 if (!newsocket->hostname && !newsocket->ip) {
201 client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
202 "Could not resolve the remote IP or hostname");
203 ke->client_entry->ke = NULL;
204 ke->completion(ke->client, ke->conn, ke->client_entry,
205 SILC_KEY_AGREEMENT_ERROR, NULL, ke->context);
206 silc_schedule_task_del_by_fd(client->schedule, ke->fd);
207 silc_schedule_unset_listen_fd(ke->client->schedule, ke->fd);
208 silc_net_close_connection(ke->fd);
210 silc_schedule_task_del(client->schedule, ke->timeout);
214 if (!newsocket->hostname)
215 newsocket->hostname = strdup(newsocket->ip);
216 newsocket->port = silc_net_get_remote_port(sock);
217 silc_client_add_socket(client, newsocket);
219 /* Allocate internal context for key exchange protocol. This is
220 sent as context for the protocol. */
221 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
222 proto_ctx->client = client;
223 proto_ctx->sock = silc_socket_dup(newsocket);
224 proto_ctx->rng = client->rng;
225 proto_ctx->responder = TRUE;
226 proto_ctx->context = context;
227 proto_ctx->send_packet = silc_client_key_agreement_send_packet;
228 proto_ctx->verify = silc_client_protocol_ke_verify_key;
229 ke->proto_ctx = proto_ctx;
231 /* Prepare the connection for key exchange protocol. We allocate the
232 protocol but will not start it yet. The connector will be the
233 initiator of the protocol thus we will wait for initiation from
234 there before we start the protocol. */
235 silc_protocol_alloc(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
236 &newsocket->protocol, proto_ctx,
237 silc_client_key_agreement_final);
239 /* Register the connection for network input and output. This sets
240 that scheduler will listen for incoming packets for this connection
241 and sets that outgoing packets may be sent to this connection as well.
242 However, this doesn't set the scheduler for outgoing traffic, it
243 will be set separately by calling SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT,
244 later when outgoing data is available. */
245 context = (void *)client;
246 SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(sock);
249 /* Timeout occured during key agreement. This means that the key agreement
250 protocol was not completed in the specified timeout. We will call the
251 completion callback. */
253 SILC_TASK_CALLBACK(silc_client_key_agreement_timeout)
255 SilcClientKeyAgreement ke = (SilcClientKeyAgreement)context;
257 ke->client_entry->ke = NULL;
258 ke->completion(ke->client, ke->conn, ke->client_entry,
259 SILC_KEY_AGREEMENT_TIMEOUT, NULL, ke->context);
262 silc_client_del_socket(ke->client, ke->sock);
263 silc_socket_free(ke->sock);
265 if (ke->proto_ctx && ke->proto_ctx->ske)
266 silc_ske_free(ke->proto_ctx->ske);
267 ke->client_entry->ke = NULL;
269 silc_schedule_task_del_by_fd(ke->client->schedule, ke->fd);
270 silc_schedule_unset_listen_fd(ke->client->schedule, ke->fd);
271 silc_net_close_connection(ke->fd);
275 /*************************** Key Agreement API ******************************/
277 /* Sends key agreement packet to remote client. If IP addresses are provided
278 creates also listener for Ãncoming key agreement connection. Supports
279 both TCP and UDP transports. */
281 void silc_client_send_key_agreement(SilcClient client,
282 SilcClientConnection conn,
283 SilcClientEntry client_entry,
284 const char *local_ip,
287 SilcUInt32 timeout_secs,
289 SilcKeyAgreementCallback completion,
292 SilcClientKeyAgreement ke = NULL;
293 SilcAsyncOperation op;
295 SilcUInt16 ports = NULL;
300 if (client_entry->internal->ke) {
301 completion(client, conn, client_entry, SILC_KEY_AGREEMENT_ALREADY_STARTED,
306 if (client_entry == conn->local_entry) {
307 completion(client, conn, client_entry, SILC_KEY_AGREEMENT_SELF_DENIED,
312 /* If local IP is provided, create listener */
313 if (local_ip || bind_ip) {
314 ke = silc_calloc(1, sizeof(*ke));
316 completion(client, conn, client_entry, SILC_KEY_AGREEMENT_NO_MEMORY,
321 /* Create network listener */
325 silc_net_udp_connect(bind_ip ? bind_ip : local_ip, port, NULL, 0,
328 client->internal->ops->say(
329 client, conn, SILC_CLIENT_MESSAGE_ERROR,
330 "Cannot create UDP listener on %s on port %d: %s",
331 bind_ip ? bind_ip : local_ip, port, strerror(errno));
332 completion(client, conn, client_entry, SILC_KEY_AGREEMENT_ERROR,
337 silc_stream_set_notifier(ke->stream, conn->schedule,
338 silc_client_udp_accept, client_entry);
342 silc_net_tcp_create_listener(bind_ip ? &bind_ip :
343 &local_ip, 1, port, FALSE,
344 FALSE, conn->internal->schedule,
345 silc_client_tcp_accept,
348 client->internal->ops->say(
349 client, conn, SILC_CLIENT_MESSAGE_ERROR,
350 "Cannot create listener on %s on port %d: %s",
351 bind_ip ? bind_ip : local_ip, port, strerror(errno));
352 completion(client, conn, client_entry, SILC_KEY_AGREEMENT_ERROR,
361 ke->completion = completion;
362 ke->context = context;
365 /* Add key agreement timeout task */
366 silc_schedule_task_add_timeout(conn->internal->schedule,
367 silc_client_key_agreement_timeout,
368 client_entry, timeout_secs, 0);
370 /* Encode the key agreement payload */
371 if (ke && ke->listener)
372 ports = silc_net_listener_get_port(ke->listener, NULL);
373 buffer = silc_key_agreement_payload_encode(local_ip, (port ? port :
374 ports ? ports[0] : 0));
378 silc_net_close_listener(ke->listener);
381 completion(client, conn, client_entry, SILC_KEY_AGREEMENT_NO_MEMORY,
388 silc_client_ref_client(client, conn, client_entry);
389 client_entry->internal.ke = ke;
392 /* Send the key agreement packet to the client */
393 silc_packet_send(conn->stream, SILC_PACKET_KEY_AGREEMENT, 0,
394 silc_buffer_data(buffer), silc_buffer_len(data));
396 silc_buffer_free(buffer);
399 /* Callback that is called after connection has been created. This actually
400 starts the key agreement protocol. This is initiator function. */
402 SILC_TASK_CALLBACK(silc_client_perform_key_agreement_start)
404 SilcClientInternalConnectContext *ctx =
405 (SilcClientInternalConnectContext *)context;
406 SilcClient client = ctx->client;
407 SilcClientConnection conn = ctx->conn;
408 SilcClientKeyAgreement ke = (SilcClientKeyAgreement)ctx->context;
409 int opt, opt_len = sizeof(opt);
411 SILC_LOG_DEBUG(("Start"));
413 /* Check the socket status as it might be in error */
414 silc_net_get_socket_opt(fd, SOL_SOCKET, SO_ERROR, &opt, &opt_len);
416 if (ctx->tries < 2) {
417 /* Connection failed but lets try again */
418 client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
419 "Could not connect to client %s: %s",
420 ctx->host, strerror(opt));
421 client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
422 "Connecting to port %d of client %s resumed",
423 ctx->port, ctx->host);
425 /* Unregister old connection try */
426 silc_schedule_unset_listen_fd(client->schedule, fd);
427 silc_net_close_connection(fd);
428 silc_schedule_task_del(client->schedule, ctx->task);
431 silc_client_connect_to_client_internal(ctx);
434 /* Connection failed and we won't try anymore */
435 client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
436 "Could not connect to client %s: %s",
437 ctx->host, strerror(opt));
438 silc_schedule_unset_listen_fd(client->schedule, fd);
439 silc_net_close_connection(fd);
440 silc_schedule_task_del(client->schedule, ctx->task);
441 silc_free(ctx->host);
444 /* Call the completion callback */
445 ke->completion(ke->client, ke->conn, ke->client_entry,
446 SILC_KEY_AGREEMENT_FAILURE, NULL, ke->context);
452 silc_schedule_unset_listen_fd(client->schedule, fd);
453 silc_schedule_task_del(client->schedule, ctx->task);
457 /* Now actually perform the key agreement protocol */
458 silc_client_perform_key_agreement_fd(ke->client, ke->conn,
459 ke->client_entry, ke->fd, ctx->host,
460 ke->completion, ke->context);
462 silc_free(ctx->host);
466 /* Performs the actual key agreement protocol. Application may use this
467 to initiate the key agreement protocol. This can be called for example
468 after the application has received the `key_agreement' client operation,
469 and did not return TRUE from it.
471 The `hostname' is the remote hostname (or IP address) and the `port'
472 is the remote port. The `completion' callback with the `context' will
473 be called after the key agreement protocol.
475 NOTE: If the application returns TRUE in the `key_agreement' client
476 operation the library will automatically start the key agreement. In this
477 case the application must not call this function. However, application
478 may choose to just ignore the `key_agreement' client operation (and
479 merely just print information about it on the screen) and call this
480 function when the user whishes to do so (by, for example, giving some
481 specific command). Thus, the API provides both, automatic and manual
482 initiation of the key agreement. Calling this function is the manual
483 initiation and returning TRUE in the `key_agreement' client operation
484 is the automatic initiation. */
486 void silc_client_perform_key_agreement(SilcClient client,
487 SilcClientConnection conn,
488 SilcClientEntry client_entry,
491 SilcKeyAgreementCallback completion,
494 SilcClientKeyAgreement ke;
496 SILC_LOG_DEBUG(("Start"));
501 if (!hostname || !port) {
502 completion(client, conn, client_entry, SILC_KEY_AGREEMENT_FAILURE,
507 if (client_entry == conn->local_entry) {
508 completion(client, conn, client_entry, SILC_KEY_AGREEMENT_SELF_DENIED,
513 ke = silc_calloc(1, sizeof(*ke));
516 ke->client_entry = client_entry;
517 ke->completion = completion;
518 ke->context = context;
520 /* Connect to the remote client */
521 ke->fd = silc_client_connect_to_client(client, conn, port, hostname, ke);
523 completion(client, conn, client_entry, SILC_KEY_AGREEMENT_FAILURE,
530 /* Same as above but application has created already the connection to
531 the remote host. The `sock' is the socket to the remote connection.
532 Application can use this function if it does not want the client library
533 to create the connection. */
535 void silc_client_perform_key_agreement_fd(SilcClient client,
536 SilcClientConnection conn,
537 SilcClientEntry client_entry,
540 SilcKeyAgreementCallback completion,
543 SilcClientKeyAgreement ke;
544 SilcClientKEInternalContext *proto_ctx;
545 SilcProtocol protocol;
547 SILC_LOG_DEBUG(("Start"));
552 if (client_entry == conn->local_entry) {
553 completion(client, conn, client_entry, SILC_KEY_AGREEMENT_SELF_DENIED,
558 ke = silc_calloc(1, sizeof(*ke));
561 ke->client_entry = client_entry;
563 ke->completion = completion;
564 ke->context = context;
566 /* Allocate new socket connection object */
567 silc_socket_alloc(sock, SILC_SOCKET_TYPE_UNKNOWN, (void *)conn, &ke->sock);
568 silc_client_add_socket(client, ke->sock);
569 ke->sock->hostname = strdup(hostname);
570 ke->sock->port = silc_net_get_remote_port(sock);
572 /* Allocate internal context for key exchange protocol. This is
573 sent as context for the protocol. */
574 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
575 proto_ctx->client = client;
576 proto_ctx->sock = silc_socket_dup(ke->sock);
577 proto_ctx->rng = client->rng;
578 proto_ctx->responder = FALSE;
579 proto_ctx->context = ke;
580 proto_ctx->send_packet = silc_client_key_agreement_send_packet;
581 proto_ctx->verify = silc_client_protocol_ke_verify_key;
582 ke->proto_ctx = proto_ctx;
584 /* Perform key exchange protocol. */
585 silc_protocol_alloc(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
586 &protocol, (void *)proto_ctx,
587 silc_client_key_agreement_final);
588 ke->sock->protocol = protocol;
590 /* Register the connection for network input and output. This sets
591 that scheduler will listen for incoming packets for this connection
592 and sets that outgoing packets may be sent to this connection as well.
593 However, this doesn't set the scheduler for outgoing traffic, it will
594 be set separately by calling SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT,
595 later when outgoing data is available. */
596 context = (void *)client;
597 SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(sock);
599 /* Execute the protocol */
600 silc_protocol_execute(protocol, client->schedule, 0, 0);
603 /* This function can be called to unbind the hostname and the port for
604 the key agreement protocol. However, this function has effect only
605 before the key agreement protocol has been performed. After it has
606 been performed the library will automatically unbind the port. The
607 `client_entry' is the client to which we sent the key agreement
610 void silc_client_abort_key_agreement(SilcClient client,
611 SilcClientConnection conn,
612 SilcClientEntry client_entry)
617 if (client_entry->ke) {
618 SilcClientKeyAgreement ke;
620 if (client_entry->ke->sock) {
621 silc_client_del_socket(client_entry->ke->client, client_entry->ke->sock);
622 silc_socket_free(client_entry->ke->sock);
624 silc_schedule_task_del_by_fd(client->schedule, client_entry->ke->fd);
625 if (client_entry->ke->timeout)
626 silc_schedule_task_del(client->schedule,
627 client_entry->ke->timeout);
628 ke = client_entry->ke;
629 client_entry->ke = NULL;
630 ke->completion(client, conn, client_entry,
631 SILC_KEY_AGREEMENT_ABORTED, NULL, ke->context);
636 /* Callback function that is called after we've resolved the client
637 information who sent us the key agreement packet from the server.
638 We actually call the key_agreement client operation now. */
641 silc_client_key_agreement_resolve_cb(SilcClient client,
642 SilcClientConnection conn,
643 SilcClientEntry *clients,
644 SilcUInt32 clients_count,
647 SilcPacketContext *packet = (SilcPacketContext *)context;
648 SilcKeyAgreementPayload payload;
650 SilcKeyAgreementCallback completion;
651 void *completion_context;
656 /* Parse the key agreement payload */
657 payload = silc_key_agreement_payload_parse(packet->buffer->data,
658 packet->buffer->len);
662 /* Call the key_agreement client operation */
663 ret = client->internal->ops->key_agreement(
664 client, conn, clients[0],
665 silc_key_agreement_get_hostname(payload),
666 silc_key_agreement_get_port(payload),
667 &completion, &completion_context);
669 /* If the user returned TRUE then we'll start the key agreement right
670 here and right now. */
672 silc_client_perform_key_agreement(client, conn, clients[0],
673 silc_key_agreement_get_hostname(payload),
674 silc_key_agreement_get_port(payload),
675 completion, completion_context);
677 silc_key_agreement_payload_free(payload);
680 silc_packet_context_free(packet);
683 /* Received Key Agreement packet from remote client. Process the packet
684 and resolve the client information from the server before actually
685 letting the application know that we've received this packet. Then
686 call the key_agreement client operation and let the user decide
687 whether we perform the key agreement protocol now or not. */
689 void silc_client_key_agreement(SilcClient client,
690 SilcSocketConnection sock,
691 SilcPacketContext *packet)
693 SilcClientID *remote_id;
695 if (packet->src_id_type != SILC_ID_CLIENT)
698 remote_id = silc_id_str2id(packet->src_id, packet->src_id_len,
703 silc_client_get_client_by_id_resolve(client, sock->user_data, remote_id,
705 silc_client_key_agreement_resolve_cb,
706 silc_packet_context_dup(packet));
707 silc_free(remote_id);