Allow rekey with PFS in backup router (for disabled connections).
[silc.git] / apps / silcd / packet_send.c
index 317168e4559b2d5ab31b2737c9ac9b3757d27121..0a7e52332a242cbe0c07f4b36397c821115b1b41 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 1997 - 2003 Pekka Riikonen
+  Copyright (C) 1997 - 2004 Pekka Riikonen
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -114,7 +114,8 @@ void silc_server_packet_send(SilcServer server,
      rekeys, though */
   if ((idata && idata->status & SILC_IDLIST_STATUS_DISABLED &&
        type != SILC_PACKET_HEARTBEAT && type != SILC_PACKET_REKEY &&
-       type != SILC_PACKET_REKEY_DONE) ||
+       type != SILC_PACKET_REKEY_DONE && type != SILC_PACKET_KEY_EXCHANGE_1
+       && type != SILC_PACKET_KEY_EXCHANGE_2) ||
       (sock->user_data == server->id_entry)) {
     SILC_LOG_DEBUG(("Connection is disabled"));
     return;
@@ -176,9 +177,13 @@ void silc_server_packet_send_dest(SilcServer server,
 
   idata = (SilcIDListData)sock->user_data;
 
-  /* If entry is disabled do not sent anything. */
-  if ((idata && idata->status & SILC_IDLIST_STATUS_DISABLED) ||
-      sock->user_data == server->id_entry) {
+  /* If entry is disabled do not sent anything.  Allow hearbeat and
+     rekeys, though */
+  if ((idata && idata->status & SILC_IDLIST_STATUS_DISABLED &&
+       type != SILC_PACKET_HEARTBEAT && type != SILC_PACKET_REKEY &&
+       type != SILC_PACKET_REKEY_DONE && type != SILC_PACKET_KEY_EXCHANGE_1
+       && type != SILC_PACKET_KEY_EXCHANGE_2) ||
+      (sock->user_data == server->id_entry)) {
     SILC_LOG_DEBUG(("Connection is disabled"));
     return;
   }
@@ -285,9 +290,13 @@ void silc_server_packet_send_srcdest(SilcServer server,
   /* Get data used in the packet sending, keys and stuff */
   idata = (SilcIDListData)sock->user_data;
 
-  /* If entry is disabled do not sent anything. */
-  if ((idata && idata->status & SILC_IDLIST_STATUS_DISABLED) ||
-      sock->user_data == server->id_entry) {
+  /* If entry is disabled do not sent anything.  Allow hearbeat and
+     rekeys, though */
+  if ((idata && idata->status & SILC_IDLIST_STATUS_DISABLED &&
+       type != SILC_PACKET_HEARTBEAT && type != SILC_PACKET_REKEY &&
+       type != SILC_PACKET_REKEY_DONE && type != SILC_PACKET_KEY_EXCHANGE_1
+       && type != SILC_PACKET_KEY_EXCHANGE_2) ||
+      (sock->user_data == server->id_entry)) {
     SILC_LOG_DEBUG(("Connection is disabled"));
     return;
   }
@@ -800,8 +809,8 @@ silc_server_packet_relay_to_channel_encrypt(SilcServer server,
     }
 
     memcpy(iv, data + (data_len - iv_len - mac_len), iv_len);
-    silc_message_payload_encrypt(data, totlen, data_len - mac_len, 
-                                 iv, iv_len, channel->channel_key, 
+    silc_message_payload_encrypt(data, totlen, data_len - mac_len,
+                                 iv, iv_len, channel->channel_key,
                                 channel->hmac);
   }
 
@@ -1314,16 +1323,18 @@ void silc_server_send_notify_cmode(SilcServer server,
                                   SilcBuffer channel_pubkeys)
 {
   SilcBuffer idp, fkey = NULL;
-  unsigned char mode[4];
+  unsigned char mode[4], ulimit[4];
 
   idp = silc_id_payload_encode((void *)id, id_type);
   SILC_PUT32_MSB(mode_mask, mode);
   if (founder_key)
     fkey = silc_pkcs_public_key_payload_encode(founder_key);
+  if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
+    SILC_PUT32_MSB(channel->user_limit, ulimit);
 
   silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id,
                               SILC_ID_CHANNEL, SILC_NOTIFY_TYPE_CMODE_CHANGE,
-                              7, idp->data, idp->len,
+                              8, idp->data, idp->len,
                               mode, 4,
                               cipher, cipher ? strlen(cipher) : 0,
                               hmac, hmac ? strlen(hmac) : 0,
@@ -1331,7 +1342,11 @@ void silc_server_send_notify_cmode(SilcServer server,
                               strlen(passphrase) : 0,
                               fkey ? fkey->data : NULL, fkey ? fkey->len : 0,
                               channel_pubkeys ? channel_pubkeys->data : NULL,
-                              channel_pubkeys ? channel_pubkeys->len : 0);
+                              channel_pubkeys ? channel_pubkeys->len : 0,
+                              mode_mask & SILC_CHANNEL_MODE_ULIMIT ?
+                              ulimit : NULL,
+                              mode_mask & SILC_CHANNEL_MODE_ULIMIT ?
+                              sizeof(ulimit) : 0);
   silc_buffer_free(fkey);
   silc_buffer_free(idp);
 }
@@ -1548,22 +1563,28 @@ void silc_server_send_notify_watch(SilcServer server,
                                   SilcClientEntry watcher,
                                   SilcClientEntry client,
                                   const char *nickname,
-                                  SilcNotifyType type)
+                                  SilcNotifyType type,
+                                  SilcPublicKey public_key)
 {
-  SilcBuffer idp;
+  SilcBuffer idp, pkp = NULL;
   unsigned char mode[4], n[2];
 
   idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
   SILC_PUT16_MSB(type, n);
   SILC_PUT32_MSB(client->mode, mode);
+  if (public_key)
+    pkp = silc_pkcs_public_key_payload_encode(public_key);
   silc_server_send_notify_dest(server, sock, FALSE, watcher->id,
                               SILC_ID_CLIENT, SILC_NOTIFY_TYPE_WATCH,
-                              4, idp->data, idp->len,
+                              5, idp->data, idp->len,
                               nickname, nickname ? strlen(nickname) : 0,
                               mode, sizeof(mode),
                               type != SILC_NOTIFY_TYPE_NONE ?
-                              n : NULL, sizeof(n));
+                              n : NULL, sizeof(n),
+                              pkp ? pkp->data : NULL,
+                              pkp ? pkp->len : 0);
   silc_buffer_free(idp);
+  silc_buffer_free(pkp);
 }
 
 /* Sends notify message destined to specific entity. */