5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2008 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"
25 extern char *server_version;
27 /* Removes the client from channels and possibly removes the channels
28 as well. After removing those channels that exist, their channel
29 keys are regnerated. This is called only by the function
30 silc_server_remove_clients_by_server. */
33 silc_server_remove_clients_channels(SilcServer server,
34 SilcServerEntry server_entry,
35 SilcHashTable clients,
36 SilcClientEntry client,
37 SilcHashTable channels)
39 SilcChannelEntry channel;
40 SilcChannelClientEntry chl, chl2;
41 SilcHashTableList htl, htl2;
46 SILC_LOG_DEBUG(("Remove client %s from all channels",
47 client->nickname ? client->nickname :
48 (unsigned char *)""));
50 if (silc_hash_table_find(clients, client, NULL, NULL))
51 silc_hash_table_del(clients, client);
53 /* Remove the client from all channels. The client is removed from
54 the channels' user list. */
55 silc_hash_table_list(client->channels, &htl);
56 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
57 channel = chl->channel;
59 /* Remove channel if this is last client leaving the channel, unless
60 the channel is permanent. */
61 if (server->server_type != SILC_SERVER &&
62 silc_hash_table_count(channel->user_list) < 2) {
63 if (silc_hash_table_find(channels, channel, NULL, NULL))
64 silc_hash_table_del(channels, channel);
65 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
66 silc_server_channel_delete(server, channel);
70 silc_hash_table_del(client->channels, channel);
71 silc_hash_table_del(channel->user_list, chl->client);
72 channel->user_count--;
74 /* If there is no global users on the channel anymore mark the channel
75 as local channel. Do not check if the removed client is local client. */
76 if (server->server_type != SILC_ROUTER && channel->global_users &&
77 chl->client->router && !silc_server_channel_has_global(channel))
78 channel->global_users = FALSE;
82 /* Update statistics */
83 if (SILC_IS_LOCAL(client))
84 server->stat.my_chanclients--;
85 if (server->server_type == SILC_ROUTER) {
86 server->stat.cell_chanclients--;
87 server->stat.chanclients--;
90 /* If there is not at least one local user on the channel then we don't
91 need the channel entry anymore, we can remove it safely, unless the
92 channel is permanent channel */
93 if (server->server_type == SILC_SERVER &&
94 !silc_server_channel_has_local(channel)) {
95 if (silc_hash_table_find(channels, channel, NULL, NULL))
96 silc_hash_table_del(channels, channel);
97 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
98 silc_server_channel_delete(server, channel);
102 /* Mark other local clients to the table of clients whom will receive
103 the SERVER_SIGNOFF notify. */
104 silc_hash_table_list(channel->user_list, &htl2);
105 while (silc_hash_table_get(&htl2, NULL, (void *)&chl2)) {
106 SilcClientEntry c = chl2->client;
110 /* Add client to table, if it's not from the signoff server */
111 if (c->router != server_entry &&
112 !silc_hash_table_find(clients, c, NULL, NULL))
113 silc_hash_table_add(clients, c, c);
115 silc_hash_table_list_reset(&htl2);
117 /* Add the channel to the the channels list to regenerate the
119 if (!silc_hash_table_find(channels, channel, NULL, NULL))
120 silc_hash_table_add(channels, channel, channel);
122 silc_hash_table_list_reset(&htl);
123 assert(!silc_hash_table_count(client->channels));
126 /* This function removes all client entries that are originated from
127 `router' and are owned by `entry'. `router' and `entry' can be same
128 too. If `server_signoff' is TRUE then SERVER_SIGNOFF notify is
129 distributed to our local clients. */
131 SilcBool silc_server_remove_clients_by_server(SilcServer server,
132 SilcServerEntry router,
133 SilcServerEntry entry,
134 SilcBool server_signoff)
137 SilcIDCacheEntry id_cache = NULL;
138 SilcClientEntry client = NULL;
140 unsigned char **argv = NULL;
141 SilcUInt32 *argv_lens = NULL, *argv_types = NULL, argc = 0;
142 SilcHashTableList htl;
143 SilcChannelEntry channel;
144 SilcHashTable channels, clients;
147 if (!(entry->data.status & SILC_IDLIST_STATUS_REGISTERED))
150 SILC_LOG_DEBUG(("Removing clients by %s",
151 entry->server_name ? entry->server_name : "server"));
156 /* Allocate the hash table that holds the channels that require
157 channel key re-generation after we've removed this server's clients
158 from the channels. */
159 channels = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL, NULL,
161 clients = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL, NULL,
164 if (server_signoff) {
165 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
166 argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
167 argv_lens = silc_realloc(argv_lens, sizeof(*argv_lens) * (argc + 1));
168 argv_types = silc_realloc(argv_types, sizeof(*argv_types) * (argc + 1));
169 argv[argc] = silc_calloc(silc_buffer_len(idp), sizeof(*argv[0]));
170 memcpy(argv[argc], idp->data, silc_buffer_len(idp));
171 argv_lens[argc] = silc_buffer_len(idp);
172 argv_types[argc] = argc + 1;
174 silc_buffer_free(idp);
177 if (silc_idcache_get_all(server->local_list->clients, &list)) {
178 silc_list_start(list);
179 while ((id_cache = silc_list_get(list))) {
180 client = (SilcClientEntry)id_cache->context;
182 /* If client is not registered, is not originated from `router'
183 and is not owned by `entry', skip it. */
184 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) ||
185 client->router != router ||
186 (router != entry && !SILC_ID_COMPARE(client->id, entry->id,
187 client->id->ip.data_len))) {
191 if (server_signoff) {
192 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(silc_buffer_len(idp), sizeof(*argv[0]));
200 memcpy(argv[argc], idp->data, silc_buffer_len(idp));
201 argv_lens[argc] = silc_buffer_len(idp);
202 argv_types[argc] = argc + 1;
204 silc_buffer_free(idp);
208 /* Update statistics */
209 assert(server->stat.clients > 0);
210 server->stat.clients--;
211 if (server->stat.cell_clients)
212 server->stat.cell_clients--;
213 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
214 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
216 /* Remove client's public key from repository, this will free it too. */
217 if (client->data.public_key) {
218 silc_skr_del_public_key(server->repository, client->data.public_key,
220 client->data.public_key = NULL;
223 silc_server_remove_clients_channels(server, entry, clients,
225 silc_server_del_from_watcher_list(server, client);
227 /* Remove the client entry */
228 if (!server_signoff) {
229 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
231 client->router = NULL;
232 client->connection = NULL;
233 client->data.created = silc_time();
234 silc_dlist_del(server->expired_clients, client);
235 silc_dlist_add(server->expired_clients, client);
237 silc_idlist_del_data(client);
238 silc_idlist_del_client(server->local_list, client);
243 if (silc_idcache_get_all(server->global_list->clients, &list)) {
244 silc_list_start(list);
245 while ((id_cache = silc_list_get(list))) {
246 client = (SilcClientEntry)id_cache->context;
248 /* If client is not registered, is not originated from `router'
249 and is not owned by `entry', skip it. */
250 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) ||
251 client->router != router ||
252 (router != entry && !SILC_ID_COMPARE(client->id, entry->id,
253 client->id->ip.data_len))) {
257 if (server_signoff) {
258 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
259 argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
260 argv_lens = silc_realloc(argv_lens, sizeof(*argv_lens) *
262 argv_types = silc_realloc(argv_types, sizeof(*argv_types) *
264 argv[argc] = silc_calloc(silc_buffer_len(idp), sizeof(*argv[0]));
265 memcpy(argv[argc], idp->data, silc_buffer_len(idp));
266 argv_lens[argc] = silc_buffer_len(idp);
267 argv_types[argc] = argc + 1;
269 silc_buffer_free(idp);
272 /* Update statistics */
273 assert(server->stat.clients > 0);
274 server->stat.clients--;
275 if (server->stat.cell_clients)
276 server->stat.cell_clients--;
277 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
278 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
280 /* Remove client's public key from repository, this will free it too. */
281 if (client->data.public_key) {
282 silc_skr_del_public_key(server->repository, client->data.public_key,
284 client->data.public_key = NULL;
287 silc_server_remove_clients_channels(server, entry, clients,
289 silc_server_del_from_watcher_list(server, client);
291 /* Remove the client entry */
292 if (!server_signoff) {
293 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
295 client->router = NULL;
296 client->connection = NULL;
297 client->data.created = silc_time();
298 silc_dlist_del(server->expired_clients, client);
299 silc_dlist_add(server->expired_clients, client);
301 silc_idlist_del_data(client);
302 silc_idlist_del_client(server->global_list, client);
307 /* Return now if we are shutting down */
308 if (server->server_shutdown) {
309 silc_hash_table_free(channels);
311 if (server_signoff) {
312 for (i = 0; i < argc; i++)
315 silc_free(argv_lens);
316 silc_free(argv_types);
317 silc_hash_table_free(clients);
322 /* Send the SERVER_SIGNOFF notify */
323 if (server_signoff) {
324 SilcBuffer args, not;
326 SILC_LOG_DEBUG(("Sending SERVER_SIGNOFF for %s with %d clients",
327 silc_id_render(entry->id, SILC_ID_SERVER), argc - 1));
329 /* Send SERVER_SIGNOFF notify to our primary router */
330 if (server->router != entry) {
331 args = silc_argument_payload_encode(1, argv, argv_lens,
333 silc_server_send_notify_args(server, SILC_PRIMARY_ROUTE(server),
334 SILC_BROADCAST(server),
335 SILC_NOTIFY_TYPE_SERVER_SIGNOFF,
337 silc_buffer_free(args);
340 /* Send to local clients. We also send the list of client ID's that
341 is to be removed for those servers that would like to use that list. */
342 args = silc_argument_payload_encode(argc, argv, argv_lens,
344 not = silc_notify_payload_encode_args(SILC_NOTIFY_TYPE_SERVER_SIGNOFF,
346 silc_server_packet_send_clients(server, clients,
347 SILC_PACKET_NOTIFY, 0, FALSE,
348 not->data, silc_buffer_len(not));
350 /* Send notify also to local backup routers */
351 silc_server_backup_send(server, NULL, SILC_PACKET_NOTIFY, 0,
352 not->data, silc_buffer_len(not), FALSE, TRUE);
354 silc_buffer_free(args);
355 silc_buffer_free(not);
356 for (i = 0; i < argc; i++)
359 silc_free(argv_lens);
360 silc_free(argv_types);
361 silc_hash_table_free(clients);
364 /* We must now re-generate the channel key for all channels that had
365 this server's client(s) on the channel. As they left the channel we
366 must re-generate the channel key. */
367 silc_hash_table_list(channels, &htl);
368 while (silc_hash_table_get(&htl, NULL, (void *)&channel)) {
369 if (!silc_server_create_channel_key(server, channel, 0)) {
370 silc_hash_table_list_reset(&htl);
371 silc_hash_table_free(channels);
375 /* Do not send the channel key if private channel key mode is set */
376 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY || !channel->send_key)
379 silc_server_send_channel_key(server, NULL, channel,
380 server->server_type == SILC_ROUTER ?
381 FALSE : !server->standalone);
383 silc_hash_table_list_reset(&htl);
384 silc_hash_table_free(channels);
389 static SilcServerEntry
390 silc_server_update_clients_by_real_server(SilcServer server,
391 SilcServerEntry from,
393 SilcClientEntry client,
395 SilcIDCacheEntry client_cache)
397 SilcServerEntry server_entry;
398 SilcIDCacheEntry id_cache = NULL;
400 SilcBool tolocal = (to == server->id_entry);
402 SILC_LOG_DEBUG(("Start"));
404 if (!silc_idcache_get_all(server->local_list->servers, &list))
407 silc_list_start(list);
408 while ((id_cache = silc_list_get(list))) {
409 server_entry = (SilcServerEntry)id_cache->context;
410 if (server_entry != from &&
411 (tolocal || server_entry != server->id_entry) &&
412 SILC_ID_COMPARE(server_entry->id, client->id,
413 client->id->ip.data_len)) {
414 SILC_LOG_DEBUG(("Found (local) %s",
415 silc_id_render(server_entry->id, SILC_ID_SERVER)));
417 if (!SILC_IS_LOCAL(server_entry) && server_entry->router) {
418 SILC_LOG_DEBUG(("Server not locally connected, use its router"));
419 /* If the client is not marked as local then move it to local list
420 since the server is local. */
422 SILC_LOG_DEBUG(("Moving client to local list"));
423 silc_idcache_move(server->global_list->clients,
424 server->local_list->clients, client_cache);
426 server_entry = server_entry->router;
428 SILC_LOG_DEBUG(("Server locally connected"));
429 /* If the client is not marked as local then move it to local list
430 since the server is local. */
431 if (server_entry->server_type != SILC_BACKUP_ROUTER && !local) {
432 SILC_LOG_DEBUG(("Moving client to local list"));
433 silc_idcache_move(server->global_list->clients,
434 server->local_list->clients, client_cache);
436 } else if (server->server_type == SILC_BACKUP_ROUTER && local) {
437 /* If we are backup router and this client is on local list, we
438 must move it to global list, as it is not currently local to
439 us (we are not primary). */
440 SILC_LOG_DEBUG(("Moving client to global list"));
441 silc_idcache_move(server->local_list->clients,
442 server->global_list->clients, client_cache);
450 if (!silc_idcache_get_all(server->global_list->servers, &list))
453 silc_list_start(list);
454 while ((id_cache = silc_list_get(list))) {
455 server_entry = (SilcServerEntry)id_cache->context;
456 if (server_entry != from && server_entry != server->id_entry &&
457 (tolocal || server_entry != server->id_entry) &&
458 SILC_ID_COMPARE(server_entry->id, client->id,
459 client->id->ip.data_len)) {
460 SILC_LOG_DEBUG(("Found (global) %s",
461 silc_id_render(server_entry->id, SILC_ID_SERVER)));
463 if (!SILC_IS_LOCAL(server_entry) && server_entry->router) {
464 SILC_LOG_DEBUG(("Server not locally connected, use its router"));
465 /* If the client is marked as local then move it to global list
466 since the server is global. */
468 SILC_LOG_DEBUG(("Moving client to global list"));
469 silc_idcache_move(server->local_list->clients,
470 server->global_list->clients, client_cache);
472 server_entry = server_entry->router;
474 SILC_LOG_DEBUG(("Server locally connected"));
475 /* If the client is marked as local then move it to global list
476 since the server is global. */
477 if (server_entry->server_type != SILC_BACKUP_ROUTER && local) {
478 SILC_LOG_DEBUG(("Moving client to global list"));
479 silc_idcache_move(server->local_list->clients,
480 server->global_list->clients, client_cache);
490 /* Updates the clients that are originated from the `from' to be originated
491 from the `to'. If the `resolve_real_server' is TRUE then this will
492 attempt to figure out which clients really are originated from the
493 `from' and which are originated from a server that we have connection
494 to, when we've acting as backup router. If it is FALSE the `to' will
495 be the new source. */
497 void silc_server_update_clients_by_server(SilcServer server,
498 SilcServerEntry from,
500 SilcBool resolve_real_server)
503 SilcIDCacheEntry id_cache = NULL;
504 SilcClientEntry client = NULL;
507 if (from && from->id) {
508 SILC_LOG_DEBUG(("Changing from server %s",
509 silc_id_render(from->id, SILC_ID_SERVER)));
512 SILC_LOG_DEBUG(("Changing to server %s",
513 silc_id_render(to->id, SILC_ID_SERVER)));
516 SILC_LOG_DEBUG(("global list"));
518 if (silc_idcache_get_all(server->global_list->clients, &list)) {
519 silc_list_start(list);
520 while ((id_cache = silc_list_get(list))) {
521 client = (SilcClientEntry)id_cache->context;
523 /* If entry is disabled skip it. If entry is local to us, do not
524 switch it to anyone else, it is ours so skip it. */
525 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) ||
526 SILC_IS_LOCAL(client))
529 SILC_LOG_DEBUG(("Client %s",
530 silc_id_render(client->id, SILC_ID_CLIENT)));
531 if (client->router && client->router->id)
532 SILC_LOG_DEBUG(("Client->router %s",
533 silc_id_render(client->router->id, SILC_ID_SERVER)));
536 if (client->router == from) {
537 if (resolve_real_server) {
539 silc_server_update_clients_by_real_server(server, from, to,
542 if (!client->router) {
543 if (server->server_type == SILC_ROUTER)
544 client->router = from;
553 /* All are changed */
554 if (resolve_real_server)
555 /* Call this so that the entry is moved to correct list if
556 needed. No resolving by real server is actually done. */
557 silc_server_update_clients_by_real_server(server, NULL, to,
564 if (client->router && client->router->id)
565 SILC_LOG_DEBUG(("Client changed to %s",
566 silc_id_render(client->router->id, SILC_ID_SERVER)));
570 SILC_LOG_DEBUG(("local list"));
572 if (silc_idcache_get_all(server->local_list->clients, &list)) {
573 silc_list_start(list);
574 while ((id_cache = silc_list_get(list))) {
575 client = (SilcClientEntry)id_cache->context;
577 /* If entry is disabled skip it. If entry is local to us, do not
578 switch it to anyone else, it is ours so skip it. */
579 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) ||
580 SILC_IS_LOCAL(client))
583 SILC_LOG_DEBUG(("Client %s",
584 silc_id_render(client->id, SILC_ID_CLIENT)));
585 if (client->router && client->router->id)
586 SILC_LOG_DEBUG(("Client->router %s",
587 silc_id_render(client->router->id, SILC_ID_SERVER)));
590 if (client->router == from) {
591 if (resolve_real_server) {
593 silc_server_update_clients_by_real_server(server, from, to,
597 client->router = from;
603 /* All are changed */
604 if (resolve_real_server)
605 /* Call this so that the entry is moved to correct list if
606 needed. No resolving by real server is actually done. */
607 silc_server_update_clients_by_real_server(server, NULL, to,
614 if (client->router && client->router->id)
615 SILC_LOG_DEBUG(("Client changed to %s",
616 silc_id_render(client->router->id, SILC_ID_SERVER)));
621 /* Updates servers that are from `from' to be originated from `to'. This
622 will also update the server's connection to `to's connection. */
624 void silc_server_update_servers_by_server(SilcServer server,
625 SilcServerEntry from,
629 SilcIDCacheEntry id_cache = NULL;
630 SilcServerEntry server_entry = NULL;
632 SILC_LOG_DEBUG(("Updating servers"));
634 if (silc_idcache_get_all(server->local_list->servers, &list)) {
635 silc_list_start(list);
636 while ((id_cache = silc_list_get(list))) {
637 server_entry = (SilcServerEntry)id_cache->context;
639 /* If entry is local to us, do not switch it to any anyone else,
641 if (SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry ||
642 server_entry == from)
645 /* If we are standalone router, any server that is not directly
646 connected to cannot exist anymore. If we are not standalone
647 we update it correctly. */
648 if (server->server_type == SILC_ROUTER && server->standalone) {
649 silc_server_backup_del(server, server_entry);
650 silc_server_backup_replaced_del(server, server_entry);
651 silc_idlist_del_data(server_entry);
652 silc_idlist_del_server(server->local_list, server_entry);
653 server->stat.servers--;
654 server->stat.cell_servers--;
656 /* XXX if we are not standalone, do a check from local config
657 whether this server is in our cell, but not connected to
658 us (in which case we must remove it). */
661 if (server_entry->router == from) {
662 SILC_LOG_DEBUG(("Updating server (local) %s",
663 server_entry->server_name ?
664 server_entry->server_name : ""));
665 server_entry->router = to;
666 server_entry->connection = to->connection;
670 SILC_LOG_DEBUG(("Updating server (local) %s",
671 server_entry->server_name ?
672 server_entry->server_name : ""));
673 server_entry->router = to;
674 server_entry->connection = to->connection;
680 if (silc_idcache_get_all(server->global_list->servers, &list)) {
681 silc_list_start(list);
682 while ((id_cache = silc_list_get(list))) {
683 server_entry = (SilcServerEntry)id_cache->context;
685 /* If entry is local to us, do not switch it to anyone else,
687 if (SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry ||
688 server_entry == from)
691 /* If we are standalone router, any server that is not directly
692 connected to cannot exist anymore. If we are not standalone
693 we update it correctly. */
694 if (server->server_type == SILC_ROUTER && server->standalone) {
695 silc_server_backup_del(server, server_entry);
696 silc_server_backup_replaced_del(server, server_entry);
697 silc_idlist_del_data(server_entry);
698 silc_idlist_del_server(server->global_list, server_entry);
699 server->stat.servers--;
700 server->stat.cell_servers--;
702 /* XXX if we are not standalone, do a check from local config
703 whether this server is in our cell, but not connected to
704 us (in which case we must remove it). */
707 if (server_entry->router == from) {
708 SILC_LOG_DEBUG(("Updating server (global) %s",
709 server_entry->server_name ?
710 server_entry->server_name : ""));
711 server_entry->router = to;
712 server_entry->connection = to->connection;
716 SILC_LOG_DEBUG(("Updating server (global) %s",
717 server_entry->server_name ?
718 server_entry->server_name : ""));
719 server_entry->router = to;
720 server_entry->connection = to->connection;
728 /* Toggles the enabled/disabled status of local server connections. Packets
729 can be sent to the servers when `toggle_enabled' is TRUE and will be
730 dropped if `toggle_enabled' is FALSE, after this function is called. */
732 void silc_server_local_servers_toggle_enabled(SilcServer server,
733 SilcBool toggle_enabled)
736 SilcIDCacheEntry id_cache = NULL;
737 SilcServerEntry server_entry = NULL;
739 if (silc_idcache_get_all(server->local_list->servers, &list)) {
740 silc_list_start(list);
741 while ((id_cache = silc_list_get(list))) {
742 server_entry = (SilcServerEntry)id_cache->context;
743 if (!SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry)
747 server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
749 server_entry->data.status |= SILC_IDLIST_STATUS_DISABLED;
754 if (silc_idcache_get_all(server->global_list->servers, &list)) {
755 silc_list_start(list);
756 while ((id_cache = silc_list_get(list))) {
757 server_entry = (SilcServerEntry)id_cache->context;
758 if (!SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry)
762 server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
764 server_entry->data.status |= SILC_IDLIST_STATUS_DISABLED;
770 /* Removes servers that are originated from the `from'. The server
771 entry is deleted in this function. If `remove_clients' is TRUE then
772 all clients originated from the server are removed too, and server
773 signoff is sent. Note that this does not remove the `from'. This
774 also does not remove locally connected servers. */
776 void silc_server_remove_servers_by_server(SilcServer server,
777 SilcServerEntry from,
778 SilcBool remove_clients)
781 SilcIDCacheEntry id_cache = NULL;
782 SilcServerEntry server_entry = NULL;
784 SILC_LOG_DEBUG(("Removing servers by %s",
785 from->server_name ? from->server_name : "server"));
787 if (silc_idcache_get_all(server->local_list->servers, &list)) {
788 silc_list_start(list);
789 while ((id_cache = silc_list_get(list))) {
790 server_entry = (SilcServerEntry)id_cache->context;
791 if (SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry ||
792 server_entry->router != from || server_entry == from)
795 /* Remove clients owned by this server */
797 silc_server_remove_clients_by_server(server, from, server_entry,
800 /* Remove the server */
801 silc_server_backup_del(server, server_entry);
802 silc_idlist_del_server(server->local_list, server_entry);
806 if (silc_idcache_get_all(server->global_list->servers, &list)) {
807 silc_list_start(list);
808 while ((id_cache = silc_list_get(list))) {
809 server_entry = (SilcServerEntry)id_cache->context;
810 if (SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry ||
811 server_entry->router != from || server_entry == from)
814 /* Remove clients owned by this server */
816 silc_server_remove_clients_by_server(server, from, server_entry,
819 /* Remove the server */
820 silc_server_backup_del(server, server_entry);
821 silc_idlist_del_server(server->global_list, server_entry);
826 /* Removes channels that are from `from. */
828 void silc_server_remove_channels_by_server(SilcServer server,
829 SilcServerEntry from)
832 SilcIDCacheEntry id_cache = NULL;
833 SilcChannelEntry channel = NULL;
835 SILC_LOG_DEBUG(("Removing channels by server"));
837 if (silc_idcache_get_all(server->global_list->channels, &list)) {
838 silc_list_start(list);
839 while ((id_cache = silc_list_get(list))) {
840 channel = (SilcChannelEntry)id_cache->context;
841 if (channel->router == from)
842 silc_idlist_del_channel(server->global_list, channel);
847 /* Updates channels that are from `from' to be originated from `to'. */
849 void silc_server_update_channels_by_server(SilcServer server,
850 SilcServerEntry from,
854 SilcIDCacheEntry id_cache = NULL;
855 SilcChannelEntry channel = NULL;
857 SILC_LOG_DEBUG(("Updating channels by server"));
859 if (silc_idcache_get_all(server->global_list->channels, &list)) {
860 silc_list_start(list);
861 while ((id_cache = silc_list_get(list))) {
862 channel = (SilcChannelEntry)id_cache->context;
864 if (channel->router == from)
865 channel->router = to;
868 channel->router = to;
874 /* Checks whether given channel has global users. If it does this returns
875 TRUE and FALSE if there is only locally connected clients on the channel. */
877 SilcBool silc_server_channel_has_global(SilcChannelEntry channel)
879 SilcChannelClientEntry chl;
880 SilcHashTableList htl;
882 silc_hash_table_list(channel->user_list, &htl);
883 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
884 if (chl->client->router) {
885 silc_hash_table_list_reset(&htl);
889 silc_hash_table_list_reset(&htl);
894 /* Checks whether given channel has locally connected users. If it does this
895 returns TRUE and FALSE if there is not one locally connected client. */
897 SilcBool silc_server_channel_has_local(SilcChannelEntry channel)
899 SilcChannelClientEntry chl;
900 SilcHashTableList htl;
902 silc_hash_table_list(channel->user_list, &htl);
903 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
904 if (SILC_IS_LOCAL(chl->client)) {
905 silc_hash_table_list_reset(&htl);
909 silc_hash_table_list_reset(&htl);
914 /* This function removes the channel and all users on the channel, unless
915 the channel is permanent. In this case the channel is disabled but all
916 users are removed from the channel. Returns TRUE if the channel is
917 destroyed totally, and FALSE if it is permanent and remains. */
919 SilcBool silc_server_channel_delete(SilcServer server,
920 SilcChannelEntry channel)
922 SilcChannelClientEntry chl;
923 SilcHashTableList htl;
924 SilcBool delchan = !(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH);
926 SILC_LOG_DEBUG(("Deleting channel %s", channel->channel_name));
929 /* Update statistics */
930 if (server->server_type == SILC_ROUTER)
931 server->stat.chanclients -= channel->user_count;
933 /* Totally delete the channel and all users on the channel. The
934 users are deleted automatically in silc_idlist_del_channel. */
935 channel->disabled = TRUE;
936 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
937 if (silc_idlist_del_channel(server->local_list, channel)) {
938 server->stat.my_channels--;
939 if (server->server_type == SILC_ROUTER) {
940 server->stat.channels--;
941 server->stat.cell_channels--;
944 if (silc_idlist_del_channel(server->global_list, channel))
945 if (server->server_type == SILC_ROUTER)
946 server->stat.channels--;
952 /* Channel is permanent, do not remove it, remove only users */
953 channel->disabled = TRUE;
954 silc_hash_table_list(channel->user_list, &htl);
955 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
956 silc_hash_table_del(chl->client->channels, channel);
957 silc_hash_table_del(channel->user_list, chl->client);
958 channel->user_count--;
960 /* Update statistics */
961 if (SILC_IS_LOCAL(chl->client))
962 server->stat.my_chanclients--;
963 if (server->server_type == SILC_ROUTER) {
964 server->stat.cell_chanclients--;
965 server->stat.chanclients--;
970 silc_hash_table_list_reset(&htl);
972 SILC_LOG_DEBUG(("Channel %s remains (permanent)", channel->channel_name));
977 /* Returns TRUE if the given client is on the channel. FALSE if not.
978 This works because we assure that the user list on the channel is
979 always in up to date thus we can only check the channel list from
980 `client' which is faster than checking the user list from `channel'. */
982 SilcBool silc_server_client_on_channel(SilcClientEntry client,
983 SilcChannelEntry channel,
984 SilcChannelClientEntry *chl)
986 if (!client || !channel)
989 return silc_hash_table_find(client->channels, channel, NULL,
993 /* Find number of sockets by IP address indicated by `ip'. Returns 0 if
994 socket connections with the IP address does not exist. Counts only
995 fully established connections. */
997 SilcUInt32 silc_server_num_sockets_by_ip(SilcServer server, const char *ip,
998 SilcConnectionType type)
1000 SilcServerConnection conn;
1001 SilcIDListData idata;
1005 silc_dlist_start(server->conns);
1006 while ((conn = silc_dlist_get(server->conns))) {
1007 if (!conn->sock || !silc_packet_stream_is_valid(conn->sock))
1009 silc_socket_stream_get_info(silc_packet_stream_get_stream(conn->sock),
1010 NULL, NULL, &ipaddr, NULL);
1011 idata = silc_packet_get_context(conn->sock);
1012 if (!strcmp(ipaddr, ip) && idata && idata->conn_type == type)
1019 /* Find active socket connection by the IP address and port indicated by
1020 `ip' and `port', and socket connection type of `type'. */
1023 silc_server_find_socket_by_host(SilcServer server,
1024 SilcConnectionType type,
1025 const char *ip, SilcUInt16 port)
1027 SilcServerConnection conn;
1028 SilcIDListData idata;
1031 silc_dlist_start(server->conns);
1032 while ((conn = silc_dlist_get(server->conns))) {
1033 if (!conn->sock || !silc_packet_stream_is_valid(conn->sock))
1035 idata = silc_packet_get_context(conn->sock);
1036 silc_socket_stream_get_info(silc_packet_stream_get_stream(conn->sock),
1037 NULL, NULL, &ipaddr, NULL);
1038 if (!strcmp(ipaddr, ip) &&
1039 (!port || conn->remote_port == port) &&
1040 idata->conn_type == type)
1047 /* Find number of sockets by IP address indicated by remote host, indicatd
1048 by `ip' or `hostname', `port', and `type'. Returns 0 if socket connections
1049 does not exist. If `ip' is provided then `hostname' is ignored. */
1051 SilcUInt32 silc_server_num_sockets_by_remote(SilcServer server,
1053 const char *hostname,
1055 SilcConnectionType type)
1057 SilcServerConnection conn;
1058 SilcIDListData idata;
1059 SilcConnectionType t = SILC_CONN_UNKNOWN;
1062 if (!ip && !hostname)
1065 SILC_LOG_DEBUG(("Num connections %d", silc_dlist_count(server->conns)));
1067 silc_dlist_start(server->conns);
1068 while ((conn = silc_dlist_get(server->conns))) {
1070 idata = silc_packet_get_context(conn->sock);
1072 t = idata->conn_type;
1074 if (((ip && !strcmp(conn->remote_host, ip)) ||
1075 (hostname && !strcmp(conn->remote_host, hostname))) &&
1076 conn->remote_port == port && t == type)
1083 /* SKR find callbcak */
1085 static void find_callback(SilcSKR skr, SilcSKRFind find,
1086 SilcSKRStatus status, SilcDList keys,
1089 SilcPublicKey *public_key = context;
1093 silc_dlist_start(keys);
1094 key = silc_dlist_get(keys);
1095 *public_key = key->key;
1096 silc_dlist_uninit(keys);
1099 silc_skr_find_free(find);
1102 /* Get public key by key usage and key context. */
1104 SilcPublicKey silc_server_get_public_key(SilcServer server,
1105 SilcSKRKeyUsage usage,
1109 SilcPublicKey public_key = NULL;
1111 SILC_LOG_DEBUG(("Start"));
1113 find = silc_skr_find_alloc();
1117 silc_skr_find_set_usage(find, usage);
1118 silc_skr_find_set_context(find, key_context);
1119 silc_skr_find(server->repository, server->schedule,
1120 find, find_callback, &public_key);
1124 SILC_LOG_DEBUG(("Found public key"));
1126 SILC_LOG_DEBUG(("Public key not found"));
1127 #endif /* SILC_DEBUG */
1132 /* Find public key by client for identification purposes. Finds keys
1133 with SILC_SKR_USAGE_IDENTIFICATION. */
1135 SilcBool silc_server_get_public_key_by_client(SilcServer server,
1136 SilcClientEntry client,
1137 SilcPublicKey *public_key)
1139 SilcPublicKey pubkey = NULL;
1140 SilcBool ret = FALSE;
1142 pubkey = silc_server_get_public_key(server, SILC_SKR_USAGE_IDENTIFICATION,
1148 *public_key = pubkey;
1153 /* Check whether the connection `sock' is allowed to connect to us. This
1154 checks for example whether there is too much connections for this host,
1155 and required version for the host etc. */
1157 SilcBool silc_server_connection_allowed(SilcServer server,
1158 SilcPacketStream sock,
1159 SilcConnectionType type,
1160 SilcServerConfigConnParams *global,
1161 SilcServerConfigConnParams *params,
1164 SilcUInt32 conn_number = (type == SILC_CONN_CLIENT ?
1165 server->stat.my_clients :
1166 type == SILC_CONN_SERVER ?
1167 server->stat.my_servers :
1168 server->stat.my_routers);
1169 SilcUInt32 num_sockets, max_hosts, max_per_host;
1170 SilcUInt32 r_protocol_version, l_protocol_version;
1171 SilcUInt32 r_software_version, l_software_version;
1172 char *r_vendor_version = NULL, *l_vendor_version;
1173 const char *hostname, *ip;
1175 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
1176 NULL, &hostname, &ip, NULL);
1178 SILC_LOG_DEBUG(("Checking whether connection is allowed"));
1182 l_protocol_version =
1183 silc_version_to_num(params && params->version_protocol ?
1184 params->version_protocol :
1185 global->version_protocol);
1186 l_software_version =
1187 silc_version_to_num(params && params->version_software ?
1188 params->version_software :
1189 global->version_software);
1190 l_vendor_version = (params && params->version_software_vendor ?
1191 params->version_software_vendor :
1192 global->version_software_vendor);
1194 if (ske && silc_ske_parse_version(ske, &r_protocol_version, NULL,
1195 &r_software_version, NULL,
1196 &r_vendor_version)) {
1197 /* Match protocol version */
1198 if (l_protocol_version && r_protocol_version &&
1199 r_protocol_version < l_protocol_version) {
1200 SILC_LOG_INFO(("Connection %s (%s) is too old version",
1202 silc_server_disconnect_remote(server, sock,
1203 SILC_STATUS_ERR_BAD_VERSION,
1204 "You support too old protocol version");
1205 silc_server_free_sock_user_data(server, sock, NULL);
1209 /* Math software version */
1210 if (l_software_version && r_software_version &&
1211 r_software_version < l_software_version) {
1212 SILC_LOG_INFO(("Connection %s (%s) is too old version",
1214 silc_server_disconnect_remote(server, sock,
1215 SILC_STATUS_ERR_BAD_VERSION,
1216 "You support too old software version");
1217 silc_server_free_sock_user_data(server, sock, NULL);
1221 /* Regex match vendor version */
1222 if (l_vendor_version && r_vendor_version &&
1223 !silc_string_match(l_vendor_version, r_vendor_version)) {
1224 SILC_LOG_INFO(("Connection %s (%s) is unsupported version",
1226 silc_server_disconnect_remote(server, sock,
1227 SILC_STATUS_ERR_BAD_VERSION,
1228 "Your software is not supported");
1229 silc_server_free_sock_user_data(server, sock, NULL);
1233 silc_free(r_vendor_version);
1235 /* Check for maximum connections limit */
1237 num_sockets = silc_server_num_sockets_by_ip(server, ip, type);
1238 max_hosts = (params ? params->connections_max : global->connections_max);
1239 max_per_host = (params ? params->connections_max_per_host :
1240 global->connections_max_per_host);
1242 if (max_hosts && conn_number >= max_hosts) {
1243 SILC_LOG_DEBUG(("Server is full, %d >= %d", conn_number, max_hosts));
1244 SILC_LOG_INFO(("Server is full, closing %s (%s) connection",
1246 silc_server_disconnect_remote(server, sock,
1247 SILC_STATUS_ERR_RESOURCE_LIMIT,
1248 "Server is full, try again later");
1249 silc_server_free_sock_user_data(server, sock, NULL);
1253 if (num_sockets >= max_per_host) {
1254 SILC_LOG_DEBUG(("Too many connections, %d >= %d", num_sockets,
1256 SILC_LOG_INFO(("Too many connections from %s (%s), closing connection",
1258 silc_server_disconnect_remote(server, sock,
1259 SILC_STATUS_ERR_RESOURCE_LIMIT,
1260 "Too many connections from your host");
1261 silc_server_free_sock_user_data(server, sock, NULL);
1268 /* Checks that client has rights to add or remove channel modes. If any
1269 of the checks fails FALSE is returned. */
1271 SilcBool silc_server_check_cmode_rights(SilcServer server,
1272 SilcChannelEntry channel,
1273 SilcChannelClientEntry client,
1276 SilcBool is_op = client->mode & SILC_CHANNEL_UMODE_CHANOP;
1277 SilcBool is_fo = client->mode & SILC_CHANNEL_UMODE_CHANFO;
1279 /* Check whether has rights to change anything */
1280 if (!is_op && !is_fo)
1283 /* Check whether has rights to change everything */
1287 /* Founder implies operator */
1291 /* We know that client is channel operator, check that they are not
1292 changing anything that requires channel founder rights. Rest of the
1293 modes are available automatically for channel operator. */
1295 if (mode & SILC_CHANNEL_MODE_PRIVKEY) {
1296 if (is_op && !is_fo)
1299 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
1300 if (is_op && !is_fo)
1305 if (mode & SILC_CHANNEL_MODE_PASSPHRASE) {
1306 if (!(channel->mode & SILC_CHANNEL_MODE_PASSPHRASE)) {
1307 if (is_op && !is_fo)
1311 if (channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
1312 if (is_op && !is_fo)
1317 if (mode & SILC_CHANNEL_MODE_CIPHER) {
1318 if (!(channel->mode & SILC_CHANNEL_MODE_CIPHER)) {
1319 if (is_op && !is_fo)
1323 if (channel->mode & SILC_CHANNEL_MODE_CIPHER) {
1324 if (is_op && !is_fo)
1329 if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
1330 if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
1331 if (is_op && !is_fo)
1335 if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
1336 if (is_op && !is_fo)
1341 if (mode & SILC_CHANNEL_MODE_SILENCE_USERS) {
1342 if (!(channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS)) {
1343 if (is_op && !is_fo)
1347 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS) {
1348 if (is_op && !is_fo)
1353 if (mode & SILC_CHANNEL_MODE_SILENCE_OPERS) {
1354 if (!(channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS)) {
1355 if (is_op && !is_fo)
1359 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS) {
1360 if (is_op && !is_fo)
1365 if (mode & SILC_CHANNEL_MODE_CHANNEL_AUTH) {
1366 if (!(channel->mode & SILC_CHANNEL_MODE_CHANNEL_AUTH)) {
1367 if (is_op && !is_fo)
1371 if (channel->mode & SILC_CHANNEL_MODE_CHANNEL_AUTH) {
1372 if (is_op && !is_fo)
1380 /* Check that the client has rights to change its user mode. Returns
1381 FALSE if setting some mode is not allowed. */
1383 SilcBool silc_server_check_umode_rights(SilcServer server,
1384 SilcClientEntry client,
1387 SilcBool server_op = FALSE, router_op = FALSE;
1389 if (mode & SILC_UMODE_SERVER_OPERATOR) {
1390 /* Cannot set server operator mode (must use OPER command) */
1391 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR))
1394 /* Remove the server operator rights */
1395 if (client->mode & SILC_UMODE_SERVER_OPERATOR)
1399 if (mode & SILC_UMODE_ROUTER_OPERATOR) {
1400 /* Cannot set router operator mode (must use SILCOPER command) */
1401 if (!(client->mode & SILC_UMODE_ROUTER_OPERATOR))
1404 /* Remove the router operator rights */
1405 if (client->mode & SILC_UMODE_ROUTER_OPERATOR)
1410 SILC_UMODE_STATS_UPDATE(server, SILC_UMODE_SERVER_OPERATOR);
1412 SILC_UMODE_STATS_UPDATE(router, SILC_UMODE_ROUTER_OPERATOR);
1417 /* This function is used to send the notify packets and motd to the
1418 incoming client connection. */
1420 void silc_server_send_connect_notifys(SilcServer server,
1421 SilcPacketStream sock,
1422 SilcClientEntry client)
1426 SILC_LOG_DEBUG(("Send welcome notifys"));
1428 /* Send some nice info to the client */
1429 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1430 ("Welcome to the SILC Network %s",
1432 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1433 ("Your host is %s, running version %s",
1434 server->server_name, server_version));
1436 if (server->server_type == SILC_ROUTER) {
1437 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1438 ("There are %d clients, %d servers and %d "
1439 "routers in SILC Network",
1440 server->stat.clients, server->stat.servers,
1441 server->stat.routers));
1443 if (server->stat.clients && server->stat.servers + 1)
1444 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1445 ("There are %d clients, %d servers and %d "
1446 "routers in SILC Network",
1447 server->stat.clients, server->stat.servers,
1448 (server->standalone ? 0 :
1449 !server->stat.routers ? 1 :
1450 server->stat.routers)));
1453 if (server->stat.cell_clients && server->stat.cell_servers + 1)
1454 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1455 ("There are %d clients on %d servers in our cell",
1456 server->stat.cell_clients,
1457 server->stat.cell_servers));
1458 if (server->server_type == SILC_ROUTER) {
1459 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1460 ("I have %d clients, %d channels, %d servers and "
1462 server->stat.my_clients,
1463 server->stat.my_channels,
1464 server->stat.my_servers,
1465 server->stat.my_routers));
1467 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1468 ("I have %d clients and %d channels formed",
1469 server->stat.my_clients,
1470 server->stat.my_channels));
1473 if (server->stat.server_ops || server->stat.router_ops)
1474 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1475 ("There are %d server operators and %d router "
1477 server->stat.server_ops,
1478 server->stat.router_ops));
1479 if (server->stat.my_router_ops + server->stat.my_server_ops)
1480 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1481 ("I have %d operators online",
1482 server->stat.my_router_ops +
1483 server->stat.my_server_ops));
1485 silc_packet_get_keys(sock, &key, NULL, NULL, NULL);
1486 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1487 ("Your connection is secured with %s cipher, "
1488 "key length %d bits",
1489 silc_cipher_get_name(key),
1490 silc_cipher_get_key_len(key)));
1491 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1492 ("Your current nickname is %s",
1496 silc_server_send_motd(server, sock);
1499 /* Kill the client indicated by `remote_client' sending KILLED notify
1500 to the client, to all channels client has joined and to primary
1501 router if needed. The killed client is also removed from all channels. */
1503 void silc_server_kill_client(SilcServer server,
1504 SilcClientEntry remote_client,
1505 const char *comment,
1507 SilcIdType killer_id_type)
1509 SilcBuffer killed, killer;
1511 SILC_LOG_DEBUG(("Killing client %s",
1512 silc_id_render(remote_client->id, SILC_ID_CLIENT)));
1514 /* Send the KILL notify packets. First send it to the channel, then
1515 to our primary router and then directly to the client who is being
1516 killed right now. */
1518 killed = silc_id_payload_encode(remote_client->id, SILC_ID_CLIENT);
1519 killer = silc_id_payload_encode(killer_id, killer_id_type);
1521 /* Send KILLED notify to the channels. It is not sent to the client
1522 as it will be sent differently destined directly to the client and not
1524 silc_server_send_notify_on_channels(server, remote_client,
1525 remote_client, SILC_NOTIFY_TYPE_KILLED,
1526 3, killed->data, silc_buffer_len(killed),
1527 comment, comment ? strlen(comment) : 0,
1528 killer->data, silc_buffer_len(killer));
1530 /* Send KILLED notify to primary route */
1531 silc_server_send_notify_killed(server, SILC_PRIMARY_ROUTE(server),
1532 SILC_BROADCAST(server), remote_client->id,
1533 comment, killer_id, killer_id_type);
1535 /* Send KILLED notify to the client directly */
1536 if (remote_client->connection || remote_client->router)
1537 silc_server_send_notify_killed(server, remote_client->connection ?
1538 remote_client->connection :
1539 remote_client->router->connection, FALSE,
1540 remote_client->id, comment,
1541 killer_id, killer_id_type);
1543 /* Remove the client from all channels. This generates new keys to the
1544 channels as well. */
1545 silc_server_remove_from_channels(server, NULL, remote_client, FALSE,
1548 /* Remove the client entry, If it is locally connected then we will also
1549 disconnect the client here */
1550 if (remote_client->connection) {
1551 /* Remove locally conneted client */
1552 SilcPacketStream sock = remote_client->connection;
1555 silc_packet_stream_ref(sock);
1557 silc_server_free_sock_user_data(server, sock, NULL);
1560 silc_packet_set_context(sock, NULL);
1561 silc_server_close_connection(server, sock);
1562 silc_packet_stream_unref(sock);
1565 /* Update statistics */
1566 assert(server->stat.clients > 0);
1567 server->stat.clients--;
1568 if (server->stat.cell_clients)
1569 server->stat.cell_clients--;
1570 SILC_OPER_STATS_UPDATE(remote_client, server, SILC_UMODE_SERVER_OPERATOR);
1571 SILC_OPER_STATS_UPDATE(remote_client, router, SILC_UMODE_ROUTER_OPERATOR);
1573 /* Remove client's public key from repository, this will free it too. */
1574 if (remote_client->data.public_key) {
1575 silc_skr_del_public_key(server->repository,
1576 remote_client->data.public_key, remote_client);
1577 remote_client->data.public_key = NULL;
1580 if (SILC_IS_LOCAL(remote_client)) {
1581 server->stat.my_clients--;
1582 silc_schedule_task_del_by_context(server->schedule, remote_client);
1585 /* Remove remote client */
1586 silc_dlist_del(server->expired_clients, remote_client);
1587 silc_idlist_del_data(remote_client);
1588 if (!silc_idlist_del_client(server->global_list, remote_client)) {
1589 /* Remove this client from watcher list if it is */
1590 silc_server_del_from_watcher_list(server, remote_client);
1591 silc_idlist_del_client(server->local_list, remote_client);
1595 silc_buffer_free(killer);
1596 silc_buffer_free(killed);
1601 SilcClientEntry client;
1602 SilcNotifyType notify;
1603 const char *new_nick;
1604 } WatcherNotifyContext;
1607 silc_server_check_watcher_list_foreach(void *key, void *context,
1610 WatcherNotifyContext *notify = user_context;
1611 SilcClientEntry entry = context;
1612 SilcPacketStream sock;
1617 if (entry == notify->client)
1620 sock = silc_server_get_client_route(notify->server, NULL, 0, entry->id,
1623 SILC_LOG_DEBUG(("Sending WATCH notify to %s",
1624 silc_id_render(entry->id, SILC_ID_CLIENT)));
1626 /* Send the WATCH notify */
1627 silc_server_send_notify_watch(notify->server, sock, entry,
1629 notify->new_nick ? notify->new_nick :
1630 (const char *)notify->client->nickname,
1632 notify->client->data.public_key);
1636 /* This function checks whether the `client' nickname and/or 'client'
1637 public key is being watched by someone, and notifies the watcher of the
1638 notify change of notify type indicated by `notify'. */
1640 SilcBool silc_server_check_watcher_list(SilcServer server,
1641 SilcClientEntry client,
1642 const char *new_nick,
1643 SilcNotifyType notify)
1645 unsigned char hash[16];
1646 WatcherNotifyContext n;
1648 SILC_LOG_DEBUG(("Checking watcher list %s",
1649 client->nickname ? client->nickname : (unsigned char *)""));
1651 /* If the watching is rejected by the client do nothing */
1652 if (client->mode & SILC_UMODE_REJECT_WATCHING)
1655 /* Make hash from the nick, or take it from Client ID */
1656 if (client->nickname) {
1657 unsigned char *nickc;
1658 nickc = silc_identifier_check(client->nickname, strlen(client->nickname),
1659 SILC_STRING_UTF8, 128, NULL);
1662 silc_hash_make(server->md5hash, nickc, strlen(nickc), hash);
1665 memset(hash, 0, sizeof(hash));
1666 memcpy(hash, client->id->hash, sizeof(client->id->hash));
1671 n.new_nick = new_nick;
1674 /* Send notify to all watchers watching this nickname */
1675 silc_hash_table_find_foreach(server->watcher_list, hash,
1676 silc_server_check_watcher_list_foreach, &n);
1678 /* Send notify to all watchers watching this public key */
1679 if (client->data.public_key)
1680 silc_hash_table_find_foreach(server->watcher_list_pk,
1681 client->data.public_key,
1682 silc_server_check_watcher_list_foreach,
1688 /* Remove the `client' from watcher list. After calling this the `client'
1689 is not watching any nicknames. */
1691 SilcBool silc_server_del_from_watcher_list(SilcServer server,
1692 SilcClientEntry client)
1694 SilcHashTableList htl;
1696 SilcClientEntry entry;
1697 SilcBool found = FALSE;
1699 silc_hash_table_list(server->watcher_list, &htl);
1700 while (silc_hash_table_get(&htl, &key, (void *)&entry)) {
1701 if (entry == client) {
1702 silc_hash_table_del_by_context(server->watcher_list, key, client);
1705 SILC_LOG_DEBUG(("Removing %s from WATCH list",
1706 silc_id_render(client->id, SILC_ID_CLIENT)));
1708 /* Now check whether there still exists entries with this key, if not
1709 then free the key to not leak memory. */
1710 if (!silc_hash_table_find(server->watcher_list, key, NULL, NULL))
1716 silc_hash_table_list_reset(&htl);
1718 silc_hash_table_list(server->watcher_list_pk, &htl);
1719 while (silc_hash_table_get(&htl, &key, (void *)&entry)) {
1720 if (entry == client) {
1721 silc_hash_table_del_by_context(server->watcher_list_pk, key, client);
1724 SILC_LOG_DEBUG(("Removing %s from WATCH list",
1725 silc_id_render(client->id, SILC_ID_CLIENT)));
1727 /* Now check whether there still exists entries with this key, if not
1728 then free the key to not leak memory. */
1729 if (!silc_hash_table_find(server->watcher_list_pk, key, NULL, NULL))
1730 silc_pkcs_public_key_free(key);
1735 silc_hash_table_list_reset(&htl);
1740 /* Force the client indicated by `chl' to change the channel user mode
1741 on channel indicated by `channel' to `forced_mode'. */
1743 SilcBool silc_server_force_cumode_change(SilcServer server,
1744 SilcPacketStream sock,
1745 SilcChannelEntry channel,
1746 SilcChannelClientEntry chl,
1747 SilcUInt32 forced_mode)
1749 SilcBuffer idp1, idp2;
1750 unsigned char cumode[4];
1752 SILC_LOG_DEBUG(("Enforcing sender to change mode"));
1755 silc_server_send_notify_cumode(server, sock, FALSE, channel, forced_mode,
1756 server->id, SILC_ID_SERVER,
1757 chl->client->id, NULL);
1759 idp1 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
1760 idp2 = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
1761 SILC_PUT32_MSB(forced_mode, cumode);
1762 silc_server_send_notify_to_channel(server, sock, channel, FALSE, TRUE,
1763 SILC_NOTIFY_TYPE_CUMODE_CHANGE,
1764 3, idp1->data, silc_buffer_len(idp1),
1765 cumode, sizeof(cumode),
1766 idp2->data, silc_buffer_len(idp2));
1767 silc_buffer_free(idp1);
1768 silc_buffer_free(idp2);
1773 /* This function can be used to match the invite and ban lists. */
1775 SilcBool silc_server_inviteban_match(SilcServer server, SilcHashTable list,
1776 SilcUInt8 type, void *check)
1778 unsigned char *tmp = NULL;
1780 SilcHashTableList htl;
1781 SilcBuffer entry, idp = NULL, pkp = NULL;
1782 SilcBool ret = FALSE;
1785 SILC_LOG_DEBUG(("Matching invite/ban"));
1787 if (type < 1 || type > 3 || !check)
1791 tmp = strdup((char *)check);
1796 pkp = silc_public_key_payload_encode(check);
1800 len = silc_buffer_len(pkp);
1803 idp = silc_id_payload_encode(check, SILC_ID_CLIENT);
1807 len = silc_buffer_len(idp);
1810 /* Compare the list */
1811 silc_hash_table_list(list, &htl);
1812 while (silc_hash_table_get(&htl, (void *)&t, (void *)&entry)) {
1813 if (type == SILC_PTR_TO_32(t)) {
1815 if (silc_string_match(entry->data, tmp)) {
1819 } else if (silc_buffer_len(entry) == len &&
1820 !memcmp(entry->data, tmp, len)) {
1826 silc_hash_table_list_reset(&htl);
1830 silc_buffer_free(idp);
1831 silc_buffer_free(pkp);
1835 /* Process invite or ban information */
1837 SilcBool silc_server_inviteban_process(SilcServer server,
1840 SilcArgumentPayload args)
1843 SilcUInt32 type, len;
1846 SilcHashTableList htl;
1848 SILC_LOG_DEBUG(("Processing invite/ban for %s action",
1849 action == 0x01 ? "DEL" : "ADD"));
1851 /* Add the information to invite list */
1852 if (action == 0x00 || action == 0x03) {
1853 /* Traverse all arguments and add to the hash table according to
1855 tmp = silc_argument_get_first_arg(args, &type, &len);
1858 /* Check validity of the string. Actually we should parse the
1859 whole string and verify all components individually. */
1860 if (!silc_utf8_valid(tmp, len) || !len) {
1861 tmp = silc_argument_get_next_arg(args, &type, &len);
1864 if (strchr(tmp, ',')) {
1865 tmp = silc_argument_get_next_arg(args, &type, &len);
1869 /* Check if the string is added already */
1870 silc_hash_table_list(list, &htl);
1871 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) {
1872 if (SILC_PTR_TO_32(ptype) == 1 &&
1873 silc_string_match(tmp2->data, tmp)) {
1878 silc_hash_table_list_reset(&htl);
1881 /* Add the string to hash table */
1882 tmp2 = silc_buffer_alloc_size(len + 1);
1883 if (tmp[len - 1] == ',')
1884 tmp[len - 1] = '\0';
1885 silc_buffer_put(tmp2, tmp, len);
1886 silc_hash_table_add(list, (void *)1, tmp2);
1889 } else if (type == 2) {
1890 /* Public key. Check first if the public key is already on the
1891 list and ignore it if it is, otherwise, add it to hash table. */
1894 /* Verify validity of the public key */
1895 if (!silc_public_key_payload_decode(tmp, len, &pk)) {
1896 tmp = silc_argument_get_next_arg(args, &type, &len);
1899 silc_pkcs_public_key_free(pk);
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 *)&ptype, (void *)&tmp2)) {
1904 if (SILC_PTR_TO_32(ptype) == 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 *)&ptype, (void *)&tmp2)) {
1924 if (SILC_PTR_TO_32(ptype) == 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 /* Check validity of the string. Actually we should parse the
1950 whole string and verify all components individually. */
1951 if (!silc_utf8_valid(tmp, len)) {
1952 tmp = silc_argument_get_next_arg(args, &type, &len);
1955 if (strchr(tmp, ',')) {
1956 tmp = silc_argument_get_next_arg(args, &type, &len);
1960 /* Delete from the list */
1961 silc_hash_table_list(list, &htl);
1962 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) {
1963 if (SILC_PTR_TO_32(ptype) == 1 &&
1964 silc_string_match(tmp2->data, tmp)) {
1965 silc_hash_table_del_by_context(list, (void *)1, tmp2);
1969 silc_hash_table_list_reset(&htl);
1971 } else if (type == 2) {
1975 /* Verify validity of the public key */
1976 if (!silc_public_key_payload_decode(tmp, len, &pk)) {
1977 tmp = silc_argument_get_next_arg(args, &type, &len);
1980 silc_pkcs_public_key_free(pk);
1982 /* Delete from the invite list */
1983 silc_hash_table_list(list, &htl);
1984 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) {
1985 if (SILC_PTR_TO_32(ptype) == 2 && !memcmp(tmp2->data, tmp, len)) {
1986 silc_hash_table_del_by_context(list, (void *)2, tmp2);
1990 silc_hash_table_list_reset(&htl);
1992 } else if (type == 3) {
1995 /* Delete from the invite list */
1996 silc_hash_table_list(list, &htl);
1997 while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) {
1998 if (SILC_PTR_TO_32(ptype) == 3 && !memcmp(tmp2->data, tmp, len)) {
1999 silc_hash_table_del_by_context(list, (void *)3, tmp2);
2003 silc_hash_table_list_reset(&htl);
2006 tmp = silc_argument_get_next_arg(args, &type, &len);
2013 /* Destructor for invite and ban list entrys */
2015 void silc_server_inviteban_destruct(void *key, void *context,
2018 silc_buffer_free(context);
2021 /* Creates connections accoring to configuration. */
2023 void silc_server_create_connections(SilcServer server)
2025 silc_schedule_task_del_by_callback(server->schedule,
2026 silc_server_connect_to_router_retry);
2027 silc_schedule_task_del_by_callback(server->schedule,
2028 silc_server_connect_to_router);
2029 silc_schedule_task_add_timeout(server->schedule,
2030 silc_server_connect_to_router, server, 1, 0);
2034 silc_server_process_channel_pk_destruct(void *key, void *context,
2038 silc_pkcs_public_key_free(context);
2041 /* Processes a channel public key, either adds or removes it. */
2044 silc_server_process_channel_pk(SilcServer server,
2045 SilcChannelEntry channel,
2046 SilcUInt32 type, const unsigned char *pk,
2049 unsigned char pkhash[20];
2052 SILC_LOG_DEBUG(("Processing channel public key"));
2055 return SILC_STATUS_ERR_NOT_ENOUGH_PARAMS;
2057 /* Decode the public key */
2058 if (!silc_public_key_payload_decode((unsigned char *)pk, pk_len, &chpk))
2059 return SILC_STATUS_ERR_UNSUPPORTED_PUBLIC_KEY;
2061 /* Create channel public key list (hash table) if needed */
2062 if (!channel->channel_pubkeys) {
2063 channel->channel_pubkeys =
2064 silc_hash_table_alloc(0, silc_hash_data, (void *)20,
2065 silc_hash_data_compare, (void *)20,
2066 silc_server_process_channel_pk_destruct, channel,
2070 /* Create SHA-1 digest of the public key data */
2071 silc_hash_make(server->sha1hash, pk + 4, pk_len - 4, pkhash);
2074 /* Add new public key to channel public key list */
2075 SILC_LOG_DEBUG(("Add new channel public key to channel %s",
2076 channel->channel_name));
2078 /* Check for resource limit */
2079 if (silc_hash_table_count(channel->channel_pubkeys) > 64) {
2080 silc_pkcs_public_key_free(chpk);
2081 return SILC_STATUS_ERR_RESOURCE_LIMIT;
2084 /* Add if doesn't exist already */
2085 if (!silc_hash_table_find(channel->channel_pubkeys, pkhash,
2087 silc_hash_table_add(channel->channel_pubkeys, silc_memdup(pkhash, 20),
2089 } else if (type == 0x01) {
2090 /* Delete public key from channel public key list */
2091 SILC_LOG_DEBUG(("Delete a channel public key from channel %s",
2092 channel->channel_name));
2093 if (!silc_hash_table_del(channel->channel_pubkeys, pkhash))
2094 silc_pkcs_public_key_free(chpk);
2096 silc_pkcs_public_key_free(chpk);
2097 return SILC_STATUS_ERR_NOT_ENOUGH_PARAMS;
2100 return SILC_STATUS_OK;
2103 /* Returns the channel public keys as Argument List payload. */
2105 SilcBuffer silc_server_get_channel_pk_list(SilcServer server,
2106 SilcChannelEntry channel,
2110 SilcHashTableList htl;
2111 SilcBuffer list, pkp;
2114 SILC_LOG_DEBUG(("Encoding channel public keys list"));
2116 if (!channel->channel_pubkeys ||
2117 !silc_hash_table_count(channel->channel_pubkeys))
2120 /* Encode the list */
2121 list = silc_buffer_alloc_size(2);
2122 silc_buffer_format(list,
2123 SILC_STR_UI_SHORT(silc_hash_table_count(
2124 channel->channel_pubkeys)),
2127 silc_hash_table_list(channel->channel_pubkeys, &htl);
2128 while (silc_hash_table_get(&htl, NULL, (void *)&pk)) {
2129 pkp = silc_public_key_payload_encode(pk);
2132 list = silc_argument_payload_encode_one(list, pkp->data,
2133 silc_buffer_len(pkp),
2135 delete ? 0x01 : 0x00);
2136 silc_buffer_free(pkp);
2138 silc_hash_table_list_reset(&htl);
2143 /* Sets the channel public keys into channel from the list of public keys. */
2145 SilcStatus silc_server_set_channel_pk_list(SilcServer server,
2146 SilcPacketStream sender,
2147 SilcChannelEntry channel,
2148 const unsigned char *pklist,
2149 SilcUInt32 pklist_len)
2152 SilcArgumentPayload args;
2153 unsigned char *chpk;
2154 SilcUInt32 chpklen, type;
2155 SilcStatus ret = SILC_STATUS_OK;
2157 SILC_LOG_DEBUG(("Setting channel public keys list"));
2159 if (!pklist || pklist_len < 2)
2160 return SILC_STATUS_ERR_NOT_ENOUGH_PARAMS;
2162 /* Get the argument from the Argument List Payload */
2163 SILC_GET16_MSB(argc, pklist);
2164 args = silc_argument_payload_parse(pklist + 2, pklist_len - 2, argc);
2166 return SILC_STATUS_ERR_NOT_ENOUGH_PARAMS;
2168 /* Process the public keys one by one */
2169 chpk = silc_argument_get_first_arg(args, &type, &chpklen);
2171 /* If announcing keys and we have them set already, do not allow this */
2172 if (chpk && type == 0x03 && channel->channel_pubkeys &&
2173 server->server_type == SILC_ROUTER &&
2174 sender != SILC_PRIMARY_ROUTE(server)) {
2175 SILC_LOG_DEBUG(("Channel public key list set already, enforce our list"));
2176 silc_argument_payload_free(args);
2177 return SILC_STATUS_ERR_OPERATION_ALLOWED;
2180 /* If we are normal server and receive announcement list and we already
2181 have keys set, we replace the old list with the announced one. */
2182 if (chpk && type == 0x03 && channel->channel_pubkeys &&
2183 server->server_type != SILC_ROUTER) {
2185 unsigned char mask[4], ulimit[4];
2187 SILC_LOG_DEBUG(("Router enforces its list, remove old list"));
2188 silc_hash_table_free(channel->channel_pubkeys);
2189 channel->channel_pubkeys = NULL;
2191 /* Send notify that removes the old list */
2192 sidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
2193 SILC_PUT32_MSB((channel->mode & (~SILC_CHANNEL_MODE_CHANNEL_AUTH)), mask);
2194 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
2195 SILC_PUT32_MSB(channel->user_limit, ulimit);
2196 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
2197 SILC_NOTIFY_TYPE_CMODE_CHANGE, 8,
2198 sidp->data, silc_buffer_len(sidp),
2202 strlen(channel->cipher) : 0,
2204 channel->hmac_name ?
2205 strlen(channel->hmac_name) : 0,
2206 channel->passphrase,
2207 channel->passphrase ?
2208 strlen(channel->passphrase) : 0,
2211 SILC_CHANNEL_MODE_ULIMIT ?
2214 SILC_CHANNEL_MODE_ULIMIT ?
2215 sizeof(ulimit) : 0));
2216 silc_buffer_free(sidp);
2222 ret = silc_server_process_channel_pk(server, channel, type,
2224 if (ret != SILC_STATUS_OK)
2226 chpk = silc_argument_get_next_arg(args, &type, &chpklen);
2229 silc_argument_payload_free(args);
2233 /* Verifies the Authentication Payload `auth' with one of the public keys
2234 on the `channel' public key list. */
2236 SilcBool silc_server_verify_channel_auth(SilcServer server,
2237 SilcChannelEntry channel,
2238 SilcClientID *client_id,
2239 const unsigned char *auth,
2240 SilcUInt32 auth_len)
2244 unsigned char *pkhash;
2245 SilcUInt32 pkhash_len;
2246 SilcBool ret = FALSE;
2248 SILC_LOG_DEBUG(("Verifying channel authentication"));
2250 if (!auth || !auth_len || !channel->channel_pubkeys)
2253 /* Get the hash from the auth data which tells us what public key we
2254 must use in verification. */
2256 ap = silc_auth_payload_parse(auth, auth_len);
2260 pkhash = silc_auth_get_public_data(ap, &pkhash_len);
2261 if (pkhash_len < 128)
2264 /* Find the public key with the hash */
2265 if (!silc_hash_table_find(channel->channel_pubkeys, pkhash,
2266 NULL, (void *)&chpk)) {
2267 SILC_LOG_DEBUG(("Public key not found in channel public key list"));
2271 /* Verify the signature */
2272 if (!silc_auth_verify(ap, SILC_AUTH_PUBLIC_KEY, (void *)chpk, 0,
2273 server->sha1hash, client_id, SILC_ID_CLIENT)) {
2274 SILC_LOG_DEBUG(("Authentication failed"));
2281 silc_auth_payload_free(ap);