if (server->rng)
silc_rng_free(server->rng);
+ if (server->pkcs)
+ silc_pkcs_free(server->pkcs);
+
#ifdef SILC_SIM
while ((sim = silc_dlist_get(server->sim)) != SILC_LIST_END) {
silc_dlist_del(server->sim, sim);
SilcServerID *id;
SilcServerEntry id_entry;
SilcIDListPurge purge;
+ SilcServerConfigSectionListenPort *listen;
SILC_LOG_DEBUG(("Initializing server"));
assert(server);
/* Initialize none cipher */
silc_cipher_alloc("none", &server->none_cipher);
- /* 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. */
+ /* Allocate PKCS context for local public and private keys */
+ silc_pkcs_alloc(server->public_key->name, &server->pkcs);
+ silc_pkcs_public_key_set(server->pkcs, server->public_key);
+ silc_pkcs_private_key_set(server->pkcs, server->private_key);
+
+ /* Create a listening server. Note that our server can listen on multiple
+ ports. All listeners are created here and now. */
sock_count = 0;
- while(server->config->listen_port) {
+ listen = server->config->listen_port;
+ while(listen) {
int tmp;
tmp = silc_net_create_server(server->config->listen_port->port,
- server->config->listen_port->host);
+ server->config->listen_port->listener_ip);
if (tmp < 0)
goto err0;
sock = silc_realloc(sock, (sizeof(int *) * (sock_count + 1)));
sock[sock_count] = tmp;
- server->config->listen_port = server->config->listen_port->next;
sock_count++;
+ listen = listen->next;
}
/* Initialize ID caches */
SILC_LOG_ERROR(("Could not add ourselves to cache"));
goto err0;
}
- id_entry->data.registered = TRUE;
+ id_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
/* Add ourselves also to the socket table. The entry allocated above
is sent as argument for fast referencing in the future. */
sconn->remote_host, sconn->remote_port));
/* Connect to remote host */
- sock = silc_net_create_connection(sconn->remote_port,
+ sock = silc_net_create_connection(server->config->listen_port->local_ip,
+ sconn->remote_port,
sconn->remote_host);
if (sock < 0) {
SILC_LOG_ERROR(("Could not connect to router"));
silc_free(ctx->dest_id);
silc_free(ctx);
silc_schedule_task_del_by_callback(server->schedule,
- silc_server_failure_callback);
+ silc_server_failure_callback);
silc_server_disconnect_remote(server, sock, "Server closed connection: "
"Key exchange failed");
return;
silc_buffer_free(packet);
silc_free(id_string);
- SILC_LOG_DEBUG(("Connected to router %s", sock->hostname));
+ SILC_LOG_INFO(("Connected to router %s", sock->hostname));
/* Add the connected router to local server list */
server->standalone = FALSE;
server->id_entry->router = id_entry;
server->router = id_entry;
idata = (SilcIDListData)sock->user_data;
- idata->registered = TRUE;
+ idata->status |= SILC_IDLIST_STATUS_REGISTERED;
/* Perform keepalive. The `hb_context' will be freed automatically
when finally calling the silc_socket_free function. XXX hardcoded
SilcServer server = (SilcServer)ctx->server;
SilcSocketConnection sock = ctx->sock;
SilcServerHBContext hb_context;
+ SilcUnknownEntry entry = (SilcUnknownEntry)sock->user_data;
void *id_entry = NULL;
SILC_LOG_DEBUG(("Start"));
return;
}
- switch(ctx->conn_type) {
+ entry->data.last_receive = time(NULL);
+
+ switch (ctx->conn_type) {
case SILC_SOCKET_TYPE_CLIENT:
{
SilcClientEntry client;
out:
silc_schedule_task_del_by_callback(server->schedule,
- silc_server_failure_callback);
+ silc_server_failure_callback);
silc_protocol_free(protocol);
if (ctx->packet)
silc_packet_context_free(ctx->packet);
/* Get keys and stuff from ID entry */
idata = (SilcIDListData)sock->user_data;
if (idata) {
- idata->last_receive = time(NULL);
cipher = idata->receive_key;
hmac = idata->hmac_receive;
}
case SILC_SOCKET_TYPE_CLIENT:
/* Parse the packet with timeout */
silc_schedule_task_add(server->schedule, sock->sock,
- silc_server_packet_parse_real,
- (void *)parser_context, 0, 100000,
- SILC_TASK_TIMEOUT,
- SILC_TASK_PRI_NORMAL);
+ silc_server_packet_parse_real,
+ (void *)parser_context, 0, 100000,
+ SILC_TASK_TIMEOUT,
+ SILC_TASK_PRI_NORMAL);
break;
case SILC_SOCKET_TYPE_SERVER:
case SILC_SOCKET_TYPE_ROUTER:
/* Packets from servers are parsed as soon as possible */
silc_schedule_task_add(server->schedule, sock->sock,
- silc_server_packet_parse_real,
- (void *)parser_context, 0, 1,
- SILC_TASK_TIMEOUT,
- SILC_TASK_PRI_NORMAL);
+ silc_server_packet_parse_real,
+ (void *)parser_context, 0, 1,
+ SILC_TASK_TIMEOUT,
+ SILC_TASK_PRI_NORMAL);
break;
default:
return;
SilcPacketContext *packet)
{
SilcPacketType type = packet->type;
+ SilcIDListData idata = (SilcIDListData)sock->user_data;
SILC_LOG_DEBUG(("Parsing packet type %d", type));
/* Parse the packet type */
- switch(type) {
+ switch (type) {
case SILC_PACKET_DISCONNECT:
SILC_LOG_DEBUG(("Disconnect packet"));
if (packet->flags & SILC_PACKET_FLAG_LIST)
SILC_LOG_DEBUG(("Channel Message packet"));
if (packet->flags & SILC_PACKET_FLAG_LIST)
break;
+ idata->last_receive = time(NULL);
silc_server_channel_message(server, sock, packet);
break;
SILC_LOG_DEBUG(("Private Message packet"));
if (packet->flags & SILC_PACKET_FLAG_LIST)
break;
+ idata->last_receive = time(NULL);
silc_server_private_message(server, sock, packet);
break;
sconn->remote_port = port;
silc_schedule_task_add(server->schedule, 0,
- silc_server_connect_router,
- (void *)sconn, 0, 1, SILC_TASK_TIMEOUT,
- SILC_TASK_PRI_NORMAL);
+ silc_server_connect_router,
+ (void *)sconn, 0, 1, SILC_TASK_TIMEOUT,
+ SILC_TASK_PRI_NORMAL);
}
SILC_TASK_CALLBACK(silc_server_close_connection_final)
i->server = server;
i->client = client;
silc_schedule_task_add(server->schedule, 0,
- silc_server_free_client_data_timeout,
- (void *)i, 300, 0,
- SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
- client->data.registered = FALSE;
+ silc_server_free_client_data_timeout,
+ (void *)i, 300, 0,
+ SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
+ client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
client->router = NULL;
client->connection = NULL;
{
SILC_LOG_DEBUG(("Start"));
- switch(sock->type) {
+ switch (sock->type) {
case SILC_SOCKET_TYPE_CLIENT:
{
SilcClientEntry user_data = (SilcClientEntry)sock->user_data;
if (silc_idcache_list_first(list, &id_cache)) {
while (id_cache) {
client = (SilcClientEntry)id_cache->context;
- if (client->data.registered == FALSE) {
+ if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
if (!silc_idcache_list_next(list, &id_cache))
break;
else
if (silc_idcache_list_first(list, &id_cache)) {
while (id_cache) {
client = (SilcClientEntry)id_cache->context;
- if (client->data.registered == FALSE) {
+ if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
if (!silc_idcache_list_next(list, &id_cache))
break;
else
while (silc_hash_table_get(&htl, NULL, (void *)&channel)) {
if (!silc_server_create_channel_key(server, channel, 0))
return FALSE;
+
+ /* Do not send the channel key if private channel key mode is set */
+ if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY)
+ continue;
+
silc_server_send_channel_key(server, NULL, channel,
server->server_type == SILC_ROUTER ?
FALSE : !server->standalone);
SILC_LOG_DEBUG(("Creating new channel"));
if (!cipher)
- cipher = "aes-256-cbc";
+ cipher = SILC_DEFAULT_CIPHER;
if (!hmac)
- hmac = "hmac-sha1-96";
+ hmac = SILC_DEFAULT_HMAC;
/* Allocate cipher */
if (!silc_cipher_alloc(cipher, &key))
SILC_LOG_DEBUG(("Creating new channel"));
if (!cipher)
- cipher = "aes-256-cbc";
+ cipher = SILC_DEFAULT_CIPHER;
if (!hmac)
- hmac = "hmac-sha1-96";
+ hmac = SILC_DEFAULT_HMAC;
/* Allocate cipher */
if (!silc_cipher_alloc(cipher, &key))
SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
SilcServer server = (SilcServer)rekey->context;
+ rekey->task = NULL;
+
if (!silc_server_create_channel_key(server, rekey->channel, rekey->key_len))
return;
+
silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
}
}
if (!channel->channel_key)
- if (!silc_cipher_alloc("aes-256-cbc", &channel->channel_key))
+ if (!silc_cipher_alloc(SILC_DEFAULT_CIPHER, &channel->channel_key))
return FALSE;
if (key_len)
/* Generate HMAC key from the channel key data and set it */
if (!channel->hmac)
- silc_hmac_alloc("hmac-sha1-96", NULL, &channel->hmac);
+ silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac);
silc_hash_make(channel->hmac->hash, channel->key, len, hash);
silc_hmac_set_key(channel->hmac, hash, silc_hash_len(channel->hmac->hash));
memset(hash, 0, sizeof(hash));
channel->rekey->context = (void *)server;
channel->rekey->channel = channel;
channel->rekey->key_len = key_len;
+ if (channel->rekey->task)
+ silc_schedule_task_del(server->schedule, channel->rekey->task);
- silc_schedule_task_add(server->schedule, 0,
- silc_server_channel_key_rekey,
- (void *)channel->rekey, 3600, 0,
- SILC_TASK_TIMEOUT,
- SILC_TASK_PRI_NORMAL);
+ channel->rekey->task =
+ silc_schedule_task_add(server->schedule, 0,
+ silc_server_channel_key_rekey,
+ (void *)channel->rekey, 3600, 0,
+ SILC_TASK_TIMEOUT,
+ SILC_TASK_PRI_NORMAL);
}
return TRUE;
/* Generate HMAC key from the channel key data and set it */
if (!channel->hmac)
- silc_hmac_alloc("hmac-sha1-96", NULL, &channel->hmac);
+ silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac);
silc_hash_make(channel->hmac->hash, tmp, tmp_len, hash);
silc_hmac_set_key(channel->hmac, hash, silc_hash_len(channel->hmac->hash));
channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
channel->rekey->context = (void *)server;
channel->rekey->channel = channel;
+ if (channel->rekey->task)
+ silc_schedule_task_del(server->schedule, channel->rekey->task);
- silc_schedule_task_del_by_callback(server->schedule,
- silc_server_channel_key_rekey);
- silc_schedule_task_add(server->schedule, 0,
- silc_server_channel_key_rekey,
- (void *)channel->rekey, 3600, 0,
- SILC_TASK_TIMEOUT,
- SILC_TASK_PRI_NORMAL);
+ channel->rekey->task =
+ silc_schedule_task_add(server->schedule, 0,
+ silc_server_channel_key_rekey,
+ (void *)channel->rekey, 3600, 0,
+ SILC_TASK_TIMEOUT,
+ SILC_TASK_PRI_NORMAL);
}
out:
- if (id)
- silc_free(id);
+ silc_free(id);
if (payload)
silc_channel_key_payload_free(payload);
form is dictated by the New ID payload. */
static void silc_server_announce_get_servers(SilcServer server,
+ SilcServerEntry remote,
SilcIDList id_list,
SilcBuffer *servers)
{
while (id_cache) {
entry = (SilcServerEntry)id_cache->context;
+ /* Do not announce the one we've sending our announcements and
+ do not announce ourself. */
+ if (entry == remote || entry == server->id_entry) {
+ if (!silc_idcache_list_next(list, &id_cache))
+ break;
+ continue;
+ }
+
idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
*servers = silc_buffer_realloc(*servers,
SILC_LOG_DEBUG(("Announcing servers"));
/* Get servers in local list */
- silc_server_announce_get_servers(server, server->local_list, &servers);
+ silc_server_announce_get_servers(server, server->router,
+ server->local_list, &servers);
/* Get servers in global list */
- silc_server_announce_get_servers(server, server->global_list, &servers);
+ silc_server_announce_get_servers(server, server->router,
+ server->global_list, &servers);
if (servers) {
silc_buffer_push(servers, servers->data - servers->head);
{
int i;
- /* Cache the received Client ID's and modes. This cache expires
- whenever server sends notify message to channel. It means two things;
- some user has joined or leaved the channel. XXX TODO! */
for (i = 0; i < user_count; i++) {
uint16 idp_len;
uint32 mode;
continue;
}
- client->data.registered = TRUE;
+ client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
}
silc_free(client_id);
if (!client || !client->nickname || !client->username) {
SilcBuffer buffer, idp;
+ client->data.status |= SILC_IDLIST_STATUS_RESOLVING;
+ client->data.status &= ~SILC_IDLIST_STATUS_RESOLVED;
+ client->resolve_cmd_ident = ++server->cmd_ident;
+
idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
buffer = silc_command_payload_encode_va(SILC_COMMAND_WHOIS,
- ++server->cmd_ident, 1,
+ server->cmd_ident, 1,
3, idp->data, idp->len);
silc_server_packet_send(server, client ? client->router->connection :
server->router->connection,