5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2009 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 %p %s from all channels",
46 client, 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);
122 SILC_VERIFY(!silc_hash_table_count(client->channels));
125 /* This function removes all client entries that are originated from
126 `router' and are owned by `entry'. `router' and `entry' can be same
127 too. If `server_signoff' is TRUE then SERVER_SIGNOFF notify is
128 distributed to our local clients. */
130 SilcBool silc_server_remove_clients_by_server(SilcServer server,
131 SilcServerEntry router,
132 SilcServerEntry entry,
133 SilcBool server_signoff)
136 SilcIDCacheEntry id_cache = NULL;
137 SilcClientEntry client = NULL;
139 unsigned char **argv = NULL;
140 SilcUInt32 *argv_lens = NULL, *argv_types = NULL, argc = 0;
141 SilcHashTableList htl;
142 SilcChannelEntry channel;
143 SilcHashTable channels, clients;
146 if (!(entry->data.status & SILC_IDLIST_STATUS_REGISTERED))
149 SILC_LOG_DEBUG(("Removing clients by %s",
150 entry->server_name ? entry->server_name : "server"));
155 /* Allocate the hash table that holds the channels that require
156 channel key re-generation after we've removed this server's clients
157 from the channels. */
158 channels = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL, NULL,
160 clients = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL, NULL,
163 if (server_signoff) {
164 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
165 argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
166 argv_lens = silc_realloc(argv_lens, sizeof(*argv_lens) * (argc + 1));
167 argv_types = silc_realloc(argv_types, sizeof(*argv_types) * (argc + 1));
168 argv[argc] = silc_calloc(silc_buffer_len(idp), sizeof(*argv[0]));
169 memcpy(argv[argc], idp->data, silc_buffer_len(idp));
170 argv_lens[argc] = silc_buffer_len(idp);
171 argv_types[argc] = argc + 1;
173 silc_buffer_free(idp);
176 if (silc_idcache_get_all(server->local_list->clients, &list)) {
177 silc_list_start(list);
178 while ((id_cache = silc_list_get(list))) {
179 client = (SilcClientEntry)id_cache->context;
181 /* If client is not registered, is not originated from `router'
182 and is not owned by `entry', skip it. */
183 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) ||
184 client->router != router ||
185 (router != entry && !SILC_ID_COMPARE(client->id, entry->id,
186 client->id->ip.data_len))) {
190 if (server_signoff) {
191 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
193 argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
194 argv_lens = silc_realloc(argv_lens, sizeof(*argv_lens) *
196 argv_types = silc_realloc(argv_types, sizeof(*argv_types) *
198 argv[argc] = silc_calloc(silc_buffer_len(idp), sizeof(*argv[0]));
199 memcpy(argv[argc], idp->data, silc_buffer_len(idp));
200 argv_lens[argc] = silc_buffer_len(idp);
201 argv_types[argc] = argc + 1;
203 silc_buffer_free(idp);
207 /* Update statistics */
208 SILC_LOG_DEBUG(("stat.clients %d->%d", server->stat.clients,
209 server->stat.clients - 1));
210 SILC_VERIFY(server->stat.clients > 0);
211 server->stat.clients--;
212 if (server->stat.cell_clients)
213 server->stat.cell_clients--;
214 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
215 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
217 /* Remove client's public key from repository, this will free it too. */
218 if (client->data.public_key) {
219 silc_skr_del_public_key(server->repository, client->data.public_key,
221 client->data.public_key = NULL;
224 silc_server_remove_clients_channels(server, entry, clients,
226 silc_server_del_from_watcher_list(server, client);
228 /* Remove the client entry */
229 if (!server_signoff) {
230 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
232 client->router = NULL;
233 client->connection = NULL;
234 client->data.created = silc_time();
235 silc_dlist_del(server->expired_clients, client);
236 silc_dlist_add(server->expired_clients, client);
238 silc_idlist_del_data(client);
239 silc_idlist_del_client(server->local_list, client);
244 if (silc_idcache_get_all(server->global_list->clients, &list)) {
245 silc_list_start(list);
246 while ((id_cache = silc_list_get(list))) {
247 client = (SilcClientEntry)id_cache->context;
249 /* If client is not registered, is not originated from `router'
250 and is not owned by `entry', skip it. */
251 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) ||
252 client->router != router ||
253 (router != entry && !SILC_ID_COMPARE(client->id, entry->id,
254 client->id->ip.data_len))) {
258 if (server_signoff) {
259 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
260 argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
261 argv_lens = silc_realloc(argv_lens, sizeof(*argv_lens) *
263 argv_types = silc_realloc(argv_types, sizeof(*argv_types) *
265 argv[argc] = silc_calloc(silc_buffer_len(idp), sizeof(*argv[0]));
266 memcpy(argv[argc], idp->data, silc_buffer_len(idp));
267 argv_lens[argc] = silc_buffer_len(idp);
268 argv_types[argc] = argc + 1;
270 silc_buffer_free(idp);
273 /* Update statistics */
274 SILC_LOG_DEBUG(("stat.clients %d->%d", server->stat.clients,
275 server->stat.clients - 1));
276 SILC_VERIFY(server->stat.clients > 0);
277 server->stat.clients--;
278 if (server->stat.cell_clients)
279 server->stat.cell_clients--;
280 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
281 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
283 /* Remove client's public key from repository, this will free it too. */
284 if (client->data.public_key) {
285 silc_skr_del_public_key(server->repository, client->data.public_key,
287 client->data.public_key = NULL;
290 silc_server_remove_clients_channels(server, entry, clients,
292 silc_server_del_from_watcher_list(server, client);
294 /* Remove the client entry */
295 if (!server_signoff) {
296 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
298 client->router = NULL;
299 client->connection = NULL;
300 client->data.created = silc_time();
301 silc_dlist_del(server->expired_clients, client);
302 silc_dlist_add(server->expired_clients, client);
304 silc_idlist_del_data(client);
305 silc_idlist_del_client(server->global_list, client);
310 /* Return now if we are shutting down */
311 if (server->server_shutdown) {
312 silc_hash_table_free(channels);
314 if (server_signoff) {
315 for (i = 0; i < argc; i++)
318 silc_free(argv_lens);
319 silc_free(argv_types);
320 silc_hash_table_free(clients);
325 /* Send the SERVER_SIGNOFF notify */
326 if (server_signoff) {
327 SilcBuffer args, not;
329 SILC_LOG_DEBUG(("Sending SERVER_SIGNOFF for %s with %d clients",
330 silc_id_render(entry->id, SILC_ID_SERVER), argc - 1));
332 /* Send SERVER_SIGNOFF notify to our primary router */
333 if (server->router != entry) {
334 args = silc_argument_payload_encode(1, argv, argv_lens,
336 silc_server_send_notify_args(server, SILC_PRIMARY_ROUTE(server),
337 SILC_BROADCAST(server),
338 SILC_NOTIFY_TYPE_SERVER_SIGNOFF,
340 silc_buffer_free(args);
343 /* Send to local clients. We also send the list of client ID's that
344 is to be removed for those servers that would like to use that list. */
345 args = silc_argument_payload_encode(argc, argv, argv_lens,
347 not = silc_notify_payload_encode_args(SILC_NOTIFY_TYPE_SERVER_SIGNOFF,
349 silc_server_packet_send_clients(server, clients,
350 SILC_PACKET_NOTIFY, 0, FALSE,
351 not->data, silc_buffer_len(not));
353 /* Send notify also to local backup routers */
354 silc_server_backup_send(server, NULL, SILC_PACKET_NOTIFY, 0,
355 not->data, silc_buffer_len(not), FALSE, TRUE);
357 silc_buffer_free(args);
358 silc_buffer_free(not);
359 for (i = 0; i < argc; i++)
362 silc_free(argv_lens);
363 silc_free(argv_types);
364 silc_hash_table_free(clients);
367 /* We must now re-generate the channel key for all channels that had
368 this server's client(s) on the channel. As they left the channel we
369 must re-generate the channel key. */
370 silc_hash_table_list(channels, &htl);
371 while (silc_hash_table_get(&htl, NULL, (void *)&channel)) {
372 if (!silc_server_create_channel_key(server, channel, 0)) {
373 silc_hash_table_list_reset(&htl);
374 silc_hash_table_free(channels);
378 /* Do not send the channel key if private channel key mode is set */
379 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY || !channel->send_key)
382 silc_server_send_channel_key(server, NULL, channel,
383 server->server_type == SILC_ROUTER ?
384 FALSE : !server->standalone);
386 silc_hash_table_list_reset(&htl);
387 silc_hash_table_free(channels);
392 static SilcServerEntry
393 silc_server_update_clients_by_real_server(SilcServer server,
394 SilcServerEntry from,
396 SilcClientEntry client,
398 SilcIDCacheEntry client_cache)
400 SilcServerEntry server_entry;
401 SilcIDCacheEntry id_cache = NULL;
403 SilcBool tolocal = (to == server->id_entry);
405 SILC_LOG_DEBUG(("Start"));
407 if (!silc_idcache_get_all(server->local_list->servers, &list))
410 silc_list_start(list);
411 while ((id_cache = silc_list_get(list))) {
412 server_entry = (SilcServerEntry)id_cache->context;
413 if (server_entry != from &&
414 (tolocal || server_entry != server->id_entry) &&
415 SILC_ID_COMPARE(server_entry->id, client->id,
416 client->id->ip.data_len)) {
417 SILC_LOG_DEBUG(("Found (local) %s",
418 silc_id_render(server_entry->id, SILC_ID_SERVER)));
420 if (!SILC_IS_LOCAL(server_entry) && server_entry->router) {
421 SILC_LOG_DEBUG(("Server not locally connected, use its router"));
422 /* If the client is not marked as local then move it to local list
423 since the server is local. */
425 SILC_LOG_DEBUG(("Moving client to local list"));
426 silc_idcache_move(server->global_list->clients,
427 server->local_list->clients, client_cache);
429 server_entry = server_entry->router;
431 SILC_LOG_DEBUG(("Server locally connected"));
432 /* If the client is not marked as local then move it to local list
433 since the server is local. */
434 if (server_entry->server_type != SILC_BACKUP_ROUTER && !local) {
435 SILC_LOG_DEBUG(("Moving client to local list"));
436 silc_idcache_move(server->global_list->clients,
437 server->local_list->clients, client_cache);
439 } else if (server->server_type == SILC_BACKUP_ROUTER && local) {
440 /* If we are backup router and this client is on local list, we
441 must move it to global list, as it is not currently local to
442 us (we are not primary). */
443 SILC_LOG_DEBUG(("Moving client to global list"));
444 silc_idcache_move(server->local_list->clients,
445 server->global_list->clients, client_cache);
453 if (!silc_idcache_get_all(server->global_list->servers, &list))
456 silc_list_start(list);
457 while ((id_cache = silc_list_get(list))) {
458 server_entry = (SilcServerEntry)id_cache->context;
459 if (server_entry != from && server_entry != server->id_entry &&
460 (tolocal || server_entry != server->id_entry) &&
461 SILC_ID_COMPARE(server_entry->id, client->id,
462 client->id->ip.data_len)) {
463 SILC_LOG_DEBUG(("Found (global) %s",
464 silc_id_render(server_entry->id, SILC_ID_SERVER)));
466 if (!SILC_IS_LOCAL(server_entry) && server_entry->router) {
467 SILC_LOG_DEBUG(("Server not locally connected, use its router"));
468 /* If the client is marked as local then move it to global list
469 since the server is global. */
471 SILC_LOG_DEBUG(("Moving client to global list"));
472 silc_idcache_move(server->local_list->clients,
473 server->global_list->clients, client_cache);
475 server_entry = server_entry->router;
477 SILC_LOG_DEBUG(("Server locally connected"));
478 /* If the client is marked as local then move it to global list
479 since the server is global. */
480 if (server_entry->server_type != SILC_BACKUP_ROUTER && local) {
481 SILC_LOG_DEBUG(("Moving client to global list"));
482 silc_idcache_move(server->local_list->clients,
483 server->global_list->clients, client_cache);
493 /* Updates the clients that are originated from the `from' to be originated
494 from the `to'. If the `resolve_real_server' is TRUE then this will
495 attempt to figure out which clients really are originated from the
496 `from' and which are originated from a server that we have connection
497 to, when we've acting as backup router. If it is FALSE the `to' will
498 be the new source. */
500 void silc_server_update_clients_by_server(SilcServer server,
501 SilcServerEntry from,
503 SilcBool resolve_real_server)
506 SilcIDCacheEntry id_cache = NULL;
507 SilcClientEntry client = NULL;
510 if (from && from->id) {
511 SILC_LOG_DEBUG(("Changing from server %s",
512 silc_id_render(from->id, SILC_ID_SERVER)));
515 SILC_LOG_DEBUG(("Changing to server %s",
516 silc_id_render(to->id, SILC_ID_SERVER)));
519 SILC_LOG_DEBUG(("global list"));
521 if (silc_idcache_get_all(server->global_list->clients, &list)) {
522 silc_list_start(list);
523 while ((id_cache = silc_list_get(list))) {
524 client = (SilcClientEntry)id_cache->context;
526 /* If entry is disabled skip it. If entry is local to us, do not
527 switch it to anyone else, it is ours so skip it. */
528 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) ||
529 SILC_IS_LOCAL(client))
532 SILC_LOG_DEBUG(("Client %s",
533 silc_id_render(client->id, SILC_ID_CLIENT)));
534 if (client->router && client->router->id)
535 SILC_LOG_DEBUG(("Client->router %s",
536 silc_id_render(client->router->id, SILC_ID_SERVER)));
539 if (client->router == from) {
540 if (resolve_real_server) {
542 silc_server_update_clients_by_real_server(server, from, to,
545 if (!client->router) {
546 if (server->server_type == SILC_ROUTER)
547 client->router = from;
556 /* All are changed */
557 if (resolve_real_server)
558 /* Call this so that the entry is moved to correct list if
559 needed. No resolving by real server is actually done. */
560 silc_server_update_clients_by_real_server(server, NULL, to,
567 if (client->router && client->router->id)
568 SILC_LOG_DEBUG(("Client changed to %s",
569 silc_id_render(client->router->id, SILC_ID_SERVER)));
573 SILC_LOG_DEBUG(("local list"));
575 if (silc_idcache_get_all(server->local_list->clients, &list)) {
576 silc_list_start(list);
577 while ((id_cache = silc_list_get(list))) {
578 client = (SilcClientEntry)id_cache->context;
580 /* If entry is disabled skip it. If entry is local to us, do not
581 switch it to anyone else, it is ours so skip it. */
582 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) ||
583 SILC_IS_LOCAL(client))
586 SILC_LOG_DEBUG(("Client %s",
587 silc_id_render(client->id, SILC_ID_CLIENT)));
588 if (client->router && client->router->id)
589 SILC_LOG_DEBUG(("Client->router %s",
590 silc_id_render(client->router->id, SILC_ID_SERVER)));
593 if (client->router == from) {
594 if (resolve_real_server) {
596 silc_server_update_clients_by_real_server(server, from, to,
600 client->router = from;
606 /* All are changed */
607 if (resolve_real_server)
608 /* Call this so that the entry is moved to correct list if
609 needed. No resolving by real server is actually done. */
610 silc_server_update_clients_by_real_server(server, NULL, to,
617 if (client->router && client->router->id)
618 SILC_LOG_DEBUG(("Client changed to %s",
619 silc_id_render(client->router->id, SILC_ID_SERVER)));
624 /* Updates servers that are from `from' to be originated from `to'. This
625 will also update the server's connection to `to's connection. */
627 void silc_server_update_servers_by_server(SilcServer server,
628 SilcServerEntry from,
632 SilcIDCacheEntry id_cache = NULL;
633 SilcServerEntry server_entry = NULL;
635 SILC_LOG_DEBUG(("Updating servers"));
637 if (silc_idcache_get_all(server->local_list->servers, &list)) {
638 silc_list_start(list);
639 while ((id_cache = silc_list_get(list))) {
640 server_entry = (SilcServerEntry)id_cache->context;
642 /* If entry is local to us, do not switch it to any anyone else,
644 if (SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry ||
645 server_entry == from)
648 /* If we are standalone router, any server that is not directly
649 connected to cannot exist anymore. If we are not standalone
650 we update it correctly. */
651 if (server->server_type == SILC_ROUTER && server->standalone) {
652 silc_server_backup_del(server, server_entry);
653 silc_server_backup_replaced_del(server, server_entry);
654 silc_idlist_del_data(server_entry);
655 silc_idlist_del_server(server->local_list, server_entry);
656 server->stat.servers--;
657 server->stat.cell_servers--;
659 /* XXX if we are not standalone, do a check from local config
660 whether this server is in our cell, but not connected to
661 us (in which case we must remove it). */
664 if (server_entry->router == from) {
665 SILC_LOG_DEBUG(("Updating server (local) %s",
666 server_entry->server_name ?
667 server_entry->server_name : ""));
668 server_entry->router = to;
669 server_entry->connection = to->connection;
673 SILC_LOG_DEBUG(("Updating server (local) %s",
674 server_entry->server_name ?
675 server_entry->server_name : ""));
676 server_entry->router = to;
677 server_entry->connection = to->connection;
683 if (silc_idcache_get_all(server->global_list->servers, &list)) {
684 silc_list_start(list);
685 while ((id_cache = silc_list_get(list))) {
686 server_entry = (SilcServerEntry)id_cache->context;
688 /* If entry is local to us, do not switch it to anyone else,
690 if (SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry ||
691 server_entry == from)
694 /* If we are standalone router, any server that is not directly
695 connected to cannot exist anymore. If we are not standalone
696 we update it correctly. */
697 if (server->server_type == SILC_ROUTER && server->standalone) {
698 silc_server_backup_del(server, server_entry);
699 silc_server_backup_replaced_del(server, server_entry);
700 silc_idlist_del_data(server_entry);
701 silc_idlist_del_server(server->global_list, server_entry);
702 server->stat.servers--;
703 server->stat.cell_servers--;
705 /* XXX if we are not standalone, do a check from local config
706 whether this server is in our cell, but not connected to
707 us (in which case we must remove it). */
710 if (server_entry->router == from) {
711 SILC_LOG_DEBUG(("Updating server (global) %s",
712 server_entry->server_name ?
713 server_entry->server_name : ""));
714 server_entry->router = to;
715 server_entry->connection = to->connection;
719 SILC_LOG_DEBUG(("Updating server (global) %s",
720 server_entry->server_name ?
721 server_entry->server_name : ""));
722 server_entry->router = to;
723 server_entry->connection = to->connection;
731 /* Toggles the enabled/disabled status of local server connections. Packets
732 can be sent to the servers when `toggle_enabled' is TRUE and will be
733 dropped if `toggle_enabled' is FALSE, after this function is called. */
735 void silc_server_local_servers_toggle_enabled(SilcServer server,
736 SilcBool toggle_enabled)
739 SilcIDCacheEntry id_cache = NULL;
740 SilcServerEntry server_entry = NULL;
742 if (silc_idcache_get_all(server->local_list->servers, &list)) {
743 silc_list_start(list);
744 while ((id_cache = silc_list_get(list))) {
745 server_entry = (SilcServerEntry)id_cache->context;
746 if (!SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry)
750 server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
752 server_entry->data.status |= SILC_IDLIST_STATUS_DISABLED;
757 if (silc_idcache_get_all(server->global_list->servers, &list)) {
758 silc_list_start(list);
759 while ((id_cache = silc_list_get(list))) {
760 server_entry = (SilcServerEntry)id_cache->context;
761 if (!SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry)
765 server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
767 server_entry->data.status |= SILC_IDLIST_STATUS_DISABLED;
773 /* Removes servers that are originated from the `from'. The server
774 entry is deleted in this function. If `remove_clients' is TRUE then
775 all clients originated from the server are removed too, and server
776 signoff is sent. Note that this does not remove the `from'. This
777 also does not remove locally connected servers. */
779 void silc_server_remove_servers_by_server(SilcServer server,
780 SilcServerEntry from,
781 SilcBool remove_clients)
784 SilcIDCacheEntry id_cache = NULL;
785 SilcServerEntry server_entry = NULL;
787 SILC_LOG_DEBUG(("Removing servers by %s",
788 from->server_name ? from->server_name : "server"));
790 if (silc_idcache_get_all(server->local_list->servers, &list)) {
791 silc_list_start(list);
792 while ((id_cache = silc_list_get(list))) {
793 server_entry = (SilcServerEntry)id_cache->context;
794 if (SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry ||
795 server_entry->router != from || server_entry == from)
798 /* Remove clients owned by this server */
800 silc_server_remove_clients_by_server(server, from, server_entry,
803 /* Remove the server */
804 silc_server_backup_del(server, server_entry);
805 silc_idlist_del_server(server->local_list, server_entry);
809 if (silc_idcache_get_all(server->global_list->servers, &list)) {
810 silc_list_start(list);
811 while ((id_cache = silc_list_get(list))) {
812 server_entry = (SilcServerEntry)id_cache->context;
813 if (SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry ||
814 server_entry->router != from || server_entry == from)
817 /* Remove clients owned by this server */
819 silc_server_remove_clients_by_server(server, from, server_entry,
822 /* Remove the server */
823 silc_server_backup_del(server, server_entry);
824 silc_idlist_del_server(server->global_list, server_entry);
829 /* Removes channels that are from `from. */
831 void silc_server_remove_channels_by_server(SilcServer server,
832 SilcServerEntry from)
835 SilcIDCacheEntry id_cache = NULL;
836 SilcChannelEntry channel = NULL;
838 SILC_LOG_DEBUG(("Removing channels by server"));
840 if (silc_idcache_get_all(server->global_list->channels, &list)) {
841 silc_list_start(list);
842 while ((id_cache = silc_list_get(list))) {
843 channel = (SilcChannelEntry)id_cache->context;
844 if (channel->router == from)
845 silc_idlist_del_channel(server->global_list, channel);
850 /* Updates channels that are from `from' to be originated from `to'. */
852 void silc_server_update_channels_by_server(SilcServer server,
853 SilcServerEntry from,
857 SilcIDCacheEntry id_cache = NULL;
858 SilcChannelEntry channel = NULL;
860 SILC_LOG_DEBUG(("Updating channels by server"));
862 if (silc_idcache_get_all(server->global_list->channels, &list)) {
863 silc_list_start(list);
864 while ((id_cache = silc_list_get(list))) {
865 channel = (SilcChannelEntry)id_cache->context;
867 if (channel->router == from)
868 channel->router = to;
871 channel->router = to;
877 /* Checks whether given channel has global users. If it does this returns
878 TRUE and FALSE if there is only locally connected clients on the channel. */
880 SilcBool silc_server_channel_has_global(SilcChannelEntry channel)
882 SilcChannelClientEntry chl;
883 SilcHashTableList htl;
885 silc_hash_table_list(channel->user_list, &htl);
886 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
887 if (chl->client->router) {
888 silc_hash_table_list_reset(&htl);
892 silc_hash_table_list_reset(&htl);
897 /* Checks whether given channel has locally connected users. If it does this
898 returns TRUE and FALSE if there is not one locally connected client. */
900 SilcBool silc_server_channel_has_local(SilcChannelEntry channel)
902 SilcChannelClientEntry chl;
903 SilcHashTableList htl;
905 silc_hash_table_list(channel->user_list, &htl);
906 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
907 if (SILC_IS_LOCAL(chl->client)) {
908 silc_hash_table_list_reset(&htl);
912 silc_hash_table_list_reset(&htl);
917 /* This function removes the channel and all users on the channel, unless
918 the channel is permanent. In this case the channel is disabled but all
919 users are removed from the channel. Returns TRUE if the channel is
920 destroyed totally, and FALSE if it is permanent and remains. */
922 SilcBool silc_server_channel_delete(SilcServer server,
923 SilcChannelEntry channel)
925 SilcChannelClientEntry chl;
926 SilcHashTableList htl;
927 SilcBool delchan = !(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH);
929 SILC_LOG_DEBUG(("Deleting channel %s", channel->channel_name));
932 /* Update statistics */
933 if (server->server_type == SILC_ROUTER)
934 server->stat.chanclients -= channel->user_count;
936 /* Totally delete the channel and all users on the channel. The
937 users are deleted automatically in silc_idlist_del_channel. */
938 channel->disabled = TRUE;
939 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
940 if (silc_idlist_del_channel(server->local_list, channel)) {
941 server->stat.my_channels--;
942 if (server->server_type == SILC_ROUTER) {
943 server->stat.channels--;
944 server->stat.cell_channels--;
947 if (silc_idlist_del_channel(server->global_list, channel))
948 if (server->server_type == SILC_ROUTER)
949 server->stat.channels--;
955 /* Channel is permanent, do not remove it, remove only users */
956 channel->disabled = TRUE;
957 silc_hash_table_list(channel->user_list, &htl);
958 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
959 silc_hash_table_del(chl->client->channels, channel);
960 silc_hash_table_del(channel->user_list, chl->client);
961 channel->user_count--;
963 /* Update statistics */
964 if (SILC_IS_LOCAL(chl->client))
965 server->stat.my_chanclients--;
966 if (server->server_type == SILC_ROUTER) {
967 server->stat.cell_chanclients--;
968 server->stat.chanclients--;
973 silc_hash_table_list_reset(&htl);
975 SILC_LOG_DEBUG(("Channel %s remains (permanent)", channel->channel_name));
980 /* Returns TRUE if the given client is on the channel. FALSE if not.
981 This works because we assure that the user list on the channel is
982 always in up to date thus we can only check the channel list from
983 `client' which is faster than checking the user list from `channel'. */
985 SilcBool silc_server_client_on_channel(SilcClientEntry client,
986 SilcChannelEntry channel,
987 SilcChannelClientEntry *chl)
989 if (!client || !channel)
992 return silc_hash_table_find(client->channels, channel, NULL,
996 /* Find number of sockets by IP address indicated by `ip'. Returns 0 if
997 socket connections with the IP address does not exist. Counts only
998 fully established connections. */
1000 SilcUInt32 silc_server_num_sockets_by_ip(SilcServer server, const char *ip,
1001 SilcConnectionType type)
1003 SilcServerConnection conn;
1004 SilcIDListData idata;
1008 silc_dlist_start(server->conns);
1009 while ((conn = silc_dlist_get(server->conns))) {
1010 if (!conn->sock || !silc_packet_stream_is_valid(conn->sock))
1012 silc_socket_stream_get_info(silc_packet_stream_get_stream(conn->sock),
1013 NULL, NULL, &ipaddr, NULL);
1014 idata = silc_packet_get_context(conn->sock);
1015 if (!strcmp(ipaddr, ip) && idata && idata->conn_type == type)
1022 /* Find active socket connection by the IP address and port indicated by
1023 `ip' and `port', and socket connection type of `type'. */
1026 silc_server_find_socket_by_host(SilcServer server,
1027 SilcConnectionType type,
1028 const char *ip, SilcUInt16 port)
1030 SilcServerConnection conn;
1031 SilcIDListData idata;
1034 silc_dlist_start(server->conns);
1035 while ((conn = silc_dlist_get(server->conns))) {
1036 if (!conn->sock || !silc_packet_stream_is_valid(conn->sock))
1038 idata = silc_packet_get_context(conn->sock);
1039 silc_socket_stream_get_info(silc_packet_stream_get_stream(conn->sock),
1040 NULL, NULL, &ipaddr, NULL);
1041 if (!strcmp(ipaddr, ip) &&
1042 (!port || conn->remote_port == port) &&
1043 idata->conn_type == type)
1050 /* Find number of sockets by IP address indicated by remote host, indicatd
1051 by `ip' or `hostname', `port', and `type'. Returns 0 if socket connections
1052 does not exist. If `ip' is provided then `hostname' is ignored. */
1054 SilcUInt32 silc_server_num_sockets_by_remote(SilcServer server,
1056 const char *hostname,
1058 SilcConnectionType type)
1060 SilcServerConnection conn;
1061 SilcIDListData idata;
1062 SilcConnectionType t = SILC_CONN_UNKNOWN;
1065 if (!ip && !hostname)
1068 SILC_LOG_DEBUG(("Num connections %d", silc_dlist_count(server->conns)));
1070 silc_dlist_start(server->conns);
1071 while ((conn = silc_dlist_get(server->conns))) {
1073 idata = silc_packet_get_context(conn->sock);
1075 t = idata->conn_type;
1077 if (((ip && !strcmp(conn->remote_host, ip)) ||
1078 (hostname && !strcmp(conn->remote_host, hostname))) &&
1079 conn->remote_port == port && t == type)
1086 /* SKR find callbcak */
1088 static void find_callback(SilcSKR skr, SilcSKRFind find,
1089 SilcSKRStatus status, SilcDList keys,
1092 SilcPublicKey *public_key = context;
1096 SILC_LOG_DEBUG(("Found %d keys", silc_dlist_count(keys)));
1097 silc_dlist_start(keys);
1098 key = silc_dlist_get(keys);
1099 *public_key = key->key;
1100 silc_dlist_uninit(keys);
1103 silc_skr_find_free(find);
1106 /* Get public key by key usage and key context. */
1108 SilcPublicKey silc_server_get_public_key(SilcServer server,
1109 SilcSKRKeyUsage usage,
1113 SilcPublicKey public_key = NULL;
1115 SILC_LOG_DEBUG(("Start"));
1117 find = silc_skr_find_alloc();
1121 silc_skr_find_set_usage(find, usage);
1122 silc_skr_find_set_context(find, key_context);
1123 silc_skr_find(server->repository, server->schedule,
1124 find, find_callback, &public_key);
1128 SILC_LOG_DEBUG(("Found public key"));
1130 SILC_LOG_DEBUG(("Public key not found"));
1131 #endif /* SILC_DEBUG */
1136 /* Find public key by client for identification purposes. Finds keys
1137 with SILC_SKR_USAGE_IDENTIFICATION. */
1139 SilcBool silc_server_get_public_key_by_client(SilcServer server,
1140 SilcClientEntry client,
1141 SilcPublicKey *public_key)
1143 SilcPublicKey pubkey = NULL;
1144 SilcBool ret = FALSE;
1146 pubkey = silc_server_get_public_key(server, SILC_SKR_USAGE_IDENTIFICATION,
1152 *public_key = pubkey;
1157 /* Check whether the connection `sock' is allowed to connect to us. This
1158 checks for example whether there is too much connections for this host,
1159 and required version for the host etc. */
1161 SilcBool silc_server_connection_allowed(SilcServer server,
1162 SilcPacketStream sock,
1163 SilcConnectionType type,
1164 SilcServerConfigConnParams *global,
1165 SilcServerConfigConnParams *params,
1168 SilcUInt32 conn_number = (type == SILC_CONN_CLIENT ?
1169 server->stat.my_clients :
1170 type == SILC_CONN_SERVER ?
1171 server->stat.my_servers :
1172 server->stat.my_routers);
1173 SilcUInt32 num_sockets, max_hosts, max_per_host;
1174 SilcUInt32 r_protocol_version, l_protocol_version;
1175 SilcUInt32 r_software_version, l_software_version;
1176 char *r_vendor_version = NULL, *l_vendor_version;
1177 const char *hostname, *ip;
1179 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
1180 NULL, &hostname, &ip, NULL);
1182 SILC_LOG_DEBUG(("Checking whether connection is allowed"));
1186 l_protocol_version =
1187 silc_version_to_num(params && params->version_protocol ?
1188 params->version_protocol :
1189 global->version_protocol);
1190 l_software_version =
1191 silc_version_to_num(params && params->version_software ?
1192 params->version_software :
1193 global->version_software);
1194 l_vendor_version = (params && params->version_software_vendor ?
1195 params->version_software_vendor :
1196 global->version_software_vendor);
1198 if (ske && silc_ske_parse_version(ske, &r_protocol_version, NULL,
1199 &r_software_version, NULL,
1200 &r_vendor_version)) {
1201 /* Match protocol version */
1202 if (l_protocol_version && r_protocol_version &&
1203 r_protocol_version < l_protocol_version) {
1204 SILC_LOG_INFO(("Connection %s (%s) is too old version",
1206 silc_server_disconnect_remote(server, sock,
1207 SILC_STATUS_ERR_BAD_VERSION,
1208 "You support too old protocol version");
1209 silc_server_free_sock_user_data(server, sock, NULL);
1213 /* Math software version */
1214 if (l_software_version && r_software_version &&
1215 r_software_version < l_software_version) {
1216 SILC_LOG_INFO(("Connection %s (%s) is too old version",
1218 silc_server_disconnect_remote(server, sock,
1219 SILC_STATUS_ERR_BAD_VERSION,
1220 "You support too old software version");
1221 silc_server_free_sock_user_data(server, sock, NULL);
1225 /* Regex match vendor version */
1226 if (l_vendor_version && r_vendor_version &&
1227 !silc_string_match(l_vendor_version, r_vendor_version)) {
1228 SILC_LOG_INFO(("Connection %s (%s) is unsupported version",
1230 silc_server_disconnect_remote(server, sock,
1231 SILC_STATUS_ERR_BAD_VERSION,
1232 "Your software is not supported");
1233 silc_server_free_sock_user_data(server, sock, NULL);
1237 silc_free(r_vendor_version);
1239 /* Check for maximum connections limit */
1241 num_sockets = silc_server_num_sockets_by_ip(server, ip, type);
1242 max_hosts = (params ? params->connections_max : global->connections_max);
1243 max_per_host = (params ? params->connections_max_per_host :
1244 global->connections_max_per_host);
1246 if (max_hosts && conn_number >= max_hosts) {
1247 SILC_LOG_DEBUG(("Server is full, %d >= %d", conn_number, max_hosts));
1248 SILC_LOG_INFO(("Server is full, closing %s (%s) connection",
1250 silc_server_disconnect_remote(server, sock,
1251 SILC_STATUS_ERR_RESOURCE_LIMIT,
1252 "Server is full, try again later");
1253 silc_server_free_sock_user_data(server, sock, NULL);
1257 if (num_sockets >= max_per_host) {
1258 SILC_LOG_DEBUG(("Too many connections, %d >= %d", num_sockets,
1260 SILC_LOG_INFO(("Too many connections from %s (%s), closing connection",
1262 silc_server_disconnect_remote(server, sock,
1263 SILC_STATUS_ERR_RESOURCE_LIMIT,
1264 "Too many connections from your host");
1265 silc_server_free_sock_user_data(server, sock, NULL);
1272 /* Checks that client has rights to add or remove channel modes. If any
1273 of the checks fails FALSE is returned. */
1275 SilcBool silc_server_check_cmode_rights(SilcServer server,
1276 SilcChannelEntry channel,
1277 SilcChannelClientEntry client,
1280 SilcBool is_op = client->mode & SILC_CHANNEL_UMODE_CHANOP;
1281 SilcBool is_fo = client->mode & SILC_CHANNEL_UMODE_CHANFO;
1283 /* Check whether has rights to change anything */
1284 if (!is_op && !is_fo)
1287 /* Check whether has rights to change everything */
1291 /* Founder implies operator */
1295 /* We know that client is channel operator, check that they are not
1296 changing anything that requires channel founder rights. Rest of the
1297 modes are available automatically for channel operator. */
1299 if (mode & SILC_CHANNEL_MODE_PRIVKEY) {
1300 if (is_op && !is_fo)
1303 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
1304 if (is_op && !is_fo)
1309 if (mode & SILC_CHANNEL_MODE_PASSPHRASE) {
1310 if (!(channel->mode & SILC_CHANNEL_MODE_PASSPHRASE)) {
1311 if (is_op && !is_fo)
1315 if (channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
1316 if (is_op && !is_fo)
1321 if (mode & SILC_CHANNEL_MODE_CIPHER) {
1322 if (!(channel->mode & SILC_CHANNEL_MODE_CIPHER)) {
1323 if (is_op && !is_fo)
1327 if (channel->mode & SILC_CHANNEL_MODE_CIPHER) {
1328 if (is_op && !is_fo)
1333 if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
1334 if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
1335 if (is_op && !is_fo)
1339 if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
1340 if (is_op && !is_fo)
1345 if (mode & SILC_CHANNEL_MODE_SILENCE_USERS) {
1346 if (!(channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS)) {
1347 if (is_op && !is_fo)
1351 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS) {
1352 if (is_op && !is_fo)
1357 if (mode & SILC_CHANNEL_MODE_SILENCE_OPERS) {
1358 if (!(channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS)) {
1359 if (is_op && !is_fo)
1363 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS) {
1364 if (is_op && !is_fo)
1369 if (mode & SILC_CHANNEL_MODE_CHANNEL_AUTH) {
1370 if (!(channel->mode & SILC_CHANNEL_MODE_CHANNEL_AUTH)) {
1371 if (is_op && !is_fo)
1375 if (channel->mode & SILC_CHANNEL_MODE_CHANNEL_AUTH) {
1376 if (is_op && !is_fo)
1384 /* Check that the client has rights to change its user mode. Returns
1385 FALSE if setting some mode is not allowed. */
1387 SilcBool silc_server_check_umode_rights(SilcServer server,
1388 SilcClientEntry client,
1391 SilcBool server_op = FALSE, router_op = FALSE;
1393 if (mode & SILC_UMODE_SERVER_OPERATOR) {
1394 /* Cannot set server operator mode (must use OPER command) */
1395 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR))
1398 /* Remove the server operator rights */
1399 if (client->mode & SILC_UMODE_SERVER_OPERATOR)
1403 if (mode & SILC_UMODE_ROUTER_OPERATOR) {
1404 /* Cannot set router operator mode (must use SILCOPER command) */
1405 if (!(client->mode & SILC_UMODE_ROUTER_OPERATOR))
1408 /* Remove the router operator rights */
1409 if (client->mode & SILC_UMODE_ROUTER_OPERATOR)
1414 SILC_UMODE_STATS_UPDATE(server, SILC_UMODE_SERVER_OPERATOR);
1416 SILC_UMODE_STATS_UPDATE(router, SILC_UMODE_ROUTER_OPERATOR);
1421 /* This function is used to send the notify packets and motd to the
1422 incoming client connection. */
1424 void silc_server_send_connect_notifys(SilcServer server,
1425 SilcPacketStream sock,
1426 SilcClientEntry client)
1430 SILC_LOG_DEBUG(("Send welcome notifys"));
1432 /* Send some nice info to the client */
1433 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1434 ("Welcome to the SILC Network %s",
1436 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1437 ("Your host is %s, running version %s",
1438 server->server_name, server_version));
1440 if (server->server_type == SILC_ROUTER) {
1441 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1442 ("There are %d clients, %d servers and %d "
1443 "routers in SILC Network",
1444 server->stat.clients, server->stat.servers,
1445 server->stat.routers));
1447 if (server->stat.clients && server->stat.servers + 1)
1448 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1449 ("There are %d clients, %d servers and %d "
1450 "routers in SILC Network",
1451 server->stat.clients, server->stat.servers,
1452 (server->standalone ? 0 :
1453 !server->stat.routers ? 1 :
1454 server->stat.routers)));
1457 if (server->stat.cell_clients && server->stat.cell_servers + 1)
1458 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1459 ("There are %d clients on %d servers in our cell",
1460 server->stat.cell_clients,
1461 server->stat.cell_servers));
1462 if (server->server_type == SILC_ROUTER) {
1463 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1464 ("I have %d clients, %d channels, %d servers and "
1466 server->stat.my_clients,
1467 server->stat.my_channels,
1468 server->stat.my_servers,
1469 server->stat.my_routers));
1471 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1472 ("I have %d clients and %d channels formed",
1473 server->stat.my_clients,
1474 server->stat.my_channels));
1477 if (server->stat.server_ops || server->stat.router_ops)
1478 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1479 ("There are %d server operators and %d router "
1481 server->stat.server_ops,
1482 server->stat.router_ops));
1483 if (server->stat.my_router_ops + server->stat.my_server_ops)
1484 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1485 ("I have %d operators online",
1486 server->stat.my_router_ops +
1487 server->stat.my_server_ops));
1489 silc_packet_get_keys(sock, &key, NULL, NULL, NULL);
1490 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1491 ("Your connection is secured with %s cipher, "
1492 "key length %d bits",
1493 silc_cipher_get_name(key),
1494 silc_cipher_get_key_len(key)));
1495 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1496 ("Your current nickname is %s",
1500 silc_server_send_motd(server, sock);
1503 /* Kill the client indicated by `remote_client' sending KILLED notify
1504 to the client, to all channels client has joined and to primary
1505 router if needed. The killed client is also removed from all channels. */
1507 void silc_server_kill_client(SilcServer server,
1508 SilcClientEntry remote_client,
1509 const char *comment,
1511 SilcIdType killer_id_type)
1513 SilcBuffer killed, killer;
1515 SILC_LOG_DEBUG(("Killing client %s",
1516 silc_id_render(remote_client->id, SILC_ID_CLIENT)));
1518 /* Send the KILL notify packets. First send it to the channel, then
1519 to our primary router and then directly to the client who is being
1520 killed right now. */
1522 killed = silc_id_payload_encode(remote_client->id, SILC_ID_CLIENT);
1523 killer = silc_id_payload_encode(killer_id, killer_id_type);
1525 /* Send KILLED notify to the channels. It is not sent to the client
1526 as it will be sent differently destined directly to the client and not
1528 silc_server_send_notify_on_channels(server, remote_client,
1529 remote_client, SILC_NOTIFY_TYPE_KILLED,
1530 3, killed->data, silc_buffer_len(killed),
1531 comment, comment ? strlen(comment) : 0,
1532 killer->data, silc_buffer_len(killer));
1534 /* Send KILLED notify to primary route */
1535 silc_server_send_notify_killed(server, SILC_PRIMARY_ROUTE(server),
1536 SILC_BROADCAST(server), remote_client->id,
1537 comment, killer_id, killer_id_type);
1539 /* Send KILLED notify to the client directly */
1540 if (remote_client->connection || remote_client->router)
1541 silc_server_send_notify_killed(server, remote_client->connection ?
1542 remote_client->connection :
1543 remote_client->router->connection, FALSE,
1544 remote_client->id, comment,
1545 killer_id, killer_id_type);
1547 /* Remove the client from all channels. This generates new keys to the
1548 channels as well. */
1549 silc_server_remove_from_channels(server, NULL, remote_client, FALSE,
1552 /* Remove the client entry, If it is locally connected then we will also
1553 disconnect the client here */
1554 if (remote_client->connection) {
1555 /* Remove locally conneted client */
1556 SilcPacketStream sock = remote_client->connection;
1559 silc_packet_stream_ref(sock);
1561 silc_server_free_sock_user_data(server, sock, NULL);
1564 silc_packet_set_context(sock, NULL);
1565 silc_server_close_connection(server, sock);
1566 silc_packet_stream_unref(sock);
1569 /* Update statistics */
1570 SILC_LOG_DEBUG(("stat.clients %d->%d", server->stat.clients,
1571 server->stat.clients - 1));
1572 SILC_VERIFY(server->stat.clients > 0);
1573 server->stat.clients--;
1574 if (server->stat.cell_clients)
1575 server->stat.cell_clients--;
1576 SILC_OPER_STATS_UPDATE(remote_client, server, SILC_UMODE_SERVER_OPERATOR);
1577 SILC_OPER_STATS_UPDATE(remote_client, router, SILC_UMODE_ROUTER_OPERATOR);
1579 /* Remove client's public key from repository, this will free it too. */
1580 if (remote_client->data.public_key) {
1581 silc_skr_del_public_key(server->repository,
1582 remote_client->data.public_key, remote_client);
1583 remote_client->data.public_key = NULL;
1586 if (SILC_IS_LOCAL(remote_client)) {
1587 if (!remote_client->local_detached)
1588 server->stat.my_clients--;
1589 silc_schedule_task_del_by_context(server->schedule, remote_client);
1592 /* Remove remote client */
1593 silc_dlist_del(server->expired_clients, remote_client);
1594 silc_idlist_del_data(remote_client);
1595 if (!silc_idlist_del_client(server->global_list, remote_client)) {
1596 /* Remove this client from watcher list if it is */
1597 silc_server_del_from_watcher_list(server, remote_client);
1598 silc_idlist_del_client(server->local_list, remote_client);
1602 silc_buffer_free(killer);
1603 silc_buffer_free(killed);
1608 SilcClientEntry client;
1609 SilcNotifyType notify;
1610 const char *new_nick;
1611 } WatcherNotifyContext;
1614 silc_server_check_watcher_list_foreach(void *key, void *context,
1617 WatcherNotifyContext *notify = user_context;
1618 SilcClientEntry entry = context;
1619 SilcPacketStream sock;
1624 if (entry == notify->client)
1627 sock = silc_server_get_client_route(notify->server, NULL, 0, entry->id,
1630 SILC_LOG_DEBUG(("Sending WATCH notify to %s",
1631 silc_id_render(entry->id, SILC_ID_CLIENT)));
1633 /* Send the WATCH notify */
1634 silc_server_send_notify_watch(notify->server, sock, entry,
1636 notify->new_nick ? notify->new_nick :
1637 (const char *)notify->client->nickname,
1639 notify->client->data.public_key);
1643 /* This function checks whether the `client' nickname and/or 'client'
1644 public key is being watched by someone, and notifies the watcher of the
1645 notify change of notify type indicated by `notify'. */
1647 SilcBool silc_server_check_watcher_list(SilcServer server,
1648 SilcClientEntry client,
1649 const char *new_nick,
1650 SilcNotifyType notify)
1652 unsigned char hash[16];
1653 WatcherNotifyContext n;
1655 SILC_LOG_DEBUG(("Checking watcher list %s",
1656 client->nickname ? client->nickname : (unsigned char *)""));
1658 /* If the watching is rejected by the client do nothing */
1659 if (client->mode & SILC_UMODE_REJECT_WATCHING)
1662 /* Make hash from the nick, or take it from Client ID */
1663 if (client->nickname) {
1664 unsigned char *nickc;
1665 nickc = silc_identifier_check(client->nickname, strlen(client->nickname),
1666 SILC_STRING_UTF8, 128, NULL);
1669 silc_hash_make(server->md5hash, nickc, strlen(nickc), hash);
1672 memset(hash, 0, sizeof(hash));
1673 memcpy(hash, client->id->hash, sizeof(client->id->hash));
1678 n.new_nick = new_nick;
1681 /* Send notify to all watchers watching this nickname */
1682 silc_hash_table_find_foreach(server->watcher_list, hash,
1683 silc_server_check_watcher_list_foreach, &n);
1685 /* Send notify to all watchers watching this public key */
1686 if (client->data.public_key)
1687 silc_hash_table_find_foreach(server->watcher_list_pk,
1688 client->data.public_key,
1689 silc_server_check_watcher_list_foreach,
1695 /* Remove the `client' from watcher list. After calling this the `client'
1696 is not watching any nicknames. */
1698 SilcBool silc_server_del_from_watcher_list(SilcServer server,
1699 SilcClientEntry client)
1701 SilcHashTableList htl;
1703 SilcClientEntry entry;
1704 SilcBool found = FALSE;
1706 silc_hash_table_list(server->watcher_list, &htl);
1707 while (silc_hash_table_get(&htl, &key, (void *)&entry)) {
1708 if (entry == client) {
1709 silc_hash_table_del_by_context(server->watcher_list, key, client);
1712 SILC_LOG_DEBUG(("Removing %s from WATCH list",
1713 silc_id_render(client->id, SILC_ID_CLIENT)));
1715 /* Now check whether there still exists entries with this key, if not
1716 then free the key to not leak memory. */
1717 if (!silc_hash_table_find(server->watcher_list, key, NULL, NULL))
1723 silc_hash_table_list_reset(&htl);
1725 silc_hash_table_list(server->watcher_list_pk, &htl);
1726 while (silc_hash_table_get(&htl, &key, (void *)&entry)) {
1727 if (entry == client) {
1728 silc_hash_table_del_by_context(server->watcher_list_pk, key, client);
1731 SILC_LOG_DEBUG(("Removing %s from WATCH list",
1732 silc_id_render(client->id, SILC_ID_CLIENT)));
1734 /* Now check whether there still exists entries with this key, if not
1735 then free the key to not leak memory. */
1736 if (!silc_hash_table_find(server->watcher_list_pk, key, NULL, NULL))
1737 silc_pkcs_public_key_free(key);
1742 silc_hash_table_list_reset(&htl);
1747 /* Force the client indicated by `chl' to change the channel user mode
1748 on channel indicated by `channel' to `forced_mode'. */
1750 SilcBool silc_server_force_cumode_change(SilcServer server,
1751 SilcPacketStream sock,
1752 SilcChannelEntry channel,
1753 SilcChannelClientEntry chl,
1754 SilcUInt32 forced_mode)
1756 SilcBuffer idp1, idp2;
1757 unsigned char cumode[4];
1759 SILC_LOG_DEBUG(("Enforcing sender to change mode"));
1762 silc_server_send_notify_cumode(server, sock, FALSE, channel, forced_mode,
1763 server->id, SILC_ID_SERVER,
1764 chl->client->id, NULL);
1766 idp1 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
1767 idp2 = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
1768 SILC_PUT32_MSB(forced_mode, cumode);
1769 silc_server_send_notify_to_channel(server, sock, channel, FALSE, TRUE,
1770 SILC_NOTIFY_TYPE_CUMODE_CHANGE,
1771 3, idp1->data, silc_buffer_len(idp1),
1772 cumode, sizeof(cumode),
1773 idp2->data, silc_buffer_len(idp2));
1774 silc_buffer_free(idp1);
1775 silc_buffer_free(idp2);
1780 /* This function can be used to match the invite and ban lists. */
1782 SilcBool silc_server_inviteban_match(SilcServer server, SilcHashTable list,
1783 SilcUInt8 type, void *check)
1785 unsigned char *tmp = NULL;
1787 SilcHashTableList htl;
1788 SilcBuffer entry, idp = NULL, pkp = NULL;
1789 SilcBool ret = FALSE;
1792 SILC_LOG_DEBUG(("Matching invite/ban"));
1794 if (type < 1 || type > 3 || !check)
1798 tmp = strdup((char *)check);
1803 pkp = silc_public_key_payload_encode(check);
1807 len = silc_buffer_len(pkp);
1810 idp = silc_id_payload_encode(check, SILC_ID_CLIENT);
1814 len = silc_buffer_len(idp);
1817 /* Compare the list */
1818 silc_hash_table_list(list, &htl);
1819 while (silc_hash_table_get(&htl, (void *)&t, (void *)&entry)) {
1820 if (type == SILC_PTR_TO_32(t)) {
1822 if (silc_string_match(entry->data, tmp)) {
1826 } else if (silc_buffer_len(entry) == len &&
1827 !memcmp(entry->data, tmp, len)) {
1833 silc_hash_table_list_reset(&htl);
1837 silc_buffer_free(idp);
1838 silc_buffer_free(pkp);
1842 /* Process invite or ban information */
1844 SilcBool silc_server_inviteban_process(SilcServer server,
1847 SilcArgumentPayload args)
1850 SilcUInt32 type, len;
1853 SilcHashTableList htl;
1855 SILC_LOG_DEBUG(("Processing invite/ban for %s action",
1856 action == 0x01 ? "DEL" : "ADD"));
1858 /* Add the information to invite list */
1859 if (action == 0x00 || action == 0x03) {
1860 /* Traverse all arguments and add to the hash table according to
1862 tmp = silc_argument_get_first_arg(args, &type, &len);
1865 /* Check validity of the string. Actually we should parse the
1866 whole string and verify all components individually. */
1867 if (!silc_utf8_valid(tmp, len) || !len) {
1868 tmp = silc_argument_get_next_arg(args, &type, &len);
1871 if (strchr(tmp, ',')) {
1872 tmp = silc_argument_get_next_arg(args, &type, &len);
1876 /* Check if the string is added already */
1877 silc_hash_table_list(list, &htl);
1878 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) {
1879 if (SILC_PTR_TO_32(ptype) == 1 &&
1880 silc_string_match(tmp2->data, tmp)) {
1885 silc_hash_table_list_reset(&htl);
1888 /* Add the string to hash table */
1889 tmp2 = silc_buffer_alloc_size(len + 1);
1890 if (tmp[len - 1] == ',')
1891 tmp[len - 1] = '\0';
1892 silc_buffer_put(tmp2, tmp, len);
1893 silc_hash_table_add(list, (void *)1, tmp2);
1896 } else if (type == 2) {
1897 /* Public key. Check first if the public key is already on the
1898 list and ignore it if it is, otherwise, add it to hash table. */
1901 /* Verify validity of the public key */
1902 if (!silc_public_key_payload_decode(tmp, len, &pk)) {
1903 tmp = silc_argument_get_next_arg(args, &type, &len);
1906 silc_pkcs_public_key_free(pk);
1908 /* Check if the public key is in the list already */
1909 silc_hash_table_list(list, &htl);
1910 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) {
1911 if (SILC_PTR_TO_32(ptype) == 2 && !memcmp(tmp2->data, tmp, len)) {
1916 silc_hash_table_list_reset(&htl);
1918 /* Add new public key to invite list */
1920 tmp2 = silc_buffer_alloc_size(len);
1921 silc_buffer_put(tmp2, tmp, len);
1922 silc_hash_table_add(list, (void *)2, tmp2);
1925 } else if (type == 3) {
1928 /* Check if the ID is in the list already */
1929 silc_hash_table_list(list, &htl);
1930 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) {
1931 if (SILC_PTR_TO_32(ptype) == 3 && !memcmp(tmp2->data, tmp, len)) {
1936 silc_hash_table_list_reset(&htl);
1938 /* Add new Client ID to invite list */
1940 tmp2 = silc_buffer_alloc_size(len);
1941 silc_buffer_put(tmp2, tmp, len);
1942 silc_hash_table_add(list, (void *)3, tmp2);
1946 tmp = silc_argument_get_next_arg(args, &type, &len);
1950 /* Delete information to invite list */
1951 if (action == 0x01 && list) {
1952 /* Now delete the arguments from invite list */
1953 tmp = silc_argument_get_first_arg(args, &type, &len);
1956 /* Check validity of the string. Actually we should parse the
1957 whole string and verify all components individually. */
1958 if (!silc_utf8_valid(tmp, len)) {
1959 tmp = silc_argument_get_next_arg(args, &type, &len);
1962 if (strchr(tmp, ',')) {
1963 tmp = silc_argument_get_next_arg(args, &type, &len);
1967 /* Delete from the list */
1968 silc_hash_table_list(list, &htl);
1969 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) {
1970 if (SILC_PTR_TO_32(ptype) == 1 &&
1971 silc_string_match(tmp2->data, tmp)) {
1972 silc_hash_table_del_by_context(list, (void *)1, tmp2);
1976 silc_hash_table_list_reset(&htl);
1978 } else if (type == 2) {
1982 /* Verify validity of the public key */
1983 if (!silc_public_key_payload_decode(tmp, len, &pk)) {
1984 tmp = silc_argument_get_next_arg(args, &type, &len);
1987 silc_pkcs_public_key_free(pk);
1989 /* Delete from the invite list */
1990 silc_hash_table_list(list, &htl);
1991 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) {
1992 if (SILC_PTR_TO_32(ptype) == 2 && !memcmp(tmp2->data, tmp, len)) {
1993 silc_hash_table_del_by_context(list, (void *)2, tmp2);
1997 silc_hash_table_list_reset(&htl);
1999 } else if (type == 3) {
2002 /* Delete from the invite list */
2003 silc_hash_table_list(list, &htl);
2004 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) {
2005 if (SILC_PTR_TO_32(ptype) == 3 && !memcmp(tmp2->data, tmp, len)) {
2006 silc_hash_table_del_by_context(list, (void *)3, tmp2);
2010 silc_hash_table_list_reset(&htl);
2013 tmp = silc_argument_get_next_arg(args, &type, &len);
2020 /* Destructor for invite and ban list entrys */
2022 void silc_server_inviteban_destruct(void *key, void *context,
2025 silc_buffer_free(context);
2028 /* Creates connections accoring to configuration. */
2030 void silc_server_create_connections(SilcServer server)
2032 silc_schedule_task_del_by_callback(server->schedule,
2033 silc_server_connect_to_router_retry);
2034 silc_schedule_task_del_by_callback(server->schedule,
2035 silc_server_connect_to_router);
2036 silc_schedule_task_add_timeout(server->schedule,
2037 silc_server_connect_to_router, server, 1, 0);
2041 silc_server_process_channel_pk_destruct(void *key, void *context,
2045 silc_pkcs_public_key_free(context);
2048 /* Processes a channel public key, either adds or removes it. */
2051 silc_server_process_channel_pk(SilcServer server,
2052 SilcChannelEntry channel,
2053 SilcUInt32 type, const unsigned char *pk,
2056 unsigned char pkhash[20];
2059 SILC_LOG_DEBUG(("Processing channel public key"));
2062 return SILC_STATUS_ERR_NOT_ENOUGH_PARAMS;
2064 /* Decode the public key */
2065 if (!silc_public_key_payload_decode((unsigned char *)pk, pk_len, &chpk))
2066 return SILC_STATUS_ERR_UNSUPPORTED_PUBLIC_KEY;
2068 /* Create channel public key list (hash table) if needed */
2069 if (!channel->channel_pubkeys) {
2070 channel->channel_pubkeys =
2071 silc_hash_table_alloc(0, silc_hash_data, (void *)20,
2072 silc_hash_data_compare, (void *)20,
2073 silc_server_process_channel_pk_destruct, channel,
2077 /* Create SHA-1 digest of the public key data */
2078 silc_hash_make(server->sha1hash, pk + 4, pk_len - 4, pkhash);
2081 /* Add new public key to channel public key list */
2082 SILC_LOG_DEBUG(("Add new channel public key to channel %s",
2083 channel->channel_name));
2085 /* Check for resource limit */
2086 if (silc_hash_table_count(channel->channel_pubkeys) > 64) {
2087 silc_pkcs_public_key_free(chpk);
2088 return SILC_STATUS_ERR_RESOURCE_LIMIT;
2091 /* Add if doesn't exist already */
2092 if (!silc_hash_table_find(channel->channel_pubkeys, pkhash,
2094 silc_hash_table_add(channel->channel_pubkeys, silc_memdup(pkhash, 20),
2096 } else if (type == 0x01) {
2097 /* Delete public key from channel public key list */
2098 SILC_LOG_DEBUG(("Delete a channel public key from channel %s",
2099 channel->channel_name));
2100 if (!silc_hash_table_del(channel->channel_pubkeys, pkhash))
2101 silc_pkcs_public_key_free(chpk);
2103 silc_pkcs_public_key_free(chpk);
2104 return SILC_STATUS_ERR_NOT_ENOUGH_PARAMS;
2107 return SILC_STATUS_OK;
2110 /* Returns the channel public keys as Argument List payload. */
2112 SilcBuffer silc_server_get_channel_pk_list(SilcServer server,
2113 SilcChannelEntry channel,
2117 SilcHashTableList htl;
2118 SilcBuffer list, pkp;
2121 SILC_LOG_DEBUG(("Encoding channel public keys list"));
2123 if (!channel->channel_pubkeys ||
2124 !silc_hash_table_count(channel->channel_pubkeys))
2127 /* Encode the list */
2128 list = silc_buffer_alloc_size(2);
2129 silc_buffer_format(list,
2130 SILC_STR_UI_SHORT(silc_hash_table_count(
2131 channel->channel_pubkeys)),
2134 silc_hash_table_list(channel->channel_pubkeys, &htl);
2135 while (silc_hash_table_get(&htl, NULL, (void *)&pk)) {
2136 pkp = silc_public_key_payload_encode(pk);
2139 list = silc_argument_payload_encode_one(list, pkp->data,
2140 silc_buffer_len(pkp),
2142 delete ? 0x01 : 0x00);
2143 silc_buffer_free(pkp);
2145 silc_hash_table_list_reset(&htl);
2150 /* Sets the channel public keys into channel from the list of public keys. */
2152 SilcStatus silc_server_set_channel_pk_list(SilcServer server,
2153 SilcPacketStream sender,
2154 SilcChannelEntry channel,
2155 const unsigned char *pklist,
2156 SilcUInt32 pklist_len)
2159 SilcArgumentPayload args;
2160 unsigned char *chpk;
2161 SilcUInt32 chpklen, type;
2162 SilcStatus ret = SILC_STATUS_OK;
2164 SILC_LOG_DEBUG(("Setting channel public keys list"));
2166 if (!pklist || pklist_len < 2)
2167 return SILC_STATUS_ERR_NOT_ENOUGH_PARAMS;
2169 /* Get the argument from the Argument List Payload */
2170 SILC_GET16_MSB(argc, pklist);
2171 args = silc_argument_payload_parse(pklist + 2, pklist_len - 2, argc);
2173 return SILC_STATUS_ERR_NOT_ENOUGH_PARAMS;
2175 /* Process the public keys one by one */
2176 chpk = silc_argument_get_first_arg(args, &type, &chpklen);
2178 /* If announcing keys and we have them set already, do not allow this */
2179 if (chpk && type == 0x03 && channel->channel_pubkeys &&
2180 server->server_type == SILC_ROUTER &&
2181 sender != SILC_PRIMARY_ROUTE(server)) {
2182 SILC_LOG_DEBUG(("Channel public key list set already, enforce our list"));
2183 silc_argument_payload_free(args);
2184 return SILC_STATUS_ERR_OPERATION_ALLOWED;
2187 /* If we are normal server and receive announcement list and we already
2188 have keys set, we replace the old list with the announced one. */
2189 if (chpk && type == 0x03 && channel->channel_pubkeys &&
2190 server->server_type != SILC_ROUTER) {
2192 unsigned char mask[4], ulimit[4];
2194 SILC_LOG_DEBUG(("Router enforces its list, remove old list"));
2195 silc_hash_table_free(channel->channel_pubkeys);
2196 channel->channel_pubkeys = NULL;
2198 /* Send notify that removes the old list */
2199 sidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
2200 SILC_PUT32_MSB((channel->mode & (~SILC_CHANNEL_MODE_CHANNEL_AUTH)), mask);
2201 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
2202 SILC_PUT32_MSB(channel->user_limit, ulimit);
2203 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
2204 SILC_NOTIFY_TYPE_CMODE_CHANGE, 8,
2205 sidp->data, silc_buffer_len(sidp),
2209 strlen(channel->cipher) : 0,
2211 channel->hmac_name ?
2212 strlen(channel->hmac_name) : 0,
2213 channel->passphrase,
2214 channel->passphrase ?
2215 strlen(channel->passphrase) : 0,
2218 SILC_CHANNEL_MODE_ULIMIT ?
2221 SILC_CHANNEL_MODE_ULIMIT ?
2222 sizeof(ulimit) : 0));
2223 silc_buffer_free(sidp);
2229 ret = silc_server_process_channel_pk(server, channel, type,
2231 if (ret != SILC_STATUS_OK)
2233 chpk = silc_argument_get_next_arg(args, &type, &chpklen);
2236 silc_argument_payload_free(args);
2240 /* Verifies the Authentication Payload `auth' with one of the public keys
2241 on the `channel' public key list. */
2243 SilcBool silc_server_verify_channel_auth(SilcServer server,
2244 SilcChannelEntry channel,
2245 SilcClientID *client_id,
2246 const unsigned char *auth,
2247 SilcUInt32 auth_len)
2251 unsigned char *pkhash;
2252 SilcUInt32 pkhash_len;
2253 SilcBool ret = FALSE;
2255 SILC_LOG_DEBUG(("Verifying channel authentication"));
2257 if (!auth || !auth_len || !channel->channel_pubkeys)
2260 /* Get the hash from the auth data which tells us what public key we
2261 must use in verification. */
2263 ap = silc_auth_payload_parse(auth, auth_len);
2267 pkhash = silc_auth_get_public_data(ap, &pkhash_len);
2268 if (pkhash_len < 128)
2271 /* Find the public key with the hash */
2272 if (!silc_hash_table_find(channel->channel_pubkeys, pkhash,
2273 NULL, (void *)&chpk)) {
2274 SILC_LOG_DEBUG(("Public key not found in channel public key list"));
2278 /* Verify the signature */
2279 if (!silc_auth_verify(ap, SILC_AUTH_PUBLIC_KEY, (void *)chpk, 0,
2280 server->sha1hash, client_id, SILC_ID_CLIENT)) {
2281 SILC_LOG_DEBUG(("Authentication failed"));
2288 silc_auth_payload_free(ap);