silcclient: auto-negotiation of private message key using SKE over SILCnet
[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   SilcUInt32 generation;                 /* Starting AKE generation */
690 };
691
692 static SilcBool
693 silc_client_autoneg_key_recv_ske(SilcPacketEngine engine,
694                                  SilcPacketStream stream,
695                                  SilcPacket packet,
696                                  void *callback_context,
697                                  void *stream_context);
698
699 static const SilcPacketCallbacks autoneg_key_ske_cbs =
700 {
701   silc_client_autoneg_key_recv_ske, NULL, NULL
702 };
703
704 /* Destroy auto-negotiation context */
705
706 static void silc_client_autoneg_key_free(SilcClient client,
707                                          SilcClientConnection conn,
708                                          SilcClientEntry client_entry)
709 {
710   SilcClientAutonegMessageKey ake = client_entry->internal.ake;
711   SilcBuffer m;
712
713   if (ake->ske_op)
714     silc_async_abort(ake->ske_op, NULL, NULL);
715
716   silc_ske_free(ake->ske);
717   silc_packet_stream_unlink(ake->ske_stream, &autoneg_key_ske_cbs, NULL);
718   silc_packet_stream_destroy(ake->ske_stream);
719   if (ake->hash)
720     silc_hash_free(ake->hash);
721
722   silc_dlist_start(ake->messages);
723   while ((m = silc_dlist_get(ake->messages)) != SILC_LIST_END) {
724     silc_dlist_del(ake->messages, m);
725     silc_buffer_free(m);
726   }
727   silc_dlist_uninit(ake->messages);
728
729   client_entry->internal.op = NULL;
730   client_entry->internal.ake = NULL;
731   silc_client_unref_client(client, conn, client_entry);
732
733   if (ake->verify)
734     ake->verify->aborted = TRUE;
735   else if (ake->public_key)
736     silc_pkcs_public_key_free(ake->public_key);
737
738   silc_free(ake);
739 }
740
741 /* Destroy auto-negotiation context */
742
743 SILC_TASK_CALLBACK(silc_client_autoneg_key_finish)
744 {
745   SilcClientEntry client_entry = context;
746   SilcClientAutonegMessageKey ake = client_entry->internal.ake;
747   SilcClientConnection conn = ake->conn;
748   SilcClient client = conn->client;
749
750   silc_client_autoneg_key_free(client, conn, client_entry);
751 }
752
753 /* Abort callback.  This aborts the auto-negotiation and the SKE */
754
755 static void
756 silc_client_autoneg_key_abort(SilcAsyncOperation op, void *context)
757 {
758   SilcClientEntry client_entry = context;
759   SilcClientAutonegMessageKey ake = client_entry->internal.ake;
760   SilcClientConnection conn = ake->conn;
761   SilcClient client = conn->client;
762
763   if (!ake)
764     return;
765
766   silc_client_autoneg_key_free(client, conn, client_entry);
767 }
768
769 /* SKE packet stream callback.  Here we verify that the packets we got
770    from the private message are actually SKE packets for us. */
771
772 static SilcBool
773 silc_client_autoneg_key_recv_ske(SilcPacketEngine engine,
774                                  SilcPacketStream stream,
775                                  SilcPacket packet,
776                                  void *callback_context,
777                                  void *stream_context)
778 {
779   SilcClientEntry client_entry = stream_context;
780   SilcClientID remote_id;
781
782   SILC_LOG_DEBUG(("Packet %p type %d inside private message", packet,
783                   packet->type));
784
785   /* Take only SKE packets, drop others, no support for anything else */
786   if (packet->type != SILC_PACKET_KEY_EXCHANGE &&
787       packet->type != SILC_PACKET_KEY_EXCHANGE_1 &&
788       packet->type != SILC_PACKET_KEY_EXCHANGE_2 &&
789       packet->type != SILC_PACKET_FAILURE)
790     goto drop;
791
792   /* Must be from client to client */
793   if (packet->dst_id_type != SILC_ID_CLIENT ||
794       packet->src_id_type != SILC_ID_CLIENT)
795     goto drop;
796
797   if (!silc_id_str2id(packet->src_id, packet->src_id_len, SILC_ID_CLIENT,
798                       &remote_id, sizeof(remote_id)))
799     goto drop;
800
801   if (!SILC_ID_CLIENT_COMPARE(&client_entry->id, &remote_id)) {
802     /* The packet is not for this client, but it must be */
803     SILC_LOG_DEBUG(("Client ids do not match"));
804     goto drop;
805   }
806
807   /* Packet is ok and is for us, let it pass to SKE */
808   SILC_LOG_DEBUG(("Pass packet %p type %d", packet, packet->type));
809   return FALSE;
810
811  drop:
812   silc_packet_free(packet);
813   return TRUE;
814 }
815
816 /* Coder callback for actually encoding/decoding the SKE packets inside
817    private messages. */
818
819 static SilcBool silc_client_autoneg_key_coder(SilcStream stream,
820                                               SilcStreamStatus status,
821                                               SilcBuffer buffer,
822                                               void *context)
823 {
824   SilcBool ret = FALSE;
825   SilcBuffer message;
826   SilcMessagePayload payload = NULL;
827   SilcMessageFlags flags;
828   unsigned char *msg;
829   SilcUInt32 message_len;
830
831   switch (status) {
832   case SILC_STREAM_CAN_READ:
833     /* Decode private message.  We get all private messages here from
834        the remote client while we're doing SKE, so we must take the
835        correct messages. */
836     SILC_LOG_DEBUG(("Decode packet inside private message"));
837
838     payload = silc_message_payload_parse(silc_buffer_datalen(buffer),
839                                          TRUE, FALSE, NULL, NULL, NULL, 0,
840                                          NULL, 0, NULL, FALSE, NULL);
841     if (!payload) {
842       SILC_LOG_DEBUG(("Error decoding private message payload"));
843       goto out;
844     }
845
846     /* Ignore this message if it's not packet */
847     flags = silc_message_get_flags(payload);
848     if (!(flags & SILC_MESSAGE_FLAG_PACKET)) {
849       SILC_LOG_DEBUG(("Private message doesn't contain packet"));
850       silc_message_payload_free(payload);
851       goto out;
852     }
853
854     /* Take the packet */
855     ret = TRUE;
856
857     msg = silc_message_get_data(payload, &message_len);
858     silc_buffer_reset(buffer);
859     if (!silc_buffer_enlarge(buffer, message_len)) {
860       silc_message_payload_free(payload);
861       goto out;
862     }
863     silc_buffer_put(buffer, msg, message_len);
864
865     silc_message_payload_free(payload);
866     break;
867
868   case SILC_STREAM_CAN_WRITE:
869     /* Encode private message */
870     SILC_LOG_DEBUG(("Encode packet inside private message"));
871
872     ret = TRUE;
873
874     message =
875       silc_message_payload_encode(SILC_MESSAGE_FLAG_PACKET,
876                                   silc_buffer_datalen(buffer),
877                                   FALSE, TRUE, NULL, NULL, NULL,
878                                   NULL, NULL, NULL, NULL, NULL, NULL);
879     if (!message) {
880       SILC_LOG_DEBUG(("Error encoding private message payload"));
881       goto out;
882     }
883
884     silc_buffer_reset(buffer);
885     if (!silc_buffer_enlarge(buffer, silc_buffer_len(message)))
886       goto out;
887     silc_buffer_put(buffer, silc_buffer_datalen(message));
888
889     break;
890
891   default:
892     break;
893   }
894
895  out:
896   return ret;
897 }
898
899 /* Called after application has verified remote client's public key */
900
901 static void
902 silc_client_autoneg_key_verify_pubkey_cb(SilcBool success, void *context)
903 {
904   SilcVerifyKeyContext verify = context;
905   SilcClientAutonegMessageKey ake = verify->context;
906
907   SILC_LOG_DEBUG(("Start"));
908
909   /* Call the completion callback back to the SKE */
910   if (!verify->aborted) {
911     ake->verify = NULL;
912     verify->completion(verify->ske, success ? SILC_SKE_STATUS_OK :
913                        SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
914                        verify->completion_context);
915   } else {
916     silc_pkcs_public_key_free(verify->public_key);
917   }
918
919   silc_free(verify);
920 }
921
922 /* Remote client's public key verification callback */
923
924 static void
925 silc_client_autoneg_key_verify_pubkey(SilcSKE ske,
926                                       SilcPublicKey public_key,
927                                       void *context,
928                                       SilcSKEVerifyCbCompletion completion,
929                                       void *completion_context)
930 {
931   SilcClientEntry client_entry = context;
932   SilcClientAutonegMessageKey ake = client_entry->internal.ake;
933   SilcClientConnection conn = ake->conn;
934   SilcClient client = conn->client;
935   SilcVerifyKeyContext verify;
936
937   /* Use public key we cached earlier in AKE for direction verification */
938   if (client_entry->internal.send_key && client_entry->public_key &&
939       silc_pkcs_public_key_compare(public_key, client_entry->public_key)) {
940     SILC_LOG_DEBUG(("Client's cached public key matches"));
941     completion(ske, SILC_SKE_STATUS_OK, completion_context);
942     return;
943   }
944
945   /* If we provided repository for SKE and we got here the key was not
946      found from the repository. */
947   if (conn->internal->params.repository &&
948       !conn->internal->params.verify_notfound) {
949     completion(ske, SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
950                completion_context);
951     return;
952   }
953
954   SILC_LOG_DEBUG(("Verify remote client public key"));
955
956   ake->public_key = silc_pkcs_public_key_copy(public_key);
957   if (!ake->public_key) {
958     completion(ske, SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
959                completion_context);
960     return;
961   }
962
963   verify = silc_calloc(1, sizeof(*verify));
964   if (!verify) {
965     completion(ske, SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
966                completion_context);
967     return;
968   }
969   verify->public_key = ake->public_key;
970   verify->ske = ske;
971   verify->completion = completion;
972   verify->completion_context = completion_context;
973   verify->context = ake;
974   ake->verify = verify;
975
976   /* Verify public key in application */
977   client->internal->ops->verify_public_key(
978                                 client, conn,
979                                 SILC_CONN_CLIENT, ake->public_key,
980                                 silc_client_autoneg_key_verify_pubkey_cb,
981                                 verify);
982 }
983
984 /* Key exchange protocol completion callback */
985
986 static void silc_client_autoneg_key_done(SilcSKE ske,
987                                          SilcSKEStatus status,
988                                          SilcSKESecurityProperties prop,
989                                          SilcSKEKeyMaterial keymat,
990                                          SilcSKERekeyMaterial rekey,
991                                          void *context)
992 {
993   SilcClientEntry client_entry = context;
994   SilcClientAutonegMessageKey ake = client_entry->internal.ake;
995   SilcClientConnection conn = ake->conn;
996   SilcClient client = conn->client;
997   SilcBool initiator = !client_entry->internal.prv_resp;
998   SilcMessageFlags flags;
999   SilcBuffer m;
1000
1001   ake->ske_op = NULL;
1002
1003   conn->context_type = SILC_ID_CLIENT;
1004   conn->client_entry = client_entry;
1005
1006   if (status != SILC_SKE_STATUS_OK) {
1007     /* Key exchange failed */
1008     SILC_LOG_DEBUG(("Error during key exchange: %s (%d)",
1009                     silc_ske_map_status(status), status));
1010
1011     if (initiator) {
1012       if (status != SILC_SKE_STATUS_PROBE_TIMEOUT)
1013         client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
1014                                    "Cannot send private message to %s (%s)",
1015                                    client_entry->nickname,
1016                                    silc_ske_map_status(status));
1017       else if (client_entry->mode & SILC_UMODE_DETACHED)
1018         client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
1019                                    "Cannot send private message to detached "
1020                                    "client %s", client_entry->nickname);
1021     } else if (status != SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY) {
1022       client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
1023                                  "Private message key exchange failed "
1024                                  "with %s (%s)", client_entry->nickname,
1025                                  silc_ske_map_status(status));
1026     }
1027
1028     /* Errors that occur due to user not responding or deciding not to
1029        trust the public key will not cause us to stop trying AKE next time.
1030        Other errors disable AKE to allow communication with other means. */
1031     if (initiator && status != SILC_SKE_STATUS_TIMEOUT &&
1032         status != SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY &&
1033         !(client_entry->mode & SILC_UMODE_DETACHED)) {
1034       client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_INFO,
1035                                  "Cannot auto-negotiate key with %s, "
1036                                  "messages will be protected with "
1037                                  "session key", client_entry->nickname);
1038
1039       /* Don't try this again with this client */
1040       client_entry->internal.no_ake = TRUE;
1041     }
1042     goto out;
1043   }
1044
1045   /* Set the new private message key into use */
1046   silc_client_del_private_message_key(client, conn, client_entry);
1047   client_entry->internal.prv_resp = !initiator;
1048   if (!silc_client_add_private_message_key_ske(
1049                                         client, conn, client_entry,
1050                                         silc_cipher_get_name(prop->cipher),
1051                                         silc_hmac_get_name(prop->hmac),
1052                                         keymat)) {
1053     SILC_LOG_DEBUG(("Error adding private message key"));
1054
1055     client->internal->ops->say(client, conn,
1056                                SILC_CLIENT_MESSAGE_ERROR,
1057                                "Private message key exchange error: "
1058                                "cannot use keys");
1059
1060     /* Don't try this again with this client */
1061     client_entry->internal.no_ake = TRUE;
1062     goto out;
1063   }
1064
1065   /* Save the public key to client entry */
1066   if (!client_entry->public_key) {
1067     client_entry->public_key = ake->public_key;
1068     ake->public_key = NULL;
1069   }
1070
1071   /* Rekey periodically */
1072   client_entry->internal.ake_rekey = silc_time() + 300;
1073   if (initiator)
1074     client_entry->internal.ake_rekey -= 30;
1075   client_entry->internal.ake_generation = conn->internal->ake_generation;
1076   client_entry->internal.no_ake = FALSE;
1077
1078   SILC_LOG_DEBUG(("AKE completed as %s with %s, rekey in %u secs, "
1079                   "generation %u", initiator ? "initiator" : "responder",
1080                   client_entry->nickname, 300,
1081                   conn->internal->ake_generation));
1082
1083   /* Send queued messages */
1084   silc_dlist_start(ake->messages);
1085   while ((m = silc_dlist_get(ake->messages)) != SILC_LIST_END) {
1086     SILC_GET16_MSB(flags, m->data - 2);
1087     silc_client_send_private_message(client, conn, client_entry,
1088                                      flags, ake->hash,
1089                                      silc_buffer_datalen(m));
1090   }
1091
1092  out:
1093   conn->context_type = SILC_ID_NONE;
1094   conn->client_entry = NULL;
1095   silc_schedule_task_add_timeout(client->schedule,
1096                                  silc_client_autoneg_key_finish,
1097                                  client_entry, 0, 1);
1098 }
1099
1100 /* Auto-negotiate private message key with the remote client using the
1101    SKE protocol, which is tunneled through the SILC network inside private
1102    messages shared between the us and the remote client.
1103
1104    This operation is naturally asynchronous and will involve exchanging
1105    multiple messages back and forth.  Despite this, we don't run this
1106    operation in own FSM thread here, but instead will use the SKE library
1107    to do the asynchronous operation which we can abort at any time in
1108    case user disconnects.
1109
1110    Messages and packets we receive during this operation will be processed
1111    in the normal connection thread. */
1112
1113 SilcBool
1114 silc_client_autoneg_private_message_key(SilcClient client,
1115                                         SilcClientConnection conn,
1116                                         SilcClientEntry client_entry,
1117                                         SilcPacket initiator_packet,
1118                                         SilcMessageFlags flags,
1119                                         SilcHash hash,
1120                                         unsigned char *data,
1121                                         SilcUInt32 data_len)
1122 {
1123   SilcClientAutonegMessageKey ake;
1124   SilcSKEParamsStruct params = {};
1125   SilcBool initiator = initiator_packet == NULL;
1126   SilcBuffer m;
1127
1128   SILC_LOG_DEBUG(("Start private message AKE as %s with %s",
1129                   initiator ? "initiator" : "responder",
1130                   client_entry->nickname));
1131
1132   if (client_entry->internal.op) {
1133     ake = client_entry->internal.ake;
1134     if (ake && data) {
1135       /* If generation has changed, we must abort this exchange and
1136          start a new one. */
1137       if (ake->generation != conn->internal->ake_generation) {
1138         SILC_LOG_DEBUG(("Abort ongoing AKE and start new one"));
1139         silc_async_abort(client_entry->internal.op, NULL, NULL);
1140       } else {
1141         SILC_LOG_DEBUG(("AKE is ongoing, queue the message"));
1142
1143         m = silc_buffer_alloc_size(data_len + 2);
1144         if (!m)
1145           return FALSE;
1146         SILC_PUT16_MSB(flags, m->data);
1147         silc_buffer_pull(m, 2);
1148         silc_buffer_put(m, data, data_len);
1149         silc_dlist_add(ake->messages, m);
1150         return TRUE;
1151       }
1152     } else {
1153       SILC_LOG_DEBUG(("Cannot start AKE, operation %p is ongoing",
1154                       client_entry->internal.op));
1155       return FALSE;
1156     }
1157   }
1158
1159   ake = silc_calloc(1, sizeof(*ake));
1160   if (!ake)
1161     return FALSE;
1162   ake->conn = conn;
1163   ake->generation = conn->internal->ake_generation;
1164
1165   ake->messages = silc_dlist_init();
1166   if (!ake->messages)
1167     goto err;
1168
1169   /* Wrap our packet stream to a generic stream for the private messages
1170      we are going to exchange.  We send the packets with packet flag
1171      SILC_PACKET_FLAG_PRIVMSG_KEY which is a lie, but is a way to get
1172      clients which do not support this protocol to ignore these messages.
1173      This kludge should be removed once support is everywhere and
1174      responder should look only for the SILC_MESSAGE_FLAG_PACKET. */
1175   ake->stream = silc_packet_stream_wrap(conn->stream,
1176                                         SILC_PACKET_PRIVATE_MESSAGE,
1177                                         SILC_PACKET_FLAG_PRIVMSG_KEY, FALSE,
1178                                         SILC_ID_NONE, NULL,
1179                                         SILC_ID_CLIENT, &client_entry->id,
1180                                         silc_client_autoneg_key_coder,
1181                                         client_entry);
1182   if (!ake->stream)
1183     goto err;
1184
1185   /* Create a new packet stream for the SKE library using the wrapped
1186      stream as the underlaying stream, in effect creating a tunnel to
1187      send SKE packets inside private message packets. */
1188   ake->ske_stream = silc_packet_stream_create(client->internal->packet_engine,
1189                                               conn->internal->schedule,
1190                                               ake->stream);
1191   if (!ake->ske_stream)
1192     goto err;
1193
1194   silc_packet_set_context(ake->ske_stream, client_entry);
1195   silc_packet_set_ids(ake->ske_stream, SILC_ID_CLIENT, conn->local_id,
1196                       SILC_ID_CLIENT, &client_entry->id);
1197
1198   /* Link to the new packet stream to intercept the packets before they
1199      go to SKE library so that we can do additional checks and decide if
1200      we really want to process the packets. */
1201   if (!silc_packet_stream_link(ake->ske_stream, &autoneg_key_ske_cbs, NULL,
1202                                1000001, SILC_PACKET_ANY, -1))
1203     goto err;
1204
1205   /* Create SKE */
1206   ake->ske = silc_ske_alloc(client->rng, conn->internal->schedule,
1207                             conn->internal->params.repository,
1208                             conn->public_key, conn->private_key,
1209                             client_entry);
1210   if (!ake->ske)
1211     goto err;
1212
1213   silc_ske_set_callbacks(ake->ske, silc_client_autoneg_key_verify_pubkey,
1214                          silc_client_autoneg_key_done, client_entry);
1215   params.version = client->internal->silc_client_version;
1216   params.probe_timeout_secs = 5;
1217   params.timeout_secs = 120;
1218   params.flags = SILC_SKE_SP_FLAG_MUTUAL | SILC_SKE_SP_FLAG_PFS;
1219   params.small_proposal = TRUE;
1220   params.no_acks = TRUE;
1221
1222   if (client_entry->internal.send_key &&
1223       client_entry->internal.ake_generation == ake->generation) {
1224     /* Security properties for rekey */
1225     SilcSKESecurityProperties prop = silc_calloc(1, sizeof(*prop));
1226     if (!prop)
1227       goto err;
1228     silc_cipher_alloc(silc_cipher_get_name(client_entry->internal.send_key),
1229                       &prop->cipher);
1230     silc_hmac_alloc(silc_hmac_get_name(client_entry->internal.hmac_send),
1231                     NULL, &prop->hmac);
1232     silc_hash_alloc(silc_hash_get_name(silc_hmac_get_hash(
1233                         client_entry->internal.hmac_send)), &prop->hash);
1234     prop->public_key = silc_pkcs_public_key_copy(client_entry->public_key);
1235     silc_ske_group_get_by_number(2, &prop->group);
1236     prop->flags = params.flags;
1237     params.prop = prop;
1238   }
1239
1240   /* Start key exchange */
1241   if (initiator)
1242     ake->ske_op = silc_ske_initiator(ake->ske, ake->ske_stream, &params, NULL);
1243   else
1244     ake->ske_op = silc_ske_responder(ake->ske, ake->ske_stream, &params);
1245   if (!ake->ske_op)
1246     goto err;
1247
1248   /* Finally, set up the client entry */
1249   client_entry->internal.op = silc_async_alloc(silc_client_autoneg_key_abort,
1250                                                NULL, client_entry);
1251   if (!client_entry->internal.op)
1252     goto err;
1253   client_entry->internal.ake = ake;
1254   client_entry->internal.no_ake = FALSE;
1255   client_entry->internal.prv_resp = !initiator;
1256   silc_client_ref_client(client, conn, client_entry);
1257
1258   /* As responder, re-inject the initiator's private message back to the
1259      stream so that the new SKE gets it. */
1260   if (initiator_packet)
1261     silc_packet_stream_inject(conn->stream, initiator_packet);
1262
1263   /* Save the initial message, it will be sent after the key has been
1264      negotiated. */
1265   if (data && data_len) {
1266     m = silc_buffer_alloc_size(data_len + 2);
1267     if (m) {
1268       SILC_PUT16_MSB(flags, m->data);
1269       silc_buffer_pull(m, 2);
1270       silc_buffer_put(m, data, data_len);
1271       silc_dlist_add(ake->messages, m);
1272     }
1273     if (hash)
1274       silc_hash_alloc(silc_hash_get_name(hash), &ake->hash);
1275   }
1276
1277   return TRUE;
1278
1279  err:
1280   if (ake->ske)
1281     silc_ske_free(ake->ske);
1282   if (ake->ske_stream) {
1283     silc_packet_stream_unlink(ake->ske_stream, &autoneg_key_ske_cbs, NULL);
1284     silc_packet_stream_destroy(ake->ske_stream);
1285   } else if (ake->stream)
1286     silc_stream_destroy(ake->stream);
1287   silc_dlist_uninit(ake->messages);
1288   silc_free(ake);
1289   return FALSE;
1290 }
1291
1292 /* Sets away `message'.  The away message may be set when the client's
1293    mode is changed to SILC_UMODE_GONE and the client whishes to reply
1294    to anyone who sends private message.  The `message' will be sent
1295    automatically back to the the client who send private message.  If
1296    away message is already set this replaces the old message with the
1297    new one.  If `message' is NULL the old away message is removed.
1298    The sender may freely free the memory of the `message'. */
1299
1300 SilcBool silc_client_set_away_message(SilcClient client,
1301                                       SilcClientConnection conn,
1302                                       char *message)
1303 {
1304   if (!client || !conn)
1305     return FALSE;
1306
1307   if (!message) {
1308     silc_free(conn->internal->away_message);
1309     conn->internal->away_message = NULL;
1310     return TRUE;
1311   }
1312
1313   if (conn->internal->away_message)
1314     silc_free(conn->internal->away_message);
1315
1316   conn->internal->away_message = strdup(message);
1317   if (!conn->internal->away_message)
1318     return FALSE;
1319
1320   return TRUE;
1321 }