X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=apps%2Fsilcd%2Fpacket_receive.c;h=f17e28546da22623d727fbc1ee90826b65544281;hb=1d2558fef038d7c846c477ab7f63985eab4790b7;hp=c6ec4501980cc43f3b725f9b72b6bc7777343d44;hpb=6f749a031aa242a4e9473b8e121d6a2676ce1e0b;p=silc.git diff --git a/apps/silcd/packet_receive.c b/apps/silcd/packet_receive.c index c6ec4501..f17e2854 100644 --- a/apps/silcd/packet_receive.c +++ b/apps/silcd/packet_receive.c @@ -316,10 +316,12 @@ static void silc_server_notify_process(SilcServer server, 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, @@ -337,6 +339,7 @@ static void silc_server_notify_process(SilcServer server, client->mode = 0; client->router = NULL; client->connection = NULL; + silc_dlist_add(server->expired_clients, client); break; case SILC_NOTIFY_TYPE_TOPIC_SET: @@ -1237,12 +1240,6 @@ static void silc_server_notify_process(SilcServer server, 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 : @@ -1459,11 +1456,12 @@ static void silc_server_notify_process(SilcServer server, 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--; @@ -1483,6 +1481,7 @@ static void silc_server_notify_process(SilcServer server, client->mode = 0; client->router = NULL; client->connection = NULL; + silc_dlist_add(server->expired_clients, client); break; } @@ -1639,11 +1638,6 @@ static void silc_server_notify_process(SilcServer server, 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); @@ -1891,7 +1885,6 @@ void silc_server_channel_message(SilcServer server, SilcChannelID id; SilcClientID cid; SilcID sid; - void *sender_id = NULL; SilcClientEntry sender_entry = NULL; SilcIDListData idata; SilcChannelClientEntry chl; @@ -1998,9 +1991,9 @@ void silc_server_channel_message(SilcServer server, /* 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: @@ -2123,12 +2116,30 @@ SilcClientEntry silc_server_new_client(SilcServer server, 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, @@ -2139,21 +2150,6 @@ SilcClientEntry silc_server_new_client(SilcServer server, 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 @@ -2167,6 +2163,7 @@ SilcClientEntry silc_server_new_client(SilcServer server, 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); @@ -2184,6 +2181,7 @@ SilcClientEntry silc_server_new_client(SilcServer server, 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); @@ -2659,19 +2657,20 @@ static void silc_server_new_id_real(SilcServer server, 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; @@ -3401,6 +3400,7 @@ void silc_server_resume_client(SilcServer server, 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), @@ -3647,21 +3647,34 @@ void silc_server_resume_client(SilcServer server, 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; @@ -3889,15 +3902,19 @@ void silc_server_resume_client(SilcServer server, /* 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)