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 from client's channel list */
55 silc_hash_table_del(client->channels, channel);
57 /* Remove channel if there is no users anymore */
58 if (server->server_type == SILC_ROUTER &&
59 silc_hash_table_count(channel->user_list) < 2) {
61 if (silc_hash_table_find(channels, channel, NULL, NULL))
62 silc_hash_table_del(channels, channel);
65 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
67 if (silc_idlist_del_channel(server->local_list, channel))
68 server->stat.my_channels--;
70 silc_idlist_del_channel(server->global_list, channel);
74 /* Remove client from channel's client list */
75 silc_hash_table_del(channel->user_list, chl->client);
76 channel->user_count--;
78 /* If there is no global users on the channel anymore mark the channel
79 as local channel. Do not check if the removed client is local client. */
80 if (server->server_type != SILC_ROUTER && channel->global_users &&
81 chl->client->router && !silc_server_channel_has_global(channel))
82 channel->global_users = FALSE;
85 server->stat.my_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. */
89 if (server->server_type != SILC_ROUTER &&
90 !silc_server_channel_has_local(channel)) {
92 if (silc_hash_table_find(channels, channel, NULL, NULL))
93 silc_hash_table_del(channels, channel);
96 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
98 if (channel->founder_key) {
99 /* The founder auth data exists, do not remove the channel entry */
100 SilcChannelClientEntry chl2;
101 SilcHashTableList htl2;
103 channel->disabled = TRUE;
105 silc_hash_table_list(channel->user_list, &htl2);
106 while (silc_hash_table_get(&htl2, NULL, (void **)&chl2)) {
107 silc_hash_table_del(chl2->client->channels, channel);
108 silc_hash_table_del(channel->user_list, chl2->client);
109 channel->user_count--;
112 silc_hash_table_list_reset(&htl2);
116 /* Remove the channel entry */
117 if (silc_idlist_del_channel(server->local_list, channel))
118 server->stat.my_channels--;
120 silc_idlist_del_channel(server->global_list, channel);
124 /* Add the channel to the the channels list to regenerate the
126 if (!silc_hash_table_find(channels, channel, NULL, NULL))
127 silc_hash_table_add(channels, channel, channel);
129 silc_hash_table_list_reset(&htl);
131 silc_buffer_free(clidp);
134 /* This function is used to remove all client entries by the server `entry'.
135 This is called when the connection is lost to the server. In this case
136 we must invalidate all the client entries owned by the server `entry'.
137 If the `server_signoff' is TRUE then the SERVER_SIGNOFF notify is
138 distributed to our local clients. */
140 bool silc_server_remove_clients_by_server(SilcServer server,
141 SilcServerEntry entry,
144 SilcIDCacheList list = NULL;
145 SilcIDCacheEntry id_cache = NULL;
146 SilcClientEntry client = NULL;
148 SilcClientEntry *clients = NULL;
149 SilcUInt32 clients_c = 0;
150 unsigned char **argv = NULL;
151 SilcUInt32 *argv_lens = NULL, *argv_types = NULL, argc = 0;
152 SilcHashTableList htl;
153 SilcChannelEntry channel;
154 SilcHashTable channels;
157 SILC_LOG_DEBUG(("Start"));
159 /* Allocate the hash table that holds the channels that require
160 channel key re-generation after we've removed this server's clients
161 from the channels. */
162 channels = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL, NULL,
165 if (server_signoff) {
166 idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
167 argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
168 argv_lens = silc_realloc(argv_lens, sizeof(*argv_lens) * (argc + 1));
169 argv_types = silc_realloc(argv_types, sizeof(*argv_types) * (argc + 1));
170 argv[argc] = silc_calloc(idp->len, sizeof(*argv[0]));
171 memcpy(argv[argc], idp->data, idp->len);
172 argv_lens[argc] = idp->len;
173 argv_types[argc] = argc + 1;
175 silc_buffer_free(idp);
178 if (silc_idcache_get_all(server->local_list->clients, &list)) {
180 if (silc_idcache_list_first(list, &id_cache)) {
182 client = (SilcClientEntry)id_cache->context;
183 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
184 if (!silc_idcache_list_next(list, &id_cache))
190 if (client->router != entry) {
191 if (server_signoff) {
192 clients = silc_realloc(clients,
193 sizeof(*clients) * (clients_c + 1));
194 clients[clients_c] = client;
198 if (!silc_idcache_list_next(list, &id_cache))
204 if (server_signoff) {
205 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
206 argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
207 argv_lens = silc_realloc(argv_lens, sizeof(*argv_lens) *
209 argv_types = silc_realloc(argv_types, sizeof(*argv_types) *
211 argv[argc] = silc_calloc(idp->len, sizeof(*argv[0]));
212 memcpy(argv[argc], idp->data, idp->len);
213 argv_lens[argc] = idp->len;
214 argv_types[argc] = argc + 1;
216 silc_buffer_free(idp);
219 /* Update statistics */
220 server->stat.clients--;
221 if (server->stat.cell_clients)
222 server->stat.cell_clients--;
223 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
224 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
226 /* Remove the client entry */
227 silc_server_remove_clients_channels(server, NULL, client, channels);
228 if (!server_signoff) {
229 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
230 id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
232 silc_idlist_del_client(server->local_list, client);
235 if (!silc_idcache_list_next(list, &id_cache))
239 silc_idcache_list_free(list);
242 if (silc_idcache_get_all(server->global_list->clients, &list)) {
244 if (silc_idcache_list_first(list, &id_cache)) {
246 client = (SilcClientEntry)id_cache->context;
247 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
248 if (!silc_idcache_list_next(list, &id_cache))
254 if (client->router != entry) {
255 if (server_signoff && client->connection) {
256 clients = silc_realloc(clients,
257 sizeof(*clients) * (clients_c + 1));
258 clients[clients_c] = client;
262 if (!silc_idcache_list_next(list, &id_cache))
268 if (server_signoff) {
269 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
270 argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
271 argv_lens = silc_realloc(argv_lens, sizeof(*argv_lens) *
273 argv_types = silc_realloc(argv_types, sizeof(*argv_types) *
275 argv[argc] = silc_calloc(idp->len, sizeof(*argv[0]));
276 memcpy(argv[argc], idp->data, idp->len);
277 argv_lens[argc] = idp->len;
278 argv_types[argc] = argc + 1;
280 silc_buffer_free(idp);
283 /* Update statistics */
284 server->stat.clients--;
285 if (server->stat.cell_clients)
286 server->stat.cell_clients--;
287 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
288 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
290 /* Remove the client entry */
291 silc_server_remove_clients_channels(server, NULL, client, channels);
292 if (!server_signoff) {
293 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
294 id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
296 silc_idlist_del_client(server->global_list, client);
299 if (!silc_idcache_list_next(list, &id_cache))
303 silc_idcache_list_free(list);
306 /* Send the SERVER_SIGNOFF notify */
307 if (server_signoff) {
308 SilcBuffer args, not;
310 /* Send SERVER_SIGNOFF notify to our primary router */
311 if (!server->standalone && server->router &&
312 server->router != entry) {
313 args = silc_argument_payload_encode(1, argv, argv_lens,
315 silc_server_send_notify_args(server,
316 server->router->connection,
317 server->server_type == SILC_SERVER ?
319 SILC_NOTIFY_TYPE_SERVER_SIGNOFF,
321 silc_buffer_free(args);
324 /* Send to local clients. We also send the list of client ID's that
325 is to be removed for those servers that would like to use that list. */
326 args = silc_argument_payload_encode(argc, argv, argv_lens,
328 not = silc_notify_payload_encode_args(SILC_NOTIFY_TYPE_SERVER_SIGNOFF,
330 silc_server_packet_send_clients(server, clients, clients_c,
331 SILC_PACKET_NOTIFY, 0, FALSE,
332 not->data, not->len, FALSE);
335 silc_buffer_free(args);
336 silc_buffer_free(not);
337 for (i = 0; i < argc; i++)
340 silc_free(argv_lens);
341 silc_free(argv_types);
344 /* We must now re-generate the channel key for all channels that had
345 this server's client(s) on the channel. As they left the channel we
346 must re-generate the channel key. */
347 silc_hash_table_list(channels, &htl);
348 while (silc_hash_table_get(&htl, NULL, (void **)&channel)) {
349 if (!silc_server_create_channel_key(server, channel, 0)) {
350 silc_hash_table_list_reset(&htl);
351 silc_hash_table_free(channels);
355 /* Do not send the channel key if private channel key mode is set */
356 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY)
359 silc_server_send_channel_key(server, NULL, channel,
360 server->server_type == SILC_ROUTER ?
361 FALSE : !server->standalone);
363 silc_hash_table_list_reset(&htl);
364 silc_hash_table_free(channels);
369 static SilcServerEntry
370 silc_server_update_clients_by_real_server(SilcServer server,
371 SilcServerEntry from,
372 SilcClientEntry client,
374 SilcIDCacheEntry client_cache)
376 SilcServerEntry server_entry;
377 SilcIDCacheEntry id_cache = NULL;
378 SilcIDCacheList list;
380 if (!silc_idcache_get_all(server->local_list->servers, &list))
383 if (silc_idcache_list_first(list, &id_cache)) {
385 server_entry = (SilcServerEntry)id_cache->context;
386 if (server_entry != from &&
387 SILC_ID_COMPARE(server_entry->id, client->id,
388 client->id->ip.data_len)) {
389 SILC_LOG_DEBUG(("Found (local) %s",
390 silc_id_render(server_entry->id, SILC_ID_SERVER)));
392 if (!server_entry->data.send_key && server_entry->router) {
393 SILC_LOG_DEBUG(("Server not locally connected, use its router"));
394 /* If the client is not marked as local then move it to local list
395 since the server is local. */
397 SILC_LOG_DEBUG(("Moving client to local list"));
398 silc_idcache_add(server->local_list->clients, client_cache->name,
399 client_cache->id, client_cache->context,
400 client_cache->expire, NULL);
401 silc_idcache_del_by_context(server->global_list->clients, client);
403 server_entry = server_entry->router;
405 /* If the client is not marked as local then move it to local list
406 since the server is local. */
407 if (server_entry->server_type != SILC_BACKUP_ROUTER && !local) {
408 SILC_LOG_DEBUG(("Moving client to local list"));
409 silc_idcache_add(server->local_list->clients, client_cache->name,
410 client_cache->id, client_cache->context,
411 client_cache->expire, NULL);
412 silc_idcache_del_by_context(server->global_list->clients, client);
416 silc_idcache_list_free(list);
420 if (!silc_idcache_list_next(list, &id_cache))
425 silc_idcache_list_free(list);
427 if (!silc_idcache_get_all(server->global_list->servers, &list))
430 if (silc_idcache_list_first(list, &id_cache)) {
432 server_entry = (SilcServerEntry)id_cache->context;
433 if (server_entry != from &&
434 SILC_ID_COMPARE(server_entry->id, client->id,
435 client->id->ip.data_len)) {
436 SILC_LOG_DEBUG(("Found (global) %s",
437 silc_id_render(server_entry->id, SILC_ID_SERVER)));
439 if (!server_entry->data.send_key && server_entry->router) {
440 SILC_LOG_DEBUG(("Server not locally connected, use its router"));
441 /* If the client is marked as local then move it to global list
442 since the server is global. */
444 SILC_LOG_DEBUG(("Moving client to global list"));
445 silc_idcache_add(server->global_list->clients, client_cache->name,
446 client_cache->id, client_cache->context,
447 client_cache->expire, NULL);
448 silc_idcache_del_by_context(server->local_list->clients, client);
450 server_entry = server_entry->router;
452 /* If the client is marked as local then move it to global list
453 since the server is global. */
454 if (server_entry->server_type != SILC_BACKUP_ROUTER && local) {
455 SILC_LOG_DEBUG(("Moving client to global list"));
456 silc_idcache_add(server->global_list->clients, client_cache->name,
457 client_cache->id, client_cache->context,
458 client_cache->expire, NULL);
459 silc_idcache_del_by_context(server->local_list->clients, client);
463 silc_idcache_list_free(list);
467 if (!silc_idcache_list_next(list, &id_cache))
472 silc_idcache_list_free(list);
477 /* Updates the clients that are originated from the `from' to be originated
478 from the `to'. If the `resolve_real_server' is TRUE then this will
479 attempt to figure out which clients really are originated from the
480 `from' and which are originated from a server that we have connection
481 to, when we've acting as backup router. If it is FALSE the `to' will
482 be the new source. This function also removes the clients that are
483 *really* originated from `from' if `remove_from' is TRUE. These are
484 clients that the `from' owns, and not just clients that are behind
487 void silc_server_update_clients_by_server(SilcServer server,
488 SilcServerEntry from,
490 bool resolve_real_server,
493 SilcIDCacheList list = NULL;
494 SilcIDCacheEntry id_cache = NULL;
495 SilcClientEntry client = NULL;
498 SILC_LOG_DEBUG(("Start"));
500 SILC_LOG_DEBUG(("Updating %s", silc_id_render(from->id,
502 SILC_LOG_DEBUG(("to %s", silc_id_render(to->id,
507 if (silc_idcache_get_all(server->global_list->clients, &list)) {
508 if (silc_idcache_list_first(list, &id_cache)) {
510 client = (SilcClientEntry)id_cache->context;
511 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
512 if (!silc_idcache_list_next(list, &id_cache))
518 SILC_LOG_DEBUG(("Client (global) %s",
519 silc_id_render(client->id, SILC_ID_CLIENT)));
521 SILC_LOG_DEBUG(("Client->router (global) %s",
522 silc_id_render(client->router->id, SILC_ID_SERVER)));
524 if (client->router == from) {
525 /* Skip clients that are *really* owned by the `from' */
526 if (remove_from && SILC_ID_COMPARE(from->id, client->id,
527 client->id->ip.data_len)) {
528 SILC_LOG_DEBUG(("Found really owned client, skip it"));
529 if (!silc_idcache_list_next(list, &id_cache))
535 if (resolve_real_server) {
537 silc_server_update_clients_by_real_server(server, from, client,
546 if (!silc_idcache_list_next(list, &id_cache))
550 silc_idcache_list_free(list);
554 if (silc_idcache_get_all(server->local_list->clients, &list)) {
555 if (silc_idcache_list_first(list, &id_cache)) {
557 client = (SilcClientEntry)id_cache->context;
558 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED)) {
559 if (!silc_idcache_list_next(list, &id_cache))
565 SILC_LOG_DEBUG(("Client (local) %s",
566 silc_id_render(client->id, SILC_ID_CLIENT)));
568 SILC_LOG_DEBUG(("Client->router (local) %s",
569 silc_id_render(client->router->id, SILC_ID_SERVER)));
571 if (client->router == from) {
572 /* Skip clients that are *really* owned by the `from' */
573 if (remove_from && SILC_ID_COMPARE(from->id, client->id,
574 client->id->ip.data_len)) {
575 SILC_LOG_DEBUG(("Found really owned client, skip it"));
576 if (!silc_idcache_list_next(list, &id_cache))
582 if (resolve_real_server) {
584 silc_server_update_clients_by_real_server(server, from, client,
587 client->router = from; /* on local list put old from */
593 if (!silc_idcache_list_next(list, &id_cache))
597 silc_idcache_list_free(list);
601 /* Now remove the clients that are still marked as orignated from the
602 `from'. These are the clients that really was owned by the `from' and
603 not just exist behind the `from'. */
604 silc_server_remove_clients_by_server(server, from, TRUE);
607 /* Updates servers that are from `from' to be originated from `to'. This
608 will also update the server's connection to `to's connection. */
610 void silc_server_update_servers_by_server(SilcServer server,
611 SilcServerEntry from,
614 SilcIDCacheList list = NULL;
615 SilcIDCacheEntry id_cache = NULL;
616 SilcServerEntry server_entry = NULL;
618 SILC_LOG_DEBUG(("Start"));
620 if (silc_idcache_get_all(server->local_list->servers, &list)) {
621 if (silc_idcache_list_first(list, &id_cache)) {
623 server_entry = (SilcServerEntry)id_cache->context;
624 if (server_entry->router == from) {
625 server_entry->router = to;
626 server_entry->connection = to->connection;
628 if (!silc_idcache_list_next(list, &id_cache))
632 silc_idcache_list_free(list);
635 if (silc_idcache_get_all(server->global_list->servers, &list)) {
636 if (silc_idcache_list_first(list, &id_cache)) {
638 server_entry = (SilcServerEntry)id_cache->context;
639 if (server_entry->router == from) {
640 server_entry->router = to;
641 server_entry->connection = to->connection;
643 if (!silc_idcache_list_next(list, &id_cache))
647 silc_idcache_list_free(list);
651 /* Removes channels that are from `from. */
653 void silc_server_remove_channels_by_server(SilcServer server,
654 SilcServerEntry from)
656 SilcIDCacheList list = NULL;
657 SilcIDCacheEntry id_cache = NULL;
658 SilcChannelEntry channel = NULL;
660 SILC_LOG_DEBUG(("Start"));
662 if (silc_idcache_get_all(server->global_list->channels, &list)) {
663 if (silc_idcache_list_first(list, &id_cache)) {
665 channel = (SilcChannelEntry)id_cache->context;
666 if (channel->router == from)
667 silc_idlist_del_channel(server->global_list, channel);
668 if (!silc_idcache_list_next(list, &id_cache))
672 silc_idcache_list_free(list);
676 /* Updates channels that are from `from' to be originated from `to'. */
678 void silc_server_update_channels_by_server(SilcServer server,
679 SilcServerEntry from,
682 SilcIDCacheList list = NULL;
683 SilcIDCacheEntry id_cache = NULL;
684 SilcChannelEntry channel = NULL;
686 SILC_LOG_DEBUG(("Start"));
688 if (silc_idcache_get_all(server->global_list->channels, &list)) {
689 if (silc_idcache_list_first(list, &id_cache)) {
691 channel = (SilcChannelEntry)id_cache->context;
692 if (channel->router == from)
693 channel->router = to;
694 if (!silc_idcache_list_next(list, &id_cache))
698 silc_idcache_list_free(list);
702 /* Checks whether given channel has global users. If it does this returns
703 TRUE and FALSE if there is only locally connected clients on the channel. */
705 bool silc_server_channel_has_global(SilcChannelEntry channel)
707 SilcChannelClientEntry chl;
708 SilcHashTableList htl;
710 silc_hash_table_list(channel->user_list, &htl);
711 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
712 if (chl->client->router) {
713 silc_hash_table_list_reset(&htl);
717 silc_hash_table_list_reset(&htl);
722 /* Checks whether given channel has locally connected users. If it does this
723 returns TRUE and FALSE if there is not one locally connected client. */
725 bool silc_server_channel_has_local(SilcChannelEntry channel)
727 SilcChannelClientEntry chl;
728 SilcHashTableList htl;
730 silc_hash_table_list(channel->user_list, &htl);
731 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
732 if (!chl->client->router) {
733 silc_hash_table_list_reset(&htl);
737 silc_hash_table_list_reset(&htl);
742 /* Returns TRUE if the given client is on the channel. FALSE if not.
743 This works because we assure that the user list on the channel is
744 always in up to date thus we can only check the channel list from
745 `client' which is faster than checking the user list from `channel'. */
747 bool silc_server_client_on_channel(SilcClientEntry client,
748 SilcChannelEntry channel,
749 SilcChannelClientEntry *chl)
751 if (!client || !channel)
754 return silc_hash_table_find(client->channels, channel, NULL,
758 /* Checks string for bad characters and returns TRUE if they are found. */
760 bool silc_server_name_bad_chars(const char *name, SilcUInt32 name_len)
764 for (i = 0; i < name_len; i++) {
765 if (!isascii(name[i]))
767 if (name[i] <= 32) return TRUE;
768 if (name[i] == ' ') return TRUE;
769 if (name[i] == '*') return TRUE;
770 if (name[i] == '?') return TRUE;
771 if (name[i] == ',') return TRUE;
777 /* Modifies the `name' if it includes bad characters and returns new
778 allocated name that does not include bad characters. */
780 char *silc_server_name_modify_bad(const char *name, SilcUInt32 name_len)
783 char *newname = strdup(name);
785 for (i = 0; i < name_len; i++) {
786 if (!isascii(newname[i])) newname[i] = '_';
787 if (newname[i] <= 32) newname[i] = '_';
788 if (newname[i] == ' ') newname[i] = '_';
789 if (newname[i] == '*') newname[i] = '_';
790 if (newname[i] == '?') newname[i] = '_';
791 if (newname[i] == ',') newname[i] = '_';
797 /* Find number of sockets by IP address indicated by `ip'. Returns 0 if
798 socket connections with the IP address does not exist. */
800 SilcUInt32 silc_server_num_sockets_by_ip(SilcServer server, const char *ip,
805 for (i = 0, count = 0; i < server->config->param.connections_max; i++) {
806 if (server->sockets[i] && !strcmp(server->sockets[i]->ip, ip) &&
807 server->sockets[i]->type == type)
814 /* Find number of sockets by IP address indicated by remote host, indicatd
815 by `ip' or `hostname', `port', and `type'. Returns 0 if socket connections
816 does not exist. If `ip' is provided then `hostname' is ignored. */
818 SilcUInt32 silc_server_num_sockets_by_remote(SilcServer server,
820 const char *hostname,
826 if (!ip && !hostname)
829 for (i = 0, count = 0; i < server->config->param.connections_max; i++) {
830 if (server->sockets[i] &&
831 ((ip && !strcmp(server->sockets[i]->ip, ip)) ||
832 (hostname && !strcmp(server->sockets[i]->hostname, hostname))) &&
833 server->sockets[i]->port == port &&
834 server->sockets[i]->type == type)
841 /* Finds locally cached public key by the public key received in the SKE.
842 If we have it locally cached then we trust it and will use it in the
843 authentication protocol. Returns the locally cached public key or NULL
844 if we do not find the public key. */
846 SilcPublicKey silc_server_find_public_key(SilcServer server,
847 SilcHashTable local_public_keys,
848 SilcPublicKey remote_public_key)
850 SilcPublicKey cached_key;
852 SILC_LOG_DEBUG(("Find remote public key (%d keys in local cache)",
853 silc_hash_table_count(local_public_keys)));
855 if (!silc_hash_table_find_ext(local_public_keys, remote_public_key,
856 (void **)&cached_key, NULL,
857 silc_hash_public_key, NULL,
858 silc_hash_public_key_compare, NULL)) {
859 SILC_LOG_ERROR(("Public key not found"));
863 SILC_LOG_DEBUG(("Found public key"));
868 /* This returns the first public key from the table of public keys. This
869 is used only in cases where single public key exists in the table and
870 we want to get a pointer to it. For public key tables that has multiple
871 keys in it the silc_server_find_public_key must be used. */
873 SilcPublicKey silc_server_get_public_key(SilcServer server,
874 SilcHashTable local_public_keys)
876 SilcPublicKey cached_key;
877 SilcHashTableList htl;
879 SILC_LOG_DEBUG(("Start"));
881 assert(silc_hash_table_count(local_public_keys) < 2);
883 silc_hash_table_list(local_public_keys, &htl);
884 if (!silc_hash_table_get(&htl, NULL, (void **)&cached_key))
886 silc_hash_table_list_reset(&htl);
891 /* Check whether the connection `sock' is allowed to connect to us. This
892 checks for example whether there is too much connections for this host,
893 and required version for the host etc. */
895 bool silc_server_connection_allowed(SilcServer server,
896 SilcSocketConnection sock,
898 SilcServerConfigConnParams *global,
899 SilcServerConfigConnParams *params,
902 SilcUInt32 conn_number = (type == SILC_SOCKET_TYPE_CLIENT ?
903 server->stat.my_clients :
904 type == SILC_SOCKET_TYPE_SERVER ?
905 server->stat.my_servers :
906 server->stat.my_routers);
907 SilcUInt32 num_sockets, max_hosts, max_per_host;
908 SilcUInt32 r_protocol_version, l_protocol_version;
909 SilcUInt32 r_software_version, l_software_version;
910 char *r_vendor_version = NULL, *l_vendor_version;
915 silc_version_to_num(params && params->version_protocol ?
916 params->version_protocol :
917 global->version_protocol);
919 silc_version_to_num(params && params->version_software ?
920 params->version_software :
921 global->version_software);
922 l_vendor_version = (params && params->version_software_vendor ?
923 params->version_software_vendor :
924 global->version_software_vendor);
926 if (ske && silc_ske_parse_version(ske, &r_protocol_version, NULL,
927 &r_software_version, NULL,
928 &r_vendor_version)) {
929 sock->version = r_protocol_version;
931 /* Match protocol version */
932 if (l_protocol_version && r_protocol_version &&
933 r_protocol_version < l_protocol_version) {
934 SILC_LOG_INFO(("Connection %s (%s) is too old version",
935 sock->hostname, sock->ip));
936 silc_server_disconnect_remote(server, sock,
937 "Server closed connection: "
938 "You support too old protocol version");
942 /* Math software version */
943 if (l_software_version && r_software_version &&
944 r_software_version < l_software_version) {
945 SILC_LOG_INFO(("Connection %s (%s) is too old version",
946 sock->hostname, sock->ip));
947 silc_server_disconnect_remote(server, sock,
948 "Server closed connection: "
949 "You support too old software version");
953 /* Regex match vendor version */
954 if (l_vendor_version && r_vendor_version &&
955 !silc_string_match(l_vendor_version, r_vendor_version)) {
956 SILC_LOG_INFO(("Connection %s (%s) is unsupported version",
957 sock->hostname, sock->ip));
958 silc_server_disconnect_remote(server, sock,
959 "Server closed connection: "
960 "Your software is not supported");
964 silc_free(r_vendor_version);
966 /* Check for maximum connections limit */
968 num_sockets = silc_server_num_sockets_by_ip(server, sock->ip, type);
969 max_hosts = (params ? params->connections_max : global->connections_max);
970 max_per_host = (params ? params->connections_max_per_host :
971 global->connections_max_per_host);
973 if (max_hosts && conn_number >= max_hosts) {
974 SILC_LOG_INFO(("Server is full, closing %s (%s) connection",
975 sock->hostname, sock->ip));
976 silc_server_disconnect_remote(server, sock,
977 "Server closed connection: "
978 "Server is full, try again later");
982 if (num_sockets >= max_per_host) {
983 SILC_LOG_INFO(("Too many connections from %s (%s), closing connection",
984 sock->hostname, sock->ip));
985 silc_server_disconnect_remote(server, sock,
986 "Server closed connection: "
987 "Too many connections from your host");
994 /* Checks that client has rights to add or remove channel modes. If any
995 of the checks fails FALSE is returned. */
997 bool silc_server_check_cmode_rights(SilcServer server,
998 SilcChannelEntry channel,
999 SilcChannelClientEntry client,
1002 bool is_op = client->mode & SILC_CHANNEL_UMODE_CHANOP;
1003 bool is_fo = client->mode & SILC_CHANNEL_UMODE_CHANFO;
1005 /* Check whether has rights to change anything */
1006 if (!is_op && !is_fo)
1009 /* Check whether has rights to change everything */
1013 /* We know that client is channel operator, check that they are not
1014 changing anything that requires channel founder rights. Rest of the
1015 modes are available automatically for channel operator. */
1017 if (mode & SILC_CHANNEL_MODE_PRIVKEY) {
1018 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY))
1019 if (is_op && !is_fo)
1022 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
1023 if (is_op && !is_fo)
1028 if (mode & SILC_CHANNEL_MODE_PASSPHRASE) {
1029 if (!(channel->mode & SILC_CHANNEL_MODE_PASSPHRASE))
1030 if (is_op && !is_fo)
1033 if (channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
1034 if (is_op && !is_fo)
1039 if (mode & SILC_CHANNEL_MODE_CIPHER) {
1040 if (!(channel->mode & SILC_CHANNEL_MODE_CIPHER))
1041 if (is_op && !is_fo)
1044 if (channel->mode & SILC_CHANNEL_MODE_CIPHER) {
1045 if (is_op && !is_fo)
1050 if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
1051 if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH))
1052 if (is_op && !is_fo)
1055 if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
1056 if (is_op && !is_fo)
1061 if (mode & SILC_CHANNEL_MODE_SILENCE_USERS) {
1062 if (!(channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS))
1063 if (is_op && !is_fo)
1066 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS) {
1067 if (is_op && !is_fo)
1072 if (mode & SILC_CHANNEL_MODE_SILENCE_OPERS) {
1073 if (!(channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS))
1074 if (is_op && !is_fo)
1077 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS) {
1078 if (is_op && !is_fo)
1086 /* Check that the client has rights to change its user mode. Returns
1087 FALSE if setting some mode is not allowed. */
1089 bool silc_server_check_umode_rights(SilcServer server,
1090 SilcClientEntry client,
1093 bool server_op = FALSE, router_op = FALSE;
1095 if (mode & SILC_UMODE_SERVER_OPERATOR) {
1096 /* Cannot set server operator mode (must use OPER command) */
1097 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR))
1100 /* Remove the server operator rights */
1101 if (client->mode & SILC_UMODE_SERVER_OPERATOR)
1105 if (mode & SILC_UMODE_ROUTER_OPERATOR) {
1106 /* Cannot set router operator mode (must use SILCOPER command) */
1107 if (!(client->mode & SILC_UMODE_ROUTER_OPERATOR))
1110 /* Remove the router operator rights */
1111 if (client->mode & SILC_UMODE_ROUTER_OPERATOR)
1116 SILC_UMODE_STATS_UPDATE(server, SILC_UMODE_SERVER_OPERATOR);
1118 SILC_UMODE_STATS_UPDATE(router, SILC_UMODE_ROUTER_OPERATOR);
1123 /* This function is used to send the notify packets and motd to the
1124 incoming client connection. */
1126 void silc_server_send_connect_notifys(SilcServer server,
1127 SilcSocketConnection sock,
1128 SilcClientEntry client)
1130 SilcIDListData idata = (SilcIDListData)client;
1132 /* Send some nice info to the client */
1133 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1134 ("Welcome to the SILC Network %s",
1136 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1137 ("Your host is %s, running version %s",
1138 server->server_name, server_version));
1140 if (server->stat.clients && server->stat.servers + 1)
1141 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1142 ("There are %d clients on %d servers in SILC "
1143 "Network", server->stat.clients,
1144 server->stat.servers + 1));
1145 if (server->stat.cell_clients && server->stat.cell_servers + 1)
1146 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1147 ("There are %d clients on %d server in our cell",
1148 server->stat.cell_clients,
1149 server->stat.cell_servers + 1));
1150 if (server->server_type == SILC_ROUTER) {
1151 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1152 ("I have %d clients, %d channels, %d servers and "
1154 server->stat.my_clients,
1155 server->stat.my_channels,
1156 server->stat.my_servers,
1157 server->stat.my_routers));
1159 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1160 ("I have %d clients and %d channels formed",
1161 server->stat.my_clients,
1162 server->stat.my_channels));
1165 if (server->stat.server_ops || server->stat.router_ops)
1166 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1167 ("There are %d server operators and %d router "
1169 server->stat.server_ops,
1170 server->stat.router_ops));
1171 if (server->stat.my_router_ops + server->stat.my_server_ops)
1172 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1173 ("I have %d operators online",
1174 server->stat.my_router_ops +
1175 server->stat.my_server_ops));
1177 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1178 ("Your connection is secured with %s cipher, "
1179 "key length %d bits",
1180 idata->send_key->cipher->name,
1181 idata->send_key->cipher->key_len));
1182 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1183 ("Your current nickname is %s",
1187 silc_server_send_motd(server, sock);
1190 /* Kill the client indicated by `remote_client' sending KILLED notify
1191 to the client, to all channels client has joined and to primary
1192 router if needed. The killed client is also removed from all channels. */
1194 void silc_server_kill_client(SilcServer server,
1195 SilcClientEntry remote_client,
1196 const char *comment,
1198 SilcIdType killer_id_type)
1200 SilcBuffer killed, killer;
1202 /* Send the KILL notify packets. First send it to the channel, then
1203 to our primary router and then directly to the client who is being
1204 killed right now. */
1206 killed = silc_id_payload_encode(remote_client->id, SILC_ID_CLIENT);
1207 killer = silc_id_payload_encode(killer_id, killer_id_type);
1209 /* Send KILLED notify to the channels. It is not sent to the client
1210 as it will be sent differently destined directly to the client and not
1212 silc_server_send_notify_on_channels(server, remote_client,
1213 remote_client, SILC_NOTIFY_TYPE_KILLED,
1214 3, killed->data, killed->len,
1215 comment, comment ? strlen(comment) : 0,
1216 killer->data, killer->len);
1218 /* Send KILLED notify to primary route */
1219 if (!server->standalone)
1220 silc_server_send_notify_killed(server, server->router->connection, TRUE,
1221 remote_client->id, comment,
1222 killer_id, killer_id_type);
1224 /* Send KILLED notify to the client directly */
1225 if (remote_client->connection || remote_client->router)
1226 silc_server_send_notify_killed(server, remote_client->connection ?
1227 remote_client->connection :
1228 remote_client->router->connection, FALSE,
1229 remote_client->id, comment,
1230 killer_id, killer_id_type);
1232 /* Remove the client from all channels. This generates new keys to the
1233 channels as well. */
1234 silc_server_remove_from_channels(server, NULL, remote_client, FALSE,
1237 /* Remove the client entry, If it is locally connected then we will also
1238 disconnect the client here */
1239 if (remote_client->connection) {
1240 /* Remove locally conneted client */
1241 SilcSocketConnection sock = remote_client->connection;
1242 silc_server_free_client_data(server, sock, remote_client, FALSE, NULL);
1243 silc_server_close_connection(server, sock);
1245 /* Update statistics */
1246 server->stat.clients--;
1247 server->stat.my_clients--;
1248 if (server->stat.cell_clients)
1249 server->stat.cell_clients--;
1250 SILC_OPER_STATS_UPDATE(remote_client, server, SILC_UMODE_SERVER_OPERATOR);
1251 SILC_OPER_STATS_UPDATE(remote_client, router, SILC_UMODE_ROUTER_OPERATOR);
1253 /* Remove remote client */
1254 if (!silc_idlist_del_client(server->global_list, remote_client))
1255 silc_idlist_del_client(server->local_list, remote_client);
1258 silc_buffer_free(killer);
1259 silc_buffer_free(killed);