5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2003 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; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
21 #include "serverincludes.h"
22 #include "server_internal.h"
24 extern char *server_version;
26 /* Removes the client from channels and possibly removes the channels
27 as well. After removing those channels that exist, their channel
28 keys are regnerated. This is called only by the function
29 silc_server_remove_clients_by_server. */
32 silc_server_remove_clients_channels(SilcServer server,
33 SilcServerEntry server_entry,
34 SilcHashTable clients,
35 SilcClientEntry client,
36 SilcHashTable channels)
38 SilcChannelEntry channel;
39 SilcChannelClientEntry chl, chl2;
40 SilcHashTableList htl, htl2;
45 SILC_LOG_DEBUG(("Remove client %s from all channels",
46 client->nickname ? client->nickname :
47 (unsigned char *)""));
49 if (silc_hash_table_find(clients, client, NULL, NULL))
50 silc_hash_table_del(clients, client);
52 /* Remove the client from all channels. The client is removed from
53 the channels' user list. */
54 silc_hash_table_list(client->channels, &htl);
55 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
56 channel = chl->channel;
58 /* Remove channel if this is last client leaving the channel, unless
59 the channel is permanent. */
60 if (server->server_type != SILC_SERVER &&
61 silc_hash_table_count(channel->user_list) < 2) {
62 if (silc_hash_table_find(channels, channel, NULL, NULL))
63 silc_hash_table_del(channels, channel);
64 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
65 silc_server_channel_delete(server, channel);
69 silc_hash_table_del(client->channels, channel);
70 silc_hash_table_del(channel->user_list, chl->client);
71 channel->user_count--;
73 /* If there is no global users on the channel anymore mark the channel
74 as local channel. Do not check if the removed client is local client. */
75 if (server->server_type != SILC_ROUTER && channel->global_users &&
76 chl->client->router && !silc_server_channel_has_global(channel))
77 channel->global_users = FALSE;
81 /* Update statistics */
82 if (SILC_IS_LOCAL(client))
83 server->stat.my_chanclients--;
84 if (server->server_type == SILC_ROUTER) {
85 server->stat.cell_chanclients--;
86 server->stat.chanclients--;
89 /* If there is not at least one local user on the channel then we don't
90 need the channel entry anymore, we can remove it safely, unless the
91 channel is permanent channel */
92 if (server->server_type == SILC_SERVER &&
93 !silc_server_channel_has_local(channel)) {
94 if (silc_hash_table_find(channels, channel, NULL, NULL))
95 silc_hash_table_del(channels, channel);
96 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
97 silc_server_channel_delete(server, channel);
101 /* Mark other local clients to the table of clients whom will receive
102 the SERVER_SIGNOFF notify. */
103 silc_hash_table_list(channel->user_list, &htl2);
104 while (silc_hash_table_get(&htl2, NULL, (void **)&chl2)) {
105 SilcClientEntry c = chl2->client;
109 /* Add client to table, if it's not from the signoff server */
110 if (c->router != server_entry &&
111 !silc_hash_table_find(clients, c, NULL, NULL))
112 silc_hash_table_add(clients, c, c);
114 silc_hash_table_list_reset(&htl2);
116 /* Add the channel to the the channels list to regenerate the
118 if (!silc_hash_table_find(channels, channel, NULL, NULL))
119 silc_hash_table_add(channels, channel, channel);
121 silc_hash_table_list_reset(&htl);
124 /* This function removes all client entries that are originated from
125 `router' and are owned by `entry'. `router' and `entry' can be same
126 too. If `server_signoff' is TRUE then SERVER_SIGNOFF notify is
127 distributed to our local clients. */
129 bool silc_server_remove_clients_by_server(SilcServer server,
130 SilcServerEntry router,
131 SilcServerEntry entry,
134 SilcIDCacheList list = NULL;
135 SilcIDCacheEntry id_cache = NULL;
136 SilcClientEntry client = NULL;
138 unsigned char **argv = NULL;
139 SilcUInt32 *argv_lens = NULL, *argv_types = NULL, argc = 0;
140 SilcHashTableList htl;
141 SilcChannelEntry channel;
142 SilcHashTable channels, clients;
145 if (!(entry->data.status & SILC_IDLIST_STATUS_REGISTERED))
148 SILC_LOG_DEBUG(("Removing clients by %s",
149 entry->server_name ? entry->server_name : "server"));
154 /* Allocate the hash table that holds the channels that require
155 channel key re-generation after we've removed this server's clients
156 from the channels. */
157 channels = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL, NULL,
159 clients = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL, NULL,
162 if (server_signoff) {
163 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
164 argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
165 argv_lens = silc_realloc(argv_lens, sizeof(*argv_lens) * (argc + 1));
166 argv_types = silc_realloc(argv_types, sizeof(*argv_types) * (argc + 1));
167 argv[argc] = silc_calloc(idp->len, sizeof(*argv[0]));
168 memcpy(argv[argc], idp->data, idp->len);
169 argv_lens[argc] = idp->len;
170 argv_types[argc] = argc + 1;
172 silc_buffer_free(idp);
175 if (silc_idcache_get_all(server->local_list->clients, &list)) {
176 if (silc_idcache_list_first(list, &id_cache)) {
178 client = (SilcClientEntry)id_cache->context;
180 /* If client is not registered, is not originated from `router'
181 and is not owned by `entry', skip it. */
182 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) ||
183 client->router != router ||
184 (router != entry && !SILC_ID_COMPARE(client->id, entry->id,
185 client->id->ip.data_len))) {
186 if (!silc_idcache_list_next(list, &id_cache))
192 if (server_signoff) {
193 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
194 argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
195 argv_lens = silc_realloc(argv_lens, sizeof(*argv_lens) *
197 argv_types = silc_realloc(argv_types, sizeof(*argv_types) *
199 argv[argc] = silc_calloc(idp->len, sizeof(*argv[0]));
200 memcpy(argv[argc], idp->data, idp->len);
201 argv_lens[argc] = idp->len;
202 argv_types[argc] = argc + 1;
204 silc_buffer_free(idp);
207 /* Update statistics */
208 server->stat.clients--;
209 if (server->stat.cell_clients)
210 server->stat.cell_clients--;
211 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
212 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
214 silc_server_remove_clients_channels(server, entry, clients,
216 silc_server_del_from_watcher_list(server, client);
218 /* Remove the client entry */
219 if (!server_signoff) {
220 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
221 id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
223 silc_idlist_del_data(client);
224 silc_idlist_del_client(server->local_list, client);
227 if (!silc_idcache_list_next(list, &id_cache))
231 silc_idcache_list_free(list);
234 if (silc_idcache_get_all(server->global_list->clients, &list)) {
236 if (silc_idcache_list_first(list, &id_cache)) {
238 client = (SilcClientEntry)id_cache->context;
240 /* If client is not registered, is not originated from `router'
241 and is not owned by `entry', skip it. */
242 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) ||
243 client->router != router ||
244 (router != entry && !SILC_ID_COMPARE(client->id, entry->id,
245 client->id->ip.data_len))) {
246 if (!silc_idcache_list_next(list, &id_cache))
252 if (server_signoff) {
253 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
254 argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
255 argv_lens = silc_realloc(argv_lens, sizeof(*argv_lens) *
257 argv_types = silc_realloc(argv_types, sizeof(*argv_types) *
259 argv[argc] = silc_calloc(idp->len, sizeof(*argv[0]));
260 memcpy(argv[argc], idp->data, idp->len);
261 argv_lens[argc] = idp->len;
262 argv_types[argc] = argc + 1;
264 silc_buffer_free(idp);
267 /* Update statistics */
268 server->stat.clients--;
269 if (server->stat.cell_clients)
270 server->stat.cell_clients--;
271 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
272 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
274 silc_server_remove_clients_channels(server, entry, clients,
276 silc_server_del_from_watcher_list(server, client);
278 /* Remove the client entry */
279 if (!server_signoff) {
280 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
281 id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
283 silc_idlist_del_data(client);
284 silc_idlist_del_client(server->global_list, client);
287 if (!silc_idcache_list_next(list, &id_cache))
291 silc_idcache_list_free(list);
294 /* Return now if we are shutting down */
295 if (server->server_shutdown) {
296 silc_hash_table_free(channels);
298 if (server_signoff) {
299 for (i = 0; i < argc; i++)
302 silc_free(argv_lens);
303 silc_free(argv_types);
304 silc_hash_table_free(clients);
309 /* Send the SERVER_SIGNOFF notify */
310 if (server_signoff) {
311 SilcBuffer args, not;
313 SILC_LOG_DEBUG(("Sending SERVER_SIGNOFF for %s with %d clients",
314 silc_id_render(entry->id, SILC_ID_SERVER), argc - 1));
316 /* Send SERVER_SIGNOFF notify to our primary router */
317 if (server->router != entry) {
318 args = silc_argument_payload_encode(1, argv, argv_lens,
320 silc_server_send_notify_args(server, SILC_PRIMARY_ROUTE(server),
321 SILC_BROADCAST(server),
322 SILC_NOTIFY_TYPE_SERVER_SIGNOFF,
324 silc_buffer_free(args);
327 /* Send to local clients. We also send the list of client ID's that
328 is to be removed for those servers that would like to use that list. */
329 args = silc_argument_payload_encode(argc, argv, argv_lens,
331 not = silc_notify_payload_encode_args(SILC_NOTIFY_TYPE_SERVER_SIGNOFF,
333 silc_server_packet_send_clients(server, clients,
334 SILC_PACKET_NOTIFY, 0, FALSE,
335 not->data, not->len, FALSE);
337 /* Send notify also to local backup routers */
338 silc_server_backup_send(server, NULL, SILC_PACKET_NOTIFY, 0,
339 not->data, not->len, FALSE, TRUE);
341 silc_buffer_free(args);
342 silc_buffer_free(not);
343 for (i = 0; i < argc; i++)
346 silc_free(argv_lens);
347 silc_free(argv_types);
348 silc_hash_table_free(clients);
351 /* We must now re-generate the channel key for all channels that had
352 this server's client(s) on the channel. As they left the channel we
353 must re-generate the channel key. */
354 silc_hash_table_list(channels, &htl);
355 while (silc_hash_table_get(&htl, NULL, (void **)&channel)) {
356 if (!silc_server_create_channel_key(server, channel, 0)) {
357 silc_hash_table_list_reset(&htl);
358 silc_hash_table_free(channels);
362 /* Do not send the channel key if private channel key mode is set */
363 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY || !channel->channel_key)
366 silc_server_send_channel_key(server, NULL, channel,
367 server->server_type == SILC_ROUTER ?
368 FALSE : !server->standalone);
370 silc_hash_table_list_reset(&htl);
371 silc_hash_table_free(channels);
376 static SilcServerEntry
377 silc_server_update_clients_by_real_server(SilcServer server,
378 SilcServerEntry from,
380 SilcClientEntry client,
382 SilcIDCacheEntry client_cache)
384 SilcServerEntry server_entry;
385 SilcIDCacheEntry id_cache = NULL;
386 SilcIDCacheList list;
387 bool tolocal = (to == server->id_entry);
389 if (!silc_idcache_get_all(server->local_list->servers, &list))
392 if (silc_idcache_list_first(list, &id_cache)) {
394 server_entry = (SilcServerEntry)id_cache->context;
395 if (server_entry != from &&
396 (tolocal || server_entry != server->id_entry) &&
397 SILC_ID_COMPARE(server_entry->id, client->id,
398 client->id->ip.data_len)) {
399 SILC_LOG_DEBUG(("Found (local) %s",
400 silc_id_render(server_entry->id, SILC_ID_SERVER)));
402 if (!server_entry->data.send_key && server_entry->router) {
403 SILC_LOG_DEBUG(("Server not locally connected, use its router"));
404 /* If the client is not marked as local then move it to local list
405 since the server is local. */
407 SILC_LOG_DEBUG(("Moving client to local list"));
408 silc_idcache_add(server->local_list->clients, client_cache->name,
409 client_cache->id, client_cache->context,
410 client_cache->expire, NULL);
411 silc_idcache_del_by_context(server->global_list->clients, client);
413 server_entry = server_entry->router;
415 /* If the client is not marked as local then move it to local list
416 since the server is local. */
417 if (server_entry->server_type != SILC_BACKUP_ROUTER && !local) {
418 SILC_LOG_DEBUG(("Moving client to local list"));
419 silc_idcache_add(server->local_list->clients, client_cache->name,
420 client_cache->id, client_cache->context,
421 client_cache->expire, NULL);
422 silc_idcache_del_by_context(server->global_list->clients, client);
426 silc_idcache_list_free(list);
430 if (!silc_idcache_list_next(list, &id_cache))
435 silc_idcache_list_free(list);
437 if (!silc_idcache_get_all(server->global_list->servers, &list))
440 if (silc_idcache_list_first(list, &id_cache)) {
442 server_entry = (SilcServerEntry)id_cache->context;
443 if (server_entry != from && server_entry != server->id_entry &&
444 (tolocal || server_entry != server->id_entry) &&
445 SILC_ID_COMPARE(server_entry->id, client->id,
446 client->id->ip.data_len)) {
447 SILC_LOG_DEBUG(("Found (global) %s",
448 silc_id_render(server_entry->id, SILC_ID_SERVER)));
450 if (!server_entry->data.send_key && server_entry->router) {
451 SILC_LOG_DEBUG(("Server not locally connected, use its router"));
452 /* If the client is marked as local then move it to global list
453 since the server is global. */
455 SILC_LOG_DEBUG(("Moving client to global list"));
456 silc_idcache_add(server->global_list->clients, client_cache->name,
457 client_cache->id, client_cache->context, 0, NULL);
458 silc_idcache_del_by_context(server->local_list->clients, client);
460 server_entry = server_entry->router;
462 /* If the client is marked as local then move it to global list
463 since the server is global. */
464 if (server_entry->server_type != SILC_BACKUP_ROUTER && local) {
465 SILC_LOG_DEBUG(("Moving client to global list"));
466 silc_idcache_add(server->global_list->clients, client_cache->name,
467 client_cache->id, client_cache->context, 0, NULL);
468 silc_idcache_del_by_context(server->local_list->clients, client);
472 silc_idcache_list_free(list);
476 if (!silc_idcache_list_next(list, &id_cache))
481 silc_idcache_list_free(list);
486 /* Updates the clients that are originated from the `from' to be originated
487 from the `to'. If the `resolve_real_server' is TRUE then this will
488 attempt to figure out which clients really are originated from the
489 `from' and which are originated from a server that we have connection
490 to, when we've acting as backup router. If it is FALSE the `to' will
491 be the new source. */
493 void silc_server_update_clients_by_server(SilcServer server,
494 SilcServerEntry from,
496 bool resolve_real_server)
498 SilcIDCacheList list = NULL;
499 SilcIDCacheEntry id_cache = NULL;
500 SilcClientEntry client = NULL;
504 if (silc_idcache_get_all(server->global_list->clients, &list)) {
505 if (silc_idcache_list_first(list, &id_cache)) {
507 client = (SilcClientEntry)id_cache->context;
509 /* If entry is disabled skip it. If entry is local to us, do not
510 switch it to anyone else, it is ours so skip it. */
511 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) ||
512 SILC_IS_LOCAL(client)) {
513 if (!silc_idcache_list_next(list, &id_cache))
519 SILC_LOG_DEBUG(("Client %s",
520 silc_id_render(client->id, SILC_ID_CLIENT)));
522 SILC_LOG_DEBUG(("Client->router %s",
523 silc_id_render(client->router->id, SILC_ID_SERVER)));
526 if (client->router == from) {
527 if (resolve_real_server) {
529 silc_server_update_clients_by_real_server(server, from, to,
532 if (!client->router) {
533 if (server->server_type == SILC_ROUTER)
534 client->router = from;
543 /* All are changed */
548 SILC_LOG_DEBUG(("Client changed to %s",
549 silc_id_render(client->router->id, SILC_ID_SERVER)));
551 if (!silc_idcache_list_next(list, &id_cache))
555 silc_idcache_list_free(list);
559 if (silc_idcache_get_all(server->local_list->clients, &list)) {
560 if (silc_idcache_list_first(list, &id_cache)) {
562 client = (SilcClientEntry)id_cache->context;
564 /* If entry is disabled skip it. If entry is local to us, do not
565 switch it to anyone else, it is ours so skip it. */
566 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) ||
567 SILC_IS_LOCAL(client)) {
568 if (!silc_idcache_list_next(list, &id_cache))
574 SILC_LOG_DEBUG(("Client %s",
575 silc_id_render(client->id, SILC_ID_CLIENT)));
577 SILC_LOG_DEBUG(("Client->router %s",
578 silc_id_render(client->router->id, SILC_ID_SERVER)));
581 if (client->router == from) {
582 if (resolve_real_server) {
584 silc_server_update_clients_by_real_server(server, from, to,
588 client->router = from;
594 /* All are changed */
599 SILC_LOG_DEBUG(("Client changed to %s",
600 silc_id_render(client->router->id, SILC_ID_SERVER)));
602 if (!silc_idcache_list_next(list, &id_cache))
606 silc_idcache_list_free(list);
610 /* Updates servers that are from `from' to be originated from `to'. This
611 will also update the server's connection to `to's connection. */
613 void silc_server_update_servers_by_server(SilcServer server,
614 SilcServerEntry from,
617 SilcIDCacheList list = NULL;
618 SilcIDCacheEntry id_cache = NULL;
619 SilcServerEntry server_entry = NULL;
621 SILC_LOG_DEBUG(("Updating servers"));
623 if (silc_idcache_get_all(server->local_list->servers, &list)) {
624 if (silc_idcache_list_first(list, &id_cache)) {
626 server_entry = (SilcServerEntry)id_cache->context;
628 /* If entry is local to us, do not switch it to any anyone else,
630 if (SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry ||
631 server_entry == from) {
632 if (!silc_idcache_list_next(list, &id_cache))
638 /* If we are standalone router, any server that is not directly
639 connected to cannot exist anymore. If we are not standalone
640 we update it correctly. */
641 if (server->server_type == SILC_ROUTER && server->standalone) {
642 silc_server_backup_del(server, server_entry);
643 silc_server_backup_replaced_del(server, server_entry);
644 silc_idlist_del_data(server_entry);
645 silc_idlist_del_server(server->local_list, server_entry);
646 server->stat.servers--;
647 server->stat.cell_servers--;
649 /* XXX if we are not standalone, do a check from local config
650 whether this server is in our cell, but not connected to
651 us (in which case we must remove it). */
653 if (server_entry->router == from) {
654 SILC_LOG_DEBUG(("Updating server (local) %s",
655 server_entry->server_name ?
656 server_entry->server_name : ""));
657 server_entry->router = to;
658 server_entry->connection = to->connection;
662 if (!silc_idcache_list_next(list, &id_cache))
666 silc_idcache_list_free(list);
669 if (silc_idcache_get_all(server->global_list->servers, &list)) {
670 if (silc_idcache_list_first(list, &id_cache)) {
672 server_entry = (SilcServerEntry)id_cache->context;
674 /* If entry is local to us, do not switch it to anyone else,
676 if (SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry ||
677 server_entry == from) {
678 if (!silc_idcache_list_next(list, &id_cache))
684 /* If we are standalone router, any server that is not directly
685 connected to cannot exist anymore. If we are not standalone
686 we update it correctly. */
687 if (server->server_type == SILC_ROUTER && server->standalone) {
688 silc_server_backup_del(server, server_entry);
689 silc_server_backup_replaced_del(server, server_entry);
690 silc_idlist_del_data(server_entry);
691 silc_idlist_del_server(server->global_list, server_entry);
692 server->stat.servers--;
693 server->stat.cell_servers--;
695 /* XXX if we are not standalone, do a check from local config
696 whether this server is in our cell, but not connected to
697 us (in which case we must remove it). */
699 if (server_entry->router == from) {
700 SILC_LOG_DEBUG(("Updating server (global) %s",
701 server_entry->server_name ?
702 server_entry->server_name : ""));
703 server_entry->router = to;
704 server_entry->connection = to->connection;
708 if (!silc_idcache_list_next(list, &id_cache))
712 silc_idcache_list_free(list);
717 /* Toggles the enabled/disabled status of local server connections. Packets
718 can be sent to the servers when `toggle_enabled' is TRUE and will be
719 dropped if `toggle_enabled' is FALSE, after this function is called. */
721 void silc_server_local_servers_toggle_enabled(SilcServer server,
724 SilcIDCacheList list = NULL;
725 SilcIDCacheEntry id_cache = NULL;
726 SilcServerEntry server_entry = NULL;
728 if (silc_idcache_get_all(server->local_list->servers, &list)) {
729 if (silc_idcache_list_first(list, &id_cache)) {
731 server_entry = (SilcServerEntry)id_cache->context;
732 if (!SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry) {
733 if (!silc_idcache_list_next(list, &id_cache))
740 server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
742 server_entry->data.status |= SILC_IDLIST_STATUS_DISABLED;
744 if (!silc_idcache_list_next(list, &id_cache))
748 silc_idcache_list_free(list);
751 if (silc_idcache_get_all(server->global_list->servers, &list)) {
752 if (silc_idcache_list_first(list, &id_cache)) {
754 server_entry = (SilcServerEntry)id_cache->context;
755 if (!SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry) {
756 if (!silc_idcache_list_next(list, &id_cache))
763 server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
765 server_entry->data.status |= SILC_IDLIST_STATUS_DISABLED;
767 if (!silc_idcache_list_next(list, &id_cache))
771 silc_idcache_list_free(list);
775 /* Removes servers that are originated from the `from'. The server
776 entry is deleted in this function. If `remove_clients' is TRUE then
777 all clients originated from the server are removed too, and server
778 signoff is sent. Note that this does not remove the `from'. This
779 also does not remove locally connected servers. */
781 void silc_server_remove_servers_by_server(SilcServer server,
782 SilcServerEntry from,
785 SilcIDCacheList list = NULL;
786 SilcIDCacheEntry id_cache = NULL;
787 SilcServerEntry server_entry = NULL;
789 SILC_LOG_DEBUG(("Removing servers by %s",
790 from->server_name ? from->server_name : "server"));
792 if (silc_idcache_get_all(server->local_list->servers, &list)) {
793 if (silc_idcache_list_first(list, &id_cache)) {
795 server_entry = (SilcServerEntry)id_cache->context;
796 if (SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry ||
797 server_entry->router != from || server_entry == from) {
798 if (!silc_idcache_list_next(list, &id_cache))
804 /* Remove clients owned by this server */
806 silc_server_remove_clients_by_server(server, from, server_entry,
809 /* Remove the server */
810 silc_idlist_del_server(server->local_list, server_entry);
812 if (!silc_idcache_list_next(list, &id_cache))
816 silc_idcache_list_free(list);
819 if (silc_idcache_get_all(server->global_list->servers, &list)) {
820 if (silc_idcache_list_first(list, &id_cache)) {
822 server_entry = (SilcServerEntry)id_cache->context;
823 if (SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry ||
824 server_entry->router != from || server_entry == from) {
825 if (!silc_idcache_list_next(list, &id_cache))
831 /* Remove clients owned by this server */
833 silc_server_remove_clients_by_server(server, from, server_entry,
836 /* Remove the server */
837 silc_idlist_del_server(server->global_list, server_entry);
839 if (!silc_idcache_list_next(list, &id_cache))
843 silc_idcache_list_free(list);
847 /* Removes channels that are from `from. */
849 void silc_server_remove_channels_by_server(SilcServer server,
850 SilcServerEntry from)
852 SilcIDCacheList list = NULL;
853 SilcIDCacheEntry id_cache = NULL;
854 SilcChannelEntry channel = NULL;
856 SILC_LOG_DEBUG(("Removing channels by server"));
858 if (silc_idcache_get_all(server->global_list->channels, &list)) {
859 if (silc_idcache_list_first(list, &id_cache)) {
861 channel = (SilcChannelEntry)id_cache->context;
862 if (channel->router == from)
863 silc_idlist_del_channel(server->global_list, channel);
864 if (!silc_idcache_list_next(list, &id_cache))
868 silc_idcache_list_free(list);
872 /* Updates channels that are from `from' to be originated from `to'. */
874 void silc_server_update_channels_by_server(SilcServer server,
875 SilcServerEntry from,
878 SilcIDCacheList list = NULL;
879 SilcIDCacheEntry id_cache = NULL;
880 SilcChannelEntry channel = NULL;
882 SILC_LOG_DEBUG(("Updating channels by server"));
884 if (silc_idcache_get_all(server->global_list->channels, &list)) {
885 if (silc_idcache_list_first(list, &id_cache)) {
887 channel = (SilcChannelEntry)id_cache->context;
888 if (channel->router == from)
889 channel->router = to;
890 if (!silc_idcache_list_next(list, &id_cache))
894 silc_idcache_list_free(list);
898 /* Checks whether given channel has global users. If it does this returns
899 TRUE and FALSE if there is only locally connected clients on the channel. */
901 bool silc_server_channel_has_global(SilcChannelEntry channel)
903 SilcChannelClientEntry chl;
904 SilcHashTableList htl;
906 silc_hash_table_list(channel->user_list, &htl);
907 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
908 if (chl->client->router) {
909 silc_hash_table_list_reset(&htl);
913 silc_hash_table_list_reset(&htl);
918 /* Checks whether given channel has locally connected users. If it does this
919 returns TRUE and FALSE if there is not one locally connected client. */
921 bool silc_server_channel_has_local(SilcChannelEntry channel)
923 SilcChannelClientEntry chl;
924 SilcHashTableList htl;
926 silc_hash_table_list(channel->user_list, &htl);
927 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
928 if (SILC_IS_LOCAL(chl->client)) {
929 silc_hash_table_list_reset(&htl);
933 silc_hash_table_list_reset(&htl);
938 /* This function removes the channel and all users on the channel, unless
939 the channel is permanent. In this case the channel is disabled but all
940 users are removed from the channel. Returns TRUE if the channel is
941 destroyed totally, and FALSE if it is permanent and remains. */
943 bool silc_server_channel_delete(SilcServer server,
944 SilcChannelEntry channel)
946 SilcChannelClientEntry chl;
947 SilcHashTableList htl;
948 bool delchan = !(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH);
951 /* Update statistics */
952 if (server->server_type == SILC_ROUTER)
953 server->stat.chanclients -= channel->user_count;
955 /* Totally delete the channel and all users on the channel. The
956 users are deleted automatically in silc_idlist_del_channel. */
957 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
958 if (silc_idlist_del_channel(server->local_list, channel)) {
959 server->stat.my_channels--;
960 if (server->server_type == SILC_ROUTER) {
961 server->stat.channels--;
962 server->stat.cell_channels--;
965 if (silc_idlist_del_channel(server->global_list, channel))
966 if (server->server_type == SILC_ROUTER)
967 server->stat.channels--;
973 /* Channel is permanent, do not remove it, remove only users */
974 channel->disabled = TRUE;
975 silc_hash_table_list(channel->user_list, &htl);
976 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
977 silc_hash_table_del(chl->client->channels, channel);
978 silc_hash_table_del(channel->user_list, chl->client);
979 channel->user_count--;
981 /* Update statistics */
982 if (SILC_IS_LOCAL(chl->client))
983 server->stat.my_chanclients--;
984 if (server->server_type == SILC_ROUTER) {
985 server->stat.cell_chanclients--;
986 server->stat.chanclients--;
991 silc_hash_table_list_reset(&htl);
993 SILC_LOG_DEBUG(("Channel %s remains", channel->channel_name));
998 /* Returns TRUE if the given client is on the channel. FALSE if not.
999 This works because we assure that the user list on the channel is
1000 always in up to date thus we can only check the channel list from
1001 `client' which is faster than checking the user list from `channel'. */
1003 bool silc_server_client_on_channel(SilcClientEntry client,
1004 SilcChannelEntry channel,
1005 SilcChannelClientEntry *chl)
1007 if (!client || !channel)
1010 return silc_hash_table_find(client->channels, channel, NULL,
1014 /* Checks string for bad characters and returns TRUE if they are found. */
1016 bool silc_server_name_bad_chars(const char *name, SilcUInt32 name_len)
1020 for (i = 0; i < name_len; i++) {
1021 if (!isascii(name[i]))
1023 if (name[i] <= 32) return TRUE;
1024 if (name[i] == ' ') return TRUE;
1025 if (name[i] == '*') return TRUE;
1026 if (name[i] == '?') return TRUE;
1027 if (name[i] == ',') return TRUE;
1028 if (name[i] == '@') return TRUE;
1029 if (name[i] == '!') return TRUE;
1035 /* Same as silc_server_name_bad_chars but check for channel names. */
1037 bool silc_server_name_bad_chchars(const char *name, SilcUInt32 name_len)
1041 for (i = 0; i < name_len; i++) {
1042 if (!isascii(name[i]))
1044 if (name[i] <= 32) return TRUE;
1045 if (name[i] == ' ') return TRUE;
1046 if (name[i] == '*') return TRUE;
1047 if (name[i] == '?') return TRUE;
1048 if (name[i] == ',') return TRUE;
1054 /* Modifies the `name' if it includes bad characters and returns new
1055 allocated name that does not include bad characters. */
1057 char *silc_server_name_modify_bad(const char *name, SilcUInt32 name_len)
1060 char *newname = strdup(name);
1062 for (i = 0; i < name_len; i++) {
1063 if (!isascii(newname[i])) newname[i] = '_';
1064 if (newname[i] <= 32) newname[i] = '_';
1065 if (newname[i] == ' ') newname[i] = '_';
1066 if (newname[i] == '*') newname[i] = '_';
1067 if (newname[i] == '?') newname[i] = '_';
1068 if (newname[i] == ',') newname[i] = '_';
1074 /* Find number of sockets by IP address indicated by `ip'. Returns 0 if
1075 socket connections with the IP address does not exist. */
1077 SilcUInt32 silc_server_num_sockets_by_ip(SilcServer server, const char *ip,
1078 SilcSocketType type)
1082 for (i = 0, count = 0; i < server->config->param.connections_max; i++) {
1083 if (server->sockets[i] && !SILC_IS_LISTENER(server->sockets[i]) &&
1084 !strcmp(server->sockets[i]->ip, ip) &&
1085 server->sockets[i]->type == type)
1092 /* Find number of sockets by IP address indicated by remote host, indicatd
1093 by `ip' or `hostname', `port', and `type'. Returns 0 if socket connections
1094 does not exist. If `ip' is provided then `hostname' is ignored. */
1096 SilcUInt32 silc_server_num_sockets_by_remote(SilcServer server,
1098 const char *hostname,
1100 SilcSocketType type)
1104 if (!ip && !hostname)
1107 for (i = 0, count = 0; i < server->config->param.connections_max; i++) {
1108 if (server->sockets[i] && !SILC_IS_LISTENER(server->sockets[i]) &&
1109 ((ip && !strcmp(server->sockets[i]->ip, ip)) ||
1110 (hostname && !strcmp(server->sockets[i]->hostname, hostname))) &&
1111 server->sockets[i]->port == port &&
1112 server->sockets[i]->type == type)
1119 /* Finds locally cached public key by the public key received in the SKE.
1120 If we have it locally cached then we trust it and will use it in the
1121 authentication protocol. Returns the locally cached public key or NULL
1122 if we do not find the public key. */
1124 SilcPublicKey silc_server_find_public_key(SilcServer server,
1125 SilcHashTable local_public_keys,
1126 SilcPublicKey remote_public_key)
1128 SilcPublicKey cached_key;
1130 SILC_LOG_DEBUG(("Find remote public key (%d keys in local cache)",
1131 silc_hash_table_count(local_public_keys)));
1133 if (!silc_hash_table_find_ext(local_public_keys, remote_public_key,
1134 (void **)&cached_key, NULL,
1135 silc_hash_public_key, NULL,
1136 silc_hash_public_key_compare, NULL)) {
1137 SILC_LOG_ERROR(("Public key not found"));
1141 SILC_LOG_DEBUG(("Found public key"));
1146 /* This returns the first public key from the table of public keys. This
1147 is used only in cases where single public key exists in the table and
1148 we want to get a pointer to it. For public key tables that has multiple
1149 keys in it the silc_server_find_public_key must be used. */
1151 SilcPublicKey silc_server_get_public_key(SilcServer server,
1152 SilcHashTable local_public_keys)
1154 SilcPublicKey cached_key;
1155 SilcHashTableList htl;
1157 SILC_LOG_DEBUG(("Start"));
1159 assert(silc_hash_table_count(local_public_keys) < 2);
1161 silc_hash_table_list(local_public_keys, &htl);
1162 if (!silc_hash_table_get(&htl, NULL, (void **)&cached_key)) {
1163 silc_hash_table_list_reset(&htl);
1166 silc_hash_table_list_reset(&htl);
1171 /* Check whether the connection `sock' is allowed to connect to us. This
1172 checks for example whether there is too much connections for this host,
1173 and required version for the host etc. */
1175 bool silc_server_connection_allowed(SilcServer server,
1176 SilcSocketConnection sock,
1177 SilcSocketType type,
1178 SilcServerConfigConnParams *global,
1179 SilcServerConfigConnParams *params,
1182 SilcUInt32 conn_number = (type == SILC_SOCKET_TYPE_CLIENT ?
1183 server->stat.my_clients :
1184 type == SILC_SOCKET_TYPE_SERVER ?
1185 server->stat.my_servers :
1186 server->stat.my_routers);
1187 SilcUInt32 num_sockets, max_hosts, max_per_host;
1188 SilcUInt32 r_protocol_version, l_protocol_version;
1189 SilcUInt32 r_software_version, l_software_version;
1190 char *r_vendor_version = NULL, *l_vendor_version;
1192 SILC_LOG_DEBUG(("Checking whether connection is allowed"));
1196 l_protocol_version =
1197 silc_version_to_num(params && params->version_protocol ?
1198 params->version_protocol :
1199 global->version_protocol);
1200 l_software_version =
1201 silc_version_to_num(params && params->version_software ?
1202 params->version_software :
1203 global->version_software);
1204 l_vendor_version = (params && params->version_software_vendor ?
1205 params->version_software_vendor :
1206 global->version_software_vendor);
1208 if (ske && silc_ske_parse_version(ske, &r_protocol_version, NULL,
1209 &r_software_version, NULL,
1210 &r_vendor_version)) {
1211 sock->version = r_protocol_version;
1213 /* Match protocol version */
1214 if (l_protocol_version && r_protocol_version &&
1215 r_protocol_version < l_protocol_version) {
1216 SILC_LOG_INFO(("Connection %s (%s) is too old version",
1217 sock->hostname, sock->ip));
1218 sock->protocol = NULL;
1219 silc_server_disconnect_remote(server, sock,
1220 SILC_STATUS_ERR_BAD_VERSION,
1221 "You support too old protocol version");
1225 /* Math software version */
1226 if (l_software_version && r_software_version &&
1227 r_software_version < l_software_version) {
1228 SILC_LOG_INFO(("Connection %s (%s) is too old version",
1229 sock->hostname, sock->ip));
1230 sock->protocol = NULL;
1231 silc_server_disconnect_remote(server, sock,
1232 SILC_STATUS_ERR_BAD_VERSION,
1233 "You support too old software version");
1237 /* Regex match vendor version */
1238 if (l_vendor_version && r_vendor_version &&
1239 !silc_string_match(l_vendor_version, r_vendor_version)) {
1240 SILC_LOG_INFO(("Connection %s (%s) is unsupported version",
1241 sock->hostname, sock->ip));
1242 sock->protocol = NULL;
1243 silc_server_disconnect_remote(server, sock,
1244 SILC_STATUS_ERR_BAD_VERSION,
1245 "Your software is not supported");
1249 silc_free(r_vendor_version);
1251 /* Check for maximum connections limit */
1253 num_sockets = silc_server_num_sockets_by_ip(server, sock->ip, type);
1254 max_hosts = (params ? params->connections_max : global->connections_max);
1255 max_per_host = (params ? params->connections_max_per_host :
1256 global->connections_max_per_host);
1258 if (max_hosts && conn_number >= max_hosts) {
1259 SILC_LOG_INFO(("Server is full, closing %s (%s) connection",
1260 sock->hostname, sock->ip));
1261 sock->protocol = NULL;
1262 silc_server_disconnect_remote(server, sock,
1263 SILC_STATUS_ERR_RESOURCE_LIMIT,
1264 "Server is full, try again later");
1268 if (num_sockets >= max_per_host) {
1269 SILC_LOG_INFO(("Too many connections from %s (%s), closing connection",
1270 sock->hostname, sock->ip));
1271 sock->protocol = NULL;
1272 silc_server_disconnect_remote(server, sock,
1273 SILC_STATUS_ERR_RESOURCE_LIMIT,
1274 "Too many connections from your host");
1281 /* Checks that client has rights to add or remove channel modes. If any
1282 of the checks fails FALSE is returned. */
1284 bool silc_server_check_cmode_rights(SilcServer server,
1285 SilcChannelEntry channel,
1286 SilcChannelClientEntry client,
1289 bool is_op = client->mode & SILC_CHANNEL_UMODE_CHANOP;
1290 bool is_fo = client->mode & SILC_CHANNEL_UMODE_CHANFO;
1292 /* Check whether has rights to change anything */
1293 if (!is_op && !is_fo)
1296 /* Check whether has rights to change everything */
1300 /* Founder implies operator */
1304 /* We know that client is channel operator, check that they are not
1305 changing anything that requires channel founder rights. Rest of the
1306 modes are available automatically for channel operator. */
1308 if (mode & SILC_CHANNEL_MODE_PRIVKEY) {
1309 if (is_op && !is_fo)
1312 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
1313 if (is_op && !is_fo)
1318 if (mode & SILC_CHANNEL_MODE_PASSPHRASE) {
1319 if (!(channel->mode & SILC_CHANNEL_MODE_PASSPHRASE)) {
1320 if (is_op && !is_fo)
1324 if (channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
1325 if (is_op && !is_fo)
1330 if (mode & SILC_CHANNEL_MODE_CIPHER) {
1331 if (!(channel->mode & SILC_CHANNEL_MODE_CIPHER)) {
1332 if (is_op && !is_fo)
1336 if (channel->mode & SILC_CHANNEL_MODE_CIPHER) {
1337 if (is_op && !is_fo)
1342 if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
1343 if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
1344 if (is_op && !is_fo)
1348 if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
1349 if (is_op && !is_fo)
1354 if (mode & SILC_CHANNEL_MODE_SILENCE_USERS) {
1355 if (!(channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS)) {
1356 if (is_op && !is_fo)
1360 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS) {
1361 if (is_op && !is_fo)
1366 if (mode & SILC_CHANNEL_MODE_SILENCE_OPERS) {
1367 if (!(channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS)) {
1368 if (is_op && !is_fo)
1372 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS) {
1373 if (is_op && !is_fo)
1378 if (mode & SILC_CHANNEL_MODE_CHANNEL_AUTH) {
1379 if (!(channel->mode & SILC_CHANNEL_MODE_CHANNEL_AUTH)) {
1380 if (is_op && !is_fo)
1384 if (channel->mode & SILC_CHANNEL_MODE_CHANNEL_AUTH) {
1385 if (is_op && !is_fo)
1393 /* Check that the client has rights to change its user mode. Returns
1394 FALSE if setting some mode is not allowed. */
1396 bool silc_server_check_umode_rights(SilcServer server,
1397 SilcClientEntry client,
1400 bool server_op = FALSE, router_op = FALSE;
1402 if (mode & SILC_UMODE_SERVER_OPERATOR) {
1403 /* Cannot set server operator mode (must use OPER command) */
1404 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR))
1407 /* Remove the server operator rights */
1408 if (client->mode & SILC_UMODE_SERVER_OPERATOR)
1412 if (mode & SILC_UMODE_ROUTER_OPERATOR) {
1413 /* Cannot set router operator mode (must use SILCOPER command) */
1414 if (!(client->mode & SILC_UMODE_ROUTER_OPERATOR))
1417 /* Remove the router operator rights */
1418 if (client->mode & SILC_UMODE_ROUTER_OPERATOR)
1423 SILC_UMODE_STATS_UPDATE(server, SILC_UMODE_SERVER_OPERATOR);
1425 SILC_UMODE_STATS_UPDATE(router, SILC_UMODE_ROUTER_OPERATOR);
1430 /* This function is used to send the notify packets and motd to the
1431 incoming client connection. */
1433 void silc_server_send_connect_notifys(SilcServer server,
1434 SilcSocketConnection sock,
1435 SilcClientEntry client)
1437 SilcIDListData idata = (SilcIDListData)client;
1439 SILC_LOG_DEBUG(("Send welcome notifys"));
1441 /* Send some nice info to the client */
1442 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1443 ("Welcome to the SILC Network %s",
1445 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1446 ("Your host is %s, running version %s",
1447 server->server_name, server_version));
1449 if (server->server_type == SILC_ROUTER) {
1450 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1451 ("There are %d clients, %d servers and %d "
1452 "routers in SILC Network",
1453 server->stat.clients, server->stat.servers,
1454 server->stat.routers));
1456 if (server->stat.clients && server->stat.servers + 1)
1457 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1458 ("There are %d clients, %d servers and %d "
1459 "routers in SILC Network",
1460 server->stat.clients, server->stat.servers,
1461 (server->standalone ? 0 :
1462 !server->stat.routers ? 1 :
1463 server->stat.routers)));
1466 if (server->stat.cell_clients && server->stat.cell_servers + 1)
1467 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1468 ("There are %d clients on %d server in our cell",
1469 server->stat.cell_clients,
1470 server->stat.cell_servers));
1471 if (server->server_type == SILC_ROUTER) {
1472 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1473 ("I have %d clients, %d channels, %d servers and "
1475 server->stat.my_clients,
1476 server->stat.my_channels,
1477 server->stat.my_servers,
1478 server->stat.my_routers));
1480 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1481 ("I have %d clients and %d channels formed",
1482 server->stat.my_clients,
1483 server->stat.my_channels));
1486 if (server->stat.server_ops || server->stat.router_ops)
1487 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1488 ("There are %d server operators and %d router "
1490 server->stat.server_ops,
1491 server->stat.router_ops));
1492 if (server->stat.my_router_ops + server->stat.my_server_ops)
1493 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1494 ("I have %d operators online",
1495 server->stat.my_router_ops +
1496 server->stat.my_server_ops));
1498 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1499 ("Your connection is secured with %s cipher, "
1500 "key length %d bits",
1501 silc_cipher_get_name(idata->send_key),
1502 silc_cipher_get_key_len(idata->send_key)));
1503 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1504 ("Your current nickname is %s",
1508 silc_server_send_motd(server, sock);
1511 /* Kill the client indicated by `remote_client' sending KILLED notify
1512 to the client, to all channels client has joined and to primary
1513 router if needed. The killed client is also removed from all channels. */
1515 void silc_server_kill_client(SilcServer server,
1516 SilcClientEntry remote_client,
1517 const char *comment,
1519 SilcIdType killer_id_type)
1521 SilcBuffer killed, killer;
1523 SILC_LOG_DEBUG(("Killing client %s",
1524 silc_id_render(remote_client->id, SILC_ID_CLIENT)));
1526 /* Send the KILL notify packets. First send it to the channel, then
1527 to our primary router and then directly to the client who is being
1528 killed right now. */
1530 killed = silc_id_payload_encode(remote_client->id, SILC_ID_CLIENT);
1531 killer = silc_id_payload_encode(killer_id, killer_id_type);
1533 /* Send KILLED notify to the channels. It is not sent to the client
1534 as it will be sent differently destined directly to the client and not
1536 silc_server_send_notify_on_channels(server, remote_client,
1537 remote_client, SILC_NOTIFY_TYPE_KILLED,
1538 3, killed->data, killed->len,
1539 comment, comment ? strlen(comment) : 0,
1540 killer->data, killer->len);
1542 /* Send KILLED notify to primary route */
1543 silc_server_send_notify_killed(server, SILC_PRIMARY_ROUTE(server),
1544 SILC_BROADCAST(server), remote_client->id,
1545 comment, killer_id, killer_id_type);
1547 /* Send KILLED notify to the client directly */
1548 if (remote_client->connection || remote_client->router)
1549 silc_server_send_notify_killed(server, remote_client->connection ?
1550 remote_client->connection :
1551 remote_client->router->connection, FALSE,
1552 remote_client->id, comment,
1553 killer_id, killer_id_type);
1555 /* Remove the client from all channels. This generates new keys to the
1556 channels as well. */
1557 silc_server_remove_from_channels(server, NULL, remote_client, FALSE,
1560 /* Remove the client entry, If it is locally connected then we will also
1561 disconnect the client here */
1562 if (remote_client->connection) {
1563 /* Remove locally conneted client */
1564 SilcSocketConnection sock = remote_client->connection;
1565 silc_server_free_client_data(server, sock, remote_client, FALSE, NULL);
1566 silc_server_close_connection(server, sock);
1568 /* Update statistics */
1569 server->stat.clients--;
1570 if (server->stat.cell_clients)
1571 server->stat.cell_clients--;
1572 SILC_OPER_STATS_UPDATE(remote_client, server, SILC_UMODE_SERVER_OPERATOR);
1573 SILC_OPER_STATS_UPDATE(remote_client, router, SILC_UMODE_ROUTER_OPERATOR);
1575 if (SILC_IS_LOCAL(remote_client)) {
1576 server->stat.my_clients--;
1577 silc_schedule_task_del_by_context(server->schedule, remote_client);
1578 silc_idlist_del_data(remote_client);
1581 /* Remove remote client */
1582 silc_idlist_del_data(remote_client);
1583 if (!silc_idlist_del_client(server->global_list, remote_client)) {
1584 /* Remove this client from watcher list if it is */
1585 silc_server_del_from_watcher_list(server, remote_client);
1586 silc_idlist_del_client(server->local_list, remote_client);
1590 silc_buffer_free(killer);
1591 silc_buffer_free(killed);
1596 SilcClientEntry client;
1597 SilcNotifyType notify;
1598 const char *new_nick;
1599 } WatcherNotifyContext;
1602 silc_server_check_watcher_list_foreach(void *key, void *context,
1605 WatcherNotifyContext *notify = user_context;
1606 SilcClientEntry entry = context;
1607 SilcSocketConnection sock;
1612 if (entry == notify->client)
1615 sock = silc_server_get_client_route(notify->server, NULL, 0, entry->id,
1618 SILC_LOG_DEBUG(("Sending WATCH notify to %s",
1619 silc_id_render(entry->id, SILC_ID_CLIENT)));
1621 /* Send the WATCH notify */
1622 silc_server_send_notify_watch(notify->server, sock, entry,
1624 notify->new_nick ? notify->new_nick :
1625 (const char *)notify->client->nickname,
1630 /* This function checks whether the `client' nickname is being watched
1631 by someone, and notifies the watcher of the notify change of notify
1632 type indicated by `notify'. */
1634 bool silc_server_check_watcher_list(SilcServer server,
1635 SilcClientEntry client,
1636 const char *new_nick,
1637 SilcNotifyType notify)
1639 unsigned char hash[16];
1640 WatcherNotifyContext n;
1642 SILC_LOG_DEBUG(("Checking watcher list %s",
1643 client->nickname ? client->nickname : (unsigned char *)""));
1645 /* If the watching is rejected by the client do nothing */
1646 if (client->mode & SILC_UMODE_REJECT_WATCHING)
1649 /* Make hash from the nick, or take it from Client ID */
1650 if (client->nickname) {
1652 memset(nick, 0, sizeof(nick));
1653 silc_to_lower(client->nickname, nick, sizeof(nick) - 1);
1654 silc_hash_make(server->md5hash, nick, strlen(nick), hash);
1656 memset(hash, 0, sizeof(hash));
1657 memcpy(hash, client->id->hash, sizeof(client->id->hash));
1662 n.new_nick = new_nick;
1665 /* Send notify to all watchers */
1666 silc_hash_table_find_foreach(server->watcher_list, hash,
1667 silc_server_check_watcher_list_foreach, &n);
1672 /* Remove the `client' from watcher list. After calling this the `client'
1673 is not watching any nicknames. */
1675 bool silc_server_del_from_watcher_list(SilcServer server,
1676 SilcClientEntry client)
1678 SilcHashTableList htl;
1680 SilcClientEntry entry;
1683 silc_hash_table_list(server->watcher_list, &htl);
1684 while (silc_hash_table_get(&htl, &key, (void **)&entry)) {
1685 if (entry == client) {
1686 silc_hash_table_del_by_context(server->watcher_list, key, client);
1689 SILC_LOG_DEBUG(("Removing %s from WATCH list",
1690 silc_id_render(client->id, SILC_ID_CLIENT)));
1692 /* Now check whether there still exists entries with this key, if not
1693 then free the key to not leak memory. */
1694 if (!silc_hash_table_find(server->watcher_list, key, NULL, NULL))
1700 silc_hash_table_list_reset(&htl);
1705 /* Force the client indicated by `chl' to change the channel user mode
1706 on channel indicated by `channel' to `forced_mode'. */
1708 bool silc_server_force_cumode_change(SilcServer server,
1709 SilcSocketConnection sock,
1710 SilcChannelEntry channel,
1711 SilcChannelClientEntry chl,
1712 SilcUInt32 forced_mode)
1714 SilcBuffer idp1, idp2;
1715 unsigned char cumode[4];
1717 SILC_LOG_DEBUG(("Enforcing sender to change mode"));
1720 silc_server_send_notify_cumode(server, sock, FALSE, channel, forced_mode,
1721 server->id, SILC_ID_SERVER,
1722 chl->client->id, NULL);
1724 idp1 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
1725 idp2 = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
1726 SILC_PUT32_MSB(forced_mode, cumode);
1727 silc_server_send_notify_to_channel(server, sock, channel, FALSE, TRUE,
1728 SILC_NOTIFY_TYPE_CUMODE_CHANGE,
1729 3, idp1->data, idp1->len,
1730 cumode, sizeof(cumode),
1731 idp2->data, idp2->len);
1732 silc_buffer_free(idp1);
1733 silc_buffer_free(idp2);
1738 /* Find active socket connection by the IP address and port indicated by
1739 `ip' and `port', and socket connection type of `type'. */
1741 SilcSocketConnection
1742 silc_server_find_socket_by_host(SilcServer server,
1743 SilcSocketType type,
1744 const char *ip, SilcUInt16 port)
1748 for (i = 0; i < server->config->param.connections_max; i++) {
1749 if (!server->sockets[i])
1751 if (!strcmp(server->sockets[i]->ip, ip) &&
1752 (!port || server->sockets[i]->port == port) &&
1753 server->sockets[i]->type == type)
1754 return server->sockets[i];
1760 /* This function can be used to match the invite and ban lists. */
1762 bool silc_server_inviteban_match(SilcServer server, SilcHashTable list,
1763 SilcUInt8 type, void *check)
1765 unsigned char *tmp = NULL;
1766 SilcUInt32 len = 0, t;
1767 SilcHashTableList htl;
1768 SilcBuffer entry, idp = NULL, pkp = NULL;
1771 if (type < 1 || type > 3 || !check)
1775 tmp = strdup((char *)check);
1780 pkp = silc_pkcs_public_key_payload_encode(check);
1787 idp = silc_id_payload_encode(check, SILC_ID_CLIENT);
1794 /* Compare the list */
1795 silc_hash_table_list(list, &htl);
1796 while (silc_hash_table_get(&htl, (void **)&t, (void **)&entry)) {
1799 if (silc_string_match(entry->data, tmp)) {
1803 } else if (!memcmp(entry->data, tmp, len)) {
1809 silc_hash_table_list_reset(&htl);
1813 silc_buffer_free(idp);
1814 silc_buffer_free(pkp);
1818 /* Process invite or ban information */
1820 void silc_server_inviteban_process(SilcServer server, SilcHashTable list,
1821 SilcUInt8 action, SilcArgumentPayload args)
1824 SilcUInt32 type, len;
1826 SilcHashTableList htl;
1828 SILC_LOG_DEBUG(("Processing invite/ban for %s action",
1829 action == 0x01 ? "DEL" : "ADD"));
1831 /* Add the information to invite list */
1832 if (action == 0x00 || action == 0x03) {
1833 /* Traverse all arguments and add to the hash table according to
1835 tmp = silc_argument_get_first_arg(args, &type, &len);
1838 /* Invite string. Get the old invite string from hash table
1839 and append this at the end of the existing one. */
1840 if (!silc_hash_table_find(list, (void *)1, NULL, (void **)&tmp2)) {
1841 tmp2 = silc_calloc(1, sizeof(*tmp2));
1842 silc_hash_table_add(list, (void *)1, tmp2);
1845 /* Check that the string is not part of invite string already */
1846 if (action == 0x00) {
1847 if (silc_string_match(tmp2->data, tmp))
1851 if (tmp[len - 1] == ',')
1852 tmp[len - 1] = '\0';
1853 silc_buffer_strformat(tmp2, tmp, SILC_STR_END);
1854 silc_buffer_strformat(tmp2, ",", SILC_STR_END);
1857 /* Announced list. Check each entry in the list */
1858 unsigned char e[256];
1859 char *start, *end, *n, *rtmp;
1862 rtmp = silc_memdup(tmp, len);
1863 for (i = 0, k = 0; i < len; i++) {
1867 memset(e, 0, sizeof(e));
1868 silc_strncat(e, sizeof(e), tmp + k, i - k);
1869 if (!silc_string_match(tmp2->data, e)) {
1874 /* Matches. Delete it since we have it already */
1875 start = strstr(rtmp, e);
1876 if (start && strlen(start) >= (i - k)) {
1877 end = start + (i - k);
1878 n = silc_calloc(strlen(rtmp) - (i - k), sizeof(*n));
1879 strncat(n, rtmp, start - rtmp);
1880 if (strlen(end) > 1)
1881 strncat(n, end + 1, ((rtmp + strlen(rtmp)) - end) - 1);
1889 /* Save the part that we didn't already have. */
1890 if (strlen(rtmp) > 1) {
1891 silc_buffer_strformat(tmp2, rtmp, SILC_STR_END);
1892 silc_buffer_strformat(tmp2, ",", SILC_STR_END);
1897 } else if (type == 2) {
1898 /* Public key. Check first if the public key is already on the
1899 list and ignore it if it is, otherwise, add it to hash table. */
1901 /* Check if the public key is in the list already */
1902 silc_hash_table_list(list, &htl);
1903 while (silc_hash_table_get(&htl, (void **)&type, (void **)&tmp2)) {
1904 if (type == 2 && !memcmp(tmp2->data, tmp, len)) {
1909 silc_hash_table_list_reset(&htl);
1911 /* Add new public key to invite list */
1913 tmp2 = silc_buffer_alloc_size(len);
1914 silc_buffer_put(tmp2, tmp, len);
1915 silc_hash_table_add(list, (void *)2, tmp2);
1918 } else if (type == 3) {
1921 /* Check if the ID is in the list already */
1922 silc_hash_table_list(list, &htl);
1923 while (silc_hash_table_get(&htl, (void **)&type, (void **)&tmp2)) {
1924 if (type == 3 && !memcmp(tmp2->data, tmp, len)) {
1929 silc_hash_table_list_reset(&htl);
1931 /* Add new Client ID to invite list */
1933 tmp2 = silc_buffer_alloc_size(len);
1934 silc_buffer_put(tmp2, tmp, len);
1935 silc_hash_table_add(list, (void *)3, tmp2);
1939 tmp = silc_argument_get_next_arg(args, &type, &len);
1943 /* Delete information to invite list */
1944 if (action == 0x01 && list) {
1945 /* Now delete the arguments from invite list */
1946 tmp = silc_argument_get_first_arg(args, &type, &len);
1949 /* Invite string. Get the old string from hash table and delete
1950 the requested string. */
1951 char *string = NULL, *start, *end, *n;
1953 if (silc_hash_table_find(list, (void *)1, NULL, (void **)&tmp2)) {
1954 string = tmp2->head;
1955 if (tmp2->truelen && !strncmp(string, tmp, tmp2->truelen - 1)) {
1956 /* Delete entire string */
1957 silc_hash_table_del(list, (void *)1);
1958 } else if (tmp2->truelen) {
1959 /* Delete part of the string */
1960 start = strstr(string, tmp);
1961 if (start && strlen(start) >= len) {
1963 n = silc_calloc(strlen(string) - len, sizeof(*n));
1964 strncat(n, string, start - string);
1965 if (strlen(end) > 1)
1966 strncat(n, end + 1, ((string + strlen(string)) - end) - 1);
1967 silc_free(tmp2->head);
1968 silc_buffer_set(tmp2, n, strlen(n));
1973 } else if (type == 2) {
1976 /* Delete from the invite list */
1977 silc_hash_table_list(list, &htl);
1978 while (silc_hash_table_get(&htl, (void **)&type, (void **)&tmp2)) {
1979 if (type == 2 && !memcmp(tmp2->data, tmp, len)) {
1980 silc_hash_table_del_by_context(list, (void *)2, tmp2);
1984 silc_hash_table_list_reset(&htl);
1986 } else if (type == 3) {
1989 /* Delete from the invite list */
1990 silc_hash_table_list(list, &htl);
1991 while (silc_hash_table_get(&htl, (void **)&type, (void **)&tmp2)) {
1992 if (type == 3 && !memcmp(tmp2->data, tmp, len)) {
1993 silc_hash_table_del_by_context(list, (void *)3, tmp2);
1997 silc_hash_table_list_reset(&htl);
2000 tmp = silc_argument_get_next_arg(args, &type, &len);
2005 /* Destructor for invite and ban list entrys */
2007 void silc_server_inviteban_destruct(void *key, void *context,
2010 silc_buffer_free(context);
2013 /* Creates connections accoring to configuration. */
2015 void silc_server_create_connections(SilcServer server)
2017 silc_schedule_task_del_by_callback(server->schedule,
2018 silc_server_connect_to_router);
2019 silc_schedule_task_add(server->schedule, 0,
2020 silc_server_connect_to_router, server, 0, 1,
2021 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
2025 silc_server_process_channel_pk_destruct(void *key, void *context,
2029 silc_pkcs_public_key_free(context);
2032 /* Processes a channel public key, either adds or removes it. */
2035 silc_server_process_channel_pk(SilcServer server,
2036 SilcChannelEntry channel,
2037 SilcUInt32 type, const unsigned char *pk,
2040 unsigned char pkhash[20];
2043 SILC_LOG_DEBUG(("Processing channel public key"));
2046 return SILC_STATUS_ERR_NOT_ENOUGH_PARAMS;
2048 /* Decode the public key */
2049 if (!silc_pkcs_public_key_payload_decode((unsigned char *)pk, pk_len, &chpk))
2050 return SILC_STATUS_ERR_UNSUPPORTED_PUBLIC_KEY;
2052 /* Create channel public key list (hash table) if needed */
2053 if (!channel->channel_pubkeys) {
2054 channel->channel_pubkeys =
2055 silc_hash_table_alloc(0, silc_hash_data, (void *)20,
2056 silc_hash_data_compare, (void *)20,
2057 silc_server_process_channel_pk_destruct, channel,
2061 /* Create SHA-1 digest of the public key data */
2062 silc_hash_make(server->sha1hash, pk + 4, pk_len - 4, pkhash);
2065 /* Add new public key to channel public key list */
2066 SILC_LOG_DEBUG(("Add new channel public key to channel %s",
2067 channel->channel_name));
2069 /* Check for resource limit */
2070 if (silc_hash_table_count(channel->channel_pubkeys) > 64) {
2071 silc_pkcs_public_key_free(chpk);
2072 return SILC_STATUS_ERR_RESOURCE_LIMIT;
2075 /* Add if doesn't exist already */
2076 if (!silc_hash_table_find(channel->channel_pubkeys, pkhash,
2078 silc_hash_table_add(channel->channel_pubkeys, silc_memdup(pkhash, 20),
2080 } else if (type == 0x01) {
2081 /* Delete public key from channel public key list */
2082 SILC_LOG_DEBUG(("Delete a channel public key from channel %s",
2083 channel->channel_name));
2084 if (!silc_hash_table_del(channel->channel_pubkeys, pkhash))
2085 silc_pkcs_public_key_free(chpk);
2087 silc_pkcs_public_key_free(chpk);
2088 return SILC_STATUS_ERR_NOT_ENOUGH_PARAMS;
2091 return SILC_STATUS_OK;
2094 /* Returns the channel public keys as Argument List payload. */
2096 SilcBuffer silc_server_get_channel_pk_list(SilcServer server,
2097 SilcChannelEntry channel,
2101 SilcHashTableList htl;
2102 SilcBuffer list, pkp;
2105 SILC_LOG_DEBUG(("Encoding channel public keys list"));
2107 if (!channel->channel_pubkeys ||
2108 !silc_hash_table_count(channel->channel_pubkeys))
2111 /* Encode the list */
2112 list = silc_buffer_alloc_size(2);
2113 silc_buffer_format(list,
2114 SILC_STR_UI_SHORT(silc_hash_table_count(
2115 channel->channel_pubkeys)),
2118 silc_hash_table_list(channel->channel_pubkeys, &htl);
2119 while (silc_hash_table_get(&htl, NULL, (void **)&pk)) {
2120 pkp = silc_pkcs_public_key_payload_encode(pk);
2121 list = silc_argument_payload_encode_one(list, pkp->data, pkp->len,
2123 delete ? 0x01 : 0x00);
2124 silc_buffer_free(pkp);
2126 silc_hash_table_list_reset(&htl);
2131 /* Sets the channel public keys into channel from the list of public keys. */
2133 SilcStatus silc_server_set_channel_pk_list(SilcServer server,
2134 SilcSocketConnection sender,
2135 SilcChannelEntry channel,
2136 const unsigned char *pklist,
2137 SilcUInt32 pklist_len)
2140 SilcArgumentPayload args;
2141 unsigned char *chpk;
2142 SilcUInt32 chpklen, type;
2143 SilcStatus ret = SILC_STATUS_OK;
2145 SILC_LOG_DEBUG(("Setting channel public keys list"));
2147 if (!pklist || pklist_len < 2)
2148 return SILC_STATUS_ERR_NOT_ENOUGH_PARAMS;
2150 /* Get the argument from the Argument List Payload */
2151 SILC_GET16_MSB(argc, pklist);
2152 args = silc_argument_payload_parse(pklist + 2, pklist_len - 2, argc);
2154 return SILC_STATUS_ERR_NOT_ENOUGH_PARAMS;
2156 /* Process the public keys one by one */
2157 chpk = silc_argument_get_first_arg(args, &type, &chpklen);
2159 /* If announcing keys and we have them set already, do not allow this */
2160 if (chpk && type == 0x03 && channel->channel_pubkeys &&
2161 server->server_type == SILC_ROUTER &&
2162 sender != SILC_PRIMARY_ROUTE(server)) {
2163 SILC_LOG_DEBUG(("Channel public key list set already, enforce our list"));
2164 silc_argument_payload_free(args);
2165 return SILC_STATUS_ERR_OPERATION_ALLOWED;
2168 /* If we are normal server and receive announcement list and we already
2169 have keys set, we replace the old list with the announced one. */
2170 if (chpk && type == 0x03 && channel->channel_pubkeys &&
2171 server->server_type != SILC_ROUTER) {
2173 unsigned char mask[4];
2175 SILC_LOG_DEBUG(("Router enforces its list, remove old list"));
2176 silc_hash_table_free(channel->channel_pubkeys);
2177 channel->channel_pubkeys = NULL;
2179 /* Send notify that removes the old list */
2180 sidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
2181 SILC_PUT32_MSB((channel->mode & (~SILC_CHANNEL_MODE_CHANNEL_AUTH)), mask);
2182 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
2183 SILC_NOTIFY_TYPE_CMODE_CHANGE, 7,
2184 sidp->data, sidp->len,
2188 strlen(channel->cipher) : 0,
2190 channel->hmac_name ?
2191 strlen(channel->hmac_name) : 0,
2192 channel->passphrase,
2193 channel->passphrase ?
2194 strlen(channel->passphrase) : 0,
2196 silc_buffer_free(sidp);
2202 ret = silc_server_process_channel_pk(server, channel, type,
2204 if (ret != SILC_STATUS_OK)
2206 chpk = silc_argument_get_next_arg(args, &type, &chpklen);
2209 silc_argument_payload_free(args);
2213 /* Verifies the Authentication Payload `auth' with one of the public keys
2214 on the `channel' public key list. */
2216 bool silc_server_verify_channel_auth(SilcServer server,
2217 SilcChannelEntry channel,
2218 SilcClientID *client_id,
2219 const unsigned char *auth,
2220 SilcUInt32 auth_len)
2224 unsigned char *pkhash;
2225 SilcUInt32 pkhash_len;
2228 SILC_LOG_DEBUG(("Verifying channel authentication"));
2230 if (!auth || !auth_len || !channel->channel_pubkeys)
2233 /* Get the hash from the auth data which tells us what public key we
2234 must use in verification. */
2236 ap = silc_auth_payload_parse(auth, auth_len);
2240 pkhash = silc_auth_get_public_data(ap, &pkhash_len);
2241 if (pkhash_len < 128)
2244 /* Find the public key with the hash */
2245 if (!silc_hash_table_find(channel->channel_pubkeys, pkhash,
2246 NULL, (void **)&chpk)) {
2247 SILC_LOG_DEBUG(("Public key not found in channel public key list"));
2251 /* Verify the signature */
2252 if (!silc_auth_verify(ap, SILC_AUTH_PUBLIC_KEY, (void *)chpk, 0,
2253 server->sha1hash, client_id, SILC_ID_CLIENT)) {
2254 SILC_LOG_DEBUG(("Authentication failed"));
2261 silc_auth_payload_free(ap);