5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2005 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
21 #include "serverincludes.h"
22 #include "server_internal.h"
24 extern char *server_version;
26 /* Removes the client from channels and possibly removes the channels
27 as well. After removing those channels that exist, their channel
28 keys are regnerated. This is called only by the function
29 silc_server_remove_clients_by_server. */
32 silc_server_remove_clients_channels(SilcServer server,
33 SilcServerEntry server_entry,
34 SilcHashTable clients,
35 SilcClientEntry client,
36 SilcHashTable channels)
38 SilcChannelEntry channel;
39 SilcChannelClientEntry chl, chl2;
40 SilcHashTableList htl, htl2;
45 SILC_LOG_DEBUG(("Remove client %s from all channels",
46 client->nickname ? client->nickname :
47 (unsigned char *)""));
49 if (silc_hash_table_find(clients, client, NULL, NULL))
50 silc_hash_table_del(clients, client);
52 /* Remove the client from all channels. The client is removed from
53 the channels' user list. */
54 silc_hash_table_list(client->channels, &htl);
55 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
56 channel = chl->channel;
58 /* Remove channel if this is last client leaving the channel, unless
59 the channel is permanent. */
60 if (server->server_type != SILC_SERVER &&
61 silc_hash_table_count(channel->user_list) < 2) {
62 if (silc_hash_table_find(channels, channel, NULL, NULL))
63 silc_hash_table_del(channels, channel);
64 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
65 silc_server_channel_delete(server, channel);
69 silc_hash_table_del(client->channels, channel);
70 silc_hash_table_del(channel->user_list, chl->client);
71 channel->user_count--;
73 /* If there is no global users on the channel anymore mark the channel
74 as local channel. Do not check if the removed client is local client. */
75 if (server->server_type != SILC_ROUTER && channel->global_users &&
76 chl->client->router && !silc_server_channel_has_global(channel))
77 channel->global_users = FALSE;
81 /* Update statistics */
82 if (SILC_IS_LOCAL(client))
83 server->stat.my_chanclients--;
84 if (server->server_type == SILC_ROUTER) {
85 server->stat.cell_chanclients--;
86 server->stat.chanclients--;
89 /* If there is not at least one local user on the channel then we don't
90 need the channel entry anymore, we can remove it safely, unless the
91 channel is permanent channel */
92 if (server->server_type == SILC_SERVER &&
93 !silc_server_channel_has_local(channel)) {
94 if (silc_hash_table_find(channels, channel, NULL, NULL))
95 silc_hash_table_del(channels, channel);
96 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
97 silc_server_channel_delete(server, channel);
101 /* Mark other local clients to the table of clients whom will receive
102 the SERVER_SIGNOFF notify. */
103 silc_hash_table_list(channel->user_list, &htl2);
104 while (silc_hash_table_get(&htl2, NULL, (void *)&chl2)) {
105 SilcClientEntry c = chl2->client;
109 /* Add client to table, if it's not from the signoff server */
110 if (c->router != server_entry &&
111 !silc_hash_table_find(clients, c, NULL, NULL))
112 silc_hash_table_add(clients, c, c);
114 silc_hash_table_list_reset(&htl2);
116 /* Add the channel to the the channels list to regenerate the
118 if (!silc_hash_table_find(channels, channel, NULL, NULL))
119 silc_hash_table_add(channels, channel, channel);
121 silc_hash_table_list_reset(&htl);
122 assert(!silc_hash_table_count(client->channels));
125 /* This function removes all client entries that are originated from
126 `router' and are owned by `entry'. `router' and `entry' can be same
127 too. If `server_signoff' is TRUE then SERVER_SIGNOFF notify is
128 distributed to our local clients. */
130 bool silc_server_remove_clients_by_server(SilcServer server,
131 SilcServerEntry router,
132 SilcServerEntry entry,
135 SilcIDCacheList list = NULL;
136 SilcIDCacheEntry id_cache = NULL;
137 SilcClientEntry client = NULL;
139 unsigned char **argv = NULL;
140 SilcUInt32 *argv_lens = NULL, *argv_types = NULL, argc = 0;
141 SilcHashTableList htl;
142 SilcChannelEntry channel;
143 SilcHashTable channels, clients;
146 if (!(entry->data.status & SILC_IDLIST_STATUS_REGISTERED))
149 SILC_LOG_DEBUG(("Removing clients by %s",
150 entry->server_name ? entry->server_name : "server"));
155 /* Allocate the hash table that holds the channels that require
156 channel key re-generation after we've removed this server's clients
157 from the channels. */
158 channels = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL, NULL,
160 clients = 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)) {
177 if (silc_idcache_list_first(list, &id_cache)) {
179 client = (SilcClientEntry)id_cache->context;
181 /* If client is not registered, is not originated from `router'
182 and is not owned by `entry', skip it. */
183 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) ||
184 client->router != router ||
185 (router != entry && !SILC_ID_COMPARE(client->id, entry->id,
186 client->id->ip.data_len))) {
187 if (!silc_idcache_list_next(list, &id_cache))
193 if (server_signoff) {
194 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
195 argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
196 argv_lens = silc_realloc(argv_lens, sizeof(*argv_lens) *
198 argv_types = silc_realloc(argv_types, sizeof(*argv_types) *
200 argv[argc] = silc_calloc(idp->len, sizeof(*argv[0]));
201 memcpy(argv[argc], idp->data, idp->len);
202 argv_lens[argc] = idp->len;
203 argv_types[argc] = argc + 1;
205 silc_buffer_free(idp);
208 /* Update statistics */
209 server->stat.clients--;
210 if (server->stat.cell_clients)
211 server->stat.cell_clients--;
212 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
213 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
215 if (client->data.public_key)
216 silc_hash_table_del_by_context(server->pk_hash,
217 client->data.public_key,
219 silc_server_remove_clients_channels(server, entry, clients,
221 silc_server_del_from_watcher_list(server, client);
223 /* Remove the client entry */
224 if (!server_signoff) {
225 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
226 id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
228 silc_idlist_del_data(client);
229 silc_idlist_del_client(server->local_list, client);
232 if (!silc_idcache_list_next(list, &id_cache))
236 silc_idcache_list_free(list);
239 if (silc_idcache_get_all(server->global_list->clients, &list)) {
241 if (silc_idcache_list_first(list, &id_cache)) {
243 client = (SilcClientEntry)id_cache->context;
245 /* If client is not registered, is not originated from `router'
246 and is not owned by `entry', skip it. */
247 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) ||
248 client->router != router ||
249 (router != entry && !SILC_ID_COMPARE(client->id, entry->id,
250 client->id->ip.data_len))) {
251 if (!silc_idcache_list_next(list, &id_cache))
257 if (server_signoff) {
258 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
259 argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
260 argv_lens = silc_realloc(argv_lens, sizeof(*argv_lens) *
262 argv_types = silc_realloc(argv_types, sizeof(*argv_types) *
264 argv[argc] = silc_calloc(idp->len, sizeof(*argv[0]));
265 memcpy(argv[argc], idp->data, idp->len);
266 argv_lens[argc] = idp->len;
267 argv_types[argc] = argc + 1;
269 silc_buffer_free(idp);
272 /* Update statistics */
273 server->stat.clients--;
274 if (server->stat.cell_clients)
275 server->stat.cell_clients--;
276 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
277 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
279 if (client->data.public_key)
280 silc_hash_table_del_by_context(server->pk_hash,
281 client->data.public_key,
283 silc_server_remove_clients_channels(server, entry, clients,
285 silc_server_del_from_watcher_list(server, client);
287 /* Remove the client entry */
288 if (!server_signoff) {
289 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
290 id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
292 silc_idlist_del_data(client);
293 silc_idlist_del_client(server->global_list, client);
296 if (!silc_idcache_list_next(list, &id_cache))
300 silc_idcache_list_free(list);
303 /* Return now if we are shutting down */
304 if (server->server_shutdown) {
305 silc_hash_table_free(channels);
307 if (server_signoff) {
308 for (i = 0; i < argc; i++)
311 silc_free(argv_lens);
312 silc_free(argv_types);
313 silc_hash_table_free(clients);
318 /* Send the SERVER_SIGNOFF notify */
319 if (server_signoff) {
320 SilcBuffer args, not;
322 SILC_LOG_DEBUG(("Sending SERVER_SIGNOFF for %s with %d clients",
323 silc_id_render(entry->id, SILC_ID_SERVER), argc - 1));
325 /* Send SERVER_SIGNOFF notify to our primary router */
326 if (server->router != entry) {
327 args = silc_argument_payload_encode(1, argv, argv_lens,
329 silc_server_send_notify_args(server, SILC_PRIMARY_ROUTE(server),
330 SILC_BROADCAST(server),
331 SILC_NOTIFY_TYPE_SERVER_SIGNOFF,
333 silc_buffer_free(args);
336 /* Send to local clients. We also send the list of client ID's that
337 is to be removed for those servers that would like to use that list. */
338 args = silc_argument_payload_encode(argc, argv, argv_lens,
340 not = silc_notify_payload_encode_args(SILC_NOTIFY_TYPE_SERVER_SIGNOFF,
342 silc_server_packet_send_clients(server, clients,
343 SILC_PACKET_NOTIFY, 0, FALSE,
344 not->data, not->len, FALSE);
346 /* Send notify also to local backup routers */
347 silc_server_backup_send(server, NULL, SILC_PACKET_NOTIFY, 0,
348 not->data, not->len, FALSE, TRUE);
350 silc_buffer_free(args);
351 silc_buffer_free(not);
352 for (i = 0; i < argc; i++)
355 silc_free(argv_lens);
356 silc_free(argv_types);
357 silc_hash_table_free(clients);
360 /* We must now re-generate the channel key for all channels that had
361 this server's client(s) on the channel. As they left the channel we
362 must re-generate the channel key. */
363 silc_hash_table_list(channels, &htl);
364 while (silc_hash_table_get(&htl, NULL, (void *)&channel)) {
365 if (!silc_server_create_channel_key(server, channel, 0)) {
366 silc_hash_table_list_reset(&htl);
367 silc_hash_table_free(channels);
371 /* Do not send the channel key if private channel key mode is set */
372 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY || !channel->channel_key)
375 silc_server_send_channel_key(server, NULL, channel,
376 server->server_type == SILC_ROUTER ?
377 FALSE : !server->standalone);
379 silc_hash_table_list_reset(&htl);
380 silc_hash_table_free(channels);
385 static SilcServerEntry
386 silc_server_update_clients_by_real_server(SilcServer server,
387 SilcServerEntry from,
389 SilcClientEntry client,
391 SilcIDCacheEntry client_cache)
393 SilcServerEntry server_entry;
394 SilcIDCacheEntry id_cache = NULL;
395 SilcIDCacheList list;
396 bool tolocal = (to == server->id_entry);
398 SILC_LOG_DEBUG(("Start"));
400 if (!silc_idcache_get_all(server->local_list->servers, &list))
403 if (silc_idcache_list_first(list, &id_cache)) {
405 server_entry = (SilcServerEntry)id_cache->context;
406 if (server_entry != from &&
407 (tolocal || server_entry != server->id_entry) &&
408 SILC_ID_COMPARE(server_entry->id, client->id,
409 client->id->ip.data_len)) {
410 SILC_LOG_DEBUG(("Found (local) %s",
411 silc_id_render(server_entry->id, SILC_ID_SERVER)));
413 if (!server_entry->data.send_key && server_entry->router) {
414 SILC_LOG_DEBUG(("Server not locally connected, use its router"));
415 /* If the client is not marked as local then move it to local list
416 since the server is local. */
418 SILC_LOG_DEBUG(("Moving client to local list"));
419 silc_idcache_add(server->local_list->clients, client_cache->name,
420 client_cache->id, client_cache->context,
421 client_cache->expire, NULL);
422 silc_idcache_del_by_context(server->global_list->clients, client);
424 server_entry = server_entry->router;
426 SILC_LOG_DEBUG(("Server locally connected"));
427 /* If the client is not marked as local then move it to local list
428 since the server is local. */
429 if (server_entry->server_type != SILC_BACKUP_ROUTER && !local) {
430 SILC_LOG_DEBUG(("Moving client to local list"));
431 silc_idcache_add(server->local_list->clients, client_cache->name,
432 client_cache->id, client_cache->context,
433 client_cache->expire, NULL);
434 silc_idcache_del_by_context(server->global_list->clients, client);
436 } else if (server->server_type == SILC_BACKUP_ROUTER && local) {
437 /* If we are backup router and this client is on local list, we
438 must move it to global list, as it is not currently local to
439 us (we are not primary). */
440 SILC_LOG_DEBUG(("Moving client to global list"));
441 silc_idcache_add(server->global_list->clients, client_cache->name,
442 client_cache->id, client_cache->context,
443 client_cache->expire, NULL);
444 silc_idcache_del_by_context(server->local_list->clients, client);
448 silc_idcache_list_free(list);
452 if (!silc_idcache_list_next(list, &id_cache))
457 silc_idcache_list_free(list);
459 if (!silc_idcache_get_all(server->global_list->servers, &list))
462 if (silc_idcache_list_first(list, &id_cache)) {
464 server_entry = (SilcServerEntry)id_cache->context;
465 if (server_entry != from && server_entry != server->id_entry &&
466 (tolocal || server_entry != server->id_entry) &&
467 SILC_ID_COMPARE(server_entry->id, client->id,
468 client->id->ip.data_len)) {
469 SILC_LOG_DEBUG(("Found (global) %s",
470 silc_id_render(server_entry->id, SILC_ID_SERVER)));
472 if (!server_entry->data.send_key && server_entry->router) {
473 SILC_LOG_DEBUG(("Server not locally connected, use its router"));
474 /* If the client is marked as local then move it to global list
475 since the server is global. */
477 SILC_LOG_DEBUG(("Moving client to global list"));
478 silc_idcache_add(server->global_list->clients, client_cache->name,
479 client_cache->id, client_cache->context, 0, NULL);
480 silc_idcache_del_by_context(server->local_list->clients, client);
482 server_entry = server_entry->router;
484 SILC_LOG_DEBUG(("Server locally connected"));
485 /* If the client is marked as local then move it to global list
486 since the server is global. */
487 if (server_entry->server_type != SILC_BACKUP_ROUTER && local) {
488 SILC_LOG_DEBUG(("Moving client to global list"));
489 silc_idcache_add(server->global_list->clients, client_cache->name,
490 client_cache->id, client_cache->context, 0, NULL);
491 silc_idcache_del_by_context(server->local_list->clients, client);
495 silc_idcache_list_free(list);
499 if (!silc_idcache_list_next(list, &id_cache))
504 silc_idcache_list_free(list);
509 /* Updates the clients that are originated from the `from' to be originated
510 from the `to'. If the `resolve_real_server' is TRUE then this will
511 attempt to figure out which clients really are originated from the
512 `from' and which are originated from a server that we have connection
513 to, when we've acting as backup router. If it is FALSE the `to' will
514 be the new source. */
516 void silc_server_update_clients_by_server(SilcServer server,
517 SilcServerEntry from,
519 bool resolve_real_server)
521 SilcIDCacheList list = NULL;
522 SilcIDCacheEntry id_cache = NULL;
523 SilcClientEntry client = NULL;
526 if (from && from->id) {
527 SILC_LOG_DEBUG(("Changing from server %s",
528 silc_id_render(from->id, SILC_ID_SERVER)));
531 SILC_LOG_DEBUG(("Changing to server %s",
532 silc_id_render(to->id, SILC_ID_SERVER)));
535 SILC_LOG_DEBUG(("global list"));
537 if (silc_idcache_get_all(server->global_list->clients, &list)) {
538 if (silc_idcache_list_first(list, &id_cache)) {
540 client = (SilcClientEntry)id_cache->context;
542 /* If entry is disabled skip it. If entry is local to us, do not
543 switch it to anyone else, it is ours so skip it. */
544 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) ||
545 SILC_IS_LOCAL(client)) {
546 if (!silc_idcache_list_next(list, &id_cache))
552 SILC_LOG_DEBUG(("Client %s",
553 silc_id_render(client->id, SILC_ID_CLIENT)));
554 if (client->router && client->router->id)
555 SILC_LOG_DEBUG(("Client->router %s",
556 silc_id_render(client->router->id, SILC_ID_SERVER)));
559 if (client->router == from) {
560 if (resolve_real_server) {
562 silc_server_update_clients_by_real_server(server, from, to,
565 if (!client->router) {
566 if (server->server_type == SILC_ROUTER)
567 client->router = from;
576 /* All are changed */
577 if (resolve_real_server)
578 /* Call this so that the entry is moved to correct list if
579 needed. No resolving by real server is actually done. */
580 silc_server_update_clients_by_real_server(server, NULL, to,
587 if (client->router && client->router->id)
588 SILC_LOG_DEBUG(("Client changed to %s",
589 silc_id_render(client->router->id, SILC_ID_SERVER)));
591 if (!silc_idcache_list_next(list, &id_cache))
595 silc_idcache_list_free(list);
598 SILC_LOG_DEBUG(("local list"));
600 if (silc_idcache_get_all(server->local_list->clients, &list)) {
601 if (silc_idcache_list_first(list, &id_cache)) {
603 client = (SilcClientEntry)id_cache->context;
605 /* If entry is disabled skip it. If entry is local to us, do not
606 switch it to anyone else, it is ours so skip it. */
607 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) ||
608 SILC_IS_LOCAL(client)) {
609 if (!silc_idcache_list_next(list, &id_cache))
615 SILC_LOG_DEBUG(("Client %s",
616 silc_id_render(client->id, SILC_ID_CLIENT)));
617 if (client->router && client->router->id)
618 SILC_LOG_DEBUG(("Client->router %s",
619 silc_id_render(client->router->id, SILC_ID_SERVER)));
622 if (client->router == from) {
623 if (resolve_real_server) {
625 silc_server_update_clients_by_real_server(server, from, to,
629 client->router = from;
635 /* All are changed */
636 if (resolve_real_server)
637 /* Call this so that the entry is moved to correct list if
638 needed. No resolving by real server is actually done. */
639 silc_server_update_clients_by_real_server(server, NULL, to,
646 if (client->router && client->router->id)
647 SILC_LOG_DEBUG(("Client changed to %s",
648 silc_id_render(client->router->id, SILC_ID_SERVER)));
650 if (!silc_idcache_list_next(list, &id_cache))
654 silc_idcache_list_free(list);
658 /* Updates servers that are from `from' to be originated from `to'. This
659 will also update the server's connection to `to's connection. */
661 void silc_server_update_servers_by_server(SilcServer server,
662 SilcServerEntry from,
665 SilcIDCacheList list = NULL;
666 SilcIDCacheEntry id_cache = NULL;
667 SilcServerEntry server_entry = NULL;
669 SILC_LOG_DEBUG(("Updating servers"));
671 if (silc_idcache_get_all(server->local_list->servers, &list)) {
672 if (silc_idcache_list_first(list, &id_cache)) {
674 server_entry = (SilcServerEntry)id_cache->context;
676 /* If entry is local to us, do not switch it to any anyone else,
678 if (SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry ||
679 server_entry == from) {
680 if (!silc_idcache_list_next(list, &id_cache))
686 /* If we are standalone router, any server that is not directly
687 connected to cannot exist anymore. If we are not standalone
688 we update it correctly. */
689 if (server->server_type == SILC_ROUTER && server->standalone) {
690 silc_server_backup_del(server, server_entry);
691 silc_server_backup_replaced_del(server, server_entry);
692 silc_idlist_del_data(server_entry);
693 silc_idlist_del_server(server->local_list, server_entry);
694 server->stat.servers--;
695 server->stat.cell_servers--;
697 /* XXX if we are not standalone, do a check from local config
698 whether this server is in our cell, but not connected to
699 us (in which case we must remove it). */
702 if (server_entry->router == from) {
703 SILC_LOG_DEBUG(("Updating server (local) %s",
704 server_entry->server_name ?
705 server_entry->server_name : ""));
706 server_entry->router = to;
707 server_entry->connection = to->connection;
711 SILC_LOG_DEBUG(("Updating server (local) %s",
712 server_entry->server_name ?
713 server_entry->server_name : ""));
714 server_entry->router = to;
715 server_entry->connection = to->connection;
719 if (!silc_idcache_list_next(list, &id_cache))
723 silc_idcache_list_free(list);
726 if (silc_idcache_get_all(server->global_list->servers, &list)) {
727 if (silc_idcache_list_first(list, &id_cache)) {
729 server_entry = (SilcServerEntry)id_cache->context;
731 /* If entry is local to us, do not switch it to anyone else,
733 if (SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry ||
734 server_entry == from) {
735 if (!silc_idcache_list_next(list, &id_cache))
741 /* If we are standalone router, any server that is not directly
742 connected to cannot exist anymore. If we are not standalone
743 we update it correctly. */
744 if (server->server_type == SILC_ROUTER && server->standalone) {
745 silc_server_backup_del(server, server_entry);
746 silc_server_backup_replaced_del(server, server_entry);
747 silc_idlist_del_data(server_entry);
748 silc_idlist_del_server(server->global_list, server_entry);
749 server->stat.servers--;
750 server->stat.cell_servers--;
752 /* XXX if we are not standalone, do a check from local config
753 whether this server is in our cell, but not connected to
754 us (in which case we must remove it). */
757 if (server_entry->router == from) {
758 SILC_LOG_DEBUG(("Updating server (global) %s",
759 server_entry->server_name ?
760 server_entry->server_name : ""));
761 server_entry->router = to;
762 server_entry->connection = to->connection;
766 SILC_LOG_DEBUG(("Updating server (global) %s",
767 server_entry->server_name ?
768 server_entry->server_name : ""));
769 server_entry->router = to;
770 server_entry->connection = to->connection;
774 if (!silc_idcache_list_next(list, &id_cache))
778 silc_idcache_list_free(list);
783 /* Toggles the enabled/disabled status of local server connections. Packets
784 can be sent to the servers when `toggle_enabled' is TRUE and will be
785 dropped if `toggle_enabled' is FALSE, after this function is called. */
787 void silc_server_local_servers_toggle_enabled(SilcServer server,
790 SilcIDCacheList list = NULL;
791 SilcIDCacheEntry id_cache = NULL;
792 SilcServerEntry server_entry = NULL;
794 if (silc_idcache_get_all(server->local_list->servers, &list)) {
795 if (silc_idcache_list_first(list, &id_cache)) {
797 server_entry = (SilcServerEntry)id_cache->context;
798 if (!SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry) {
799 if (!silc_idcache_list_next(list, &id_cache))
806 server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
808 server_entry->data.status |= SILC_IDLIST_STATUS_DISABLED;
810 if (!silc_idcache_list_next(list, &id_cache))
814 silc_idcache_list_free(list);
817 if (silc_idcache_get_all(server->global_list->servers, &list)) {
818 if (silc_idcache_list_first(list, &id_cache)) {
820 server_entry = (SilcServerEntry)id_cache->context;
821 if (!SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry) {
822 if (!silc_idcache_list_next(list, &id_cache))
829 server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
831 server_entry->data.status |= SILC_IDLIST_STATUS_DISABLED;
833 if (!silc_idcache_list_next(list, &id_cache))
837 silc_idcache_list_free(list);
841 /* Removes servers that are originated from the `from'. The server
842 entry is deleted in this function. If `remove_clients' is TRUE then
843 all clients originated from the server are removed too, and server
844 signoff is sent. Note that this does not remove the `from'. This
845 also does not remove locally connected servers. */
847 void silc_server_remove_servers_by_server(SilcServer server,
848 SilcServerEntry from,
851 SilcIDCacheList list = NULL;
852 SilcIDCacheEntry id_cache = NULL;
853 SilcServerEntry server_entry = NULL;
855 SILC_LOG_DEBUG(("Removing servers by %s",
856 from->server_name ? from->server_name : "server"));
858 if (silc_idcache_get_all(server->local_list->servers, &list)) {
859 if (silc_idcache_list_first(list, &id_cache)) {
861 server_entry = (SilcServerEntry)id_cache->context;
862 if (SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry ||
863 server_entry->router != from || server_entry == from) {
864 if (!silc_idcache_list_next(list, &id_cache))
870 /* Remove clients owned by this server */
872 silc_server_remove_clients_by_server(server, from, server_entry,
875 /* Remove the server */
876 silc_server_backup_del(server, server_entry);
877 silc_idlist_del_server(server->local_list, server_entry);
879 if (!silc_idcache_list_next(list, &id_cache))
883 silc_idcache_list_free(list);
886 if (silc_idcache_get_all(server->global_list->servers, &list)) {
887 if (silc_idcache_list_first(list, &id_cache)) {
889 server_entry = (SilcServerEntry)id_cache->context;
890 if (SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry ||
891 server_entry->router != from || server_entry == from) {
892 if (!silc_idcache_list_next(list, &id_cache))
898 /* Remove clients owned by this server */
900 silc_server_remove_clients_by_server(server, from, server_entry,
903 /* Remove the server */
904 silc_server_backup_del(server, server_entry);
905 silc_idlist_del_server(server->global_list, server_entry);
907 if (!silc_idcache_list_next(list, &id_cache))
911 silc_idcache_list_free(list);
915 /* Removes channels that are from `from. */
917 void silc_server_remove_channels_by_server(SilcServer server,
918 SilcServerEntry from)
920 SilcIDCacheList list = NULL;
921 SilcIDCacheEntry id_cache = NULL;
922 SilcChannelEntry channel = NULL;
924 SILC_LOG_DEBUG(("Removing channels by server"));
926 if (silc_idcache_get_all(server->global_list->channels, &list)) {
927 if (silc_idcache_list_first(list, &id_cache)) {
929 channel = (SilcChannelEntry)id_cache->context;
930 if (channel->router == from)
931 silc_idlist_del_channel(server->global_list, channel);
932 if (!silc_idcache_list_next(list, &id_cache))
936 silc_idcache_list_free(list);
940 /* Updates channels that are from `from' to be originated from `to'. */
942 void silc_server_update_channels_by_server(SilcServer server,
943 SilcServerEntry from,
946 SilcIDCacheList list = NULL;
947 SilcIDCacheEntry id_cache = NULL;
948 SilcChannelEntry channel = NULL;
950 SILC_LOG_DEBUG(("Updating channels by server"));
952 if (silc_idcache_get_all(server->global_list->channels, &list)) {
953 if (silc_idcache_list_first(list, &id_cache)) {
955 channel = (SilcChannelEntry)id_cache->context;
957 if (channel->router == from)
958 channel->router = to;
961 channel->router = to;
963 if (!silc_idcache_list_next(list, &id_cache))
967 silc_idcache_list_free(list);
971 /* Checks whether given channel has global users. If it does this returns
972 TRUE and FALSE if there is only locally connected clients on the channel. */
974 bool silc_server_channel_has_global(SilcChannelEntry channel)
976 SilcChannelClientEntry chl;
977 SilcHashTableList htl;
979 silc_hash_table_list(channel->user_list, &htl);
980 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
981 if (chl->client->router) {
982 silc_hash_table_list_reset(&htl);
986 silc_hash_table_list_reset(&htl);
991 /* Checks whether given channel has locally connected users. If it does this
992 returns TRUE and FALSE if there is not one locally connected client. */
994 bool silc_server_channel_has_local(SilcChannelEntry channel)
996 SilcChannelClientEntry chl;
997 SilcHashTableList htl;
999 silc_hash_table_list(channel->user_list, &htl);
1000 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
1001 if (SILC_IS_LOCAL(chl->client)) {
1002 silc_hash_table_list_reset(&htl);
1006 silc_hash_table_list_reset(&htl);
1011 /* This function removes the channel and all users on the channel, unless
1012 the channel is permanent. In this case the channel is disabled but all
1013 users are removed from the channel. Returns TRUE if the channel is
1014 destroyed totally, and FALSE if it is permanent and remains. */
1016 bool silc_server_channel_delete(SilcServer server,
1017 SilcChannelEntry channel)
1019 SilcChannelClientEntry chl;
1020 SilcHashTableList htl;
1021 bool delchan = !(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH);
1024 /* Update statistics */
1025 if (server->server_type == SILC_ROUTER)
1026 server->stat.chanclients -= channel->user_count;
1028 /* Totally delete the channel and all users on the channel. The
1029 users are deleted automatically in silc_idlist_del_channel. */
1030 channel->disabled = TRUE;
1031 silc_schedule_task_del_by_context(server->schedule, channel->rekey);
1032 if (silc_idlist_del_channel(server->local_list, channel)) {
1033 server->stat.my_channels--;
1034 if (server->server_type == SILC_ROUTER) {
1035 server->stat.channels--;
1036 server->stat.cell_channels--;
1039 if (silc_idlist_del_channel(server->global_list, channel))
1040 if (server->server_type == SILC_ROUTER)
1041 server->stat.channels--;
1047 /* Channel is permanent, do not remove it, remove only users */
1048 channel->disabled = TRUE;
1049 silc_hash_table_list(channel->user_list, &htl);
1050 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
1051 silc_hash_table_del(chl->client->channels, channel);
1052 silc_hash_table_del(channel->user_list, chl->client);
1053 channel->user_count--;
1055 /* Update statistics */
1056 if (SILC_IS_LOCAL(chl->client))
1057 server->stat.my_chanclients--;
1058 if (server->server_type == SILC_ROUTER) {
1059 server->stat.cell_chanclients--;
1060 server->stat.chanclients--;
1065 silc_hash_table_list_reset(&htl);
1067 SILC_LOG_DEBUG(("Channel %s remains", channel->channel_name));
1072 /* Returns TRUE if the given client is on the channel. FALSE if not.
1073 This works because we assure that the user list on the channel is
1074 always in up to date thus we can only check the channel list from
1075 `client' which is faster than checking the user list from `channel'. */
1077 bool silc_server_client_on_channel(SilcClientEntry client,
1078 SilcChannelEntry channel,
1079 SilcChannelClientEntry *chl)
1081 if (!client || !channel)
1084 return silc_hash_table_find(client->channels, channel, NULL,
1088 /* Checks string for bad characters and returns TRUE if they are found. */
1090 bool silc_server_name_bad_chars(const char *name, SilcUInt32 name_len)
1094 for (i = 0; i < name_len; i++) {
1095 if (!isascii(name[i]))
1097 if (name[i] <= 32) return TRUE;
1098 if (name[i] == ' ') return TRUE;
1099 if (name[i] == '*') return TRUE;
1100 if (name[i] == '?') return TRUE;
1101 if (name[i] == ',') return TRUE;
1102 if (name[i] == '@') return TRUE;
1103 if (name[i] == '!') return TRUE;
1109 /* Same as silc_server_name_bad_chars but check for channel names. */
1111 bool silc_server_name_bad_chchars(const char *name, SilcUInt32 name_len)
1115 for (i = 0; i < name_len; i++) {
1116 if (!isascii(name[i]))
1118 if (name[i] <= 32) return TRUE;
1119 if (name[i] == ' ') return TRUE;
1120 if (name[i] == '*') return TRUE;
1121 if (name[i] == '?') return TRUE;
1122 if (name[i] == ',') return TRUE;
1128 /* Modifies the `name' if it includes bad characters and returns new
1129 allocated name that does not include bad characters. */
1131 char *silc_server_name_modify_bad(const char *name, SilcUInt32 name_len)
1134 char *newname = strdup(name);
1136 for (i = 0; i < name_len; i++) {
1137 if (!isascii(newname[i])) newname[i] = '_';
1138 if (newname[i] <= 32) newname[i] = '_';
1139 if (newname[i] == ' ') newname[i] = '_';
1140 if (newname[i] == '*') newname[i] = '_';
1141 if (newname[i] == '?') newname[i] = '_';
1142 if (newname[i] == ',') newname[i] = '_';
1148 /* Find number of sockets by IP address indicated by `ip'. Returns 0 if
1149 socket connections with the IP address does not exist. */
1151 SilcUInt32 silc_server_num_sockets_by_ip(SilcServer server, const char *ip,
1152 SilcSocketType type)
1156 for (i = 0, count = 0; i < server->config->param.connections_max; i++) {
1157 if (server->sockets[i] && !SILC_IS_LISTENER(server->sockets[i]) &&
1158 !strcmp(server->sockets[i]->ip, ip) &&
1159 server->sockets[i]->type == type)
1166 /* Find number of sockets by IP address indicated by remote host, indicatd
1167 by `ip' or `hostname', `port', and `type'. Returns 0 if socket connections
1168 does not exist. If `ip' is provided then `hostname' is ignored. */
1170 SilcUInt32 silc_server_num_sockets_by_remote(SilcServer server,
1172 const char *hostname,
1174 SilcSocketType type)
1178 if (!ip && !hostname)
1181 for (i = 0, count = 0; i < server->config->param.connections_max; i++) {
1182 if (server->sockets[i] && !SILC_IS_LISTENER(server->sockets[i]) &&
1183 ((ip && !strcmp(server->sockets[i]->ip, ip)) ||
1184 (hostname && !strcmp(server->sockets[i]->hostname, hostname))) &&
1185 server->sockets[i]->port == port &&
1186 server->sockets[i]->type == type)
1193 /* Finds locally cached public key by the public key received in the SKE.
1194 If we have it locally cached then we trust it and will use it in the
1195 authentication protocol. Returns the locally cached public key or NULL
1196 if we do not find the public key. */
1198 SilcPublicKey silc_server_find_public_key(SilcServer server,
1199 SilcHashTable local_public_keys,
1200 SilcPublicKey remote_public_key)
1202 SilcPublicKey cached_key;
1204 SILC_LOG_DEBUG(("Find remote public key (%d keys in local cache)",
1205 silc_hash_table_count(local_public_keys)));
1207 if (!silc_hash_table_find_ext(local_public_keys, remote_public_key,
1208 (void *)&cached_key, NULL,
1209 silc_hash_public_key, NULL,
1210 silc_hash_public_key_compare, NULL)) {
1211 SILC_LOG_ERROR(("Public key not found"));
1215 SILC_LOG_DEBUG(("Found public key"));
1220 /* This returns the first public key from the table of public keys. This
1221 is used only in cases where single public key exists in the table and
1222 we want to get a pointer to it. For public key tables that has multiple
1223 keys in it the silc_server_find_public_key must be used. */
1225 SilcPublicKey silc_server_get_public_key(SilcServer server,
1226 SilcHashTable local_public_keys)
1228 SilcPublicKey cached_key;
1229 SilcHashTableList htl;
1231 SILC_LOG_DEBUG(("Start"));
1233 assert(silc_hash_table_count(local_public_keys) < 2);
1235 silc_hash_table_list(local_public_keys, &htl);
1236 if (!silc_hash_table_get(&htl, NULL, (void *)&cached_key)) {
1237 silc_hash_table_list_reset(&htl);
1240 silc_hash_table_list_reset(&htl);
1245 /* Check whether the connection `sock' is allowed to connect to us. This
1246 checks for example whether there is too much connections for this host,
1247 and required version for the host etc. */
1249 bool silc_server_connection_allowed(SilcServer server,
1250 SilcSocketConnection sock,
1251 SilcSocketType type,
1252 SilcServerConfigConnParams *global,
1253 SilcServerConfigConnParams *params,
1256 SilcUInt32 conn_number = (type == SILC_SOCKET_TYPE_CLIENT ?
1257 server->stat.my_clients :
1258 type == SILC_SOCKET_TYPE_SERVER ?
1259 server->stat.my_servers :
1260 server->stat.my_routers);
1261 SilcUInt32 num_sockets, max_hosts, max_per_host;
1262 SilcUInt32 r_protocol_version, l_protocol_version;
1263 SilcUInt32 r_software_version, l_software_version;
1264 char *r_vendor_version = NULL, *l_vendor_version;
1266 SILC_LOG_DEBUG(("Checking whether connection is allowed"));
1270 l_protocol_version =
1271 silc_version_to_num(params && params->version_protocol ?
1272 params->version_protocol :
1273 global->version_protocol);
1274 l_software_version =
1275 silc_version_to_num(params && params->version_software ?
1276 params->version_software :
1277 global->version_software);
1278 l_vendor_version = (params && params->version_software_vendor ?
1279 params->version_software_vendor :
1280 global->version_software_vendor);
1282 if (ske && silc_ske_parse_version(ske, &r_protocol_version, NULL,
1283 &r_software_version, NULL,
1284 &r_vendor_version)) {
1285 sock->version = r_protocol_version;
1287 /* Match protocol version */
1288 if (l_protocol_version && r_protocol_version &&
1289 r_protocol_version < l_protocol_version) {
1290 SILC_LOG_INFO(("Connection %s (%s) is too old version",
1291 sock->hostname, sock->ip));
1292 sock->protocol = NULL;
1293 silc_server_disconnect_remote(server, sock,
1294 SILC_STATUS_ERR_BAD_VERSION,
1295 "You support too old protocol version");
1299 /* Math software version */
1300 if (l_software_version && r_software_version &&
1301 r_software_version < l_software_version) {
1302 SILC_LOG_INFO(("Connection %s (%s) is too old version",
1303 sock->hostname, sock->ip));
1304 sock->protocol = NULL;
1305 silc_server_disconnect_remote(server, sock,
1306 SILC_STATUS_ERR_BAD_VERSION,
1307 "You support too old software version");
1311 /* Regex match vendor version */
1312 if (l_vendor_version && r_vendor_version &&
1313 !silc_string_match(l_vendor_version, r_vendor_version)) {
1314 SILC_LOG_INFO(("Connection %s (%s) is unsupported version",
1315 sock->hostname, sock->ip));
1316 sock->protocol = NULL;
1317 silc_server_disconnect_remote(server, sock,
1318 SILC_STATUS_ERR_BAD_VERSION,
1319 "Your software is not supported");
1323 silc_free(r_vendor_version);
1325 /* Check for maximum connections limit */
1327 num_sockets = silc_server_num_sockets_by_ip(server, sock->ip, type);
1328 max_hosts = (params ? params->connections_max : global->connections_max);
1329 max_per_host = (params ? params->connections_max_per_host :
1330 global->connections_max_per_host);
1332 if (max_hosts && conn_number >= max_hosts) {
1333 SILC_LOG_INFO(("Server is full, closing %s (%s) connection",
1334 sock->hostname, sock->ip));
1335 sock->protocol = NULL;
1336 silc_server_disconnect_remote(server, sock,
1337 SILC_STATUS_ERR_RESOURCE_LIMIT,
1338 "Server is full, try again later");
1342 if (num_sockets >= max_per_host) {
1343 SILC_LOG_INFO(("Too many connections from %s (%s), closing connection",
1344 sock->hostname, sock->ip));
1345 sock->protocol = NULL;
1346 silc_server_disconnect_remote(server, sock,
1347 SILC_STATUS_ERR_RESOURCE_LIMIT,
1348 "Too many connections from your host");
1355 /* Checks that client has rights to add or remove channel modes. If any
1356 of the checks fails FALSE is returned. */
1358 bool silc_server_check_cmode_rights(SilcServer server,
1359 SilcChannelEntry channel,
1360 SilcChannelClientEntry client,
1363 bool is_op = client->mode & SILC_CHANNEL_UMODE_CHANOP;
1364 bool is_fo = client->mode & SILC_CHANNEL_UMODE_CHANFO;
1366 /* Check whether has rights to change anything */
1367 if (!is_op && !is_fo)
1370 /* Check whether has rights to change everything */
1374 /* Founder implies operator */
1378 /* We know that client is channel operator, check that they are not
1379 changing anything that requires channel founder rights. Rest of the
1380 modes are available automatically for channel operator. */
1382 if (mode & SILC_CHANNEL_MODE_PRIVKEY) {
1383 if (is_op && !is_fo)
1386 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
1387 if (is_op && !is_fo)
1392 if (mode & SILC_CHANNEL_MODE_PASSPHRASE) {
1393 if (!(channel->mode & SILC_CHANNEL_MODE_PASSPHRASE)) {
1394 if (is_op && !is_fo)
1398 if (channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
1399 if (is_op && !is_fo)
1404 if (mode & SILC_CHANNEL_MODE_CIPHER) {
1405 if (!(channel->mode & SILC_CHANNEL_MODE_CIPHER)) {
1406 if (is_op && !is_fo)
1410 if (channel->mode & SILC_CHANNEL_MODE_CIPHER) {
1411 if (is_op && !is_fo)
1416 if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
1417 if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
1418 if (is_op && !is_fo)
1422 if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
1423 if (is_op && !is_fo)
1428 if (mode & SILC_CHANNEL_MODE_SILENCE_USERS) {
1429 if (!(channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS)) {
1430 if (is_op && !is_fo)
1434 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS) {
1435 if (is_op && !is_fo)
1440 if (mode & SILC_CHANNEL_MODE_SILENCE_OPERS) {
1441 if (!(channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS)) {
1442 if (is_op && !is_fo)
1446 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS) {
1447 if (is_op && !is_fo)
1452 if (mode & SILC_CHANNEL_MODE_CHANNEL_AUTH) {
1453 if (!(channel->mode & SILC_CHANNEL_MODE_CHANNEL_AUTH)) {
1454 if (is_op && !is_fo)
1458 if (channel->mode & SILC_CHANNEL_MODE_CHANNEL_AUTH) {
1459 if (is_op && !is_fo)
1467 /* Check that the client has rights to change its user mode. Returns
1468 FALSE if setting some mode is not allowed. */
1470 bool silc_server_check_umode_rights(SilcServer server,
1471 SilcClientEntry client,
1474 bool server_op = FALSE, router_op = FALSE;
1476 if (mode & SILC_UMODE_SERVER_OPERATOR) {
1477 /* Cannot set server operator mode (must use OPER command) */
1478 if (!(client->mode & SILC_UMODE_SERVER_OPERATOR))
1481 /* Remove the server operator rights */
1482 if (client->mode & SILC_UMODE_SERVER_OPERATOR)
1486 if (mode & SILC_UMODE_ROUTER_OPERATOR) {
1487 /* Cannot set router operator mode (must use SILCOPER command) */
1488 if (!(client->mode & SILC_UMODE_ROUTER_OPERATOR))
1491 /* Remove the router operator rights */
1492 if (client->mode & SILC_UMODE_ROUTER_OPERATOR)
1497 SILC_UMODE_STATS_UPDATE(server, SILC_UMODE_SERVER_OPERATOR);
1499 SILC_UMODE_STATS_UPDATE(router, SILC_UMODE_ROUTER_OPERATOR);
1504 /* This function is used to send the notify packets and motd to the
1505 incoming client connection. */
1507 void silc_server_send_connect_notifys(SilcServer server,
1508 SilcSocketConnection sock,
1509 SilcClientEntry client)
1511 SilcIDListData idata = (SilcIDListData)client;
1513 SILC_LOG_DEBUG(("Send welcome notifys"));
1515 /* Send some nice info to the client */
1516 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1517 ("Welcome to the SILC Network %s",
1519 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1520 ("Your host is %s, running version %s",
1521 server->server_name, server_version));
1523 if (server->server_type == SILC_ROUTER) {
1524 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1525 ("There are %d clients, %d servers and %d "
1526 "routers in SILC Network",
1527 server->stat.clients, server->stat.servers,
1528 server->stat.routers));
1530 if (server->stat.clients && server->stat.servers + 1)
1531 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1532 ("There are %d clients, %d servers and %d "
1533 "routers in SILC Network",
1534 server->stat.clients, server->stat.servers,
1535 (server->standalone ? 0 :
1536 !server->stat.routers ? 1 :
1537 server->stat.routers)));
1540 if (server->stat.cell_clients && server->stat.cell_servers + 1)
1541 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1542 ("There are %d clients on %d servers in our cell",
1543 server->stat.cell_clients,
1544 server->stat.cell_servers));
1545 if (server->server_type == SILC_ROUTER) {
1546 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1547 ("I have %d clients, %d channels, %d servers and "
1549 server->stat.my_clients,
1550 server->stat.my_channels,
1551 server->stat.my_servers,
1552 server->stat.my_routers));
1554 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1555 ("I have %d clients and %d channels formed",
1556 server->stat.my_clients,
1557 server->stat.my_channels));
1560 if (server->stat.server_ops || server->stat.router_ops)
1561 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1562 ("There are %d server operators and %d router "
1564 server->stat.server_ops,
1565 server->stat.router_ops));
1566 if (server->stat.my_router_ops + server->stat.my_server_ops)
1567 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1568 ("I have %d operators online",
1569 server->stat.my_router_ops +
1570 server->stat.my_server_ops));
1572 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1573 ("Your connection is secured with %s cipher, "
1574 "key length %d bits",
1575 silc_cipher_get_name(idata->send_key),
1576 silc_cipher_get_key_len(idata->send_key)));
1577 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1578 ("Your current nickname is %s",
1582 silc_server_send_motd(server, sock);
1585 /* Kill the client indicated by `remote_client' sending KILLED notify
1586 to the client, to all channels client has joined and to primary
1587 router if needed. The killed client is also removed from all channels. */
1589 void silc_server_kill_client(SilcServer server,
1590 SilcClientEntry remote_client,
1591 const char *comment,
1593 SilcIdType killer_id_type)
1595 SilcBuffer killed, killer;
1597 SILC_LOG_DEBUG(("Killing client %s",
1598 silc_id_render(remote_client->id, SILC_ID_CLIENT)));
1600 /* Send the KILL notify packets. First send it to the channel, then
1601 to our primary router and then directly to the client who is being
1602 killed right now. */
1604 killed = silc_id_payload_encode(remote_client->id, SILC_ID_CLIENT);
1605 killer = silc_id_payload_encode(killer_id, killer_id_type);
1607 /* Send KILLED notify to the channels. It is not sent to the client
1608 as it will be sent differently destined directly to the client and not
1610 silc_server_send_notify_on_channels(server, remote_client,
1611 remote_client, SILC_NOTIFY_TYPE_KILLED,
1612 3, killed->data, killed->len,
1613 comment, comment ? strlen(comment) : 0,
1614 killer->data, killer->len);
1616 /* Send KILLED notify to primary route */
1617 silc_server_send_notify_killed(server, SILC_PRIMARY_ROUTE(server),
1618 SILC_BROADCAST(server), remote_client->id,
1619 comment, killer_id, killer_id_type);
1621 /* Send KILLED notify to the client directly */
1622 if (remote_client->connection || remote_client->router)
1623 silc_server_send_notify_killed(server, remote_client->connection ?
1624 remote_client->connection :
1625 remote_client->router->connection, FALSE,
1626 remote_client->id, comment,
1627 killer_id, killer_id_type);
1629 /* Remove the client from all channels. This generates new keys to the
1630 channels as well. */
1631 silc_server_remove_from_channels(server, NULL, remote_client, FALSE,
1634 /* Remove the client entry, If it is locally connected then we will also
1635 disconnect the client here */
1636 if (remote_client->connection) {
1637 /* Remove locally conneted client */
1638 SilcSocketConnection sock = remote_client->connection;
1639 silc_server_free_client_data(server, sock, remote_client, FALSE, NULL);
1640 silc_server_close_connection(server, sock);
1642 /* Update statistics */
1643 server->stat.clients--;
1644 if (server->stat.cell_clients)
1645 server->stat.cell_clients--;
1646 SILC_OPER_STATS_UPDATE(remote_client, server, SILC_UMODE_SERVER_OPERATOR);
1647 SILC_OPER_STATS_UPDATE(remote_client, router, SILC_UMODE_ROUTER_OPERATOR);
1649 if (remote_client->data.public_key)
1650 silc_hash_table_del_by_context(server->pk_hash,
1651 remote_client->data.public_key,
1654 if (SILC_IS_LOCAL(remote_client)) {
1655 server->stat.my_clients--;
1656 silc_schedule_task_del_by_context(server->schedule, remote_client);
1657 silc_idlist_del_data(remote_client);
1660 /* Remove remote client */
1661 silc_idlist_del_data(remote_client);
1662 if (!silc_idlist_del_client(server->global_list, remote_client)) {
1663 /* Remove this client from watcher list if it is */
1664 silc_server_del_from_watcher_list(server, remote_client);
1665 silc_idlist_del_client(server->local_list, remote_client);
1669 silc_buffer_free(killer);
1670 silc_buffer_free(killed);
1675 SilcClientEntry client;
1676 SilcNotifyType notify;
1677 const char *new_nick;
1678 } WatcherNotifyContext;
1681 silc_server_check_watcher_list_foreach(void *key, void *context,
1684 WatcherNotifyContext *notify = user_context;
1685 SilcClientEntry entry = context;
1686 SilcSocketConnection sock;
1691 if (entry == notify->client)
1694 sock = silc_server_get_client_route(notify->server, NULL, 0, entry->id,
1697 SILC_LOG_DEBUG(("Sending WATCH notify to %s",
1698 silc_id_render(entry->id, SILC_ID_CLIENT)));
1700 /* Send the WATCH notify */
1701 silc_server_send_notify_watch(notify->server, sock, entry,
1703 notify->new_nick ? notify->new_nick :
1704 (const char *)notify->client->nickname,
1706 notify->client->data.public_key);
1710 /* This function checks whether the `client' nickname and/or 'client'
1711 public key is being watched by someone, and notifies the watcher of the
1712 notify change of notify type indicated by `notify'. */
1714 bool silc_server_check_watcher_list(SilcServer server,
1715 SilcClientEntry client,
1716 const char *new_nick,
1717 SilcNotifyType notify)
1719 unsigned char hash[16];
1720 WatcherNotifyContext n;
1722 SILC_LOG_DEBUG(("Checking watcher list %s",
1723 client->nickname ? client->nickname : (unsigned char *)""));
1725 /* If the watching is rejected by the client do nothing */
1726 if (client->mode & SILC_UMODE_REJECT_WATCHING)
1729 /* Make hash from the nick, or take it from Client ID */
1730 if (client->nickname) {
1731 unsigned char *nickc;
1732 nickc = silc_identifier_check(client->nickname, strlen(client->nickname),
1733 SILC_STRING_UTF8, 128, NULL);
1736 silc_hash_make(server->md5hash, nickc, strlen(nickc), hash);
1739 memset(hash, 0, sizeof(hash));
1740 memcpy(hash, client->id->hash, sizeof(client->id->hash));
1745 n.new_nick = new_nick;
1748 /* Send notify to all watchers watching this nickname */
1749 silc_hash_table_find_foreach(server->watcher_list, hash,
1750 silc_server_check_watcher_list_foreach, &n);
1752 /* Send notify to all watchers watching this public key */
1753 if (client->data.public_key)
1754 silc_hash_table_find_foreach(server->watcher_list_pk,
1755 client->data.public_key,
1756 silc_server_check_watcher_list_foreach,
1762 /* Remove the `client' from watcher list. After calling this the `client'
1763 is not watching any nicknames. */
1765 bool silc_server_del_from_watcher_list(SilcServer server,
1766 SilcClientEntry client)
1768 SilcHashTableList htl;
1770 SilcClientEntry entry;
1773 silc_hash_table_list(server->watcher_list, &htl);
1774 while (silc_hash_table_get(&htl, &key, (void *)&entry)) {
1775 if (entry == client) {
1776 silc_hash_table_del_by_context(server->watcher_list, key, client);
1779 SILC_LOG_DEBUG(("Removing %s from WATCH list",
1780 silc_id_render(client->id, SILC_ID_CLIENT)));
1782 /* Now check whether there still exists entries with this key, if not
1783 then free the key to not leak memory. */
1784 if (!silc_hash_table_find(server->watcher_list, key, NULL, NULL))
1790 silc_hash_table_list_reset(&htl);
1792 silc_hash_table_list(server->watcher_list_pk, &htl);
1793 while (silc_hash_table_get(&htl, &key, (void *)&entry)) {
1794 if (entry == client) {
1795 silc_hash_table_del_by_context(server->watcher_list_pk, key, client);
1798 SILC_LOG_DEBUG(("Removing %s from WATCH list",
1799 silc_id_render(client->id, SILC_ID_CLIENT)));
1801 /* Now check whether there still exists entries with this key, if not
1802 then free the key to not leak memory. */
1803 if (!silc_hash_table_find(server->watcher_list_pk, key, NULL, NULL))
1804 silc_pkcs_public_key_free(key);
1809 silc_hash_table_list_reset(&htl);
1814 /* Force the client indicated by `chl' to change the channel user mode
1815 on channel indicated by `channel' to `forced_mode'. */
1817 bool silc_server_force_cumode_change(SilcServer server,
1818 SilcSocketConnection sock,
1819 SilcChannelEntry channel,
1820 SilcChannelClientEntry chl,
1821 SilcUInt32 forced_mode)
1823 SilcBuffer idp1, idp2;
1824 unsigned char cumode[4];
1826 SILC_LOG_DEBUG(("Enforcing sender to change mode"));
1829 silc_server_send_notify_cumode(server, sock, FALSE, channel, forced_mode,
1830 server->id, SILC_ID_SERVER,
1831 chl->client->id, NULL);
1833 idp1 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
1834 idp2 = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
1835 SILC_PUT32_MSB(forced_mode, cumode);
1836 silc_server_send_notify_to_channel(server, sock, channel, FALSE, TRUE,
1837 SILC_NOTIFY_TYPE_CUMODE_CHANGE,
1838 3, idp1->data, idp1->len,
1839 cumode, sizeof(cumode),
1840 idp2->data, idp2->len);
1841 silc_buffer_free(idp1);
1842 silc_buffer_free(idp2);
1847 /* Find active socket connection by the IP address and port indicated by
1848 `ip' and `port', and socket connection type of `type'. */
1850 SilcSocketConnection
1851 silc_server_find_socket_by_host(SilcServer server,
1852 SilcSocketType type,
1853 const char *ip, SilcUInt16 port)
1857 for (i = 0; i < server->config->param.connections_max; i++) {
1858 if (!server->sockets[i])
1860 if (!strcmp(server->sockets[i]->ip, ip) &&
1861 (!port || server->sockets[i]->port == port) &&
1862 server->sockets[i]->type == type)
1863 return server->sockets[i];
1869 /* This function can be used to match the invite and ban lists. */
1871 bool silc_server_inviteban_match(SilcServer server, SilcHashTable list,
1872 SilcUInt8 type, void *check)
1874 unsigned char *tmp = NULL;
1875 SilcUInt32 len = 0, t;
1876 SilcHashTableList htl;
1877 SilcBuffer entry, idp = NULL, pkp = NULL;
1880 if (type < 1 || type > 3 || !check)
1884 tmp = strdup((char *)check);
1889 pkp = silc_pkcs_public_key_payload_encode(check);
1896 idp = silc_id_payload_encode(check, SILC_ID_CLIENT);
1903 /* Compare the list */
1904 silc_hash_table_list(list, &htl);
1905 while (silc_hash_table_get(&htl, (void *)&t, (void *)&entry)) {
1908 if (silc_string_match(entry->data, tmp)) {
1912 } else if (!memcmp(entry->data, tmp, len)) {
1918 silc_hash_table_list_reset(&htl);
1922 silc_buffer_free(idp);
1923 silc_buffer_free(pkp);
1927 /* Process invite or ban information */
1929 void silc_server_inviteban_process(SilcServer server, SilcHashTable list,
1930 SilcUInt8 action, SilcArgumentPayload args)
1933 SilcUInt32 type, len;
1935 SilcHashTableList htl;
1937 SILC_LOG_DEBUG(("Processing invite/ban for %s action",
1938 action == 0x01 ? "DEL" : "ADD"));
1940 /* Add the information to invite list */
1941 if (action == 0x00 || action == 0x03) {
1942 /* Traverse all arguments and add to the hash table according to
1944 tmp = silc_argument_get_first_arg(args, &type, &len);
1947 /* Invite string. Get the old invite string from hash table
1948 and append this at the end of the existing one. */
1949 if (!silc_hash_table_find(list, (void *)1, NULL, (void *)&tmp2)) {
1950 tmp2 = silc_calloc(1, sizeof(*tmp2));
1951 silc_hash_table_add(list, (void *)1, tmp2);
1954 /* Check that the string is not part of invite string already */
1955 if (action == 0x00) {
1956 if (silc_string_match(tmp2->data, tmp))
1960 if (tmp[len - 1] == ',')
1961 tmp[len - 1] = '\0';
1962 silc_buffer_strformat(tmp2, tmp, SILC_STRFMT_END);
1963 silc_buffer_strformat(tmp2, ",", SILC_STRFMT_END);
1966 /* Announced list. Check each entry in the list */
1967 unsigned char e[256];
1968 char *start, *end, *n, *rtmp;
1971 rtmp = silc_memdup(tmp, len);
1972 for (i = 0, k = 0; i < len; i++) {
1976 memset(e, 0, sizeof(e));
1977 silc_strncat(e, sizeof(e), tmp + k, i - k);
1978 if (!silc_string_match(tmp2->data, e)) {
1983 /* Matches. Delete it since we have it already */
1984 start = strstr(rtmp, e);
1985 if (start && strlen(start) >= (i - k)) {
1986 end = start + (i - k);
1987 n = silc_calloc(strlen(rtmp) - (i - k), sizeof(*n));
1988 strncat(n, rtmp, start - rtmp);
1989 if (strlen(end) > 1)
1990 strncat(n, end + 1, ((rtmp + strlen(rtmp)) - end) - 1);
1998 /* Save the part that we didn't already have. */
1999 if (strlen(rtmp) > 1) {
2000 silc_buffer_strformat(tmp2, rtmp, SILC_STRFMT_END);
2001 silc_buffer_strformat(tmp2, ",", SILC_STRFMT_END);
2006 } else if (type == 2) {
2007 /* Public key. Check first if the public key is already on the
2008 list and ignore it if it is, otherwise, add it to hash table. */
2010 /* Check if the public key is in the list already */
2011 silc_hash_table_list(list, &htl);
2012 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) {
2013 if (type == 2 && !memcmp(tmp2->data, tmp, len)) {
2018 silc_hash_table_list_reset(&htl);
2020 /* Add new public key to invite list */
2022 tmp2 = silc_buffer_alloc_size(len);
2023 silc_buffer_put(tmp2, tmp, len);
2024 silc_hash_table_add(list, (void *)2, tmp2);
2027 } else if (type == 3) {
2030 /* Check if the ID is in the list already */
2031 silc_hash_table_list(list, &htl);
2032 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) {
2033 if (type == 3 && !memcmp(tmp2->data, tmp, len)) {
2038 silc_hash_table_list_reset(&htl);
2040 /* Add new Client ID to invite list */
2042 tmp2 = silc_buffer_alloc_size(len);
2043 silc_buffer_put(tmp2, tmp, len);
2044 silc_hash_table_add(list, (void *)3, tmp2);
2048 tmp = silc_argument_get_next_arg(args, &type, &len);
2052 /* Delete information to invite list */
2053 if (action == 0x01 && list) {
2054 /* Now delete the arguments from invite list */
2055 tmp = silc_argument_get_first_arg(args, &type, &len);
2058 /* Invite string. Get the old string from hash table and delete
2059 the requested string. */
2060 char *string = NULL, *start, *end, *n;
2062 if (silc_hash_table_find(list, (void *)1, NULL, (void *)&tmp2)) {
2063 string = tmp2->head;
2064 if (tmp2->truelen && !strncmp(string, tmp, tmp2->truelen - 1)) {
2065 /* Delete entire string */
2066 silc_hash_table_del(list, (void *)1);
2067 } else if (tmp2->truelen) {
2068 /* Delete part of the string */
2069 start = strstr(string, tmp);
2070 if (start && strlen(start) >= len) {
2072 n = silc_calloc(strlen(string) - len, sizeof(*n));
2073 strncat(n, string, start - string);
2074 if (strlen(end) > 1)
2075 strncat(n, end + 1, ((string + strlen(string)) - end) - 1);
2076 silc_free(tmp2->head);
2077 silc_buffer_set(tmp2, n, strlen(n));
2082 } else if (type == 2) {
2085 /* Delete from the invite list */
2086 silc_hash_table_list(list, &htl);
2087 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) {
2088 if (type == 2 && !memcmp(tmp2->data, tmp, len)) {
2089 silc_hash_table_del_by_context(list, (void *)2, tmp2);
2093 silc_hash_table_list_reset(&htl);
2095 } else if (type == 3) {
2098 /* Delete from the invite list */
2099 silc_hash_table_list(list, &htl);
2100 while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) {
2101 if (type == 3 && !memcmp(tmp2->data, tmp, len)) {
2102 silc_hash_table_del_by_context(list, (void *)3, tmp2);
2106 silc_hash_table_list_reset(&htl);
2109 tmp = silc_argument_get_next_arg(args, &type, &len);
2114 /* Destructor for invite and ban list entrys */
2116 void silc_server_inviteban_destruct(void *key, void *context,
2119 silc_buffer_free(context);
2122 /* Creates connections accoring to configuration. */
2124 void silc_server_create_connections(SilcServer server)
2126 silc_schedule_task_del_by_callback(server->schedule,
2127 silc_server_connect_to_router);
2128 silc_schedule_task_add(server->schedule, 0,
2129 silc_server_connect_to_router, server, 0, 1,
2130 SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
2134 silc_server_process_channel_pk_destruct(void *key, void *context,
2138 silc_pkcs_public_key_free(context);
2141 /* Processes a channel public key, either adds or removes it. */
2144 silc_server_process_channel_pk(SilcServer server,
2145 SilcChannelEntry channel,
2146 SilcUInt32 type, const unsigned char *pk,
2149 unsigned char pkhash[20];
2152 SILC_LOG_DEBUG(("Processing channel public key"));
2155 return SILC_STATUS_ERR_NOT_ENOUGH_PARAMS;
2157 /* Decode the public key */
2158 if (!silc_pkcs_public_key_payload_decode((unsigned char *)pk, pk_len, &chpk))
2159 return SILC_STATUS_ERR_UNSUPPORTED_PUBLIC_KEY;
2161 /* Create channel public key list (hash table) if needed */
2162 if (!channel->channel_pubkeys) {
2163 channel->channel_pubkeys =
2164 silc_hash_table_alloc(0, silc_hash_data, (void *)20,
2165 silc_hash_data_compare, (void *)20,
2166 silc_server_process_channel_pk_destruct, channel,
2170 /* Create SHA-1 digest of the public key data */
2171 silc_hash_make(server->sha1hash, pk + 4, pk_len - 4, pkhash);
2174 /* Add new public key to channel public key list */
2175 SILC_LOG_DEBUG(("Add new channel public key to channel %s",
2176 channel->channel_name));
2178 /* Check for resource limit */
2179 if (silc_hash_table_count(channel->channel_pubkeys) > 64) {
2180 silc_pkcs_public_key_free(chpk);
2181 return SILC_STATUS_ERR_RESOURCE_LIMIT;
2184 /* Add if doesn't exist already */
2185 if (!silc_hash_table_find(channel->channel_pubkeys, pkhash,
2187 silc_hash_table_add(channel->channel_pubkeys, silc_memdup(pkhash, 20),
2189 } else if (type == 0x01) {
2190 /* Delete public key from channel public key list */
2191 SILC_LOG_DEBUG(("Delete a channel public key from channel %s",
2192 channel->channel_name));
2193 if (!silc_hash_table_del(channel->channel_pubkeys, pkhash))
2194 silc_pkcs_public_key_free(chpk);
2196 silc_pkcs_public_key_free(chpk);
2197 return SILC_STATUS_ERR_NOT_ENOUGH_PARAMS;
2200 return SILC_STATUS_OK;
2203 /* Returns the channel public keys as Argument List payload. */
2205 SilcBuffer silc_server_get_channel_pk_list(SilcServer server,
2206 SilcChannelEntry channel,
2210 SilcHashTableList htl;
2211 SilcBuffer list, pkp;
2214 SILC_LOG_DEBUG(("Encoding channel public keys list"));
2216 if (!channel->channel_pubkeys ||
2217 !silc_hash_table_count(channel->channel_pubkeys))
2220 /* Encode the list */
2221 list = silc_buffer_alloc_size(2);
2222 silc_buffer_format(list,
2223 SILC_STR_UI_SHORT(silc_hash_table_count(
2224 channel->channel_pubkeys)),
2227 silc_hash_table_list(channel->channel_pubkeys, &htl);
2228 while (silc_hash_table_get(&htl, NULL, (void *)&pk)) {
2229 pkp = silc_pkcs_public_key_payload_encode(pk);
2230 list = silc_argument_payload_encode_one(list, pkp->data, pkp->len,
2232 delete ? 0x01 : 0x00);
2233 silc_buffer_free(pkp);
2235 silc_hash_table_list_reset(&htl);
2240 /* Sets the channel public keys into channel from the list of public keys. */
2242 SilcStatus silc_server_set_channel_pk_list(SilcServer server,
2243 SilcSocketConnection sender,
2244 SilcChannelEntry channel,
2245 const unsigned char *pklist,
2246 SilcUInt32 pklist_len)
2249 SilcArgumentPayload args;
2250 unsigned char *chpk;
2251 SilcUInt32 chpklen, type;
2252 SilcStatus ret = SILC_STATUS_OK;
2254 SILC_LOG_DEBUG(("Setting channel public keys list"));
2256 if (!pklist || pklist_len < 2)
2257 return SILC_STATUS_ERR_NOT_ENOUGH_PARAMS;
2259 /* Get the argument from the Argument List Payload */
2260 SILC_GET16_MSB(argc, pklist);
2261 args = silc_argument_payload_parse(pklist + 2, pklist_len - 2, argc);
2263 return SILC_STATUS_ERR_NOT_ENOUGH_PARAMS;
2265 /* Process the public keys one by one */
2266 chpk = silc_argument_get_first_arg(args, &type, &chpklen);
2268 /* If announcing keys and we have them set already, do not allow this */
2269 if (chpk && type == 0x03 && channel->channel_pubkeys &&
2270 server->server_type == SILC_ROUTER &&
2271 sender != SILC_PRIMARY_ROUTE(server)) {
2272 SILC_LOG_DEBUG(("Channel public key list set already, enforce our list"));
2273 silc_argument_payload_free(args);
2274 return SILC_STATUS_ERR_OPERATION_ALLOWED;
2277 /* If we are normal server and receive announcement list and we already
2278 have keys set, we replace the old list with the announced one. */
2279 if (chpk && type == 0x03 && channel->channel_pubkeys &&
2280 server->server_type != SILC_ROUTER) {
2282 unsigned char mask[4], ulimit[4];
2284 SILC_LOG_DEBUG(("Router enforces its list, remove old list"));
2285 silc_hash_table_free(channel->channel_pubkeys);
2286 channel->channel_pubkeys = NULL;
2288 /* Send notify that removes the old list */
2289 sidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
2290 SILC_PUT32_MSB((channel->mode & (~SILC_CHANNEL_MODE_CHANNEL_AUTH)), mask);
2291 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
2292 SILC_PUT32_MSB(channel->user_limit, ulimit);
2293 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
2294 SILC_NOTIFY_TYPE_CMODE_CHANGE, 8,
2295 sidp->data, sidp->len,
2299 strlen(channel->cipher) : 0,
2301 channel->hmac_name ?
2302 strlen(channel->hmac_name) : 0,
2303 channel->passphrase,
2304 channel->passphrase ?
2305 strlen(channel->passphrase) : 0,
2308 SILC_CHANNEL_MODE_ULIMIT ?
2311 SILC_CHANNEL_MODE_ULIMIT ?
2312 sizeof(ulimit) : 0));
2313 silc_buffer_free(sidp);
2319 ret = silc_server_process_channel_pk(server, channel, type,
2321 if (ret != SILC_STATUS_OK)
2323 chpk = silc_argument_get_next_arg(args, &type, &chpklen);
2326 silc_argument_payload_free(args);
2330 /* Verifies the Authentication Payload `auth' with one of the public keys
2331 on the `channel' public key list. */
2333 bool silc_server_verify_channel_auth(SilcServer server,
2334 SilcChannelEntry channel,
2335 SilcClientID *client_id,
2336 const unsigned char *auth,
2337 SilcUInt32 auth_len)
2341 unsigned char *pkhash;
2342 SilcUInt32 pkhash_len;
2345 SILC_LOG_DEBUG(("Verifying channel authentication"));
2347 if (!auth || !auth_len || !channel->channel_pubkeys)
2350 /* Get the hash from the auth data which tells us what public key we
2351 must use in verification. */
2353 ap = silc_auth_payload_parse(auth, auth_len);
2357 pkhash = silc_auth_get_public_data(ap, &pkhash_len);
2358 if (pkhash_len < 128)
2361 /* Find the public key with the hash */
2362 if (!silc_hash_table_find(channel->channel_pubkeys, pkhash,
2363 NULL, (void *)&chpk)) {
2364 SILC_LOG_DEBUG(("Public key not found in channel public key list"));
2368 /* Verify the signature */
2369 if (!silc_auth_verify(ap, SILC_AUTH_PUBLIC_KEY, (void *)chpk, 0,
2370 server->sha1hash, client_id, SILC_ID_CLIENT)) {
2371 SILC_LOG_DEBUG(("Authentication failed"));
2378 silc_auth_payload_free(ap);