silcclient: check packet type as responder before starting AKE
[silc.git] / lib / silcclient / client_prvmsg.c
1 /*
2
3   client_prvmsg.c
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 1997 - 2014 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; version 2 of the License.
12
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.
17
18 */
19 /* $Id$ */
20
21 #include "silc.h"
22 #include "silcclient.h"
23 #include "client_internal.h"
24
25 /************************** Private Message Send ****************************/
26
27 /* Sends private message to remote client. */
28
29 SilcBool silc_client_send_private_message(SilcClient client,
30                                           SilcClientConnection conn,
31                                           SilcClientEntry client_entry,
32                                           SilcMessageFlags flags,
33                                           SilcHash hash,
34                                           unsigned char *data,
35                                           SilcUInt32 data_len)
36 {
37   SilcBuffer buffer;
38   SilcBool ret;
39   SilcID sid, rid;
40
41   if (silc_unlikely(!client || !conn || !client_entry))
42     return FALSE;
43   if (silc_unlikely(flags & SILC_MESSAGE_FLAG_SIGNED && !hash))
44     return FALSE;
45   if (silc_unlikely(conn->internal->disconnected))
46     return FALSE;
47
48   SILC_LOG_DEBUG(("Sending private message"));
49
50   /* Auto-negotiate private message key (AKE) if there is no key or
51      it's time to rekey. */
52   if (!client->internal->params->dont_autoneg_prvmsg_keys &&
53       !client_entry->internal.no_ake && client_entry != conn->local_entry &&
54       (!client_entry->internal.send_key ||
55        (client_entry->internal.ake_rekey <= silc_time() ||
56         client_entry->internal.ake_generation !=
57         conn->internal->ake_generation))) {
58     return silc_client_autoneg_private_message_key(
59                                         client, conn, client_entry, NULL,
60                                         flags, hash, data, data_len);
61   }
62
63   sid.type = SILC_ID_CLIENT;
64   sid.u.client_id = *conn->local_id;
65   rid.type = SILC_ID_CLIENT;
66   rid.u.client_id = client_entry->id;
67
68   /* Encode private message payload */
69   buffer =
70     silc_message_payload_encode(flags, data, data_len,
71                                 (!client_entry->internal.send_key ? FALSE :
72                                  !client_entry->internal.generated),
73                                 TRUE, client_entry->internal.send_key,
74                                 client_entry->internal.hmac_send,
75                                 client->rng, NULL, conn->private_key,
76                                 hash, &sid, &rid, NULL);
77   if (silc_unlikely(!buffer)) {
78     SILC_LOG_ERROR(("Error encoding private message"));
79     return FALSE;
80   }
81
82   /* Send the private message packet */
83   ret = silc_packet_send_ext(conn->stream, SILC_PACKET_PRIVATE_MESSAGE,
84                              client_entry->internal.send_key ?
85                              SILC_PACKET_FLAG_PRIVMSG_KEY : 0,
86                              0, NULL, SILC_ID_CLIENT, &client_entry->id,
87                              silc_buffer_datalen(buffer), NULL, NULL);
88
89   silc_buffer_free(buffer);
90   return ret;
91 }
92
93 /************************* Private Message Receive **************************/
94
95 /* Client resolving callback.  Continues with the private message processing */
96
97 static void silc_client_private_message_resolved(SilcClient client,
98                                                  SilcClientConnection conn,
99                                                  SilcStatus status,
100                                                  SilcDList clients,
101                                                  void *context)
102 {
103   /* If no client found, ignore the private message, a silent error */
104   if (!clients)
105     silc_fsm_next(context, silc_client_private_message_error);
106
107   /* Continue processing the private message packet */
108   SILC_FSM_CALL_CONTINUE(context);
109 }
110
111 /* Private message received. */
112
113 SILC_FSM_STATE(silc_client_private_message)
114 {
115   SilcClientConnection conn = fsm_context;
116   SilcClient client = conn->client;
117   SilcPacket packet = state_context;
118   SilcMessagePayload payload = NULL;
119   SilcClientID remote_id;
120   SilcClientEntry remote_client = NULL;
121   SilcMessageFlags flags;
122   unsigned char *message;
123   SilcUInt32 message_len;
124
125   SILC_LOG_DEBUG(("Received private message"));
126
127   if (silc_unlikely(packet->src_id_type != SILC_ID_CLIENT)) {
128     /** Invalid packet */
129     silc_fsm_next(fsm, silc_client_private_message_error);
130     return SILC_FSM_CONTINUE;
131   }
132
133   if (silc_unlikely(!silc_id_str2id(packet->src_id, packet->src_id_len,
134                                     SILC_ID_CLIENT, &remote_id,
135                                     sizeof(remote_id)))) {
136     /** Invalid source ID */
137     silc_fsm_next(fsm, silc_client_private_message_error);
138     return SILC_FSM_CONTINUE;
139   }
140
141   /* Check whether we know this client already */
142   remote_client = silc_client_get_client_by_id(client, conn, &remote_id);
143   if (!remote_client || !remote_client->nickname[0]) {
144     /** Resolve client info */
145     silc_client_unref_client(client, conn, remote_client);
146     SILC_FSM_CALL(silc_client_get_client_by_id_resolve(
147                                          client, conn, &remote_id, NULL,
148                                          silc_client_private_message_resolved,
149                                          fsm));
150     /* NOT REACHED */
151   }
152
153   if (silc_unlikely(packet->flags & SILC_PACKET_FLAG_PRIVMSG_KEY &&
154                     !remote_client->internal.receive_key &&
155                     !remote_client->internal.hmac_receive)) {
156 #if 1
157     /* Kludge to check if the message has SKE packet inside, and then start
158        key exchange protocol.  Remove this once AKE support is everywhere. */
159     payload = silc_message_payload_parse(silc_buffer_datalen(&packet->buffer),
160                                          TRUE, FALSE, NULL, NULL,
161                                          packet->src_id, packet->src_id_len,
162                                          packet->dst_id, packet->dst_id_len,
163                                          NULL, FALSE, NULL);
164     if (!payload)
165       goto out;
166
167     flags = silc_message_get_flags(payload);
168     if (flags & SILC_MESSAGE_FLAG_PACKET &&
169         silc_client_autoneg_private_message_key(client, conn, remote_client,
170                                                 packet, 0, NULL, NULL, 0))
171       packet = NULL;
172 #endif /* 0 */
173     goto out;
174   }
175
176   /* Parse the payload and decrypt it also if private message key is set */
177   payload =
178     silc_message_payload_parse(silc_buffer_datalen(&packet->buffer),
179                                TRUE, !remote_client->internal.generated,
180                                remote_client->internal.receive_key,
181                                remote_client->internal.hmac_receive,
182                                packet->src_id, packet->src_id_len,
183                                packet->dst_id, packet->dst_id_len,
184                                NULL, FALSE, NULL);
185   if (silc_unlikely(!payload)) {
186     /* Private message key is set but the sender may have removed it,
187        try to parse without it. */
188     if (remote_client->internal.receive_key) {
189       SILC_LOG_DEBUG(("Parse payload without using private message key"));
190       payload =
191         silc_message_payload_parse(silc_buffer_datalen(&packet->buffer),
192                                    TRUE, FALSE, NULL, NULL,
193                                    packet->src_id, packet->src_id_len,
194                                    packet->dst_id, packet->dst_id_len,
195                                    NULL, FALSE, NULL);
196     }
197   }
198   if (!payload)
199     goto out;
200
201   flags = silc_message_get_flags(payload);
202
203   /* If message contains SILC packet, process the packet here */
204   if (flags & SILC_MESSAGE_FLAG_PACKET) {
205     if (silc_client_autoneg_private_message_key(client, conn, remote_client,
206                                                 packet, 0, NULL, NULL, 0))
207       packet = NULL;
208     goto out;
209   }
210
211   message = silc_message_get_data(payload, &message_len);
212
213   /* Pass the private message to application */
214   client->internal->ops->private_message(client, conn, remote_client, payload,
215                                          flags, message, message_len);
216
217   /* See if we are away (gone). If we are away we will reply to the
218      sender with the set away message. */
219   if (conn->internal->away_message &&
220       !(flags & SILC_MESSAGE_FLAG_NOREPLY)) {
221     /* If it's me, ignore */
222     if (SILC_ID_CLIENT_COMPARE(&remote_id, conn->local_id))
223       goto out;
224
225     /* Send the away message */
226     silc_client_send_private_message(client, conn, remote_client,
227                                      SILC_MESSAGE_FLAG_AUTOREPLY |
228                                      SILC_MESSAGE_FLAG_NOREPLY, NULL,
229                                      conn->internal->away_message,
230                                      strlen(conn->internal->away_message));
231   }
232
233  out:
234   /** Packet processed */
235   if (packet)
236     silc_packet_free(packet);
237   silc_client_unref_client(client, conn, remote_client);
238   if (payload)
239     silc_message_payload_free(payload);
240   return SILC_FSM_FINISH;
241 }
242
243 /* Private message error. */
244
245 SILC_FSM_STATE(silc_client_private_message_error)
246 {
247   SilcPacket packet = state_context;
248   silc_packet_free(packet);
249   return SILC_FSM_FINISH;
250 }
251
252 /* Initialize private message waiter for the `conn' connection. */
253
254 SilcBool silc_client_private_message_wait_init(SilcClient client,
255                                                SilcClientConnection conn,
256                                                SilcClientEntry client_entry)
257 {
258   SilcID id;
259
260   if (client_entry->internal.prv_waiter)
261     return TRUE;
262
263   /* We want SILC_PACKET_PRIVATE_MESSAGE packets from this source ID. */
264   id.type = SILC_ID_CLIENT;
265   id.u.client_id = client_entry->id;
266
267   client_entry->internal.prv_waiter =
268     silc_packet_wait_init(conn->stream, &id, SILC_PACKET_PRIVATE_MESSAGE, -1);
269   if (!client_entry->internal.prv_waiter)
270     return FALSE;
271
272   return TRUE;
273 }
274
275 /* Uninitializes private message waiter. */
276
277 void silc_client_private_message_wait_uninit(SilcClient client,
278                                              SilcClientConnection conn,
279                                              SilcClientEntry client_entry)
280 {
281   if (!client_entry->internal.prv_waiter)
282     return;
283   silc_packet_wait_uninit(client_entry->internal.prv_waiter, conn->stream);
284   client_entry->internal.prv_waiter = NULL;
285 }
286
287 /* Blocks the calling process or thread until private message has been
288    received from the specified client. */
289
290 SilcBool silc_client_private_message_wait(SilcClient client,
291                                           SilcClientConnection conn,
292                                           SilcClientEntry client_entry,
293                                           SilcMessagePayload *payload)
294 {
295   SilcPacket packet;
296
297   if (!client_entry->internal.prv_waiter)
298     return FALSE;
299
300   /* Block until private message arrives */
301   do {
302     if ((silc_packet_wait(client_entry->internal.prv_waiter, 0, &packet)) < 0)
303       return FALSE;
304
305     /* Parse the payload and decrypt it also if private message key is set */
306     *payload =
307       silc_message_payload_parse(silc_buffer_data(&packet->buffer),
308                                  silc_buffer_len(&packet->buffer),
309                                  TRUE, !client_entry->internal.generated,
310                                  client_entry->internal.receive_key,
311                                  client_entry->internal.hmac_receive,
312                                  packet->src_id, packet->src_id_len,
313                                  packet->dst_id, packet->dst_id_len,
314                                  NULL, FALSE, NULL);
315     if (!(*payload)) {
316       silc_packet_free(packet);
317       continue;
318     }
319
320     break;
321   } while (1);
322
323   silc_packet_free(packet);
324   return TRUE;
325 }
326
327 /*************************** Private Message Key ****************************/
328
329 /* Sends private message key request.  Sender of this packet is initiator
330    when setting the private message key. */
331
332 static SilcBool
333 silc_client_send_private_message_key_request(SilcClient client,
334                                              SilcClientConnection conn,
335                                              SilcClientEntry client_entry)
336 {
337   const char *cipher, *hmac;
338
339   SILC_LOG_DEBUG(("Sending private message key request"));
340
341   cipher = silc_cipher_get_name(client_entry->internal.send_key);
342   hmac = silc_hmac_get_name(client_entry->internal.hmac_send);
343
344   /* Send the packet */
345   return silc_packet_send_va_ext(conn->stream,
346                                  SILC_PACKET_PRIVATE_MESSAGE_KEY,
347                                  0, 0, NULL, SILC_ID_CLIENT,
348                                  &client_entry->id, NULL, NULL,
349                                  SILC_STR_UI_SHORT(strlen(cipher)),
350                                  SILC_STR_DATA(cipher, strlen(cipher)),
351                                  SILC_STR_UI_SHORT(strlen(hmac)),
352                                  SILC_STR_DATA(hmac, strlen(hmac)),
353                                  SILC_STR_END);
354 }
355
356 /* Client resolving callback.  Here we simply mark that we are the responder
357    side of this private message key request.  */
358
359 static void silc_client_private_message_key_cb(SilcClient client,
360                                                SilcClientConnection conn,
361                                                SilcStatus status,
362                                                SilcDList clients,
363                                                void *context)
364 {
365   SilcFSMThread thread = context;
366   SilcPacket packet = silc_fsm_get_state_context(thread);
367   unsigned char *cipher = NULL, *hmac = NULL;
368   SilcClientEntry client_entry;
369   int ret;
370
371   if (!clients) {
372     silc_packet_free(packet);
373     silc_fsm_finish(thread);
374     return;
375   }
376
377   /* Parse the private message key payload */
378   ret = silc_buffer_unformat(&packet->buffer,
379                              SILC_STR_UI16_STRING_ALLOC(&cipher),
380                              SILC_STR_UI16_STRING_ALLOC(&hmac),
381                              SILC_STR_END);
382   if (!ret)
383     goto out;
384
385   /* Mark that we are responder */
386   client_entry = silc_dlist_get(clients);
387   if (client_entry)
388     client_entry->internal.prv_resp = TRUE;
389
390   /* XXX we should notify application that remote wants to set up the
391      static key.  And we should tell if we already have key with remote.
392      Application should return status telling whether to delete the key
393      or not. */
394
395  out:
396   silc_free(cipher);
397   silc_free(hmac);
398   silc_packet_free(packet);
399   silc_fsm_finish(thread);
400 }
401
402 /* Processes incoming Private Message Key payload to indicate that the
403    sender whishes to set up a static private message key. */
404
405 SILC_FSM_STATE(silc_client_private_message_key)
406 {
407   SilcClientConnection conn = fsm_context;
408   SilcClient client = conn->client;
409   SilcPacket packet = state_context;
410   SilcClientID remote_id;
411
412   if (packet->src_id_type != SILC_ID_CLIENT) {
413     silc_packet_free(packet);
414     return SILC_FSM_FINISH;
415   }
416
417   if (!silc_id_str2id(packet->src_id, packet->src_id_len, SILC_ID_CLIENT,
418                       &remote_id, sizeof(remote_id))) {
419     silc_packet_free(packet);
420     return SILC_FSM_FINISH;
421   }
422
423   /* Always resolve the remote client.  The actual packet is processed
424      in the resolving callback. */
425   SILC_FSM_CALL(silc_client_get_client_by_id_resolve(
426                                        client, conn, &remote_id, NULL,
427                                        silc_client_private_message_key_cb,
428                                        fsm));
429 }
430
431 /* Adds new private message key to `client_entry'.  If we are setting this
432    before receiving request for it from `client_entry' we will send the
433    request to the client.  Otherwise, we are responder side. */
434
435 SilcBool silc_client_add_private_message_key(SilcClient client,
436                                              SilcClientConnection conn,
437                                              SilcClientEntry client_entry,
438                                              const char *cipher,
439                                              const char *hmac,
440                                              unsigned char *key,
441                                              SilcUInt32 key_len)
442 {
443   SilcSKEKeyMaterial keymat;
444   SilcBool ret;
445
446   if (!client || !client_entry)
447     return FALSE;
448
449   /* Return FALSE if key already set */
450   if (client_entry->internal.send_key && client_entry->internal.receive_key)
451     return FALSE;
452
453   if (!cipher)
454     cipher = SILC_DEFAULT_CIPHER;
455   if (!hmac)
456     hmac = SILC_DEFAULT_HMAC;
457
458   /* Check the requested cipher and HMAC */
459   if (!silc_cipher_is_supported(cipher))
460     return FALSE;
461   if (!silc_hmac_is_supported(hmac))
462     return FALSE;
463
464   /* Save the key */
465   client_entry->internal.key = silc_memdup(key, key_len);
466   client_entry->internal.key_len = key_len;
467
468   /* Produce the key material as the protocol defines */
469   keymat = silc_ske_process_key_material_data(key, key_len, 16, 256, 16,
470                                               conn->internal->sha1hash);
471   if (!keymat)
472     return FALSE;
473
474   /* Set the key into use */
475   ret = silc_client_add_private_message_key_ske(client, conn, client_entry,
476                                                 cipher, hmac, keymat);
477   client_entry->internal.generated = FALSE;
478
479   /* Free the key material */
480   silc_ske_free_key_material(keymat);
481
482   /* If we are setting the key without a request from the remote client,
483      we will send request to remote. */
484   if (!client_entry->internal.prv_resp)
485     silc_client_send_private_message_key_request(client, conn, client_entry);
486
487   return ret;
488 }
489
490 /* Same as above but takes the key material from the SKE key material
491    structure. */
492
493 SilcBool silc_client_add_private_message_key_ske(SilcClient client,
494                                                  SilcClientConnection conn,
495                                                  SilcClientEntry client_entry,
496                                                  const char *cipher,
497                                                  const char *hmac,
498                                                  SilcSKEKeyMaterial keymat)
499 {
500   if (!client || !client_entry)
501     return FALSE;
502
503   /* Return FALSE if key already set */
504   if (client_entry->internal.send_key && client_entry->internal.receive_key)
505     return FALSE;
506
507   if (!cipher)
508     cipher = SILC_DEFAULT_CIPHER;
509   if (!hmac)
510     hmac = SILC_DEFAULT_HMAC;
511
512   /* Check the requested cipher and HMAC */
513   if (!silc_cipher_is_supported(cipher))
514     return FALSE;
515   if (!silc_hmac_is_supported(hmac))
516     return FALSE;
517
518   client_entry->internal.generated = TRUE;
519   client_entry->internal.no_ake = TRUE;
520
521   /* Allocate the cipher and HMAC */
522   if (!silc_cipher_alloc(cipher, &client_entry->internal.send_key))
523     return FALSE;
524   if (!silc_cipher_alloc(cipher, &client_entry->internal.receive_key))
525     return FALSE;
526   if (!silc_hmac_alloc(hmac, NULL, &client_entry->internal.hmac_send))
527     return FALSE;
528   if (!silc_hmac_alloc(hmac, NULL, &client_entry->internal.hmac_receive))
529     return FALSE;
530
531   /* Set the keys */
532   if (client_entry->internal.prv_resp) {
533     silc_cipher_set_key(client_entry->internal.send_key,
534                         keymat->receive_enc_key,
535                         keymat->enc_key_len, TRUE);
536     silc_cipher_set_iv(client_entry->internal.send_key,
537                        keymat->receive_iv);
538     silc_cipher_set_key(client_entry->internal.receive_key,
539                         keymat->send_enc_key,
540                         keymat->enc_key_len, FALSE);
541     silc_cipher_set_iv(client_entry->internal.receive_key, keymat->send_iv);
542     silc_hmac_set_key(client_entry->internal.hmac_send,
543                       keymat->receive_hmac_key,
544                       keymat->hmac_key_len);
545     silc_hmac_set_key(client_entry->internal.hmac_receive,
546                       keymat->send_hmac_key,
547                       keymat->hmac_key_len);
548   } else {
549     silc_cipher_set_key(client_entry->internal.send_key,
550                         keymat->send_enc_key,
551                         keymat->enc_key_len, TRUE);
552     silc_cipher_set_iv(client_entry->internal.send_key,
553                        keymat->send_iv);
554     silc_cipher_set_key(client_entry->internal.receive_key,
555                         keymat->receive_enc_key,
556                         keymat->enc_key_len, FALSE);
557     silc_cipher_set_iv(client_entry->internal.receive_key, keymat->receive_iv);
558     silc_hmac_set_key(client_entry->internal.hmac_send,
559                       keymat->send_hmac_key,
560                       keymat->hmac_key_len);
561     silc_hmac_set_key(client_entry->internal.hmac_receive,
562                       keymat->receive_hmac_key,
563                       keymat->hmac_key_len);
564   }
565
566   return TRUE;
567 }
568
569 /* Removes the private message from the library. The key won't be used
570    after this to protect the private messages with the remote `client_entry'
571    client. Returns FALSE on error, TRUE otherwise. */
572
573 SilcBool silc_client_del_private_message_key(SilcClient client,
574                                              SilcClientConnection conn,
575                                              SilcClientEntry client_entry)
576 {
577   if (!client || !client_entry)
578     return FALSE;
579
580   if (!client_entry->internal.send_key && !client_entry->internal.receive_key)
581     return FALSE;
582
583   silc_cipher_free(client_entry->internal.send_key);
584   silc_cipher_free(client_entry->internal.receive_key);
585
586   if (client_entry->internal.key) {
587     memset(client_entry->internal.key, 0, client_entry->internal.key_len);
588     silc_free(client_entry->internal.key);
589   }
590
591   client_entry->internal.send_key = NULL;
592   client_entry->internal.receive_key = NULL;
593   client_entry->internal.key = NULL;
594   client_entry->internal.prv_resp = FALSE;
595
596   return TRUE;
597 }
598
599 /* Returns array of set private message keys associated to the connection
600    `conn'. Returns allocated SilcPrivateMessageKeys array and the array
601    count to the `key_count' argument. The array must be freed by the caller
602    by calling the silc_client_free_private_message_keys function. Note:
603    the keys returned in the array is in raw format. It might not be desired
604    to show the keys as is. The application might choose not to show the keys
605    at all or to show the fingerprints of the keys. */
606
607 SilcPrivateMessageKeys
608 silc_client_list_private_message_keys(SilcClient client,
609                                       SilcClientConnection conn,
610                                       SilcUInt32 *key_count)
611 {
612   SilcPrivateMessageKeys keys;
613   SilcUInt32 count = 0;
614   SilcList list;
615   SilcIDCacheEntry id_cache;
616   SilcClientEntry entry;
617
618   if (!client || !conn)
619     return NULL;
620
621   silc_mutex_lock(conn->internal->lock);
622   if (!silc_idcache_get_all(conn->internal->client_cache, &list)) {
623     silc_mutex_unlock(conn->internal->lock);
624     return NULL;
625   }
626
627   keys = silc_calloc(silc_list_count(list), sizeof(*keys));
628   if (!keys) {
629     silc_mutex_unlock(conn->internal->lock);
630     return NULL;
631   }
632
633   silc_list_start(list);
634   while ((id_cache = silc_list_get(list))) {
635     entry = id_cache->context;
636     if (entry->internal.send_key) {
637       keys[count].client_entry = entry;
638       keys[count].cipher = (char *)silc_cipher_get_name(entry->internal.
639                                                         send_key);
640       keys[count].key = (entry->internal.generated == FALSE ?
641                          entry->internal.key : NULL);
642       keys[count].key_len = (entry->internal.generated == FALSE ?
643                              entry->internal.key_len : 0);
644       count++;
645     }
646   }
647
648   silc_mutex_unlock(conn->internal->lock);
649
650   if (key_count)
651     *key_count = count;
652
653   return keys;
654 }
655
656 /* Frees the SilcPrivateMessageKeys array returned by the function
657    silc_client_list_private_message_keys. */
658
659 void silc_client_free_private_message_keys(SilcPrivateMessageKeys keys,
660                                            SilcUInt32 key_count)
661 {
662   silc_free(keys);
663 }
664
665 /* Return private message key from the client entry. */
666
667 SilcBool
668 silc_client_private_message_key_is_set(SilcClient client,
669                                        SilcClientConnection conn,
670                                        SilcClientEntry client_entry)
671 {
672   return client_entry->internal.send_key != NULL;
673 }
674
675 /********************* Private Message Key Autoneg (AKE) ********************/
676
677 /* Private message key auto-negotiation context */
678 struct SilcClientAutonegMessageKeyStruct {
679   SilcClientConnection conn;             /* Connection to server */
680   SilcSKE ske;                           /* SKE with remote client */
681   SilcAsyncOperation ske_op;             /* SKE operation */
682   SilcStream stream;                     /* PRIVATE_MESSAGE stream */
683   SilcPacketStream ske_stream;           /* Packet stream for SKE (inside
684                                             the PRIVATE_MESSAGE stream) */
685   SilcDList messages;                    /* Message queue */
686   SilcHash hash;                         /* Initial message hash */
687   SilcPublicKey public_key;              /* Remote client public key */
688   SilcVerifyKeyContext verify;
689   SilcSKEParamsStruct params;
690   SilcUInt32 generation;                 /* Starting AKE generation */
691 };
692
693 static SilcBool
694 silc_client_autoneg_key_recv_ske(SilcPacketEngine engine,
695                                  SilcPacketStream stream,
696                                  SilcPacket packet,
697                                  void *callback_context,
698                                  void *stream_context);
699
700 static const SilcPacketCallbacks autoneg_key_ske_cbs =
701 {
702   silc_client_autoneg_key_recv_ske, NULL, NULL
703 };
704
705 /* Destroy auto-negotiation context */
706
707 static void silc_client_autoneg_key_free(SilcClient client,
708                                          SilcClientConnection conn,
709                                          SilcClientEntry client_entry)
710 {
711   SilcClientAutonegMessageKey ake = client_entry->internal.ake;
712   SilcBuffer m;
713
714   if (ake->ske_op)
715     silc_async_abort(ake->ske_op, NULL, NULL);
716
717   silc_ske_free(ake->ske);
718   silc_packet_stream_unlink(ake->ske_stream, &autoneg_key_ske_cbs, NULL);
719   silc_packet_stream_destroy(ake->ske_stream);
720   if (ake->hash)
721     silc_hash_free(ake->hash);
722
723   silc_dlist_start(ake->messages);
724   while ((m = silc_dlist_get(ake->messages)) != SILC_LIST_END) {
725     silc_dlist_del(ake->messages, m);
726     silc_buffer_free(m);
727   }
728   silc_dlist_uninit(ake->messages);
729
730   client_entry->internal.op = NULL;
731   client_entry->internal.ake = NULL;
732   silc_client_unref_client(client, conn, client_entry);
733
734   if (ake->verify)
735     ake->verify->aborted = TRUE;
736   else if (ake->public_key)
737     silc_pkcs_public_key_free(ake->public_key);
738
739   silc_free(ake);
740 }
741
742 /* Destroy auto-negotiation context */
743
744 SILC_TASK_CALLBACK(silc_client_autoneg_key_finish)
745 {
746   SilcClientEntry client_entry = context;
747   SilcClientAutonegMessageKey ake = client_entry->internal.ake;
748   SilcClientConnection conn = ake->conn;
749   SilcClient client = conn->client;
750
751   silc_client_autoneg_key_free(client, conn, client_entry);
752 }
753
754 /* Abort callback.  This aborts the auto-negotiation and the SKE */
755
756 static void
757 silc_client_autoneg_key_abort(SilcAsyncOperation op, void *context)
758 {
759   SilcClientEntry client_entry = context;
760   SilcClientAutonegMessageKey ake = client_entry->internal.ake;
761   SilcClientConnection conn = ake->conn;
762   SilcClient client = conn->client;
763
764   if (!ake)
765     return;
766
767   silc_client_autoneg_key_free(client, conn, client_entry);
768 }
769
770 /* SKE packet stream callback.  Here we verify that the packets we got
771    from the private message are actually SKE packets for us. */
772
773 static SilcBool
774 silc_client_autoneg_key_recv_ske(SilcPacketEngine engine,
775                                  SilcPacketStream stream,
776                                  SilcPacket packet,
777                                  void *callback_context,
778                                  void *stream_context)
779 {
780   SilcClientEntry client_entry = stream_context;
781   SilcClientAutonegMessageKey ake = client_entry->internal.ake;
782   SilcClientID remote_id;
783
784   SILC_LOG_DEBUG(("Packet %p type %d inside private message", packet,
785                   packet->type));
786
787   /* Take only SKE packets, drop others, no support for anything else */
788   if (packet->type != SILC_PACKET_KEY_EXCHANGE &&
789       packet->type != SILC_PACKET_KEY_EXCHANGE_1 &&
790       packet->type != SILC_PACKET_KEY_EXCHANGE_2 &&
791       packet->type != SILC_PACKET_FAILURE)
792     goto drop;
793
794   /* Must be from client to client */
795   if (packet->dst_id_type != SILC_ID_CLIENT ||
796       packet->src_id_type != SILC_ID_CLIENT)
797     goto drop;
798
799   if (!silc_id_str2id(packet->src_id, packet->src_id_len, SILC_ID_CLIENT,
800                       &remote_id, sizeof(remote_id)))
801     goto drop;
802
803   if (!SILC_ID_CLIENT_COMPARE(&client_entry->id, &remote_id)) {
804     /* The packet is not for this client, but it must be */
805     SILC_LOG_DEBUG(("Client ids do not match"));
806     goto drop;
807   }
808
809   /* Responder is started here if correct packet comes in */
810   if (!ake->ske_op) {
811     if (packet->type == SILC_PACKET_KEY_EXCHANGE)
812       {
813         /* Ignore pre-set proposal */
814         if (ake->params.prop) {
815           silc_ske_group_free(ake->params.prop->group);
816           silc_cipher_free(ake->params.prop->cipher);
817           silc_hash_free(ake->params.prop->hash);
818           silc_hmac_free(ake->params.prop->hmac);
819           silc_pkcs_public_key_free(ake->params.prop->public_key);
820           silc_free(ake->params.prop);
821           ake->params.prop = NULL;
822         }
823       }
824     else if (packet->type != SILC_PACKET_KEY_EXCHANGE_1)
825       {
826         SILC_LOG_DEBUG(("Invalid SKE packet for responder"));
827         silc_async_abort(client_entry->internal.op, NULL, NULL);
828         goto drop;
829       }
830
831     ake->ske_op = silc_ske_responder(ake->ske, ake->ske_stream, &ake->params);
832     if (!ake->ske_op) {
833       silc_async_abort(client_entry->internal.op, NULL, NULL);
834       goto drop;
835     }
836
837     /* We have to re-inject the packet to SKE stream because SKE wasn't
838        listenning to these packets until silc_ske_responder() was called */
839     silc_packet_stream_inject(ake->ske_stream, packet);
840     return TRUE;
841   }
842
843   /* Packet is ok and is for us, let it pass to SKE */
844   SILC_LOG_DEBUG(("Pass packet %p type %d", packet, packet->type));
845   return FALSE;
846
847  drop:
848   silc_packet_free(packet);
849   return TRUE;
850 }
851
852 /* Coder callback for actually encoding/decoding the SKE packets inside
853    private messages. */
854
855 static SilcBool silc_client_autoneg_key_coder(SilcStream stream,
856                                               SilcStreamStatus status,
857                                               SilcBuffer buffer,
858                                               void *context)
859 {
860   SilcBool ret = FALSE;
861   SilcBuffer message;
862   SilcMessagePayload payload = NULL;
863   SilcMessageFlags flags;
864   unsigned char *msg;
865   SilcUInt32 message_len;
866
867   switch (status) {
868   case SILC_STREAM_CAN_READ:
869     /* Decode private message.  We get all private messages here from
870        the remote client while we're doing SKE, so we must take the
871        correct messages. */
872     SILC_LOG_DEBUG(("Decode packet inside private message"));
873
874     payload = silc_message_payload_parse(silc_buffer_datalen(buffer),
875                                          TRUE, FALSE, NULL, NULL, NULL, 0,
876                                          NULL, 0, NULL, FALSE, NULL);
877     if (!payload) {
878       SILC_LOG_DEBUG(("Error decoding private message payload"));
879       goto out;
880     }
881
882     /* Ignore this message if it's not packet */
883     flags = silc_message_get_flags(payload);
884     if (!(flags & SILC_MESSAGE_FLAG_PACKET)) {
885       SILC_LOG_DEBUG(("Private message doesn't contain packet"));
886       silc_message_payload_free(payload);
887       goto out;
888     }
889
890     /* Take the packet */
891     ret = TRUE;
892
893     msg = silc_message_get_data(payload, &message_len);
894     silc_buffer_reset(buffer);
895     if (!silc_buffer_enlarge(buffer, message_len)) {
896       silc_message_payload_free(payload);
897       goto out;
898     }
899     silc_buffer_put(buffer, msg, message_len);
900
901     silc_message_payload_free(payload);
902     break;
903
904   case SILC_STREAM_CAN_WRITE:
905     /* Encode private message */
906     SILC_LOG_DEBUG(("Encode packet inside private message"));
907
908     ret = TRUE;
909
910     message =
911       silc_message_payload_encode(SILC_MESSAGE_FLAG_PACKET,
912                                   silc_buffer_datalen(buffer),
913                                   FALSE, TRUE, NULL, NULL, NULL,
914                                   NULL, NULL, NULL, NULL, NULL, NULL);
915     if (!message) {
916       SILC_LOG_DEBUG(("Error encoding private message payload"));
917       goto out;
918     }
919
920     silc_buffer_reset(buffer);
921     if (!silc_buffer_enlarge(buffer, silc_buffer_len(message)))
922       goto out;
923     silc_buffer_put(buffer, silc_buffer_datalen(message));
924
925     break;
926
927   default:
928     break;
929   }
930
931  out:
932   return ret;
933 }
934
935 /* Called after application has verified remote client's public key */
936
937 static void
938 silc_client_autoneg_key_verify_pubkey_cb(SilcBool success, void *context)
939 {
940   SilcVerifyKeyContext verify = context;
941   SilcClientAutonegMessageKey ake = verify->context;
942
943   SILC_LOG_DEBUG(("Start"));
944
945   /* Call the completion callback back to the SKE */
946   if (!verify->aborted) {
947     ake->verify = NULL;
948     verify->completion(verify->ske, success ? SILC_SKE_STATUS_OK :
949                        SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
950                        verify->completion_context);
951   } else {
952     silc_pkcs_public_key_free(verify->public_key);
953   }
954
955   silc_free(verify);
956 }
957
958 /* Remote client's public key verification callback */
959
960 static void
961 silc_client_autoneg_key_verify_pubkey(SilcSKE ske,
962                                       SilcPublicKey public_key,
963                                       void *context,
964                                       SilcSKEVerifyCbCompletion completion,
965                                       void *completion_context)
966 {
967   SilcClientEntry client_entry = context;
968   SilcClientAutonegMessageKey ake = client_entry->internal.ake;
969   SilcClientConnection conn = ake->conn;
970   SilcClient client = conn->client;
971   SilcVerifyKeyContext verify;
972
973   /* Use public key we cached earlier in AKE for direction verification */
974   if (client_entry->internal.send_key && client_entry->public_key &&
975       silc_pkcs_public_key_compare(public_key, client_entry->public_key)) {
976     SILC_LOG_DEBUG(("Client's cached public key matches"));
977     completion(ske, SILC_SKE_STATUS_OK, completion_context);
978     return;
979   }
980
981   /* If we provided repository for SKE and we got here the key was not
982      found from the repository. */
983   if (conn->internal->params.repository &&
984       !conn->internal->params.verify_notfound) {
985     completion(ske, SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
986                completion_context);
987     return;
988   }
989
990   SILC_LOG_DEBUG(("Verify remote client public key"));
991
992   ake->public_key = silc_pkcs_public_key_copy(public_key);
993   if (!ake->public_key) {
994     completion(ske, SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
995                completion_context);
996     return;
997   }
998
999   verify = silc_calloc(1, sizeof(*verify));
1000   if (!verify) {
1001     completion(ske, SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
1002                completion_context);
1003     return;
1004   }
1005   verify->public_key = ake->public_key;
1006   verify->ske = ske;
1007   verify->completion = completion;
1008   verify->completion_context = completion_context;
1009   verify->context = ake;
1010   ake->verify = verify;
1011
1012   /* Verify public key in application */
1013   client->internal->ops->verify_public_key(
1014                                 client, conn,
1015                                 SILC_CONN_CLIENT, ake->public_key,
1016                                 silc_client_autoneg_key_verify_pubkey_cb,
1017                                 verify);
1018 }
1019
1020 /* Key exchange protocol completion callback */
1021
1022 static void silc_client_autoneg_key_done(SilcSKE ske,
1023                                          SilcSKEStatus status,
1024                                          SilcSKESecurityProperties prop,
1025                                          SilcSKEKeyMaterial keymat,
1026                                          SilcSKERekeyMaterial rekey,
1027                                          void *context)
1028 {
1029   SilcClientEntry client_entry = context;
1030   SilcClientAutonegMessageKey ake = client_entry->internal.ake;
1031   SilcClientConnection conn = ake->conn;
1032   SilcClient client = conn->client;
1033   SilcBool initiator = !client_entry->internal.prv_resp;
1034   SilcMessageFlags flags;
1035   SilcBuffer m;
1036
1037   ake->ske_op = NULL;
1038
1039   conn->context_type = SILC_ID_CLIENT;
1040   conn->client_entry = client_entry;
1041
1042   if (status != SILC_SKE_STATUS_OK) {
1043     /* Key exchange failed */
1044     SILC_LOG_DEBUG(("Error during key exchange: %s (%d)",
1045                     silc_ske_map_status(status), status));
1046
1047     if (initiator) {
1048       if (status != SILC_SKE_STATUS_PROBE_TIMEOUT)
1049         client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
1050                                    "Cannot send private message to %s (%s)",
1051                                    client_entry->nickname,
1052                                    silc_ske_map_status(status));
1053       else if (client_entry->mode & SILC_UMODE_DETACHED)
1054         client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
1055                                    "Cannot send private message to detached "
1056                                    "client %s", client_entry->nickname);
1057     } else if (status != SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY) {
1058       client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
1059                                  "Private message key exchange failed "
1060                                  "with %s (%s)", client_entry->nickname,
1061                                  silc_ske_map_status(status));
1062     }
1063
1064     /* Errors that occur due to user not responding or deciding not to
1065        trust the public key will not cause us to stop trying AKE next time.
1066        Other errors disable AKE to allow communication with other means. */
1067     if (initiator && status != SILC_SKE_STATUS_TIMEOUT &&
1068         status != SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY &&
1069         !(client_entry->mode & SILC_UMODE_DETACHED)) {
1070       client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_INFO,
1071                                  "Cannot auto-negotiate key with %s, "
1072                                  "messages will be protected with "
1073                                  "session key", client_entry->nickname);
1074
1075       /* Don't try this again with this client */
1076       client_entry->internal.no_ake = TRUE;
1077     }
1078     goto out;
1079   }
1080
1081   /* Set the new private message key into use */
1082   silc_client_del_private_message_key(client, conn, client_entry);
1083   client_entry->internal.prv_resp = !initiator;
1084   if (!silc_client_add_private_message_key_ske(
1085                                         client, conn, client_entry,
1086                                         silc_cipher_get_name(prop->cipher),
1087                                         silc_hmac_get_name(prop->hmac),
1088                                         keymat)) {
1089     SILC_LOG_DEBUG(("Error adding private message key"));
1090
1091     client->internal->ops->say(client, conn,
1092                                SILC_CLIENT_MESSAGE_ERROR,
1093                                "Private message key exchange error: "
1094                                "cannot use keys");
1095
1096     /* Don't try this again with this client */
1097     client_entry->internal.no_ake = TRUE;
1098     goto out;
1099   }
1100
1101   /* Save the public key to client entry */
1102   if (!client_entry->public_key) {
1103     client_entry->public_key = ake->public_key;
1104     ake->public_key = NULL;
1105   }
1106
1107   /* Rekey periodically */
1108   client_entry->internal.ake_rekey = silc_time() + 300;
1109   if (initiator)
1110     client_entry->internal.ake_rekey -= 30;
1111   client_entry->internal.ake_generation = conn->internal->ake_generation;
1112   client_entry->internal.no_ake = FALSE;
1113
1114   SILC_LOG_DEBUG(("AKE completed as %s with %s, rekey in %u secs, "
1115                   "generation %u", initiator ? "initiator" : "responder",
1116                   client_entry->nickname, 300,
1117                   conn->internal->ake_generation));
1118
1119   /* Send queued messages */
1120   silc_dlist_start(ake->messages);
1121   while ((m = silc_dlist_get(ake->messages)) != SILC_LIST_END) {
1122     SILC_GET16_MSB(flags, m->data - 2);
1123     silc_client_send_private_message(client, conn, client_entry,
1124                                      flags, ake->hash,
1125                                      silc_buffer_datalen(m));
1126   }
1127
1128  out:
1129   conn->context_type = SILC_ID_NONE;
1130   conn->client_entry = NULL;
1131   silc_schedule_task_add_timeout(client->schedule,
1132                                  silc_client_autoneg_key_finish,
1133                                  client_entry, 0, 1);
1134 }
1135
1136 /* Auto-negotiate private message key with the remote client using the
1137    SKE protocol, which is tunneled through the SILC network inside private
1138    messages shared between the us and the remote client.
1139
1140    This operation is naturally asynchronous and will involve exchanging
1141    multiple messages back and forth.  Despite this, we don't run this
1142    operation in own FSM thread here, but instead will use the SKE library
1143    to do the asynchronous operation which we can abort at any time in
1144    case user disconnects.
1145
1146    Messages and packets we receive during this operation will be processed
1147    in the normal connection thread. */
1148
1149 SilcBool
1150 silc_client_autoneg_private_message_key(SilcClient client,
1151                                         SilcClientConnection conn,
1152                                         SilcClientEntry client_entry,
1153                                         SilcPacket initiator_packet,
1154                                         SilcMessageFlags flags,
1155                                         SilcHash hash,
1156                                         unsigned char *data,
1157                                         SilcUInt32 data_len)
1158 {
1159   SilcClientAutonegMessageKey ake;
1160   SilcBool initiator = initiator_packet == NULL;
1161   SilcBuffer m;
1162
1163   SILC_LOG_DEBUG(("Start private message AKE as %s with %s",
1164                   initiator ? "initiator" : "responder",
1165                   client_entry->nickname));
1166
1167   if (client_entry->internal.op) {
1168     ake = client_entry->internal.ake;
1169     if (ake && data) {
1170       /* If generation has changed, we must abort this exchange and
1171          start a new one. */
1172       if (ake->generation != conn->internal->ake_generation) {
1173         SILC_LOG_DEBUG(("Abort ongoing AKE and start new one"));
1174         silc_async_abort(client_entry->internal.op, NULL, NULL);
1175       } else {
1176         SILC_LOG_DEBUG(("AKE is ongoing, queue the message"));
1177
1178         m = silc_buffer_alloc_size(data_len + 2);
1179         if (!m)
1180           return FALSE;
1181         SILC_PUT16_MSB(flags, m->data);
1182         silc_buffer_pull(m, 2);
1183         silc_buffer_put(m, data, data_len);
1184         silc_dlist_add(ake->messages, m);
1185         return TRUE;
1186       }
1187     } else {
1188       SILC_LOG_DEBUG(("Cannot start AKE, operation %p is ongoing",
1189                       client_entry->internal.op));
1190       return FALSE;
1191     }
1192   }
1193
1194   ake = silc_calloc(1, sizeof(*ake));
1195   if (!ake)
1196     return FALSE;
1197   ake->conn = conn;
1198   ake->generation = conn->internal->ake_generation;
1199
1200   ake->messages = silc_dlist_init();
1201   if (!ake->messages)
1202     goto err;
1203
1204   /* Wrap our packet stream to a generic stream for the private messages
1205      we are going to exchange.  We send the packets with packet flag
1206      SILC_PACKET_FLAG_PRIVMSG_KEY which is a lie, but is a way to get
1207      clients which do not support this protocol to ignore these messages.
1208      This kludge should be removed once support is everywhere and
1209      responder should look only for the SILC_MESSAGE_FLAG_PACKET. */
1210   ake->stream = silc_packet_stream_wrap(conn->stream,
1211                                         SILC_PACKET_PRIVATE_MESSAGE,
1212                                         SILC_PACKET_FLAG_PRIVMSG_KEY, FALSE,
1213                                         SILC_ID_NONE, NULL,
1214                                         SILC_ID_CLIENT, &client_entry->id,
1215                                         silc_client_autoneg_key_coder,
1216                                         client_entry);
1217   if (!ake->stream)
1218     goto err;
1219
1220   /* Create a new packet stream for the SKE library using the wrapped
1221      stream as the underlaying stream, in effect creating a tunnel to
1222      send SKE packets inside private message packets. */
1223   ake->ske_stream = silc_packet_stream_create(client->internal->packet_engine,
1224                                               conn->internal->schedule,
1225                                               ake->stream);
1226   if (!ake->ske_stream)
1227     goto err;
1228
1229   silc_packet_set_context(ake->ske_stream, client_entry);
1230   silc_packet_set_ids(ake->ske_stream, SILC_ID_CLIENT, conn->local_id,
1231                       SILC_ID_CLIENT, &client_entry->id);
1232
1233   /* Link to the new packet stream to intercept the packets before they
1234      go to SKE library so that we can do additional checks and decide if
1235      we really want to process the packets. */
1236   if (!silc_packet_stream_link(ake->ske_stream, &autoneg_key_ske_cbs, NULL,
1237                                1000001, SILC_PACKET_ANY, -1))
1238     goto err;
1239
1240   /* Create SKE */
1241   ake->ske = silc_ske_alloc(client->rng, conn->internal->schedule,
1242                             conn->internal->params.repository,
1243                             conn->public_key, conn->private_key,
1244                             client_entry);
1245   if (!ake->ske)
1246     goto err;
1247
1248   silc_ske_set_callbacks(ake->ske, silc_client_autoneg_key_verify_pubkey,
1249                          silc_client_autoneg_key_done, client_entry);
1250   ake->params.version = client->internal->silc_client_version;
1251   ake->params.probe_timeout_secs = 5;
1252   ake->params.timeout_secs = 120;
1253   ake->params.flags = SILC_SKE_SP_FLAG_MUTUAL | SILC_SKE_SP_FLAG_PFS;
1254   ake->params.small_proposal = TRUE;
1255   ake->params.no_acks = TRUE;
1256
1257   if (client_entry->internal.send_key &&
1258       client_entry->internal.ake_generation == ake->generation) {
1259     /* Security properties for rekey */
1260     SilcSKESecurityProperties prop = silc_calloc(1, sizeof(*prop));
1261     if (!prop)
1262       goto err;
1263     silc_cipher_alloc(silc_cipher_get_name(client_entry->internal.send_key),
1264                       &prop->cipher);
1265     silc_hmac_alloc(silc_hmac_get_name(client_entry->internal.hmac_send),
1266                     NULL, &prop->hmac);
1267     silc_hash_alloc(silc_hash_get_name(silc_hmac_get_hash(
1268                         client_entry->internal.hmac_send)), &prop->hash);
1269     prop->public_key = silc_pkcs_public_key_copy(client_entry->public_key);
1270     silc_ske_group_get_by_number(2, &prop->group);
1271     prop->flags = ake->params.flags;
1272     ake->params.prop = prop;
1273   }
1274
1275   /* Start key exchange, responder is started in the packet callback  */
1276   if (initiator) {
1277     ake->ske_op = silc_ske_initiator(ake->ske, ake->ske_stream, &ake->params,
1278                                      NULL);
1279     if (!ake->ske_op)
1280       goto err;
1281   }
1282
1283   /* Finally, set up the client entry */
1284   client_entry->internal.op = silc_async_alloc(silc_client_autoneg_key_abort,
1285                                                NULL, client_entry);
1286   if (!client_entry->internal.op)
1287     goto err;
1288   client_entry->internal.ake = ake;
1289   client_entry->internal.no_ake = FALSE;
1290   client_entry->internal.prv_resp = !initiator;
1291   silc_client_ref_client(client, conn, client_entry);
1292
1293   /* As responder reinject the packet to the new stream so it gets decoded
1294      from the private message payload. */
1295   if (initiator_packet)
1296     silc_packet_stream_inject(conn->stream, initiator_packet);
1297
1298   /* Save the initial message, it will be sent after the key has been
1299      negotiated. */
1300   if (data && data_len) {
1301     m = silc_buffer_alloc_size(data_len + 2);
1302     if (m) {
1303       SILC_PUT16_MSB(flags, m->data);
1304       silc_buffer_pull(m, 2);
1305       silc_buffer_put(m, data, data_len);
1306       silc_dlist_add(ake->messages, m);
1307     }
1308     if (hash)
1309       silc_hash_alloc(silc_hash_get_name(hash), &ake->hash);
1310   }
1311
1312   return TRUE;
1313
1314  err:
1315   if (ake->ske)
1316     silc_ske_free(ake->ske);
1317   if (ake->ske_stream) {
1318     silc_packet_stream_unlink(ake->ske_stream, &autoneg_key_ske_cbs, NULL);
1319     silc_packet_stream_destroy(ake->ske_stream);
1320   } else if (ake->stream)
1321     silc_stream_destroy(ake->stream);
1322   silc_dlist_uninit(ake->messages);
1323   silc_free(ake);
1324   return FALSE;
1325 }
1326
1327 /* Sets away `message'.  The away message may be set when the client's
1328    mode is changed to SILC_UMODE_GONE and the client whishes to reply
1329    to anyone who sends private message.  The `message' will be sent
1330    automatically back to the the client who send private message.  If
1331    away message is already set this replaces the old message with the
1332    new one.  If `message' is NULL the old away message is removed.
1333    The sender may freely free the memory of the `message'. */
1334
1335 SilcBool silc_client_set_away_message(SilcClient client,
1336                                       SilcClientConnection conn,
1337                                       char *message)
1338 {
1339   if (!client || !conn)
1340     return FALSE;
1341
1342   if (!message) {
1343     silc_free(conn->internal->away_message);
1344     conn->internal->away_message = NULL;
1345     return TRUE;
1346   }
1347
1348   if (conn->internal->away_message)
1349     silc_free(conn->internal->away_message);
1350
1351   conn->internal->away_message = strdup(message);
1352   if (!conn->internal->away_message)
1353     return FALSE;
1354
1355   return TRUE;
1356 }