return;
}
- SILC_LOG_DEBUG(("Sending %s packet", silc_get_packet_name(type)));
+ SILC_LOG_DEBUG(("Sending %s packet (forced=%s)",
+ silc_get_packet_name(type), force_send ? "yes" : "no"));
if (dst_id) {
dst_id_data = silc_id_id2str(dst_id, dst_id_type);
hmac = idata->hmac_send;
sequence = idata->psn_send++;
block_len = silc_cipher_get_block_len(cipher);
+
+ /* Check for mandatory rekey */
+ if (sequence == SILC_SERVER_REKEY_THRESHOLD)
+ silc_schedule_task_add(server->schedule, sock->sock,
+ silc_server_rekey_callback, sock, 0, 1,
+ SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
}
/* Set the packet context pointers */
packetdata.dst_id_len));
packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN +
packetdata.src_id_len + dst_id_len;
- packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen, block_len);
+ if (type == SILC_PACKET_CONNECTION_AUTH)
+ SILC_PACKET_PADLEN_MAX(packetdata.truelen, block_len, packetdata.padlen);
+ else
+ SILC_PACKET_PADLEN(packetdata.truelen, block_len, packetdata.padlen);
/* Create the outgoing packet */
if (!silc_packet_assemble(&packetdata, NULL, cipher, hmac, sock,
hmac = idata->hmac_send;
sequence = idata->psn_send++;
block_len = silc_cipher_get_block_len(cipher);
+
+ /* Check for mandatory rekey */
+ if (sequence == SILC_SERVER_REKEY_THRESHOLD)
+ silc_schedule_task_add(server->schedule, sock->sock,
+ silc_server_rekey_callback, sock, 0, 1,
+ SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
}
if (dst_id) {
dst_id_len));
packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN +
packetdata.src_id_len + dst_id_len;
- packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen, block_len);
+ SILC_PACKET_PADLEN(packetdata.truelen, block_len, packetdata.padlen);
/* Create the outgoing packet */
if (!silc_packet_assemble(&packetdata, NULL, cipher, hmac, sock, data,
/* Now actually send the packet */
silc_server_packet_send_real(server, sock, TRUE);
silc_free(id);
+
+ /* Check for mandatory rekey */
+ if (idata->psn_send == SILC_SERVER_REKEY_THRESHOLD)
+ silc_schedule_task_add(server->schedule, sock->sock,
+ silc_server_rekey_callback, sock, 0, 1,
+ SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
return;
}
/* Now actually send the packet */
silc_server_packet_send_real(server, sock, TRUE);
+
+ /* Check for mandatory rekey */
+ if (idata->psn_send == SILC_SERVER_REKEY_THRESHOLD)
+ silc_schedule_task_add(server->schedule, sock->sock,
+ silc_server_rekey_callback, sock, 0, 1,
+ SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
}
/* This routine can be used to send a packet to table of clients provided
block_len = cipher ? silc_cipher_get_block_len(cipher) : 0;
if (channel_message)
- packet->padlen = SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
- packet->src_id_len +
- packet->dst_id_len), block_len);
+ SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
+ packet->src_id_len +
+ packet->dst_id_len), block_len, packet->padlen);
else
- packet->padlen = SILC_PACKET_PADLEN(packet->truelen, block_len);
+ SILC_PACKET_PADLEN(packet->truelen, block_len, packet->padlen);
/* Put the data to buffer, assemble and encrypt the packet. The packet
is encrypted with normal session key shared with the client, unless
continue;
gone = TRUE;
+ /* If we are backup router and remote is our primary router and
+ we are currently doing backup resuming protocol we must not
+ re-encrypt message with session key. */
+ if (server->backup_router && SILC_SERVER_IS_BACKUP(sock) &&
+ SILC_PRIMARY_ROUTE(server) == sock) {
+ silc_server_packet_send_to_channel_real(server, sock, &packetdata,
+ idata->send_key,
+ idata->hmac_send,
+ idata->psn_send++,
+ data, data_len, TRUE,
+ force_send);
+ continue;
+ }
+
SILC_LOG_DEBUG(("Remote is router, encrypt with session key"));
/* If private key mode is not set then decrypt the packet
/* Send the packet */
silc_server_packet_send_real(server, dst_sock, FALSE);
+
+ /* Check for mandatory rekey */
+ if (sequence == SILC_SERVER_REKEY_THRESHOLD)
+ silc_schedule_task_add(server->schedule, dst_sock->sock,
+ silc_server_rekey_callback, dst_sock, 0, 1,
+ SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
}
/* Sends current motd to client */
const char *passphrase,
SilcPublicKey founder_key)
{
- SilcBuffer idp;
- unsigned char mode[4], *key = NULL;
- SilcUInt32 key_len = 0;
+ SilcBuffer idp, fkey = NULL;
+ unsigned char mode[4];
idp = silc_id_payload_encode((void *)id, id_type);
SILC_PUT32_MSB(mode_mask, mode);
if (founder_key)
- key = silc_pkcs_public_key_encode(founder_key, &key_len);
+ fkey = silc_pkcs_public_key_payload_encode(founder_key);
silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id,
SILC_ID_CHANNEL, SILC_NOTIFY_TYPE_CMODE_CHANGE,
hmac, hmac ? strlen(hmac) : 0,
passphrase, passphrase ?
strlen(passphrase) : 0,
- key, key_len);
- silc_free(key);
+ fkey ? fkey->data : NULL, fkey ? fkey->len : 0);
+ silc_buffer_free(fkey),
silc_buffer_free(idp);
}
SilcClientID *target,
SilcPublicKey founder_key)
{
- SilcBuffer idp1, idp2;
- unsigned char mode[4], *key = NULL;
- SilcUInt32 key_len = 0;
+ SilcBuffer idp1, idp2, fkey = NULL;
+ unsigned char mode[4];
idp1 = silc_id_payload_encode((void *)id, id_type);
idp2 = silc_id_payload_encode((void *)target, SILC_ID_CLIENT);
SILC_PUT32_MSB(mode_mask, mode);
if (founder_key)
- key = silc_pkcs_public_key_encode(founder_key, &key_len);
+ fkey = silc_pkcs_public_key_payload_encode(founder_key);
silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id,
SILC_ID_CHANNEL,
idp1->data, idp1->len,
mode, 4,
idp2->data, idp2->len,
- key, key_len);
- silc_free(key);
+ fkey ? fkey->data : NULL, fkey ? fkey->len : 0);
+ silc_buffer_free(fkey);
silc_buffer_free(idp1);
silc_buffer_free(idp2);
}
SilcBuffer packet;
unsigned char *chid;
SilcUInt32 tmp_len;
+ const char *cipher;
SILC_LOG_DEBUG(("Sending key to channel %s", channel->channel_name));
return;
/* Encode channel key packet */
- tmp_len = strlen(channel->channel_key->cipher->name);
+ cipher = silc_cipher_get_name(channel->channel_key);
+ tmp_len = strlen(cipher);
packet = silc_channel_key_payload_encode(silc_id_get_len(channel->id,
SILC_ID_CHANNEL),
- chid, tmp_len,
- channel->channel_key->cipher->name,
+ chid, tmp_len, cipher,
channel->key_len / 8, channel->key);
silc_server_packet_send_to_channel(server, sender, channel,
SILC_PACKET_CHANNEL_KEY,
silc_buffer_pull(packet->buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
+ packet->dst_id_len + packet->padlen);
+
+ /* Check for mandatory rekey */
+ if (sequence == SILC_SERVER_REKEY_THRESHOLD)
+ silc_schedule_task_add(server->schedule, dst_sock->sock,
+ silc_server_rekey_callback, dst_sock, 0, 1,
+ SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
}
/* Routine used to send the connection authentication packet. */