SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
silc_schedule_task_del_by_context(server->schedule, client);
- /* Remove from public key hash table. */
- if (client->data.public_key)
- silc_hash_table_del_by_context(server->pk_hash, client->data.public_key,
- client);
+ /* Remove client's public key from repository, this will free it too. */
+ if (client->data.public_key) {
+ silc_skr_del_public_key(server->repository, client->data.public_key,
+ client);
+ client->data.public_key = NULL;
+ }
/* Remove the client from all channels. */
silc_server_remove_from_channels(server, NULL, client, TRUE,
client->mode = 0;
client->router = NULL;
client->connection = NULL;
+ silc_dlist_add(server->expired_clients, client);
break;
case SILC_NOTIFY_TYPE_TOPIC_SET:
if (local)
silc_server_del_from_watcher_list(server, client);
- /* Remove from public key hash table. */
- if (client->data.public_key)
- silc_hash_table_del_by_context(server->pk_hash,
- client->data.public_key,
- client);
-
/* Remove the client */
silc_idlist_del_data(client);
silc_idlist_del_client(local ? server->local_list :
silc_server_check_watcher_list(server, client, NULL,
SILC_NOTIFY_TYPE_KILLED);
- /* Remove from public key hash table. */
- if (client->data.public_key)
- silc_hash_table_del_by_context(server->pk_hash,
- client->data.public_key,
- client);
+ /* Remove client's public key from repository, this will free it too. */
+ if (client->data.public_key) {
+ silc_skr_del_public_key(server->repository, client->data.public_key,
+ client);
+ client->data.public_key = NULL;
+ }
/* Update statistics */
server->stat.clients--;
client->mode = 0;
client->router = NULL;
client->connection = NULL;
+ silc_dlist_add(server->expired_clients, client);
break;
}
if (!client)
goto out;
- if (client->data.public_key)
- silc_hash_table_del_by_context(server->pk_hash,
- client->data.public_key,
- client);
-
silc_server_remove_from_channels(server, NULL, client, TRUE,
NULL, TRUE, FALSE);
silc_idlist_del_data(client);
SilcChannelID id;
SilcClientID cid;
SilcID sid;
- void *sender_id = NULL;
SilcClientEntry sender_entry = NULL;
SilcIDListData idata;
SilcChannelClientEntry chl;
/* Distribute the packet to our local clients. This will send the
packet for further routing as well, if needed. */
- silc_server_packet_relay_to_channel(server, sock, channel, sender_id,
- packet->src_id_type, sender_entry,
- packet->buffer.data,
+ silc_server_packet_relay_to_channel(server, sock, channel,
+ SILC_ID_GET_ID(sid), sid.type,
+ sender_entry, packet->buffer.data,
silc_buffer_len(&packet->buffer));
out:
username[username_len - 1] = '\0';
}
+ /* Take nickname from NEW_CLIENT packet, if present */
+ if (silc_buffer_unformat(buffer,
+ SILC_STR_UI16_NSTRING_ALLOC(&nickname,
+ &nickname_len),
+ SILC_STR_END)) {
+ if (nickname_len > 128) {
+ nickname_len = 128;
+ nickname[nickname_len - 1] = '\0';
+ }
+ }
+
+ /* Nickname is initially same as username, if not present in NEW_CLIENT */
+ if (!nickname) {
+ nickname = strdup(username);
+ nickname_len = strlen(nickname);
+ }
+
/* Check for valid username string */
- nicknamec = silc_identifier_check(username, username_len,
+ nicknamec = silc_identifier_check(nickname, nickname_len,
SILC_STRING_UTF8, 128, &tmp_len);
if (!nicknamec) {
silc_free(username);
silc_free(realname);
+ silc_free(nickname);
SILC_LOG_ERROR(("Client %s (%s) sent bad username string '%s', closing "
"connection", hostname, ip, username));
silc_server_disconnect_remote(server, sock,
return NULL;
}
- /* Take nickname from NEW_CLIENT packet, if present */
- if (silc_buffer_unformat(buffer,
- SILC_STR_UI16_NSTRING_ALLOC(&nickname,
- &nickname_len),
- SILC_STR_END)) {
- if (nickname_len > 128) {
- nickname_len = 128;
- nickname[nickname_len - 1] = '\0';
- }
- }
-
- /* Nickname is initially same as username, if not present in NEW_CLIENT */
- if (!nickname)
- nickname = strdup(username);
-
/* Make sanity checks for the hostname of the client. If the hostname
is provided in the `username' check that it is the same than the
resolved hostname, or if not resolved the hostname that appears in
host = silc_memdup(username + tlen + 1, strlen(username) - tlen - 1);
if (strcmp(hostname, ip) && strcmp(hostname, host)) {
+ silc_free(nickname);
silc_free(username);
silc_free(host);
silc_free(realname);
client->data.public_key);
phostname = strdup(silc_pubkey->identifier.host);
if (!strcmp(hostname, ip) && phostname && strcmp(phostname, host)) {
+ silc_free(nickname);
silc_free(username);
silc_free(host);
silc_free(phostname);
silc_server_check_watcher_list(server, entry, NULL, 0);
if (server->server_type == SILC_ROUTER) {
- /* Add the client's public key to hash table or get the key with
+ /* Add the client's public key to repository or get the key with
GETKEY command. */
if (entry->data.public_key) {
- if (!silc_hash_table_find_by_context(server->pk_hash,
- entry->data.public_key,
- entry, NULL))
- silc_hash_table_add(server->pk_hash, entry->data.public_key,
- entry);
- } else
+ if (!silc_server_get_public_key_by_client(server, entry, NULL))
+ silc_skr_add_public_key_simple(server->repository,
+ entry->data.public_key,
+ SILC_SKR_USAGE_IDENTIFICATION,
+ entry, NULL);
+ } else {
silc_server_send_command(server, router_sock,
SILC_COMMAND_GETKEY, ++server->cmd_ident,
1, 1, buffer->data,
silc_buffer_len(buffer));
+ }
}
}
break;
SilcHashTableList htl;
SilcChannelClientEntry chl;
SilcServerResumeResolve r;
+ SilcPublicKey public_key;
const char *cipher, *hostname, *ip;
silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
silc_packet_set_context(sock, detached_client);
detached_client->connection = sock;
- if (detached_client->data.public_key)
- silc_hash_table_del_by_context(server->pk_hash,
- detached_client->data.public_key,
- detached_client);
- if (idata->public_key)
- silc_hash_table_del_by_context(server->pk_hash,
- idata->public_key, idata);
+ if (detached_client->data.public_key) {
+ /* Delete the detached client's public key from repository */
+ silc_skr_del_public_key(server->repository,
+ detached_client->data.public_key,
+ detached_client);
+ detached_client->data.public_key = NULL;
+ }
+
+ if (idata->public_key) {
+ /* Delete the resuming client's public key from repository. It will
+ be added later again. */
+ public_key = silc_pkcs_public_key_copy(idata->public_key);
+ silc_skr_del_public_key(server->repository, idata->public_key, idata);
+ idata->public_key = public_key;
+ }
/* Take new keys and stuff into use in the old entry */
silc_idlist_del_data(detached_client);
silc_idlist_add_data(detached_client, idata);
- if (detached_client->data.public_key)
- silc_hash_table_add(server->pk_hash,
- detached_client->data.public_key, detached_client);
+ if (detached_client->data.public_key) {
+ /* Add the resumed client's public key back to repository. */
+ if (!silc_server_get_public_key_by_client(server, detached_client, NULL))
+ silc_skr_add_public_key_simple(server->repository,
+ detached_client->data.public_key,
+ SILC_SKR_USAGE_IDENTIFICATION,
+ detached_client, NULL);
+ }
detached_client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
/* Client is detached, and now it is resumed. Remove the detached
mode and mark that it is resumed. */
- if (detached_client->data.public_key)
- silc_hash_table_del_by_context(server->pk_hash,
- detached_client->data.public_key,
- detached_client);
+ if (detached_client->data.public_key) {
+ /* Delete the detached client's public key from repository */
+ silc_skr_del_public_key(server->repository,
+ detached_client->data.public_key,
+ detached_client);
+ detached_client->data.public_key = NULL;
+ }
silc_idlist_del_data(detached_client);
detached_client->mode &= ~SILC_UMODE_DETACHED;
detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
detached_client->data.status &= ~SILC_IDLIST_STATUS_LOCAL;
+ silc_dlist_del(server->expired_clients, detached_client);
/* Check if anyone is watching this client */
if (server->server_type == SILC_ROUTER)