5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2000 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
23 * Revision 1.7 2000/07/26 07:04:01 priikone
24 * Added server_find_by_id, replace_[server/client]_id.
26 * Revision 1.6 2000/07/17 11:47:30 priikone
27 * Added command lagging support. Added idle counting support.
29 * Revision 1.5 2000/07/12 05:59:41 priikone
30 * Major rewrite of ID Cache system. Support added for the new
31 * ID cache system. Major rewrite of ID List stuff on server. All
32 * SilcXXXList's are now called SilcXXXEntry's and they are pointers
33 * by default. A lot rewritten ID list functions.
35 * Revision 1.4 2000/07/06 07:16:13 priikone
36 * Added SilcPublicKey's
38 * Revision 1.3 2000/07/05 06:14:01 priikone
39 * Global costemic changes.
41 * Revision 1.2 2000/07/03 05:52:11 priikone
42 * Fixed typo and a bug.
44 * Revision 1.1.1.1 2000/06/27 11:36:56 priikone
45 * Imported from internal CVS/Added Log headers.
50 #include "serverincludes.h"
53 /******************************************************************************
55 Server entry functions
57 ******************************************************************************/
59 /* Add new server entry. This adds the new server entry to ID cache and
60 returns the allocated entry object or NULL on error. This is called
61 when new server connects to us. We also add ourselves to cache with
65 silc_idlist_add_server(SilcIDList id_list,
66 char *server_name, int server_type,
67 SilcServerID *id, SilcServerEntry router,
68 SilcCipher send_key, SilcCipher receive_key,
69 SilcPKCS pkcs, SilcHmac hmac,
70 SilcPublicKey public_key, void *connection)
72 SilcServerEntry server;
74 SILC_LOG_DEBUG(("Adding new server entry"));
76 server = silc_calloc(1, sizeof(*server));
77 server->server_name = server_name;
78 server->server_type = server_type;
80 server->router = router;
81 server->send_key = send_key;
82 server->receive_key = receive_key;
85 server->public_key = public_key;
86 server->connection = connection;
88 if (!silc_idcache_add(id_list->servers, server->server_name, SILC_ID_SERVER,
89 (void *)server->id, (void *)server, TRUE)) {
97 /* Finds server by Server ID */
100 silc_idlist_find_server_by_id(SilcIDList id_list, SilcServerID *id)
102 SilcIDCacheEntry id_cache = NULL;
103 SilcServerEntry server;
108 SILC_LOG_DEBUG(("Finding server by ID"));
110 if (!silc_idcache_find_by_id_one(id_list->servers, (void *)id,
111 SILC_ID_SERVER, &id_cache))
114 server = (SilcServerEntry)id_cache->context;
119 /* Replaces old Server ID with new one */
122 silc_idlist_replace_server_id(SilcIDList id_list, SilcServerID *old_id,
123 SilcServerID *new_id)
125 SilcIDCacheEntry id_cache = NULL;
126 SilcServerEntry server;
128 if (!old_id || !new_id)
131 SILC_LOG_DEBUG(("Replacing Server ID"));
133 if (!silc_idcache_find_by_id_one(id_list->servers, (void *)old_id,
134 SILC_ID_SERVER, &id_cache))
137 server = (SilcServerEntry)id_cache->context;
138 silc_free(server->id);
140 id_cache->id = (void *)new_id;
145 /******************************************************************************
147 Client entry functions
149 ******************************************************************************/
151 /* Add new client entry. This adds the client entry to ID cache system
152 and returns the allocated client entry or NULL on error. This is
153 called when new client connection is accepted to the server. */
156 silc_idlist_add_client(SilcIDList id_list, char *nickname, char *username,
157 char *userinfo, SilcClientID *id,
158 SilcServerEntry router,
159 SilcCipher send_key, SilcCipher receive_key,
160 SilcPKCS pkcs, SilcHmac hmac,
161 SilcPublicKey public_key, void *connection)
163 SilcClientEntry client;
165 SILC_LOG_DEBUG(("Adding new client entry"));
167 client = silc_calloc(1, sizeof(*client));
168 client->nickname = nickname;
169 client->username = username;
170 client->userinfo = userinfo;
172 client->router = router;
173 client->send_key = send_key;
174 client->receive_key = receive_key;
177 client->public_key = public_key;
178 client->connection = connection;
180 if (!silc_idcache_add(id_list->clients, client->nickname, SILC_ID_CLIENT,
181 (void *)client->id, (void *)client, TRUE)) {
189 /* Free client entry. This free's everything and removes the entry
192 void silc_idlist_del_client(SilcIDList id_list, SilcClientEntry entry)
195 /* Remove from cache */
197 silc_idcache_del_by_id(id_list->clients, SILC_ID_CLIENT,
202 silc_free(entry->nickname);
204 silc_free(entry->username);
206 silc_free(entry->userinfo);
208 silc_free(entry->id);
210 silc_cipher_free(entry->send_key);
211 if (entry->receive_key)
212 silc_cipher_free(entry->receive_key);
214 silc_pkcs_free(entry->pkcs);
215 if (entry->public_key)
216 silc_pkcs_public_key_free(entry->public_key);
218 silc_hmac_free(entry->hmac);
222 /* Finds client entry by nickname. */
225 silc_idlist_find_client_by_nickname(SilcIDList id_list, char *nickname,
228 SilcIDCacheList list = NULL;
229 SilcIDCacheEntry id_cache = NULL;
230 SilcClientEntry client = NULL;
232 SILC_LOG_DEBUG(("Finding client by nickname"));
235 if (!silc_idcache_find_by_data(id_list->clients, nickname, &list))
239 while (silc_idcache_list_next(list, &id_cache)) {
240 client = (SilcClientEntry)id_cache->context;
242 if (!strcmp(server, XXX, strlen(server)))
249 silc_idcache_list_free(list);
254 if (!silc_idcache_find_by_data_one(id_list->clients, nickname, &id_cache))
257 client = (SilcClientEntry)id_cache->context;
263 /* Finds client by nickname hash. */
266 silc_idlist_find_client_by_hash(SilcIDList id_list, char *nickname,
269 SilcIDCacheList list = NULL;
270 SilcIDCacheEntry id_cache = NULL;
271 SilcClientEntry client = NULL;
272 unsigned char hash[32];
274 SILC_LOG_DEBUG(("Finding client by hash"));
276 silc_hash_make(md5hash, nickname, strlen(nickname), hash);
278 if (!silc_idcache_find_by_id(id_list->clients, SILC_ID_CACHE_ANY,
279 SILC_ID_CLIENT, &list))
282 if (!silc_idcache_list_first(list, &id_cache)) {
283 silc_idcache_list_free(list);
288 client = (SilcClientEntry)id_cache->context;
290 if (client && !SILC_ID_COMPARE_HASH(client->id, hash))
296 if (!silc_idcache_list_next(list, &id_cache))
300 silc_idcache_list_free(list);
305 /* Finds client by Client ID */
308 silc_idlist_find_client_by_id(SilcIDList id_list, SilcClientID *id)
310 SilcIDCacheEntry id_cache = NULL;
311 SilcClientEntry client;
316 SILC_LOG_DEBUG(("Finding client by ID"));
318 if (!silc_idcache_find_by_id_one(id_list->clients, (void *)id,
319 SILC_ID_CLIENT, &id_cache))
322 client = (SilcClientEntry)id_cache->context;
327 /* Replaces old Client ID with new one */
330 silc_idlist_replace_client_id(SilcIDList id_list, SilcClientID *old_id,
331 SilcClientID *new_id)
333 SilcIDCacheEntry id_cache = NULL;
334 SilcClientEntry client;
336 if (!old_id || !new_id)
339 SILC_LOG_DEBUG(("Replacing Client ID"));
341 if (!silc_idcache_find_by_id_one(id_list->clients, (void *)old_id,
342 SILC_ID_CLIENT, &id_cache))
345 client = (SilcClientEntry)id_cache->context;
346 silc_free(client->id);
348 id_cache->id = (void *)new_id;
354 /******************************************************************************
356 Channel entry functions
358 ******************************************************************************/
360 /* Add new channel entry. This add the new channel entry to the ID cache
361 system and returns the allocated entry or NULL on error. */
364 silc_idlist_add_channel(SilcIDList id_list, char *channel_name, int mode,
365 SilcChannelID *id, SilcServerEntry router,
366 SilcCipher channel_key)
368 SilcChannelEntry channel;
370 channel = silc_calloc(1, sizeof(*channel));
371 channel->channel_name = channel_name;
372 channel->mode = mode;
374 channel->router = router;
375 channel->channel_key = channel_key;
377 if (!silc_idcache_add(id_list->channels, channel->channel_name,
378 SILC_ID_CHANNEL, (void *)channel->id,
379 (void *)channel, TRUE)) {
387 /* Free channel entry. This free's everything. */
389 void silc_idlist_del_channel(SilcIDList id_list, SilcChannelEntry entry)
392 /* Remove from cache */
394 silc_idcache_del_by_id(id_list->channels, SILC_ID_CHANNEL,
398 if (entry->channel_name)
399 silc_free(entry->channel_name);
401 silc_free(entry->id);
403 silc_free(entry->topic);
404 if (entry->channel_key)
405 silc_cipher_free(entry->channel_key);
407 memset(entry->key, 0, entry->key_len / 8);
408 silc_free(entry->key);
410 memset(entry->iv, 0, sizeof(entry->iv));
412 if (entry->user_list_count)
413 silc_free(entry->user_list);
417 /* Finds channel by channel name. Channel names are unique and they
418 are not case-sensitive. */
421 silc_idlist_find_channel_by_name(SilcIDList id_list, char *name)
423 SilcIDCacheList list = NULL;
424 SilcIDCacheEntry id_cache = NULL;
425 SilcChannelEntry channel;
427 SILC_LOG_DEBUG(("Finding channel by name"));
429 if (!silc_idcache_find_by_data_loose(id_list->channels, name, &list))
432 if (!silc_idcache_list_first(list, &id_cache)) {
433 silc_idcache_list_free(list);
437 channel = (SilcChannelEntry)id_cache->context;
439 silc_idcache_list_free(list);
444 /* Finds channel by Channel ID. */
447 silc_idlist_find_channel_by_id(SilcIDList id_list, SilcChannelID *id)
449 SilcIDCacheEntry id_cache = NULL;
450 SilcChannelEntry channel;
455 SILC_LOG_DEBUG(("Finding channel by ID"));
457 if (!silc_idcache_find_by_id_one(id_list->channels, (void *)id,
458 SILC_ID_CHANNEL, &id_cache))
461 channel = (SilcChannelEntry)id_cache->context;