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   proto_ctx->verify = silc_client_protocol_ke_verify_key;
182
183   /* Prepare the connection for key exchange protocol. We allocate the
184      protocol but will not start it yet. The connector will be the
185      initiator of the protocol thus we will wait for initiation from 
186      there before we start the protocol. */
187   silc_protocol_alloc(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE, 
188                       &newsocket->protocol, proto_ctx, 
189                       silc_client_key_agreement_final);
190
191   /* Register the connection for network input and output. This sets
192      that scheduler will listen for incoming packets for this connection 
193      and sets that outgoing packets may be sent to this connection as well.
194      However, this doesn't set the scheduler for outgoing traffic, it
195      will be set separately by calling SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT,
196      later when outgoing data is available. */
197   SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(sock);
198 }
199
200 /* Timeout occured during key agreement. This means that the key agreement
201    protocol was not completed in the specified timeout. We will call the 
202    completion callback. */
203
204 SILC_TASK_CALLBACK(silc_client_key_agreement_timeout)
205 {
206   SilcClientKeyAgreement ke = (SilcClientKeyAgreement)context;
207
208   ke->client_entry->ke = NULL;
209   ke->completion(ke->client, ke->conn, ke->client_entry, NULL, ke->context);
210
211   if (ke->sock)
212     silc_socket_free(ke->sock);
213   ke->client_entry->ke = NULL;
214   silc_free(ke);
215   silc_task_unregister_by_callback(ke->client->timeout_queue,
216                                    silc_client_failure_callback);
217   silc_task_unregister_by_fd(ke->client->io_queue, ke->fd);
218 }
219
220 /* Sends key agreement request to the remote client indicated by the
221    `client_entry'. If the caller provides the `hostname' and the `port'
222    arguments then the library will bind the client to that hostname and
223    that port for the key agreement protocol. It also sends the `hostname'
224    and the `port' in the key agreement packet to the remote client. This
225    would indicate that the remote client may initiate the key agreement
226    protocol to the `hostname' on the `port'.  If port is zero then the
227    bound port is undefined (the operating system defines it).
228
229    If the `hostname' and `port' is not provided then empty key agreement
230    packet is sent to the remote client. The remote client may reply with
231    the same packet including its hostname and port. If the library receives
232    the reply from the remote client the `key_agreement' client operation
233    callback will be called to verify whether the user wants to perform the
234    key agreement or not. 
235
236    NOTE: If the application provided the `hostname' and the `port' and the 
237    remote side initiates the key agreement protocol it is not verified
238    from the user anymore whether the protocol should be executed or not.
239    By setting the `hostname' and `port' the user gives permission to
240    perform the protocol (we are responder in this case).
241
242    NOTE: If the remote side decides not to initiate the key agreement
243    or decides not to reply with the key agreement packet then we cannot
244    perform the key agreement at all. If the key agreement protocol is
245    performed the `completion' callback with the `context' will be called.
246    If remote side decides to ignore the request the `completion' will be
247    called after the specified timeout, `timeout_secs'. 
248
249    NOTE: There can be only one active key agreement for one client entry.
250    Before setting new one, the old one must be finished (it is finished
251    after calling the completion callback) or the function 
252    silc_client_abort_key_agreement must be called. */
253
254 void silc_client_send_key_agreement(SilcClient client,
255                                     SilcClientConnection conn,
256                                     SilcClientEntry client_entry,
257                                     char *hostname,
258                                     int port,
259                                     unsigned long timeout_secs,
260                                     SilcKeyAgreementCallback completion,
261                                     void *context)
262 {
263   SilcSocketConnection sock = conn->sock;
264   SilcClientKeyAgreement ke;
265   SilcBuffer buffer;
266
267   assert(client_entry);
268
269   if (client_entry->ke)
270     return;
271
272   /* Create the listener if hostname and port was provided */
273   if (hostname) {
274     ke = silc_calloc(1, sizeof(*ke));
275     ke->fd = silc_net_create_server(port, hostname);
276
277     if (ke->fd < 0) {
278       client->ops->say(client, conn, 
279                        "Cannot create listener on %s on port %d: %s", 
280                        hostname, port, strerror(errno));
281       completion(client, conn, client_entry, NULL, context);
282       silc_free(ke);
283       return;
284     }
285
286     ke->client = client;
287     ke->conn = conn;
288     ke->client_entry = client_entry;
289     ke->completion = completion;
290     ke->context = context;
291
292     /* Add listener task to the queue. This task receives the key 
293        negotiations. */
294     silc_task_register(client->io_queue, ke->fd,
295                        silc_client_process_key_agreement,
296                        (void *)ke, 0, 0, 
297                        SILC_TASK_FD,
298                        SILC_TASK_PRI_NORMAL);
299
300     /* Register a timeout task that will be executed if the connector
301        will not start the key exchange protocol within the specified 
302        timeout. */
303     ke->timeout = 
304       silc_task_register(client->timeout_queue, 0, 
305                          silc_client_key_agreement_timeout,
306                          (void *)ke, timeout_secs, 0, 
307                          SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
308   }
309
310   /* Encode the key agreement payload */
311   buffer = silc_key_agreement_payload_encode(hostname, port);
312
313   /* Send the key agreement packet to the client */
314   silc_client_packet_send(client, sock, SILC_PACKET_KEY_AGREEMENT,
315                           client_entry->id, SILC_ID_CLIENT, NULL, NULL,
316                           buffer->data, buffer->len, FALSE);
317   silc_free(buffer);
318 }
319
320 static int 
321 silc_client_connect_to_client_internal(SilcClientInternalConnectContext *ctx)
322 {
323   int sock;
324
325   /* Create connection to server asynchronously */
326   sock = silc_net_create_connection_async(ctx->port, ctx->host);
327   if (sock < 0)
328     return -1;
329
330   /* Register task that will receive the async connect and will
331      read the result. */
332   ctx->task = silc_task_register(ctx->client->io_queue, sock, 
333                                  silc_client_perform_key_agreement_start,
334                                  (void *)ctx, 0, 0, 
335                                  SILC_TASK_FD,
336                                  SILC_TASK_PRI_NORMAL);
337   silc_task_reset_iotype(ctx->task, SILC_TASK_WRITE);
338   silc_schedule_set_listen_fd(sock, ctx->task->iomask);
339
340   ctx->sock = sock;
341
342   return sock;
343 }
344
345 /* Routine used by silc_client_perform_key_agreement to create connection
346    to the remote client on specified port. */
347
348 static int
349 silc_client_connect_to_client(SilcClient client, 
350                               SilcClientConnection conn, int port,
351                               char *host, void *context)
352 {
353   SilcClientInternalConnectContext *ctx;
354
355   /* Allocate internal context for connection process. This is
356      needed as we are doing async connecting. */
357   ctx = silc_calloc(1, sizeof(*ctx));
358   ctx->client = client;
359   ctx->conn = conn;
360   ctx->host = strdup(host);
361   ctx->port = port;
362   ctx->tries = 0;
363   ctx->context = context;
364
365   /* Do the actual connecting process */
366   return silc_client_connect_to_client_internal(ctx);
367 }
368
369 /* Callback that is called after connection has been created. This actually
370    starts the key agreement protocol. This is initiator function. */
371
372 SILC_TASK_CALLBACK(silc_client_perform_key_agreement_start)
373 {
374   SilcClientInternalConnectContext *ctx =
375     (SilcClientInternalConnectContext *)context;
376   SilcClient client = ctx->client;
377   SilcClientConnection conn = ctx->conn;
378   SilcClientKeyAgreement ke = (SilcClientKeyAgreement)ctx->context;
379   int opt, opt_len = sizeof(opt);
380
381   SILC_LOG_DEBUG(("Start"));
382
383   /* Check the socket status as it might be in error */
384   getsockopt(fd, SOL_SOCKET, SO_ERROR, &opt, &opt_len);
385   if (opt != 0) {
386     if (ctx->tries < 2) {
387       /* Connection failed but lets try again */
388       client->ops->say(client, conn, "Could not connect to client %s: %s",
389                        ctx->host, strerror(opt));
390       client->ops->say(client, conn, 
391                        "Connecting to port %d of client %s resumed", 
392                        ctx->port, ctx->host);
393
394       /* Unregister old connection try */
395       silc_schedule_unset_listen_fd(fd);
396       silc_net_close_connection(fd);
397       silc_task_unregister(client->io_queue, ctx->task);
398
399       /* Try again */
400       silc_client_connect_to_client_internal(ctx);
401       ctx->tries++;
402     } else {
403       /* Connection failed and we won't try anymore */
404       client->ops->say(client, conn, "Could not connect to client %s: %s",
405                        ctx->host, strerror(opt));
406       silc_schedule_unset_listen_fd(fd);
407       silc_net_close_connection(fd);
408       silc_task_unregister(client->io_queue, ctx->task);
409       silc_free(ctx);
410
411       /* Call the completion callback */
412       ke->completion(ke->client, ke->conn, ke->client_entry, 
413                      NULL, ke->context);
414       silc_free(ke);
415     }
416     return;
417   }
418
419   silc_schedule_unset_listen_fd(fd);
420   silc_task_unregister(client->io_queue, ctx->task);
421   silc_free(ctx);
422
423   ke->fd = fd;
424
425   /* Now actually perform the key agreement protocol */
426   silc_client_perform_key_agreement_fd(ke->client, ke->conn,
427                                        ke->client_entry, ke->fd,
428                                        ke->completion, ke->context);
429   silc_free(ke);
430 }
431
432 /* Performs the actual key agreement protocol. Application may use this
433    to initiate the key agreement protocol. This can be called for example
434    after the application has received the `key_agreement' client operation,
435    and did not return TRUE from it.
436
437    The `hostname' is the remote hostname (or IP address) and the `port'
438    is the remote port. The `completion' callback with the `context' will
439    be called after the key agreement protocol.
440    
441    NOTE: If the application returns TRUE in the `key_agreement' client
442    operation the library will automatically start the key agreement. In this
443    case the application must not call this function. However, application
444    may choose to just ignore the `key_agreement' client operation (and
445    merely just print information about it on the screen) and call this
446    function when the user whishes to do so (by, for example, giving some
447    specific command). Thus, the API provides both, automatic and manual
448    initiation of the key agreement. Calling this function is the manual
449    initiation and returning TRUE in the `key_agreement' client operation
450    is the automatic initiation. */
451
452 void silc_client_perform_key_agreement(SilcClient client,
453                                        SilcClientConnection conn,
454                                        SilcClientEntry client_entry,
455                                        char *hostname,
456                                        int port,
457                                        SilcKeyAgreementCallback completion,
458                                        void *context)
459 {
460   SilcClientKeyAgreement ke;
461
462   assert(client_entry && hostname && port);
463
464   ke = silc_calloc(1, sizeof(*ke));
465   ke->client = client;
466   ke->conn = conn;
467   ke->client_entry = client_entry;
468   ke->completion = completion;
469   ke->context = context;
470
471   /* Connect to the remote client */
472   ke->fd = silc_client_connect_to_client(client, conn, port, hostname, ke);
473   if (ke->fd < 0) {
474     completion(client, conn, client_entry, NULL, context);
475     silc_free(ke);
476     return;
477   }
478 }
479
480 /* Same as above but application has created already the connection to 
481    the remote host. The `sock' is the socket to the remote connection. 
482    Application can use this function if it does not want the client library
483    to create the connection. */
484
485 void silc_client_perform_key_agreement_fd(SilcClient client,
486                                           SilcClientConnection conn,
487                                           SilcClientEntry client_entry,
488                                           int sock,
489                                           SilcKeyAgreementCallback completion,
490                                           void *context)
491 {
492   SilcClientKeyAgreement ke;
493   SilcClientKEInternalContext *proto_ctx;
494   SilcProtocol protocol;
495
496   assert(client_entry);
497
498   ke = silc_calloc(1, sizeof(*ke));
499   ke->client = client;
500   ke->conn = conn;
501   ke->client_entry = client_entry;
502   ke->fd = sock;
503   ke->completion = completion;
504   ke->context = context;
505
506   /* Allocate new socket connection object */
507   silc_socket_alloc(sock, SILC_SOCKET_TYPE_UNKNOWN, (void *)conn, &ke->sock);
508
509   /* Allocate internal context for key exchange protocol. This is
510      sent as context for the protocol. */
511   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
512   proto_ctx->client = client;
513   proto_ctx->sock = ke->sock;
514   proto_ctx->rng = client->rng;
515   proto_ctx->responder = FALSE;
516   proto_ctx->context = ke;
517   proto_ctx->send_packet = silc_client_key_agreement_send_packet;
518   proto_ctx->verify = silc_client_protocol_ke_verify_key;
519
520   /* Perform key exchange protocol. */
521   silc_protocol_alloc(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE, 
522                       &protocol, (void *)proto_ctx,
523                       silc_client_key_agreement_final);
524   ke->sock->protocol = protocol;
525
526   /* Register the connection for network input and output. This sets
527      that scheduler will listen for incoming packets for this connection 
528      and sets that outgoing packets may be sent to this connection as well.
529      However, this doesn't set the scheduler for outgoing traffic, it will 
530      be set separately by calling SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT,
531      later when outgoing data is available. */
532   context = (void *)client;
533   SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(sock);
534
535   /* Execute the protocol */
536   protocol->execute(client->timeout_queue, 0, protocol, sock, 0, 0);
537 }
538
539 /* This function can be called to unbind the hostname and the port for
540    the key agreement protocol. However, this function has effect only 
541    before the key agreement protocol has been performed. After it has
542    been performed the library will automatically unbind the port. The 
543    `client_entry' is the client to which we sent the key agreement 
544    request. */
545
546 void silc_client_abort_key_agreement(SilcClient client,
547                                      SilcClientConnection conn,
548                                      SilcClientEntry client_entry)
549 {
550   assert(client_entry);
551
552   if (client_entry->ke) {
553     if (client_entry->ke->sock)
554       silc_socket_free(client_entry->ke->sock);
555     client_entry->ke = NULL;
556     silc_task_unregister_by_fd(client->io_queue, client_entry->ke->fd);
557     if (client_entry->ke->timeout)
558       silc_task_unregister(client->timeout_queue, 
559                            client_entry->ke->timeout);
560     silc_free(client_entry->ke);
561   }
562 }
563
564 /* Callback function that is called after we've resolved the client 
565    information who sent us the key agreement packet from the server.
566    We actually call the key_agreement client operation now. */
567
568 static void 
569 silc_client_key_agreement_resolve_cb(SilcClient client,
570                                      SilcClientConnection conn,
571                                      SilcClientEntry *clients,
572                                      unsigned int clients_count,
573                                      void *context)
574 {
575   SilcPacketContext *packet = (SilcPacketContext *)context;
576   SilcKeyAgreementPayload payload;
577   int ret;
578   SilcKeyAgreementCallback completion;
579   void *completion_context;
580
581   if (!clients)
582     goto out;
583
584   /* Parse the key agreement payload */
585   payload = silc_key_agreement_payload_parse(packet->buffer);
586   if (!payload)
587     goto out;
588
589   /* Call the key_agreement client operation */
590   ret = client->ops->key_agreement(client, conn, clients[0], 
591                                    silc_key_agreement_get_hostname(payload),
592                                    silc_key_agreement_get_port(payload),
593                                    &completion, &completion_context);
594
595   /* If the user returned TRUE then we'll start the key agreement right
596      here and right now. */
597   if (ret == TRUE)
598     silc_client_perform_key_agreement(client, conn, clients[0],
599                                       silc_key_agreement_get_hostname(payload),
600                                       silc_key_agreement_get_port(payload),
601                                       completion, completion_context);
602
603   silc_key_agreement_payload_free(payload);
604
605  out:
606   silc_packet_context_free(packet);
607 }
608
609 /* Received Key Agreement packet from remote client. Process the packet
610    and resolve the client information from the server before actually
611    letting the application know that we've received this packet.  Then 
612    call the key_agreement client operation and let the user decide
613    whether we perform the key agreement protocol now or not. */
614
615 void silc_client_key_agreement(SilcClient client,
616                                SilcSocketConnection sock,
617                                SilcPacketContext *packet)
618 {
619   SilcClientID *remote_id;
620
621   if (packet->src_id_type != SILC_ID_CLIENT)
622     return;
623
624   remote_id = silc_id_str2id(packet->src_id, packet->src_id_len, 
625                              SILC_ID_CLIENT);
626   if (!remote_id)
627     return;
628
629   silc_client_get_client_by_id_resolve(client, sock->user_data, remote_id,
630                                        silc_client_key_agreement_resolve_cb,
631                                        silc_packet_context_dup(packet));
632   silc_free(remote_id);
633 }