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