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 /* Removes the client from channels and possibly removes the channels
25 as well. After removing those channels that exist, their channel
26 keys are regnerated. This is called only by the function
27 silc_server_remove_clients_by_server. */
29 static void silc_server_remove_clients_channels(SilcServer server,
30 SilcSocketConnection sock,
31 SilcClientEntry client,
32 SilcHashTable channels)
34 SilcChannelEntry channel;
35 SilcChannelClientEntry chl;
36 SilcHashTableList htl;
39 SILC_LOG_DEBUG(("Start"));
41 if (!client || !client->id)
44 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
46 /* Remove the client from all channels. The client is removed from
47 the channels' user list. */
48 silc_hash_table_list(client->channels, &htl);
49 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
50 channel = chl->channel;
52 /* Remove channel from client's channel list */
53 silc_hash_table_del(client->channels, channel);
55 /* Remove channel if there is no users anymore */
56 if (server->server_type == SILC_ROUTER &&
57 silc_hash_table_count(channel->user_list) < 2) {
59 if (silc_hash_table_find(channels, channel, NULL, NULL))
60 silc_hash_table_del(channels, channel);
63 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
65 if (silc_idlist_del_channel(server->local_list, channel))
66 server->stat.my_channels--;
68 silc_idlist_del_channel(server->global_list, channel);
72 /* Remove client from channel's client list */
73 silc_hash_table_del(channel->user_list, chl->client);
74 channel->user_count--;
76 /* If there is no global users on the channel anymore mark the channel
77 as local channel. Do not check if the removed client is local client. */
78 if (server->server_type != SILC_ROUTER && channel->global_users &&
79 chl->client->router && !silc_server_channel_has_global(channel))
80 channel->global_users = FALSE;
83 server->stat.my_chanclients--;
85 /* If there is not at least one local user on the channel then we don't
86 need the channel entry anymore, we can remove it safely. */
87 if (server->server_type != SILC_ROUTER &&
88 !silc_server_channel_has_local(channel)) {
90 if (silc_hash_table_find(channels, channel, NULL, NULL))
91 silc_hash_table_del(channels, channel);
94 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
96 if (channel->founder_key) {
97 /* The founder auth data exists, do not remove the channel entry */
98 SilcChannelClientEntry chl2;
99 SilcHashTableList htl2;
101 channel->disabled = TRUE;
103 silc_hash_table_list(channel->user_list, &htl2);
104 while (silc_hash_table_get(&htl2, NULL, (void **)&chl2)) {
105 silc_hash_table_del(chl2->client->channels, channel);
106 silc_hash_table_del(channel->user_list, chl2->client);
107 channel->user_count--;
110 silc_hash_table_list_reset(&htl2);
114 /* Remove the channel entry */
115 if (silc_idlist_del_channel(server->local_list, channel))
116 server->stat.my_channels--;
118 silc_idlist_del_channel(server->global_list, channel);
122 /* Add the channel to the the channels list to regenerate the
124 if (!silc_hash_table_find(channels, channel, NULL, NULL))
125 silc_hash_table_add(channels, channel, channel);
127 silc_hash_table_list_reset(&htl);
129 silc_buffer_free(clidp);
132 /* This function is used to remove all client entries by the server `entry'.
133 This is called when the connection is lost to the server. In this case
134 we must invalidate all the client entries owned by the server `entry'.
135 If the `server_signoff' is TRUE then the SERVER_SIGNOFF notify is
136 distributed to our local clients. */
138 bool silc_server_remove_clients_by_server(SilcServer server,
139 SilcServerEntry entry,
142 SilcIDCacheList list = NULL;
143 SilcIDCacheEntry id_cache = NULL;
144 SilcClientEntry client = NULL;
146 SilcClientEntry *clients = NULL;
147 SilcUInt32 clients_c = 0;
148 unsigned char **argv = NULL;
149 SilcUInt32 *argv_lens = NULL, *argv_types = NULL, argc = 0;
150 SilcHashTableList htl;
151 SilcChannelEntry channel;
152 SilcHashTable channels;
155 SILC_LOG_DEBUG(("Start"));
157 /* Allocate the hash table that holds the channels that require
158 channel key re-generation after we've removed this server's clients
159 from the channels. */
160 channels = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL, NULL,
163 if (server_signoff) {
164 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
165 argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
166 argv_lens = silc_realloc(argv_lens, sizeof(*argv_lens) * (argc + 1));
167 argv_types = silc_realloc(argv_types, sizeof(*argv_types) * (argc + 1));
168 argv[argc] = silc_calloc(idp->len, sizeof(*argv[0]));
169 memcpy(argv[argc], idp->data, idp->len);
170 argv_lens[argc] = idp->len;
171 argv_types[argc] = argc + 1;
173 silc_buffer_free(idp);
176 if (silc_idcache_get_all(server->local_list->clients, &list)) {
178 if (silc_idcache_list_first(list, &id_cache)) {
180 client = (SilcClientEntry)id_cache->context;
181 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
182 if (!silc_idcache_list_next(list, &id_cache))
188 if (client->router != entry) {
189 if (server_signoff) {
190 clients = silc_realloc(clients,
191 sizeof(*clients) * (clients_c + 1));
192 clients[clients_c] = client;
196 if (!silc_idcache_list_next(list, &id_cache))
202 if (server_signoff) {
203 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
204 argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
205 argv_lens = silc_realloc(argv_lens, sizeof(*argv_lens) *
207 argv_types = silc_realloc(argv_types, sizeof(*argv_types) *
209 argv[argc] = silc_calloc(idp->len, sizeof(*argv[0]));
210 memcpy(argv[argc], idp->data, idp->len);
211 argv_lens[argc] = idp->len;
212 argv_types[argc] = argc + 1;
214 silc_buffer_free(idp);
217 /* Update statistics */
218 server->stat.clients--;
219 if (server->stat.cell_clients)
220 server->stat.cell_clients--;
221 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
222 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
224 /* Remove the client entry */
225 silc_server_remove_clients_channels(server, NULL, client, channels);
226 if (!server_signoff) {
227 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
228 id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
230 silc_idlist_del_client(server->local_list, client);
233 if (!silc_idcache_list_next(list, &id_cache))
237 silc_idcache_list_free(list);
240 if (silc_idcache_get_all(server->global_list->clients, &list)) {
242 if (silc_idcache_list_first(list, &id_cache)) {
244 client = (SilcClientEntry)id_cache->context;
245 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
246 if (!silc_idcache_list_next(list, &id_cache))
252 if (client->router != entry) {
253 if (server_signoff && client->connection) {
254 clients = silc_realloc(clients,
255 sizeof(*clients) * (clients_c + 1));
256 clients[clients_c] = client;
260 if (!silc_idcache_list_next(list, &id_cache))
266 if (server_signoff) {
267 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
268 argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
269 argv_lens = silc_realloc(argv_lens, sizeof(*argv_lens) *
271 argv_types = silc_realloc(argv_types, sizeof(*argv_types) *
273 argv[argc] = silc_calloc(idp->len, sizeof(*argv[0]));
274 memcpy(argv[argc], idp->data, idp->len);
275 argv_lens[argc] = idp->len;
276 argv_types[argc] = argc + 1;
278 silc_buffer_free(idp);
281 /* Update statistics */
282 server->stat.clients--;
283 if (server->stat.cell_clients)
284 server->stat.cell_clients--;
285 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
286 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
288 /* Remove the client entry */
289 silc_server_remove_clients_channels(server, NULL, client, channels);
290 if (!server_signoff) {
291 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
292 id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
294 silc_idlist_del_client(server->global_list, client);
297 if (!silc_idcache_list_next(list, &id_cache))
301 silc_idcache_list_free(list);
304 /* Send the SERVER_SIGNOFF notify */
305 if (server_signoff) {
306 SilcBuffer args, not;
308 /* Send SERVER_SIGNOFF notify to our primary router */
309 if (!server->standalone && server->router &&
310 server->router != entry) {
311 args = silc_argument_payload_encode(1, argv, argv_lens,
313 silc_server_send_notify_args(server,
314 server->router->connection,
315 server->server_type == SILC_SERVER ?
317 SILC_NOTIFY_TYPE_SERVER_SIGNOFF,
319 silc_buffer_free(args);
322 /* Send to local clients. We also send the list of client ID's that
323 is to be removed for those servers that would like to use that list. */
324 args = silc_argument_payload_encode(argc, argv, argv_lens,
326 not = silc_notify_payload_encode_args(SILC_NOTIFY_TYPE_SERVER_SIGNOFF,
328 silc_server_packet_send_clients(server, clients, clients_c,
329 SILC_PACKET_NOTIFY, 0, FALSE,
330 not->data, not->len, FALSE);
333 silc_buffer_free(args);
334 silc_buffer_free(not);
335 for (i = 0; i < argc; i++)
338 silc_free(argv_lens);
339 silc_free(argv_types);
342 /* We must now re-generate the channel key for all channels that had
343 this server's client(s) on the channel. As they left the channel we
344 must re-generate the channel key. */
345 silc_hash_table_list(channels, &htl);
346 while (silc_hash_table_get(&htl, NULL, (void **)&channel)) {
347 if (!silc_server_create_channel_key(server, channel, 0)) {
348 silc_hash_table_list_reset(&htl);
349 silc_hash_table_free(channels);
353 /* Do not send the channel key if private channel key mode is set */
354 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY)
357 silc_server_send_channel_key(server, NULL, channel,
358 server->server_type == SILC_ROUTER ?
359 FALSE : !server->standalone);
361 silc_hash_table_list_reset(&htl);
362 silc_hash_table_free(channels);
367 static SilcServerEntry
368 silc_server_update_clients_by_real_server(SilcServer server,
369 SilcServerEntry from,
370 SilcClientEntry client,
372 SilcIDCacheEntry client_cache)
374 SilcServerEntry server_entry;
375 SilcIDCacheEntry id_cache = NULL;
376 SilcIDCacheList list;
378 if (!silc_idcache_get_all(server->local_list->servers, &list))
381 if (silc_idcache_list_first(list, &id_cache)) {
383 server_entry = (SilcServerEntry)id_cache->context;
384 if (server_entry != from &&
385 SILC_ID_COMPARE(server_entry->id, client->id,
386 client->id->ip.data_len)) {
387 SILC_LOG_DEBUG(("Found (local) %s",
388 silc_id_render(server_entry->id, SILC_ID_SERVER)));
390 if (!server_entry->data.send_key && server_entry->router) {
391 SILC_LOG_DEBUG(("Server not locally connected, use its router"));
392 /* If the client is not marked as local then move it to local list
393 since the server is local. */
395 SILC_LOG_DEBUG(("Moving client to local list"));
396 silc_idcache_add(server->local_list->clients, client_cache->name,
397 client_cache->id, client_cache->context,
398 client_cache->expire, NULL);
399 silc_idcache_del_by_context(server->global_list->clients, client);
401 server_entry = server_entry->router;
403 /* If the client is not marked as local then move it to local list
404 since the server is local. */
405 if (server_entry->server_type != SILC_BACKUP_ROUTER && !local) {
406 SILC_LOG_DEBUG(("Moving client to local list"));
407 silc_idcache_add(server->local_list->clients, client_cache->name,
408 client_cache->id, client_cache->context,
409 client_cache->expire, NULL);
410 silc_idcache_del_by_context(server->global_list->clients, client);
414 silc_idcache_list_free(list);
418 if (!silc_idcache_list_next(list, &id_cache))
423 silc_idcache_list_free(list);
425 if (!silc_idcache_get_all(server->global_list->servers, &list))
428 if (silc_idcache_list_first(list, &id_cache)) {
430 server_entry = (SilcServerEntry)id_cache->context;
431 if (server_entry != from &&
432 SILC_ID_COMPARE(server_entry->id, client->id,
433 client->id->ip.data_len)) {
434 SILC_LOG_DEBUG(("Found (global) %s",
435 silc_id_render(server_entry->id, SILC_ID_SERVER)));
437 if (!server_entry->data.send_key && server_entry->router) {
438 SILC_LOG_DEBUG(("Server not locally connected, use its router"));
439 /* If the client is marked as local then move it to global list
440 since the server is global. */
442 SILC_LOG_DEBUG(("Moving client to global list"));
443 silc_idcache_add(server->global_list->clients, client_cache->name,
444 client_cache->id, client_cache->context,
445 client_cache->expire, NULL);
446 silc_idcache_del_by_context(server->local_list->clients, client);
448 server_entry = server_entry->router;
450 /* If the client is marked as local then move it to global list
451 since the server is global. */
452 if (server_entry->server_type != SILC_BACKUP_ROUTER && local) {
453 SILC_LOG_DEBUG(("Moving client to global list"));
454 silc_idcache_add(server->global_list->clients, client_cache->name,
455 client_cache->id, client_cache->context,
456 client_cache->expire, NULL);
457 silc_idcache_del_by_context(server->local_list->clients, client);
461 silc_idcache_list_free(list);
465 if (!silc_idcache_list_next(list, &id_cache))
470 silc_idcache_list_free(list);
475 /* Updates the clients that are originated from the `from' to be originated
476 from the `to'. If the `resolve_real_server' is TRUE then this will
477 attempt to figure out which clients really are originated from the
478 `from' and which are originated from a server that we have connection
479 to, when we've acting as backup router. If it is FALSE the `to' will
480 be the new source. This function also removes the clients that are
481 *really* originated from `from' if `remove_from' is TRUE. These are
482 clients that the `from' owns, and not just clients that are behind
485 void silc_server_update_clients_by_server(SilcServer server,
486 SilcServerEntry from,
488 bool resolve_real_server,
491 SilcIDCacheList list = NULL;
492 SilcIDCacheEntry id_cache = NULL;
493 SilcClientEntry client = NULL;
496 SILC_LOG_DEBUG(("Start"));
498 SILC_LOG_DEBUG(("Updating %s", silc_id_render(from->id,
500 SILC_LOG_DEBUG(("to %s", silc_id_render(to->id,
505 if (silc_idcache_get_all(server->global_list->clients, &list)) {
506 if (silc_idcache_list_first(list, &id_cache)) {
508 client = (SilcClientEntry)id_cache->context;
509 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
510 if (!silc_idcache_list_next(list, &id_cache))
516 SILC_LOG_DEBUG(("Client (global) %s",
517 silc_id_render(client->id, SILC_ID_CLIENT)));
519 SILC_LOG_DEBUG(("Client->router (global) %s",
520 silc_id_render(client->router->id, SILC_ID_SERVER)));
522 if (client->router == from) {
523 /* Skip clients that are *really* owned by the `from' */
524 if (remove_from && SILC_ID_COMPARE(from->id, client->id,
525 client->id->ip.data_len)) {
526 SILC_LOG_DEBUG(("Found really owned client, skip it"));
527 if (!silc_idcache_list_next(list, &id_cache))
533 if (resolve_real_server) {
535 silc_server_update_clients_by_real_server(server, from, client,
544 if (!silc_idcache_list_next(list, &id_cache))
548 silc_idcache_list_free(list);
552 if (silc_idcache_get_all(server->local_list->clients, &list)) {
553 if (silc_idcache_list_first(list, &id_cache)) {
555 client = (SilcClientEntry)id_cache->context;
556 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
557 if (!silc_idcache_list_next(list, &id_cache))
563 SILC_LOG_DEBUG(("Client (local) %s",
564 silc_id_render(client->id, SILC_ID_CLIENT)));
566 SILC_LOG_DEBUG(("Client->router (local) %s",
567 silc_id_render(client->router->id, SILC_ID_SERVER)));
569 if (client->router == from) {
570 /* Skip clients that are *really* owned by the `from' */
571 if (remove_from && SILC_ID_COMPARE(from->id, client->id,
572 client->id->ip.data_len)) {
573 SILC_LOG_DEBUG(("Found really owned client, skip it"));
574 if (!silc_idcache_list_next(list, &id_cache))
580 if (resolve_real_server) {
582 silc_server_update_clients_by_real_server(server, from, client,
585 client->router = from; /* on local list put old from */
591 if (!silc_idcache_list_next(list, &id_cache))
595 silc_idcache_list_free(list);
599 /* Now remove the clients that are still marked as orignated from the
600 `from'. These are the clients that really was owned by the `from' and
601 not just exist behind the `from'. */
602 silc_server_remove_clients_by_server(server, from, TRUE);
605 /* Updates servers that are from `from' to be originated from `to'. This
606 will also update the server's connection to `to's connection. */
608 void silc_server_update_servers_by_server(SilcServer server,
609 SilcServerEntry from,
612 SilcIDCacheList list = NULL;
613 SilcIDCacheEntry id_cache = NULL;
614 SilcServerEntry server_entry = NULL;
616 SILC_LOG_DEBUG(("Start"));
618 if (silc_idcache_get_all(server->local_list->servers, &list)) {
619 if (silc_idcache_list_first(list, &id_cache)) {
621 server_entry = (SilcServerEntry)id_cache->context;
622 if (server_entry->router == from) {
623 server_entry->router = to;
624 server_entry->connection = to->connection;
626 if (!silc_idcache_list_next(list, &id_cache))
630 silc_idcache_list_free(list);
633 if (silc_idcache_get_all(server->global_list->servers, &list)) {
634 if (silc_idcache_list_first(list, &id_cache)) {
636 server_entry = (SilcServerEntry)id_cache->context;
637 if (server_entry->router == from) {
638 server_entry->router = to;
639 server_entry->connection = to->connection;
641 if (!silc_idcache_list_next(list, &id_cache))
645 silc_idcache_list_free(list);
649 /* Removes channels that are from `from. */
651 void silc_server_remove_channels_by_server(SilcServer server,
652 SilcServerEntry from)
654 SilcIDCacheList list = NULL;
655 SilcIDCacheEntry id_cache = NULL;
656 SilcChannelEntry channel = NULL;
658 SILC_LOG_DEBUG(("Start"));
660 if (silc_idcache_get_all(server->global_list->channels, &list)) {
661 if (silc_idcache_list_first(list, &id_cache)) {
663 channel = (SilcChannelEntry)id_cache->context;
664 if (channel->router == from)
665 silc_idlist_del_channel(server->global_list, channel);
666 if (!silc_idcache_list_next(list, &id_cache))
670 silc_idcache_list_free(list);
674 /* Updates channels that are from `from' to be originated from `to'. */
676 void silc_server_update_channels_by_server(SilcServer server,
677 SilcServerEntry from,
680 SilcIDCacheList list = NULL;
681 SilcIDCacheEntry id_cache = NULL;
682 SilcChannelEntry channel = NULL;
684 SILC_LOG_DEBUG(("Start"));
686 if (silc_idcache_get_all(server->global_list->channels, &list)) {
687 if (silc_idcache_list_first(list, &id_cache)) {
689 channel = (SilcChannelEntry)id_cache->context;
690 if (channel->router == from)
691 channel->router = to;
692 if (!silc_idcache_list_next(list, &id_cache))
696 silc_idcache_list_free(list);
700 /* Checks whether given channel has global users. If it does this returns
701 TRUE and FALSE if there is only locally connected clients on the channel. */
703 bool silc_server_channel_has_global(SilcChannelEntry channel)
705 SilcChannelClientEntry chl;
706 SilcHashTableList htl;
708 silc_hash_table_list(channel->user_list, &htl);
709 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
710 if (chl->client->router) {
711 silc_hash_table_list_reset(&htl);
715 silc_hash_table_list_reset(&htl);
720 /* Checks whether given channel has locally connected users. If it does this
721 returns TRUE and FALSE if there is not one locally connected client. */
723 bool silc_server_channel_has_local(SilcChannelEntry channel)
725 SilcChannelClientEntry chl;
726 SilcHashTableList htl;
728 silc_hash_table_list(channel->user_list, &htl);
729 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
730 if (!chl->client->router) {
731 silc_hash_table_list_reset(&htl);
735 silc_hash_table_list_reset(&htl);
740 /* Returns TRUE if the given client is on the channel. FALSE if not.
741 This works because we assure that the user list on the channel is
742 always in up to date thus we can only check the channel list from
743 `client' which is faster than checking the user list from `channel'. */
745 bool silc_server_client_on_channel(SilcClientEntry client,
746 SilcChannelEntry channel,
747 SilcChannelClientEntry *chl)
749 if (!client || !channel)
752 return silc_hash_table_find(client->channels, channel, NULL,
756 /* Checks string for bad characters and returns TRUE if they are found. */
758 bool silc_server_name_bad_chars(const char *name, SilcUInt32 name_len)
762 for (i = 0; i < name_len; i++) {
763 if (!isascii(name[i]))
765 if (name[i] <= 32) return TRUE;
766 if (name[i] == ' ') return TRUE;
767 if (name[i] == '*') return TRUE;
768 if (name[i] == '?') return TRUE;
769 if (name[i] == ',') return TRUE;
775 /* Modifies the `name' if it includes bad characters and returns new
776 allocated name that does not include bad characters. */
778 char *silc_server_name_modify_bad(const char *name, SilcUInt32 name_len)
781 char *newname = strdup(name);
783 for (i = 0; i < name_len; i++) {
784 if (!isascii(newname[i])) newname[i] = '_';
785 if (newname[i] <= 32) newname[i] = '_';
786 if (newname[i] == ' ') newname[i] = '_';
787 if (newname[i] == '*') newname[i] = '_';
788 if (newname[i] == '?') newname[i] = '_';
789 if (newname[i] == ',') newname[i] = '_';
795 /* Find number of sockets by IP address indicated by `ip'. Returns 0 if
796 socket connections with the IP address does not exist. */
798 SilcUInt32 silc_server_num_sockets_by_ip(SilcServer server, const char *ip,
803 for (i = 0, count = 0; i < server->config->param.connections_max; i++) {
804 if (server->sockets[i] && !strcmp(server->sockets[i]->ip, ip) &&
805 server->sockets[i]->type == type)
812 /* Find number of sockets by IP address indicated by remote host, indicatd
813 by `ip' or `hostname', `port', and `type'. Returns 0 if socket connections
814 does not exist. If `ip' is provided then `hostname' is ignored. */
816 SilcUInt32 silc_server_num_sockets_by_remote(SilcServer server,
818 const char *hostname,
824 if (!ip && !hostname)
827 for (i = 0, count = 0; i < server->config->param.connections_max; i++) {
828 if (server->sockets[i] &&
829 ((ip && !strcmp(server->sockets[i]->ip, ip)) ||
830 (hostname && !strcmp(server->sockets[i]->hostname, hostname))) &&
831 server->sockets[i]->port == port &&
832 server->sockets[i]->type == type)
839 /* Finds locally cached public key by the public key received in the SKE.
840 If we have it locally cached then we trust it and will use it in the
841 authentication protocol. Returns the locally cached public key or NULL
842 if we do not find the public key. */
844 SilcPublicKey silc_server_find_public_key(SilcServer server,
845 SilcHashTable local_public_keys,
846 SilcPublicKey remote_public_key)
848 SilcPublicKey cached_key;
850 SILC_LOG_DEBUG(("Find remote public key (%d keys in local cache)",
851 silc_hash_table_count(local_public_keys)));
853 if (!silc_hash_table_find_ext(local_public_keys, remote_public_key,
854 (void **)&cached_key, NULL,
855 silc_hash_public_key, NULL,
856 silc_hash_public_key_compare, NULL)) {
857 SILC_LOG_ERROR(("Public key not found"));
861 SILC_LOG_DEBUG(("Found public key"));
866 /* This returns the first public key from the table of public keys. This
867 is used only in cases where single public key exists in the table and
868 we want to get a pointer to it. For public key tables that has multiple
869 keys in it the silc_server_find_public_key must be used. */
871 SilcPublicKey silc_server_get_public_key(SilcServer server,
872 SilcHashTable local_public_keys)
874 SilcPublicKey cached_key;
875 SilcHashTableList htl;
877 SILC_LOG_DEBUG(("Start"));
879 assert(silc_hash_table_count(local_public_keys) < 2);
881 silc_hash_table_list(local_public_keys, &htl);
882 if (!silc_hash_table_get(&htl, NULL, (void **)&cached_key))
884 silc_hash_table_list_reset(&htl);
889 /* Check whether the connection `sock' is allowed to connect to us. This
890 checks for example whether there is too much connections for this host,
891 and required version for the host etc. */
893 bool silc_server_connection_allowed(SilcServer server,
894 SilcSocketConnection sock,
896 SilcServerConfigConnParams *global,
897 SilcServerConfigConnParams *params,
900 SilcUInt32 conn_number = (type == SILC_SOCKET_TYPE_CLIENT ?
901 server->stat.my_clients :
902 type == SILC_SOCKET_TYPE_SERVER ?
903 server->stat.my_servers :
904 server->stat.my_routers);
905 SilcUInt32 num_sockets, max_hosts, max_per_host;
906 SilcUInt32 r_protocol_version, l_protocol_version;
907 SilcUInt32 r_software_version, l_software_version;
908 char *r_vendor_version = NULL, *l_vendor_version;
913 silc_version_to_num(params && params->version_protocol ?
914 params->version_protocol :
915 global->version_protocol);
917 silc_version_to_num(params && params->version_software ?
918 params->version_software :
919 global->version_software);
920 l_vendor_version = (params && params->version_software_vendor ?
921 params->version_software_vendor :
922 global->version_software_vendor);
924 if (ske && silc_ske_parse_version(ske, &r_protocol_version, NULL,
925 &r_software_version, NULL,
926 &r_vendor_version)) {
927 sock->version = r_protocol_version;
929 /* Match protocol version */
930 if (l_protocol_version && r_protocol_version &&
931 r_protocol_version < l_protocol_version) {
932 SILC_LOG_INFO(("Connection %s (%s) is too old version",
933 sock->hostname, sock->ip));
934 silc_server_disconnect_remote(server, sock,
935 "Server closed connection: "
936 "You support too old protocol version");
940 /* Math software version */
941 if (l_software_version && r_software_version &&
942 r_software_version < l_software_version) {
943 SILC_LOG_INFO(("Connection %s (%s) is too old version",
944 sock->hostname, sock->ip));
945 silc_server_disconnect_remote(server, sock,
946 "Server closed connection: "
947 "You support too old software version");
951 /* Regex match vendor version */
952 if (l_vendor_version && r_vendor_version &&
953 !silc_string_match(l_vendor_version, r_vendor_version)) {
954 SILC_LOG_INFO(("Connection %s (%s) is unsupported version",
955 sock->hostname, sock->ip));
956 silc_server_disconnect_remote(server, sock,
957 "Server closed connection: "
958 "Your software is not supported");
962 silc_free(r_vendor_version);
964 /* Check for maximum connections limit */
966 num_sockets = silc_server_num_sockets_by_ip(server, sock->ip, type);
967 max_hosts = (params ? params->connections_max : global->connections_max);
968 max_per_host = (params ? params->connections_max_per_host :
969 global->connections_max_per_host);
971 if (max_hosts && conn_number >= max_hosts) {
972 SILC_LOG_INFO(("Server is full, closing %s (%s) connection",
973 sock->hostname, sock->ip));
974 silc_server_disconnect_remote(server, sock,
975 "Server closed connection: "
976 "Server is full, try again later");
980 if (num_sockets >= max_per_host) {
981 SILC_LOG_INFO(("Too many connections from %s (%s), closing connection",
982 sock->hostname, sock->ip));
983 silc_server_disconnect_remote(server, sock,
984 "Server closed connection: "
985 "Too many connections from your host");
992 /* Checks that client has rights to add or remove channel modes. If any
993 of the checks fails FALSE is returned. */
995 bool silc_server_check_cmode_rights(SilcServer server,
996 SilcChannelEntry channel,
997 SilcChannelClientEntry client,
1000 bool is_op = client->mode & SILC_CHANNEL_UMODE_CHANOP;
1001 bool is_fo = client->mode & SILC_CHANNEL_UMODE_CHANFO;
1003 /* Check whether has rights to change anything */
1004 if (!is_op && !is_fo)
1007 /* Check whether has rights to change everything */
1011 /* We know that client is channel operator, check that they are not
1012 changing anything that requires channel founder rights. Rest of the
1013 modes are available automatically for channel operator. */
1015 if (mode & SILC_CHANNEL_MODE_PRIVKEY) {
1016 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY))
1017 if (is_op && !is_fo)
1020 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
1021 if (is_op && !is_fo)
1026 if (mode & SILC_CHANNEL_MODE_PASSPHRASE) {
1027 if (!(channel->mode & SILC_CHANNEL_MODE_PASSPHRASE))
1028 if (is_op && !is_fo)
1031 if (channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
1032 if (is_op && !is_fo)
1037 if (mode & SILC_CHANNEL_MODE_CIPHER) {
1038 if (!(channel->mode & SILC_CHANNEL_MODE_CIPHER))
1039 if (is_op && !is_fo)
1042 if (channel->mode & SILC_CHANNEL_MODE_CIPHER) {
1043 if (is_op && !is_fo)
1048 if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
1049 if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH))
1050 if (is_op && !is_fo)
1053 if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
1054 if (is_op && !is_fo)
1059 if (mode & SILC_CHANNEL_MODE_SILENCE_USERS) {
1060 if (!(channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS))
1061 if (is_op && !is_fo)
1064 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS) {
1065 if (is_op && !is_fo)
1070 if (mode & SILC_CHANNEL_MODE_SILENCE_OPERS) {
1071 if (!(channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS))
1072 if (is_op && !is_fo)
1075 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS) {
1076 if (is_op && !is_fo)
1084 /* Check that the client has rights to change its user mode. Returns
1085 FALSE if setting some mode is not allowed. */
1087 bool silc_server_check_umode_rights(SilcServer server,
1088 SilcClientEntry client,
1091 bool server_op = FALSE, router_op = FALSE;
1093 if (mode & SILC_UMODE_SERVER_OPERATOR) {
1094 /* Cannot set server operator mode (must use OPER command) */
1095 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR))
1098 /* Remove the server operator rights */
1099 if (client->mode & SILC_UMODE_SERVER_OPERATOR)
1103 if (mode & SILC_UMODE_ROUTER_OPERATOR) {
1104 /* Cannot set router operator mode (must use SILCOPER command) */
1105 if (!(client->mode & SILC_UMODE_ROUTER_OPERATOR))
1108 /* Remove the router operator rights */
1109 if (client->mode & SILC_UMODE_ROUTER_OPERATOR)
1114 SILC_UMODE_STATS_UPDATE(server, SILC_UMODE_SERVER_OPERATOR);
1116 SILC_UMODE_STATS_UPDATE(router, SILC_UMODE_ROUTER_OPERATOR);