From d240437ee03891f161fae5cb8ddb534ef88a016e Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Fri, 1 Apr 2005 16:00:42 +0000 Subject: [PATCH] Fixed username handling in command replies. Do not announce unregistered clients. --- CHANGES | 8 ++++++++ TODO | 9 --------- apps/silcd/command_reply.c | 38 ++++++++++++++++++++++--------------- apps/silcd/idlist.c | 23 +++++++++++++++------- apps/silcd/packet_receive.c | 6 ++++++ apps/silcd/server.c | 10 +++++++--- apps/silcd/server_backup.c | 7 +++---- apps/silcd/server_util.c | 4 +++- 8 files changed, 66 insertions(+), 39 deletions(-) diff --git a/CHANGES b/CHANGES index b9917fd4..a5734c70 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,11 @@ +Fri Apr 1 18:52:47 EEST 2005 Pekka Riikonen + + * Changed announcing to not announce unregistered clients. + Affected file silcd/server.c. + + * Fixed username handling in command reply. Affected file + silcd/command_reply.c. + Thu Mar 31 22:34:22 CEST 2005 Patrik Weiskircher * Added new define SILC_MACOSX, if __APPLE__ and __MACH__ is defined. diff --git a/TODO b/TODO index 32f3a9b8..01e32f9f 100644 --- a/TODO +++ b/TODO @@ -18,18 +18,9 @@ TODO for SILC Server 1.0 o The log files should be opened with silc_file* routines to make sure they are 0600. - o BUG: assert() happened in silc_server_free_client_data_timeout, - server.c:3322. - - o BUG: The server number stats is wrong on router when backup is - connected. - o BUG: silc_idlist_del_client had been called but sock->user_data remained and pointed to invalid pointer. Where it was called is not known. - o BUG: server->backup has the backup router added twice (old connection - presumably remains, and is invalid). - o Check for valid ban strings. Check ban string notifying. o Basic UTF-8 stringprep profile that makes sure UTF-8 strings are diff --git a/apps/silcd/command_reply.c b/apps/silcd/command_reply.c index 1250eaa5..9f0958f8 100644 --- a/apps/silcd/command_reply.c +++ b/apps/silcd/command_reply.c @@ -224,9 +224,11 @@ silc_server_command_reply_whois_save(SilcServerCommandReplyContext cmd) cmd->sock->user_data, NULL, 0); if (!client) { SILC_LOG_ERROR(("Could not add new client to the ID Cache")); + silc_free(tmp); silc_free(nick); return FALSE; } + silc_free(tmp); client->data.status |= (SILC_IDLIST_STATUS_REGISTERED | SILC_IDLIST_STATUS_RESOLVED); @@ -238,24 +240,27 @@ silc_server_command_reply_whois_save(SilcServerCommandReplyContext cmd) SILC_LOG_DEBUG(("Updating client data")); - /* Take hostname out of nick string if it includes it. */ - silc_parse_userfqdn(nickname, &nick, &servername); - /* Check nickname */ + silc_parse_userfqdn(nickname, &nick, &servername); nickname = silc_identifier_check(nick, strlen(nick), SILC_STRING_UTF8, 128, NULL); if (!nickname) { SILC_LOG_ERROR(("Malformed nickname received in WHOIS reply")); + silc_free(nick); + silc_free(servername); return FALSE; } /* Check username */ - username = silc_identifier_check(username, strlen(username), - SILC_STRING_UTF8, 128, NULL); - if (!username) { + silc_parse_userfqdn(username, (char **)&tmp, NULL); + if (!silc_identifier_verify(tmp, strlen(tmp), SILC_STRING_UTF8, 128)) { + silc_free(tmp); + silc_free(nick); + silc_free(servername); SILC_LOG_ERROR(("Malformed username received in WHOIS reply")); return FALSE; } + silc_free(tmp); /* Remove the old cache entry */ silc_idcache_del_by_context(global ? server->global_list->clients : @@ -267,7 +272,7 @@ silc_server_command_reply_whois_save(SilcServerCommandReplyContext cmd) silc_free(client->servername); client->nickname = nick; - client->username = username; + client->username = strdup(username); client->userinfo = strdup(realname); client->servername = servername; client->mode = mode; @@ -452,7 +457,7 @@ silc_server_command_reply_whowas_save(SilcServerCommandReplyContext cmd) SilcServer server = cmd->server; SilcUInt32 len, id_len; unsigned char *id_data; - char *nickname, *username, *realname, *servername = NULL; + char *nickname, *username, *realname, *servername = NULL, *tmp; SilcClientID *client_id; SilcClientEntry client; SilcIDCacheEntry cache = NULL; @@ -511,31 +516,34 @@ silc_server_command_reply_whowas_save(SilcServerCommandReplyContext cmd) } else { /* We have the client already, update the data */ - /* Take hostname out of nick string if it includes it. */ - silc_parse_userfqdn(nickname, &nick, &servername); - /* Check nickname */ + silc_parse_userfqdn(nickname, &nick, &servername); nickname = silc_identifier_check(nick, strlen(nick), SILC_STRING_UTF8, 128, NULL); if (!nickname) { SILC_LOG_ERROR(("Malformed nickname received in WHOWAS reply")); + silc_free(nick); + silc_free(servername); return FALSE; } /* Check username */ - username = silc_identifier_check(username, strlen(username), - SILC_STRING_UTF8, 128, NULL); - if (!username) { + silc_parse_userfqdn(username, &tmp, NULL); + if (!silc_identifier_verify(tmp, strlen(tmp), SILC_STRING_UTF8, 128)) { + silc_free(tmp); + silc_free(nick); + silc_free(servername); SILC_LOG_ERROR(("Malformed username received in WHOWAS reply")); return FALSE; } + silc_free(tmp); silc_free(client->nickname); silc_free(client->username); silc_free(client->servername); client->nickname = nick; - client->username = username; + client->username = strdup(username); client->servername = servername; client->data.status |= SILC_IDLIST_STATUS_RESOLVED; client->data.status &= ~SILC_IDLIST_STATUS_RESOLVING; diff --git a/apps/silcd/idlist.c b/apps/silcd/idlist.c index e3f3df8a..db904bad 100644 --- a/apps/silcd/idlist.c +++ b/apps/silcd/idlist.c @@ -348,7 +348,7 @@ silc_idlist_add_client(SilcIDList id_list, char *nickname, char *username, int expire) { SilcClientEntry client; - char *nicknamec = NULL, *usernamec = NULL; + char *nicknamec = NULL; SILC_LOG_DEBUG(("Adding new client entry")); @@ -360,17 +360,27 @@ silc_idlist_add_client(SilcIDList id_list, char *nickname, char *username, return NULL; } - /* Normalize username. */ + /* Check username. */ if (username) { - usernamec = silc_identifier_check(username, strlen(username), - SILC_STRING_UTF8, 128, NULL); - if (!usernamec) + char *u = NULL, *h = NULL; + silc_parse_userfqdn(username, &u, &h); + if (!u) + return NULL; + if (!silc_identifier_verify(u, strlen(u), SILC_STRING_UTF8, 128)) { + silc_free(u); + silc_free(h); return NULL; + } + if (h && !silc_identifier_verify(h, strlen(h), SILC_STRING_UTF8, 256)) { + silc_free(u); + silc_free(h); + return NULL; + } } client = silc_calloc(1, sizeof(*client)); client->nickname = nickname; - client->username = usernamec; + client->username = username ? strdup(username) : NULL; client->userinfo = userinfo; client->id = id; client->router = router; @@ -383,7 +393,6 @@ silc_idlist_add_client(SilcIDList id_list, char *nickname, char *username, silc_hash_table_free(client->channels); silc_free(client); silc_free(nicknamec); - silc_free(usernamec); return NULL; } diff --git a/apps/silcd/packet_receive.c b/apps/silcd/packet_receive.c index 42631642..7d0ae314 100644 --- a/apps/silcd/packet_receive.c +++ b/apps/silcd/packet_receive.c @@ -379,6 +379,9 @@ void silc_server_notify(SilcServer server, silc_server_del_from_watcher_list(server, client); client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED; + client->mode = 0; + client->router = NULL; + client->connection = NULL; cache->expire = SILC_ID_CACHE_EXPIRE_DEF; break; @@ -1657,6 +1660,9 @@ void silc_server_notify(SilcServer server, } client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED; + client->mode = 0; + client->router = NULL; + client->connection = NULL; cache->expire = SILC_ID_CACHE_EXPIRE_DEF; break; } diff --git a/apps/silcd/server.c b/apps/silcd/server.c index 6111c5f2..e685db93 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -3409,7 +3409,7 @@ void silc_server_free_client_data(SilcServer server, if (!server->server_shutdown) { silc_schedule_task_add(server->schedule, 0, silc_server_free_client_data_timeout, - client, 300, 0, + client, 600, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW); client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED; client->data.status &= ~SILC_IDLIST_STATUS_LOCAL; @@ -4462,8 +4462,12 @@ static void silc_server_announce_get_clients(SilcServer server, break; continue; } - if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) && - !client->connection && !client->router && !SILC_IS_LOCAL(client)) { + if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) { + if (!silc_idcache_list_next(list, &id_cache)) + break; + continue; + } + if (!client->connection && !client->router) { if (!silc_idcache_list_next(list, &id_cache)) break; continue; diff --git a/apps/silcd/server_backup.c b/apps/silcd/server_backup.c index ddc3ab14..7c5a3693 100644 --- a/apps/silcd/server_backup.c +++ b/apps/silcd/server_backup.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 2001 - 2003 Pekka Riikonen + Copyright (C) 2001 - 2005 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -296,7 +296,6 @@ void silc_server_backup_replaced_del(SilcServer server, if (server->backup->replaced[i]->server == server_entry) { silc_free(server->backup->replaced[i]); server->backup->replaced[i] = NULL; - return; } } } @@ -795,11 +794,11 @@ SILC_TASK_CALLBACK(silc_server_backup_connection_established) silc_schedule_task_del_by_fd(server->schedule, sock); silc_schedule_unset_listen_fd(server->schedule, sock); - if (silc_net_get_socket_opt(sock, SOL_SOCKET, SO_ERROR, &opt, &optlen) || + if (silc_net_get_socket_opt(sock, SOL_SOCKET, SO_ERROR, &opt, &optlen) || (opt != 0)) { SILC_LOG_DEBUG(("Could not connect to router %s:%d: %s", sconn->remote_host, sconn->remote_port, strerror(opt))); - + if (server->server_type == SILC_SERVER) { sconn->retry_count++; if (sconn->retry_count > 3) { diff --git a/apps/silcd/server_util.c b/apps/silcd/server_util.c index b19f495d..8b2c6233 100644 --- a/apps/silcd/server_util.c +++ b/apps/silcd/server_util.c @@ -1020,6 +1020,8 @@ bool silc_server_channel_delete(SilcServer server, SilcHashTableList htl; bool delchan = !(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH); + SILC_LOG_DEBUG(("Deleting channel %s", channel->channel_name)); + if (delchan) { /* Update statistics */ if (server->server_type == SILC_ROUTER) @@ -1064,7 +1066,7 @@ bool silc_server_channel_delete(SilcServer server, } silc_hash_table_list_reset(&htl); - SILC_LOG_DEBUG(("Channel %s remains", channel->channel_name)); + SILC_LOG_DEBUG(("Channel %s remains (permanent)", channel->channel_name)); return TRUE; } -- 2.24.0