In signoff assure that channel key is present before sending it.
[silc.git] / apps / silcd / server_util.c
1 /*
2
3   server_util.c 
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 1997 - 2002 Pekka Riikonen
8
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.
12
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.
17
18 */
19 /* $Id$ */
20
21 #include "serverincludes.h"
22 #include "server_internal.h"
23
24 extern char *server_version;
25
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. */
30
31 static void
32 silc_server_remove_clients_channels(SilcServer server,
33                                     SilcServerEntry server_entry,
34                                     SilcHashTable clients,
35                                     SilcClientEntry client,
36                                     SilcHashTable channels)
37 {
38   SilcChannelEntry channel;
39   SilcChannelClientEntry chl, chl2;
40   SilcHashTableList htl, htl2;
41
42   if (!client)
43     return;
44
45   SILC_LOG_DEBUG(("Remove client from all channels"));
46
47   if (silc_hash_table_find(clients, client, NULL, NULL))
48     silc_hash_table_del(clients, client);
49
50   /* Remove the client from all channels. The client is removed from
51      the channels' user list. */
52   silc_hash_table_list(client->channels, &htl);
53   while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
54     channel = chl->channel;
55
56     /* Remove channel if this is last client leaving the channel, unless
57        the channel is permanent. */
58     if (server->server_type != SILC_SERVER &&
59         silc_hash_table_count(channel->user_list) < 2) {
60       if (silc_hash_table_find(channels, channel, NULL, NULL))
61         silc_hash_table_del(channels, channel);
62       silc_schedule_task_del_by_context(server->schedule, channel->rekey);
63       silc_server_channel_delete(server, channel);
64       continue;
65     }
66
67     silc_hash_table_del(client->channels, channel);
68     silc_hash_table_del(channel->user_list, chl->client);
69     channel->user_count--;
70
71     /* If there is no global users on the channel anymore mark the channel
72        as local channel. Do not check if the removed client is local client. */
73     if (server->server_type != SILC_ROUTER && channel->global_users && 
74         chl->client->router && !silc_server_channel_has_global(channel))
75       channel->global_users = FALSE;
76
77     silc_free(chl);
78
79     /* Update statistics */
80     if (SILC_IS_LOCAL(client))
81       server->stat.my_chanclients--;
82     if (server->server_type == SILC_ROUTER) {
83       server->stat.cell_chanclients--;
84       server->stat.chanclients--;
85     }
86
87     /* If there is not at least one local user on the channel then we don't
88        need the channel entry anymore, we can remove it safely, unless the
89        channel is permanent channel */
90     if (server->server_type == SILC_SERVER &&
91         !silc_server_channel_has_local(channel)) {
92       if (silc_hash_table_find(channels, channel, NULL, NULL))
93         silc_hash_table_del(channels, channel);
94       silc_schedule_task_del_by_context(server->schedule, channel->rekey);
95       silc_server_channel_delete(server, channel);
96       continue;
97     }
98
99     /* Mark other local clients to the table of clients whom will receive
100        the SERVER_SIGNOFF notify. */
101     silc_hash_table_list(channel->user_list, &htl2);
102     while (silc_hash_table_get(&htl2, NULL, (void **)&chl2)) {
103       SilcClientEntry c = chl2->client;
104       if (!c)
105         continue;
106
107       /* Add client to table, if it's not from the signoff server */
108       if (c->router != server_entry &&
109           !silc_hash_table_find(clients, c, NULL, NULL))
110         silc_hash_table_add(clients, c, c);
111     }
112     silc_hash_table_list_reset(&htl2);
113
114     /* Add the channel to the the channels list to regenerate the 
115        channel key */
116     if (!silc_hash_table_find(channels, channel, NULL, NULL))
117       silc_hash_table_add(channels, channel, channel);
118   }
119   silc_hash_table_list_reset(&htl);
120 }
121
122 /* This function removes all client entries that are originated from
123    `router' and are owned by `entry'.  `router' and `entry' can be same
124    too.  If `server_signoff' is TRUE then SERVER_SIGNOFF notify is 
125    distributed to our local clients. */
126
127 bool silc_server_remove_clients_by_server(SilcServer server,
128                                           SilcServerEntry router,
129                                           SilcServerEntry entry,
130                                           bool server_signoff)
131 {
132   SilcIDCacheList list = NULL;
133   SilcIDCacheEntry id_cache = NULL;
134   SilcClientEntry client = NULL;
135   SilcBuffer idp;
136   unsigned char **argv = NULL;
137   SilcUInt32 *argv_lens = NULL, *argv_types = NULL, argc = 0;
138   SilcHashTableList htl;
139   SilcChannelEntry channel;
140   SilcHashTable channels, clients;
141   int i;
142
143   if (!(entry->data.status & SILC_IDLIST_STATUS_REGISTERED))
144     return FALSE;
145
146   SILC_LOG_DEBUG(("Removing clients by %s",
147                   entry->server_name ? entry->server_name : "server"));
148
149   if (!router)
150     router = entry;
151
152   /* Allocate the hash table that holds the channels that require
153      channel key re-generation after we've removed this server's clients
154      from the channels. */
155   channels = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL, NULL,
156                                    NULL, NULL, TRUE);
157   clients = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL, NULL,
158                                   NULL, NULL, TRUE);
159
160   if (server_signoff) {
161     idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
162     argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
163     argv_lens = silc_realloc(argv_lens,  sizeof(*argv_lens) * (argc + 1));
164     argv_types = silc_realloc(argv_types, sizeof(*argv_types) * (argc + 1));
165     argv[argc] = silc_calloc(idp->len, sizeof(*argv[0]));
166     memcpy(argv[argc], idp->data, idp->len);
167     argv_lens[argc] = idp->len;
168     argv_types[argc] = argc + 1;
169     argc++;
170     silc_buffer_free(idp);
171   }
172
173   if (silc_idcache_get_all(server->local_list->clients, &list)) {
174     if (silc_idcache_list_first(list, &id_cache)) {
175       while (id_cache) {
176         client = (SilcClientEntry)id_cache->context;
177
178         /* If client is not registered, is not originated from `router'
179            and is not owned by `entry', skip it. */
180         if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) ||
181             client->router != router ||
182             (router != entry && !SILC_ID_COMPARE(client->id, entry->id,
183                                                  client->id->ip.data_len))) {
184           if (!silc_idcache_list_next(list, &id_cache))
185             break;
186           else
187             continue;
188         }
189
190         if (server_signoff) {
191           idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
192           argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
193           argv_lens = silc_realloc(argv_lens, sizeof(*argv_lens) *
194                                    (argc + 1));
195           argv_types = silc_realloc(argv_types, sizeof(*argv_types) *
196                                     (argc + 1));
197           argv[argc] = silc_calloc(idp->len, sizeof(*argv[0]));
198           memcpy(argv[argc], idp->data, idp->len);
199           argv_lens[argc] = idp->len;
200           argv_types[argc] = argc + 1;
201           argc++;
202           silc_buffer_free(idp);
203         }
204
205         /* Update statistics */
206         server->stat.clients--;
207         if (server->stat.cell_clients)
208           server->stat.cell_clients--;
209         SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
210         SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
211
212         silc_server_remove_clients_channels(server, entry, clients,
213                                             client, channels);
214         silc_server_del_from_watcher_list(server, client);
215
216         /* Remove the client entry */
217         if (!server_signoff) {
218           client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
219           id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
220         } else {
221           silc_idlist_del_data(client);
222           silc_idlist_del_client(server->local_list, client);
223         }
224
225         if (!silc_idcache_list_next(list, &id_cache))
226           break;
227       }
228     }
229     silc_idcache_list_free(list);
230   }
231   
232   if (silc_idcache_get_all(server->global_list->clients, &list)) {
233
234     if (silc_idcache_list_first(list, &id_cache)) {
235       while (id_cache) {
236         client = (SilcClientEntry)id_cache->context;
237
238         /* If client is not registered, is not originated from `router'
239            and is not owned by `entry', skip it. */
240         if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) ||
241             client->router != router ||
242             (router != entry && !SILC_ID_COMPARE(client->id, entry->id,
243                                                  client->id->ip.data_len))) {
244           if (!silc_idcache_list_next(list, &id_cache))
245             break;
246           else
247             continue;
248         }
249
250         if (server_signoff) {
251           idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
252           argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
253           argv_lens = silc_realloc(argv_lens, sizeof(*argv_lens) *
254                                    (argc + 1));
255           argv_types = silc_realloc(argv_types, sizeof(*argv_types) *
256                                     (argc + 1));
257           argv[argc] = silc_calloc(idp->len, sizeof(*argv[0]));
258           memcpy(argv[argc], idp->data, idp->len);
259           argv_lens[argc] = idp->len;
260           argv_types[argc] = argc + 1;
261           argc++;
262           silc_buffer_free(idp);
263         }
264
265         /* Update statistics */
266         server->stat.clients--;
267         if (server->stat.cell_clients)
268           server->stat.cell_clients--;
269         SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
270         SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
271
272         silc_server_remove_clients_channels(server, entry, clients,
273                                             client, channels);
274         silc_server_del_from_watcher_list(server, client);
275
276         /* Remove the client entry */
277         if (!server_signoff) {
278           client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
279           id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
280         } else {
281           silc_idlist_del_data(client);
282           silc_idlist_del_client(server->global_list, client);
283         }
284
285         if (!silc_idcache_list_next(list, &id_cache))
286           break;
287       }
288     }
289     silc_idcache_list_free(list);
290   }
291
292   /* Return now if we are shutting down */
293   if (server->server_shutdown) {
294     silc_hash_table_free(channels);
295
296     if (server_signoff) {
297       for (i = 0; i < argc; i++)
298         silc_free(argv[i]);
299       silc_free(argv);
300       silc_free(argv_lens);
301       silc_free(argv_types);
302       silc_hash_table_free(clients);
303     }
304     return TRUE;
305   }
306
307   /* Send the SERVER_SIGNOFF notify */
308   if (server_signoff) {
309     SilcBuffer args, not;
310
311     SILC_LOG_DEBUG(("Sending SERVER_SIGNOFF for %s with %d clients",
312                     silc_id_render(entry->id, SILC_ID_SERVER), argc - 1));
313
314     /* Send SERVER_SIGNOFF notify to our primary router */
315     if (server->router != entry) {
316       args = silc_argument_payload_encode(1, argv, argv_lens,
317                                           argv_types);
318       silc_server_send_notify_args(server, SILC_PRIMARY_ROUTE(server),
319                                    SILC_BROADCAST(server),
320                                    SILC_NOTIFY_TYPE_SERVER_SIGNOFF,
321                                    argc, args);
322       silc_buffer_free(args);
323     }
324
325     /* Send to local clients. We also send the list of client ID's that
326        is to be removed for those servers that would like to use that list. */
327     args = silc_argument_payload_encode(argc, argv, argv_lens,
328                                         argv_types);
329     not = silc_notify_payload_encode_args(SILC_NOTIFY_TYPE_SERVER_SIGNOFF, 
330                                           argc, args);
331     silc_server_packet_send_clients(server, clients,
332                                     SILC_PACKET_NOTIFY, 0, FALSE,
333                                     not->data, not->len, FALSE);
334
335     /* Send notify also to local backup routers */
336     silc_server_backup_send(server, NULL, SILC_PACKET_NOTIFY, 0,
337                             not->data, not->len, FALSE, TRUE);
338
339     silc_buffer_free(args);
340     silc_buffer_free(not);
341     for (i = 0; i < argc; i++)
342       silc_free(argv[i]);
343     silc_free(argv);
344     silc_free(argv_lens);
345     silc_free(argv_types);
346     silc_hash_table_free(clients);
347   }
348
349   /* We must now re-generate the channel key for all channels that had
350      this server's client(s) on the channel. As they left the channel we
351      must re-generate the channel key. */
352   silc_hash_table_list(channels, &htl);
353   while (silc_hash_table_get(&htl, NULL, (void **)&channel)) {
354     if (!silc_server_create_channel_key(server, channel, 0)) {
355       silc_hash_table_list_reset(&htl);
356       silc_hash_table_free(channels);
357       return FALSE;
358     }
359
360     /* Do not send the channel key if private channel key mode is set */
361     if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY || !channel->channel_key)
362       continue;
363
364     silc_server_send_channel_key(server, NULL, channel, 
365                                  server->server_type == SILC_ROUTER ? 
366                                  FALSE : !server->standalone);
367   }
368   silc_hash_table_list_reset(&htl);
369   silc_hash_table_free(channels);
370
371   return TRUE;
372 }
373
374 static SilcServerEntry
375 silc_server_update_clients_by_real_server(SilcServer server,
376                                           SilcServerEntry from,
377                                           SilcClientEntry client,
378                                           bool local,
379                                           SilcIDCacheEntry client_cache)
380 {
381   SilcServerEntry server_entry;
382   SilcIDCacheEntry id_cache = NULL;
383   SilcIDCacheList list;
384
385   if (!silc_idcache_get_all(server->local_list->servers, &list))
386     return NULL;
387
388   if (silc_idcache_list_first(list, &id_cache)) {
389     while (id_cache) {
390       server_entry = (SilcServerEntry)id_cache->context;
391       if (server_entry != from &&
392           SILC_ID_COMPARE(server_entry->id, client->id, 
393                           client->id->ip.data_len)) {
394         SILC_LOG_DEBUG(("Found (local) %s",
395                         silc_id_render(server_entry->id, SILC_ID_SERVER)));
396
397         if (!server_entry->data.send_key && server_entry->router) {
398           SILC_LOG_DEBUG(("Server not locally connected, use its router"));
399           /* If the client is not marked as local then move it to local list
400              since the server is local. */
401           if (!local) {
402             SILC_LOG_DEBUG(("Moving client to local list"));
403             silc_idcache_add(server->local_list->clients, client_cache->name,
404                              client_cache->id, client_cache->context,
405                              client_cache->expire, NULL);
406             silc_idcache_del_by_context(server->global_list->clients, client);
407           }
408           server_entry = server_entry->router;
409         } else {
410           /* If the client is not marked as local then move it to local list
411              since the server is local. */
412           if (server_entry->server_type != SILC_BACKUP_ROUTER && !local) {
413             SILC_LOG_DEBUG(("Moving client to local list"));
414             silc_idcache_add(server->local_list->clients, client_cache->name,
415                              client_cache->id, client_cache->context,
416                              client_cache->expire, NULL);
417             silc_idcache_del_by_context(server->global_list->clients, client);
418           }
419         }
420
421         silc_idcache_list_free(list);
422         return server_entry;
423       }
424
425       if (!silc_idcache_list_next(list, &id_cache))
426         break;
427     }
428   }
429
430   silc_idcache_list_free(list);
431
432   if (!silc_idcache_get_all(server->global_list->servers, &list))
433     return NULL;
434
435   if (silc_idcache_list_first(list, &id_cache)) {
436     while (id_cache) {
437       server_entry = (SilcServerEntry)id_cache->context;
438       if (server_entry != from &&
439           SILC_ID_COMPARE(server_entry->id, client->id, 
440                           client->id->ip.data_len)) {
441         SILC_LOG_DEBUG(("Found (global) %s",
442                         silc_id_render(server_entry->id, SILC_ID_SERVER)));
443
444         if (!server_entry->data.send_key && server_entry->router) {
445           SILC_LOG_DEBUG(("Server not locally connected, use its router"));
446           /* If the client is marked as local then move it to global list
447              since the server is global. */
448           if (local) {
449             SILC_LOG_DEBUG(("Moving client to global list"));
450             silc_idcache_add(server->global_list->clients, client_cache->name,
451                              client_cache->id, client_cache->context, 0, NULL);
452             silc_idcache_del_by_context(server->local_list->clients, client);
453           }
454           server_entry = server_entry->router;
455         } else {
456           /* If the client is marked as local then move it to global list
457              since the server is global. */
458           if (server_entry->server_type != SILC_BACKUP_ROUTER && local) {
459             SILC_LOG_DEBUG(("Moving client to global list"));
460             silc_idcache_add(server->global_list->clients, client_cache->name,
461                              client_cache->id, client_cache->context, 0, NULL);
462             silc_idcache_del_by_context(server->local_list->clients, client);
463           }
464         }
465
466         silc_idcache_list_free(list);
467         return server_entry;
468       }
469
470       if (!silc_idcache_list_next(list, &id_cache))
471         break;
472     }
473   }
474
475   silc_idcache_list_free(list);
476
477   return NULL;
478 }
479
480 /* Updates the clients that are originated from the `from' to be originated
481    from the `to'. If the `resolve_real_server' is TRUE then this will
482    attempt to figure out which clients really are originated from the
483    `from' and which are originated from a server that we have connection
484    to, when we've acting as backup router. If it is FALSE the `to' will
485    be the new source. */
486
487 void silc_server_update_clients_by_server(SilcServer server, 
488                                           SilcServerEntry from,
489                                           SilcServerEntry to,
490                                           bool resolve_real_server)
491 {
492   SilcIDCacheList list = NULL;
493   SilcIDCacheEntry id_cache = NULL;
494   SilcClientEntry client = NULL;
495   bool local;
496
497   local = FALSE;
498   if (silc_idcache_get_all(server->global_list->clients, &list)) {
499     if (silc_idcache_list_first(list, &id_cache)) {
500       while (id_cache) {
501         client = (SilcClientEntry)id_cache->context;
502
503         /* If entry is disabled skip it.  If entry is local to us, do not
504            switch it to anyone else, it is ours so skip it. */
505         if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) ||
506             SILC_IS_LOCAL(client)) {
507           if (!silc_idcache_list_next(list, &id_cache))
508             break;
509           else
510             continue;
511         }
512
513         SILC_LOG_DEBUG(("Client %s", 
514                         silc_id_render(client->id, SILC_ID_CLIENT)));
515         if (client->router)
516           SILC_LOG_DEBUG(("Client->router %s", 
517                           silc_id_render(client->router->id, SILC_ID_SERVER)));
518
519         if (from) {
520           if (client->router == from) {
521             if (resolve_real_server) {
522               client->router = 
523                 silc_server_update_clients_by_real_server(server, from, client,
524                                                           local, id_cache);
525               if (!client->router) {
526                 if (server->server_type == SILC_ROUTER)
527                   client->router = from;
528                 else
529                   client->router = to;
530               }
531             } else {
532               client->router = to;
533             }
534           }
535         } else {
536           /* All are changed */
537           client->router = to;
538         }
539
540         if (client->router)
541           SILC_LOG_DEBUG(("Client changed to %s", 
542                           silc_id_render(client->router->id, SILC_ID_CLIENT)));
543
544         if (!silc_idcache_list_next(list, &id_cache))
545           break;
546       }
547     }
548     silc_idcache_list_free(list);
549   }
550
551   local = TRUE;
552   if (silc_idcache_get_all(server->local_list->clients, &list)) {
553     if (silc_idcache_list_first(list, &id_cache)) {
554       while (id_cache) {
555         client = (SilcClientEntry)id_cache->context;
556
557         /* If entry is disabled skip it.  If entry is local to us, do not
558            switch it to anyone else, it is ours so skip it. */
559         if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) ||
560             SILC_IS_LOCAL(client)) {
561           if (!silc_idcache_list_next(list, &id_cache))
562             break;
563           else
564             continue;
565         }
566
567         SILC_LOG_DEBUG(("Client %s", 
568                         silc_id_render(client->id, SILC_ID_CLIENT)));
569         if (client->router)
570           SILC_LOG_DEBUG(("Client->router %s", 
571                           silc_id_render(client->router->id, SILC_ID_SERVER)));
572
573         if (from) {
574           if (client->router == from) {
575             if (resolve_real_server) {
576               client->router = 
577                 silc_server_update_clients_by_real_server(server, from, client,
578                                                           local, id_cache);
579               if (!client->router)
580                 client->router = from;
581             } else {
582               client->router = to;
583             }
584           }
585         } else {
586           /* All are changed */
587           client->router = to;
588         }
589
590         if (client->router)
591           SILC_LOG_DEBUG(("Client changed to %s", 
592                           silc_id_render(client->router->id, SILC_ID_CLIENT)));
593
594         if (!silc_idcache_list_next(list, &id_cache))
595           break;
596       }
597     }
598     silc_idcache_list_free(list);
599   }
600 }
601
602 /* Updates servers that are from `from' to be originated from `to'.  This
603    will also update the server's connection to `to's connection. */
604
605 void silc_server_update_servers_by_server(SilcServer server, 
606                                           SilcServerEntry from,
607                                           SilcServerEntry to)
608 {
609   SilcIDCacheList list = NULL;
610   SilcIDCacheEntry id_cache = NULL;
611   SilcServerEntry server_entry = NULL;
612
613   SILC_LOG_DEBUG(("Updating servers"));
614
615   if (silc_idcache_get_all(server->local_list->servers, &list)) {
616     if (silc_idcache_list_first(list, &id_cache)) {
617       while (id_cache) {
618         server_entry = (SilcServerEntry)id_cache->context;
619
620         /* If entry is local to us, do not switch it to any anyone else,
621            it is ours. */
622         if (SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry ||
623             server_entry == from) {
624           if (!silc_idcache_list_next(list, &id_cache))
625             break;
626           else
627             continue;
628         }
629
630         /* If we are standalone router, any server that is not directly
631            connected to cannot exist anymore.  If we are not standalone
632            we update it correctly. */
633         if (server->server_type == SILC_ROUTER && server->standalone) {
634           silc_server_backup_del(server, server_entry);
635           silc_server_backup_replaced_del(server, server_entry);
636           silc_idlist_del_data(server_entry);
637           silc_idlist_del_server(server->local_list, server_entry);
638           server->stat.servers--;
639           server->stat.cell_servers--;
640         } else {
641           /* XXX if we are not standalone, do a check from local config
642              whether this server is in our cell, but not connected to
643              us (in which case we must remove it). */
644
645           if (server_entry->router == from) {
646             SILC_LOG_DEBUG(("Updating server (local) %s",
647                             server_entry->server_name ? 
648                             server_entry->server_name : ""));
649             server_entry->router = to;
650             server_entry->connection = to->connection;
651           }
652         }
653
654         if (!silc_idcache_list_next(list, &id_cache))
655           break;
656       }
657     }
658     silc_idcache_list_free(list);
659   }
660
661   if (silc_idcache_get_all(server->global_list->servers, &list)) {
662     if (silc_idcache_list_first(list, &id_cache)) {
663       while (id_cache) {
664         server_entry = (SilcServerEntry)id_cache->context;
665
666         /* If entry is local to us, do not switch it to anyone else,
667            it is ours. */
668         if (SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry ||
669             server_entry == from) {
670           if (!silc_idcache_list_next(list, &id_cache))
671             break;
672           else
673             continue;
674         }
675
676         /* If we are standalone router, any server that is not directly
677            connected to cannot exist anymore.  If we are not standalone
678            we update it correctly. */
679         if (server->server_type == SILC_ROUTER && server->standalone) {
680           silc_server_backup_del(server, server_entry);
681           silc_server_backup_replaced_del(server, server_entry);
682           silc_idlist_del_data(server_entry);
683           silc_idlist_del_server(server->global_list, server_entry);
684           server->stat.servers--;
685           server->stat.cell_servers--;
686         } else {
687           /* XXX if we are not standalone, do a check from local config
688              whether this server is in our cell, but not connected to
689              us (in which case we must remove it). */
690
691           if (server_entry->router == from) {
692             SILC_LOG_DEBUG(("Updating server (global) %s",
693                             server_entry->server_name ? 
694                             server_entry->server_name : ""));
695             server_entry->router = to;
696             server_entry->connection = to->connection;
697           }
698         }
699
700         if (!silc_idcache_list_next(list, &id_cache))
701           break;
702       }
703     }
704     silc_idcache_list_free(list);
705   }
706 }
707
708
709 /* Toggles the enabled/disabled status of local server connections.  Packets
710    can be sent to the servers when `toggle_enabled' is TRUE and will be
711    dropped if `toggle_enabled' is FALSE, after this function is called. */
712
713 void silc_server_local_servers_toggle_enabled(SilcServer server,
714                                               bool toggle_enabled)
715 {
716   SilcIDCacheList list = NULL;
717   SilcIDCacheEntry id_cache = NULL;
718   SilcServerEntry server_entry = NULL;
719
720   if (silc_idcache_get_all(server->local_list->servers, &list)) {
721     if (silc_idcache_list_first(list, &id_cache)) {
722       while (id_cache) {
723         server_entry = (SilcServerEntry)id_cache->context;
724         if (!SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry) {
725           if (!silc_idcache_list_next(list, &id_cache))
726             break;
727           else
728             continue;
729         }
730
731         if (toggle_enabled)
732           server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
733         else
734           server_entry->data.status |= SILC_IDLIST_STATUS_DISABLED;
735
736         if (!silc_idcache_list_next(list, &id_cache))
737           break;
738       }
739     }
740     silc_idcache_list_free(list);
741   }
742
743   if (silc_idcache_get_all(server->global_list->servers, &list)) {
744     if (silc_idcache_list_first(list, &id_cache)) {
745       while (id_cache) {
746         server_entry = (SilcServerEntry)id_cache->context;
747         if (!SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry) {
748           if (!silc_idcache_list_next(list, &id_cache))
749             break;
750           else
751             continue;
752         }
753
754         if (toggle_enabled)
755           server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
756         else
757           server_entry->data.status |= SILC_IDLIST_STATUS_DISABLED;
758
759         if (!silc_idcache_list_next(list, &id_cache))
760           break;
761       }
762     }
763     silc_idcache_list_free(list);
764   }
765 }
766
767 /* Removes servers that are originated from the `from'.  The server
768    entry is deleted in this function.  If `remove_clients' is TRUE then
769    all clients originated from the server are removed too, and server
770    signoff is sent.  Note that this does not remove the `from'.  This
771    also does not remove locally connected servers. */
772
773 void silc_server_remove_servers_by_server(SilcServer server,
774                                           SilcServerEntry from,
775                                           bool remove_clients)
776 {
777   SilcIDCacheList list = NULL;
778   SilcIDCacheEntry id_cache = NULL;
779   SilcServerEntry server_entry = NULL;
780
781   SILC_LOG_DEBUG(("Removing servers by %s",
782                   from->server_name ? from->server_name : "server"));
783
784   if (silc_idcache_get_all(server->local_list->servers, &list)) {
785     if (silc_idcache_list_first(list, &id_cache)) {
786       while (id_cache) {
787         server_entry = (SilcServerEntry)id_cache->context;
788         if (SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry ||
789           server_entry->router != from || server_entry == from) {
790           if (!silc_idcache_list_next(list, &id_cache))
791             break;
792           else
793             continue;
794         }
795
796         /* Remove clients owned by this server */
797         if (remove_clients)
798           silc_server_remove_clients_by_server(server, from, server_entry,
799                                                TRUE);
800
801         /* Remove the server */
802         silc_idlist_del_server(server->local_list, server_entry);
803
804         if (!silc_idcache_list_next(list, &id_cache))
805           break;
806       }
807     }
808     silc_idcache_list_free(list);
809   }
810
811   if (silc_idcache_get_all(server->global_list->servers, &list)) {
812     if (silc_idcache_list_first(list, &id_cache)) {
813       while (id_cache) {
814         server_entry = (SilcServerEntry)id_cache->context;
815         if (SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry ||
816           server_entry->router != from || server_entry == from) {
817           if (!silc_idcache_list_next(list, &id_cache))
818             break;
819           else
820             continue;
821         }
822
823         /* Remove clients owned by this server */
824         if (remove_clients)
825           silc_server_remove_clients_by_server(server, from, server_entry,
826                                                TRUE);
827
828         /* Remove the server */
829         silc_idlist_del_server(server->global_list, server_entry);
830
831         if (!silc_idcache_list_next(list, &id_cache))
832           break;
833       }
834     }
835     silc_idcache_list_free(list);
836   }
837 }
838
839 /* Removes channels that are from `from. */
840
841 void silc_server_remove_channels_by_server(SilcServer server, 
842                                            SilcServerEntry from)
843 {
844   SilcIDCacheList list = NULL;
845   SilcIDCacheEntry id_cache = NULL;
846   SilcChannelEntry channel = NULL;
847
848   SILC_LOG_DEBUG(("Removing channels by server"));
849
850   if (silc_idcache_get_all(server->global_list->channels, &list)) {
851     if (silc_idcache_list_first(list, &id_cache)) {
852       while (id_cache) {
853         channel = (SilcChannelEntry)id_cache->context;
854         if (channel->router == from)
855           silc_idlist_del_channel(server->global_list, channel);
856         if (!silc_idcache_list_next(list, &id_cache))
857           break;
858       }
859     }
860     silc_idcache_list_free(list);
861   }
862 }
863
864 /* Updates channels that are from `from' to be originated from `to'.  */
865
866 void silc_server_update_channels_by_server(SilcServer server, 
867                                            SilcServerEntry from,
868                                            SilcServerEntry to)
869 {
870   SilcIDCacheList list = NULL;
871   SilcIDCacheEntry id_cache = NULL;
872   SilcChannelEntry channel = NULL;
873
874   SILC_LOG_DEBUG(("Updating channels by server"));
875
876   if (silc_idcache_get_all(server->global_list->channels, &list)) {
877     if (silc_idcache_list_first(list, &id_cache)) {
878       while (id_cache) {
879         channel = (SilcChannelEntry)id_cache->context;
880         if (channel->router == from)
881           channel->router = to;
882         if (!silc_idcache_list_next(list, &id_cache))
883           break;
884       }
885     }
886     silc_idcache_list_free(list);
887   }
888 }
889
890 /* Checks whether given channel has global users.  If it does this returns
891    TRUE and FALSE if there is only locally connected clients on the channel. */
892
893 bool silc_server_channel_has_global(SilcChannelEntry channel)
894 {
895   SilcChannelClientEntry chl;
896   SilcHashTableList htl;
897
898   silc_hash_table_list(channel->user_list, &htl);
899   while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
900     if (chl->client->router) {
901       silc_hash_table_list_reset(&htl);
902       return TRUE;
903     }
904   }
905   silc_hash_table_list_reset(&htl);
906
907   return FALSE;
908 }
909
910 /* Checks whether given channel has locally connected users.  If it does this
911    returns TRUE and FALSE if there is not one locally connected client. */
912
913 bool silc_server_channel_has_local(SilcChannelEntry channel)
914 {
915   SilcChannelClientEntry chl;
916   SilcHashTableList htl;
917
918   silc_hash_table_list(channel->user_list, &htl);
919   while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
920     if (!chl->client->router) {
921       silc_hash_table_list_reset(&htl);
922       return TRUE;
923     }
924   }
925   silc_hash_table_list_reset(&htl);
926
927   return FALSE;
928 }
929
930 /* This function removes the channel and all users on the channel, unless
931    the channel is permanent.  In this case the channel is disabled but all
932    users are removed from the channel.  Returns TRUE if the channel is
933    destroyed totally, and FALSE if it is permanent and remains. */
934
935 bool silc_server_channel_delete(SilcServer server,
936                                 SilcChannelEntry channel)
937 {
938   SilcChannelClientEntry chl;
939   SilcHashTableList htl;
940   bool delchan = !(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH);
941
942   if (delchan) {
943     /* Update statistics */
944     if (server->server_type == SILC_ROUTER)
945       server->stat.chanclients -= channel->user_count;
946
947     /* Totally delete the channel and all users on the channel. The
948        users are deleted automatically in silc_idlist_del_channel. */
949     silc_schedule_task_del_by_context(server->schedule, channel->rekey);
950     if (silc_idlist_del_channel(server->local_list, channel)) {
951       server->stat.my_channels--;
952       if (server->server_type == SILC_ROUTER) {
953         server->stat.channels--;
954         server->stat.cell_channels--;
955       }
956     } else {
957       if (silc_idlist_del_channel(server->global_list, channel))
958         if (server->server_type == SILC_ROUTER)
959           server->stat.channels--;
960     }
961
962     return FALSE;
963   }
964
965   /* Channel is permanent, do not remove it, remove only users */
966   channel->disabled = TRUE;
967   silc_hash_table_list(channel->user_list, &htl);
968   while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
969     silc_hash_table_del(chl->client->channels, channel);
970     silc_hash_table_del(channel->user_list, chl->client);
971     channel->user_count--;
972
973     /* Update statistics */
974     if (SILC_IS_LOCAL(chl->client))
975       server->stat.my_chanclients--;
976     if (server->server_type == SILC_ROUTER) {
977       server->stat.cell_chanclients--;
978       server->stat.chanclients--;
979     }
980
981     silc_free(chl);
982   }
983   silc_hash_table_list_reset(&htl);
984
985   SILC_LOG_DEBUG(("Channel %s remains", channel->channel_name));
986
987   return TRUE;
988 }
989
990 /* Returns TRUE if the given client is on the channel.  FALSE if not. 
991    This works because we assure that the user list on the channel is
992    always in up to date thus we can only check the channel list from 
993    `client' which is faster than checking the user list from `channel'. */
994
995 bool silc_server_client_on_channel(SilcClientEntry client,
996                                    SilcChannelEntry channel,
997                                    SilcChannelClientEntry *chl)
998 {
999   if (!client || !channel)
1000     return FALSE;
1001
1002   return silc_hash_table_find(client->channels, channel, NULL, 
1003                               (void **)chl);
1004 }
1005
1006 /* Checks string for bad characters and returns TRUE if they are found. */
1007
1008 bool silc_server_name_bad_chars(const char *name, SilcUInt32 name_len)
1009 {
1010   int i;
1011
1012   for (i = 0; i < name_len; i++) {
1013     if (!isascii(name[i]))
1014       return TRUE;
1015     if (name[i] <= 32) return TRUE;
1016     if (name[i] == ' ') return TRUE;
1017     if (name[i] == '*') return TRUE;
1018     if (name[i] == '?') return TRUE;
1019     if (name[i] == ',') return TRUE;
1020   }
1021
1022   return FALSE;
1023 }
1024
1025 /* Modifies the `name' if it includes bad characters and returns new
1026    allocated name that does not include bad characters. */
1027
1028 char *silc_server_name_modify_bad(const char *name, SilcUInt32 name_len)
1029 {
1030   int i;
1031   char *newname = strdup(name);
1032
1033   for (i = 0; i < name_len; i++) {
1034     if (!isascii(newname[i])) newname[i] = '_';
1035     if (newname[i] <= 32) newname[i] = '_';
1036     if (newname[i] == ' ') newname[i] = '_';
1037     if (newname[i] == '*') newname[i] = '_';
1038     if (newname[i] == '?') newname[i] = '_';
1039     if (newname[i] == ',') newname[i] = '_';
1040   }
1041
1042   return newname;
1043 }
1044
1045 /* Find number of sockets by IP address indicated by `ip'. Returns 0 if
1046    socket connections with the IP address does not exist. */
1047
1048 SilcUInt32 silc_server_num_sockets_by_ip(SilcServer server, const char *ip,
1049                                          SilcSocketType type)
1050 {
1051   int i, count;
1052
1053   for (i = 0, count = 0; i < server->config->param.connections_max; i++) {
1054     if (server->sockets[i] && !SILC_IS_LISTENER(server->sockets[i]) &&
1055         !strcmp(server->sockets[i]->ip, ip) &&
1056         server->sockets[i]->type == type)
1057       count++;
1058   }
1059
1060   return count;
1061 }
1062
1063 /* Find number of sockets by IP address indicated by remote host, indicatd
1064    by `ip' or `hostname', `port', and `type'.  Returns 0 if socket connections
1065    does not exist. If `ip' is provided then `hostname' is ignored. */
1066
1067 SilcUInt32 silc_server_num_sockets_by_remote(SilcServer server, 
1068                                              const char *ip,
1069                                              const char *hostname,
1070                                              SilcUInt16 port,
1071                                              SilcSocketType type)
1072 {
1073   int i, count;
1074
1075   if (!ip && !hostname)
1076     return 0;
1077
1078   for (i = 0, count = 0; i < server->config->param.connections_max; i++) {
1079     if (server->sockets[i] && !SILC_IS_LISTENER(server->sockets[i]) &&
1080         ((ip && !strcmp(server->sockets[i]->ip, ip)) ||
1081          (hostname && !strcmp(server->sockets[i]->hostname, hostname))) &&
1082         server->sockets[i]->port == port &&
1083         server->sockets[i]->type == type)
1084       count++;
1085   }
1086
1087   return count;
1088 }
1089
1090 /* Finds locally cached public key by the public key received in the SKE. 
1091    If we have it locally cached then we trust it and will use it in the
1092    authentication protocol.  Returns the locally cached public key or NULL
1093    if we do not find the public key.  */
1094
1095 SilcPublicKey silc_server_find_public_key(SilcServer server, 
1096                                           SilcHashTable local_public_keys,
1097                                           SilcPublicKey remote_public_key)
1098 {
1099   SilcPublicKey cached_key;
1100
1101   SILC_LOG_DEBUG(("Find remote public key (%d keys in local cache)",
1102                   silc_hash_table_count(local_public_keys)));
1103
1104   if (!silc_hash_table_find_ext(local_public_keys, remote_public_key,
1105                                 (void **)&cached_key, NULL, 
1106                                 silc_hash_public_key, NULL,
1107                                 silc_hash_public_key_compare, NULL)) {
1108     SILC_LOG_ERROR(("Public key not found"));
1109     return NULL;
1110   }
1111
1112   SILC_LOG_DEBUG(("Found public key"));
1113
1114   return cached_key;
1115 }
1116
1117 /* This returns the first public key from the table of public keys.  This
1118    is used only in cases where single public key exists in the table and
1119    we want to get a pointer to it.  For public key tables that has multiple
1120    keys in it the silc_server_find_public_key must be used. */
1121
1122 SilcPublicKey silc_server_get_public_key(SilcServer server,
1123                                          SilcHashTable local_public_keys)
1124 {
1125   SilcPublicKey cached_key;
1126   SilcHashTableList htl;
1127
1128   SILC_LOG_DEBUG(("Start"));
1129
1130   assert(silc_hash_table_count(local_public_keys) < 2);
1131
1132   silc_hash_table_list(local_public_keys, &htl);
1133   if (!silc_hash_table_get(&htl, NULL, (void **)&cached_key))
1134     return NULL;
1135   silc_hash_table_list_reset(&htl);
1136
1137   return cached_key;
1138 }
1139
1140 /* Check whether the connection `sock' is allowed to connect to us.  This
1141    checks for example whether there is too much connections for this host,
1142    and required version for the host etc. */
1143
1144 bool silc_server_connection_allowed(SilcServer server, 
1145                                     SilcSocketConnection sock,
1146                                     SilcSocketType type,
1147                                     SilcServerConfigConnParams *global,
1148                                     SilcServerConfigConnParams *params,
1149                                     SilcSKE ske)
1150 {
1151   SilcUInt32 conn_number = (type == SILC_SOCKET_TYPE_CLIENT ?
1152                             server->stat.my_clients :
1153                             type == SILC_SOCKET_TYPE_SERVER ?
1154                             server->stat.my_servers :
1155                             server->stat.my_routers);
1156   SilcUInt32 num_sockets, max_hosts, max_per_host;
1157   SilcUInt32 r_protocol_version, l_protocol_version;
1158   SilcUInt32 r_software_version, l_software_version;
1159   char *r_vendor_version = NULL, *l_vendor_version;
1160
1161   SILC_LOG_DEBUG(("Checking whether connection is allowed"));
1162
1163   /* Check version */
1164
1165   l_protocol_version = 
1166     silc_version_to_num(params && params->version_protocol ? 
1167                         params->version_protocol : 
1168                         global->version_protocol);
1169   l_software_version = 
1170     silc_version_to_num(params && params->version_software ? 
1171                         params->version_software : 
1172                         global->version_software);
1173   l_vendor_version = (params && params->version_software_vendor ? 
1174                       params->version_software_vendor : 
1175                       global->version_software_vendor);
1176   
1177   if (ske && silc_ske_parse_version(ske, &r_protocol_version, NULL,
1178                                     &r_software_version, NULL,
1179                                     &r_vendor_version)) {
1180     sock->version = r_protocol_version;
1181
1182     /* Match protocol version */
1183     if (l_protocol_version && r_protocol_version &&
1184         r_protocol_version < l_protocol_version) {
1185       SILC_LOG_INFO(("Connection %s (%s) is too old version",
1186                      sock->hostname, sock->ip));
1187       silc_server_disconnect_remote(server, sock, 
1188                                     SILC_STATUS_ERR_BAD_VERSION,
1189                                     "You support too old protocol version");
1190       return FALSE;
1191     }
1192
1193     /* Math software version */
1194     if (l_software_version && r_software_version &&
1195         r_software_version < l_software_version) {
1196       SILC_LOG_INFO(("Connection %s (%s) is too old version",
1197                      sock->hostname, sock->ip));
1198       silc_server_disconnect_remote(server, sock, 
1199                                     SILC_STATUS_ERR_BAD_VERSION,
1200                                     "You support too old software version");
1201       return FALSE;
1202     }
1203
1204     /* Regex match vendor version */
1205     if (l_vendor_version && r_vendor_version && 
1206         !silc_string_match(l_vendor_version, r_vendor_version)) {
1207       SILC_LOG_INFO(("Connection %s (%s) is unsupported version",
1208                      sock->hostname, sock->ip));
1209       silc_server_disconnect_remote(server, sock, 
1210                                     SILC_STATUS_ERR_BAD_VERSION,
1211                                     "Your software is not supported");
1212       return FALSE;
1213     }
1214   }
1215   silc_free(r_vendor_version);
1216
1217   /* Check for maximum connections limit */
1218
1219   num_sockets = silc_server_num_sockets_by_ip(server, sock->ip, type);
1220   max_hosts = (params ? params->connections_max : global->connections_max);
1221   max_per_host = (params ? params->connections_max_per_host :
1222                   global->connections_max_per_host);
1223
1224   if (max_hosts && conn_number >= max_hosts) {
1225     SILC_LOG_INFO(("Server is full, closing %s (%s) connection",
1226                    sock->hostname, sock->ip));
1227     silc_server_disconnect_remote(server, sock, 
1228                                   SILC_STATUS_ERR_RESOURCE_LIMIT,
1229                                   "Server is full, try again later");
1230     return FALSE;
1231   }
1232
1233   if (num_sockets >= max_per_host) {
1234     SILC_LOG_INFO(("Too many connections from %s (%s), closing connection",
1235                    sock->hostname, sock->ip));
1236     silc_server_disconnect_remote(server, sock, 
1237                                   SILC_STATUS_ERR_RESOURCE_LIMIT,
1238                                   "Too many connections from your host");
1239     return FALSE;
1240   }
1241
1242   return TRUE;
1243 }
1244
1245 /* Checks that client has rights to add or remove channel modes. If any
1246    of the checks fails FALSE is returned. */
1247
1248 bool silc_server_check_cmode_rights(SilcServer server,
1249                                     SilcChannelEntry channel,
1250                                     SilcChannelClientEntry client,
1251                                     SilcUInt32 mode)
1252 {
1253   bool is_op = client->mode & SILC_CHANNEL_UMODE_CHANOP;
1254   bool is_fo = client->mode & SILC_CHANNEL_UMODE_CHANFO;
1255
1256   /* Check whether has rights to change anything */
1257   if (!is_op && !is_fo)
1258     return FALSE;
1259
1260   /* Check whether has rights to change everything */
1261   if (is_op && is_fo)
1262     return TRUE;
1263
1264   /* Founder implies operator */
1265   if (is_fo)
1266     is_op = TRUE;
1267
1268   /* We know that client is channel operator, check that they are not
1269      changing anything that requires channel founder rights. Rest of the
1270      modes are available automatically for channel operator. */
1271
1272   if (mode & SILC_CHANNEL_MODE_PRIVKEY) {
1273     if (is_op && !is_fo)
1274       return FALSE;
1275   } else {
1276     if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
1277       if (is_op && !is_fo)
1278         return FALSE;
1279     }
1280   }
1281   
1282   if (mode & SILC_CHANNEL_MODE_PASSPHRASE) {
1283     if (!(channel->mode & SILC_CHANNEL_MODE_PASSPHRASE)) {
1284       if (is_op && !is_fo)
1285         return FALSE;
1286     }
1287   } else {
1288     if (channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
1289       if (is_op && !is_fo)
1290         return FALSE;
1291     }
1292   }
1293
1294   if (mode & SILC_CHANNEL_MODE_CIPHER) {
1295     if (!(channel->mode & SILC_CHANNEL_MODE_CIPHER)) {
1296       if (is_op && !is_fo)
1297         return FALSE;
1298     }
1299   } else {
1300     if (channel->mode & SILC_CHANNEL_MODE_CIPHER) {
1301       if (is_op && !is_fo)
1302         return FALSE;
1303     }
1304   }
1305   
1306   if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
1307     if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
1308       if (is_op && !is_fo)
1309         return FALSE;
1310     }
1311   } else {
1312     if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
1313       if (is_op && !is_fo)
1314         return FALSE;
1315     }
1316   }
1317   
1318   if (mode & SILC_CHANNEL_MODE_SILENCE_USERS) {
1319     if (!(channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS)) {
1320       if (is_op && !is_fo)
1321         return FALSE;
1322     }
1323   } else {
1324     if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS) {
1325       if (is_op && !is_fo)
1326         return FALSE;
1327     }
1328   }
1329   
1330   if (mode & SILC_CHANNEL_MODE_SILENCE_OPERS) {
1331     if (!(channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS)) {
1332       if (is_op && !is_fo)
1333         return FALSE;
1334     }
1335   } else {
1336     if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS) {
1337       if (is_op && !is_fo)
1338         return FALSE;
1339     }
1340   }
1341   
1342   return TRUE;
1343 }
1344
1345 /* Check that the client has rights to change its user mode.  Returns
1346    FALSE if setting some mode is not allowed. */
1347
1348 bool silc_server_check_umode_rights(SilcServer server,
1349                                     SilcClientEntry client,
1350                                     SilcUInt32 mode)
1351 {
1352   bool server_op = FALSE, router_op = FALSE;
1353
1354   if (mode & SILC_UMODE_SERVER_OPERATOR) {
1355     /* Cannot set server operator mode (must use OPER command) */
1356     if (!(client->mode & SILC_UMODE_SERVER_OPERATOR))
1357       return FALSE;
1358   } else {
1359     /* Remove the server operator rights */
1360     if (client->mode & SILC_UMODE_SERVER_OPERATOR)
1361       server_op = TRUE;
1362   }
1363
1364   if (mode & SILC_UMODE_ROUTER_OPERATOR) {
1365     /* Cannot set router operator mode (must use SILCOPER command) */
1366     if (!(client->mode & SILC_UMODE_ROUTER_OPERATOR))
1367       return FALSE;
1368   } else {
1369     /* Remove the router operator rights */
1370     if (client->mode & SILC_UMODE_ROUTER_OPERATOR)
1371       router_op = TRUE;
1372   }
1373
1374   if (server_op)
1375     SILC_UMODE_STATS_UPDATE(server, SILC_UMODE_SERVER_OPERATOR);
1376   if (router_op)
1377     SILC_UMODE_STATS_UPDATE(router, SILC_UMODE_ROUTER_OPERATOR);
1378
1379   return TRUE;
1380 }
1381
1382 /* This function is used to send the notify packets and motd to the
1383    incoming client connection. */
1384
1385 void silc_server_send_connect_notifys(SilcServer server,
1386                                       SilcSocketConnection sock,
1387                                       SilcClientEntry client)
1388 {
1389   SilcIDListData idata = (SilcIDListData)client;
1390
1391   SILC_LOG_DEBUG(("Send welcome notifys"));
1392
1393   /* Send some nice info to the client */
1394   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1395                           ("Welcome to the SILC Network %s",
1396                            client->username));
1397   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1398                           ("Your host is %s, running version %s",
1399                            server->server_name, server_version));
1400
1401   if (server->server_type == SILC_ROUTER) {
1402     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1403                             ("There are %d clients, %d servers and %d "
1404                              "routers in SILC Network",
1405                              server->stat.clients, server->stat.servers + 1,
1406                              server->stat.routers));
1407   } else {
1408     if (server->stat.clients && server->stat.servers + 1)
1409       SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1410                               ("There are %d clients, %d servers and %d "
1411                                "routers in SILC Network",
1412                                server->stat.clients, server->stat.servers + 1,
1413                                (server->standalone ? 0 :
1414                                 !server->stat.routers ? 1 :
1415                                 server->stat.routers)));
1416   }
1417
1418   if (server->stat.cell_clients && server->stat.cell_servers + 1)
1419     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1420                             ("There are %d clients on %d server in our cell",
1421                              server->stat.cell_clients,
1422                              server->stat.cell_servers + 1));
1423   if (server->server_type == SILC_ROUTER) {
1424     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1425                             ("I have %d clients, %d channels, %d servers and "
1426                              "%d routers",
1427                              server->stat.my_clients, 
1428                              server->stat.my_channels,
1429                              server->stat.my_servers,
1430                              server->stat.my_routers));
1431   } else {
1432     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1433                             ("I have %d clients and %d channels formed",
1434                              server->stat.my_clients,
1435                              server->stat.my_channels));
1436   }
1437
1438   if (server->stat.server_ops || server->stat.router_ops)
1439     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1440                             ("There are %d server operators and %d router "
1441                              "operators online",
1442                              server->stat.server_ops,
1443                              server->stat.router_ops));
1444   if (server->stat.my_router_ops + server->stat.my_server_ops)
1445     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1446                             ("I have %d operators online",
1447                              server->stat.my_router_ops +
1448                              server->stat.my_server_ops));
1449
1450   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1451                           ("Your connection is secured with %s cipher, "
1452                            "key length %d bits",
1453                            idata->send_key->cipher->name,
1454                            idata->send_key->cipher->key_len));
1455   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1456                           ("Your current nickname is %s",
1457                            client->nickname));
1458
1459   /* Send motd */
1460   silc_server_send_motd(server, sock);
1461 }
1462
1463 /* Kill the client indicated by `remote_client' sending KILLED notify
1464    to the client, to all channels client has joined and to primary
1465    router if needed.  The killed client is also removed from all channels. */
1466
1467 void silc_server_kill_client(SilcServer server,
1468                              SilcClientEntry remote_client,
1469                              const char *comment,
1470                              void *killer_id,
1471                              SilcIdType killer_id_type)
1472 {
1473   SilcBuffer killed, killer;
1474
1475   SILC_LOG_DEBUG(("Killing client %s", 
1476                   silc_id_render(remote_client->id, SILC_ID_CLIENT)));
1477
1478   /* Send the KILL notify packets. First send it to the channel, then
1479      to our primary router and then directly to the client who is being
1480      killed right now. */
1481
1482   killed = silc_id_payload_encode(remote_client->id, SILC_ID_CLIENT);
1483   killer = silc_id_payload_encode(killer_id, killer_id_type);
1484
1485   /* Send KILLED notify to the channels. It is not sent to the client
1486      as it will be sent differently destined directly to the client and not
1487      to the channel. */
1488   silc_server_send_notify_on_channels(server, remote_client, 
1489                                       remote_client, SILC_NOTIFY_TYPE_KILLED,
1490                                       3, killed->data, killed->len,
1491                                       comment, comment ? strlen(comment) : 0,
1492                                       killer->data, killer->len);
1493
1494   /* Send KILLED notify to primary route */
1495   silc_server_send_notify_killed(server, SILC_PRIMARY_ROUTE(server),
1496                                  SILC_BROADCAST(server), remote_client->id,
1497                                  comment, killer_id, killer_id_type);
1498
1499   /* Send KILLED notify to the client directly */
1500   if (remote_client->connection || remote_client->router)
1501     silc_server_send_notify_killed(server, remote_client->connection ? 
1502                                    remote_client->connection : 
1503                                    remote_client->router->connection, FALSE,
1504                                    remote_client->id, comment, 
1505                                    killer_id, killer_id_type);
1506
1507   /* Remove the client from all channels. This generates new keys to the
1508      channels as well. */
1509   silc_server_remove_from_channels(server, NULL, remote_client, FALSE, 
1510                                    NULL, TRUE);
1511
1512   /* Remove the client entry, If it is locally connected then we will also
1513      disconnect the client here */
1514   if (remote_client->connection) {
1515     /* Remove locally conneted client */
1516     SilcSocketConnection sock = remote_client->connection;
1517     silc_server_free_client_data(server, sock, remote_client, FALSE, NULL);
1518     silc_server_close_connection(server, sock);
1519   } else {
1520     /* Update statistics */
1521     server->stat.clients--;
1522     if (server->stat.cell_clients)
1523       server->stat.cell_clients--;
1524     SILC_OPER_STATS_UPDATE(remote_client, server, SILC_UMODE_SERVER_OPERATOR);
1525     SILC_OPER_STATS_UPDATE(remote_client, router, SILC_UMODE_ROUTER_OPERATOR);
1526
1527     if (SILC_IS_LOCAL(remote_client)) {
1528       server->stat.my_clients--;
1529       silc_schedule_task_del_by_context(server->schedule, remote_client);
1530       silc_idlist_del_data(remote_client);
1531     }
1532
1533     /* Remove remote client */
1534     silc_idlist_del_data(remote_client);
1535     if (!silc_idlist_del_client(server->global_list, remote_client)) {
1536       /* Remove this client from watcher list if it is */
1537       silc_server_del_from_watcher_list(server, remote_client);
1538       silc_idlist_del_client(server->local_list, remote_client);  
1539     }
1540   }
1541
1542   silc_buffer_free(killer);
1543   silc_buffer_free(killed);
1544 }
1545
1546 typedef struct {
1547   SilcServer server;
1548   SilcClientEntry client;
1549   SilcNotifyType notify;
1550   const char *new_nick;
1551 } WatcherNotifyContext;
1552
1553 static void 
1554 silc_server_check_watcher_list_foreach(void *key, void *context, 
1555                                        void *user_context)
1556 {
1557   WatcherNotifyContext *notify = user_context;
1558   SilcClientEntry entry = context;
1559   SilcSocketConnection sock;
1560
1561   if (entry == notify->client)
1562     return;
1563
1564   sock = silc_server_get_client_route(notify->server, NULL, 0, entry->id,
1565                                       NULL, NULL);
1566   if (sock) {
1567     SILC_LOG_DEBUG(("Sending WATCH notify to %s",
1568                     silc_id_render(entry->id, SILC_ID_CLIENT)));
1569
1570     /* Send the WATCH notify */
1571     silc_server_send_notify_watch(notify->server, sock, entry, 
1572                                   notify->client, 
1573                                   notify->new_nick ? notify->new_nick :
1574                                   (const char *)notify->client->nickname, 
1575                                   notify->notify);
1576   }
1577 }
1578
1579 /* This function checks whether the `client' nickname is being watched
1580    by someone, and notifies the watcher of the notify change of notify
1581    type indicated by `notify'. */
1582
1583 bool silc_server_check_watcher_list(SilcServer server,
1584                                     SilcClientEntry client,
1585                                     const char *new_nick,
1586                                     SilcNotifyType notify)
1587 {
1588   unsigned char hash[16];
1589   WatcherNotifyContext n;
1590
1591   SILC_LOG_DEBUG(("Checking watcher list %s",
1592                   client->nickname ? client->nickname : (unsigned char *)""));
1593
1594   /* If the watching is rejected by the client do nothing */
1595   if (client->mode & SILC_UMODE_REJECT_WATCHING)
1596     return FALSE;
1597
1598   /* Make hash from the nick, or take it from Client ID */
1599   if (client->nickname) {
1600     char nick[128 + 1];
1601     memset(nick, 0, sizeof(nick));
1602     silc_to_lower(client->nickname, nick, sizeof(nick) - 1);
1603     silc_hash_make(server->md5hash, nick, strlen(nick), hash);
1604   } else {
1605     memset(hash, 0, sizeof(hash));
1606     memcpy(hash, client->id->hash, sizeof(client->id->hash));
1607   }
1608
1609   n.server = server;
1610   n.client = client;
1611   n.new_nick = new_nick;
1612   n.notify = notify;
1613
1614   /* Send notify to all watchers */
1615   silc_hash_table_find_foreach(server->watcher_list, hash,
1616                                silc_server_check_watcher_list_foreach, &n);
1617
1618   return TRUE;
1619 }
1620
1621 /* Remove the `client' from watcher list. After calling this the `client'
1622    is not watching any nicknames. */
1623
1624 bool silc_server_del_from_watcher_list(SilcServer server,
1625                                        SilcClientEntry client)
1626 {
1627   SilcHashTableList htl;
1628   void *key;
1629   SilcClientEntry entry;
1630   bool found = FALSE;
1631
1632   silc_hash_table_list(server->watcher_list, &htl);
1633   while (silc_hash_table_get(&htl, &key, (void **)&entry)) {
1634     if (entry == client) {
1635       silc_hash_table_del_by_context(server->watcher_list, key, client);
1636
1637       if (client->id)
1638         SILC_LOG_DEBUG(("Removing %s from WATCH list",
1639                         silc_id_render(client->id, SILC_ID_CLIENT)));
1640
1641       /* Now check whether there still exists entries with this key, if not
1642          then free the key to not leak memory. */
1643       if (!silc_hash_table_find(server->watcher_list, key, NULL, NULL))
1644         silc_free(key);
1645
1646       found = TRUE;
1647     }
1648   }
1649   silc_hash_table_list_reset(&htl);
1650
1651   return found;
1652 }
1653
1654 /* Force the client indicated by `chl' to change the channel user mode
1655    on channel indicated by `channel' to `forced_mode'. */
1656
1657 bool silc_server_force_cumode_change(SilcServer server,
1658                                      SilcSocketConnection sock,
1659                                      SilcChannelEntry channel,
1660                                      SilcChannelClientEntry chl,
1661                                      SilcUInt32 forced_mode)
1662 {
1663   SilcBuffer idp1, idp2;
1664   unsigned char cumode[4];
1665
1666   SILC_LOG_DEBUG(("Enforcing sender to change mode"));
1667
1668   if (sock)
1669     silc_server_send_notify_cumode(server, sock, FALSE, channel, forced_mode,
1670                                    server->id, SILC_ID_SERVER,
1671                                    chl->client->id, NULL);
1672
1673   idp1 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
1674   idp2 = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
1675   SILC_PUT32_MSB(forced_mode, cumode);
1676   silc_server_send_notify_to_channel(server, sock, channel, FALSE,
1677                                      SILC_NOTIFY_TYPE_CUMODE_CHANGE,
1678                                      3, idp1->data, idp1->len,
1679                                      cumode, sizeof(cumode),
1680                                      idp2->data, idp2->len);
1681   silc_buffer_free(idp1);
1682   silc_buffer_free(idp2);
1683
1684   return TRUE;
1685 }
1686
1687 /* Find active socket connection by the IP address and port indicated by
1688    `ip' and `port', and socket connection type of `type'. */
1689
1690 SilcSocketConnection
1691 silc_server_find_socket_by_host(SilcServer server,
1692                                 SilcSocketType type,
1693                                 const char *ip, SilcUInt16 port)
1694 {
1695   int i;
1696
1697   for (i = 0; i < server->config->param.connections_max; i++) {
1698     if (!server->sockets[i])
1699       continue;
1700     if (!strcmp(server->sockets[i]->ip, ip) &&
1701         (!port || server->sockets[i]->port == port) &&
1702         server->sockets[i]->type == type)
1703       return server->sockets[i];
1704   }
1705
1706   return NULL;
1707 }