assert(server);
assert(server->config);
+ /* Set public and private keys */
+ if (!server->config->server_keys ||
+ !server->config->server_keys->public_key ||
+ !server->config->server_keys->private_key) {
+ SILC_LOG_ERROR(("Server public key and/or private key does not exist"));
+ return FALSE;
+ }
+ server->public_key = server->config->server_keys->public_key;
+ server->private_key = server->config->server_keys->private_key;
+
/* XXX After server is made as Silc Server Library this can be given
as argument, for now this is hard coded */
server->params = silc_calloc(1, sizeof(*server->params));
/* Initialize none cipher */
silc_cipher_alloc("none", &server->none_cipher);
- /* XXXXX Generate RSA key pair */
- {
- unsigned char *public_key;
- unsigned char *private_key;
- uint32 pk_len, prv_len;
- struct stat st;
-
- if (stat("pubkey.pub", &st) < 0 && stat("privkey.prv", &st) < 0) {
-
- if (silc_pkcs_alloc("rsa", &server->pkcs) == FALSE) {
- SILC_LOG_ERROR(("Could not create RSA key pair"));
- goto err0;
- }
-
- if (server->pkcs->pkcs->init(server->pkcs->context,
- 1024, server->rng) == FALSE) {
- SILC_LOG_ERROR(("Could not generate RSA key pair"));
- goto err0;
- }
-
- public_key = server->pkcs->pkcs->get_public_key(server->pkcs->context,
- &pk_len);
- private_key = server->pkcs->pkcs->get_private_key(server->pkcs->context,
- &prv_len);
-
- SILC_LOG_HEXDUMP(("public key"), public_key, pk_len);
- SILC_LOG_HEXDUMP(("private key"), private_key, prv_len);
-
- server->public_key =
- silc_pkcs_public_key_alloc("rsa", "UN=root, HN=dummy",
- public_key, pk_len);
- server->private_key =
- silc_pkcs_private_key_alloc("rsa", private_key, prv_len);
-
- /* XXX Save keys */
- silc_pkcs_save_public_key("pubkey.pub", server->public_key,
- SILC_PKCS_FILE_PEM);
- silc_pkcs_save_private_key("privkey.prv", server->private_key, NULL,
- SILC_PKCS_FILE_BIN);
-
- memset(public_key, 0, pk_len);
- memset(private_key, 0, prv_len);
- silc_free(public_key);
- silc_free(private_key);
- } else {
- silc_pkcs_load_public_key("pubkey.pub", &server->public_key,
- SILC_PKCS_FILE_PEM);
- silc_pkcs_load_private_key("privkey.prv", &server->private_key,
- SILC_PKCS_FILE_BIN);
- }
- }
-
/* Create a listening server. Note that our server can listen on
multiple ports. All listeners are created here and now. */
/* XXX Still check this whether to use server_info or listen_port. */
&newsocket);
server->sockets[sock[i]] = newsocket;
+
+ /* Perform name and address lookups to resolve the listenning address
+ and port. */
+ if (!silc_net_check_local_by_sock(sock[i], &newsocket->hostname,
+ &newsocket->ip)) {
+ if ((server->params->require_reverse_mapping && !newsocket->hostname) ||
+ !newsocket->ip) {
+ SILC_LOG_ERROR(("IP/DNS lookup failed for local host %s",
+ newsocket->hostname ? newsocket->hostname :
+ newsocket->ip ? newsocket->ip : ""));
+ server->stat.conn_failures++;
+ goto err0;
+ }
+ if (!newsocket->hostname)
+ newsocket->hostname = strdup(newsocket->ip);
+ }
+ newsocket->port = silc_net_get_local_port(sock[i]);
/* Put the allocated socket pointer also to the entry allocated above
for fast back-referencing to the socket list. */
SilcServerKEInternalContext *proto_ctx;
int sock;
+ SILC_LOG_INFO(("Connecting to the router %s on port %d",
+ sconn->remote_host, sconn->remote_port));
+
/* Connect to remote host */
sock = silc_net_create_connection(sconn->remote_port,
sconn->remote_host);
ctx->ske->prop->pkcs,
ctx->ske->prop->hash,
ctx->ske->prop->hmac,
+ ctx->ske->prop->group,
ctx->responder)) {
silc_protocol_free(protocol);
sock->protocol = NULL;
/* Add the connected router to local server list */
server->standalone = FALSE;
- id_entry = silc_idlist_add_server(server->local_list, sock->hostname,
+ id_entry = silc_idlist_add_server(server->local_list, strdup(sock->hostname),
SILC_ROUTER, ctx->dest_id, NULL, sock);
if (!id_entry) {
if (ctx->dest_id)
server->timeout_queue);
/* Register re-key timeout */
- idata->rekey->timeout = 60; /* XXX hardcoded */
+ idata->rekey->timeout = 3600; /* XXX hardcoded */
idata->rekey->context = (void *)server;
silc_task_register(server->timeout_queue, sock->sock,
silc_server_rekey_callback,
SilcServer server = (SilcServer)context;
SilcSocketConnection newsocket;
SilcServerKEInternalContext *proto_ctx;
- int sock;
+ int sock, port;
+ void *cconfig, *sconfig, *rconfig;
+ SilcServerConfigSectionDenyConnection *deny;
SILC_LOG_DEBUG(("Accepting new connection"));
process. Either we have to do our own resolver stuff or in the future
we can use threads. */
/* Perform name and address lookups for the remote host. */
- silc_net_check_host_by_sock(sock, &newsocket->hostname, &newsocket->ip);
- if ((server->params->require_reverse_mapping && !newsocket->hostname) ||
- !newsocket->ip) {
- SILC_LOG_ERROR(("IP/DNS lookup failed"));
+ if (!silc_net_check_host_by_sock(sock, &newsocket->hostname,
+ &newsocket->ip)) {
+ if ((server->params->require_reverse_mapping && !newsocket->hostname) ||
+ !newsocket->ip) {
+ SILC_LOG_ERROR(("IP/DNS lookup failed %s",
+ newsocket->hostname ? newsocket->hostname :
+ newsocket->ip ? newsocket->ip : ""));
+ server->stat.conn_failures++;
+ return;
+ }
+ if (!newsocket->hostname)
+ newsocket->hostname = strdup(newsocket->ip);
+ }
+ newsocket->port = silc_net_get_remote_port(sock);
+
+ /* Register the connection for network input and output. This sets
+ 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 be set separately by calling SILC_SET_CONNECTION_FOR_OUTPUT,
+ later when outgoing data is available. */
+ SILC_REGISTER_CONNECTION_FOR_IO(sock);
+
+ port = server->sockets[fd]->port; /* Listenning port */
+
+ /* Check whether this connection is denied to connect to us. */
+ deny = silc_server_config_denied_conn(server->config, newsocket->ip, port);
+ if (!deny)
+ deny = silc_server_config_denied_conn(server->config, newsocket->hostname,
+ port);
+ if (deny) {
+ /* The connection is denied */
+ silc_server_disconnect_remote(server, newsocket, deny->comment ?
+ deny->comment :
+ "Server closed connection: "
+ "Connection refused");
server->stat.conn_failures++;
return;
}
- if (!newsocket->hostname)
- newsocket->hostname = strdup(newsocket->ip);
- newsocket->port = silc_net_get_remote_port(sock);
+
+ /* Check whether we have configred this sort of connection at all. We
+ have to check all configurations since we don't know what type of
+ connection this is. */
+ if (!(cconfig = silc_server_config_find_client_conn(server->config,
+ newsocket->ip, port)))
+ cconfig = silc_server_config_find_client_conn(server->config,
+ newsocket->hostname,
+ port);
+ if (!(sconfig = silc_server_config_find_server_conn(server->config,
+ newsocket->ip,
+ port)))
+ sconfig = silc_server_config_find_server_conn(server->config,
+ newsocket->hostname,
+ port);
+ if (!(rconfig = silc_server_config_find_router_conn(server->config,
+ newsocket->ip, port)))
+ rconfig = silc_server_config_find_router_conn(server->config,
+ newsocket->hostname,
+ port);
+ if (!cconfig && !sconfig && !rconfig) {
+ silc_server_disconnect_remote(server, newsocket,
+ "Server closed connection: "
+ "Connection refused");
+ server->stat.conn_failures++;
+ return;
+ }
+
+ /* The connection is allowed */
SILC_LOG_INFO(("Incoming connection from %s (%s)", newsocket->hostname,
newsocket->ip));
proto_ctx->sock = newsocket;
proto_ctx->rng = server->rng;
proto_ctx->responder = TRUE;
+ proto_ctx->cconfig = cconfig;
+ proto_ctx->sconfig = sconfig;
+ proto_ctx->rconfig = rconfig;
/* Prepare the connection for key exchange protocol. We allocate the
protocol but will not start it yet. The connector will be the
context, 60, 0,
SILC_TASK_TIMEOUT,
SILC_TASK_PRI_LOW);
-
- /* Register the connection for network input and output. This sets
- 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 be set separately by calling SILC_SET_CONNECTION_FOR_OUTPUT,
- later when outgoing data is available. */
- SILC_REGISTER_CONNECTION_FOR_IO(sock);
}
/* Second part of accepting new connection. Key exchange protocol has been
ctx->ske->prop->pkcs,
ctx->ske->prop->hash,
ctx->ske->prop->hmac,
+ ctx->ske->prop->group,
ctx->responder)) {
silc_protocol_free(protocol);
sock->protocol = NULL;
proto_ctx->responder = TRUE;
proto_ctx->dest_id_type = ctx->dest_id_type;
proto_ctx->dest_id = ctx->dest_id;
+ proto_ctx->cconfig = ctx->cconfig;
+ proto_ctx->sconfig = ctx->sconfig;
+ proto_ctx->rconfig = ctx->rconfig;
/* Free old protocol as it is finished now */
silc_protocol_free(protocol);
case SILC_SOCKET_TYPE_ROUTER:
{
SilcServerEntry new_server;
+ SilcServerConfigSectionServerConnection *conn =
+ sock->type == SILC_SOCKET_TYPE_SERVER ? ctx->sconfig : ctx->rconfig;
SILC_LOG_DEBUG(("Remote host is %s",
sock->type == SILC_SOCKET_TYPE_SERVER ?
server->stat.servers++;
id_entry = (void *)new_server;
-
- /* There is connection to other server now, if it is router then
- we will have connection to outside world. If we are router but
- normal server connected to us then we will remain standalone,
- if we are standlone. */
+
+ /* Check whether this connection is to be our primary router connection
+ if we dont' already have the primary route. */
if (server->standalone && sock->type == SILC_SOCKET_TYPE_ROUTER) {
+ if (silc_server_config_is_primary_route(server->config) &&
+ !conn->initiator)
+ break;
+
SILC_LOG_DEBUG(("We are not standalone server anymore"));
server->standalone = FALSE;
if (!server->id_entry->router) {
server->router = id_entry;
}
}
+
break;
}
default:
if (sock->outbuf->data - sock->outbuf->head)
silc_buffer_push(sock->outbuf, sock->outbuf->data - sock->outbuf->head);
- ret = silc_server_packet_send_real(server, sock, TRUE);
+ /* Send the packet */
+ ret = silc_packet_send(sock, TRUE);
/* If returned -2 could not write to connection now, will do
it later. */
if (idata) {
idata->last_receive = time(NULL);
cipher = idata->receive_key;
- hmac = idata->hmac;
+ hmac = idata->hmac_receive;
}
/* Process the packet. This will call the parser that will then
return FALSE;
}
-
+
/* Parses whole packet, received earlier. */
SILC_TASK_CALLBACK(silc_server_packet_parse_real)
SilcServer server = (SilcServer)parse_ctx->context;
SilcSocketConnection sock = parse_ctx->sock;
SilcPacketContext *packet = parse_ctx->packet;
+ SilcIDListData idata = (SilcIDListData)sock->user_data;
int ret;
SILC_LOG_DEBUG(("Start"));
/* Decrypt the received packet */
- ret = silc_packet_decrypt(parse_ctx->cipher, parse_ctx->hmac,
+ ret = silc_packet_decrypt(idata ? idata->receive_key : NULL,
+ idata ? idata->hmac_receive : NULL,
packet->buffer, packet,
silc_server_packet_decrypt_check, parse_ctx);
if (ret < 0)
if (client && client->id) {
void *id = silc_id_str2id(packet->src_id, packet->src_id_len,
packet->src_id_type);
- if (SILC_ID_CLIENT_COMPARE(client->id, id)) {
+ if (!id || SILC_ID_CLIENT_COMPARE(client->id, id)) {
silc_free(id);
goto out;
}
if (server->server_type == SILC_ROUTER) {
/* Route the packet if it is not destined to us. Other ID types but
server are handled separately after processing them. */
- if (packet->dst_id_type == SILC_ID_SERVER &&
+ if (!(packet->flags & SILC_PACKET_FLAG_BROADCAST) &&
+ packet->dst_id_type == SILC_ID_SERVER &&
sock->type != SILC_SOCKET_TYPE_CLIENT &&
SILC_ID_SERVER_COMPARE(packet->dst_id, server->id_string)) {
silc_free(id);
goto out;
}
-
+ }
+
+ /* Parse the incoming packet type */
+ silc_server_packet_parse_type(server, sock, packet);
+
+ if (server->server_type == SILC_ROUTER) {
/* Broadcast packet if it is marked as broadcast packet and it is
originated from router and we are router. */
if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
- packet->flags & SILC_PACKET_FLAG_BROADCAST) {
+ packet->flags & SILC_PACKET_FLAG_BROADCAST &&
+ !server->standalone) {
silc_server_packet_broadcast(server, server->router->connection, packet);
}
}
- /* Parse the incoming packet type */
- silc_server_packet_parse_type(server, sock, packet);
-
out:
/* silc_buffer_clear(sock->inbuf); */
silc_packet_context_free(packet);
SilcSocketConnection sock = parser_context->sock;
switch (sock->type) {
- case SILC_SOCKET_TYPE_CLIENT:
case SILC_SOCKET_TYPE_UNKNOWN:
+ case SILC_SOCKET_TYPE_CLIENT:
/* Parse the packet with timeout */
silc_task_register(server->timeout_queue, sock->sock,
silc_server_packet_parse_real,
break;
if (sock->protocol && sock->protocol->protocol &&
- sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE) {
-
- SilcServerKEInternalContext *proto_ctx =
- (SilcServerKEInternalContext *)sock->protocol->context;
+ (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
+ sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY)) {
- if (proto_ctx->packet)
- silc_packet_context_free(proto_ctx->packet);
+ if (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
+ SilcServerRekeyInternalContext *proto_ctx =
+ (SilcServerRekeyInternalContext *)sock->protocol->context;
+
+ if (proto_ctx->packet)
+ silc_packet_context_free(proto_ctx->packet);
+
+ proto_ctx->packet = silc_packet_context_dup(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 */
+ sock->protocol->execute(server->timeout_queue, 0,
+ sock->protocol, sock->sock, 0, 0);
+ } else {
+ SilcServerKEInternalContext *proto_ctx =
+ (SilcServerKEInternalContext *)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 */
- sock->protocol->execute(server->timeout_queue, 0,
- sock->protocol, sock->sock,
- 0, 100000);
+ /* Let the protocol handle the packet */
+ sock->protocol->execute(server->timeout_queue, 0,
+ sock->protocol, sock->sock,
+ 0, 100000);
+ }
} else {
SILC_LOG_ERROR(("Received Key Exchange 1 packet but no key exchange "
"protocol active, packet dropped."));
break;
if (sock->protocol && sock->protocol->protocol &&
- sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE) {
-
- SilcServerKEInternalContext *proto_ctx =
- (SilcServerKEInternalContext *)sock->protocol->context;
+ (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_KEY_EXCHANGE ||
+ sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY)) {
- if (proto_ctx->packet)
- silc_packet_context_free(proto_ctx->packet);
+ if (sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) {
+ SilcServerRekeyInternalContext *proto_ctx =
+ (SilcServerRekeyInternalContext *)sock->protocol->context;
+
+ if (proto_ctx->packet)
+ silc_packet_context_free(proto_ctx->packet);
+
+ proto_ctx->packet = silc_packet_context_dup(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 */
+ sock->protocol->execute(server->timeout_queue, 0,
+ sock->protocol, sock->sock, 0, 0);
+ } else {
+ SilcServerKEInternalContext *proto_ctx =
+ (SilcServerKEInternalContext *)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 */
- sock->protocol->execute(server->timeout_queue, 0,
- sock->protocol, sock->sock,
- 0, 100000);
+ /* Let the protocol handle the packet */
+ sock->protocol->execute(server->timeout_queue, 0,
+ sock->protocol, sock->sock,
+ 0, 100000);
+ }
} else {
SILC_LOG_ERROR(("Received Key Exchange 2 packet but no key exchange "
"protocol active, packet dropped."));
/* Let the protocol handle the packet */
sock->protocol->execute(server->timeout_queue, 0,
- sock->protocol, sock->sock,
- 0, 100000);
+ sock->protocol, sock->sock, 0, 0);
} else {
SILC_LOG_ERROR(("Received Re-key done packet but no re-key "
"protocol active, packet dropped."));
void silc_server_close_connection(SilcServer server,
SilcSocketConnection sock)
{
- SILC_LOG_DEBUG(("Closing connection %d", sock->sock));
+ SILC_LOG_INFO(("Closing connection %s:%d [%s] (%d)", sock->hostname,
+ sock->port,
+ (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" :
+ sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
+ sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
+ "Router"), sock->sock));
/* We won't listen for this connection anymore */
silc_schedule_unset_listen_fd(sock->sock);
if (sock->outbuf->data - sock->outbuf->head)
silc_buffer_push(sock->outbuf, sock->outbuf->data - sock->outbuf->head);
- silc_server_packet_send_real(server, sock, TRUE);
+ silc_packet_send(sock, TRUE);
SILC_SET_CONNECTION_FOR_INPUT(sock->sock);
SILC_UNSET_OUTBUF_PENDING(sock);
/* Free all client entries that this server owns as they will
become invalid now as well. */
- silc_server_remove_clients_by_server(server, user_data, TRUE);
+ if (user_data->id)
+ silc_server_remove_clients_by_server(server, user_data, TRUE);
/* If this was our primary router connection then we're lost to
the outside world. */
argv_types);
silc_server_send_notify_args(server,
server->router->connection,
- server->server_type ==
- SILC_SERVER ? FALSE : TRUE,
+ server->server_type == SILC_SERVER ?
+ FALSE : TRUE,
SILC_NOTIFY_TYPE_SERVER_SIGNOFF,
argc, args);
silc_buffer_free(args);
signoff_message, signoff_message ?
strlen(signoff_message) : 0);
- server->stat.my_channels--;
-
if (channel->rekey)
silc_task_unregister_by_context(server->timeout_queue, channel->rekey);
if (!silc_idlist_del_channel(server->local_list, channel))
silc_idlist_del_channel(server->global_list, channel);
+ server->stat.my_channels--;
continue;
}
SILC_NOTIFY_TYPE_LEAVE, 1,
clidp->data, clidp->len);
- server->stat.my_channels--;
silc_buffer_free(clidp);
if (channel->rekey)
if (!silc_idlist_del_channel(server->local_list, channel))
silc_idlist_del_channel(server->global_list, channel);
+ server->stat.my_channels--;
return FALSE;
}
}
static SilcBuffer
-silc_server_announce_encode_join(uint32 argc, ...)
+silc_server_announce_encode_notify(SilcNotifyType notify, uint32 argc, ...)
{
va_list ap;
va_start(ap, argc);
- return silc_notify_payload_encode(SILC_NOTIFY_TYPE_JOIN, argc, ap);
+ return silc_notify_payload_encode(notify, argc, ap);
}
/* Returns assembled packets for channel users of the `channel'. */
void silc_server_announce_get_channel_users(SilcServer server,
SilcChannelEntry channel,
- SilcBuffer *channel_users)
+ SilcBuffer *channel_users,
+ SilcBuffer *channel_users_modes)
{
SilcChannelClientEntry chl;
SilcBuffer chidp, clidp;
SilcBuffer tmp;
int len;
+ unsigned char mode[4];
SILC_LOG_DEBUG(("Start"));
silc_list_start(channel->user_list);
while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
- tmp = silc_server_announce_encode_join(2, clidp->data, clidp->len,
- chidp->data, chidp->len);
+
+ /* JOIN Notify */
+ tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_JOIN, 2,
+ clidp->data, clidp->len,
+ chidp->data, chidp->len);
len = tmp->len;
*channel_users =
silc_buffer_realloc(*channel_users,
silc_buffer_put(*channel_users, tmp->data, tmp->len);
silc_buffer_pull(*channel_users, len);
- silc_buffer_free(clidp);
silc_buffer_free(tmp);
+
+ /* CUMODE notify for mode change on the channel */
+ SILC_PUT32_MSB(chl->mode, mode);
+ tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
+ 3, clidp->data, clidp->len,
+ mode, 4,
+ clidp->data, clidp->len);
+ len = tmp->len;
+ *channel_users_modes =
+ silc_buffer_realloc(*channel_users_modes,
+ (*channel_users_modes ?
+ (*channel_users_modes)->truelen + len : len));
+ silc_buffer_pull_tail(*channel_users_modes,
+ ((*channel_users_modes)->end -
+ (*channel_users_modes)->data));
+
+ silc_buffer_put(*channel_users_modes, tmp->data, tmp->len);
+ silc_buffer_pull(*channel_users_modes, len);
+ silc_buffer_free(tmp);
+
+ silc_buffer_free(clidp);
}
silc_buffer_free(chidp);
}
void silc_server_announce_get_channels(SilcServer server,
SilcIDList id_list,
SilcBuffer *channels,
- SilcBuffer *channel_users)
+ SilcBuffer *channel_users,
+ SilcBuffer *channel_users_modes)
{
SilcIDCacheList list;
SilcIDCacheEntry id_cache;
silc_buffer_pull(*channels, len);
silc_server_announce_get_channel_users(server, channel,
- channel_users);
+ channel_users,
+ channel_users_modes);
silc_free(cid);
void silc_server_announce_channels(SilcServer server)
{
- SilcBuffer channels = NULL, channel_users = NULL;
+ SilcBuffer channels = NULL, channel_users = NULL, channel_users_modes = NULL;
SILC_LOG_DEBUG(("Announcing channels and channel users"));
/* Get channels and channel users in local list */
silc_server_announce_get_channels(server, server->local_list,
- &channels, &channel_users);
+ &channels, &channel_users,
+ &channel_users_modes);
/* Get channels and channel users in global list */
silc_server_announce_get_channels(server, server->global_list,
- &channels, &channel_users);
+ &channels, &channel_users,
+ &channel_users_modes);
if (channels) {
silc_buffer_push(channels, channels->data - channels->head);
silc_buffer_free(channel_users);
}
+
+ if (channel_users_modes) {
+ silc_buffer_push(channel_users_modes,
+ channel_users_modes->data - channel_users_modes->head);
+ SILC_LOG_HEXDUMP(("channel users modes"), channel_users_modes->data,
+ channel_users_modes->len);
+
+ /* Send the packet */
+ silc_server_packet_send(server, server->router->connection,
+ SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
+ channel_users_modes->data,
+ channel_users_modes->len,
+ FALSE);
+
+ silc_buffer_free(channel_users_modes);
+ }
}
/* Failure timeout callback. If this is called then we will immediately
}
}
-/* Lookups route to the client indicated by `id' client ID. The connection
+/* Lookups route to the client indicated by the `id_data'. The connection
object and internal data object is returned. Returns NULL if route
could not be found to the client. If the `client_id' is specified then
it is used and the `id_data' is ignored. */
/* We are of course in this case the client's router thus the real
"router" of the client is the server who owns the client. Thus
we will send the packet to that server. */
- *idata = (SilcIDListData)client->router;
+ if (idata)
+ *idata = (SilcIDListData)client->router;
return client->router->connection;
}
/* Seems that client really is directly connected to us */
- *idata = (SilcIDListData)client;
+ if (idata)
+ *idata = (SilcIDListData)client;
return client->connection;
}
server our action is to send the packet to our router. */
if (server->server_type == SILC_SERVER && !server->standalone) {
silc_free(id);
- *idata = (SilcIDListData)server->router;
+ if (idata)
+ *idata = (SilcIDListData)server->router;
return server->router->connection;
}
dst_sock = silc_server_route_get(server, id, SILC_ID_CLIENT);
silc_free(id);
- *idata = (SilcIDListData)dst_sock->user_data;
+ if (idata)
+ *idata = (SilcIDListData)dst_sock->user_data;
return dst_sock;
}
}
proto_ctx->server = (void *)server;
proto_ctx->sock = sock;
proto_ctx->responder = FALSE;
+ proto_ctx->pfs = idata->rekey->pfs;
/* Perform rekey protocol. Will call the final callback after the
protocol is over. */
if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
/* Error occured during protocol */
+ silc_protocol_cancel(server->timeout_queue, protocol);
silc_protocol_free(protocol);
sock->protocol = NULL;
- if (ctx->keymat)
- silc_ske_free_key_material(ctx->keymat);
if (ctx->packet)
silc_packet_context_free(ctx->packet);
if (ctx->ske)
return;
}
- /* Take the keys into use */
- if (ctx->pfs == TRUE) {
-
- } else {
- /* Then just generate the new keys and take them into use */
- silc_server_protocol_rekey_generate(server, ctx);
- }
-
/* Cleanup */
silc_protocol_free(protocol);
sock->protocol = NULL;
- if (ctx->keymat)
- silc_ske_free_key_material(ctx->keymat);
if (ctx->packet)
silc_packet_context_free(ctx->packet);
if (ctx->ske)