X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=apps%2Fsilcd%2Fserver.c;h=f0ed13f8e6b1950302bfdb8045d0f1e150ffcdb1;hb=d47a87b03b846e2333ef57b2c0d81f1644992964;hp=e894d964ae17e06a933a14f55ab6310fbef332fe;hpb=2098fa97e35cddd1903eac0b22d0efa7fd703adf;p=silc.git diff --git a/apps/silcd/server.c b/apps/silcd/server.c index e894d964..f0ed13f8 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -115,21 +115,20 @@ int silc_server_init(SilcServer server) 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 */ @@ -141,17 +140,14 @@ int silc_server_init(SilcServer server) 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. */ @@ -163,9 +159,6 @@ int silc_server_init(SilcServer 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); @@ -174,24 +167,23 @@ int silc_server_init(SilcServer server) /* 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)); + SILC_LOG_ERROR(("Could not create server listener: %s on %hd", + server->config->server_info->server_ip, + server->config->server_info->port)); goto err0; } sock = silc_realloc(sock, sizeof(*sock) * (sock_count + 1)); sock[sock_count] = tmp; sock_count++; - listen = listen->next; + break; } /* Initialize ID caches */ @@ -310,7 +302,7 @@ int silc_server_init(SilcServer 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) { @@ -393,8 +385,7 @@ void silc_server_drop(SilcServer server) 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" @@ -404,8 +395,8 @@ void silc_server_drop(SilcServer server) } /* 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) { @@ -638,7 +629,7 @@ SILC_TASK_CALLBACK(silc_server_connect_router) 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) { @@ -665,7 +656,7 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router) { SilcServer server = (SilcServer)context; SilcServerConnection sconn; - SilcServerConfigSectionServerConnection *ptr; + SilcServerConfigSectionRouter *ptr; SILC_LOG_DEBUG(("Connecting to router(s)")); @@ -732,7 +723,7 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_second) SilcServerConnection sconn = (SilcServerConnection)ctx->context; SilcSocketConnection sock = ctx->sock; SilcServerConnAuthInternalContext *proto_ctx; - SilcServerConfigSectionServerConnection *conn = NULL; + SilcServerConfigSectionRouter *conn = NULL; SILC_LOG_DEBUG(("Start")); @@ -952,7 +943,7 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_final) 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); @@ -1027,7 +1018,7 @@ silc_server_accept_new_connection_lookup(SilcSocketConnection sock, SilcServer server = (SilcServer)context; SilcServerKEInternalContext *proto_ctx; void *cconfig, *sconfig, *rconfig; - SilcServerConfigSectionDenyConnection *deny; + SilcServerConfigSectionDeny *deny; int port; SILC_LOG_DEBUG(("Start")); @@ -1058,16 +1049,16 @@ silc_server_accept_new_connection_lookup(SilcSocketConnection sock, 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->config, sock->ip, port); if (!deny) - deny = silc_server_config_denied_conn(server->config, sock->hostname, + deny = silc_server_config_find_denied(server->config, 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++; @@ -1077,9 +1068,9 @@ silc_server_accept_new_connection_lookup(SilcSocketConnection 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, + if (!(cconfig = silc_server_config_find_client(server->config, sock->ip, port))) - cconfig = silc_server_config_find_client_conn(server->config, + cconfig = silc_server_config_find_client(server->config, sock->hostname, port); if (!(sconfig = silc_server_config_find_server_conn(server->config, @@ -1299,7 +1290,7 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final) SilcSocketConnection sock = ctx->sock; SilcServerHBContext hb_context; SilcUnknownEntry entry = (SilcUnknownEntry)sock->user_data; - void *id_entry = NULL; + void *id_entry; SILC_LOG_DEBUG(("Start")); @@ -1361,7 +1352,8 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final) 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; @@ -1441,15 +1433,15 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final) break; } default: + goto out; break; } sock->type = ctx->conn_type; /* Add the common data structure to the ID entry. */ - if (id_entry) - silc_idlist_add_data(id_entry, (SilcIDListData)sock->user_data); - + silc_idlist_add_data(id_entry, (SilcIDListData)sock->user_data); + /* Add to sockets internal pointer for fast referencing */ silc_free(sock->user_data); sock->user_data = id_entry; @@ -1462,7 +1454,7 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final) 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); @@ -2607,6 +2599,7 @@ void silc_server_remove_from_channels(SilcServer server, silc_hash_table_del(channel->user_list, chl2->client); silc_free(chl2); } + silc_hash_table_list_reset(&htl2); continue; } @@ -2631,7 +2624,7 @@ void silc_server_remove_from_channels(SilcServer server, 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. */ @@ -2641,6 +2634,8 @@ void silc_server_remove_from_channels(SilcServer server, } } + out: + silc_hash_table_list_reset(&htl); silc_buffer_free(clidp); } @@ -2727,6 +2722,7 @@ int silc_server_remove_from_one_channel(SilcServer server, silc_hash_table_del(channel->user_list, chl2->client); silc_free(chl2); } + silc_hash_table_list_reset(&htl2); return FALSE; } @@ -2815,7 +2811,7 @@ SilcChannelEntry silc_server_create_new_channel(SilcServer server, 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); @@ -2823,6 +2819,8 @@ SilcChannelEntry silc_server_create_new_channel(SilcServer server, 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); @@ -2830,6 +2828,7 @@ SilcChannelEntry silc_server_create_new_channel(SilcServer server, silc_free(channel_name); silc_cipher_free(key); silc_hmac_free(newhmac); + silc_free(channel_id); return NULL; } @@ -2839,11 +2838,7 @@ SilcChannelEntry silc_server_create_new_channel(SilcServer server, /* 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; } @@ -2898,6 +2893,8 @@ silc_server_create_new_channel_with_id(SilcServer server, 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; } @@ -2905,7 +2902,7 @@ silc_server_create_new_channel_with_id(SilcServer server, /* 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; } @@ -3032,7 +3029,7 @@ SilcChannelEntry silc_server_save_channel_key(SilcServer server, 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")); @@ -3055,7 +3052,8 @@ SilcChannelEntry silc_server_save_channel_key(SilcServer server, 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; } } @@ -3140,8 +3138,7 @@ void silc_server_perform_heartbeat(SilcSocketConnection sock, { 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); @@ -3435,6 +3432,7 @@ void silc_server_announce_get_channel_users(SilcServer server, silc_buffer_free(clidp); } + silc_hash_table_list_reset(&htl); silc_buffer_free(chidp); } @@ -3597,6 +3595,8 @@ void silc_server_announce_channels(SilcServer server, 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); @@ -3676,6 +3676,7 @@ void silc_server_get_users_on_channel(SilcServer server, 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 = @@ -3697,6 +3698,7 @@ void silc_server_get_users_on_channel(SilcServer server, 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, @@ -3921,6 +3923,7 @@ SilcBuffer silc_server_get_client_channel_list(SilcServer server, silc_buffer_pull(buffer, len); silc_free(cid); } + silc_hash_table_list_reset(&htl); if (buffer) silc_buffer_push(buffer, buffer->data - buffer->head);