SilcServerID *id;
SilcServerEntry id_entry;
SilcIDListPurge purge;
- SilcServerConfigSectionListenPort *listen;
SILC_LOG_DEBUG(("Initializing server"));
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) {
+ if (!server->config->server_info ||
+ !server->config->server_info->public_key ||
+ !server->config->server_info->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;
+ server->public_key = server->config->server_info->public_key;
+ server->private_key = server->config->server_info->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->protocol_timeout = 60;
server->params->require_reverse_mapping = FALSE;
- /* Set log files where log message should be saved. */
- server->config->server = server;
-
/* Register all configured ciphers, PKCS and hash functions. */
- if (!silc_server_config_register_ciphers(server->config))
+ if (!silc_server_config_register_ciphers(server))
silc_cipher_register_default();
- if (!silc_server_config_register_pkcs(server->config))
+ if (!silc_server_config_register_pkcs(server))
silc_pkcs_register_default();
- if (!silc_server_config_register_hashfuncs(server->config))
+ if (!silc_server_config_register_hashfuncs(server))
silc_hash_register_default();
- if (!silc_server_config_register_hmacs(server->config))
+ if (!silc_server_config_register_hmacs(server))
silc_hmac_register_default();
/* Initialize random number generator for the server. */
silc_hash_alloc("md5", &server->md5hash);
silc_hash_alloc("sha1", &server->sha1hash);
- /* Initialize none cipher */
- silc_cipher_alloc("none", &server->none_cipher);
-
/* 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);
/* Create a listening server. Note that our server can listen on multiple
ports. All listeners are created here and now. */
sock_count = 0;
- listen = server->config->listen_port;
- while(listen) {
+ while (1) {
int tmp;
- tmp = silc_net_create_server(server->config->listen_port->port,
- server->config->listen_port->listener_ip);
+ tmp = silc_net_create_server(server->config->server_info->port,
+ server->config->server_info->server_ip);
if (tmp < 0) {
- SILC_LOG_ERROR(("Could not create server listener: %s on %d",
- server->config->listen_port->listener_ip,
- server->config->listen_port->port));
- goto err0;
+ SILC_LOG_ERROR(("Could not create server listener: %s on %hd",
+ server->config->server_info->server_ip,
+ server->config->server_info->port));
+ goto err;
}
sock = silc_realloc(sock, sizeof(*sock) * (sock_count + 1));
sock[sock_count] = tmp;
sock_count++;
- listen = listen->next;
+ break;
}
/* Initialize ID caches */
newsocket->hostname ? newsocket->hostname :
newsocket->ip ? newsocket->ip : ""));
server->stat.conn_failures++;
- goto err0;
+ goto err;
}
if (!newsocket->hostname)
newsocket->hostname = strdup(newsocket->ip);
/* Create a Server ID for the server. */
silc_id_create_server_id(newsocket->ip, newsocket->port, server->rng, &id);
if (!id)
- goto err0;
+ goto err;
server->id = id;
server->id_string = silc_id_id2str(id, SILC_ID_SERVER);
server->server_type, server->id, NULL, NULL);
if (!id_entry) {
SILC_LOG_ERROR(("Could not add ourselves to cache"));
- goto err0;
+ goto err;
}
id_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
/* Initialize the scheduler. */
server->schedule = silc_schedule_init(SILC_SERVER_MAX_CONNECTIONS);
if (!server->schedule)
- goto err0;
+ goto err;
/* Add the first task to the scheduler. This is task that is executed by
timeout. It expires as soon as the caller calls silc_server_run. This
server->listenning = TRUE;
/* Send log file configuration */
- silc_server_config_setlogfiles(server->config, server->schedule);
+ silc_server_config_setlogfiles(server);
/* If server connections has been configured then we must be router as
normal server cannot have server connections, only router connections. */
if (server->config->servers) {
- SilcServerConfigSectionServerConnection *ptr = server->config->servers;
+ SilcServerConfigSectionServer *ptr = server->config->servers;
server->server_type = SILC_ROUTER;
while (ptr) {
/* We are done here, return succesfully */
return TRUE;
- err0:
+ err:
for (i = 0; i < sock_count; i++)
silc_net_close_server(sock[i]);
struct group *gr;
char *user, *group;
- if (!server->config->identity || !server->config->identity->user ||
- !server->config->identity->group) {
+ if (!server->config->server_info->user || !server->config->server_info->group) {
fprintf(stderr, "Error:"
"\tSILC server must not be run as root. For the security of your\n"
"\tsystem it is strongly suggested that you run SILC under dedicated\n"
}
/* Get the values given for user and group in configuration file */
- user=server->config->identity->user;
- group=server->config->identity->group;
+ user=server->config->server_info->user;
+ group=server->config->server_info->group;
/* Check whether the user/group information is text */
if (atoi(user)!=0 || atoi(group)!=0) {
server->router_connect = time(0);
/* Connect to remote host */
- sock = silc_net_create_connection(server->config->listen_port->local_ip,
+ sock = silc_net_create_connection(server->config->server_info->server_ip,
sconn->remote_port,
sconn->remote_host);
if (sock < 0) {
{
SilcServer server = (SilcServer)context;
SilcServerConnection sconn;
- SilcServerConfigSectionServerConnection *ptr;
+ SilcServerConfigSectionRouter *ptr;
SILC_LOG_DEBUG(("Connecting to router(s)"));
SilcServerConnection sconn = (SilcServerConnection)ctx->context;
SilcSocketConnection sock = ctx->sock;
SilcServerConnAuthInternalContext *proto_ctx;
- SilcServerConfigSectionServerConnection *conn = NULL;
+ SilcServerConfigSectionRouter *conn = NULL;
SILC_LOG_DEBUG(("Start"));
/* Resolve the authentication method used in this connection. Check if
we find a match from user configured connections */
- conn = silc_server_config_find_router_conn(server->config,
- sock->hostname,
+ conn = silc_server_config_find_router_conn(server, sock->hostname,
sock->port);
if (conn) {
/* Match found. Use the configured authentication method */
- proto_ctx->auth_meth = conn->auth_meth;
- if (conn->auth_data) {
- proto_ctx->auth_data = strdup(conn->auth_data);
- proto_ctx->auth_data_len = strlen(conn->auth_data);
+ if (conn->passphrase) {
+ if (conn->publickey && !server->config->prefer_passphrase_auth) {
+ proto_ctx->auth_data = conn->publickey;
+ proto_ctx->auth_data_len = 0;
+ proto_ctx->auth_meth = SILC_AUTH_PUBLIC_KEY;
+ } else {
+ proto_ctx->auth_data = strdup(conn->passphrase);
+ proto_ctx->auth_data_len = strlen(conn->passphrase);
+ proto_ctx->auth_meth = SILC_AUTH_PASSWORD;
+ }
+ } else if (conn->publickey) {
+ proto_ctx->auth_data = conn->publickey;
+ proto_ctx->auth_data_len = 0;
+ proto_ctx->auth_meth = SILC_AUTH_PUBLIC_KEY;
+ } else {
+ proto_ctx->auth_meth = SILC_AUTH_NONE;
}
} else {
SILC_LOG_ERROR(("Could not find connection data for %s (%s) on port",
timeout!! */
hb_context = silc_calloc(1, sizeof(*hb_context));
hb_context->server = server;
- silc_socket_set_heartbeat(sock, 600, hb_context,
+ silc_socket_set_heartbeat(sock, 300, hb_context,
silc_server_perform_heartbeat,
server->schedule);
silc_packet_context_free(ctx->packet);
if (ctx->ske)
silc_ske_free(ctx->ske);
- silc_free(ctx->auth_data);
+ if (ctx->auth_meth == SILC_AUTH_PASSWORD)
+ silc_free(ctx->auth_data);
silc_free(ctx);
}
SilcServer server = (SilcServer)context;
SilcServerKEInternalContext *proto_ctx;
void *cconfig, *sconfig, *rconfig;
- SilcServerConfigSectionDenyConnection *deny;
+ SilcServerConfigSectionDeny *deny;
int port;
SILC_LOG_DEBUG(("Start"));
port = server->sockets[server->sock]->port; /* Listenning port */
/* Check whether this connection is denied to connect to us. */
- deny = silc_server_config_denied_conn(server->config, sock->ip, port);
+ deny = silc_server_config_find_denied(server, sock->ip, port);
if (!deny)
- deny = silc_server_config_denied_conn(server->config, sock->hostname,
- port);
+ deny = silc_server_config_find_denied(server, sock->hostname, port);
if (deny) {
/* The connection is denied */
SILC_LOG_INFO(("Connection %s (%s) is denied",
sock->hostname, sock->ip));
- silc_server_disconnect_remote(server, sock, deny->comment ?
- deny->comment :
+ silc_server_disconnect_remote(server, sock, deny->reason ?
+ deny->reason :
"Server closed connection: "
"Connection refused");
server->stat.conn_failures++;
/* 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,
- sock->ip, port)))
- cconfig = silc_server_config_find_client_conn(server->config,
- sock->hostname,
- port);
- if (!(sconfig = silc_server_config_find_server_conn(server->config,
- sock->ip,
- port)))
- sconfig = silc_server_config_find_server_conn(server->config,
- sock->hostname,
- port);
- if (!(rconfig = silc_server_config_find_router_conn(server->config,
- sock->ip, port)))
- rconfig = silc_server_config_find_router_conn(server->config,
- sock->hostname,
- port);
+ if (!(cconfig = silc_server_config_find_client(server, sock->ip, port)))
+ cconfig = silc_server_config_find_client(server, sock->hostname, port);
+ if (!(sconfig = silc_server_config_find_server_conn(server, sock->ip)))
+ sconfig = silc_server_config_find_server_conn(server, sock->hostname);
+ if (!(rconfig = silc_server_config_find_router_conn(server, sock->ip, port)))
+ rconfig = silc_server_config_find_router_conn(server, sock->hostname,
+ sock->port);
if (!cconfig && !sconfig && !rconfig) {
- SILC_LOG_INFO(("Connection %s (%s) is not allowed",
- sock->hostname, sock->ip));
+ SILC_LOG_INFO(("Connection %s (%s) is not allowed", sock->hostname,
+ sock->ip));
silc_server_disconnect_remote(server, sock,
"Server closed connection: "
"Connection refused");
case SILC_SOCKET_TYPE_ROUTER:
{
SilcServerEntry new_server;
- SilcServerConfigSectionServerConnection *conn =
+ /* XXX FIXME: Now server and router has different table, so this is probably broken. */
+ SilcServerConfigSectionRouter *conn =
ctx->conn_type == SILC_SOCKET_TYPE_SERVER ?
ctx->sconfig : ctx->rconfig;
/* Check whether this connection is to be our primary router connection
if we do not already have the primary route. */
if (server->standalone && ctx->conn_type == SILC_SOCKET_TYPE_ROUTER) {
- if (silc_server_config_is_primary_route(server->config) &&
+ if (silc_server_config_is_primary_route(server) &&
!conn->initiator)
break;
timeout!! */
hb_context = silc_calloc(1, sizeof(*hb_context));
hb_context->server = server;
- silc_socket_set_heartbeat(sock, 600, hb_context,
+ silc_socket_set_heartbeat(sock, 400, hb_context,
silc_server_perform_heartbeat,
server->schedule);
silc_hash_table_del(channel->user_list, chl2->client);
silc_free(chl2);
}
+ silc_hash_table_list_reset(&htl2);
continue;
}
if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
/* Re-generate channel key */
if (!silc_server_create_channel_key(server, channel, 0))
- return;
+ goto out;
/* Send the channel key to the channel. The key of course is not sent
to the client who was removed from the channel. */
}
}
+ out:
+ silc_hash_table_list_reset(&htl);
silc_buffer_free(clidp);
}
silc_hash_table_del(channel->user_list, chl2->client);
silc_free(chl2);
}
+ silc_hash_table_list_reset(&htl2);
return FALSE;
}
channel_name = strdup(channel_name);
- /* Create the channel */
+ /* Create the channel ID */
if (!silc_id_create_channel_id(server, router_id, server->rng,
&channel_id)) {
silc_free(channel_name);
silc_hmac_free(newhmac);
return NULL;
}
+
+ /* Create the channel */
entry = silc_idlist_add_channel(server->local_list, channel_name,
SILC_CHANNEL_MODE_NONE, channel_id,
NULL, key, newhmac, 0);
silc_free(channel_name);
silc_cipher_free(key);
silc_hmac_free(newhmac);
+ silc_free(channel_id);
return NULL;
}
/* Now create the actual key material */
if (!silc_server_create_channel_key(server, entry,
silc_cipher_get_key_len(key) / 8)) {
- silc_free(channel_name);
- silc_cipher_free(key);
- silc_hmac_free(newhmac);
- silc_free(entry->cipher);
- silc_free(entry->hmac_name);
+ silc_idlist_del_channel(server->local_list, entry);
return NULL;
}
SILC_CHANNEL_MODE_NONE, channel_id,
NULL, key, newhmac, 0);
if (!entry) {
+ silc_cipher_free(key);
+ silc_hmac_free(newhmac);
silc_free(channel_name);
return NULL;
}
/* Now create the actual key material */
if (!silc_server_create_channel_key(server, entry,
silc_cipher_get_key_len(key) / 8)) {
- silc_free(channel_name);
+ silc_idlist_del_channel(server->local_list, entry);
return NULL;
}
SILC_LOG_DEBUG(("Start"));
/* Decode channel key payload */
- payload = silc_channel_key_payload_parse(key_payload->data,
+ payload = silc_channel_key_payload_parse(key_payload->data,
key_payload->len);
if (!payload) {
SILC_LOG_ERROR(("Bad channel key payload received, dropped"));
if (!channel) {
channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
if (!channel) {
- SILC_LOG_ERROR(("Received key for non-existent channel"));
+ SILC_LOG_ERROR(("Received key for non-existent channel %s",
+ silc_id_render(id, SILC_ID_CHANNEL)));
goto out;
}
}
{
SilcServerHBContext hb = (SilcServerHBContext)hb_context;
- SILC_LOG_DEBUG(("Sending heartbeat to %s (%s)", sock->hostname,
- sock->ip));
+ SILC_LOG_DEBUG(("Sending heartbeat to %s (%s)", sock->hostname, sock->ip));
/* Send the heartbeat */
silc_server_send_heartbeat(hb->server, sock);
silc_buffer_free(clidp);
}
+ silc_hash_table_list_reset(&htl);
silc_buffer_free(chidp);
}
int i;
for (i = 0; i < channel_users_modes_c; i++) {
+ if (!channel_users_modes[i])
+ continue;
silc_buffer_push(channel_users_modes[i],
channel_users_modes[i]->data -
channel_users_modes[i]->head);
silc_hash_table_list(channel->user_list, &htl);
while (silc_hash_table_get(&htl, NULL, (void *)&chl))
len += (silc_id_get_len(chl->client->id, SILC_ID_CLIENT) + 4);
+ silc_hash_table_list_reset(&htl);
client_id_list = silc_buffer_alloc(len);
client_mode_list =
list_count++;
}
+ silc_hash_table_list_reset(&htl);
silc_buffer_push(client_id_list,
client_id_list->data - client_id_list->head);
silc_buffer_push(client_mode_list,
silc_buffer_pull(buffer, len);
silc_free(cid);
}
+ silc_hash_table_list_reset(&htl);
if (buffer)
silc_buffer_push(buffer, buffer->data - buffer->head);