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. */
31 static void silc_server_remove_clients_channels(SilcServer server,
32 SilcSocketConnection sock,
33 SilcClientEntry client,
34 SilcHashTable channels)
36 SilcChannelEntry channel;
37 SilcChannelClientEntry chl;
38 SilcHashTableList htl;
41 SILC_LOG_DEBUG(("Start"));
43 if (!client || !client->id)
46 clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
48 /* Remove the client from all channels. The client is removed from
49 the channels' user list. */
50 silc_hash_table_list(client->channels, &htl);
51 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
52 channel = chl->channel;
54 /* Remove channel if this is last client leaving the channel, unless
55 the channel is permanent. */
56 if (server->server_type == SILC_ROUTER &&
57 silc_hash_table_count(channel->user_list) < 2) {
58 if (silc_hash_table_find(channels, channel, NULL, NULL))
59 silc_hash_table_del(channels, channel);
60 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
61 silc_server_channel_delete(server, channel);
65 silc_hash_table_del(client->channels, channel);
66 silc_hash_table_del(channel->user_list, chl->client);
67 channel->user_count--;
69 /* If there is no global users on the channel anymore mark the channel
70 as local channel. Do not check if the removed client is local client. */
71 if (server->server_type != SILC_ROUTER && channel->global_users &&
72 chl->client->router && !silc_server_channel_has_global(channel))
73 channel->global_users = FALSE;
76 server->stat.my_chanclients--;
78 /* If there is not at least one local user on the channel then we don't
79 need the channel entry anymore, we can remove it safely, unless the
80 channel is permanent channel */
81 if (server->server_type != SILC_ROUTER &&
82 !silc_server_channel_has_local(channel)) {
83 if (silc_hash_table_find(channels, channel, NULL, NULL))
84 silc_hash_table_del(channels, channel);
85 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
86 silc_server_channel_delete(server, channel);
90 /* Add the channel to the the channels list to regenerate the
92 if (!silc_hash_table_find(channels, channel, NULL, NULL))
93 silc_hash_table_add(channels, channel, channel);
95 silc_hash_table_list_reset(&htl);
96 silc_buffer_free(clidp);
99 /* This function is used to remove all client entries by the server `entry'.
100 This is called when the connection is lost to the server. In this case
101 we must invalidate all the client entries owned by the server `entry'.
102 If the `server_signoff' is TRUE then the SERVER_SIGNOFF notify is
103 distributed to our local clients. */
105 bool silc_server_remove_clients_by_server(SilcServer server,
106 SilcServerEntry entry,
109 SilcIDCacheList list = NULL;
110 SilcIDCacheEntry id_cache = NULL;
111 SilcClientEntry client = NULL;
113 SilcClientEntry *clients = NULL;
114 SilcUInt32 clients_c = 0;
115 unsigned char **argv = NULL;
116 SilcUInt32 *argv_lens = NULL, *argv_types = NULL, argc = 0;
117 SilcHashTableList htl;
118 SilcChannelEntry channel;
119 SilcHashTable channels;
122 SILC_LOG_DEBUG(("Start"));
124 /* Allocate the hash table that holds the channels that require
125 channel key re-generation after we've removed this server's clients
126 from the channels. */
127 channels = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL, NULL,
130 if (server_signoff) {
131 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
132 argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
133 argv_lens = silc_realloc(argv_lens, sizeof(*argv_lens) * (argc + 1));
134 argv_types = silc_realloc(argv_types, sizeof(*argv_types) * (argc + 1));
135 argv[argc] = silc_calloc(idp->len, sizeof(*argv[0]));
136 memcpy(argv[argc], idp->data, idp->len);
137 argv_lens[argc] = idp->len;
138 argv_types[argc] = argc + 1;
140 silc_buffer_free(idp);
143 if (silc_idcache_get_all(server->local_list->clients, &list)) {
145 if (silc_idcache_list_first(list, &id_cache)) {
147 client = (SilcClientEntry)id_cache->context;
148 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
149 if (!silc_idcache_list_next(list, &id_cache))
155 if (client->router != entry) {
156 if (server_signoff) {
157 clients = silc_realloc(clients,
158 sizeof(*clients) * (clients_c + 1));
159 clients[clients_c] = client;
163 if (!silc_idcache_list_next(list, &id_cache))
169 if (server_signoff) {
170 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
171 argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
172 argv_lens = silc_realloc(argv_lens, sizeof(*argv_lens) *
174 argv_types = silc_realloc(argv_types, sizeof(*argv_types) *
176 argv[argc] = silc_calloc(idp->len, sizeof(*argv[0]));
177 memcpy(argv[argc], idp->data, idp->len);
178 argv_lens[argc] = idp->len;
179 argv_types[argc] = argc + 1;
181 silc_buffer_free(idp);
184 /* Update statistics */
185 server->stat.clients--;
186 if (server->stat.cell_clients)
187 server->stat.cell_clients--;
188 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
189 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
191 /* Remove the client entry */
192 silc_server_remove_clients_channels(server, NULL, client, channels);
193 if (!server_signoff) {
194 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
195 id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
197 silc_idlist_del_client(server->local_list, client);
199 /* Remove this client from watcher list if it is */
200 silc_server_del_from_watcher_list(server, client);
203 if (!silc_idcache_list_next(list, &id_cache))
207 silc_idcache_list_free(list);
210 if (silc_idcache_get_all(server->global_list->clients, &list)) {
212 if (silc_idcache_list_first(list, &id_cache)) {
214 client = (SilcClientEntry)id_cache->context;
215 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
216 if (!silc_idcache_list_next(list, &id_cache))
222 if (client->router != entry) {
223 if (server_signoff && client->connection) {
224 clients = silc_realloc(clients,
225 sizeof(*clients) * (clients_c + 1));
226 clients[clients_c] = client;
230 if (!silc_idcache_list_next(list, &id_cache))
236 if (server_signoff) {
237 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
238 argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
239 argv_lens = silc_realloc(argv_lens, sizeof(*argv_lens) *
241 argv_types = silc_realloc(argv_types, sizeof(*argv_types) *
243 argv[argc] = silc_calloc(idp->len, sizeof(*argv[0]));
244 memcpy(argv[argc], idp->data, idp->len);
245 argv_lens[argc] = idp->len;
246 argv_types[argc] = argc + 1;
248 silc_buffer_free(idp);
251 /* Update statistics */
252 server->stat.clients--;
253 if (server->stat.cell_clients)
254 server->stat.cell_clients--;
255 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
256 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
258 /* Remove the client entry */
259 silc_server_remove_clients_channels(server, NULL, client, channels);
260 if (!server_signoff) {
261 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
262 id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
264 silc_idlist_del_client(server->global_list, client);
267 if (!silc_idcache_list_next(list, &id_cache))
271 silc_idcache_list_free(list);
274 /* Send the SERVER_SIGNOFF notify */
275 if (server_signoff) {
276 SilcBuffer args, not;
278 /* Send SERVER_SIGNOFF notify to our primary router */
279 if (!server->standalone && server->router &&
280 server->router != entry) {
281 args = silc_argument_payload_encode(1, argv, argv_lens,
283 silc_server_send_notify_args(server,
284 server->router->connection,
285 server->server_type == SILC_SERVER ?
287 SILC_NOTIFY_TYPE_SERVER_SIGNOFF,
289 silc_buffer_free(args);
292 /* Send to local clients. We also send the list of client ID's that
293 is to be removed for those servers that would like to use that list. */
294 args = silc_argument_payload_encode(argc, argv, argv_lens,
296 not = silc_notify_payload_encode_args(SILC_NOTIFY_TYPE_SERVER_SIGNOFF,
298 silc_server_packet_send_clients(server, clients, clients_c,
299 SILC_PACKET_NOTIFY, 0, FALSE,
300 not->data, not->len, FALSE);
303 silc_buffer_free(args);
304 silc_buffer_free(not);
305 for (i = 0; i < argc; i++)
308 silc_free(argv_lens);
309 silc_free(argv_types);
312 /* We must now re-generate the channel key for all channels that had
313 this server's client(s) on the channel. As they left the channel we
314 must re-generate the channel key. */
315 silc_hash_table_list(channels, &htl);
316 while (silc_hash_table_get(&htl, NULL, (void **)&channel)) {
317 if (!silc_server_create_channel_key(server, channel, 0)) {
318 silc_hash_table_list_reset(&htl);
319 silc_hash_table_free(channels);
323 /* Do not send the channel key if private channel key mode is set */
324 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY)
327 silc_server_send_channel_key(server, NULL, channel,
328 server->server_type == SILC_ROUTER ?
329 FALSE : !server->standalone);
331 silc_hash_table_list_reset(&htl);
332 silc_hash_table_free(channels);
337 static SilcServerEntry
338 silc_server_update_clients_by_real_server(SilcServer server,
339 SilcServerEntry from,
340 SilcClientEntry client,
342 SilcIDCacheEntry client_cache)
344 SilcServerEntry server_entry;
345 SilcIDCacheEntry id_cache = NULL;
346 SilcIDCacheList list;
348 if (!silc_idcache_get_all(server->local_list->servers, &list))
351 if (silc_idcache_list_first(list, &id_cache)) {
353 server_entry = (SilcServerEntry)id_cache->context;
354 if (server_entry != from &&
355 SILC_ID_COMPARE(server_entry->id, client->id,
356 client->id->ip.data_len)) {
357 SILC_LOG_DEBUG(("Found (local) %s",
358 silc_id_render(server_entry->id, SILC_ID_SERVER)));
360 if (!server_entry->data.send_key && server_entry->router) {
361 SILC_LOG_DEBUG(("Server not locally connected, use its router"));
362 /* If the client is not marked as local then move it to local list
363 since the server is local. */
365 SILC_LOG_DEBUG(("Moving client to local list"));
366 silc_idcache_add(server->local_list->clients, client_cache->name,
367 client_cache->id, client_cache->context,
368 client_cache->expire, NULL);
369 silc_idcache_del_by_context(server->global_list->clients, client);
371 server_entry = server_entry->router;
373 /* If the client is not marked as local then move it to local list
374 since the server is local. */
375 if (server_entry->server_type != SILC_BACKUP_ROUTER && !local) {
376 SILC_LOG_DEBUG(("Moving client to local list"));
377 silc_idcache_add(server->local_list->clients, client_cache->name,
378 client_cache->id, client_cache->context,
379 client_cache->expire, NULL);
380 silc_idcache_del_by_context(server->global_list->clients, client);
384 silc_idcache_list_free(list);
388 if (!silc_idcache_list_next(list, &id_cache))
393 silc_idcache_list_free(list);
395 if (!silc_idcache_get_all(server->global_list->servers, &list))
398 if (silc_idcache_list_first(list, &id_cache)) {
400 server_entry = (SilcServerEntry)id_cache->context;
401 if (server_entry != from &&
402 SILC_ID_COMPARE(server_entry->id, client->id,
403 client->id->ip.data_len)) {
404 SILC_LOG_DEBUG(("Found (global) %s",
405 silc_id_render(server_entry->id, SILC_ID_SERVER)));
407 if (!server_entry->data.send_key && server_entry->router) {
408 SILC_LOG_DEBUG(("Server not locally connected, use its router"));
409 /* If the client is marked as local then move it to global list
410 since the server is global. */
412 SILC_LOG_DEBUG(("Moving client to global list"));
413 silc_idcache_add(server->global_list->clients, client_cache->name,
414 client_cache->id, client_cache->context,
415 client_cache->expire, NULL);
416 silc_idcache_del_by_context(server->local_list->clients, client);
418 server_entry = server_entry->router;
420 /* If the client is marked as local then move it to global list
421 since the server is global. */
422 if (server_entry->server_type != SILC_BACKUP_ROUTER && local) {
423 SILC_LOG_DEBUG(("Moving client to global list"));
424 silc_idcache_add(server->global_list->clients, client_cache->name,
425 client_cache->id, client_cache->context,
426 client_cache->expire, NULL);
427 silc_idcache_del_by_context(server->local_list->clients, client);
431 silc_idcache_list_free(list);
435 if (!silc_idcache_list_next(list, &id_cache))
440 silc_idcache_list_free(list);
445 /* Updates the clients that are originated from the `from' to be originated
446 from the `to'. If the `resolve_real_server' is TRUE then this will
447 attempt to figure out which clients really are originated from the
448 `from' and which are originated from a server that we have connection
449 to, when we've acting as backup router. If it is FALSE the `to' will
450 be the new source. This function also removes the clients that are
451 *really* originated from `from' if `remove_from' is TRUE. These are
452 clients that the `from' owns, and not just clients that are behind
455 void silc_server_update_clients_by_server(SilcServer server,
456 SilcServerEntry from,
458 bool resolve_real_server,
461 SilcIDCacheList list = NULL;
462 SilcIDCacheEntry id_cache = NULL;
463 SilcClientEntry client = NULL;
466 SILC_LOG_DEBUG(("Start"));
468 SILC_LOG_DEBUG(("Updating %s", silc_id_render(from->id,
470 SILC_LOG_DEBUG(("to %s", silc_id_render(to->id,
475 if (silc_idcache_get_all(server->global_list->clients, &list)) {
476 if (silc_idcache_list_first(list, &id_cache)) {
478 client = (SilcClientEntry)id_cache->context;
479 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
480 if (!silc_idcache_list_next(list, &id_cache))
486 SILC_LOG_DEBUG(("Client (global) %s",
487 silc_id_render(client->id, SILC_ID_CLIENT)));
489 SILC_LOG_DEBUG(("Client->router (global) %s",
490 silc_id_render(client->router->id, SILC_ID_SERVER)));
492 if (client->router == from) {
493 /* Skip clients that are *really* owned by the `from' */
494 if (remove_from && SILC_ID_COMPARE(from->id, client->id,
495 client->id->ip.data_len)) {
496 SILC_LOG_DEBUG(("Found really owned client, skip it"));
497 if (!silc_idcache_list_next(list, &id_cache))
503 if (resolve_real_server) {
505 silc_server_update_clients_by_real_server(server, from, client,
514 if (!silc_idcache_list_next(list, &id_cache))
518 silc_idcache_list_free(list);
522 if (silc_idcache_get_all(server->local_list->clients, &list)) {
523 if (silc_idcache_list_first(list, &id_cache)) {
525 client = (SilcClientEntry)id_cache->context;
526 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
527 if (!silc_idcache_list_next(list, &id_cache))
533 SILC_LOG_DEBUG(("Client (local) %s",
534 silc_id_render(client->id, SILC_ID_CLIENT)));
536 SILC_LOG_DEBUG(("Client->router (local) %s",
537 silc_id_render(client->router->id, SILC_ID_SERVER)));
539 if (client->router == from) {
540 /* Skip clients that are *really* owned by the `from' */
541 if (remove_from && SILC_ID_COMPARE(from->id, client->id,
542 client->id->ip.data_len)) {
543 SILC_LOG_DEBUG(("Found really owned client, skip it"));
544 if (!silc_idcache_list_next(list, &id_cache))
550 if (resolve_real_server) {
552 silc_server_update_clients_by_real_server(server, from, client,
555 client->router = from; /* on local list put old from */
561 if (!silc_idcache_list_next(list, &id_cache))
565 silc_idcache_list_free(list);
569 /* Now remove the clients that are still marked as orignated from the
570 `from'. These are the clients that really was owned by the `from' and
571 not just exist behind the `from'. */
572 silc_server_remove_clients_by_server(server, from, TRUE);
575 /* Updates servers that are from `from' to be originated from `to'. This
576 will also update the server's connection to `to's connection. */
578 void silc_server_update_servers_by_server(SilcServer server,
579 SilcServerEntry from,
582 SilcIDCacheList list = NULL;
583 SilcIDCacheEntry id_cache = NULL;
584 SilcServerEntry server_entry = NULL;
586 SILC_LOG_DEBUG(("Start"));
588 if (silc_idcache_get_all(server->local_list->servers, &list)) {
589 if (silc_idcache_list_first(list, &id_cache)) {
591 server_entry = (SilcServerEntry)id_cache->context;
592 if (server_entry->router == from) {
593 server_entry->router = to;
594 server_entry->connection = to->connection;
596 if (!silc_idcache_list_next(list, &id_cache))
600 silc_idcache_list_free(list);
603 if (silc_idcache_get_all(server->global_list->servers, &list)) {
604 if (silc_idcache_list_first(list, &id_cache)) {
606 server_entry = (SilcServerEntry)id_cache->context;
607 if (server_entry->router == from) {
608 server_entry->router = to;
609 server_entry->connection = to->connection;
611 if (!silc_idcache_list_next(list, &id_cache))
615 silc_idcache_list_free(list);
619 /* Removes channels that are from `from. */
621 void silc_server_remove_channels_by_server(SilcServer server,
622 SilcServerEntry from)
624 SilcIDCacheList list = NULL;
625 SilcIDCacheEntry id_cache = NULL;
626 SilcChannelEntry channel = NULL;
628 SILC_LOG_DEBUG(("Start"));
630 if (silc_idcache_get_all(server->global_list->channels, &list)) {
631 if (silc_idcache_list_first(list, &id_cache)) {
633 channel = (SilcChannelEntry)id_cache->context;
634 if (channel->router == from)
635 silc_idlist_del_channel(server->global_list, channel);
636 if (!silc_idcache_list_next(list, &id_cache))
640 silc_idcache_list_free(list);
644 /* Updates channels that are from `from' to be originated from `to'. */
646 void silc_server_update_channels_by_server(SilcServer server,
647 SilcServerEntry from,
650 SilcIDCacheList list = NULL;
651 SilcIDCacheEntry id_cache = NULL;
652 SilcChannelEntry channel = NULL;
654 SILC_LOG_DEBUG(("Start"));
656 if (silc_idcache_get_all(server->global_list->channels, &list)) {
657 if (silc_idcache_list_first(list, &id_cache)) {
659 channel = (SilcChannelEntry)id_cache->context;
660 if (channel->router == from)
661 channel->router = to;
662 if (!silc_idcache_list_next(list, &id_cache))
666 silc_idcache_list_free(list);
670 /* Checks whether given channel has global users. If it does this returns
671 TRUE and FALSE if there is only locally connected clients on the channel. */
673 bool silc_server_channel_has_global(SilcChannelEntry channel)
675 SilcChannelClientEntry chl;
676 SilcHashTableList htl;
678 silc_hash_table_list(channel->user_list, &htl);
679 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
680 if (chl->client->router) {
681 silc_hash_table_list_reset(&htl);
685 silc_hash_table_list_reset(&htl);
690 /* Checks whether given channel has locally connected users. If it does this
691 returns TRUE and FALSE if there is not one locally connected client. */
693 bool silc_server_channel_has_local(SilcChannelEntry channel)
695 SilcChannelClientEntry chl;
696 SilcHashTableList htl;
698 silc_hash_table_list(channel->user_list, &htl);
699 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
700 if (!chl->client->router) {
701 silc_hash_table_list_reset(&htl);
705 silc_hash_table_list_reset(&htl);
710 /* This function removes the channel and all users on the channel, unless
711 the channel is permanent. In this case the channel is disabled but all
712 users are removed from the channel. Returns TRUE if the channel is
713 destroyed totally, and FALSE if it is permanent and remains. */
715 bool silc_server_channel_delete(SilcServer server,
716 SilcChannelEntry channel)
718 SilcChannelClientEntry chl;
719 SilcHashTableList htl;
720 bool delchan = !(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH);
723 SILC_LOG_DEBUG(("Deleting %s channel", channel->channel_name));
725 /* Totally delete the channel and all users on the channel. The
726 users are deleted automatically in silc_idlist_del_channel. */
727 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
728 if (silc_idlist_del_channel(server->local_list, channel))
729 server->stat.my_channels--;
731 silc_idlist_del_channel(server->global_list, channel);
735 /* Channel is permanent, do not remove it, remove only users */
736 channel->disabled = TRUE;
737 silc_hash_table_list(channel->user_list, &htl);
738 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
739 silc_hash_table_del(chl->client->channels, channel);
740 silc_hash_table_del(channel->user_list, chl->client);
741 channel->user_count--;
744 silc_hash_table_list_reset(&htl);
746 SILC_LOG_DEBUG(("Channel %s remains", channel->channel_name));
751 /* Returns TRUE if the given client is on the channel. FALSE if not.
752 This works because we assure that the user list on the channel is
753 always in up to date thus we can only check the channel list from
754 `client' which is faster than checking the user list from `channel'. */
756 bool silc_server_client_on_channel(SilcClientEntry client,
757 SilcChannelEntry channel,
758 SilcChannelClientEntry *chl)
760 if (!client || !channel)
763 return silc_hash_table_find(client->channels, channel, NULL,
767 /* Checks string for bad characters and returns TRUE if they are found. */
769 bool silc_server_name_bad_chars(const char *name, SilcUInt32 name_len)
773 for (i = 0; i < name_len; i++) {
774 if (!isascii(name[i]))
776 if (name[i] <= 32) return TRUE;
777 if (name[i] == ' ') return TRUE;
778 if (name[i] == '*') return TRUE;
779 if (name[i] == '?') return TRUE;
780 if (name[i] == ',') return TRUE;
786 /* Modifies the `name' if it includes bad characters and returns new
787 allocated name that does not include bad characters. */
789 char *silc_server_name_modify_bad(const char *name, SilcUInt32 name_len)
792 char *newname = strdup(name);
794 for (i = 0; i < name_len; i++) {
795 if (!isascii(newname[i])) newname[i] = '_';
796 if (newname[i] <= 32) newname[i] = '_';
797 if (newname[i] == ' ') newname[i] = '_';
798 if (newname[i] == '*') newname[i] = '_';
799 if (newname[i] == '?') newname[i] = '_';
800 if (newname[i] == ',') newname[i] = '_';
806 /* Find number of sockets by IP address indicated by `ip'. Returns 0 if
807 socket connections with the IP address does not exist. */
809 SilcUInt32 silc_server_num_sockets_by_ip(SilcServer server, const char *ip,
814 for (i = 0, count = 0; i < server->config->param.connections_max; i++) {
815 if (server->sockets[i] && !strcmp(server->sockets[i]->ip, ip) &&
816 server->sockets[i]->type == type)
823 /* Find number of sockets by IP address indicated by remote host, indicatd
824 by `ip' or `hostname', `port', and `type'. Returns 0 if socket connections
825 does not exist. If `ip' is provided then `hostname' is ignored. */
827 SilcUInt32 silc_server_num_sockets_by_remote(SilcServer server,
829 const char *hostname,
835 if (!ip && !hostname)
838 for (i = 0, count = 0; i < server->config->param.connections_max; i++) {
839 if (server->sockets[i] &&
840 ((ip && !strcmp(server->sockets[i]->ip, ip)) ||
841 (hostname && !strcmp(server->sockets[i]->hostname, hostname))) &&
842 server->sockets[i]->port == port &&
843 server->sockets[i]->type == type)
850 /* Finds locally cached public key by the public key received in the SKE.
851 If we have it locally cached then we trust it and will use it in the
852 authentication protocol. Returns the locally cached public key or NULL
853 if we do not find the public key. */
855 SilcPublicKey silc_server_find_public_key(SilcServer server,
856 SilcHashTable local_public_keys,
857 SilcPublicKey remote_public_key)
859 SilcPublicKey cached_key;
861 SILC_LOG_DEBUG(("Find remote public key (%d keys in local cache)",
862 silc_hash_table_count(local_public_keys)));
864 if (!silc_hash_table_find_ext(local_public_keys, remote_public_key,
865 (void **)&cached_key, NULL,
866 silc_hash_public_key, NULL,
867 silc_hash_public_key_compare, NULL)) {
868 SILC_LOG_ERROR(("Public key not found"));
872 SILC_LOG_DEBUG(("Found public key"));
877 /* This returns the first public key from the table of public keys. This
878 is used only in cases where single public key exists in the table and
879 we want to get a pointer to it. For public key tables that has multiple
880 keys in it the silc_server_find_public_key must be used. */
882 SilcPublicKey silc_server_get_public_key(SilcServer server,
883 SilcHashTable local_public_keys)
885 SilcPublicKey cached_key;
886 SilcHashTableList htl;
888 SILC_LOG_DEBUG(("Start"));
890 assert(silc_hash_table_count(local_public_keys) < 2);
892 silc_hash_table_list(local_public_keys, &htl);
893 if (!silc_hash_table_get(&htl, NULL, (void **)&cached_key))
895 silc_hash_table_list_reset(&htl);
900 /* Check whether the connection `sock' is allowed to connect to us. This
901 checks for example whether there is too much connections for this host,
902 and required version for the host etc. */
904 bool silc_server_connection_allowed(SilcServer server,
905 SilcSocketConnection sock,
907 SilcServerConfigConnParams *global,
908 SilcServerConfigConnParams *params,
911 SilcUInt32 conn_number = (type == SILC_SOCKET_TYPE_CLIENT ?
912 server->stat.my_clients :
913 type == SILC_SOCKET_TYPE_SERVER ?
914 server->stat.my_servers :
915 server->stat.my_routers);
916 SilcUInt32 num_sockets, max_hosts, max_per_host;
917 SilcUInt32 r_protocol_version, l_protocol_version;
918 SilcUInt32 r_software_version, l_software_version;
919 char *r_vendor_version = NULL, *l_vendor_version;
924 silc_version_to_num(params && params->version_protocol ?
925 params->version_protocol :
926 global->version_protocol);
928 silc_version_to_num(params && params->version_software ?
929 params->version_software :
930 global->version_software);
931 l_vendor_version = (params && params->version_software_vendor ?
932 params->version_software_vendor :
933 global->version_software_vendor);
935 if (ske && silc_ske_parse_version(ske, &r_protocol_version, NULL,
936 &r_software_version, NULL,
937 &r_vendor_version)) {
938 sock->version = r_protocol_version;
940 /* Match protocol version */
941 if (l_protocol_version && r_protocol_version &&
942 r_protocol_version < l_protocol_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 SILC_STATUS_ERR_BAD_VERSION,
947 "You support too old protocol version");
951 /* Math software version */
952 if (l_software_version && r_software_version &&
953 r_software_version < l_software_version) {
954 SILC_LOG_INFO(("Connection %s (%s) is too old version",
955 sock->hostname, sock->ip));
956 silc_server_disconnect_remote(server, sock,
957 SILC_STATUS_ERR_BAD_VERSION,
958 "You support too old software version");
962 /* Regex match vendor version */
963 if (l_vendor_version && r_vendor_version &&
964 !silc_string_match(l_vendor_version, r_vendor_version)) {
965 SILC_LOG_INFO(("Connection %s (%s) is unsupported version",
966 sock->hostname, sock->ip));
967 silc_server_disconnect_remote(server, sock,
968 SILC_STATUS_ERR_BAD_VERSION,
969 "Your software is not supported");
973 silc_free(r_vendor_version);
975 /* Check for maximum connections limit */
977 num_sockets = silc_server_num_sockets_by_ip(server, sock->ip, type);
978 max_hosts = (params ? params->connections_max : global->connections_max);
979 max_per_host = (params ? params->connections_max_per_host :
980 global->connections_max_per_host);
982 if (max_hosts && conn_number >= max_hosts) {
983 SILC_LOG_INFO(("Server is full, closing %s (%s) connection",
984 sock->hostname, sock->ip));
985 silc_server_disconnect_remote(server, sock,
986 SILC_STATUS_ERR_RESOURCE_LIMIT,
987 "Server is full, try again later");
991 if (num_sockets >= max_per_host) {
992 SILC_LOG_INFO(("Too many connections from %s (%s), closing connection",
993 sock->hostname, sock->ip));
994 silc_server_disconnect_remote(server, sock,
995 SILC_STATUS_ERR_RESOURCE_LIMIT,
996 "Too many connections from your host");
1003 /* Checks that client has rights to add or remove channel modes. If any
1004 of the checks fails FALSE is returned. */
1006 bool silc_server_check_cmode_rights(SilcServer server,
1007 SilcChannelEntry channel,
1008 SilcChannelClientEntry client,
1011 bool is_op = client->mode & SILC_CHANNEL_UMODE_CHANOP;
1012 bool is_fo = client->mode & SILC_CHANNEL_UMODE_CHANFO;
1014 /* Check whether has rights to change anything */
1015 if (!is_op && !is_fo)
1018 /* Check whether has rights to change everything */
1022 /* We know that client is channel operator, check that they are not
1023 changing anything that requires channel founder rights. Rest of the
1024 modes are available automatically for channel operator. */
1026 if (mode & SILC_CHANNEL_MODE_PRIVKEY) {
1027 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY))
1028 if (is_op && !is_fo)
1031 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
1032 if (is_op && !is_fo)
1037 if (mode & SILC_CHANNEL_MODE_PASSPHRASE) {
1038 if (!(channel->mode & SILC_CHANNEL_MODE_PASSPHRASE))
1039 if (is_op && !is_fo)
1042 if (channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
1043 if (is_op && !is_fo)
1048 if (mode & SILC_CHANNEL_MODE_CIPHER) {
1049 if (!(channel->mode & SILC_CHANNEL_MODE_CIPHER))
1050 if (is_op && !is_fo)
1053 if (channel->mode & SILC_CHANNEL_MODE_CIPHER) {
1054 if (is_op && !is_fo)
1059 if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
1060 if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH))
1061 if (is_op && !is_fo)
1064 if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
1065 if (is_op && !is_fo)
1070 if (mode & SILC_CHANNEL_MODE_SILENCE_USERS) {
1071 if (!(channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS))
1072 if (is_op && !is_fo)
1075 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS) {
1076 if (is_op && !is_fo)
1081 if (mode & SILC_CHANNEL_MODE_SILENCE_OPERS) {
1082 if (!(channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS))
1083 if (is_op && !is_fo)
1086 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS) {
1087 if (is_op && !is_fo)
1095 /* Check that the client has rights to change its user mode. Returns
1096 FALSE if setting some mode is not allowed. */
1098 bool silc_server_check_umode_rights(SilcServer server,
1099 SilcClientEntry client,
1102 bool server_op = FALSE, router_op = FALSE;
1104 if (mode & SILC_UMODE_SERVER_OPERATOR) {
1105 /* Cannot set server operator mode (must use OPER command) */
1106 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR))
1109 /* Remove the server operator rights */
1110 if (client->mode & SILC_UMODE_SERVER_OPERATOR)
1114 if (mode & SILC_UMODE_ROUTER_OPERATOR) {
1115 /* Cannot set router operator mode (must use SILCOPER command) */
1116 if (!(client->mode & SILC_UMODE_ROUTER_OPERATOR))
1119 /* Remove the router operator rights */
1120 if (client->mode & SILC_UMODE_ROUTER_OPERATOR)
1125 SILC_UMODE_STATS_UPDATE(server, SILC_UMODE_SERVER_OPERATOR);
1127 SILC_UMODE_STATS_UPDATE(router, SILC_UMODE_ROUTER_OPERATOR);
1132 /* This function is used to send the notify packets and motd to the
1133 incoming client connection. */
1135 void silc_server_send_connect_notifys(SilcServer server,
1136 SilcSocketConnection sock,
1137 SilcClientEntry client)
1139 SilcIDListData idata = (SilcIDListData)client;
1141 /* Send some nice info to the client */
1142 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1143 ("Welcome to the SILC Network %s",
1145 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1146 ("Your host is %s, running version %s",
1147 server->server_name, server_version));
1149 if (server->stat.clients && server->stat.servers + 1)
1150 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1151 ("There are %d clients on %d servers in SILC "
1152 "Network", server->stat.clients,
1153 server->stat.servers + 1));
1154 if (server->stat.cell_clients && server->stat.cell_servers + 1)
1155 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1156 ("There are %d clients on %d server in our cell",
1157 server->stat.cell_clients,
1158 server->stat.cell_servers + 1));
1159 if (server->server_type == SILC_ROUTER) {
1160 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1161 ("I have %d clients, %d channels, %d servers and "
1163 server->stat.my_clients,
1164 server->stat.my_channels,
1165 server->stat.my_servers,
1166 server->stat.my_routers));
1168 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1169 ("I have %d clients and %d channels formed",
1170 server->stat.my_clients,
1171 server->stat.my_channels));
1174 if (server->stat.server_ops || server->stat.router_ops)
1175 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1176 ("There are %d server operators and %d router "
1178 server->stat.server_ops,
1179 server->stat.router_ops));
1180 if (server->stat.my_router_ops + server->stat.my_server_ops)
1181 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1182 ("I have %d operators online",
1183 server->stat.my_router_ops +
1184 server->stat.my_server_ops));
1186 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1187 ("Your connection is secured with %s cipher, "
1188 "key length %d bits",
1189 idata->send_key->cipher->name,
1190 idata->send_key->cipher->key_len));
1191 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1192 ("Your current nickname is %s",
1196 silc_server_send_motd(server, sock);
1199 /* Kill the client indicated by `remote_client' sending KILLED notify
1200 to the client, to all channels client has joined and to primary
1201 router if needed. The killed client is also removed from all channels. */
1203 void silc_server_kill_client(SilcServer server,
1204 SilcClientEntry remote_client,
1205 const char *comment,
1207 SilcIdType killer_id_type)
1209 SilcBuffer killed, killer;
1211 /* Send the KILL notify packets. First send it to the channel, then
1212 to our primary router and then directly to the client who is being
1213 killed right now. */
1215 killed = silc_id_payload_encode(remote_client->id, SILC_ID_CLIENT);
1216 killer = silc_id_payload_encode(killer_id, killer_id_type);
1218 /* Send KILLED notify to the channels. It is not sent to the client
1219 as it will be sent differently destined directly to the client and not
1221 silc_server_send_notify_on_channels(server, remote_client,
1222 remote_client, SILC_NOTIFY_TYPE_KILLED,
1223 3, killed->data, killed->len,
1224 comment, comment ? strlen(comment) : 0,
1225 killer->data, killer->len);
1227 /* Send KILLED notify to primary route */
1228 if (!server->standalone)
1229 silc_server_send_notify_killed(server, server->router->connection, TRUE,
1230 remote_client->id, comment,
1231 killer_id, killer_id_type);
1233 /* Send KILLED notify to the client directly */
1234 if (remote_client->connection || remote_client->router)
1235 silc_server_send_notify_killed(server, remote_client->connection ?
1236 remote_client->connection :
1237 remote_client->router->connection, FALSE,
1238 remote_client->id, comment,
1239 killer_id, killer_id_type);
1241 /* Remove the client from all channels. This generates new keys to the
1242 channels as well. */
1243 silc_server_remove_from_channels(server, NULL, remote_client, FALSE,
1246 /* Remove the client entry, If it is locally connected then we will also
1247 disconnect the client here */
1248 if (remote_client->connection) {
1249 /* Remove locally conneted client */
1250 SilcSocketConnection sock = remote_client->connection;
1251 silc_server_free_client_data(server, sock, remote_client, FALSE, NULL);
1252 silc_server_close_connection(server, sock);
1254 /* Update statistics */
1255 server->stat.clients--;
1256 server->stat.my_clients--;
1257 if (server->stat.cell_clients)
1258 server->stat.cell_clients--;
1259 SILC_OPER_STATS_UPDATE(remote_client, server, SILC_UMODE_SERVER_OPERATOR);
1260 SILC_OPER_STATS_UPDATE(remote_client, router, SILC_UMODE_ROUTER_OPERATOR);
1262 /* Remove remote client */
1263 if (!silc_idlist_del_client(server->global_list, remote_client)) {
1264 /* Remove this client from watcher list if it is */
1265 silc_server_del_from_watcher_list(server, remote_client);
1267 silc_idlist_del_client(server->local_list, remote_client);
1271 silc_buffer_free(killer);
1272 silc_buffer_free(killed);
1277 SilcClientEntry client;
1278 SilcNotifyType notify;
1279 const char *new_nick;
1280 } WatcherNotifyContext;
1283 silc_server_check_watcher_list_foreach(void *key, void *context,
1286 WatcherNotifyContext *notify = user_context;
1287 SilcClientEntry entry = context;
1288 SilcSocketConnection sock;
1290 if (entry == notify->client)
1293 sock = silc_server_get_client_route(notify->server, NULL, 0, entry->id,
1296 SILC_LOG_DEBUG(("Sending WATCH notify to %s",
1297 silc_id_render(entry->id, SILC_ID_CLIENT)));
1299 /* Send the WATCH notify */
1300 silc_server_send_notify_watch(notify->server, sock, entry,
1302 notify->new_nick ? notify->new_nick :
1303 (const char *)notify->client->nickname,
1308 /* This function checks whether the `client' nickname is being watched
1309 by someone, and notifies the watcher of the notify change of notify
1310 type indicated by `notify'. */
1312 bool silc_server_check_watcher_list(SilcServer server,
1313 SilcClientEntry client,
1314 const char *new_nick,
1315 SilcNotifyType notify)
1317 unsigned char hash[16];
1318 WatcherNotifyContext n;
1320 SILC_LOG_DEBUG(("Start"));
1322 /* If the watching is rejected by the client do nothing */
1323 if (client->mode & SILC_UMODE_REJECT_WATCHING)
1326 /* Make hash from the nick, or take it from Client ID */
1327 if (client->nickname) {
1329 memset(nick, 0, sizeof(nick));
1330 silc_to_lower(client->nickname, nick, sizeof(nick) - 1);
1331 silc_hash_make(server->md5hash, nick, strlen(nick), hash);
1333 memset(hash, 0, sizeof(hash));
1334 memcpy(hash, client->id->hash, sizeof(client->id->hash));
1339 n.new_nick = new_nick;
1342 /* Send notify to all watchers */
1343 silc_hash_table_find_foreach(server->watcher_list, hash,
1344 silc_server_check_watcher_list_foreach, &n);
1349 /* Remove the `client' from watcher list. After calling this the `client'
1350 is not watching any nicknames. */
1352 bool silc_server_del_from_watcher_list(SilcServer server,
1353 SilcClientEntry client)
1355 SilcHashTableList htl;
1357 SilcClientEntry entry;
1360 silc_hash_table_list(server->watcher_list, &htl);
1361 while (silc_hash_table_get(&htl, &key, (void **)&entry)) {
1362 if (entry == client) {
1363 silc_hash_table_del_by_context(server->watcher_list, key, client);
1365 SILC_LOG_DEBUG(("Removing %s from WATCH list",
1366 silc_id_render(client->id, SILC_ID_CLIENT)));
1368 /* Now check whether there still exists entries with this key, if not
1369 then free the key to not leak memory. */
1370 if (!silc_hash_table_find(server->watcher_list, key, NULL, NULL))
1376 silc_hash_table_list_reset(&htl);
1381 /* Force the client indicated by `chl' to change the channel user mode
1382 on channel indicated by `channel' to `forced_mode'. */
1384 bool silc_server_force_cumode_change(SilcServer server,
1385 SilcSocketConnection sock,
1386 SilcChannelEntry channel,
1387 SilcChannelClientEntry chl,
1388 SilcUInt32 forced_mode)
1390 SilcBuffer idp1, idp2;
1391 unsigned char cumode[4];
1393 silc_server_send_notify_cumode(server, sock, FALSE, channel, forced_mode,
1394 server->id, SILC_ID_SERVER,
1397 idp1 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
1398 idp2 = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
1399 SILC_PUT32_MSB(forced_mode, cumode);
1400 silc_server_send_notify_to_channel(server, sock, channel, FALSE,
1401 SILC_NOTIFY_TYPE_CUMODE_CHANGE,
1402 3, idp1->data, idp1->len,
1403 cumode, sizeof(cumode),
1404 idp2->data, idp2->len);
1405 silc_buffer_free(idp1);
1406 silc_buffer_free(idp2);