updates.
[silc.git] / lib / silcclient / client_keyagr.c
1 /*
2
3   client_keyagr.c
4
5   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
6
7   Copyright (C) 2001 Pekka Riikonen
8
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.
13   
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.
18
19 */
20 /* $Id$ */
21 /* This file includes the Key Agreement packet processing and actual
22    key agreement routines. This file has nothing to do with the actual
23    connection key exchange protocol, it is implemented in the client.c
24    and in protocol.c. This file implements the client-to-client key 
25    agreement as defined by the SILC protocol. */
26
27 #include "clientlibincludes.h"
28 #include "client_internal.h"
29
30 SILC_TASK_CALLBACK(silc_client_key_agreement_final);
31 SILC_TASK_CALLBACK(silc_client_process_key_agreement);
32 SILC_TASK_CALLBACK(silc_client_key_agreement_timeout);
33 SILC_TASK_CALLBACK(silc_client_perform_key_agreement_start);
34
35 /* Key agreement context */
36 struct SilcClientKeyAgreementStruct {
37   SilcClient client;
38   SilcClientConnection conn;
39   int fd;                               /* Listening/connection socket */
40   SilcSocketConnection sock;            /* Remote socket connection */
41   SilcClientEntry client_entry;         /* Destination client */
42   SilcKeyAgreementCallback completion;  /* Key agreement completion */
43   void *context;                        /* User context */
44   SilcTask timeout;                     /* Timeout task */
45 };
46
47 /* Packet sending function used by the SKE in the key agreement process. */
48
49 static void silc_client_key_agreement_send_packet(SilcSKE ske,
50                                                   SilcBuffer packet,
51                                                   SilcPacketType type,
52                                                   void *context)
53 {
54   SilcProtocol protocol = (SilcProtocol)context;
55   SilcClientKEInternalContext *ctx = 
56     (SilcClientKEInternalContext *)protocol->context;
57   void *tmp;
58
59   /* Send the packet immediately. We will assure that the packet is not
60      encrypted by setting the socket's user_data pointer to NULL. The
61      silc_client_packet_send would take the keys (wrong keys that is,
62      because user_data is the current SilcClientConnection) from it and
63      we cannot allow that. The packets are never encrypted when doing SKE
64      with another client. */
65   tmp = ske->sock->user_data;
66   ske->sock->user_data = NULL;
67   silc_client_packet_send(ctx->client, ske->sock, type, NULL, 0, NULL, NULL,
68                           packet->data, packet->len, TRUE);
69   ske->sock->user_data = tmp;
70 }
71
72 /* This callback is called after the key agreement protocol has been
73    performed. This calls the final completion callback for the application. */
74
75 SILC_TASK_CALLBACK(silc_client_key_agreement_final)
76 {
77   SilcProtocol protocol = (SilcProtocol)context;
78   SilcClientKEInternalContext *ctx = 
79     (SilcClientKEInternalContext *)protocol->context;
80   SilcClient client = (SilcClient)ctx->client;
81   SilcClientKeyAgreement ke = (SilcClientKeyAgreement)ctx->context;
82
83   SILC_LOG_DEBUG(("Start"));
84
85   if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
86       protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
87     /* Error occured during protocol */
88     ke->client_entry->ke = NULL;
89     ke->completion(ke->client, ke->conn, ke->client_entry, NULL, ke->context);
90     silc_ske_free_key_material(ctx->keymat);
91     goto out;
92   }
93
94   /* Pass the negotiated key material to the application. The application
95      is responsible of freeing the key material. */
96   ke->client_entry->ke = NULL;
97   ke->completion(ke->client, ke->conn, ke->client_entry, ctx->keymat, 
98                  ke->context);
99
100  out:
101   silc_protocol_free(protocol);
102   if (ctx->ske)
103     silc_ske_free(ctx->ske);
104   if (ctx->dest_id)
105     silc_free(ctx->dest_id);
106   silc_task_unregister_by_callback(client->timeout_queue,
107                                    silc_client_failure_callback);
108   silc_task_unregister_by_fd(client->io_queue, ke->fd);
109   if (ke->timeout)
110     silc_task_unregister(client->timeout_queue, ke->timeout);
111   silc_socket_free(ke->sock);
112   silc_free(ke);
113   silc_free(ctx);
114 }
115
116 /* Key agreement callback that is called when remote end has initiated
117    the key agreement protocol. This accepts the incoming TCP/IP connection
118    for the key agreement protocol. */
119
120 SILC_TASK_CALLBACK(silc_client_process_key_agreement)
121 {
122   SilcClientKeyAgreement ke = (SilcClientKeyAgreement)context;
123   SilcClient client = ke->client;
124   SilcClientConnection conn = ke->conn;
125   SilcSocketConnection newsocket;
126   SilcClientKEInternalContext *proto_ctx;
127   int sock;
128
129   SILC_LOG_DEBUG(("Start"));
130
131   sock = silc_net_accept_connection(ke->fd);
132   if (sock < 0) {
133     client->ops->say(client, conn, 
134                      "Could not accept key agreement connection: ", 
135                      strerror(errno));
136     ke->client_entry->ke = NULL;
137     ke->completion(ke->client, ke->conn, ke->client_entry, NULL, ke->context);
138     silc_task_unregister_by_fd(client->io_queue, ke->fd);
139     if (ke->timeout)
140       silc_task_unregister(client->timeout_queue, ke->timeout);
141     silc_free(ke);
142     return;
143   }
144
145   /* Set socket options */
146   silc_net_set_socket_nonblock(sock);
147   silc_net_set_socket_opt(sock, SOL_SOCKET, SO_REUSEADDR, 1);
148
149   /* Create socket for this connection (it is of type UNKNOWN since this
150      really is not a real SILC connection. It is only for the key
151      agreement protocol). */
152   silc_socket_alloc(sock, SILC_SOCKET_TYPE_UNKNOWN, (void *)conn, &newsocket);
153   ke->sock = newsocket;
154
155   /* Perform name and address lookups for the remote host. */
156   silc_net_check_host_by_sock(sock, &newsocket->hostname, &newsocket->ip);
157   if (!newsocket->hostname && !newsocket->ip) {
158     client->ops->say(client, conn, 
159                      "Could not resolve the remote IP or hostname");
160     ke->client_entry->ke = NULL;
161     ke->completion(ke->client, ke->conn, ke->client_entry, NULL, ke->context);
162     silc_task_unregister_by_fd(client->io_queue, ke->fd);
163     if (ke->timeout)
164       silc_task_unregister(client->timeout_queue, ke->timeout);
165     silc_free(ke);
166     return;
167   }
168   if (!newsocket->hostname)
169     newsocket->hostname = strdup(newsocket->ip);
170   newsocket->port = silc_net_get_remote_port(sock);
171
172   /* Allocate internal context for key exchange protocol. This is
173      sent as context for the protocol. */
174   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
175   proto_ctx->client = client;
176   proto_ctx->sock = newsocket;
177   proto_ctx->rng = client->rng;
178   proto_ctx->responder = TRUE;
179   proto_ctx->context = context;
180   proto_ctx->send_packet = silc_client_key_agreement_send_packet;
181
182   /* Prepare the connection for key exchange protocol. We allocate the
183      protocol but will not start it yet. The connector will be the
184      initiator of the protocol thus we will wait for initiation from 
185      there before we start the protocol. */
186   silc_protocol_alloc(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE, 
187                       &newsocket->protocol, proto_ctx, 
188                       silc_client_key_agreement_final);
189
190   /* Register the connection for network input and output. This sets
191      that scheduler will listen for incoming packets for this connection 
192      and sets that outgoing packets may be sent to this connection as well.
193      However, this doesn't set the scheduler for outgoing traffic, it
194      will be set separately by calling SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT,
195      later when outgoing data is available. */
196   SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(sock);
197 }
198
199 /* Timeout occured during key agreement. This means that the key agreement
200    protocol was not completed in the specified timeout. We will call the 
201    completion callback. */
202
203 SILC_TASK_CALLBACK(silc_client_key_agreement_timeout)
204 {
205   SilcClientKeyAgreement ke = (SilcClientKeyAgreement)context;
206
207   ke->client_entry->ke = NULL;
208   ke->completion(ke->client, ke->conn, ke->client_entry, NULL, ke->context);
209
210   if (ke->sock)
211     silc_socket_free(ke->sock);
212   ke->client_entry->ke = NULL;
213   silc_free(ke);
214   silc_task_unregister_by_callback(ke->client->timeout_queue,
215                                    silc_client_failure_callback);
216   silc_task_unregister_by_fd(ke->client->io_queue, ke->fd);
217 }
218
219 /* Sends key agreement request to the remote client indicated by the
220    `client_entry'. If the caller provides the `hostname' and the `port'
221    arguments then the library will bind the client to that hostname and
222    that port for the key agreement protocol. It also sends the `hostname'
223    and the `port' in the key agreement packet to the remote client. This
224    would indicate that the remote client may initiate the key agreement
225    protocol to the `hostname' on the `port'.  If port is zero then the
226    bound port is undefined (the operating system defines it).
227
228    If the `hostname' and `port' is not provided then empty key agreement
229    packet is sent to the remote client. The remote client may reply with
230    the same packet including its hostname and port. If the library receives
231    the reply from the remote client the `key_agreement' client operation
232    callback will be called to verify whether the user wants to perform the
233    key agreement or not. 
234
235    NOTE: If the application provided the `hostname' and the `port' and the 
236    remote side initiates the key agreement protocol it is not verified
237    from the user anymore whether the protocol should be executed or not.
238    By setting the `hostname' and `port' the user gives permission to
239    perform the protocol (we are responder in this case).
240
241    NOTE: If the remote side decides not to initiate the key agreement
242    or decides not to reply with the key agreement packet then we cannot
243    perform the key agreement at all. If the key agreement protocol is
244    performed the `completion' callback with the `context' will be called.
245    If remote side decides to ignore the request the `completion' will be
246    called after the specified timeout, `timeout_secs'. 
247
248    NOTE: There can be only one active key agreement for one client entry.
249    Before setting new one, the old one must be finished (it is finished
250    after calling the completion callback) or the function 
251    silc_client_abort_key_agreement must be called. */
252
253 void silc_client_send_key_agreement(SilcClient client,
254                                     SilcClientConnection conn,
255                                     SilcClientEntry client_entry,
256                                     char *hostname,
257                                     int port,
258                                     unsigned long timeout_secs,
259                                     SilcKeyAgreementCallback completion,
260                                     void *context)
261 {
262   SilcSocketConnection sock = conn->sock;
263   SilcClientKeyAgreement ke;
264   SilcBuffer buffer;
265
266   assert(client_entry);
267
268   if (client_entry->ke)
269     return;
270
271   /* Create the listener if hostname and port was provided */
272   if (hostname) {
273     ke = silc_calloc(1, sizeof(*ke));
274     ke->fd = silc_net_create_server(port, hostname);
275
276     if (ke->fd < 0) {
277       client->ops->say(client, conn, 
278                        "Cannot create listener on %s on port %d: %s", 
279                        hostname, port, strerror(errno));
280       completion(client, conn, client_entry, NULL, context);
281       silc_free(ke);
282       return;
283     }
284
285     ke->client = client;
286     ke->conn = conn;
287     ke->client_entry = client_entry;
288     ke->completion = completion;
289     ke->context = context;
290
291     /* Add listener task to the queue. This task receives the key 
292        negotiations. */
293     silc_task_register(client->io_queue, ke->fd,
294                        silc_client_process_key_agreement,
295                        (void *)ke, 0, 0, 
296                        SILC_TASK_FD,
297                        SILC_TASK_PRI_NORMAL);
298
299     /* Register a timeout task that will be executed if the connector
300        will not start the key exchange protocol within the specified 
301        timeout. */
302     ke->timeout = 
303       silc_task_register(client->timeout_queue, 0, 
304                          silc_client_key_agreement_timeout,
305                          (void *)ke, timeout_secs, 0, 
306                          SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
307   }
308
309   /* Encode the key agreement payload */
310   buffer = silc_key_agreement_payload_encode(hostname, port);
311
312   /* Send the key agreement packet to the client */
313   silc_client_packet_send(client, sock, SILC_PACKET_KEY_AGREEMENT,
314                           client_entry->id, SILC_ID_CLIENT, NULL, NULL,
315                           buffer->data, buffer->len, FALSE);
316   silc_free(buffer);
317 }
318
319 static int 
320 silc_client_connect_to_client_internal(SilcClientInternalConnectContext *ctx)
321 {
322   int sock;
323
324   /* Create connection to server asynchronously */
325   sock = silc_net_create_connection_async(ctx->port, ctx->host);
326   if (sock < 0)
327     return -1;
328
329   /* Register task that will receive the async connect and will
330      read the result. */
331   ctx->task = silc_task_register(ctx->client->io_queue, sock, 
332                                  silc_client_perform_key_agreement_start,
333                                  (void *)ctx, 0, 0, 
334                                  SILC_TASK_FD,
335                                  SILC_TASK_PRI_NORMAL);
336   silc_task_reset_iotype(ctx->task, SILC_TASK_WRITE);
337   silc_schedule_set_listen_fd(sock, ctx->task->iomask);
338
339   ctx->sock = sock;
340
341   return sock;
342 }
343
344 /* Routine used by silc_client_perform_key_agreement to create connection
345    to the remote client on specified port. */
346
347 static int
348 silc_client_connect_to_client(SilcClient client, 
349                               SilcClientConnection conn, int port,
350                               char *host, void *context)
351 {
352   SilcClientInternalConnectContext *ctx;
353
354   /* Allocate internal context for connection process. This is
355      needed as we are doing async connecting. */
356   ctx = silc_calloc(1, sizeof(*ctx));
357   ctx->client = client;
358   ctx->conn = conn;
359   ctx->host = strdup(host);
360   ctx->port = port;
361   ctx->tries = 0;
362   ctx->context = context;
363
364   /* Do the actual connecting process */
365   return silc_client_connect_to_client_internal(ctx);
366 }
367
368 /* Callback that is called after connection has been created. This actually
369    starts the key agreement protocol. This is initiator function. */
370
371 SILC_TASK_CALLBACK(silc_client_perform_key_agreement_start)
372 {
373   SilcClientInternalConnectContext *ctx =
374     (SilcClientInternalConnectContext *)context;
375   SilcClient client = ctx->client;
376   SilcClientConnection conn = ctx->conn;
377   SilcClientKeyAgreement ke = (SilcClientKeyAgreement)ctx->context;
378   int opt, opt_len = sizeof(opt);
379
380   SILC_LOG_DEBUG(("Start"));
381
382   /* Check the socket status as it might be in error */
383   getsockopt(fd, SOL_SOCKET, SO_ERROR, &opt, &opt_len);
384   if (opt != 0) {
385     if (ctx->tries < 2) {
386       /* Connection failed but lets try again */
387       client->ops->say(client, conn, "Could not connect to client %s: %s",
388                        ctx->host, strerror(opt));
389       client->ops->say(client, conn, 
390                        "Connecting to port %d of client %s resumed", 
391                        ctx->port, ctx->host);
392
393       /* Unregister old connection try */
394       silc_schedule_unset_listen_fd(fd);
395       silc_net_close_connection(fd);
396       silc_task_unregister(client->io_queue, ctx->task);
397
398       /* Try again */
399       silc_client_connect_to_client_internal(ctx);
400       ctx->tries++;
401     } else {
402       /* Connection failed and we won't try anymore */
403       client->ops->say(client, conn, "Could not connect to client %s: %s",
404                        ctx->host, strerror(opt));
405       silc_schedule_unset_listen_fd(fd);
406       silc_net_close_connection(fd);
407       silc_task_unregister(client->io_queue, ctx->task);
408       silc_free(ctx);
409
410       /* Call the completion callback */
411       ke->completion(ke->client, ke->conn, ke->client_entry, 
412                      NULL, ke->context);
413       silc_free(ke);
414     }
415     return;
416   }
417
418   silc_schedule_unset_listen_fd(fd);
419   silc_task_unregister(client->io_queue, ctx->task);
420   silc_free(ctx);
421
422   ke->fd = fd;
423
424   /* Now actually perform the key agreement protocol */
425   silc_client_perform_key_agreement_fd(ke->client, ke->conn,
426                                        ke->client_entry, ke->fd,
427                                        ke->completion, ke->context);
428   silc_free(ke);
429 }
430
431 /* Performs the actual key agreement protocol. Application may use this
432    to initiate the key agreement protocol. This can be called for example
433    after the application has received the `key_agreement' client operation,
434    and did not return TRUE from it.
435
436    The `hostname' is the remote hostname (or IP address) and the `port'
437    is the remote port. The `completion' callback with the `context' will
438    be called after the key agreement protocol.
439    
440    NOTE: If the application returns TRUE in the `key_agreement' client
441    operation the library will automatically start the key agreement. In this
442    case the application must not call this function. However, application
443    may choose to just ignore the `key_agreement' client operation (and
444    merely just print information about it on the screen) and call this
445    function when the user whishes to do so (by, for example, giving some
446    specific command). Thus, the API provides both, automatic and manual
447    initiation of the key agreement. Calling this function is the manual
448    initiation and returning TRUE in the `key_agreement' client operation
449    is the automatic initiation. */
450
451 void silc_client_perform_key_agreement(SilcClient client,
452                                        SilcClientConnection conn,
453                                        SilcClientEntry client_entry,
454                                        char *hostname,
455                                        int port,
456                                        SilcKeyAgreementCallback completion,
457                                        void *context)
458 {
459   SilcClientKeyAgreement ke;
460
461   assert(client_entry && hostname && port);
462
463   ke = silc_calloc(1, sizeof(*ke));
464   ke->client = client;
465   ke->conn = conn;
466   ke->client_entry = client_entry;
467   ke->completion = completion;
468   ke->context = context;
469
470   /* Connect to the remote client */
471   ke->fd = silc_client_connect_to_client(client, conn, port, hostname, ke);
472   if (ke->fd < 0) {
473     completion(client, conn, client_entry, NULL, context);
474     silc_free(ke);
475     return;
476   }
477 }
478
479 /* Same as above but application has created already the connection to 
480    the remote host. The `sock' is the socket to the remote connection. 
481    Application can use this function if it does not want the client library
482    to create the connection. */
483
484 void silc_client_perform_key_agreement_fd(SilcClient client,
485                                           SilcClientConnection conn,
486                                           SilcClientEntry client_entry,
487                                           int sock,
488                                           SilcKeyAgreementCallback completion,
489                                           void *context)
490 {
491   SilcClientKeyAgreement ke;
492   SilcClientKEInternalContext *proto_ctx;
493   SilcProtocol protocol;
494
495   assert(client_entry);
496
497   ke = silc_calloc(1, sizeof(*ke));
498   ke->client = client;
499   ke->conn = conn;
500   ke->client_entry = client_entry;
501   ke->fd = sock;
502   ke->completion = completion;
503   ke->context = context;
504
505   /* Allocate new socket connection object */
506   silc_socket_alloc(sock, SILC_SOCKET_TYPE_UNKNOWN, (void *)conn, &ke->sock);
507
508   /* Allocate internal context for key exchange protocol. This is
509      sent as context for the protocol. */
510   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
511   proto_ctx->client = client;
512   proto_ctx->sock = ke->sock;
513   proto_ctx->rng = client->rng;
514   proto_ctx->responder = FALSE;
515   proto_ctx->context = ke;
516   proto_ctx->send_packet = silc_client_key_agreement_send_packet;
517
518   /* Perform key exchange protocol. */
519   silc_protocol_alloc(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE, 
520                       &protocol, (void *)proto_ctx,
521                       silc_client_key_agreement_final);
522   ke->sock->protocol = protocol;
523
524   /* Register the connection for network input and output. This sets
525      that scheduler will listen for incoming packets for this connection 
526      and sets that outgoing packets may be sent to this connection as well.
527      However, this doesn't set the scheduler for outgoing traffic, it will 
528      be set separately by calling SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT,
529      later when outgoing data is available. */
530   context = (void *)client;
531   SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(sock);
532
533   /* Execute the protocol */
534   protocol->execute(client->timeout_queue, 0, protocol, sock, 0, 0);
535 }
536
537 /* This function can be called to unbind the hostname and the port for
538    the key agreement protocol. However, this function has effect only 
539    before the key agreement protocol has been performed. After it has
540    been performed the library will automatically unbind the port. The 
541    `client_entry' is the client to which we sent the key agreement 
542    request. */
543
544 void silc_client_abort_key_agreement(SilcClient client,
545                                      SilcClientConnection conn,
546                                      SilcClientEntry client_entry)
547 {
548   assert(client_entry);
549
550   if (client_entry->ke) {
551     if (client_entry->ke->sock)
552       silc_socket_free(client_entry->ke->sock);
553     client_entry->ke = NULL;
554     silc_task_unregister_by_fd(client->io_queue, client_entry->ke->fd);
555     if (client_entry->ke->timeout)
556       silc_task_unregister(client->timeout_queue, 
557                            client_entry->ke->timeout);
558     silc_free(client_entry->ke);
559   }
560 }
561
562 /* Callback function that is called after we've resolved the client 
563    information who sent us the key agreement packet from the server.
564    We actually call the key_agreement client operation now. */
565
566 static void 
567 silc_client_key_agreement_resolve_cb(SilcClient client,
568                                      SilcClientConnection conn,
569                                      SilcClientEntry *clients,
570                                      unsigned int clients_count,
571                                      void *context)
572 {
573   SilcPacketContext *packet = (SilcPacketContext *)context;
574   SilcKeyAgreementPayload payload;
575   int ret;
576   SilcKeyAgreementCallback completion;
577   void *completion_context;
578
579   if (!clients)
580     goto out;
581
582   /* Parse the key agreement payload */
583   payload = silc_key_agreement_payload_parse(packet->buffer);
584   if (!payload)
585     goto out;
586
587   /* Call the key_agreement client operation */
588   ret = client->ops->key_agreement(client, conn, clients[0], 
589                                    silc_key_agreement_get_hostname(payload),
590                                    silc_key_agreement_get_port(payload),
591                                    &completion, &completion_context);
592
593   /* If the user returned TRUE then we'll start the key agreement right
594      here and right now. */
595   if (ret == TRUE)
596     silc_client_perform_key_agreement(client, conn, clients[0],
597                                       silc_key_agreement_get_hostname(payload),
598                                       silc_key_agreement_get_port(payload),
599                                       completion, completion_context);
600
601   silc_key_agreement_payload_free(payload);
602
603  out:
604   silc_packet_context_free(packet);
605 }
606
607 /* Received Key Agreement packet from remote client. Process the packet
608    and resolve the client information from the server before actually
609    letting the application know that we've received this packet.  Then 
610    call the key_agreement client operation and let the user decide
611    whether we perform the key agreement protocol now or not. */
612
613 void silc_client_key_agreement(SilcClient client,
614                                SilcSocketConnection sock,
615                                SilcPacketContext *packet)
616 {
617   SilcClientID *remote_id;
618
619   if (packet->src_id_type != SILC_ID_CLIENT)
620     return;
621
622   remote_id = silc_id_str2id(packet->src_id, packet->src_id_len, 
623                              SILC_ID_CLIENT);
624   if (!remote_id)
625     return;
626
627   silc_client_get_client_by_id_resolve(client, sock->user_data, remote_id,
628                                        silc_client_key_agreement_resolve_cb,
629                                        silc_packet_context_dup(packet));
630   silc_free(remote_id);
631 }