5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2002 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;
42 SILC_LOG_DEBUG(("Start"));
47 if (silc_hash_table_find(clients, client, NULL, NULL))
48 silc_hash_table_del(clients, client);
50 /* Remove the client from all channels. The client is removed from
51 the channels' user list. */
52 silc_hash_table_list(client->channels, &htl);
53 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
54 channel = chl->channel;
56 /* Remove channel if this is last client leaving the channel, unless
57 the channel is permanent. */
58 if (server->server_type == SILC_ROUTER &&
59 silc_hash_table_count(channel->user_list) < 2) {
60 if (silc_hash_table_find(channels, channel, NULL, NULL))
61 silc_hash_table_del(channels, channel);
62 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
63 silc_server_channel_delete(server, channel);
67 silc_hash_table_del(client->channels, channel);
68 silc_hash_table_del(channel->user_list, chl->client);
69 channel->user_count--;
71 /* If there is no global users on the channel anymore mark the channel
72 as local channel. Do not check if the removed client is local client. */
73 if (server->server_type != SILC_ROUTER && channel->global_users &&
74 chl->client->router && !silc_server_channel_has_global(channel))
75 channel->global_users = FALSE;
79 /* Update statistics */
80 if (SILC_IS_LOCAL(client))
81 server->stat.my_chanclients--;
82 if (server->server_type == SILC_ROUTER) {
83 server->stat.cell_chanclients--;
84 server->stat.chanclients--;
87 /* If there is not at least one local user on the channel then we don't
88 need the channel entry anymore, we can remove it safely, unless the
89 channel is permanent channel */
90 if (server->server_type != SILC_ROUTER &&
91 !silc_server_channel_has_local(channel)) {
92 if (silc_hash_table_find(channels, channel, NULL, NULL))
93 silc_hash_table_del(channels, channel);
94 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
95 silc_server_channel_delete(server, channel);
99 /* Mark other local clients to the table of clients whom will receive
100 the SERVER_SIGNOFF notify. */
101 silc_hash_table_list(channel->user_list, &htl2);
102 while (silc_hash_table_get(&htl2, NULL, (void **)&chl2)) {
103 SilcClientEntry c = chl2->client;
107 /* Add client to table, if it's not from the signoff server */
108 if (c->router != server_entry &&
109 !silc_hash_table_find(clients, c, NULL, NULL))
110 silc_hash_table_add(clients, c, c);
112 silc_hash_table_list_reset(&htl2);
114 /* Add the channel to the the channels list to regenerate the
116 if (!silc_hash_table_find(channels, channel, NULL, NULL))
117 silc_hash_table_add(channels, channel, channel);
119 silc_hash_table_list_reset(&htl);
122 /* This function is used to remove all client entries by the server `entry'.
123 This is called when the connection is lost to the server. In this case
124 we must invalidate all the client entries owned by the server `entry'.
125 If the `server_signoff' is TRUE then the SERVER_SIGNOFF notify is
126 distributed to our local clients. */
128 bool silc_server_remove_clients_by_server(SilcServer server,
129 SilcServerEntry entry,
132 SilcIDCacheList list = NULL;
133 SilcIDCacheEntry id_cache = NULL;
134 SilcClientEntry client = NULL;
136 unsigned char **argv = NULL;
137 SilcUInt32 *argv_lens = NULL, *argv_types = NULL, argc = 0;
138 SilcHashTableList htl;
139 SilcChannelEntry channel;
140 SilcHashTable channels, clients;
143 SILC_LOG_DEBUG(("Start"));
145 /* Allocate the hash table that holds the channels that require
146 channel key re-generation after we've removed this server's clients
147 from the channels. */
148 channels = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL, NULL,
150 clients = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL, NULL,
153 if (server_signoff) {
154 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
155 argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
156 argv_lens = silc_realloc(argv_lens, sizeof(*argv_lens) * (argc + 1));
157 argv_types = silc_realloc(argv_types, sizeof(*argv_types) * (argc + 1));
158 argv[argc] = silc_calloc(idp->len, sizeof(*argv[0]));
159 memcpy(argv[argc], idp->data, idp->len);
160 argv_lens[argc] = idp->len;
161 argv_types[argc] = argc + 1;
163 silc_buffer_free(idp);
166 if (silc_idcache_get_all(server->local_list->clients, &list)) {
168 if (silc_idcache_list_first(list, &id_cache)) {
170 client = (SilcClientEntry)id_cache->context;
171 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
172 if (!silc_idcache_list_next(list, &id_cache))
178 if (client->router != entry) {
179 if (!silc_idcache_list_next(list, &id_cache))
185 if (server_signoff) {
186 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
187 argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
188 argv_lens = silc_realloc(argv_lens, sizeof(*argv_lens) *
190 argv_types = silc_realloc(argv_types, sizeof(*argv_types) *
192 argv[argc] = silc_calloc(idp->len, sizeof(*argv[0]));
193 memcpy(argv[argc], idp->data, idp->len);
194 argv_lens[argc] = idp->len;
195 argv_types[argc] = argc + 1;
197 silc_buffer_free(idp);
200 /* Update statistics */
201 server->stat.clients--;
202 if (server->stat.cell_clients)
203 server->stat.cell_clients--;
204 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
205 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
207 silc_server_remove_clients_channels(server, entry, clients,
209 silc_server_del_from_watcher_list(server, client);
211 /* Remove the client entry */
212 if (!server_signoff) {
213 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
214 id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
216 silc_idlist_del_client(server->local_list, client);
219 if (!silc_idcache_list_next(list, &id_cache))
223 silc_idcache_list_free(list);
226 if (silc_idcache_get_all(server->global_list->clients, &list)) {
228 if (silc_idcache_list_first(list, &id_cache)) {
230 client = (SilcClientEntry)id_cache->context;
231 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
232 if (!silc_idcache_list_next(list, &id_cache))
238 if (client->router != entry) {
239 if (!silc_idcache_list_next(list, &id_cache))
245 if (server_signoff) {
246 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
247 argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
248 argv_lens = silc_realloc(argv_lens, sizeof(*argv_lens) *
250 argv_types = silc_realloc(argv_types, sizeof(*argv_types) *
252 argv[argc] = silc_calloc(idp->len, sizeof(*argv[0]));
253 memcpy(argv[argc], idp->data, idp->len);
254 argv_lens[argc] = idp->len;
255 argv_types[argc] = argc + 1;
257 silc_buffer_free(idp);
260 /* Update statistics */
261 server->stat.clients--;
262 if (server->stat.cell_clients)
263 server->stat.cell_clients--;
264 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
265 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
267 silc_server_remove_clients_channels(server, entry, clients,
269 silc_server_del_from_watcher_list(server, client);
271 /* Remove the client entry */
272 if (!server_signoff) {
273 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
274 id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
276 silc_idlist_del_client(server->global_list, client);
279 if (!silc_idcache_list_next(list, &id_cache))
283 silc_idcache_list_free(list);
286 /* Send the SERVER_SIGNOFF notify */
287 if (server_signoff) {
288 SilcBuffer args, not;
290 /* Send SERVER_SIGNOFF notify to our primary router */
291 if (server->router != entry) {
292 args = silc_argument_payload_encode(1, argv, argv_lens,
294 silc_server_send_notify_args(server, SILC_PRIMARY_ROUTE(server),
295 SILC_BROADCAST(server),
296 SILC_NOTIFY_TYPE_SERVER_SIGNOFF,
298 silc_buffer_free(args);
301 /* Send to local clients. We also send the list of client ID's that
302 is to be removed for those servers that would like to use that list. */
303 args = silc_argument_payload_encode(argc, argv, argv_lens,
305 not = silc_notify_payload_encode_args(SILC_NOTIFY_TYPE_SERVER_SIGNOFF,
307 silc_server_packet_send_clients(server, clients,
308 SILC_PACKET_NOTIFY, 0, FALSE,
309 not->data, not->len, FALSE);
311 silc_buffer_free(args);
312 silc_buffer_free(not);
313 for (i = 0; i < argc; i++)
316 silc_free(argv_lens);
317 silc_free(argv_types);
318 silc_hash_table_free(clients);
321 /* We must now re-generate the channel key for all channels that had
322 this server's client(s) on the channel. As they left the channel we
323 must re-generate the channel key. */
324 silc_hash_table_list(channels, &htl);
325 while (silc_hash_table_get(&htl, NULL, (void **)&channel)) {
326 if (!silc_server_create_channel_key(server, channel, 0)) {
327 silc_hash_table_list_reset(&htl);
328 silc_hash_table_free(channels);
332 /* Do not send the channel key if private channel key mode is set */
333 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY)
336 silc_server_send_channel_key(server, NULL, channel,
337 server->server_type == SILC_ROUTER ?
338 FALSE : !server->standalone);
340 silc_hash_table_list_reset(&htl);
341 silc_hash_table_free(channels);
346 static SilcServerEntry
347 silc_server_update_clients_by_real_server(SilcServer server,
348 SilcServerEntry from,
349 SilcClientEntry client,
351 SilcIDCacheEntry client_cache)
353 SilcServerEntry server_entry;
354 SilcIDCacheEntry id_cache = NULL;
355 SilcIDCacheList list;
357 if (!silc_idcache_get_all(server->local_list->servers, &list))
360 if (silc_idcache_list_first(list, &id_cache)) {
362 server_entry = (SilcServerEntry)id_cache->context;
363 if (server_entry != from &&
364 SILC_ID_COMPARE(server_entry->id, client->id,
365 client->id->ip.data_len)) {
366 SILC_LOG_DEBUG(("Found (local) %s",
367 silc_id_render(server_entry->id, SILC_ID_SERVER)));
369 if (!server_entry->data.send_key && server_entry->router) {
370 SILC_LOG_DEBUG(("Server not locally connected, use its router"));
371 /* If the client is not marked as local then move it to local list
372 since the server is local. */
374 SILC_LOG_DEBUG(("Moving client to local list"));
375 silc_idcache_add(server->local_list->clients, client_cache->name,
376 client_cache->id, client_cache->context,
377 client_cache->expire, NULL);
378 silc_idcache_del_by_context(server->global_list->clients, client);
380 server_entry = server_entry->router;
382 /* If the client is not marked as local then move it to local list
383 since the server is local. */
384 if (server_entry->server_type != SILC_BACKUP_ROUTER && !local) {
385 SILC_LOG_DEBUG(("Moving client to local list"));
386 silc_idcache_add(server->local_list->clients, client_cache->name,
387 client_cache->id, client_cache->context,
388 client_cache->expire, NULL);
389 silc_idcache_del_by_context(server->global_list->clients, client);
393 silc_idcache_list_free(list);
397 if (!silc_idcache_list_next(list, &id_cache))
402 silc_idcache_list_free(list);
404 if (!silc_idcache_get_all(server->global_list->servers, &list))
407 if (silc_idcache_list_first(list, &id_cache)) {
409 server_entry = (SilcServerEntry)id_cache->context;
410 if (server_entry != from &&
411 SILC_ID_COMPARE(server_entry->id, client->id,
412 client->id->ip.data_len)) {
413 SILC_LOG_DEBUG(("Found (global) %s",
414 silc_id_render(server_entry->id, SILC_ID_SERVER)));
416 if (!server_entry->data.send_key && server_entry->router) {
417 SILC_LOG_DEBUG(("Server not locally connected, use its router"));
418 /* If the client is marked as local then move it to global list
419 since the server is global. */
421 SILC_LOG_DEBUG(("Moving client to global list"));
422 silc_idcache_add(server->global_list->clients, client_cache->name,
423 client_cache->id, client_cache->context,
424 client_cache->expire, NULL);
425 silc_idcache_del_by_context(server->local_list->clients, client);
427 server_entry = server_entry->router;
429 /* If the client is marked as local then move it to global list
430 since the server is global. */
431 if (server_entry->server_type != SILC_BACKUP_ROUTER && local) {
432 SILC_LOG_DEBUG(("Moving client to global list"));
433 silc_idcache_add(server->global_list->clients, client_cache->name,
434 client_cache->id, client_cache->context,
435 client_cache->expire, NULL);
436 silc_idcache_del_by_context(server->local_list->clients, client);
440 silc_idcache_list_free(list);
444 if (!silc_idcache_list_next(list, &id_cache))
449 silc_idcache_list_free(list);
454 /* Updates the clients that are originated from the `from' to be originated
455 from the `to'. If the `resolve_real_server' is TRUE then this will
456 attempt to figure out which clients really are originated from the
457 `from' and which are originated from a server that we have connection
458 to, when we've acting as backup router. If it is FALSE the `to' will
459 be the new source. This function also removes the clients that are
460 *really* originated from `from' if `remove_from' is TRUE. These are
461 clients that the `from' owns, and not just clients that are behind
464 void silc_server_update_clients_by_server(SilcServer server,
465 SilcServerEntry from,
467 bool resolve_real_server,
470 SilcIDCacheList list = NULL;
471 SilcIDCacheEntry id_cache = NULL;
472 SilcClientEntry client = NULL;
475 SILC_LOG_DEBUG(("Start"));
477 SILC_LOG_DEBUG(("Updating %s", silc_id_render(from->id,
479 SILC_LOG_DEBUG(("to %s", silc_id_render(to->id,
484 if (silc_idcache_get_all(server->global_list->clients, &list)) {
485 if (silc_idcache_list_first(list, &id_cache)) {
487 client = (SilcClientEntry)id_cache->context;
488 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
489 if (!silc_idcache_list_next(list, &id_cache))
495 SILC_LOG_DEBUG(("Client (global) %s",
496 silc_id_render(client->id, SILC_ID_CLIENT)));
498 SILC_LOG_DEBUG(("Client->router (global) %s",
499 silc_id_render(client->router->id, SILC_ID_SERVER)));
501 if (client->router == from) {
502 /* Skip clients that are *really* owned by the `from' */
503 if (remove_from && SILC_ID_COMPARE(from->id, client->id,
504 client->id->ip.data_len)) {
505 SILC_LOG_DEBUG(("Found really owned client, skip it"));
506 if (!silc_idcache_list_next(list, &id_cache))
512 if (resolve_real_server) {
514 silc_server_update_clients_by_real_server(server, from, client,
523 if (!silc_idcache_list_next(list, &id_cache))
527 silc_idcache_list_free(list);
531 if (silc_idcache_get_all(server->local_list->clients, &list)) {
532 if (silc_idcache_list_first(list, &id_cache)) {
534 client = (SilcClientEntry)id_cache->context;
535 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
536 if (!silc_idcache_list_next(list, &id_cache))
542 SILC_LOG_DEBUG(("Client (local) %s",
543 silc_id_render(client->id, SILC_ID_CLIENT)));
545 SILC_LOG_DEBUG(("Client->router (local) %s",
546 silc_id_render(client->router->id, SILC_ID_SERVER)));
548 if (client->router == from) {
549 /* Skip clients that are *really* owned by the `from' */
550 if (remove_from && SILC_ID_COMPARE(from->id, client->id,
551 client->id->ip.data_len)) {
552 SILC_LOG_DEBUG(("Found really owned client, skip it"));
553 if (!silc_idcache_list_next(list, &id_cache))
559 if (resolve_real_server) {
561 silc_server_update_clients_by_real_server(server, from, client,
564 client->router = from; /* on local list put old from */
570 if (!silc_idcache_list_next(list, &id_cache))
574 silc_idcache_list_free(list);
578 /* Now remove the clients that are still marked as orignated from the
579 `from'. These are the clients that really was owned by the `from' and
580 not just exist behind the `from'. */
581 silc_server_remove_clients_by_server(server, from, TRUE);
584 /* Updates servers that are from `from' to be originated from `to'. This
585 will also update the server's connection to `to's connection. */
587 void silc_server_update_servers_by_server(SilcServer server,
588 SilcServerEntry from,
591 SilcIDCacheList list = NULL;
592 SilcIDCacheEntry id_cache = NULL;
593 SilcServerEntry server_entry = NULL;
595 SILC_LOG_DEBUG(("Start"));
597 if (silc_idcache_get_all(server->local_list->servers, &list)) {
598 if (silc_idcache_list_first(list, &id_cache)) {
600 server_entry = (SilcServerEntry)id_cache->context;
601 if (server_entry->router == from) {
602 server_entry->router = to;
603 server_entry->connection = to->connection;
605 if (!silc_idcache_list_next(list, &id_cache))
609 silc_idcache_list_free(list);
612 if (silc_idcache_get_all(server->global_list->servers, &list)) {
613 if (silc_idcache_list_first(list, &id_cache)) {
615 server_entry = (SilcServerEntry)id_cache->context;
616 if (server_entry->router == from) {
617 server_entry->router = to;
618 server_entry->connection = to->connection;
620 if (!silc_idcache_list_next(list, &id_cache))
624 silc_idcache_list_free(list);
628 /* Removes channels that are from `from. */
630 void silc_server_remove_channels_by_server(SilcServer server,
631 SilcServerEntry from)
633 SilcIDCacheList list = NULL;
634 SilcIDCacheEntry id_cache = NULL;
635 SilcChannelEntry channel = NULL;
637 SILC_LOG_DEBUG(("Removing channels by server"));
639 if (silc_idcache_get_all(server->global_list->channels, &list)) {
640 if (silc_idcache_list_first(list, &id_cache)) {
642 channel = (SilcChannelEntry)id_cache->context;
643 if (channel->router == from)
644 silc_idlist_del_channel(server->global_list, channel);
645 if (!silc_idcache_list_next(list, &id_cache))
649 silc_idcache_list_free(list);
653 /* Updates channels that are from `from' to be originated from `to'. */
655 void silc_server_update_channels_by_server(SilcServer server,
656 SilcServerEntry from,
659 SilcIDCacheList list = NULL;
660 SilcIDCacheEntry id_cache = NULL;
661 SilcChannelEntry channel = NULL;
663 SILC_LOG_DEBUG(("Updating channels by server"));
665 if (silc_idcache_get_all(server->global_list->channels, &list)) {
666 if (silc_idcache_list_first(list, &id_cache)) {
668 channel = (SilcChannelEntry)id_cache->context;
669 if (channel->router == from)
670 channel->router = to;
671 if (!silc_idcache_list_next(list, &id_cache))
675 silc_idcache_list_free(list);
679 /* Checks whether given channel has global users. If it does this returns
680 TRUE and FALSE if there is only locally connected clients on the channel. */
682 bool silc_server_channel_has_global(SilcChannelEntry channel)
684 SilcChannelClientEntry chl;
685 SilcHashTableList htl;
687 silc_hash_table_list(channel->user_list, &htl);
688 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
689 if (chl->client->router) {
690 silc_hash_table_list_reset(&htl);
694 silc_hash_table_list_reset(&htl);
699 /* Checks whether given channel has locally connected users. If it does this
700 returns TRUE and FALSE if there is not one locally connected client. */
702 bool silc_server_channel_has_local(SilcChannelEntry channel)
704 SilcChannelClientEntry chl;
705 SilcHashTableList htl;
707 silc_hash_table_list(channel->user_list, &htl);
708 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
709 if (!chl->client->router) {
710 silc_hash_table_list_reset(&htl);
714 silc_hash_table_list_reset(&htl);
719 /* This function removes the channel and all users on the channel, unless
720 the channel is permanent. In this case the channel is disabled but all
721 users are removed from the channel. Returns TRUE if the channel is
722 destroyed totally, and FALSE if it is permanent and remains. */
724 bool silc_server_channel_delete(SilcServer server,
725 SilcChannelEntry channel)
727 SilcChannelClientEntry chl;
728 SilcHashTableList htl;
729 bool delchan = !(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH);
732 SILC_LOG_DEBUG(("Deleting %s channel", channel->channel_name));
734 /* Update statistics */
735 if (server->server_type == SILC_ROUTER)
736 server->stat.chanclients -= channel->user_count;
738 /* Totally delete the channel and all users on the channel. The
739 users are deleted automatically in silc_idlist_del_channel. */
740 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
741 if (silc_idlist_del_channel(server->local_list, channel)) {
742 server->stat.my_channels--;
743 if (server->server_type == SILC_ROUTER) {
744 server->stat.channels--;
745 server->stat.cell_channels--;
748 if (silc_idlist_del_channel(server->global_list, channel))
749 if (server->server_type == SILC_ROUTER)
750 server->stat.channels--;
756 /* Channel is permanent, do not remove it, remove only users */
757 channel->disabled = TRUE;
758 silc_hash_table_list(channel->user_list, &htl);
759 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
760 silc_hash_table_del(chl->client->channels, channel);
761 silc_hash_table_del(channel->user_list, chl->client);
762 channel->user_count--;
764 /* Update statistics */
765 if (SILC_IS_LOCAL(chl->client))
766 server->stat.my_chanclients--;
767 if (server->server_type == SILC_ROUTER) {
768 server->stat.cell_chanclients--;
769 server->stat.chanclients--;
774 silc_hash_table_list_reset(&htl);
776 SILC_LOG_DEBUG(("Channel %s remains", channel->channel_name));
781 /* Returns TRUE if the given client is on the channel. FALSE if not.
782 This works because we assure that the user list on the channel is
783 always in up to date thus we can only check the channel list from
784 `client' which is faster than checking the user list from `channel'. */
786 bool silc_server_client_on_channel(SilcClientEntry client,
787 SilcChannelEntry channel,
788 SilcChannelClientEntry *chl)
790 if (!client || !channel)
793 return silc_hash_table_find(client->channels, channel, NULL,
797 /* Checks string for bad characters and returns TRUE if they are found. */
799 bool silc_server_name_bad_chars(const char *name, SilcUInt32 name_len)
803 for (i = 0; i < name_len; i++) {
804 if (!isascii(name[i]))
806 if (name[i] <= 32) return TRUE;
807 if (name[i] == ' ') return TRUE;
808 if (name[i] == '*') return TRUE;
809 if (name[i] == '?') return TRUE;
810 if (name[i] == ',') return TRUE;
816 /* Modifies the `name' if it includes bad characters and returns new
817 allocated name that does not include bad characters. */
819 char *silc_server_name_modify_bad(const char *name, SilcUInt32 name_len)
822 char *newname = strdup(name);
824 for (i = 0; i < name_len; i++) {
825 if (!isascii(newname[i])) newname[i] = '_';
826 if (newname[i] <= 32) newname[i] = '_';
827 if (newname[i] == ' ') newname[i] = '_';
828 if (newname[i] == '*') newname[i] = '_';
829 if (newname[i] == '?') newname[i] = '_';
830 if (newname[i] == ',') newname[i] = '_';
836 /* Find number of sockets by IP address indicated by `ip'. Returns 0 if
837 socket connections with the IP address does not exist. */
839 SilcUInt32 silc_server_num_sockets_by_ip(SilcServer server, const char *ip,
844 for (i = 0, count = 0; i < server->config->param.connections_max; i++) {
845 if (server->sockets[i] && !strcmp(server->sockets[i]->ip, ip) &&
846 server->sockets[i]->type == type)
853 /* Find number of sockets by IP address indicated by remote host, indicatd
854 by `ip' or `hostname', `port', and `type'. Returns 0 if socket connections
855 does not exist. If `ip' is provided then `hostname' is ignored. */
857 SilcUInt32 silc_server_num_sockets_by_remote(SilcServer server,
859 const char *hostname,
865 if (!ip && !hostname)
868 for (i = 0, count = 0; i < server->config->param.connections_max; i++) {
869 if (server->sockets[i] &&
870 ((ip && !strcmp(server->sockets[i]->ip, ip)) ||
871 (hostname && !strcmp(server->sockets[i]->hostname, hostname))) &&
872 server->sockets[i]->port == port &&
873 server->sockets[i]->type == type)
880 /* Finds locally cached public key by the public key received in the SKE.
881 If we have it locally cached then we trust it and will use it in the
882 authentication protocol. Returns the locally cached public key or NULL
883 if we do not find the public key. */
885 SilcPublicKey silc_server_find_public_key(SilcServer server,
886 SilcHashTable local_public_keys,
887 SilcPublicKey remote_public_key)
889 SilcPublicKey cached_key;
891 SILC_LOG_DEBUG(("Find remote public key (%d keys in local cache)",
892 silc_hash_table_count(local_public_keys)));
894 if (!silc_hash_table_find_ext(local_public_keys, remote_public_key,
895 (void **)&cached_key, NULL,
896 silc_hash_public_key, NULL,
897 silc_hash_public_key_compare, NULL)) {
898 SILC_LOG_ERROR(("Public key not found"));
902 SILC_LOG_DEBUG(("Found public key"));
907 /* This returns the first public key from the table of public keys. This
908 is used only in cases where single public key exists in the table and
909 we want to get a pointer to it. For public key tables that has multiple
910 keys in it the silc_server_find_public_key must be used. */
912 SilcPublicKey silc_server_get_public_key(SilcServer server,
913 SilcHashTable local_public_keys)
915 SilcPublicKey cached_key;
916 SilcHashTableList htl;
918 SILC_LOG_DEBUG(("Start"));
920 assert(silc_hash_table_count(local_public_keys) < 2);
922 silc_hash_table_list(local_public_keys, &htl);
923 if (!silc_hash_table_get(&htl, NULL, (void **)&cached_key))
925 silc_hash_table_list_reset(&htl);
930 /* Check whether the connection `sock' is allowed to connect to us. This
931 checks for example whether there is too much connections for this host,
932 and required version for the host etc. */
934 bool silc_server_connection_allowed(SilcServer server,
935 SilcSocketConnection sock,
937 SilcServerConfigConnParams *global,
938 SilcServerConfigConnParams *params,
941 SilcUInt32 conn_number = (type == SILC_SOCKET_TYPE_CLIENT ?
942 server->stat.my_clients :
943 type == SILC_SOCKET_TYPE_SERVER ?
944 server->stat.my_servers :
945 server->stat.my_routers);
946 SilcUInt32 num_sockets, max_hosts, max_per_host;
947 SilcUInt32 r_protocol_version, l_protocol_version;
948 SilcUInt32 r_software_version, l_software_version;
949 char *r_vendor_version = NULL, *l_vendor_version;
954 silc_version_to_num(params && params->version_protocol ?
955 params->version_protocol :
956 global->version_protocol);
958 silc_version_to_num(params && params->version_software ?
959 params->version_software :
960 global->version_software);
961 l_vendor_version = (params && params->version_software_vendor ?
962 params->version_software_vendor :
963 global->version_software_vendor);
965 if (ske && silc_ske_parse_version(ske, &r_protocol_version, NULL,
966 &r_software_version, NULL,
967 &r_vendor_version)) {
968 sock->version = r_protocol_version;
970 /* Match protocol version */
971 if (l_protocol_version && r_protocol_version &&
972 r_protocol_version < l_protocol_version) {
973 SILC_LOG_INFO(("Connection %s (%s) is too old version",
974 sock->hostname, sock->ip));
975 silc_server_disconnect_remote(server, sock,
976 SILC_STATUS_ERR_BAD_VERSION,
977 "You support too old protocol version");
981 /* Math software version */
982 if (l_software_version && r_software_version &&
983 r_software_version < l_software_version) {
984 SILC_LOG_INFO(("Connection %s (%s) is too old version",
985 sock->hostname, sock->ip));
986 silc_server_disconnect_remote(server, sock,
987 SILC_STATUS_ERR_BAD_VERSION,
988 "You support too old software version");
992 /* Regex match vendor version */
993 if (l_vendor_version && r_vendor_version &&
994 !silc_string_match(l_vendor_version, r_vendor_version)) {
995 SILC_LOG_INFO(("Connection %s (%s) is unsupported version",
996 sock->hostname, sock->ip));
997 silc_server_disconnect_remote(server, sock,
998 SILC_STATUS_ERR_BAD_VERSION,
999 "Your software is not supported");
1003 silc_free(r_vendor_version);
1005 /* Check for maximum connections limit */
1007 num_sockets = silc_server_num_sockets_by_ip(server, sock->ip, type);
1008 max_hosts = (params ? params->connections_max : global->connections_max);
1009 max_per_host = (params ? params->connections_max_per_host :
1010 global->connections_max_per_host);
1012 if (max_hosts && conn_number >= max_hosts) {
1013 SILC_LOG_INFO(("Server is full, closing %s (%s) connection",
1014 sock->hostname, sock->ip));
1015 silc_server_disconnect_remote(server, sock,
1016 SILC_STATUS_ERR_RESOURCE_LIMIT,
1017 "Server is full, try again later");
1021 if (num_sockets >= max_per_host) {
1022 SILC_LOG_INFO(("Too many connections from %s (%s), closing connection",
1023 sock->hostname, sock->ip));
1024 silc_server_disconnect_remote(server, sock,
1025 SILC_STATUS_ERR_RESOURCE_LIMIT,
1026 "Too many connections from your host");
1033 /* Checks that client has rights to add or remove channel modes. If any
1034 of the checks fails FALSE is returned. */
1036 bool silc_server_check_cmode_rights(SilcServer server,
1037 SilcChannelEntry channel,
1038 SilcChannelClientEntry client,
1041 bool is_op = client->mode & SILC_CHANNEL_UMODE_CHANOP;
1042 bool is_fo = client->mode & SILC_CHANNEL_UMODE_CHANFO;
1044 /* Check whether has rights to change anything */
1045 if (!is_op && !is_fo)
1048 /* Check whether has rights to change everything */
1052 /* Founder implies operator */
1056 /* We know that client is channel operator, check that they are not
1057 changing anything that requires channel founder rights. Rest of the
1058 modes are available automatically for channel operator. */
1060 if (mode & SILC_CHANNEL_MODE_PRIVKEY) {
1061 if (is_op && !is_fo)
1064 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
1065 if (is_op && !is_fo)
1070 if (mode & SILC_CHANNEL_MODE_PASSPHRASE) {
1071 if (!(channel->mode & SILC_CHANNEL_MODE_PASSPHRASE)) {
1072 if (is_op && !is_fo)
1076 if (channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
1077 if (is_op && !is_fo)
1082 if (mode & SILC_CHANNEL_MODE_CIPHER) {
1083 if (!(channel->mode & SILC_CHANNEL_MODE_CIPHER)) {
1084 if (is_op && !is_fo)
1088 if (channel->mode & SILC_CHANNEL_MODE_CIPHER) {
1089 if (is_op && !is_fo)
1094 if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
1095 if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
1096 if (is_op && !is_fo)
1100 if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
1101 if (is_op && !is_fo)
1106 if (mode & SILC_CHANNEL_MODE_SILENCE_USERS) {
1107 if (!(channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS)) {
1108 if (is_op && !is_fo)
1112 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS) {
1113 if (is_op && !is_fo)
1118 if (mode & SILC_CHANNEL_MODE_SILENCE_OPERS) {
1119 if (!(channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS)) {
1120 if (is_op && !is_fo)
1124 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS) {
1125 if (is_op && !is_fo)
1133 /* Check that the client has rights to change its user mode. Returns
1134 FALSE if setting some mode is not allowed. */
1136 bool silc_server_check_umode_rights(SilcServer server,
1137 SilcClientEntry client,
1140 bool server_op = FALSE, router_op = FALSE;
1142 if (mode & SILC_UMODE_SERVER_OPERATOR) {
1143 /* Cannot set server operator mode (must use OPER command) */
1144 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR))
1147 /* Remove the server operator rights */
1148 if (client->mode & SILC_UMODE_SERVER_OPERATOR)
1152 if (mode & SILC_UMODE_ROUTER_OPERATOR) {
1153 /* Cannot set router operator mode (must use SILCOPER command) */
1154 if (!(client->mode & SILC_UMODE_ROUTER_OPERATOR))
1157 /* Remove the router operator rights */
1158 if (client->mode & SILC_UMODE_ROUTER_OPERATOR)
1163 SILC_UMODE_STATS_UPDATE(server, SILC_UMODE_SERVER_OPERATOR);
1165 SILC_UMODE_STATS_UPDATE(router, SILC_UMODE_ROUTER_OPERATOR);
1170 /* This function is used to send the notify packets and motd to the
1171 incoming client connection. */
1173 void silc_server_send_connect_notifys(SilcServer server,
1174 SilcSocketConnection sock,
1175 SilcClientEntry client)
1177 SilcIDListData idata = (SilcIDListData)client;
1179 SILC_LOG_DEBUG(("Send welcome notifys"));
1181 /* Send some nice info to the client */
1182 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1183 ("Welcome to the SILC Network %s",
1185 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1186 ("Your host is %s, running version %s",
1187 server->server_name, server_version));
1189 if (server->server_type == SILC_ROUTER) {
1190 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1191 ("There are %d clients, %d servers and %d "
1192 "routers in SILC Network",
1193 server->stat.clients, server->stat.servers + 1,
1194 server->stat.routers));
1196 if (server->stat.clients && server->stat.servers + 1)
1197 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1198 ("There are %d clients, %d servers and %d "
1199 "routers in SILC Network",
1200 server->stat.clients, server->stat.servers + 1,
1201 (server->standalone ? 0 :
1202 !server->stat.routers ? 1 :
1203 server->stat.routers)));
1206 if (server->stat.cell_clients && server->stat.cell_servers + 1)
1207 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1208 ("There are %d clients on %d server in our cell",
1209 server->stat.cell_clients,
1210 server->stat.cell_servers + 1));
1211 if (server->server_type == SILC_ROUTER) {
1212 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1213 ("I have %d clients, %d channels, %d servers and "
1215 server->stat.my_clients,
1216 server->stat.my_channels,
1217 server->stat.my_servers,
1218 server->stat.my_routers));
1220 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1221 ("I have %d clients and %d channels formed",
1222 server->stat.my_clients,
1223 server->stat.my_channels));
1226 if (server->stat.server_ops || server->stat.router_ops)
1227 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1228 ("There are %d server operators and %d router "
1230 server->stat.server_ops,
1231 server->stat.router_ops));
1232 if (server->stat.my_router_ops + server->stat.my_server_ops)
1233 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1234 ("I have %d operators online",
1235 server->stat.my_router_ops +
1236 server->stat.my_server_ops));
1238 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1239 ("Your connection is secured with %s cipher, "
1240 "key length %d bits",
1241 idata->send_key->cipher->name,
1242 idata->send_key->cipher->key_len));
1243 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1244 ("Your current nickname is %s",
1248 silc_server_send_motd(server, sock);
1251 /* Kill the client indicated by `remote_client' sending KILLED notify
1252 to the client, to all channels client has joined and to primary
1253 router if needed. The killed client is also removed from all channels. */
1255 void silc_server_kill_client(SilcServer server,
1256 SilcClientEntry remote_client,
1257 const char *comment,
1259 SilcIdType killer_id_type)
1261 SilcBuffer killed, killer;
1263 SILC_LOG_DEBUG(("Killing client %s",
1264 silc_id_render(remote_client->id, SILC_ID_CLIENT)));
1266 /* Send the KILL notify packets. First send it to the channel, then
1267 to our primary router and then directly to the client who is being
1268 killed right now. */
1270 killed = silc_id_payload_encode(remote_client->id, SILC_ID_CLIENT);
1271 killer = silc_id_payload_encode(killer_id, killer_id_type);
1273 /* Send KILLED notify to the channels. It is not sent to the client
1274 as it will be sent differently destined directly to the client and not
1276 silc_server_send_notify_on_channels(server, remote_client,
1277 remote_client, SILC_NOTIFY_TYPE_KILLED,
1278 3, killed->data, killed->len,
1279 comment, comment ? strlen(comment) : 0,
1280 killer->data, killer->len);
1282 /* Send KILLED notify to primary route */
1283 silc_server_send_notify_killed(server, SILC_PRIMARY_ROUTE(server),
1284 SILC_BROADCAST(server), remote_client->id,
1285 comment, killer_id, killer_id_type);
1287 /* Send KILLED notify to the client directly */
1288 if (remote_client->connection || remote_client->router)
1289 silc_server_send_notify_killed(server, remote_client->connection ?
1290 remote_client->connection :
1291 remote_client->router->connection, FALSE,
1292 remote_client->id, comment,
1293 killer_id, killer_id_type);
1295 /* Remove the client from all channels. This generates new keys to the
1296 channels as well. */
1297 silc_server_remove_from_channels(server, NULL, remote_client, FALSE,
1300 /* Remove the client entry, If it is locally connected then we will also
1301 disconnect the client here */
1302 if (remote_client->connection) {
1303 /* Remove locally conneted client */
1304 SilcSocketConnection sock = remote_client->connection;
1305 silc_server_free_client_data(server, sock, remote_client, FALSE, NULL);
1306 silc_server_close_connection(server, sock);
1308 /* Update statistics */
1309 server->stat.clients--;
1310 if (server->stat.cell_clients)
1311 server->stat.cell_clients--;
1312 SILC_OPER_STATS_UPDATE(remote_client, server, SILC_UMODE_SERVER_OPERATOR);
1313 SILC_OPER_STATS_UPDATE(remote_client, router, SILC_UMODE_ROUTER_OPERATOR);
1315 if (SILC_IS_LOCAL(remote_client)) {
1316 server->stat.my_clients--;
1317 silc_schedule_task_del_by_context(server->schedule, remote_client);
1318 silc_idlist_del_data(remote_client);
1321 /* Remove remote client */
1322 if (!silc_idlist_del_client(server->global_list, remote_client)) {
1323 /* Remove this client from watcher list if it is */
1324 silc_server_del_from_watcher_list(server, remote_client);
1325 silc_idlist_del_client(server->local_list, remote_client);
1329 silc_buffer_free(killer);
1330 silc_buffer_free(killed);
1335 SilcClientEntry client;
1336 SilcNotifyType notify;
1337 const char *new_nick;
1338 } WatcherNotifyContext;
1341 silc_server_check_watcher_list_foreach(void *key, void *context,
1344 WatcherNotifyContext *notify = user_context;
1345 SilcClientEntry entry = context;
1346 SilcSocketConnection sock;
1348 if (entry == notify->client)
1351 sock = silc_server_get_client_route(notify->server, NULL, 0, entry->id,
1354 SILC_LOG_DEBUG(("Sending WATCH notify to %s",
1355 silc_id_render(entry->id, SILC_ID_CLIENT)));
1357 /* Send the WATCH notify */
1358 silc_server_send_notify_watch(notify->server, sock, entry,
1360 notify->new_nick ? notify->new_nick :
1361 (const char *)notify->client->nickname,
1366 /* This function checks whether the `client' nickname is being watched
1367 by someone, and notifies the watcher of the notify change of notify
1368 type indicated by `notify'. */
1370 bool silc_server_check_watcher_list(SilcServer server,
1371 SilcClientEntry client,
1372 const char *new_nick,
1373 SilcNotifyType notify)
1375 unsigned char hash[16];
1376 WatcherNotifyContext n;
1378 SILC_LOG_DEBUG(("Checking watcher list %s",
1379 client->nickname ? client->nickname : (unsigned char *)""));
1381 /* If the watching is rejected by the client do nothing */
1382 if (client->mode & SILC_UMODE_REJECT_WATCHING)
1385 /* Make hash from the nick, or take it from Client ID */
1386 if (client->nickname) {
1388 memset(nick, 0, sizeof(nick));
1389 silc_to_lower(client->nickname, nick, sizeof(nick) - 1);
1390 silc_hash_make(server->md5hash, nick, strlen(nick), hash);
1392 memset(hash, 0, sizeof(hash));
1393 memcpy(hash, client->id->hash, sizeof(client->id->hash));
1398 n.new_nick = new_nick;
1401 /* Send notify to all watchers */
1402 silc_hash_table_find_foreach(server->watcher_list, hash,
1403 silc_server_check_watcher_list_foreach, &n);
1408 /* Remove the `client' from watcher list. After calling this the `client'
1409 is not watching any nicknames. */
1411 bool silc_server_del_from_watcher_list(SilcServer server,
1412 SilcClientEntry client)
1414 SilcHashTableList htl;
1416 SilcClientEntry entry;
1419 silc_hash_table_list(server->watcher_list, &htl);
1420 while (silc_hash_table_get(&htl, &key, (void **)&entry)) {
1421 if (entry == client) {
1422 silc_hash_table_del_by_context(server->watcher_list, key, client);
1425 SILC_LOG_DEBUG(("Removing %s from WATCH list",
1426 silc_id_render(client->id, SILC_ID_CLIENT)));
1428 /* Now check whether there still exists entries with this key, if not
1429 then free the key to not leak memory. */
1430 if (!silc_hash_table_find(server->watcher_list, key, NULL, NULL))
1436 silc_hash_table_list_reset(&htl);
1441 /* Force the client indicated by `chl' to change the channel user mode
1442 on channel indicated by `channel' to `forced_mode'. */
1444 bool silc_server_force_cumode_change(SilcServer server,
1445 SilcSocketConnection sock,
1446 SilcChannelEntry channel,
1447 SilcChannelClientEntry chl,
1448 SilcUInt32 forced_mode)
1450 SilcBuffer idp1, idp2;
1451 unsigned char cumode[4];
1453 SILC_LOG_DEBUG(("Enforcing sender to change mode"));
1456 silc_server_send_notify_cumode(server, sock, FALSE, channel, forced_mode,
1457 server->id, SILC_ID_SERVER,
1458 chl->client->id, NULL);
1460 idp1 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
1461 idp2 = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
1462 SILC_PUT32_MSB(forced_mode, cumode);
1463 silc_server_send_notify_to_channel(server, sock, channel, FALSE,
1464 SILC_NOTIFY_TYPE_CUMODE_CHANGE,
1465 3, idp1->data, idp1->len,
1466 cumode, sizeof(cumode),
1467 idp2->data, idp2->len);
1468 silc_buffer_free(idp1);
1469 silc_buffer_free(idp2);