+Wed Apr 9 18:51:59 EEST 2003 Pekka Riikonen <priikone@silcnet.org>
+
+ * Fixed stack overflow in Irssi SILC client. Affected
+ file irssi/src/silc/core/client_ops.c.
+
+ * Check that Host is set in ServerConnection and RouterConnection
+ in silcd.conf. Affected file silcd/serverconfig.c.
+
+ * Fixed crash in server with protocol completion callbacks,
+ namely rekey and backup resuming protocols. Affected files
+ are silcd/server_backup.c and silcd/server.c.
+
+ * Fixed rekey protocol to not restart if it is started already.
+ Affected files are lib/silcclient/client.c and
+ silcd/server.c.c
+
Mon Mar 17 18:35:24 EET 2003 Pekka Riikonen <priikone@silcnet.org>
* Rewrote SilcList, affected file lib/silcutil/silc*list.h.
* Fixed incorrect connection deletion from client library
after calling "connect" client operation. Could cause
crashes for example during reconnect timeouts. Affected
- files are lib/silcclient/client.c and
+ files are lib/silcclient/client.c and
irssi/src/silc/core/client_ops.c.
* Check server private key file permissions before starting
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1997 - 2002 Pekka Riikonen
+ Copyright (C) 1997 - 2003 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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#include "serverincludes.h"
#include "server_internal.h"
-/* Received notify packet. Server can receive notify packets from router.
+/* Received notify packet. Server can receive notify packets from router.
Server then relays the notify messages to clients if needed. */
void silc_server_notify(SilcServer server,
/* Get the route to the client */
dst_sock = silc_server_get_client_route(server, packet->dst_id,
- packet->dst_id_len, NULL,
+ packet->dst_id_len, NULL,
&idata, NULL);
if (dst_sock)
/* Relay the packet */
if (!channel_id)
goto out;
- silc_server_packet_send_dest(server, SILC_PRIMARY_ROUTE(server),
- packet->type, packet->flags |
- SILC_PACKET_FLAG_BROADCAST,
+ silc_server_packet_send_dest(server, SILC_PRIMARY_ROUTE(server),
+ packet->type, packet->flags |
+ SILC_PACKET_FLAG_BROADCAST,
channel_id, SILC_ID_CHANNEL,
- packet->buffer->data,
+ packet->buffer->data,
packet->buffer->len, FALSE);
- silc_server_backup_send_dest(server, sock->user_data,
+ silc_server_backup_send_dest(server, sock->user_data,
packet->type, packet->flags,
channel_id, SILC_ID_CHANNEL,
- packet->buffer->data, packet->buffer->len,
+ packet->buffer->data, packet->buffer->len,
FALSE, TRUE);
} else {
/* Packet is destined to client or server */
- silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
+ silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
packet->type,
- packet->flags | SILC_PACKET_FLAG_BROADCAST,
- packet->buffer->data, packet->buffer->len,
+ packet->flags | SILC_PACKET_FLAG_BROADCAST,
+ packet->buffer->data, packet->buffer->len,
FALSE);
silc_server_backup_send(server, sock->user_data,
packet->type, packet->flags,
- packet->buffer->data, packet->buffer->len,
+ packet->buffer->data, packet->buffer->len,
FALSE, TRUE);
}
}
switch(type) {
case SILC_NOTIFY_TYPE_JOIN:
- /*
+ /*
* Distribute the notify to local clients on the channel
*/
SILC_LOG_DEBUG(("JOIN notify"));
goto out;
/* Get channel entry */
- channel = silc_idlist_find_channel_by_id(server->global_list,
+ channel = silc_idlist_find_channel_by_id(server->global_list,
channel_id, NULL);
if (!channel) {
- channel = silc_idlist_find_channel_by_id(server->local_list,
+ channel = silc_idlist_find_channel_by_id(server->local_list,
channel_id, NULL);
if (!channel) {
SILC_LOG_DEBUG(("Notify for unknown channel"));
/* If the the client is not in local list we check global list (ie. the
channel will be global channel) and if it does not exist then create
entry for the client. */
- client = silc_idlist_find_client_by_id(server->global_list,
- client_id, server->server_type,
+ client = silc_idlist_find_client_by_id(server->global_list,
+ client_id, server->server_type,
&cache);
if (!client) {
- client = silc_idlist_find_client_by_id(server->local_list,
+ client = silc_idlist_find_client_by_id(server->local_list,
client_id, server->server_type,
&cache);
if (!client) {
goto out;
}
- client =
+ client =
silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
- silc_id_dup(client_id, SILC_ID_CLIENT),
+ silc_id_dup(client_id, SILC_ID_CLIENT),
sock->user_data, NULL, 0);
if (!client) {
SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
}
/* Send to channel */
- silc_server_packet_send_to_channel(server, sock, channel, packet->type,
- FALSE, packet->buffer->data,
+ silc_server_packet_send_to_channel(server, sock, channel, packet->type,
+ FALSE, packet->buffer->data,
packet->buffer->len, FALSE);
- if (server->server_type != SILC_ROUTER &&
+ if (server->server_type != SILC_ROUTER &&
sock->type == SILC_SOCKET_TYPE_ROUTER)
/* The channel is global now */
channel->global_users = TRUE;
SILC_LOG_DEBUG(("Joining to channel %s", channel->channel_name));
- /* JOIN the global client to the channel (local clients (if router
+ /* JOIN the global client to the channel (local clients (if router
created the channel) is joined in the pending JOIN command). */
chl = silc_calloc(1, sizeof(*chl));
chl->client = client;
break;
case SILC_NOTIFY_TYPE_LEAVE:
- /*
+ /*
* Distribute the notify to local clients on the channel
*/
SILC_LOG_DEBUG(("LEAVE notify"));
}
/* Get channel entry */
- channel = silc_idlist_find_channel_by_id(server->global_list,
+ channel = silc_idlist_find_channel_by_id(server->global_list,
channel_id, NULL);
- if (!channel) {
- channel = silc_idlist_find_channel_by_id(server->local_list,
+ if (!channel) {
+ channel = silc_idlist_find_channel_by_id(server->local_list,
channel_id, NULL);
if (!channel) {
SILC_LOG_DEBUG(("Notify for unknown channel"));
}
/* Get client entry */
- client = silc_idlist_find_client_by_id(server->global_list,
+ client = silc_idlist_find_client_by_id(server->global_list,
client_id, TRUE, NULL);
if (!client) {
- client = silc_idlist_find_client_by_id(server->local_list,
+ client = silc_idlist_find_client_by_id(server->local_list,
client_id, TRUE, NULL);
if (!client) {
silc_free(client_id);
break;
/* Send the leave notify to channel */
- silc_server_packet_send_to_channel(server, sock, channel, packet->type,
- FALSE, packet->buffer->data,
+ silc_server_packet_send_to_channel(server, sock, channel, packet->type,
+ FALSE, packet->buffer->data,
packet->buffer->len, FALSE);
/* Remove the user from channel */
break;
case SILC_NOTIFY_TYPE_SIGNOFF:
- /*
+ /*
* Distribute the notify to local clients on the channel
*/
SILC_LOG_DEBUG(("SIGNOFF notify"));
goto out;
/* Get client entry */
- client = silc_idlist_find_client_by_id(server->global_list,
+ client = silc_idlist_find_client_by_id(server->global_list,
client_id, TRUE, &cache);
if (!client) {
- client = silc_idlist_find_client_by_id(server->local_list,
+ client = silc_idlist_find_client_by_id(server->local_list,
client_id, TRUE, &cache);
if (!client) {
silc_free(client_id);
break;
case SILC_NOTIFY_TYPE_TOPIC_SET:
- /*
+ /*
* Distribute the notify to local clients on the channel
*/
/* Get client entry */
if (id_type == SILC_ID_CLIENT) {
- client = silc_idlist_find_client_by_id(server->global_list,
+ client = silc_idlist_find_client_by_id(server->global_list,
client_id, TRUE, &cache);
if (!client) {
- client = silc_idlist_find_client_by_id(server->local_list,
+ client = silc_idlist_find_client_by_id(server->local_list,
client_id, TRUE, &cache);
if (!client) {
silc_free(client_id);
}
/* Get channel entry */
- channel = silc_idlist_find_channel_by_id(server->global_list,
+ channel = silc_idlist_find_channel_by_id(server->global_list,
channel_id, NULL);
if (!channel) {
- channel = silc_idlist_find_channel_by_id(server->local_list,
+ channel = silc_idlist_find_channel_by_id(server->local_list,
channel_id, NULL);
if (!channel) {
SILC_LOG_DEBUG(("Notify for unknown channel"));
channel->topic = strdup(tmp);
/* Send the same notify to the channel */
- silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
- FALSE, packet->buffer->data,
+ silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
+ FALSE, packet->buffer->data,
packet->buffer->len, FALSE);
break;
case SILC_NOTIFY_TYPE_NICK_CHANGE:
{
- /*
+ /*
* Distribute the notify to local clients on the channel
*/
unsigned char *id, *id2;
SilcUInt32 nickname_len;
SILC_LOG_DEBUG(("NICK CHANGE notify"));
-
+
/* Get old client ID */
id = silc_argument_get_arg_type(args, 1, &tmp_len);
if (!id)
client_id = silc_id_payload_parse_id(id, tmp_len, NULL);
if (!client_id)
goto out;
-
+
/* Get new client ID */
id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
if (!id2)
silc_free(client_id);
goto out;
}
-
- SILC_LOG_DEBUG(("Old Client ID id(%s)",
+
+ SILC_LOG_DEBUG(("Old Client ID id(%s)",
silc_id_render(client_id, SILC_ID_CLIENT)));
- SILC_LOG_DEBUG(("New Client ID id(%s)",
+ SILC_LOG_DEBUG(("New Client ID id(%s)",
silc_id_render(client_id2, SILC_ID_CLIENT)));
/* From protocol version 1.1 we also get the new nickname */
client_id2, nickname);
if (!client)
client = silc_idlist_replace_client_id(server,
- server->local_list, client_id,
+ server->local_list, client_id,
client_id2, nickname);
if (client) {
}
case SILC_NOTIFY_TYPE_CMODE_CHANGE:
- /*
+ /*
* Distribute the notify to local clients on the channel
*/
/* Get client entry */
if (id_type == SILC_ID_CLIENT) {
- client = silc_idlist_find_client_by_id(server->global_list,
+ client = silc_idlist_find_client_by_id(server->global_list,
client_id, TRUE, &cache);
if (!client) {
- client = silc_idlist_find_client_by_id(server->local_list,
+ client = silc_idlist_find_client_by_id(server->local_list,
client_id, TRUE, &cache);
if (!client) {
silc_free(client_id);
}
/* Get channel entry */
- channel = silc_idlist_find_channel_by_id(server->global_list,
+ channel = silc_idlist_find_channel_by_id(server->global_list,
channel_id, NULL);
if (!channel) {
- channel = silc_idlist_find_channel_by_id(server->local_list,
+ channel = silc_idlist_find_channel_by_id(server->local_list,
channel_id, NULL);
if (!channel) {
SILC_LOG_DEBUG(("Notify for unknown channel"));
/* Re-generate channel key */
if (!silc_server_create_channel_key(server, channel, 0))
goto out;
-
+
/* Send the channel key. This sends it to our local clients and if
we are normal server to our router as well. */
- silc_server_send_channel_key(server, NULL, channel,
- server->server_type == SILC_ROUTER ?
+ silc_server_send_channel_key(server, NULL, channel,
+ server->server_type == SILC_ROUTER ?
FALSE : !server->standalone);
}
/* Set the HMAC key out of current channel key. The client must do
this locally. */
- silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key,
+ silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key,
channel->key_len / 8, hash);
- silc_hmac_set_key(channel->hmac, hash,
+ silc_hmac_set_key(channel->hmac, hash,
silc_hash_len(silc_hmac_get_hash(channel->hmac)));
memset(hash, 0, sizeof(hash));
}
mode &= ~SILC_CHANNEL_MODE_FOUNDER_AUTH;
silc_server_send_notify_cmode(server, sock, FALSE, channel,
mode, server->id, SILC_ID_SERVER,
- channel->cipher,
+ channel->cipher,
channel->hmac_name,
channel->passphrase, NULL);
if (channel->founder_key)
mode &= ~SILC_CHANNEL_MODE_FOUNDER_AUTH;
silc_server_send_notify_cmode(server, sock, FALSE, channel,
mode, server->id, SILC_ID_SERVER,
- channel->cipher,
+ channel->cipher,
channel->hmac_name,
channel->passphrase, NULL);
}
/* Send the same notify to the channel */
- silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
- FALSE, packet->buffer->data,
+ silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
+ FALSE, packet->buffer->data,
packet->buffer->len, FALSE);
/* Change mode */
case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
{
- /*
+ /*
* Distribute the notify to local clients on the channel
*/
SilcChannelClientEntry chl2 = NULL;
/* Get client entry */
if (id_type == SILC_ID_CLIENT) {
- client = silc_idlist_find_client_by_id(server->global_list,
+ client = silc_idlist_find_client_by_id(server->global_list,
client_id, TRUE, &cache);
if (!client) {
- client = silc_idlist_find_client_by_id(server->local_list,
+ client = silc_idlist_find_client_by_id(server->local_list,
client_id, TRUE, &cache);
if (!client) {
silc_free(client_id);
}
/* Get channel entry */
- channel = silc_idlist_find_channel_by_id(server->global_list,
+ channel = silc_idlist_find_channel_by_id(server->global_list,
channel_id, NULL);
if (!channel) {
- channel = silc_idlist_find_channel_by_id(server->local_list,
+ channel = silc_idlist_find_channel_by_id(server->local_list,
channel_id, NULL);
if (!channel) {
SILC_LOG_DEBUG(("Notify for unknown channel"));
silc_free(channel_id);
goto out;
}
-
+
SILC_GET32_MSB(mode, tmp);
-
+
/* Get target client */
tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
if (!tmp)
client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
if (!client_id)
goto out;
-
+
/* Get client entry */
- client2 = silc_idlist_find_client_by_id(server->global_list,
+ client2 = silc_idlist_find_client_by_id(server->global_list,
client_id, TRUE, NULL);
if (!client2) {
- client2 = silc_idlist_find_client_by_id(server->local_list,
+ client2 = silc_idlist_find_client_by_id(server->local_list,
client_id, TRUE, NULL);
if (!client2) {
silc_free(client_id);
/* Check that sender is on channel */
if (!silc_server_client_on_channel(client, channel, &chl))
goto out;
-
+
if (client != client2 && server->server_type == SILC_ROUTER) {
/* Sender must be operator */
if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
/* Now match the public key we have cached and public key sent.
They must match. */
#if 0 /* The key may be other than the client's in 1.2 */
- if (client && client->data.public_key &&
+ if (client && client->data.public_key &&
!silc_pkcs_public_key_compare(channel->founder_key,
client->data.public_key)) {
chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
packet->type,
FALSE, packet->buffer->data,
packet->buffer->len, FALSE);
-
+
silc_free(channel_id);
break;
}
goto out;
/* Get channel entry */
- channel = silc_idlist_find_channel_by_id(server->global_list,
+ channel = silc_idlist_find_channel_by_id(server->global_list,
channel_id, NULL);
if (!channel) {
- channel = silc_idlist_find_channel_by_id(server->local_list,
+ channel = silc_idlist_find_channel_by_id(server->local_list,
channel_id, NULL);
if (!channel) {
SILC_LOG_DEBUG(("Notify for unknown channel"));
goto out;
/* Get client entry */
- client = silc_idlist_find_client_by_id(server->global_list,
+ client = silc_idlist_find_client_by_id(server->global_list,
client_id, TRUE, &cache);
if (!client) {
- client = silc_idlist_find_client_by_id(server->local_list,
+ client = silc_idlist_find_client_by_id(server->local_list,
client_id, TRUE, &cache);
if (!client) {
silc_free(client_id);
goto out;
/* Get the channel entry */
- channel = silc_idlist_find_channel_by_id(server->local_list,
+ channel = silc_idlist_find_channel_by_id(server->local_list,
channel_id, NULL);
if (!channel) {
- channel = silc_idlist_find_channel_by_id(server->global_list,
+ channel = silc_idlist_find_channel_by_id(server->global_list,
channel_id, NULL);
if (!channel) {
SILC_LOG_DEBUG(("Notify for unknown channel"));
}
/* Send the notify to the channel */
- silc_server_packet_send_to_channel(server, sock, channel, packet->type,
- FALSE, packet->buffer->data,
+ silc_server_packet_send_to_channel(server, sock, channel, packet->type,
+ FALSE, packet->buffer->data,
packet->buffer->len, FALSE);
/* Get the new Channel ID */
if (!channel_id2)
goto out;
- SILC_LOG_DEBUG(("Old Channel ID id(%s)",
+ SILC_LOG_DEBUG(("Old Channel ID id(%s)",
silc_id_render(channel_id, SILC_ID_CHANNEL)));
- SILC_LOG_DEBUG(("New Channel ID id(%s)",
+ SILC_LOG_DEBUG(("New Channel ID id(%s)",
silc_id_render(channel_id2, SILC_ID_CHANNEL)));
/* Replace the Channel ID */
/* Re-announce this channel which ID was changed. */
silc_server_send_new_channel(server, sock, FALSE, channel->channel_name,
- channel->id,
- silc_id_get_len(channel->id,
+ channel->id,
+ silc_id_get_len(channel->id,
SILC_ID_CHANNEL),
channel->mode);
silc_server_packet_send_dest(server, sock,
SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
channel->id, SILC_ID_CHANNEL,
- users_modes->data,
+ users_modes->data,
users_modes->len, FALSE);
silc_buffer_free(users_modes);
}
if (channel->topic) {
silc_server_send_notify_topic_set(server, sock,
server->server_type == SILC_ROUTER ?
- TRUE : FALSE, channel,
+ TRUE : FALSE, channel,
server->id, SILC_ID_SERVER,
channel->topic);
}
break;
case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
- /*
+ /*
* Remove the server entry and all clients that this server owns.
*/
}
/* Get server entry */
- server_entry = silc_idlist_find_server_by_id(server->global_list,
+ server_entry = silc_idlist_find_server_by_id(server->global_list,
server_id, TRUE, NULL);
local = FALSE;
if (!server_entry) {
- server_entry = silc_idlist_find_server_by_id(server->local_list,
+ server_entry = silc_idlist_find_server_by_id(server->local_list,
server_id, TRUE, NULL);
local = TRUE;
if (!server_entry) {
continue;
/* Get client entry */
- client = silc_idlist_find_client_by_id(server->global_list,
+ client = silc_idlist_find_client_by_id(server->global_list,
client_id, TRUE, &cache);
local = TRUE;
if (!client) {
- client = silc_idlist_find_client_by_id(server->local_list,
+ client = silc_idlist_find_client_by_id(server->local_list,
client_id, TRUE, &cache);
local = FALSE;
if (!client) {
SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
/* Remove the client from all channels. */
- silc_server_remove_from_channels(server, NULL, client,
+ silc_server_remove_from_channels(server, NULL, client,
TRUE, NULL, FALSE, FALSE);
/* Check if anyone is watching this nickname */
break;
case SILC_NOTIFY_TYPE_KICKED:
- /*
+ /*
* Distribute the notify to local clients on the channel
*/
-
+
SILC_LOG_DEBUG(("KICKED notify"));
-
+
if (!channel_id) {
channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
packet->dst_id_type);
}
/* Get channel entry */
- channel = silc_idlist_find_channel_by_id(server->global_list,
+ channel = silc_idlist_find_channel_by_id(server->global_list,
channel_id, NULL);
if (!channel) {
- channel = silc_idlist_find_channel_by_id(server->local_list,
+ channel = silc_idlist_find_channel_by_id(server->local_list,
channel_id, NULL);
if (!channel) {
SILC_LOG_DEBUG(("Notify for unknown channel"));
goto out;
/* If the the client is not in local list we check global list */
- client = silc_idlist_find_client_by_id(server->global_list,
+ client = silc_idlist_find_client_by_id(server->global_list,
client_id, TRUE, NULL);
if (!client) {
- client = silc_idlist_find_client_by_id(server->local_list,
+ client = silc_idlist_find_client_by_id(server->local_list,
client_id, TRUE, NULL);
if (!client) {
silc_free(client_id);
goto out;
if (chl->mode & SILC_CHANNEL_UMODE_CHANFO)
goto out;
-
+
/* Get the kicker's Client ID */
tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
if (!tmp)
goto out;
/* If the the client is not in local list we check global list */
- client2 = silc_idlist_find_client_by_id(server->global_list,
+ client2 = silc_idlist_find_client_by_id(server->global_list,
client_id, TRUE, NULL);
if (!client2) {
- client2 = silc_idlist_find_client_by_id(server->local_list,
+ client2 = silc_idlist_find_client_by_id(server->local_list,
client_id, TRUE, NULL);
if (!client2) {
silc_free(client_id);
}
/* Send to channel */
- silc_server_packet_send_to_channel(server, sock, channel, packet->type,
- FALSE, packet->buffer->data,
+ silc_server_packet_send_to_channel(server, sock, channel, packet->type,
+ FALSE, packet->buffer->data,
packet->buffer->len, FALSE);
/* Remove the client from channel's invite list */
case SILC_NOTIFY_TYPE_KILLED:
{
- /*
+ /*
* Distribute the notify to local clients on channels
*/
unsigned char *id, *comment;
SilcUInt32 id_len, comment_len;
-
+
SILC_LOG_DEBUG(("KILLED notify"));
-
+
/* Get client ID */
id = silc_argument_get_arg_type(args, 1, &id_len);
if (!id)
goto out;
/* If the the client is not in local list we check global list */
- client = silc_idlist_find_client_by_id(server->global_list,
+ client = silc_idlist_find_client_by_id(server->global_list,
client_id, TRUE, &cache);
if (!client) {
- client = silc_idlist_find_client_by_id(server->local_list,
+ client = silc_idlist_find_client_by_id(server->local_list,
client_id, TRUE, &cache);
if (!client) {
silc_free(client_id);
if (id_type == SILC_ID_CLIENT) {
/* If the the client is not in local list we check global list */
- client2 = silc_idlist_find_client_by_id(server->global_list,
+ client2 = silc_idlist_find_client_by_id(server->global_list,
client_id, TRUE, NULL);
if (!client2) {
- client2 = silc_idlist_find_client_by_id(server->local_list,
+ client2 = silc_idlist_find_client_by_id(server->local_list,
client_id, TRUE, NULL);
if (!client2) {
silc_free(client_id);
tmp, tmp_len);
/* Remove the client from all channels */
- silc_server_remove_from_channels(server, NULL, client, FALSE, NULL,
+ silc_server_remove_from_channels(server, NULL, client, FALSE, NULL,
FALSE, TRUE);
/* Check if anyone is watching this nickname */
goto out;
/* Get client entry */
- client = silc_idlist_find_client_by_id(server->global_list,
+ client = silc_idlist_find_client_by_id(server->global_list,
client_id, TRUE, NULL);
if (!client) {
- client = silc_idlist_find_client_by_id(server->local_list,
+ client = silc_idlist_find_client_by_id(server->local_list,
client_id, TRUE, NULL);
if (!client) {
silc_free(client_id);
*/
SILC_LOG_DEBUG(("BAN notify"));
-
+
/* Get Channel ID */
tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
if (!tmp)
channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
if (!channel_id)
goto out;
-
+
/* Get channel entry */
- channel = silc_idlist_find_channel_by_id(server->global_list,
+ channel = silc_idlist_find_channel_by_id(server->global_list,
channel_id, NULL);
if (!channel) {
- channel = silc_idlist_find_channel_by_id(server->local_list,
+ channel = silc_idlist_find_channel_by_id(server->local_list,
channel_id, NULL);
if (!channel) {
SILC_LOG_DEBUG(("Notify for unknown channel"));
client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
if (!client_id)
goto out;
- client = silc_idlist_find_client_by_id(server->global_list,
+ client = silc_idlist_find_client_by_id(server->global_list,
client_id, FALSE, NULL);
if (client) {
- silc_server_remove_from_channels(server, NULL, client, TRUE,
+ silc_server_remove_from_channels(server, NULL, client, TRUE,
NULL, TRUE, FALSE);
silc_idlist_del_data(client);
silc_idlist_del_client(server->global_list, client);
silc_free(new);
}
-/* Received private message. This resolves the destination of the message
+/* Received private message. This resolves the destination of the message
and sends the packet. This is used by both server and router. If the
destination is our locally connected client this sends the packet to
the client. This may also send the message for further routing if
/* Get the route to the client */
dst_sock = silc_server_get_client_route(server, packet->dst_id,
- packet->dst_id_len, NULL,
+ packet->dst_id_len, NULL,
&idata, &client);
if (!dst_sock) {
SilcBuffer idp;
/* Get the route to the client */
dst_sock = silc_server_get_client_route(server, packet->dst_id,
- packet->dst_id_len, NULL,
+ packet->dst_id_len, NULL,
&idata, NULL);
if (!dst_sock)
return;
}
/* Processes incoming command reply packet. The command reply packet may
- be destined to one of our clients or it may directly for us. We will
+ be destined to one of our clients or it may directly for us. We will
call the command reply routine after processing the packet. */
void silc_server_command_reply(SilcServer server,
if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
/* Relay the packet to the client */
const SilcBufferStruct p;
-
+
dst_sock = (SilcSocketConnection)client->connection;
idata = (SilcIDListData)client;
-
- silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
+
+ silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
+ packet->dst_id_len + packet->padlen);
if (!silc_packet_send_prepare(dst_sock, 0, 0, buffer->len,
idata->hmac_send, (const SilcBuffer)&p)) {
return;
}
silc_buffer_put((SilcBuffer)&p, buffer->data, buffer->len);
-
+
/* Encrypt packet */
silc_packet_encrypt(idata->send_key, idata->hmac_send, idata->psn_send++,
(SilcBuffer)&p, buffer->len);
-
+
/* Send the packet */
silc_server_packet_send_real(server, dst_sock, TRUE);
SILC_NOTIFY_TYPE_ERROR, 2,
&error, 1, idp->data, idp->len);
}
-
+
silc_buffer_free(idp);
goto out;
}
/* See that this client is on the channel. If the original sender is
not client (as it can be server as well) we don't do the check. */
- sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
+ sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
packet->src_id_type);
if (!sender_id)
goto out;
if (packet->src_id_type == SILC_ID_CLIENT) {
- sender_entry = silc_idlist_find_client_by_id(server->local_list,
+ sender_entry = silc_idlist_find_client_by_id(server->local_list,
sender_id, TRUE, NULL);
if (!sender_entry) {
local = FALSE;
- sender_entry = silc_idlist_find_client_by_id(server->global_list,
+ sender_entry = silc_idlist_find_client_by_id(server->global_list,
sender_id, TRUE, NULL);
}
- if (!sender_entry || !silc_server_client_on_channel(sender_entry,
+ if (!sender_entry || !silc_server_client_on_channel(sender_entry,
channel, &chl)) {
SILC_LOG_DEBUG(("Client not on channel"));
goto out;
/* If channel is moderated check that client is allowed to send
messages. */
- if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS &&
+ if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS &&
!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
!(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
SILC_LOG_DEBUG(("Channel is silenced from normal users"));
goto out;
}
- if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS &&
+ if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS &&
chl->mode & SILC_CHANNEL_UMODE_CHANOP &&
!(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
SILC_LOG_DEBUG(("Channel is silenced from operators"));
goto out;
}
- /* If the packet is coming from router, but the client entry is local
- entry to us then some router is rerouting this to us and it is not
+ /* If the packet is coming from router, but the client entry is local
+ entry to us then some router is rerouting this to us and it is not
allowed. When the client is local to us it means that we've routed
this packet to network, and now someone is routing it back to us. */
if (server->server_type == SILC_ROUTER &&
sock->hostname, sock->ip));
return;
}
-
+
/* Distribute the key to everybody who is on the channel. If we are router
we will also send it to locally connected servers. */
silc_server_send_channel_key(server, sock, channel, FALSE);
-
+
if (server->server_type != SILC_BACKUP_ROUTER) {
/* Distribute to local cell backup routers. */
- silc_server_backup_send(server, sock->user_data,
+ silc_server_backup_send(server, sock->user_data,
SILC_PACKET_CHANNEL_KEY, 0,
buffer->data, buffer->len, FALSE, TRUE);
}
/* Remove the old cache entry. */
if (!silc_idcache_del_by_context(server->local_list->clients, client)) {
SILC_LOG_INFO(("Unauthenticated client attempted to register to network"));
- silc_server_disconnect_remote(server, sock,
+ silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_NOT_AUTHENTICATED, NULL);
if (sock->user_data)
silc_server_free_sock_user_data(server, sock, NULL);
/* Make sure this client hasn't registered already */
if (idata->status & SILC_IDLIST_STATUS_REGISTERED) {
- silc_server_disconnect_remote(server, sock,
+ silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_OPERATION_ALLOWED,
"Too many registrations");
if (sock->user_data)
/* Parse incoming packet */
ret = silc_buffer_unformat(buffer,
- SILC_STR_UI16_NSTRING_ALLOC(&username,
+ SILC_STR_UI16_NSTRING_ALLOC(&username,
&username_len),
SILC_STR_UI16_STRING_ALLOC(&realname),
SILC_STR_END);
silc_free(realname);
SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
"connection", sock->hostname, sock->ip));
- silc_server_disconnect_remote(server, sock,
- SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
+ silc_server_disconnect_remote(server, sock,
+ SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
NULL);
if (sock->user_data)
silc_server_free_sock_user_data(server, sock, NULL);
silc_free(realname);
SILC_LOG_ERROR(("Client %s (%s) did not send its username, closing "
"connection", sock->hostname, sock->ip));
- silc_server_disconnect_remote(server, sock,
+ silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
NULL);
if (sock->user_data)
hostname = silc_memdup(username + tlen + 1, strlen(username) - tlen - 1);
- if (strcmp(sock->hostname, sock->ip) &&
+ if (strcmp(sock->hostname, sock->ip) &&
strcmp(sock->hostname, hostname)) {
silc_free(username);
silc_free(hostname);
silc_free(realname);
SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
"connection", sock->hostname, sock->ip));
- silc_server_disconnect_remote(server, sock,
+ silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
NULL);
if (sock->user_data)
silc_server_free_sock_user_data(server, sock, NULL);
return NULL;
}
-
+
pident = silc_pkcs_decode_identifier(client->data.public_key->identifier);
if (pident) {
phostname = strdup(pident->host);
silc_pkcs_free_identifier(pident);
}
- if (!strcmp(sock->hostname, sock->ip) &&
+ if (!strcmp(sock->hostname, sock->ip) &&
phostname && strcmp(phostname, hostname)) {
silc_free(username);
silc_free(hostname);
silc_free(realname);
SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
"connection", sock->hostname, sock->ip));
- silc_server_disconnect_remote(server, sock,
+ silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
NULL);
if (sock->user_data)
silc_server_free_sock_user_data(server, sock, NULL);
return NULL;
}
-
+
silc_free(phostname);
} else {
/* The hostname is not present, add it. */
#if 0
if (strcmp(sock->hostname, sock->ip)) {
#endif
- newusername = silc_calloc(strlen(username) +
+ newusername = silc_calloc(strlen(username) +
strlen(sock->hostname) + 2,
sizeof(*newusername));
strncat(newusername, username, strlen(username));
username = newusername;
#if 0
} else {
- SilcPublicKeyIdentifier pident =
+ SilcPublicKeyIdentifier pident =
silc_pkcs_decode_identifier(client->data.public_key->identifier);
-
+
if (pident) {
- newusername = silc_calloc(strlen(username) +
+ newusername = silc_calloc(strlen(username) +
strlen(pident->host) + 2,
sizeof(*newusername));
strncat(newusername, username, strlen(username));
}
/* Create Client ID */
- while (!silc_id_create_client_id(server, server->id, server->rng,
+ while (!silc_id_create_client_id(server, server->id, server->rng,
server->md5hash, nickname, &client_id)) {
nickfail++;
if (nickfail > 9) {
- silc_server_disconnect_remote(server, sock,
+ silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_BAD_NICKNAME, NULL);
if (sock->user_data)
silc_server_free_sock_user_data(server, sock, NULL);
/* Create new server. This processes received New Server packet and
saves the received Server ID. The server is our locally connected
- server thus we save all the information and save it to local list.
+ server thus we save all the information and save it to local list.
This funtion can be used by both normal server and router server.
If normal server uses this it means that its router has connected
to the server. If router uses this it means that one of the cell's
/* Remove the old cache entry */
if (!silc_idcache_del_by_context(server->local_list->servers, new_server)) {
- if (!silc_idcache_del_by_context(server->global_list->servers,
+ if (!silc_idcache_del_by_context(server->global_list->servers,
new_server)) {
SILC_LOG_INFO(("Unauthenticated %s attempted to register to "
"network", (sock->type == SILC_SOCKET_TYPE_SERVER ?
"server" : "router")));
- silc_server_disconnect_remote(server, sock,
+ silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_NOT_AUTHENTICATED, NULL);
if (sock->user_data)
silc_server_free_sock_user_data(server, sock, NULL);
/* Make sure this server hasn't registered already */
if (idata->status & SILC_IDLIST_STATUS_REGISTERED) {
- silc_server_disconnect_remote(server, sock,
+ silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_OPERATION_ALLOWED,
"Too many registrations");
if (sock->user_data)
/* Parse the incoming packet */
ret = silc_buffer_unformat(buffer,
SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
- SILC_STR_UI16_NSTRING_ALLOC(&server_name,
+ SILC_STR_UI16_NSTRING_ALLOC(&server_name,
&name_len),
SILC_STR_END);
if (ret == -1) {
silc_free(id_string);
silc_free(server_name);
- silc_server_disconnect_remote(server, sock,
+ silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
NULL);
if (sock->user_data)
if (id_len > buffer->len) {
silc_free(id_string);
silc_free(server_name);
- silc_server_disconnect_remote(server, sock,
+ silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
NULL);
if (sock->user_data)
if (!server_id) {
silc_free(id_string);
silc_free(server_name);
- silc_server_disconnect_remote(server, sock,
+ silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
NULL);
if (sock->user_data)
if (!silc_id_is_valid_server_id(server, server_id, sock)) {
SILC_LOG_INFO(("Invalid server ID sent by %s (%s)",
sock->ip, sock->hostname));
- silc_server_disconnect_remote(server, sock,
+ silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_BAD_SERVER_ID, NULL);
if (sock->user_data)
silc_server_free_sock_user_data(server, sock, NULL);
}
/* Check that we do not have this ID already */
- server_entry = silc_idlist_find_server_by_id(server->local_list,
+ server_entry = silc_idlist_find_server_by_id(server->local_list,
server_id, TRUE, NULL);
if (server_entry) {
if (SILC_IS_LOCAL(server_entry)) {
- silc_server_disconnect_remote(server, server_entry->connection,
+ silc_server_disconnect_remote(server, server_entry->connection,
SILC_STATUS_ERR_OPERATION_ALLOWED,
"Too many registrations");
if (((SilcSocketConnection)server_entry->connection)->user_data)
silc_idcache_del_by_context(server->local_list->servers, server_entry);
}
} else {
- server_entry = silc_idlist_find_server_by_id(server->global_list,
+ server_entry = silc_idlist_find_server_by_id(server->global_list,
server_id, TRUE, NULL);
if (server_entry) {
if (SILC_IS_LOCAL(server_entry)) {
- silc_server_disconnect_remote(server, server_entry->connection,
+ silc_server_disconnect_remote(server, server_entry->connection,
SILC_STATUS_ERR_OPERATION_ALLOWED,
"Too many registrations");
if (((SilcSocketConnection)server_entry->connection)->user_data)
silc_id_render(server_id, SILC_ID_SERVER)));
/* Add again the entry to the ID cache. */
- silc_idcache_add(local ? server->local_list->servers :
- server->global_list->servers, server_name, server_id,
+ silc_idcache_add(local ? server->local_list->servers :
+ server->global_list->servers, server_name, server_id,
new_server, 0, NULL);
/* Distribute the information about new server in the SILC network
if (server->server_type == SILC_ROUTER && !server->standalone &&
SILC_PRIMARY_ROUTE(server) != sock)
silc_server_send_new_id(server, SILC_PRIMARY_ROUTE(server),
- TRUE, new_server->id, SILC_ID_SERVER,
+ TRUE, new_server->id, SILC_ID_SERVER,
silc_id_get_len(server_id, SILC_ID_SERVER));
if (server->server_type == SILC_ROUTER) {
SILC_STR_UI_CHAR(SILC_SERVER_BACKUP_REPLACED),
SILC_STR_UI_CHAR(0),
SILC_STR_END);
- silc_server_packet_send(server, sock,
- SILC_PACKET_RESUME_ROUTER, 0,
+ silc_server_packet_send(server, sock,
+ SILC_PACKET_RESUME_ROUTER, 0,
packet->data, packet->len, TRUE);
silc_buffer_free(packet);
idata->status |= SILC_IDLIST_STATUS_DISABLED;
} else {
/* If it is router announce our stuff to it. */
- if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
+ if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
server->server_type == SILC_ROUTER) {
silc_server_announce_servers(server, FALSE, 0, sock);
silc_server_announce_clients(server, 0, sock);
/* Processes incoming New ID packet. New ID Payload is used to distribute
information about newly registered clients and servers. */
-static void silc_server_new_id_real(SilcServer server,
+static void silc_server_new_id_real(SilcServer server,
SilcSocketConnection sock,
SilcPacketContext *packet,
int broadcast)
/* If the sender is backup router and ID is server (and we are not
backup router) then switch the entry to global list. */
- if (server_entry->server_type == SILC_BACKUP_ROUTER &&
- id_type == SILC_ID_SERVER &&
+ if (server_entry->server_type == SILC_BACKUP_ROUTER &&
+ id_type == SILC_ID_SERVER &&
server->id_entry->server_type != SILC_BACKUP_ROUTER) {
id_list = server->global_list;
router_sock = server->router ? SILC_PRIMARY_ROUTE(server) : sock;
SilcClientEntry entry;
/* Check that we do not have this client already */
- entry = silc_idlist_find_client_by_id(server->global_list,
- id, server->server_type,
+ entry = silc_idlist_find_client_by_id(server->global_list,
+ id, server->server_type,
NULL);
if (!entry)
- entry = silc_idlist_find_client_by_id(server->local_list,
+ entry = silc_idlist_find_client_by_id(server->local_list,
id, server->server_type,
NULL);
if (entry) {
silc_id_render(id, SILC_ID_CLIENT),
sock->type == SILC_SOCKET_TYPE_SERVER ?
"Server" : "Router", sock->hostname));
-
+
/* As a router we keep information of all global information in our
global list. Cell wide information however is kept in the local
list. */
- entry = silc_idlist_add_client(id_list, NULL, NULL, NULL,
+ entry = silc_idlist_add_client(id_list, NULL, NULL, NULL,
id, router, NULL, 0);
if (!entry) {
SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
SILC_LOG_DEBUG(("Ignoring sender's own ID"));
break;
}
-
+
/* Check that we do not have this server already */
- entry = silc_idlist_find_server_by_id(server->global_list,
- id, server->server_type,
+ entry = silc_idlist_find_server_by_id(server->global_list,
+ id, server->server_type,
NULL);
if (!entry)
- entry = silc_idlist_find_server_by_id(server->local_list,
+ entry = silc_idlist_find_server_by_id(server->local_list,
id, server->server_type,
NULL);
if (entry) {
silc_id_render(id, SILC_ID_SERVER),
sock->type == SILC_SOCKET_TYPE_SERVER ?
"Server" : "Router", sock->hostname));
-
- /* As a router we keep information of all global information in our
+
+ /* As a router we keep information of all global information in our
global list. Cell wide information however is kept in the local
list. */
- entry = silc_idlist_add_server(id_list, NULL, 0, id, router,
+ entry = silc_idlist_add_server(id_list, NULL, 0, id, router,
router_sock);
if (!entry) {
SILC_LOG_ERROR(("Could not add new server to the ID Cache"));
goto out;
}
entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
-
+
if (sock->type == SILC_SOCKET_TYPE_SERVER)
server->stat.cell_servers++;
server->stat.servers++;
!(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
- packet->type,
+ packet->type,
packet->flags | SILC_PACKET_FLAG_BROADCAST,
buffer->data, buffer->len, FALSE);
- silc_server_backup_send(server, sock->user_data,
+ silc_server_backup_send(server, sock->user_data,
packet->type, packet->flags,
- packet->buffer->data, packet->buffer->len,
+ packet->buffer->data, packet->buffer->len,
FALSE, TRUE);
}
!(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
- packet->type,
+ packet->type,
packet->flags | SILC_PACKET_FLAG_BROADCAST,
- packet->buffer->data,
+ packet->buffer->data,
packet->buffer->len, FALSE);
- silc_server_backup_send(server, sock->user_data,
+ silc_server_backup_send(server, sock->user_data,
packet->type, packet->flags,
- packet->buffer->data, packet->buffer->len,
+ packet->buffer->data, packet->buffer->len,
FALSE, TRUE);
}
silc_free(new_id);
}
-/* Received New Channel packet. Information about new channels in the
+/* Received New Channel packet. Information about new channels in the
network are distributed using this packet. Save the information about
the new channel. This usually comes from router but also normal server
can send this to notify channels it has when it connects to us. */
packet->buffer->len);
if (!payload)
return;
-
+
/* Get the channel ID */
channel_id = silc_channel_get_id_parse(payload);
if (!channel_id) {
server_entry = (SilcServerEntry)sock->user_data;
if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
- /* Add the channel to global list as it is coming from router. It
+ /* Add the channel to global list as it is coming from router. It
cannot be our own channel as it is coming from router. */
/* Check that we don't already have this channel */
- channel = silc_idlist_find_channel_by_name(server->local_list,
+ channel = silc_idlist_find_channel_by_name(server->local_list,
channel_name, NULL);
if (!channel)
- channel = silc_idlist_find_channel_by_name(server->global_list,
+ channel = silc_idlist_find_channel_by_name(server->global_list,
channel_name, NULL);
if (!channel) {
SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
- silc_id_render(channel_id, SILC_ID_CHANNEL),
+ silc_id_render(channel_id, SILC_ID_CHANNEL),
sock->hostname));
-
- channel =
- silc_idlist_add_channel(server->global_list, strdup(channel_name),
+
+ channel =
+ silc_idlist_add_channel(server->global_list, strdup(channel_name),
0, channel_id, sock->user_data, NULL, NULL, 0);
if (!channel) {
silc_channel_payload_free(payload);
SilcBuffer chk;
SILC_LOG_DEBUG(("Channel id(%s) from [Server] %s",
- silc_id_render(channel_id, SILC_ID_CHANNEL),
+ silc_id_render(channel_id, SILC_ID_CHANNEL),
sock->hostname));
/* Check that we don't already have this channel */
- channel = silc_idlist_find_channel_by_name(server->local_list,
+ channel = silc_idlist_find_channel_by_name(server->local_list,
channel_name, NULL);
if (!channel)
- channel = silc_idlist_find_channel_by_name(server->global_list,
+ channel = silc_idlist_find_channel_by_name(server->global_list,
channel_name, NULL);
/* If the channel does not exist, then create it. This creates a new
SilcChannelID *tmp;
SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
if (silc_id_create_channel_id(server, server->id, server->rng, &tmp)) {
- silc_server_send_notify_channel_change(server, sock, FALSE,
+ silc_server_send_notify_channel_change(server, sock, FALSE,
channel_id, tmp);
silc_channel_payload_free(payload);
silc_free(channel_id);
cipher_len = strlen(cipher);
chk = silc_channel_key_payload_encode(id_len, id,
cipher_len, cipher,
- channel->key_len / 8,
+ channel->key_len / 8,
channel->key);
- silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
+ silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
chk->data, chk->len, FALSE);
silc_buffer_free(chk);
silc_free(id);
/* They don't match, send CHANNEL_CHANGE notify to the server to
force the ID change. */
SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
- silc_server_send_notify_channel_change(server, sock, FALSE,
+ silc_server_send_notify_channel_change(server, sock, FALSE,
channel_id, channel->id);
silc_channel_payload_free(payload);
silc_free(channel_id);
cipher_len = strlen(cipher);
chk = silc_channel_key_payload_encode(id_len, id,
cipher_len, cipher,
- channel->key_len / 8,
+ channel->key_len / 8,
channel->key);
- silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
+ silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
chk->data, chk->len, FALSE);
silc_buffer_free(chk);
silc_free(id);
silc_server_packet_send_dest(server, sock,
SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
channel->id, SILC_ID_CHANNEL,
- users_modes->data,
+ users_modes->data,
users_modes->len, FALSE);
silc_buffer_free(users_modes);
}
if (channel->topic) {
silc_server_send_notify_topic_set(server, sock,
server->server_type == SILC_ROUTER ?
- TRUE : FALSE, channel,
+ TRUE : FALSE, channel,
server->id, SILC_ID_SERVER,
channel->topic);
}
!(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
SILC_LOG_DEBUG(("Broadcasting received New Channel packet"));
silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
- packet->type,
+ packet->type,
packet->flags | SILC_PACKET_FLAG_BROADCAST,
- packet->buffer->data,
+ packet->buffer->data,
packet->buffer->len, FALSE);
- silc_server_backup_send(server, sock->user_data,
+ silc_server_backup_send(server, sock->user_data,
packet->type, packet->flags,
- packet->buffer->data, packet->buffer->len,
+ packet->buffer->data, packet->buffer->len,
FALSE, TRUE);
}
/* Get the route to the client */
dst_sock = silc_server_get_client_route(server, packet->dst_id,
- packet->dst_id_len, NULL,
+ packet->dst_id_len, NULL,
&idata, NULL);
if (!dst_sock)
return;
proto_ctx->sock = sock;
proto_ctx->responder = TRUE;
proto_ctx->pfs = idata->rekey->pfs;
-
+
/* Perform rekey protocol. Will call the final callback after the
protocol is over. */
- silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
+ silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
&protocol, proto_ctx, silc_server_rekey_final);
sock->protocol = protocol;
/* Get the route to the client */
dst_sock = silc_server_get_client_route(server, packet->dst_id,
- packet->dst_id_len, NULL,
+ packet->dst_id_len, NULL,
&idata, NULL);
if (!dst_sock)
return;
if (reply && silc_command_get(reply->payload) == SILC_COMMAND_WHOIS) {
/* Get entry to the client, and resolve it if we don't have it. */
- client = silc_idlist_find_client_by_id(server->local_list,
+ client = silc_idlist_find_client_by_id(server->local_list,
r->data, TRUE, NULL);
if (!client) {
client = silc_idlist_find_client_by_id(server->global_list,
/* We must retrieve the detached client's public key by sending
GETKEY command. Reprocess this packet after receiving the key */
SilcBuffer idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
- SilcSocketConnection dest_sock =
+ SilcSocketConnection dest_sock =
silc_server_get_client_route(server, NULL, 0, client_id, NULL, NULL);
SILC_LOG_DEBUG(("Resolving client public key"));
- silc_server_send_command(server, dest_sock ? dest_sock :
+ silc_server_send_command(server, dest_sock ? dest_sock :
SILC_PRIMARY_ROUTE(server),
SILC_COMMAND_GETKEY, ++server->cmd_ident,
1, 1, idp->data, idp->len);
if (!idata->hash ||
!silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
detached_client->data.public_key, 0,
- idata->hash, detached_client->id,
+ idata->hash, detached_client->id,
SILC_ID_CLIENT)) {
SILC_LOG_ERROR(("Client %s (%s) resume authentication failed, "
"closing connection", sock->hostname, sock->ip));
/* Send to primary router */
silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
- SILC_PACKET_RESUME_CLIENT, 0,
+ SILC_PACKET_RESUME_CLIENT, 0,
buf->data, buf->len, TRUE);
silc_server_backup_send(server, detached_client->router,
SILC_PACKET_RESUME_CLIENT, 0,
if (server->server_type == SILC_ROUTER && detached_client->router &&
detached_client->router->server_type != SILC_ROUTER)
silc_server_packet_send(server, detached_client->router->connection,
- SILC_PACKET_RESUME_CLIENT, 0,
+ SILC_PACKET_RESUME_CLIENT, 0,
buf->data, buf->len, TRUE);
silc_buffer_free(buf);
/* If the ID is not based in our ID then change it */
if (!SILC_ID_COMPARE(client->id, server->id, server->id->ip.data_len)) {
silc_free(client_id);
- while (!silc_id_create_client_id(server, server->id, server->rng,
- server->md5hash, client->nickname,
+ while (!silc_id_create_client_id(server, server->id, server->rng,
+ server->md5hash, client->nickname,
&client_id)) {
nickfail++;
if (nickfail > 9) {
- silc_server_disconnect_remote(server, sock,
+ silc_server_disconnect_remote(server, sock,
SILC_STATUS_ERR_BAD_NICKNAME, NULL);
if (sock->user_data)
silc_server_free_sock_user_data(server, sock, NULL);
return;
}
- snprintf(&client->nickname[strlen(client->nickname) - 1], 1,
+ snprintf(&client->nickname[strlen(client->nickname) - 1], 1,
"%d", nickfail);
}
nick_change = TRUE;
silc_hash_table_list(client->channels, &htl);
while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
channel = chl->channel;
- SILC_LOG_DEBUG(("Resolving users for %s channel",
+ SILC_LOG_DEBUG(("Resolving users for %s channel",
channel->channel_name));
if (channel->disabled || !channel->users_resolved) {
silc_server_send_command(server, SILC_PRIMARY_ROUTE(server),
SilcBuffer oidp, nidp;
oidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
nidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
- silc_server_send_notify_on_channels(server, NULL, client,
+ silc_server_send_notify_on_channels(server, NULL, client,
SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
- oidp->data, oidp->len,
+ oidp->data, oidp->len,
nidp->data, nidp->len,
- client->nickname,
+ client->nickname,
strlen(client->nickname));
silc_buffer_free(oidp);
silc_buffer_free(nidp);
id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
cipher = silc_cipher_get_name(channel->channel_key);
- keyp =
+ keyp =
silc_channel_key_payload_encode(silc_id_get_len(channel->id,
- SILC_ID_CHANNEL),
+ SILC_ID_CHANNEL),
id_string,
strlen(cipher), cipher,
channel->key_len / 8, channel->key);
silc_free(id_string);
/* Send the channel key to the client */
- silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
+ silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
keyp->data, keyp->len, FALSE);
/* Distribute the channel key to channel */
if (created) {
silc_server_send_channel_key(server, NULL, channel,
- server->server_type == SILC_ROUTER ?
+ server->server_type == SILC_ROUTER ?
FALSE : !server->standalone);
silc_server_backup_send(server, NULL, SILC_PACKET_CHANNEL_KEY, 0,
keyp->data, keyp->len, FALSE, TRUE);
}
/* Get entry to the client, and resolve it if we don't have it. */
- detached_client = silc_idlist_find_client_by_id(server->local_list,
+ detached_client = silc_idlist_find_client_by_id(server->local_list,
client_id, TRUE,
&id_cache);
if (!detached_client) {
!(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
SILC_LOG_DEBUG(("Broadcasting received Resume Client packet"));
silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
- packet->type,
+ packet->type,
packet->flags | SILC_PACKET_FLAG_BROADCAST,
buffer->data, buffer->len, FALSE);
- silc_server_backup_send(server, sock->user_data,
+ silc_server_backup_send(server, sock->user_data,
packet->type, packet->flags,
- packet->buffer->data, packet->buffer->len,
+ packet->buffer->data, packet->buffer->len,
FALSE, TRUE);
}
}
/* Get server entry */
- server_entry = silc_idlist_find_server_by_id(server->global_list,
+ server_entry = silc_idlist_find_server_by_id(server->global_list,
server_id, TRUE, NULL);
local = FALSE;
if (!server_entry) {
- server_entry = silc_idlist_find_server_by_id(server->local_list,
+ server_entry = silc_idlist_find_server_by_id(server->local_list,
server_id, TRUE, NULL);
local = TRUE;
if (!server_entry) {
if (server->server_type != SILC_ROUTER) {
silc_hash_table_list(detached_client->channels, &htl);
while (silc_hash_table_get(&htl, NULL, (void **)&chl))
- chl->channel->global_users =
+ chl->channel->global_users =
silc_server_channel_has_global(chl->channel);
silc_hash_table_list_reset(&htl);
}
/*
- packet_send.c
+ packet_send.c
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1997 - 2002 Pekka Riikonen
+ Copyright (C) 1997 - 2003 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
*/
/*
- * Server packet routines to send packets.
+ * Server packet routines to send packets.
*/
/* $Id$ */
return ret;
}
- /* Mark that there is some outgoing data available for this connection.
+ /* Mark that there is some outgoing data available for this connection.
This call sets the connection both for input and output (the input
- is set always and this call keeps the input setting, actually).
+ is set always and this call keeps the input setting, actually).
Actual data sending is performed by silc_server_packet_process. */
SILC_SET_CONNECTION_FOR_OUTPUT(server->schedule, sock->sock);
/* Assembles a new packet to be sent out to network. This doesn't actually
send the packet but creates the packet and fills the outgoing data
- buffer and marks the packet ready to be sent to network. However, If
- argument force_send is TRUE the packet is sent immediately and not put
+ buffer and marks the packet ready to be sent to network. However, If
+ argument force_send is TRUE the packet is sent immediately and not put
to queue. Normal case is that the packet is not sent immediately. */
void silc_server_packet_send(SilcServer server,
- SilcSocketConnection sock,
- SilcPacketType type,
+ SilcSocketConnection sock,
+ SilcPacketType type,
SilcPacketFlags flags,
- unsigned char *data,
+ unsigned char *data,
SilcUInt32 data_len,
bool force_send)
{
/* 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_HEARTBEAT && type != SILC_PACKET_REKEY &&
type != SILC_PACKET_REKEY_DONE) ||
- sock->user_data == server->id_entry) {
+ (sock->user_data == server->id_entry)) {
SILC_LOG_DEBUG(("Connection is disabled"));
return;
}
/* Assembles a new packet to be sent out to network. This doesn't actually
send the packet but creates the packet and fills the outgoing data
- buffer and marks the packet ready to be sent to network. However, If
- argument force_send is TRUE the packet is sent immediately and not put
- to queue. Normal case is that the packet is not sent immediately.
+ buffer and marks the packet ready to be sent to network. However, If
+ argument force_send is TRUE the packet is sent immediately and not put
+ to queue. Normal case is that the packet is not sent immediately.
Destination information is sent as argument for this function. */
void silc_server_packet_send_dest(SilcServer server,
- SilcSocketConnection sock,
- SilcPacketType type,
+ SilcSocketConnection sock,
+ SilcPacketType type,
SilcPacketFlags flags,
void *dst_id,
SilcIdType dst_id_type,
- unsigned char *data,
+ unsigned char *data,
SilcUInt32 data_len,
bool force_send)
{
packetdata.dst_id_len = dst_id_len;
packetdata.dst_id_type = dst_id_type;
data_len = SILC_PACKET_DATALEN(data_len, (SILC_PACKET_HEADER_LEN +
- packetdata.src_id_len +
+ packetdata.src_id_len +
packetdata.dst_id_len));
- packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN +
+ packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN +
packetdata.src_id_len + dst_id_len;
if (type == SILC_PACKET_CONNECTION_AUTH)
SILC_PACKET_PADLEN_MAX(packetdata.truelen, block_len, packetdata.padlen);
/* Assembles a new packet to be sent out to network. This doesn't actually
send the packet but creates the packet and fills the outgoing data
- buffer and marks the packet ready to be sent to network. However, If
- argument force_send is TRUE the packet is sent immediately and not put
- to queue. Normal case is that the packet is not sent immediately.
+ buffer and marks the packet ready to be sent to network. However, If
+ argument force_send is TRUE the packet is sent immediately and not put
+ to queue. Normal case is that the packet is not sent immediately.
The source and destination information is sent as argument for this
function. */
void silc_server_packet_send_srcdest(SilcServer server,
- SilcSocketConnection sock,
- SilcPacketType type,
+ SilcSocketConnection sock,
+ SilcPacketType type,
SilcPacketFlags flags,
void *src_id,
SilcIdType src_id_type,
void *dst_id,
SilcIdType dst_id_type,
- unsigned char *data,
+ unsigned char *data,
SilcUInt32 data_len,
bool force_send)
{
packetdata.dst_id_len = dst_id_len;
packetdata.dst_id_type = dst_id_type;
data_len = SILC_PACKET_DATALEN(data_len, (SILC_PACKET_HEADER_LEN +
- packetdata.src_id_len +
+ packetdata.src_id_len +
dst_id_len));
- packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN +
+ packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN +
packetdata.src_id_len + dst_id_len;
SILC_PACKET_PADLEN(packetdata.truelen, block_len, packetdata.padlen);
silc_packet_encrypt(idata->send_key, idata->hmac_send, idata->psn_send++,
(SilcBuffer)&p, p.len);
- SILC_LOG_HEXDUMP(("Routed packet (%d), len %d", idata->psn_send - 1,
+ SILC_LOG_HEXDUMP(("Routed packet (%d), len %d", idata->psn_send - 1,
p.len), p.data, p.len);
/* Now actually send the packet */
void silc_server_packet_send_clients(SilcServer server,
SilcHashTable clients,
- SilcPacketType type,
+ SilcPacketType type,
SilcPacketFlags flags,
bool route,
- unsigned char *data,
+ unsigned char *data,
SilcUInt32 data_len,
bool force_send)
{
/* If client has router set it is not locally connected client and
we will route the message to the router set in the client. Though,
send locally connected server in all cases. */
- if (server->server_type == SILC_ROUTER && client->router &&
+ if (server->server_type == SILC_ROUTER && client->router &&
((!route && client->router->router == server->id_entry) || route)) {
/* Check if we have sent the packet to this route already */
return;
data_len = SILC_PACKET_DATALEN(data_len, (SILC_PACKET_HEADER_LEN +
- packet->src_id_len +
+ packet->src_id_len +
packet->dst_id_len));
- packet->truelen = data_len + SILC_PACKET_HEADER_LEN +
+ packet->truelen = data_len + SILC_PACKET_HEADER_LEN +
packet->src_id_len + packet->dst_id_len;
block_len = cipher ? silc_cipher_get_block_len(cipher) : 0;
}
if (channel_message)
- silc_packet_encrypt(cipher, hmac, sequence, (SilcBuffer)&p,
- SILC_PACKET_HEADER_LEN + packet->src_id_len +
+ silc_packet_encrypt(cipher, hmac, sequence, (SilcBuffer)&p,
+ SILC_PACKET_HEADER_LEN + packet->src_id_len +
packet->dst_id_len + packet->padlen);
else
silc_packet_encrypt(cipher, hmac, sequence, (SilcBuffer)&p, p.len);
-
+
SILC_LOG_HEXDUMP(("Channel packet (%d), len %d", sequence, p.len),
p.data, p.len);
silc_server_packet_send_real(server, sock, force_send);
}
-/* This routine is used by the server to send packets to channel. The
+/* This routine is used by the server to send packets to channel. The
packet sent with this function is distributed to all clients on
the channel. Usually this is used to send notify messages to the
- channel, things like notify about new user joining to the channel.
+ channel, things like notify about new user joining to the channel.
If `route' is FALSE then the packet is sent only locally and will not
be routed anywhere (for router locally means cell wide). If `sender'
is provided then the packet is not sent to that connection since it
/* This doesn't send channel message packets */
assert(type != SILC_PACKET_CHANNEL_MESSAGE);
-
+
/* Set the packet context pointers. */
packetdata.flags = 0;
packetdata.type = type;
router = server->router;
sock = (SilcSocketConnection)router->connection;
idata = (SilcIDListData)router;
-
+
if (sock != sender) {
SILC_LOG_DEBUG(("Sending packet to router for routing"));
silc_server_packet_send_to_channel_real(server, sock, &packetdata,
- idata->send_key,
- idata->hmac_send,
+ idata->send_key,
+ idata->hmac_send,
idata->psn_send++,
- data, data_len, FALSE,
+ data, data_len, FALSE,
force_send);
}
}
SILC_LOG_DEBUG(("Sending %s to channel %s",
silc_get_packet_name(type), channel->channel_name));
- routed = silc_calloc(silc_hash_table_count(channel->user_list),
+ routed = silc_calloc(silc_hash_table_count(channel->user_list),
sizeof(*routed));
/* Send the message to clients on the channel's client list. */
/* If client has router set it is not locally connected client and
we will route the message to the router set in the client. Though,
send locally connected server in all cases. */
- if (server->server_type == SILC_ROUTER && client->router &&
+ if (server->server_type == SILC_ROUTER && client->router &&
((!route && client->router->router == server->id_entry) || route)) {
/* Check if we have sent the packet to this route already */
/* Send the packet */
silc_server_packet_send_to_channel_real(server, sock, &packetdata,
- idata->send_key,
- idata->hmac_send,
+ idata->send_key,
+ idata->hmac_send,
idata->psn_send++,
- data, data_len, FALSE,
+ data, data_len, FALSE,
force_send);
/* Mark this route routed already */
/* Get data used in packet header encryption, keys and stuff. */
sock = (SilcSocketConnection)client->connection;
idata = (SilcIDListData)client;
-
+
if (!sock || (sender && sock == sender))
continue;
/* Send the packet */
silc_server_packet_send_to_channel_real(server, sock, &packetdata,
- idata->send_key,
- idata->hmac_send,
- idata->psn_send++,
- data, data_len, FALSE,
+ idata->send_key,
+ idata->hmac_send,
+ idata->psn_send++,
+ data, data_len, FALSE,
force_send);
}
silc_hash_table_list_reset(&htl);
/* This routine is explicitly used to relay messages to some channel.
Packets sent with this function we have received earlier and are
totally encrypted. This just sends the packet to all clients on
- the channel. If the sender of the packet is someone on the channel
+ the channel. If the sender of the packet is someone on the channel
the message will not be sent to that client. The SILC Packet header
is encrypted with the session key shared between us and the client.
MAC is also computed before encrypting the header. Rest of the
SILC_LOG_DEBUG(("Sending message to router for routing"));
silc_server_packet_send_to_channel_real(server, sock, &packetdata,
- idata->send_key,
- idata->hmac_send,
- idata->psn_send++,
- data, data_len, TRUE,
+ idata->send_key,
+ idata->hmac_send,
+ idata->psn_send++,
+ data, data_len, TRUE,
force_send);
}
}
- routed = silc_calloc(silc_hash_table_count(channel->user_list),
+ routed = silc_calloc(silc_hash_table_count(channel->user_list),
sizeof(*routed));
/* Assure we won't route the message back to the sender's way. */
if (sender_sock && sock == sender_sock)
continue;
- SILC_LOG_DEBUG(("Relaying packet to client ID(%s) %s (%s)",
+ SILC_LOG_DEBUG(("Relaying packet to client ID(%s) %s (%s)",
silc_id_render(client->id, SILC_ID_CLIENT),
sock->hostname, sock->ip));
/* Mark this route routed already. */
routed[routed_count++] = client->router;
-
+
if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
/* The remote connection is router then we'll decrypt the
channel message and re-encrypt it with the session key shared
/* If private key mode is not set then decrypt the packet
and re-encrypt it */
- if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY) &&
+ if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY) &&
channel->channel_key) {
unsigned char tmp[SILC_PACKET_MAX_LEN];
if (!sock || (sender_sock && sock == sender_sock))
continue;
- SILC_LOG_DEBUG(("Sending packet to client ID(%s) %s (%s)",
+ SILC_LOG_DEBUG(("Sending packet to client ID(%s) %s (%s)",
silc_id_render(client->id, SILC_ID_CLIENT),
sock->hostname, sock->ip));
/* Send the packet */
silc_server_packet_send_to_channel_real(server, sock, &packetdata,
- idata->send_key,
- idata->hmac_send,
- idata->psn_send++,
- data, data_len, TRUE,
+ idata->send_key,
+ idata->hmac_send,
+ idata->psn_send++,
+ data, data_len, TRUE,
force_send);
}
/* This function is used to send packets strictly to all local clients
on a particular channel. This is used for example to distribute new
- channel key to all our locally connected clients on the channel.
+ channel key to all our locally connected clients on the channel.
The packets are always encrypted with the session key shared between
the client, this means these are not _to the channel_ but _to the client_
on the channel. */
SilcBuffer buffer = packet->buffer;
const SilcBufferStruct p;
- silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
+ silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
+ packet->dst_id_len + packet->padlen);
if (!silc_packet_send_prepare(dst_sock, 0, 0, buffer->len, hmac,
(const SilcBuffer)&p)) {
silc_packet_encrypt(cipher, hmac, sequence, (SilcBuffer)&p, buffer->len);
} else {
/* Key exist so encrypt just header and send it */
- silc_packet_encrypt(cipher, hmac, sequence, (SilcBuffer)&p,
- SILC_PACKET_HEADER_LEN + packet->src_id_len +
+ silc_packet_encrypt(cipher, hmac, sequence, (SilcBuffer)&p,
+ SILC_PACKET_HEADER_LEN + packet->src_id_len +
packet->dst_id_len + packet->padlen);
}
}
}
-/* Sends error message. Error messages may or may not have any
+/* Sends error message. Error messages may or may not have any
implications. */
void silc_server_send_error(SilcServer server,
vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
va_end(ap);
- silc_server_packet_send(server, sock, SILC_PACKET_ERROR, 0,
+ silc_server_packet_send(server, sock, SILC_PACKET_ERROR, 0,
buf, strlen(buf), FALSE);
}
va_start(ap, argc);
packet = silc_notify_payload_encode(type, argc, ap);
- silc_server_packet_send(server, sock, SILC_PACKET_NOTIFY,
+ silc_server_packet_send(server, sock, SILC_PACKET_NOTIFY,
broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
packet->data, packet->len, FALSE);
SilcBuffer packet;
packet = silc_notify_payload_encode_args(type, argc, args);
- silc_server_packet_send(server, sock, SILC_PACKET_NOTIFY,
+ silc_server_packet_send(server, sock, SILC_PACKET_NOTIFY,
broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
packet->data, packet->len, FALSE);
silc_buffer_free(packet);
idp1 = silc_id_payload_encode((void *)old_id, SILC_ID_CLIENT);
idp2 = silc_id_payload_encode((void *)new_id, SILC_ID_CLIENT);
- silc_server_send_notify(server, sock, broadcast,
+ silc_server_send_notify(server, sock, broadcast,
SILC_NOTIFY_TYPE_NICK_CHANGE,
3, idp1->data, idp1->len, idp2->data, idp2->len,
nickname, nickname ? strlen(nickname) : 0);
mode, 4,
cipher, cipher ? strlen(cipher) : 0,
hmac, hmac ? strlen(hmac) : 0,
- passphrase, passphrase ?
+ passphrase, passphrase ?
strlen(passphrase) : 0,
fkey ? fkey->data : NULL, fkey ? fkey->len : 0);
silc_buffer_free(fkey),
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_CUMODE_CHANGE, 4,
+ SILC_ID_CHANNEL,
+ SILC_NOTIFY_TYPE_CUMODE_CHANGE, 4,
idp1->data, idp1->len,
mode, 4,
idp2->data, idp2->len,
silc_server_send_notify_dest(server, sock, broadcast,
(void *)channel->id, SILC_ID_CHANNEL,
SILC_NOTIFY_TYPE_TOPIC_SET,
- topic ? 2 : 1,
- idp->data, idp->len,
+ topic ? 2 : 1,
+ idp->data, idp->len,
topic, topic ? strlen(topic) : 0);
silc_buffer_free(idp);
}
silc_server_send_notify(server, sock, broadcast,
SILC_NOTIFY_TYPE_UMODE_CHANGE, 2,
- idp->data, idp->len,
+ idp->data, idp->len,
mode, 4);
silc_buffer_free(idp);
}
SILC_ID_CLIENT, SILC_NOTIFY_TYPE_WATCH,
4, idp->data, idp->len,
nickname, nickname ? strlen(nickname) : 0,
- mode, sizeof(mode),
+ mode, sizeof(mode),
type != SILC_NOTIFY_TYPE_NONE ?
n : NULL, sizeof(n));
silc_buffer_free(idp);
va_start(ap, argc);
packet = silc_notify_payload_encode(type, argc, ap);
- silc_server_packet_send_dest(server, sock, SILC_PACKET_NOTIFY,
+ silc_server_packet_send_dest(server, sock, SILC_PACKET_NOTIFY,
broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
dest_id, dest_id_type,
packet->data, packet->len, FALSE);
va_end(ap);
}
-/* Sends notify message to a channel. The notify message sent is
+/* Sends notify message to a channel. The notify message sent is
distributed to all clients on the channel. If `route_notify' is TRUE
then the notify may be routed to primary route or to some other routers.
If FALSE it is assured that the notify is sent only locally. If `sender'
va_start(ap, argc);
packet = silc_notify_payload_encode(type, argc, ap);
- silc_server_packet_send_to_channel(server, sender, channel,
+ silc_server_packet_send_to_channel(server, sender, channel,
SILC_PACKET_NOTIFY, route_notify,
packet->data, packet->len, FALSE);
silc_buffer_free(packet);
silc_hash_table_list(channel->user_list, &htl2);
while (silc_hash_table_get(&htl2, NULL, (void **)&chl2)) {
c = chl2->client;
-
+
if (sender && c == sender)
continue;
break;
if (k < routed_count)
continue;
-
+
/* Get data used in packet header encryption, keys and stuff. */
sock = (SilcSocketConnection)c->router->connection;
idata = (SilcIDListData)c->router;
/* Send the packet */
silc_server_packet_send_to_channel_real(server, sock, &packetdata,
- idata->send_key,
- idata->hmac_send,
- idata->psn_send++,
- data, data_len, FALSE,
+ idata->send_key,
+ idata->hmac_send,
+ idata->psn_send++,
+ data, data_len, FALSE,
force_send);
-
+
silc_free(packetdata.dst_id);
/* We want to make sure that the packet is routed to same router
/* Send to locally connected client */
if (c) {
-
+
/* Get data used in packet header encryption, keys and stuff. */
sock = (SilcSocketConnection)c->connection;
idata = (SilcIDListData)c;
-
+
if (!sock)
continue;
/* Send the packet */
silc_server_packet_send_to_channel_real(server, sock, &packetdata,
- idata->send_key,
- idata->hmac_send,
- idata->psn_send++,
- data, data_len, FALSE,
+ idata->send_key,
+ idata->hmac_send,
+ idata->psn_send++,
+ data, data_len, FALSE,
force_send);
silc_free(packetdata.dst_id);
/* Make sure that we send the notify only once per client. */
- sent_clients = silc_realloc(sent_clients, sizeof(*sent_clients) *
+ sent_clients = silc_realloc(sent_clients, sizeof(*sent_clients) *
(sent_clients_count + 1));
sent_clients[sent_clients_count++] = c;
}
/* Sends New ID Payload to remote end. The packet is used to distribute
information about new registered clients, servers, channel etc. usually
- to routers so that they can keep these information up to date.
+ to routers so that they can keep these information up to date.
If the argument `broadcast' is TRUE then the packet is sent as
broadcast packet. */
void silc_server_send_new_id(SilcServer server,
SilcSocketConnection sock,
bool broadcast,
- void *id, SilcIdType id_type,
+ void *id, SilcIdType id_type,
SilcUInt32 id_len)
{
SilcBuffer idp;
SILC_LOG_DEBUG(("Sending new ID"));
idp = silc_id_payload_encode(id, id_type);
- silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID,
- broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
+ silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID,
+ broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
idp->data, idp->len, FALSE);
silc_buffer_free(idp);
}
/* Send New Channel Payload to notify about newly created channel in the
- SILC network. Router uses this to notify other routers in the network
+ SILC network. Router uses this to notify other routers in the network
about new channel. This packet is broadcasted by router. */
void silc_server_send_new_channel(SilcServer server,
SilcSocketConnection sock,
bool broadcast,
char *channel_name,
- void *channel_id,
+ void *channel_id,
SilcUInt32 channel_id_len,
SilcUInt32 mode)
{
packet = silc_channel_payload_encode(channel_name, name_len,
cid, channel_id_len, mode);
- silc_server_packet_send(server, sock, SILC_PACKET_NEW_CHANNEL,
- broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
+ silc_server_packet_send(server, sock, SILC_PACKET_NEW_CHANNEL,
+ broadcast ? SILC_PACKET_FLAG_BROADCAST : 0,
packet->data, packet->len, FALSE);
silc_free(cid);
sends this to the local server who sent the join command in case where
the channel did not exist yet. Both normal and router servers uses this
also to send this to locally connected clients on the channel. This
- must not be broadcasted packet. Routers do not send this to each other.
+ must not be broadcasted packet. Routers do not send this to each other.
If `sender is provided then the packet is not sent to that connection since
it originally came from it. */
unsigned char *chid;
SilcUInt32 tmp_len;
const char *cipher;
-
+
SILC_LOG_DEBUG(("Sending key to channel %s", channel->channel_name));
-
+
chid = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
if (!chid)
return;
if (!channel->channel_key)
return;
-
+
/* Encode channel key packet */
cipher = silc_cipher_get_name(channel->channel_key);
tmp_len = strlen(cipher);
SILC_ID_CHANNEL),
chid, tmp_len, cipher,
channel->key_len / 8, channel->key);
- silc_server_packet_send_to_channel(server, sender, channel,
+ silc_server_packet_send_to_channel(server, sender, channel,
SILC_PACKET_CHANNEL_KEY,
- route, packet->data, packet->len,
+ route, packet->data, packet->len,
FALSE);
silc_buffer_free(packet);
silc_free(chid);
/* Generic function to send any command. The arguments must be sent already
encoded into correct form in correct order. */
-void silc_server_send_command(SilcServer server,
+void silc_server_send_command(SilcServer server,
SilcSocketConnection sock,
- SilcCommand command,
+ SilcCommand command,
SilcUInt16 ident,
SilcUInt32 argc, ...)
{
/* Generic function to send any command reply. The arguments must be sent
already encoded into correct form in correct order. */
-void silc_server_send_command_reply(SilcServer server,
+void silc_server_send_command_reply(SilcServer server,
SilcSocketConnection sock,
- SilcCommand command,
+ SilcCommand command,
SilcStatus status,
SilcStatus error,
SilcUInt16 ident,
/* Generic function to send any command reply. The arguments must be sent
already encoded into correct form in correct order. */
-void silc_server_send_dest_command_reply(SilcServer server,
+void silc_server_send_dest_command_reply(SilcServer server,
SilcSocketConnection sock,
void *dst_id,
SilcIdType dst_id_type,
- SilcCommand command,
+ SilcCommand command,
SilcStatus status,
SilcStatus error,
SilcUInt16 ident,
packet = silc_command_reply_payload_encode_vap(command, status, error,
ident, argc, ap);
silc_server_packet_send_dest(server, sock, SILC_PACKET_COMMAND_REPLY, 0,
- dst_id, dst_id_type, packet->data,
+ dst_id, dst_id_type, packet->data,
packet->len, FALSE);
silc_buffer_free(packet);
va_end(ap);
{
const SilcBufferStruct p;
- silc_buffer_push(packet->buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
+ silc_buffer_push(packet->buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
+ packet->dst_id_len + packet->padlen);
if (!silc_packet_send_prepare(dst_sock, 0, 0, packet->buffer->len, hmac,
(const SilcBuffer)&p)) {
/* Re-encrypt packet */
silc_packet_encrypt(cipher, hmac, sequence, (SilcBuffer)&p, p.len);
-
+
/* Send the packet */
silc_server_packet_send_real(server, dst_sock, force_send);
- silc_buffer_pull(packet->buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
+ silc_buffer_pull(packet->buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
+ packet->dst_id_len + packet->padlen);
/* Check for mandatory rekey */
void silc_server_packet_queue_purge(SilcServer server,
SilcSocketConnection sock)
{
- if (sock && SILC_IS_OUTBUF_PENDING(sock) &&
+ if (sock && SILC_IS_OUTBUF_PENDING(sock) &&
(SILC_IS_DISCONNECTED(sock) == FALSE)) {
- SILC_LOG_DEBUG(("Purging ourgoing queue"));
+ SILC_LOG_DEBUG(("Purging outgoing queue"));
server->stat.packets_sent++;
silc_packet_send(sock, TRUE);
SILC_UNSET_OUTBUF_PENDING(sock);
SilcPacketType type,
SilcPacketFlags flags,
bool route, bool local,
- unsigned char *data,
+ unsigned char *data,
SilcUInt32 data_len,
bool force_send)
{
!(client->mode & SILC_UMODE_ROUTER_OPERATOR))
goto next;
- if (server->server_type != SILC_SERVER && client->router &&
+ if (server->server_type != SILC_SERVER && client->router &&
((!route && client->router->router == server->id_entry) || route)) {
/* Check if we have sent the packet to this route already */
!(client->mode & SILC_UMODE_ROUTER_OPERATOR))
goto nextg;
- if (server->server_type != SILC_SERVER && client->router &&
+ if (server->server_type != SILC_SERVER && client->router &&
((!route && client->router->router == server->id_entry) || route)) {
/* Check if we have sent the packet to this route already */
key to the new key since all packets after this packet must
encrypted with the new key. */
silc_server_protocol_rekey_generate(server, ctx, TRUE);
+ silc_server_packet_queue_purge(server, ctx->sock);
/* The protocol ends in next stage. */
protocol->state = SILC_PROTOCOL_STATE_END;
key to the new key since all packets after this packet must
encrypted with the new key. */
silc_server_protocol_rekey_generate(server, ctx, TRUE);
+ silc_server_packet_queue_purge(server, ctx->sock);
/* The protocol ends in next stage. */
protocol->state = SILC_PROTOCOL_STATE_END;
case 2:
/*
- * Second state, used only when oding re-key with PFS.
+ * Second state, used only when doing re-key with PFS.
*/
if (ctx->responder == TRUE) {
if (ctx->pfs == TRUE) {
/*
- * Send our KE packe to the initiator now that we've processed
+ * Send our KE packet to the initiator now that we've processed
* the initiator's KE packet.
*/
status = silc_ske_responder_finish(ctx->ske, NULL, NULL,
if (SILC_PRIMARY_ROUTE(server) == sock && server->backup_router)
server->backup_noswitch = TRUE;
- if (sock->protocol && sock->protocol->protocol) {
- SILC_LOG_INFO(("Error during %d protocol",
- sock->protocol->protocol->type));
- }
-
SILC_SET_DISCONNECTING(sock);
if (sock->user_data)
silc_server_free_sock_user_data(server, sock, NULL);
process all packets synchronously, since there might be packets in
queue that we are not able to decrypt without first processing the
packets before them. */
- if ((parser_context->packet->type == SILC_PACKET_REKEY ||
- parser_context->packet->type == SILC_PACKET_REKEY_DONE) ||
- (sock->protocol && sock->protocol->protocol &&
- (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
- sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY))) {
+ if (sock->protocol && sock->protocol->protocol &&
+ (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
+ sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY)) {
silc_server_packet_parse_real(server->schedule, server, 0, sock->sock,
parser_context);
SilcProtocol protocol;
SilcServerRekeyInternalContext *proto_ctx;
+ /* If rekey protocol is active already wait for it to finish */
+ if (sock->protocol && sock->protocol->protocol &&
+ sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY)
+ return;
+
/* Allocate internal protocol context. This is sent as context
to the protocol. */
proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
/* Run the protocol */
silc_protocol_execute(protocol, server->schedule, 0, 0);
-
- SILC_LOG_DEBUG(("Rekey protocol completed"));
-
- /* Re-register re-key timeout */
- silc_schedule_task_add(server->schedule, sock->sock,
- silc_server_rekey_callback,
- context, idata->rekey->timeout, 0,
- SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
}
/* The final callback for the REKEY protocol. This will actually take the
(SilcServerRekeyInternalContext *)protocol->context;
SilcServer server = (SilcServer)ctx->server;
SilcSocketConnection sock = ctx->sock;
-
- SILC_LOG_DEBUG(("Start"));
+ SilcIDListData idata = (SilcIDListData)sock->user_data;
if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
silc_free(ctx);
/* Reconnect */
- SILC_SET_DISCONNECTING(sock);
- server->backup_noswitch = TRUE;
- if (sock->user_data)
- silc_server_free_sock_user_data(server, sock, NULL);
- silc_server_close_connection(server, sock);
+ silc_server_disconnect_remote(server, sock,
+ SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL);
silc_server_create_connections(server);
return;
}
+ SILC_LOG_DEBUG(("Rekey protocol completed"));
+
/* Purge the outgoing data queue to assure that all rekey packets really
go to the network before we quit the protocol. */
silc_server_packet_queue_purge(server, sock);
+ /* Re-register re-key timeout */
+ if (ctx->responder == FALSE)
+ silc_schedule_task_add(server->schedule, sock->sock,
+ silc_server_rekey_callback,
+ sock, idata->rekey->timeout, 0,
+ SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
+
/* Cleanup */
silc_protocol_free(protocol);
sock->protocol = NULL;
SilcServer server = (SilcServer)context;
SilcBuffer idp, packet;
- SILC_LOG_DEBUG(("Retrieving stats from router"));
-
if (!server->standalone) {
+ SILC_LOG_DEBUG(("Retrieving stats from router"));
idp = silc_id_payload_encode(server->router->id, SILC_ID_SERVER);
packet = silc_command_payload_encode_va(SILC_COMMAND_STATS,
++server->cmd_ident, 1,
/*
- server_backup.c
+ server_backup.c
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 2001 - 2002 Pekka Riikonen
+ Copyright (C) 2001 - 2003 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
/* Returns backup router for IP and port in `replacing' or NULL if there
does not exist backup router. */
-SilcServerEntry silc_server_backup_get(SilcServer server,
+SilcServerEntry silc_server_backup_get(SilcServer server,
SilcServerID *server_id)
{
int i;
a later time we can check whether it has been replaced by an backup
router. */
-void silc_server_backup_replaced_add(SilcServer server,
+void silc_server_backup_replaced_add(SilcServer server,
SilcServerID *server_id,
SilcServerEntry server_entry)
{
if (!server->backup)
server->backup = silc_calloc(1, sizeof(*server->backup));
if (!server->backup->replaced) {
- server->backup->replaced =
+ server->backup->replaced =
silc_calloc(1, sizeof(*server->backup->replaced));
server->backup->replaced_count = 1;
}
}
}
-/* Broadcast the received packet indicated by `packet' to all of our backup
- routers. All router wide information is passed using broadcast packets.
+/* Broadcast the received packet indicated by `packet' to all of our backup
+ routers. All router wide information is passed using broadcast packets.
That is why all backup routers need to get this data too. It is expected
that the caller already knows that the `packet' is broadcast packet. */
-void silc_server_backup_broadcast(SilcServer server,
+void silc_server_backup_broadcast(SilcServer server,
SilcSocketConnection sender,
SilcPacketContext *packet)
{
for (i = 0; i < server->backup->servers_count; i++) {
backup = server->backup->servers[i].server;
- if (!backup || backup->connection == sender ||
+ if (!backup || backup->connection == sender ||
server->backup->servers[i].local == FALSE)
continue;
if (server->backup->servers[i].server == server->id_entry)
return;
}
silc_buffer_put((SilcBuffer)&p, buffer->data, buffer->len);
- silc_packet_encrypt(idata->send_key, idata->hmac_send, idata->psn_send++,
+ silc_packet_encrypt(idata->send_key, idata->hmac_send, idata->psn_send++,
(SilcBuffer)&p, p.len);
SILC_LOG_HEXDUMP(("Broadcasted packet, len %d", p.len), p.data, p.len);
SILC_LOG_DEBUG(("Sending %s packet to backup router %s (%s)",
silc_get_packet_name(type), sock->hostname, sock->ip));
- silc_server_packet_send(server, backup->connection, type, flags,
+ silc_server_packet_send(server, backup->connection, type, flags,
data, data_len, force_send);
}
}
SILC_LOG_DEBUG(("Sending %s packet to backup router %s (%s)",
silc_get_packet_name(type), sock->hostname, sock->ip));
- silc_server_packet_send_dest(server, backup->connection, type, flags,
- dst_id, dst_id_type, data, data_len,
+ silc_server_packet_send_dest(server, backup->connection, type, flags,
+ dst_id, dst_id_type, data, data_len,
force_send);
}
}
for processing to the protocol handler or allocate new protocol if
start command is received. */
-void silc_server_backup_resume_router(SilcServer server,
- SilcSocketConnection sock,
+void silc_server_backup_resume_router(SilcServer server,
+ SilcSocketConnection sock,
SilcPacketContext *packet)
{
SilcUInt8 type, session;
SILC_LOG_ERROR(("Malformed resume router packet received"));
return;
}
-
+
/* Activate the protocol for this socket if necessary */
- if ((type == SILC_SERVER_BACKUP_RESUMED ||
+ if ((type == SILC_SERVER_BACKUP_RESUMED ||
type == SILC_SERVER_BACKUP_RESUMED_GLOBAL) &&
- sock->type == SILC_SOCKET_TYPE_ROUTER && !sock->protocol &&
- ((SilcIDListData)sock->user_data)->status &
+ sock->type == SILC_SOCKET_TYPE_ROUTER && !sock->protocol &&
+ ((SilcIDListData)sock->user_data)->status &
SILC_IDLIST_STATUS_DISABLED) {
SilcServerEntry backup_router;
- if (silc_server_backup_replaced_get(server,
+ if (silc_server_backup_replaced_get(server,
((SilcServerEntry)sock->
- user_data)->id,
+ user_data)->id,
&backup_router)) {
- SilcSocketConnection bsock =
+ SilcSocketConnection bsock =
(SilcSocketConnection)backup_router->connection;
if (bsock->protocol && bsock->protocol->protocol &&
bsock->protocol->protocol->type == SILC_PROTOCOL_SERVER_BACKUP) {
return;
}
- /* We don't have protocol active. If we are router and the packet is
+ /* We don't have protocol active. If we are router and the packet is
coming from our primary router then lets check whether it means we've
been replaced by an backup router in my cell. This is usually received
immediately after we've connected to our primary router. */
/* Run the backup resuming protocol */
silc_protocol_alloc(SILC_PROTOCOL_SERVER_BACKUP,
- &sock->protocol, proto_ctx,
+ &sock->protocol, proto_ctx,
silc_server_protocol_backup_done);
silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
silc_schedule_task_add(server->schedule, sock->sock,
if (sock < 0) {
silc_schedule_task_add(server->schedule, 0,
silc_server_backup_connect_to_router,
- context, 5, 0, SILC_TASK_TIMEOUT,
+ context, 5, 0, SILC_TASK_TIMEOUT,
SILC_TASK_PRI_NORMAL);
return;
}
sconn->callback = callback;
sconn->callback_context = context;
sconn->no_reconnect = TRUE;
- silc_schedule_task_add(server->schedule, 0,
+ silc_schedule_task_add(server->schedule, 0,
silc_server_backup_connect_to_router,
sconn, 1, 0, SILC_TASK_TIMEOUT,
SILC_TASK_PRI_NORMAL);
SILC_TASK_CALLBACK(silc_server_backup_connected_later)
{
- SilcServerBackupProtocolContext proto_ctx =
+ SilcServerBackupProtocolContext proto_ctx =
(SilcServerBackupProtocolContext)context;
SilcServer server = proto_ctx->server;
SilcSocketConnection sock = proto_ctx->sock;
/* Run the backup resuming protocol */
silc_protocol_alloc(SILC_PROTOCOL_SERVER_BACKUP,
- &sock->protocol, proto_ctx,
+ &sock->protocol, proto_ctx,
silc_server_protocol_backup_done);
silc_protocol_execute(sock->protocol, server->schedule, 0, 0);
SILC_STR_UI_CHAR(SILC_SERVER_BACKUP_CONNECTED),
SILC_STR_UI_CHAR(ctx->session),
SILC_STR_END);
- silc_server_packet_send(server, backup_router,
- SILC_PACKET_RESUME_ROUTER, 0,
+ silc_server_packet_send(server, backup_router,
+ SILC_PACKET_RESUME_ROUTER, 0,
buffer->data, buffer->len, FALSE);
silc_buffer_free(buffer);
/* Move this protocol context from this backup router connection to
the primary router connection since it will send the subsequent
- packets in this protocol. We don't talk with backup router
+ packets in this protocol. We don't talk with backup router
anymore. */
sock->protocol = backup_router->protocol;
ctx->sock = (SilcSocketConnection)server_entry->connection;
for (i = 0; i < ctx->sessions_count; i++)
if (ctx->sessions[i].server_entry == ctx->sock->user_data)
ctx->session = ctx->sessions[i].session;
-
+
/* We've received all the CONNECTED packets and now we'll send the
ENDING packet to the new primary router. */
packet = silc_buffer_alloc(2);
SILC_STR_UI_CHAR(SILC_SERVER_BACKUP_ENDING),
SILC_STR_UI_CHAR(ctx->session),
SILC_STR_END);
- silc_server_packet_send(server, ctx->sock,
- SILC_PACKET_RESUME_ROUTER, 0,
+ silc_server_packet_send(server, ctx->sock,
+ SILC_PACKET_RESUME_ROUTER, 0,
packet->data, packet->len, FALSE);
silc_buffer_free(packet);
-
+
protocol->state = SILC_PROTOCOL_STATE_END;
}
if (silc_idcache_list_first(list, &id_cache)) {
while (id_cache) {
server_entry = (SilcServerEntry)id_cache->context;
- if (!server_entry || (server_entry == server->id_entry) ||
+ if (!server_entry || (server_entry == server->id_entry) ||
!server_entry->connection || !server_entry->data.send_key ||
(server_entry->data.status & SILC_IDLIST_STATUS_DISABLED)) {
if (!silc_idcache_list_next(list, &id_cache))
packet->data[0] = SILC_SERVER_BACKUP_START_GLOBAL;
packet->data[1] = ctx->sessions_count;
silc_server_packet_send(server, server_entry->connection,
- SILC_PACKET_RESUME_ROUTER, 0,
+ SILC_PACKET_RESUME_ROUTER, 0,
packet->data, packet->len, FALSE);
ctx->sessions_count++;
if (silc_idcache_list_first(list, &id_cache)) {
while (id_cache) {
server_entry = (SilcServerEntry)id_cache->context;
- if (!server_entry || (server_entry == server->id_entry) ||
+ if (!server_entry || (server_entry == server->id_entry) ||
!server_entry->connection || !server_entry->data.send_key ||
(server_entry->data.status & SILC_IDLIST_STATUS_DISABLED)) {
if (!silc_idcache_list_next(list, &id_cache))
ctx->sessions[ctx->sessions_count].connected = FALSE;
ctx->sessions[ctx->sessions_count].server_entry = server_entry;
- SILC_LOG_DEBUG(("Sending START to %s (session %d)",
+ SILC_LOG_DEBUG(("Sending START to %s (session %d)",
server_entry->server_name, ctx->sessions_count));
SILC_LOG_INFO(("Expecting CONNECTED from %s (session %d)",
server_entry->server_name, ctx->sessions_count));
packet->data[0] = SILC_SERVER_BACKUP_START_GLOBAL;
packet->data[1] = ctx->sessions_count;
silc_server_packet_send(server, server_entry->connection,
- SILC_PACKET_RESUME_ROUTER, 0,
+ SILC_PACKET_RESUME_ROUTER, 0,
packet->data, packet->len, FALSE);
ctx->sessions_count++;
SILC_STR_UI_CHAR(SILC_SERVER_BACKUP_CONNECTED),
SILC_STR_UI_CHAR(ctx->session),
SILC_STR_END);
- silc_server_packet_send(server, ctx->sock,
- SILC_PACKET_RESUME_ROUTER, 0,
+ silc_server_packet_send(server, ctx->sock,
+ SILC_PACKET_RESUME_ROUTER, 0,
packet->data, packet->len, FALSE);
silc_buffer_free(packet);
}
if (server->server_type == SILC_ROUTER &&
- (!server->router ||
+ (!server->router ||
server->router->data.status & SILC_IDLIST_STATUS_DISABLED))
protocol->state++;
else
SILC_LOG_DEBUG(("Sending ENDING packet to primary router"));
/* Send with a timeout */
- silc_schedule_task_add(server->schedule, 0,
+ silc_schedule_task_add(server->schedule, 0,
silc_server_backup_send_resumed,
protocol, 1, 0, SILC_TASK_TIMEOUT,
SILC_TASK_PRI_NORMAL);
/* Switch announced informations to our primary router of using the
backup router. */
silc_server_local_servers_toggle_enabled(server, TRUE);
- silc_server_update_servers_by_server(server, ctx->sock->user_data,
+ silc_server_update_servers_by_server(server, ctx->sock->user_data,
server->router);
silc_server_update_clients_by_server(server, ctx->sock->user_data,
server->router, TRUE);
if (server->server_type == SILC_SERVER)
- silc_server_update_channels_by_server(server, ctx->sock->user_data,
+ silc_server_update_channels_by_server(server, ctx->sock->user_data,
server->router);
packet = silc_buffer_alloc(2);
if (silc_idcache_list_first(list, &id_cache)) {
while (id_cache) {
server_entry = (SilcServerEntry)id_cache->context;
- if (!server_entry || (server_entry == server->id_entry) ||
+ if (!server_entry || (server_entry == server->id_entry) ||
!server_entry->connection || !server_entry->data.send_key) {
if (!silc_idcache_list_next(list, &id_cache))
break;
else
packet->data[0] = SILC_SERVER_BACKUP_RESUMED_GLOBAL;
silc_server_packet_send(server, server_entry->connection,
- SILC_PACKET_RESUME_ROUTER, 0,
+ SILC_PACKET_RESUME_ROUTER, 0,
packet->data, packet->len, FALSE);
if (!silc_idcache_list_next(list, &id_cache))
if (silc_idcache_list_first(list, &id_cache)) {
while (id_cache) {
server_entry = (SilcServerEntry)id_cache->context;
- if (!server_entry || (server_entry == server->id_entry) ||
+ if (!server_entry || (server_entry == server->id_entry) ||
!server_entry->connection || !server_entry->data.send_key) {
if (!silc_idcache_list_next(list, &id_cache))
break;
else
packet->data[0] = SILC_SERVER_BACKUP_RESUMED_GLOBAL;
silc_server_packet_send(server, server_entry->connection,
- SILC_PACKET_RESUME_ROUTER, 0,
+ SILC_PACKET_RESUME_ROUTER, 0,
packet->data, packet->len, FALSE);
if (!silc_idcache_list_next(list, &id_cache))
/* We have now new primary router. All traffic goes there from now on. */
router = (SilcServerEntry)ctx->sock->user_data;
- if (silc_server_backup_replaced_get(server, router->id,
+ if (silc_server_backup_replaced_get(server, router->id,
&backup_router)) {
if (backup_router == server->router) {
}
server->backup_primary = FALSE;
- /* Update the client entries of the backup router to the new
+ /* Update the client entries of the backup router to the new
router */
silc_server_local_servers_toggle_enabled(server, FALSE);
router->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
if (ctx->sock == sock)
ctx->sock = NULL;
- if (sock->user_data)
- silc_server_free_sock_user_data(server, sock, NULL);
- silc_server_close_connection(server, sock);
+ silc_server_disconnect_remote(server, sock, 0, NULL);
silc_server_create_connections(server);
if (!silc_idcache_list_next(list, &id_cache))
if (server_entry->data.status & SILC_IDLIST_STATUS_DISABLED)
server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
}
-
+
if (!silc_idcache_list_next(list, &id_cache))
break;
}
if (ctx->sock == sock)
ctx->sock = NULL;
- if (sock->user_data)
- silc_server_free_sock_user_data(server, sock, NULL);
- silc_server_close_connection(server, sock);
+ silc_server_disconnect_remote(server, sock, 0, NULL);
silc_server_create_connections(server);
if (!silc_idcache_list_next(list, &id_cache))
if (server_entry->data.status & SILC_IDLIST_STATUS_DISABLED)
server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
}
-
+
if (!silc_idcache_list_next(list, &id_cache))
break;
}
/*
- client.c
+ client.c
Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 1997 - 2002 Pekka Riikonen
+ Copyright (C) 1997 - 2003 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
static bool silc_client_packet_parse(SilcPacketParserContext *parser_context,
void *context);
-static void silc_client_packet_parse_type(SilcClient client,
+static void silc_client_packet_parse_type(SilcClient client,
SilcSocketConnection sock,
SilcPacketContext *packet);
void silc_client_resolve_auth_method(bool success,
the client. The `application' is application specific user data pointer
and caller must free it. */
-SilcClient silc_client_alloc(SilcClientOperations *ops,
+SilcClient silc_client_alloc(SilcClientOperations *ops,
SilcClientParams *params,
void *application,
const char *version_string)
new_client->internal = silc_calloc(1, sizeof(*new_client->internal));
new_client->internal->ops = ops;
- new_client->internal->params =
+ new_client->internal->params =
silc_calloc(1, sizeof(*new_client->internal->params));
if (!version_string)
version_string = silc_version_string;
silc_client_protocols_register();
/* Initialize the scheduler */
- client->schedule =
+ client->schedule =
silc_schedule_init(client->internal->params->task_max ?
client->internal->params->task_max : 200, client);
if (!client->schedule)
connection to the connection table and returns a pointer to it. A client
can have multiple connections to multiple servers. Every connection must
be added to the client using this function. User data `context' may
- be sent as argument. This function is normally used only if the
+ be sent as argument. This function is normally used only if the
application performed the connecting outside the library. The library
however may use this internally. */
return conn;
}
- client->internal->conns =
+ client->internal->conns =
silc_realloc(client->internal->conns, sizeof(*client->internal->conns)
* (client->internal->conns_count + 1));
client->internal->conns[client->internal->conns_count] = conn;
int i;
if (!client->internal->sockets) {
- client->internal->sockets =
+ client->internal->sockets =
silc_calloc(1, sizeof(*client->internal->sockets));
client->internal->sockets[0] = silc_socket_dup(sock);
client->internal->sockets_count = 1;
}
}
- client->internal->sockets =
- silc_realloc(client->internal->sockets,
+ client->internal->sockets =
+ silc_realloc(client->internal->sockets,
sizeof(*client->internal->sockets) *
(client->internal->sockets_count + 1));
- client->internal->sockets[client->internal->sockets_count] =
+ client->internal->sockets[client->internal->sockets_count] =
silc_socket_dup(sock);
client->internal->sockets_count++;
}
}
}
-static int
+static int
silc_client_connect_to_server_internal(SilcClientInternalConnectContext *ctx)
{
int sock;
/* Register task that will receive the async connect and will
read the result. */
- ctx->task = silc_schedule_task_add(ctx->client->schedule, sock,
+ ctx->task = silc_schedule_task_add(ctx->client->schedule, sock,
silc_client_connect_to_server_start,
- (void *)ctx, 0, 0,
+ (void *)ctx, 0, 0,
SILC_TASK_FD,
SILC_TASK_PRI_NORMAL);
silc_schedule_set_listen_fd(ctx->client->schedule, sock, SILC_TASK_WRITE,
}
/* Connects to remote server. This is the main routine used to connect
- to SILC server. Returns -1 on error and the created socket otherwise.
+ to SILC server. Returns -1 on error and the created socket otherwise.
The `context' is user context that is saved into the SilcClientConnection
that is created after the connection is created. Note that application
may handle the connecting process outside the library. If this is the
conn = silc_client_add_connection(client, params, host, port, context);
- client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
+ client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
"Connecting to port %d of server %s", port, host);
/* Allocate internal context for connection process. This is
/* Perform key exchange protocol. silc_client_connect_to_server_final
will be called after the protocol is finished. */
- silc_protocol_alloc(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
+ silc_protocol_alloc(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
&protocol, (void *)proto_ctx,
silc_client_connect_to_server_second);
if (!protocol) {
conn->sock->protocol = protocol;
/* Register the connection for network input and output. This sets
- that scheduler will listen for incoming packets for this connection
+ that scheduler will listen for incoming packets for this connection
and sets that outgoing packets may be sent to this connection as well.
- However, this doesn't set the scheduler for outgoing traffic, it will
+ However, this doesn't set the scheduler for outgoing traffic, it will
be set separately by calling SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT,
later when outgoing data is available. */
context = (void *)client;
silc_socket_alloc(fd, SILC_SOCKET_TYPE_SERVER, (void *)conn, &conn->sock);
/* Sometimes when doing quick reconnects the new socket may be same as
- the old one and there might be pending stuff for the old socket.
+ the old one and there might be pending stuff for the old socket.
If new one is same then those pending sutff might cause problems.
Make sure they do not do that. */
silc_schedule_task_del_by_fd(client->schedule, fd);
SILC_TASK_CALLBACK(silc_client_connect_failure)
{
- SilcClientKEInternalContext *ctx =
+ SilcClientKEInternalContext *ctx =
(SilcClientKEInternalContext *)context;
SilcClient client = (SilcClient)ctx->client;
- client->internal->ops->connected(client, ctx->sock->user_data,
+ client->internal->ops->connected(client, ctx->sock->user_data,
SILC_CLIENT_CONN_ERROR);
if (ctx->packet)
silc_packet_context_free(ctx->packet);
(SilcClientConnAuthInternalContext *)context;
SilcClient client = (SilcClient)ctx->client;
- client->internal->ops->connected(client, ctx->sock->user_data,
+ client->internal->ops->connected(client, ctx->sock->user_data,
SILC_CLIENT_CONN_ERROR);
silc_free(ctx);
}
client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
"Could not connect to server %s: %s",
ctx->host, strerror(opt));
- client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
- "Connecting to port %d of server %s resumed",
+ client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
+ "Connecting to port %d of server %s resumed",
ctx->port, ctx->host);
/* Unregister old connection try */
silc_client_start_key_exchange(client, conn, fd);
}
-/* Second part of the connecting to the server. This executed
+/* Second part of the connecting to the server. This executed
authentication protocol. */
SILC_TASK_CALLBACK(silc_client_connect_to_server_second)
{
SilcProtocol protocol = (SilcProtocol)context;
- SilcClientKEInternalContext *ctx =
+ SilcClientKEInternalContext *ctx =
(SilcClientKEInternalContext *)protocol->context;
SilcClient client = (SilcClient)ctx->client;
SilcSocketConnection sock = NULL;
/* Resolve the authentication method to be used in this connection. The
completion callback is called after the application has resolved
the authentication method. */
- client->internal->ops->get_auth_method(client, sock->user_data,
+ client->internal->ops->get_auth_method(client, sock->user_data,
sock->hostname,
- sock->port,
+ sock->port,
silc_client_resolve_auth_method,
proto_ctx);
}
/* Authentication method resolving callback. Application calls this function
- after we've called the client->internal->ops->get_auth_method
+ after we've called the client->internal->ops->get_auth_method
client operation to resolve the authentication method. We will continue
the executiong of the protocol in this function. */
if (success && auth_data && auth_data_len) {
/* Passphrase must be UTF-8 encoded, if it isn't encode it */
- if (auth_meth == SILC_AUTH_PASSWORD &&
+ if (auth_meth == SILC_AUTH_PASSWORD &&
!silc_utf8_valid(auth_data, auth_data_len)) {
int payload_len = 0;
unsigned char *autf8 = NULL;
- payload_len = silc_utf8_encoded_len(auth_data, auth_data_len,
+ payload_len = silc_utf8_encoded_len(auth_data, auth_data_len,
SILC_STRING_ASCII);
autf8 = silc_calloc(payload_len, sizeof(*autf8));
- auth_data_len = silc_utf8_encode(auth_data, auth_data_len,
+ auth_data_len = silc_utf8_encode(auth_data, auth_data_len,
SILC_STRING_ASCII, autf8, payload_len);
auth_data = autf8;
}
}
/* Allocate the authenteication protocol and execute it. */
- silc_protocol_alloc(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
- &proto_ctx->sock->protocol, (void *)proto_ctx,
+ silc_protocol_alloc(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
+ &proto_ctx->sock->protocol, (void *)proto_ctx,
silc_client_connect_to_server_final);
/* Execute the protocol */
SILC_TASK_CALLBACK(silc_client_connect_to_server_final)
{
SilcProtocol protocol = (SilcProtocol)context;
- SilcClientConnAuthInternalContext *ctx =
+ SilcClientConnAuthInternalContext *ctx =
(SilcClientConnAuthInternalContext *)protocol->context;
SilcClient client = (SilcClient)ctx->client;
SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
/* Send the packet */
silc_client_packet_send(client, ctx->sock, SILC_PACKET_RESUME_CLIENT,
- NULL, 0, NULL, NULL,
+ NULL, 0, NULL, NULL,
packet->data, packet->len, TRUE);
silc_buffer_free(packet);
silc_buffer_free(auth);
/* Send NEW_CLIENT packet to the server. We will become registered
to the SILC network after sending this packet and we will receive
client ID from the server. */
- packet = silc_buffer_alloc(2 + 2 + strlen(client->username) +
+ packet = silc_buffer_alloc(2 + 2 + strlen(client->username) +
strlen(client->realname));
silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
silc_buffer_format(packet,
/* Send the packet */
silc_client_packet_send(client, ctx->sock, SILC_PACKET_NEW_CLIENT,
- NULL, 0, NULL, NULL,
+ NULL, 0, NULL, NULL,
packet->data, packet->len, TRUE);
silc_buffer_free(packet);
}
/* Register re-key timeout */
conn->internal->rekey->timeout = client->internal->params->rekey_secs;
conn->internal->rekey->context = (void *)client;
- silc_schedule_task_add(client->schedule, conn->sock->sock,
+ silc_schedule_task_add(client->schedule, conn->sock->sock,
silc_client_rekey_callback,
(void *)conn->sock, conn->internal->rekey->timeout, 0,
SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
if (ret != -2)
return ret;
- /* Mark that there is some outgoing data available for this connection.
+ /* Mark that there is some outgoing data available for this connection.
This call sets the connection both for input and output (the input
- is set always and this call keeps the input setting, actually).
+ is set always and this call keeps the input setting, actually).
Actual data sending is performed by silc_client_packet_process. */
SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(client->schedule, sock->sock);
/* Error */
if (ret == -1)
return;
-
+
/* The packet has been sent and now it is time to set the connection
- back to only for input. When there is again some outgoing data
- available for this connection it will be set for output as well.
+ back to only for input. When there is again some outgoing data
+ available for this connection it will be set for output as well.
This call clears the output setting and sets it only for input. */
SILC_CLIENT_SET_CONNECTION_FOR_INPUT(client->schedule, fd);
SILC_UNSET_OUTBUF_PENDING(sock);
ret = silc_packet_receive(sock);
if (ret < 0)
return;
-
+
/* EOF */
if (ret == 0) {
SILC_LOG_DEBUG(("Read EOF"));
silc_client_close_connection_real(client, sock, conn);
return;
}
-
+
SILC_LOG_DEBUG(("EOF from connection %d", sock->sock));
if (sock == conn->sock && sock->type != SILC_SOCKET_TYPE_CLIENT)
client->internal->ops->disconnected(client, conn, 0, NULL);
/* Process the packet. This will call the parser that will then
decrypt and parse the packet. */
if (sock->type != SILC_SOCKET_TYPE_UNKNOWN)
- silc_packet_receive_process(sock, FALSE, conn->internal->receive_key,
+ silc_packet_receive_process(sock, FALSE, conn->internal->receive_key,
conn->internal->hmac_receive,
conn->internal->psn_receive,
silc_client_packet_parse, client);
else
- silc_packet_receive_process(sock, FALSE, NULL, NULL, 0,
+ silc_packet_receive_process(sock, FALSE, NULL, NULL, 0,
silc_client_packet_parse, client);
}
}
silc_free(parser_context);
return FALSE;
}
-
+
/* If protocol for this connection is key exchange or rekey then we'll
process all packets synchronously, since there might be packets in
queue that we are not able to decrypt without first processing the
packets before them. */
- if ((ret == SILC_PACKET_REKEY || ret == SILC_PACKET_REKEY_DONE) ||
- (sock->protocol && sock->protocol->protocol &&
- (sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE ||
- sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY))) {
+ if (sock->protocol && sock->protocol->protocol &&
+ (sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE ||
+ sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY)) {
/* Parse the incoming packet type */
silc_client_packet_parse_type(client, sock, packet);
the `conn->internal->receive_key' might have become valid by processing
the previous packet */
if (sock->type != SILC_SOCKET_TYPE_UNKNOWN)
- silc_packet_receive_process(sock, FALSE, conn->internal->receive_key,
+ silc_packet_receive_process(sock, FALSE, conn->internal->receive_key,
conn->internal->hmac_receive,
conn->internal->psn_receive,
silc_client_packet_parse, client);
else
- silc_packet_receive_process(sock, FALSE, NULL, NULL, 0,
+ silc_packet_receive_process(sock, FALSE, NULL, NULL, 0,
silc_client_packet_parse, client);
-
+
return FALSE;
}
/* Parses the packet type and calls what ever routines the packet type
requires. This is done for all incoming packets. */
-void silc_client_packet_parse_type(SilcClient client,
+void silc_client_packet_parse_type(SilcClient client,
SilcSocketConnection sock,
SilcPacketContext *packet)
{
case SILC_PACKET_FAILURE:
/*
- * Failure received for some protocol. Set the protocol state to
+ * Failure received for some protocol. Set the protocol state to
* error and call the protocol callback. This fill cause error on
* protocol and it will call the final callback.
*/
case SILC_PACKET_NOTIFY:
/*
- * Received notify message
+ * Received notify message
*/
silc_client_notify_by_server(client, sock, packet);
break;
break;
case SILC_PACKET_KEY_EXCHANGE:
- if (sock->protocol && sock->protocol->protocol &&
+ if (sock->protocol && sock->protocol->protocol &&
sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE) {
- SilcClientKEInternalContext *proto_ctx =
+ SilcClientKEInternalContext *proto_ctx =
(SilcClientKEInternalContext *)sock->protocol->context;
proto_ctx->packet = silc_packet_context_dup(packet);
break;
case SILC_PACKET_KEY_EXCHANGE_1:
- if (sock->protocol && sock->protocol->protocol &&
+ if (sock->protocol && sock->protocol->protocol &&
(sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE ||
sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY)) {
if (sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY) {
- SilcClientRekeyInternalContext *proto_ctx =
+ SilcClientRekeyInternalContext *proto_ctx =
(SilcClientRekeyInternalContext *)sock->protocol->context;
-
+
if (proto_ctx->packet)
silc_packet_context_free(proto_ctx->packet);
-
+
proto_ctx->packet = silc_packet_context_dup(packet);
/* Let the protocol handle the packet */
silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
} else {
- SilcClientKEInternalContext *proto_ctx =
+ SilcClientKEInternalContext *proto_ctx =
(SilcClientKEInternalContext *)sock->protocol->context;
-
+
if (proto_ctx->packet)
silc_packet_context_free(proto_ctx->packet);
-
+
proto_ctx->packet = silc_packet_context_dup(packet);
proto_ctx->dest_id_type = packet->src_id_type;
proto_ctx->dest_id = silc_id_str2id(packet->src_id, packet->src_id_len,
packet->src_id_type);
if (!proto_ctx->dest_id)
break;
-
+
/* Let the protocol handle the packet */
silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
}
break;
case SILC_PACKET_KEY_EXCHANGE_2:
- if (sock->protocol && sock->protocol->protocol &&
+ if (sock->protocol && sock->protocol->protocol &&
(sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE ||
sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY)) {
if (sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY) {
- SilcClientRekeyInternalContext *proto_ctx =
+ SilcClientRekeyInternalContext *proto_ctx =
(SilcClientRekeyInternalContext *)sock->protocol->context;
-
+
if (proto_ctx->packet)
silc_packet_context_free(proto_ctx->packet);
-
+
proto_ctx->packet = silc_packet_context_dup(packet);
/* Let the protocol handle the packet */
silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
} else {
- SilcClientKEInternalContext *proto_ctx =
+ SilcClientKEInternalContext *proto_ctx =
(SilcClientKEInternalContext *)sock->protocol->context;
-
+
if (proto_ctx->packet)
silc_packet_context_free(proto_ctx->packet);
if (proto_ctx->dest_id)
packet->src_id_type);
if (!proto_ctx->dest_id)
break;
-
+
/* Let the protocol handle the packet */
silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
}
{
/*
* Received new ID from server. This packet is received at
- * the connection to the server. New ID is also received when
+ * the connection to the server. New ID is also received when
* user changes nickname but in that case the new ID is received
* as command reply and not as this packet type.
*/
case SILC_PACKET_REKEY_DONE:
SILC_LOG_DEBUG(("Re-key done packet"));
- if (sock->protocol && sock->protocol->protocol &&
+ if (sock->protocol && sock->protocol->protocol &&
sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY) {
- SilcClientRekeyInternalContext *proto_ctx =
+ SilcClientRekeyInternalContext *proto_ctx =
(SilcClientRekeyInternalContext *)sock->protocol->context;
-
+
if (proto_ctx->packet)
silc_packet_context_free(proto_ctx->packet);
-
+
proto_ctx->packet = silc_packet_context_dup(packet);
/* Let the protocol handle the packet */
silc_protocol_execute(sock->protocol, client->schedule, 0, 0);
else
/* Let the protocol handle the packet */
- silc_protocol_execute(sock->protocol, client->schedule,
+ silc_protocol_execute(sock->protocol, client->schedule,
0, 100000);
} else {
SILC_LOG_ERROR(("Received Re-key done packet but no re-key "
will be derived from sock argument. Otherwise the valid arguments sent
are used. */
-void silc_client_packet_send(SilcClient client,
+void silc_client_packet_send(SilcClient client,
SilcSocketConnection sock,
- SilcPacketType type,
+ SilcPacketType type,
void *dst_id,
SilcIdType dst_id_type,
SilcCipher cipher,
SilcHmac hmac,
- unsigned char *data,
- SilcUInt32 data_len,
+ unsigned char *data,
+ SilcUInt32 data_len,
bool force_send)
{
SilcPacketContext packetdata;
/* Set the packet context pointers */
packetdata.flags = 0;
packetdata.type = type;
- if (sock->user_data &&
+ if (sock->user_data &&
((SilcClientConnection)sock->user_data)->local_id_data) {
packetdata.src_id = ((SilcClientConnection)sock->user_data)->local_id_data;
- packetdata.src_id_len =
+ packetdata.src_id_len =
silc_id_get_len(((SilcClientConnection)sock->user_data)->local_id,
SILC_ID_CLIENT);
- } else {
+ } else {
packetdata.src_id = silc_calloc(SILC_ID_CLIENT_LEN, sizeof(unsigned char));
packetdata.src_id_len = SILC_ID_CLIENT_LEN;
}
packetdata.dst_id_type = SILC_ID_NONE;
}
data_len = SILC_PACKET_DATALEN(data_len, (SILC_PACKET_HEADER_LEN +
- packetdata.src_id_len +
+ packetdata.src_id_len +
packetdata.dst_id_len));
- packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN +
+ packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN +
packetdata.src_id_len + packetdata.dst_id_len;
if (type == SILC_PACKET_CONNECTION_AUTH)
SILC_PACKET_PADLEN_MAX(packetdata.truelen, block_len, packetdata.padlen);
SILC_PACKET_PADLEN(packetdata.truelen, block_len, packetdata.padlen);
/* Create the outgoing packet */
- if (!silc_packet_assemble(&packetdata, client->rng, cipher, hmac, sock,
+ if (!silc_packet_assemble(&packetdata, client->rng, cipher, hmac, sock,
data, data_len, (const SilcBuffer)&packet)) {
SILC_LOG_ERROR(("Error assembling packet"));
return;
/* Encrypt the packet */
if (cipher)
- silc_packet_encrypt(cipher, hmac, sequence, (SilcBuffer)&packet,
+ silc_packet_encrypt(cipher, hmac, sequence, (SilcBuffer)&packet,
packet.len);
SILC_LOG_HEXDUMP(("Packet (%d), len %d", sequence, packet.len),
void silc_client_packet_queue_purge(SilcClient client,
SilcSocketConnection sock)
{
- if (sock && SILC_IS_OUTBUF_PENDING(sock) &&
+ if (sock && SILC_IS_OUTBUF_PENDING(sock) &&
(SILC_IS_DISCONNECTED(sock) == FALSE)) {
silc_packet_send(sock, TRUE);
- SILC_CLIENT_SET_CONNECTION_FOR_INPUT(client->schedule, sock->sock);
SILC_UNSET_OUTBUF_PENDING(sock);
+ SILC_CLIENT_SET_CONNECTION_FOR_INPUT(client->schedule, sock->sock);
silc_buffer_clear(sock->outbuf);
}
}
/* Closes connection to remote end. Free's all allocated data except
- for some information such as nickname etc. that are valid at all time.
+ for some information such as nickname etc. that are valid at all time.
If the `sock' is NULL then the conn->sock will be used. If `sock' is
provided it will be checked whether the sock and `conn->sock' are the
same (they can be different, ie. a socket can use `conn' as its
/* Cancel any active protocol */
if (sock->protocol) {
- if (sock->protocol->protocol->type ==
+ if (sock->protocol->protocol->type ==
SILC_PROTOCOL_CLIENT_KEY_EXCHANGE ||
- sock->protocol->protocol->type ==
+ sock->protocol->protocol->type ==
SILC_PROTOCOL_CLIENT_CONNECTION_AUTH) {
sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
silc_protocol_execute_final(sock->protocol, client->schedule);
silc_client_close_connection_real(client, NULL, conn);
}
-/* Called when we receive disconnection packet from server. This
+/* Called when we receive disconnection packet from server. This
closes our end properly and displays the reason of the disconnection
on the screen. */
silc_client_close_connection_real(client, sock, sock->user_data);
}
-/* Called when we receive disconnection packet from server. This
+/* Called when we receive disconnection packet from server. This
closes our end properly and displays the reason of the disconnection
on the screen. */
SILC_SET_DISCONNECTED(sock);
/* Close connection through scheduler. */
- silc_schedule_task_add(client->schedule, sock->sock,
+ silc_schedule_task_add(client->schedule, sock->sock,
silc_client_disconnected_by_server_later,
- client, 0, 1, SILC_TASK_TIMEOUT,
+ client, 0, 1, SILC_TASK_TIMEOUT,
SILC_TASK_PRI_NORMAL);
}
-/* Received error message from server. Display it on the screen.
+/* Received error message from server. Display it on the screen.
We don't take any action what so ever of the error message. */
void silc_client_error_by_server(SilcClient client,
char *msg;
msg = silc_memdup(message->data, message->len);
- client->internal->ops->say(client, sock->user_data,
+ client->internal->ops->say(client, sock->user_data,
SILC_CLIENT_MESSAGE_AUDIT, msg);
silc_free(msg);
}
SilcClientConnection conn = (SilcClientConnection)context;
SilcClient client = conn->client;
if (client)
- silc_client_command_send(client, conn, SILC_COMMAND_NICK,
- ++conn->cmd_ident, 1, 1,
+ silc_client_command_send(client, conn, SILC_COMMAND_NICK,
+ ++conn->cmd_ident, 1, 1,
client->nickname, strlen(client->nickname));
}
/* Issue INFO command to fetch the real server name and server
information and other stuff. */
silc_client_command_register(client, SILC_COMMAND_INFO, NULL, NULL,
- silc_client_command_reply_info_i, 0,
+ silc_client_command_reply_info_i, 0,
++conn->cmd_ident);
sidp = silc_id_payload_encode(conn->remote_id, SILC_ID_SERVER);
silc_client_command_send(client, conn, SILC_COMMAND_INFO,
conn->local_entry);
silc_free(conn->local_id);
}
-
+
/* Save the new ID */
if (conn->local_id_data)
conn->local_entry->id = conn->local_id;
conn->local_entry->valid = TRUE;
if (!conn->local_entry->channels)
- conn->local_entry->channels = silc_hash_table_alloc(1, silc_hash_ptr,
+ conn->local_entry->channels = silc_hash_table_alloc(1, silc_hash_ptr,
NULL, NULL,
- NULL, NULL, NULL,
+ NULL, NULL, NULL,
TRUE);
/* Put it to the ID cache */
silc_idcache_add(conn->internal->client_cache,
- strdup(conn->nickname), conn->local_id,
+ strdup(conn->nickname), conn->local_id,
(void *)conn->local_entry, 0, NULL);
if (connecting) {
/* Issue IDENTIFY command for itself to get resolved hostname
correctly from server. */
silc_client_command_register(client, SILC_COMMAND_IDENTIFY, NULL, NULL,
- silc_client_command_reply_identify_i, 0,
+ silc_client_command_reply_identify_i, 0,
++conn->cmd_ident);
sidp = silc_id_payload_encode(conn->local_entry->id, SILC_ID_CLIENT);
silc_client_command_send(client, conn, SILC_COMMAND_IDENTIFY,
/* Issue INFO command to fetch the real server name and server
information and other stuff. */
silc_client_command_register(client, SILC_COMMAND_INFO, NULL, NULL,
- silc_client_command_reply_info_i, 0,
+ silc_client_command_reply_info_i, 0,
++conn->cmd_ident);
sidp = silc_id_payload_encode(conn->remote_id, SILC_ID_SERVER);
silc_client_command_send(client, conn, SILC_COMMAND_INFO,
is replaced from ID cache with the new one. If the old ID entry is only
updated, then this fucntion needs not to be called. */
-void silc_client_replace_from_channels(SilcClient client,
+void silc_client_replace_from_channels(SilcClient client,
SilcClientConnection conn,
SilcClientEntry old,
SilcClientEntry new)
/* Replace client entry */
silc_hash_table_del(chu->client->channels, chu->channel);
silc_hash_table_del(chu->channel->user_list, chu->client);
-
+
chu->client = new;
silc_hash_table_add(chu->channel->user_list, chu->client, chu);
silc_hash_table_add(chu->client->channels, chu->channel, chu);
SILC_LOG_DEBUG(("Start"));
+ /* If rekey protocol is active already wait for it to finish */
+ if (sock->protocol && sock->protocol->protocol &&
+ sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY)
+ return;
+
/* Allocate internal protocol context. This is sent as context
to the protocol. */
proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
proto_ctx->sock = silc_socket_dup(sock);
proto_ctx->responder = FALSE;
proto_ctx->pfs = conn->internal->rekey->pfs;
-
+
/* Perform rekey protocol. Will call the final callback after the
protocol is over. */
- silc_protocol_alloc(SILC_PROTOCOL_CLIENT_REKEY,
+ silc_protocol_alloc(SILC_PROTOCOL_CLIENT_REKEY,
&protocol, proto_ctx, silc_client_rekey_final);
sock->protocol = protocol;
-
+
/* Run the protocol */
silc_protocol_execute(protocol, client->schedule, 0, 0);
-
- /* Re-register re-key timeout */
- silc_schedule_task_add(client->schedule, sock->sock,
- silc_client_rekey_callback,
- context, conn->internal->rekey->timeout, 0,
- SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
}
/* The final callback for the REKEY protocol. This will actually take the
(SilcClientRekeyInternalContext *)protocol->context;
SilcClient client = (SilcClient)ctx->client;
SilcSocketConnection sock = ctx->sock;
+ SilcClientConnection conn = (SilcClientConnection)sock->user_data;
SILC_LOG_DEBUG(("Start"));
go to the network before we quit the protocol. */
silc_client_packet_queue_purge(client, sock);
+ /* Re-register re-key timeout */
+ if (ctx->responder == FALSE)
+ silc_schedule_task_add(client->schedule, sock->sock,
+ silc_client_rekey_callback,
+ sock, conn->internal->rekey->timeout, 0,
+ SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
+
/* Cleanup */
silc_protocol_free(protocol);
sock->protocol = NULL;
if (ret == -1)
auth_meth = SILC_AUTH_NONE;
- /* Call the request callback to notify application for received
+ /* Call the request callback to notify application for received
authentication method information. */
if (conn->internal->connauth->callback)
(*conn->internal->connauth->callback)(client, conn, auth_meth,
conn->internal->connauth = NULL;
}
-/* Timeout task callback called if the server does not reply to our
+/* Timeout task callback called if the server does not reply to our
connection authentication method request in the specified time interval. */
SILC_TASK_CALLBACK(silc_client_request_authentication_method_timeout)
The `callback' with `context' will be called after the server has
replied back with the current authentication method. */
-void
+void
silc_client_request_authentication_method(SilcClient client,
SilcClientConnection conn,
SilcConnectionAuthRequest callback,
SILC_STR_UI_SHORT(SILC_SOCKET_TYPE_CLIENT),
SILC_STR_UI_SHORT(SILC_AUTH_NONE),
SILC_STR_END);
- silc_client_packet_send(client, conn->sock,
+ silc_client_packet_send(client, conn->sock,
SILC_PACKET_CONNECTION_AUTH_REQUEST,
- NULL, 0, NULL, NULL,
+ NULL, 0, NULL, NULL,
packet->data, packet->len, FALSE);
silc_buffer_free(packet);
/* Register a timeout in case server does not reply anything back. */
connauth->timeout =
- silc_schedule_task_add(client->schedule, conn->sock->sock,
+ silc_schedule_task_add(client->schedule, conn->sock->sock,
silc_client_request_authentication_method_timeout,
- conn,
+ conn,
client->internal->params->connauth_request_secs, 0,
SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
}
Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
- Copyright (C) 1997 - 2001 Pekka Riikonen
+ Copyright (C) 1997 - 2003 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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
void *context)
{
SilcProtocol protocol = (SilcProtocol)context;
- SilcClientKEInternalContext *ctx =
+ SilcClientKEInternalContext *ctx =
(SilcClientKEInternalContext *)protocol->context;
SilcClient client = (SilcClient)ctx->client;
SILC_LOG_DEBUG(("Start"));
/* Call the completion callback back to the SKE */
- verify->completion(verify->ske, success ? SILC_SKE_STATUS_OK :
- SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
+ verify->completion(verify->ske, success ? SILC_SKE_STATUS_OK :
+ SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY,
verify->completion_context);
silc_free(verify);
void *completion_context)
{
SilcProtocol protocol = (SilcProtocol)context;
- SilcClientKEInternalContext *ctx =
+ SilcClientKEInternalContext *ctx =
(SilcClientKEInternalContext *)protocol->context;
SilcClient client = (SilcClient)ctx->client;
VerifyKeyContext verify;
verify->completion_context = completion_context;
/* Verify public key from user. */
- client->internal->ops->verify_public_key(client, ctx->sock->user_data,
+ client->internal->ops->verify_public_key(client, ctx->sock->user_data,
ctx->sock->type,
pk_data, pk_len, pk_type,
silc_client_verify_key_cb, verify);
&conn->internal->hmac_receive);
if (is_responder == TRUE) {
- silc_cipher_set_key(conn->internal->send_key, keymat->receive_enc_key,
+ silc_cipher_set_key(conn->internal->send_key, keymat->receive_enc_key,
keymat->enc_key_len);
silc_cipher_set_iv(conn->internal->send_key, keymat->receive_iv);
- silc_cipher_set_key(conn->internal->receive_key, keymat->send_enc_key,
+ silc_cipher_set_key(conn->internal->receive_key, keymat->send_enc_key,
keymat->enc_key_len);
silc_cipher_set_iv(conn->internal->receive_key, keymat->send_iv);
- silc_hmac_set_key(conn->internal->hmac_send, keymat->receive_hmac_key,
+ silc_hmac_set_key(conn->internal->hmac_send, keymat->receive_hmac_key,
keymat->hmac_key_len);
- silc_hmac_set_key(conn->internal->hmac_receive, keymat->send_hmac_key,
+ silc_hmac_set_key(conn->internal->hmac_receive, keymat->send_hmac_key,
keymat->hmac_key_len);
} else {
- silc_cipher_set_key(conn->internal->send_key, keymat->send_enc_key,
+ silc_cipher_set_key(conn->internal->send_key, keymat->send_enc_key,
keymat->enc_key_len);
silc_cipher_set_iv(conn->internal->send_key, keymat->send_iv);
- silc_cipher_set_key(conn->internal->receive_key, keymat->receive_enc_key,
+ silc_cipher_set_key(conn->internal->receive_key, keymat->receive_enc_key,
keymat->enc_key_len);
silc_cipher_set_iv(conn->internal->receive_key, keymat->receive_iv);
- silc_hmac_set_key(conn->internal->hmac_send, keymat->send_hmac_key,
+ silc_hmac_set_key(conn->internal->hmac_send, keymat->send_hmac_key,
keymat->hmac_key_len);
- silc_hmac_set_key(conn->internal->hmac_receive, keymat->receive_hmac_key,
+ silc_hmac_set_key(conn->internal->hmac_receive, keymat->receive_hmac_key,
keymat->hmac_key_len);
}
/* Rekey stuff */
conn->internal->rekey = silc_calloc(1, sizeof(*conn->internal->rekey));
- conn->internal->rekey->send_enc_key = silc_memdup(keymat->send_enc_key,
+ conn->internal->rekey->send_enc_key = silc_memdup(keymat->send_enc_key,
keymat->enc_key_len / 8);
conn->internal->rekey->enc_key_len = keymat->enc_key_len / 8;
if (!silc_parse_version_string(version, &r_protocol_version, NULL, NULL,
NULL, NULL)) {
client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
- "We don't support server version `%s'",
+ "We don't support server version `%s'",
version);
return SILC_SKE_STATUS_BAD_VERSION;
}
- if (!silc_parse_version_string(client->internal->silc_client_version,
+ if (!silc_parse_version_string(client->internal->silc_client_version,
&l_protocol_version, NULL, NULL,
NULL, NULL)) {
client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
- "We don't support server version `%s'",
+ "We don't support server version `%s'",
version);
return SILC_SKE_STATUS_BAD_VERSION;
}
/* If remote is too new, don't connect */
if (l_protocol_version < r_protocol_version) {
client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
- "We don't support server version `%s'",
+ "We don't support server version `%s'",
version);
return SILC_SKE_STATUS_BAD_VERSION;
}
}
/* Callback that is called by the SKE to indicate that it is safe to
- continue the execution of the protocol. Is given as argument to the
- silc_ske_initiator_finish or silc_ske_responder_phase_2 functions.
+ continue the execution of the protocol. Is given as argument to the
+ silc_ske_initiator_finish or silc_ske_responder_phase_2 functions.
This is called due to the fact that the public key verification
process is asynchronous and we must not continue the protocl until
the public key has been verified and this callback is called. */
void *context)
{
SilcProtocol protocol = (SilcProtocol)context;
- SilcClientKEInternalContext *ctx =
+ SilcClientKEInternalContext *ctx =
(SilcClientKEInternalContext *)protocol->context;
SilcClient client = (SilcClient)ctx->client;
SilcClientConnection conn = ctx->sock->user_data;
if (ske->status != SILC_SKE_STATUS_OK) {
/* Call failure client operation */
- client->internal->ops->failure(client, conn, protocol,
+ client->internal->ops->failure(client, conn, protocol,
(void *)ske->status);
protocol->state = SILC_PROTOCOL_STATE_ERROR;
silc_protocol_execute(protocol, client->schedule, 0, 0);
protocol->state = SILC_PROTOCOL_STATE_END;
}
- /* Advance protocol state and call the next state if we are responder.
+ /* Advance protocol state and call the next state if we are responder.
This happens when this callback was sent to silc_ske_responder_phase_2
function. */
if (ctx->responder == TRUE) {
SILC_TASK_CALLBACK(silc_client_protocol_key_exchange)
{
SilcProtocol protocol = (SilcProtocol)context;
- SilcClientKEInternalContext *ctx =
+ SilcClientKEInternalContext *ctx =
(SilcClientKEInternalContext *)protocol->context;
SilcClient client = (SilcClient)ctx->client;
SilcClientConnection conn = ctx->sock->user_data;
silc_ske_set_callbacks(ske, ctx->send_packet, NULL,
ctx->verify,
silc_client_protocol_ke_continue,
- silc_ske_check_version,
+ silc_ske_check_version,
context);
-
+
if (ctx->responder == TRUE) {
/* Start the key exchange by processing the received security
properties packet from initiator. */
- status =
+ status =
silc_ske_responder_start(ske, ctx->rng, ctx->sock,
client->internal->silc_client_version,
ctx->packet->buffer, TRUE);
/* Assemble security properties. */
silc_ske_assemble_security_properties(
- ske, SILC_SKE_SP_FLAG_MUTUAL,
+ ske, SILC_SKE_SP_FLAG_MUTUAL,
client->internal->silc_client_version,
&start_payload);
break;
case 2:
{
- /*
- * Phase 1
+ /*
+ * Phase 1
*/
if (ctx->responder == TRUE) {
/* Sends the selected security properties to the initiator. */
break;
case 3:
{
- /*
- * Phase 2
+ /*
+ * Phase 2
*/
if (ctx->responder == TRUE) {
/* Process the received Key Exchange 1 Payload packet from
break;
case 4:
{
- /*
+ /*
* Finish protocol
*/
if (ctx->responder == TRUE) {
/* This creates the key exchange material and sends our
public parts to the initiator inside Key Exchange 2 Payload. */
- status =
- silc_ske_responder_finish(ctx->ske,
+ status =
+ silc_ske_responder_finish(ctx->ske,
client->public_key, client->private_key,
SILC_SKE_PK_TYPE_SILC);
if (status != SILC_SKE_STATUS_OK) {
if (status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY) {
client->internal->ops->say(
- client, conn, SILC_CLIENT_MESSAGE_AUDIT,
+ client, conn, SILC_CLIENT_MESSAGE_AUDIT,
"Received unsupported server %s public key",
ctx->sock->hostname);
} else {
case SILC_PROTOCOL_STATE_END:
{
- /*
+ /*
* End protocol
*/
SilcSKEKeyMaterial *keymat;
if (ctx->responder == TRUE)
silc_ske_end(ctx->ske);
- /* Unregister the timeout task since the protocol has ended.
+ /* Unregister the timeout task since the protocol has ended.
This was the timeout task to be executed if the protocol is
not completed fast enough. */
if (ctx->timeout_task)
/*
* Error during protocol
*/
-
+
/* Send abort notification */
silc_ske_abort(ctx->ske, ctx->ske->status);
* Received failure from remote.
*/
- /* Unregister the timeout task since the protocol has ended.
+ /* Unregister the timeout task since the protocol has ended.
This was the timeout task to be executed if the protocol is
not completed fast enough. */
if (ctx->timeout_task)
ske->start_payload_copy->len),
SILC_STR_END);
- if (silc_pkcs_sign_with_hash(pkcs, ske->prop->hash, auth->data,
+ if (silc_pkcs_sign_with_hash(pkcs, ske->prop->hash, auth->data,
auth->len, auth_data, auth_data_len)) {
silc_buffer_free(auth);
return TRUE;
/* Continues the connection authentication protocol. This funtion may
be called directly or used as SilcAskPassphrase callback. */
-static void
+static void
silc_client_conn_auth_continue(unsigned char *auth_data,
SilcUInt32 auth_data_len, void *context)
{
SilcProtocol protocol = (SilcProtocol)context;
- SilcClientConnAuthInternalContext *ctx =
+ SilcClientConnAuthInternalContext *ctx =
(SilcClientConnAuthInternalContext *)protocol->context;
SilcClient client = (SilcClient)ctx->client;
SilcBuffer packet;
SILC_LOG_DEBUG(("Sending authentication to server"));
/* Passphrase must be UTF-8 encoded, if it isn't encode it */
- if (ctx->auth_meth == SILC_AUTH_PASSWORD &&
+ if (ctx->auth_meth == SILC_AUTH_PASSWORD &&
!silc_utf8_valid(auth_data, auth_data_len)) {
- payload_len = silc_utf8_encoded_len(auth_data, auth_data_len,
+ payload_len = silc_utf8_encoded_len(auth_data, auth_data_len,
SILC_STRING_ASCII);
autf8 = silc_calloc(payload_len, sizeof(*autf8));
- auth_data_len = silc_utf8_encode(auth_data, auth_data_len,
+ auth_data_len = silc_utf8_encode(auth_data, auth_data_len,
SILC_STRING_ASCII, autf8, payload_len);
auth_data = autf8;
}
packet->data, packet->len, TRUE);
silc_buffer_free(packet);
silc_free(autf8);
-
+
/* Next state is end of protocol */
protocol->state = SILC_PROTOCOL_STATE_END;
}
-
+
SILC_TASK_CALLBACK(silc_client_protocol_connection_auth)
{
SilcProtocol protocol = (SilcProtocol)context;
- SilcClientConnAuthInternalContext *ctx =
+ SilcClientConnAuthInternalContext *ctx =
(SilcClientConnAuthInternalContext *)protocol->context;
SilcClient client = (SilcClient)ctx->client;
SilcClientConnection conn = ctx->sock->user_data;
switch(protocol->state) {
case SILC_PROTOCOL_STATE_START:
{
- /*
+ /*
* Start protocol. We send authentication data to the server
* to be authenticated.
*/
case SILC_AUTH_PUBLIC_KEY:
if (!ctx->auth_data) {
/* Public key authentication */
- silc_client_get_public_key_auth(client, conn, sign, &auth_data_len,
+ silc_client_get_public_key_auth(client, conn, sign, &auth_data_len,
ctx->ske);
auth_data = sign;
} else {
auth_data = ctx->auth_data;
auth_data_len = ctx->auth_data_len;
}
-
+
break;
}
case SILC_PROTOCOL_STATE_END:
{
- /*
+ /*
* End protocol. Nothing special to be done here.
*/
case SILC_PROTOCOL_STATE_ERROR:
{
- /*
+ /*
* Error. Send notify to remote.
*/
unsigned char error[4];
/* Actually takes the new keys into use. */
-static void
+static void
silc_client_protocol_rekey_validate(SilcClient client,
SilcClientRekeyInternalContext *ctx,
SilcSocketConnection sock,
if (ctx->responder == TRUE) {
if (send) {
- silc_cipher_set_key(conn->internal->send_key, keymat->receive_enc_key,
+ silc_cipher_set_key(conn->internal->send_key, keymat->receive_enc_key,
keymat->enc_key_len);
silc_cipher_set_iv(conn->internal->send_key, keymat->receive_iv);
- silc_hmac_set_key(conn->internal->hmac_send, keymat->receive_hmac_key,
+ silc_hmac_set_key(conn->internal->hmac_send, keymat->receive_hmac_key,
keymat->hmac_key_len);
} else {
- silc_cipher_set_key(conn->internal->receive_key, keymat->send_enc_key,
+ silc_cipher_set_key(conn->internal->receive_key, keymat->send_enc_key,
keymat->enc_key_len);
silc_cipher_set_iv(conn->internal->receive_key, keymat->send_iv);
- silc_hmac_set_key(conn->internal->hmac_receive, keymat->send_hmac_key,
+ silc_hmac_set_key(conn->internal->hmac_receive, keymat->send_hmac_key,
keymat->hmac_key_len);
}
} else {
if (send) {
- silc_cipher_set_key(conn->internal->send_key, keymat->send_enc_key,
+ silc_cipher_set_key(conn->internal->send_key, keymat->send_enc_key,
keymat->enc_key_len);
silc_cipher_set_iv(conn->internal->send_key, keymat->send_iv);
- silc_hmac_set_key(conn->internal->hmac_send, keymat->send_hmac_key,
+ silc_hmac_set_key(conn->internal->hmac_send, keymat->send_hmac_key,
keymat->hmac_key_len);
} else {
silc_cipher_set_key(conn->internal->receive_key,
/* This function actually re-generates (when not using PFS) the keys and
takes them into use. */
-static void
+static void
silc_client_protocol_rekey_generate(SilcClient client,
SilcClientRekeyInternalContext *ctx,
bool send)
keymat = silc_calloc(1, sizeof(*keymat));
silc_ske_process_key_material_data(conn->internal->rekey->send_enc_key,
conn->internal->rekey->enc_key_len,
- 16, key_len, hash_len,
+ 16, key_len, hash_len,
conn->internal->hash, keymat);
/* Set the keys into use */
/* This function actually re-generates (with PFS) the keys and
takes them into use. */
-static void
+static void
silc_client_protocol_rekey_generate_pfs(SilcClient client,
SilcClientRekeyInternalContext *ctx,
bool send)
/* Generate the new key */
keymat = silc_calloc(1, sizeof(*keymat));
- silc_ske_process_key_material_data(tmpbuf, klen, 16, key_len, hash_len,
+ silc_ske_process_key_material_data(tmpbuf, klen, 16, key_len, hash_len,
conn->internal->hash, keymat);
/* Set the keys into use */
/* Packet sending callback. This function is provided as packet sending
routine to the Key Exchange functions. */
-static void
+static void
silc_client_protocol_rekey_send_packet(SilcSKE ske,
SilcBuffer packet,
SilcPacketType type,
void *context)
{
SilcProtocol protocol = (SilcProtocol)context;
- SilcClientRekeyInternalContext *ctx =
+ SilcClientRekeyInternalContext *ctx =
(SilcClientRekeyInternalContext *)protocol->context;
SilcClient client = (SilcClient)ctx->client;
SILC_TASK_CALLBACK(silc_client_protocol_rekey)
{
SilcProtocol protocol = (SilcProtocol)context;
- SilcClientRekeyInternalContext *ctx =
+ SilcClientRekeyInternalContext *ctx =
(SilcClientRekeyInternalContext *)protocol->context;
SilcClient client = (SilcClient)ctx->client;
SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
switch(protocol->state) {
case SILC_PROTOCOL_STATE_START:
{
- /*
+ /*
* Start protocol.
*/
*/
if (ctx->pfs == TRUE) {
- /*
+ /*
* Use Perfect Forward Secrecy, ie. negotiate the key material
* using the SKE protocol.
*/
silc_ske_group_get_by_number(conn->internal->rekey->ske_group,
&ctx->ske->prop->group);
- silc_ske_set_callbacks(ctx->ske,
+ silc_ske_set_callbacks(ctx->ske,
silc_client_protocol_rekey_send_packet,
NULL, NULL, NULL, silc_ske_check_version,
context);
-
+
status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer);
if (status != SILC_SKE_STATUS_OK) {
SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
status));
-
+
protocol->state = SILC_PROTOCOL_STATE_ERROR;
silc_protocol_execute(protocol, client->schedule, 0, 300000);
return;
*/
/* Send the REKEY_DONE to indicate we will take new keys into use */
- silc_client_packet_send(client, ctx->sock,
- SILC_PACKET_REKEY_DONE,
+ silc_client_packet_send(client, ctx->sock,
+ SILC_PACKET_REKEY_DONE,
NULL, 0, NULL, NULL, NULL, 0, FALSE);
/* After we send REKEY_DONE we must set the sending encryption
key to the new key since all packets after this packet must
encrypted with the new key. */
silc_client_protocol_rekey_generate(client, ctx, TRUE);
+ silc_client_packet_queue_purge(client, ctx->sock);
/* The protocol ends in next stage. */
protocol->state = SILC_PROTOCOL_STATE_END;
}
-
+
} else {
/*
* We are the initiator of this protocol
*/
/* Start the re-key by sending the REKEY packet */
- silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY,
+ silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY,
NULL, 0, NULL, NULL, NULL, 0, FALSE);
if (ctx->pfs == TRUE) {
- /*
+ /*
* Use Perfect Forward Secrecy, ie. negotiate the key material
* using the SKE protocol.
*/
silc_ske_group_get_by_number(conn->internal->rekey->ske_group,
&ctx->ske->prop->group);
- silc_ske_set_callbacks(ctx->ske,
+ silc_ske_set_callbacks(ctx->ske,
silc_client_protocol_rekey_send_packet,
NULL, NULL, NULL, silc_ske_check_version,
context);
-
+
status = silc_ske_initiator_phase_2(ctx->ske, NULL, NULL, 0);
if (status != SILC_SKE_STATUS_OK) {
SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
status));
-
+
protocol->state = SILC_PROTOCOL_STATE_ERROR;
silc_protocol_execute(protocol, client->schedule, 0, 300000);
return;
* Do normal and simple re-key.
*/
- /* Send the REKEY_DONE to indicate we will take new keys into use
- now. */
- silc_client_packet_send(client, ctx->sock,
- SILC_PACKET_REKEY_DONE,
+ /* Send the REKEY_DONE to indicate we will take new keys into use
+ now. */
+ silc_client_packet_send(client, ctx->sock,
+ SILC_PACKET_REKEY_DONE,
NULL, 0, NULL, NULL, NULL, 0, FALSE);
/* After we send REKEY_DONE we must set the sending encryption
key to the new key since all packets after this packet must
encrypted with the new key. */
silc_client_protocol_rekey_generate(client, ctx, TRUE);
+ silc_client_packet_queue_purge(client, ctx->sock);
/* The protocol ends in next stage. */
protocol->state = SILC_PROTOCOL_STATE_END;
* Send our KE packe to the initiator now that we've processed
* the initiator's KE packet.
*/
- status = silc_ske_responder_finish(ctx->ske, NULL, NULL,
+ status = silc_ske_responder_finish(ctx->ske, NULL, NULL,
SILC_SKE_PK_TYPE_SILC);
if (status != SILC_SKE_STATUS_OK) {
SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
status));
-
+
protocol->state = SILC_PROTOCOL_STATE_ERROR;
silc_protocol_execute(protocol, client->schedule, 0, 300000);
return;
protocol->state = SILC_PROTOCOL_STATE_ERROR;
silc_protocol_execute(protocol, client->schedule, 0, 300000);
}
-
+
status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer);
if (status != SILC_SKE_STATUS_OK) {
SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
status));
-
+
protocol->state = SILC_PROTOCOL_STATE_ERROR;
silc_protocol_execute(protocol, client->schedule, 0, 300000);
return;
}
}
- /* Send the REKEY_DONE to indicate we will take new keys into use
- now. */
- silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY_DONE,
+ /* Send the REKEY_DONE to indicate we will take new keys into use
+ now. */
+ silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY_DONE,
NULL, 0, NULL, NULL, NULL, 0, FALSE);
-
+
/* After we send REKEY_DONE we must set the sending encryption
key to the new key since all packets after this packet must
encrypted with the new key. */
break;
case SILC_PROTOCOL_STATE_END:
- /*
+ /*
* End protocol
*/