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 (client->connection)
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 (chl->client->connection)
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 (is_op && !is_fo)
1074 if (channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
1075 if (is_op && !is_fo)
1080 if (mode & SILC_CHANNEL_MODE_CIPHER) {
1081 if (is_op && !is_fo)
1084 if (channel->mode & SILC_CHANNEL_MODE_CIPHER) {
1085 if (is_op && !is_fo)
1090 if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
1091 if (is_op && !is_fo)
1094 if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
1095 if (is_op && !is_fo)
1100 if (mode & SILC_CHANNEL_MODE_SILENCE_USERS) {
1101 if (is_op && !is_fo)
1104 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS) {
1105 if (is_op && !is_fo)
1110 if (mode & SILC_CHANNEL_MODE_SILENCE_OPERS) {
1111 if (is_op && !is_fo)
1114 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS) {
1115 if (is_op && !is_fo)
1123 /* Check that the client has rights to change its user mode. Returns
1124 FALSE if setting some mode is not allowed. */
1126 bool silc_server_check_umode_rights(SilcServer server,
1127 SilcClientEntry client,
1130 bool server_op = FALSE, router_op = FALSE;
1132 if (mode & SILC_UMODE_SERVER_OPERATOR) {
1133 /* Cannot set server operator mode (must use OPER command) */
1134 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR))
1137 /* Remove the server operator rights */
1138 if (client->mode & SILC_UMODE_SERVER_OPERATOR)
1142 if (mode & SILC_UMODE_ROUTER_OPERATOR) {
1143 /* Cannot set router operator mode (must use SILCOPER command) */
1144 if (!(client->mode & SILC_UMODE_ROUTER_OPERATOR))
1147 /* Remove the router operator rights */
1148 if (client->mode & SILC_UMODE_ROUTER_OPERATOR)
1153 SILC_UMODE_STATS_UPDATE(server, SILC_UMODE_SERVER_OPERATOR);
1155 SILC_UMODE_STATS_UPDATE(router, SILC_UMODE_ROUTER_OPERATOR);
1160 /* This function is used to send the notify packets and motd to the
1161 incoming client connection. */
1163 void silc_server_send_connect_notifys(SilcServer server,
1164 SilcSocketConnection sock,
1165 SilcClientEntry client)
1167 SilcIDListData idata = (SilcIDListData)client;
1169 SILC_LOG_DEBUG(("Send welcome notifys"));
1171 /* Send some nice info to the client */
1172 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1173 ("Welcome to the SILC Network %s",
1175 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1176 ("Your host is %s, running version %s",
1177 server->server_name, server_version));
1179 if (server->server_type == SILC_ROUTER) {
1180 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1181 ("There are %d clients, %d servers and %d "
1182 "routers in SILC Network",
1183 server->stat.clients, server->stat.servers + 1,
1184 server->stat.routers));
1186 if (server->stat.clients && server->stat.servers + 1)
1187 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1188 ("There are %d clients, %d servers and %d "
1189 "routers in SILC Network",
1190 server->stat.clients, server->stat.servers + 1,
1191 (server->standalone ? 0 :
1192 !server->stat.routers ? 1 :
1193 server->stat.routers)));
1196 if (server->stat.cell_clients && server->stat.cell_servers + 1)
1197 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1198 ("There are %d clients on %d server in our cell",
1199 server->stat.cell_clients,
1200 server->stat.cell_servers + 1));
1201 if (server->server_type == SILC_ROUTER) {
1202 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1203 ("I have %d clients, %d channels, %d servers and "
1205 server->stat.my_clients,
1206 server->stat.my_channels,
1207 server->stat.my_servers,
1208 server->stat.my_routers));
1210 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1211 ("I have %d clients and %d channels formed",
1212 server->stat.my_clients,
1213 server->stat.my_channels));
1216 if (server->stat.server_ops || server->stat.router_ops)
1217 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1218 ("There are %d server operators and %d router "
1220 server->stat.server_ops,
1221 server->stat.router_ops));
1222 if (server->stat.my_router_ops + server->stat.my_server_ops)
1223 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1224 ("I have %d operators online",
1225 server->stat.my_router_ops +
1226 server->stat.my_server_ops));
1228 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1229 ("Your connection is secured with %s cipher, "
1230 "key length %d bits",
1231 idata->send_key->cipher->name,
1232 idata->send_key->cipher->key_len));
1233 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1234 ("Your current nickname is %s",
1238 silc_server_send_motd(server, sock);
1241 /* Kill the client indicated by `remote_client' sending KILLED notify
1242 to the client, to all channels client has joined and to primary
1243 router if needed. The killed client is also removed from all channels. */
1245 void silc_server_kill_client(SilcServer server,
1246 SilcClientEntry remote_client,
1247 const char *comment,
1249 SilcIdType killer_id_type)
1251 SilcBuffer killed, killer;
1253 SILC_LOG_DEBUG(("Killing client %s",
1254 silc_id_render(remote_client->id, SILC_ID_CLIENT)));
1256 /* Send the KILL notify packets. First send it to the channel, then
1257 to our primary router and then directly to the client who is being
1258 killed right now. */
1260 killed = silc_id_payload_encode(remote_client->id, SILC_ID_CLIENT);
1261 killer = silc_id_payload_encode(killer_id, killer_id_type);
1263 /* Send KILLED notify to the channels. It is not sent to the client
1264 as it will be sent differently destined directly to the client and not
1266 silc_server_send_notify_on_channels(server, remote_client,
1267 remote_client, SILC_NOTIFY_TYPE_KILLED,
1268 3, killed->data, killed->len,
1269 comment, comment ? strlen(comment) : 0,
1270 killer->data, killer->len);
1272 /* Send KILLED notify to primary route */
1273 silc_server_send_notify_killed(server, SILC_PRIMARY_ROUTE(server),
1274 SILC_BROADCAST(server), remote_client->id,
1275 comment, killer_id, killer_id_type);
1277 /* Send KILLED notify to the client directly */
1278 if (remote_client->connection || remote_client->router)
1279 silc_server_send_notify_killed(server, remote_client->connection ?
1280 remote_client->connection :
1281 remote_client->router->connection, FALSE,
1282 remote_client->id, comment,
1283 killer_id, killer_id_type);
1285 /* Remove the client from all channels. This generates new keys to the
1286 channels as well. */
1287 silc_server_remove_from_channels(server, NULL, remote_client, FALSE,
1290 /* Remove the client entry, If it is locally connected then we will also
1291 disconnect the client here */
1292 if (remote_client->connection) {
1293 /* Remove locally conneted client */
1294 SilcSocketConnection sock = remote_client->connection;
1295 silc_server_free_client_data(server, sock, remote_client, FALSE, NULL);
1296 silc_server_close_connection(server, sock);
1298 /* Update statistics */
1299 server->stat.clients--;
1300 server->stat.my_clients--;
1301 if (server->stat.cell_clients)
1302 server->stat.cell_clients--;
1303 SILC_OPER_STATS_UPDATE(remote_client, server, SILC_UMODE_SERVER_OPERATOR);
1304 SILC_OPER_STATS_UPDATE(remote_client, router, SILC_UMODE_ROUTER_OPERATOR);
1306 /* Remove remote client */
1307 if (!silc_idlist_del_client(server->global_list, remote_client)) {
1308 /* Remove this client from watcher list if it is */
1309 silc_server_del_from_watcher_list(server, remote_client);
1310 silc_idlist_del_client(server->local_list, remote_client);
1314 silc_buffer_free(killer);
1315 silc_buffer_free(killed);
1320 SilcClientEntry client;
1321 SilcNotifyType notify;
1322 const char *new_nick;
1323 } WatcherNotifyContext;
1326 silc_server_check_watcher_list_foreach(void *key, void *context,
1329 WatcherNotifyContext *notify = user_context;
1330 SilcClientEntry entry = context;
1331 SilcSocketConnection sock;
1333 if (entry == notify->client)
1336 sock = silc_server_get_client_route(notify->server, NULL, 0, entry->id,
1339 SILC_LOG_DEBUG(("Sending WATCH notify to %s",
1340 silc_id_render(entry->id, SILC_ID_CLIENT)));
1342 /* Send the WATCH notify */
1343 silc_server_send_notify_watch(notify->server, sock, entry,
1345 notify->new_nick ? notify->new_nick :
1346 (const char *)notify->client->nickname,
1351 /* This function checks whether the `client' nickname is being watched
1352 by someone, and notifies the watcher of the notify change of notify
1353 type indicated by `notify'. */
1355 bool silc_server_check_watcher_list(SilcServer server,
1356 SilcClientEntry client,
1357 const char *new_nick,
1358 SilcNotifyType notify)
1360 unsigned char hash[16];
1361 WatcherNotifyContext n;
1363 SILC_LOG_DEBUG(("Checking watcher list %s",
1364 client->nickname ? client->nickname : (unsigned char *)""));
1366 /* If the watching is rejected by the client do nothing */
1367 if (client->mode & SILC_UMODE_REJECT_WATCHING)
1370 /* Make hash from the nick, or take it from Client ID */
1371 if (client->nickname) {
1373 memset(nick, 0, sizeof(nick));
1374 silc_to_lower(client->nickname, nick, sizeof(nick) - 1);
1375 silc_hash_make(server->md5hash, nick, strlen(nick), hash);
1377 memset(hash, 0, sizeof(hash));
1378 memcpy(hash, client->id->hash, sizeof(client->id->hash));
1383 n.new_nick = new_nick;
1386 /* Send notify to all watchers */
1387 silc_hash_table_find_foreach(server->watcher_list, hash,
1388 silc_server_check_watcher_list_foreach, &n);
1393 /* Remove the `client' from watcher list. After calling this the `client'
1394 is not watching any nicknames. */
1396 bool silc_server_del_from_watcher_list(SilcServer server,
1397 SilcClientEntry client)
1399 SilcHashTableList htl;
1401 SilcClientEntry entry;
1404 silc_hash_table_list(server->watcher_list, &htl);
1405 while (silc_hash_table_get(&htl, &key, (void **)&entry)) {
1406 if (entry == client) {
1407 silc_hash_table_del_by_context(server->watcher_list, key, client);
1410 SILC_LOG_DEBUG(("Removing %s from WATCH list",
1411 silc_id_render(client->id, SILC_ID_CLIENT)));
1413 /* Now check whether there still exists entries with this key, if not
1414 then free the key to not leak memory. */
1415 if (!silc_hash_table_find(server->watcher_list, key, NULL, NULL))
1421 silc_hash_table_list_reset(&htl);
1426 /* Force the client indicated by `chl' to change the channel user mode
1427 on channel indicated by `channel' to `forced_mode'. */
1429 bool silc_server_force_cumode_change(SilcServer server,
1430 SilcSocketConnection sock,
1431 SilcChannelEntry channel,
1432 SilcChannelClientEntry chl,
1433 SilcUInt32 forced_mode)
1435 SilcBuffer idp1, idp2;
1436 unsigned char cumode[4];
1438 SILC_LOG_DEBUG(("Enforcing sender to change mode"));
1441 silc_server_send_notify_cumode(server, sock, FALSE, channel, forced_mode,
1442 server->id, SILC_ID_SERVER,
1443 chl->client->id, NULL);
1445 idp1 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
1446 idp2 = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
1447 SILC_PUT32_MSB(forced_mode, cumode);
1448 silc_server_send_notify_to_channel(server, sock, channel, FALSE,
1449 SILC_NOTIFY_TYPE_CUMODE_CHANGE,
1450 3, idp1->data, idp1->len,
1451 cumode, sizeof(cumode),
1452 idp2->data, idp2->len);
1453 silc_buffer_free(idp1);
1454 silc_buffer_free(idp2);