Don't decrement my_clients when killing or expiring a detached client.
[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 - 2008 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 %s from all channels",
46                  client->nickname ? client->nickname :
47                   (unsigned char *)""));
48
49   if (silc_hash_table_find(clients, client, NULL, NULL))
50     silc_hash_table_del(clients, client);
51
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;
57
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);
66       continue;
67     }
68
69     silc_hash_table_del(client->channels, channel);
70     silc_hash_table_del(channel->user_list, chl->client);
71     channel->user_count--;
72
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;
78
79     silc_free(chl);
80
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--;
87     }
88
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);
98       continue;
99     }
100
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;
106       if (!c)
107         continue;
108
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);
113     }
114     silc_hash_table_list_reset(&htl2);
115
116     /* Add the channel to the the channels list to regenerate the
117        channel key */
118     if (!silc_hash_table_find(channels, channel, NULL, NULL))
119       silc_hash_table_add(channels, channel, channel);
120   }
121   silc_hash_table_list_reset(&htl);
122   SILC_VERIFY(!silc_hash_table_count(client->channels));
123 }
124
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. */
129
130 SilcBool silc_server_remove_clients_by_server(SilcServer server,
131                                               SilcServerEntry router,
132                                               SilcServerEntry entry,
133                                               SilcBool server_signoff)
134 {
135   SilcList list;
136   SilcIDCacheEntry id_cache = NULL;
137   SilcClientEntry client = NULL;
138   SilcBuffer idp;
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;
144   int i;
145
146   if (!(entry->data.status & SILC_IDLIST_STATUS_REGISTERED))
147     return FALSE;
148
149   SILC_LOG_DEBUG(("Removing clients by %s",
150                   entry->server_name ? entry->server_name : "server"));
151
152   if (!router)
153     router = entry;
154
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,
159                                    NULL, NULL, TRUE);
160   clients = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL, NULL,
161                                   NULL, NULL, TRUE);
162
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(silc_buffer_len(idp), sizeof(*argv[0]));
169     memcpy(argv[argc], idp->data, silc_buffer_len(idp));
170     argv_lens[argc] = silc_buffer_len(idp);
171     argv_types[argc] = argc + 1;
172     argc++;
173     silc_buffer_free(idp);
174   }
175
176   if (silc_idcache_get_all(server->local_list->clients, &list)) {
177     silc_list_start(list);
178     while ((id_cache = silc_list_get(list))) {
179       client = (SilcClientEntry)id_cache->context;
180
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         continue;
188       }
189
190       if (server_signoff) {
191         idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
192         if (idp) {
193           argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
194           argv_lens = silc_realloc(argv_lens, sizeof(*argv_lens) *
195                                    (argc + 1));
196           argv_types = silc_realloc(argv_types, sizeof(*argv_types) *
197                                     (argc + 1));
198           argv[argc] = silc_calloc(silc_buffer_len(idp), sizeof(*argv[0]));
199           memcpy(argv[argc], idp->data, silc_buffer_len(idp));
200           argv_lens[argc] = silc_buffer_len(idp);
201           argv_types[argc] = argc + 1;
202           argc++;
203           silc_buffer_free(idp);
204         }
205       }
206
207       /* Update statistics */
208       SILC_VERIFY(server->stat.clients > 0);
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);
214
215       /* Remove client's public key from repository, this will free it too. */
216       if (client->data.public_key) {
217         silc_skr_del_public_key(server->repository, client->data.public_key,
218                                 client);
219         client->data.public_key = NULL;
220       }
221
222       silc_server_remove_clients_channels(server, entry, clients,
223                                           client, channels);
224       silc_server_del_from_watcher_list(server, client);
225
226       /* Remove the client entry */
227       if (!server_signoff) {
228         client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
229         client->mode = 0;
230         client->router = NULL;
231         client->connection = NULL;
232         client->data.created = silc_time();
233         silc_dlist_del(server->expired_clients, client);
234         silc_dlist_add(server->expired_clients, client);
235       } else {
236         silc_idlist_del_data(client);
237         silc_idlist_del_client(server->local_list, client);
238       }
239     }
240   }
241
242   if (silc_idcache_get_all(server->global_list->clients, &list)) {
243     silc_list_start(list);
244     while ((id_cache = silc_list_get(list))) {
245       client = (SilcClientEntry)id_cache->context;
246
247       /* If client is not registered, is not originated from `router'
248          and is not owned by `entry', skip it. */
249       if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) ||
250           client->router != router ||
251           (router != entry && !SILC_ID_COMPARE(client->id, entry->id,
252                                                client->id->ip.data_len))) {
253         continue;
254       }
255
256       if (server_signoff) {
257         idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
258         argv = silc_realloc(argv, sizeof(*argv) * (argc + 1));
259         argv_lens = silc_realloc(argv_lens, sizeof(*argv_lens) *
260                                  (argc + 1));
261         argv_types = silc_realloc(argv_types, sizeof(*argv_types) *
262                                   (argc + 1));
263         argv[argc] = silc_calloc(silc_buffer_len(idp), sizeof(*argv[0]));
264         memcpy(argv[argc], idp->data, silc_buffer_len(idp));
265         argv_lens[argc] = silc_buffer_len(idp);
266         argv_types[argc] = argc + 1;
267         argc++;
268         silc_buffer_free(idp);
269       }
270
271       /* Update statistics */
272       SILC_VERIFY(server->stat.clients > 0);
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);
278
279       /* Remove client's public key from repository, this will free it too. */
280       if (client->data.public_key) {
281         silc_skr_del_public_key(server->repository, client->data.public_key,
282                                 client);
283         client->data.public_key = NULL;
284       }
285
286       silc_server_remove_clients_channels(server, entry, clients,
287                                           client, channels);
288       silc_server_del_from_watcher_list(server, client);
289
290       /* Remove the client entry */
291       if (!server_signoff) {
292         client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
293         client->mode = 0;
294         client->router = NULL;
295         client->connection = NULL;
296         client->data.created = silc_time();
297         silc_dlist_del(server->expired_clients, client);
298         silc_dlist_add(server->expired_clients, client);
299       } else {
300         silc_idlist_del_data(client);
301         silc_idlist_del_client(server->global_list, client);
302       }
303     }
304   }
305
306   /* Return now if we are shutting down */
307   if (server->server_shutdown) {
308     silc_hash_table_free(channels);
309
310     if (server_signoff) {
311       for (i = 0; i < argc; i++)
312         silc_free(argv[i]);
313       silc_free(argv);
314       silc_free(argv_lens);
315       silc_free(argv_types);
316       silc_hash_table_free(clients);
317     }
318     return TRUE;
319   }
320
321   /* Send the SERVER_SIGNOFF notify */
322   if (server_signoff) {
323     SilcBuffer args, not;
324
325     SILC_LOG_DEBUG(("Sending SERVER_SIGNOFF for %s with %d clients",
326                     silc_id_render(entry->id, SILC_ID_SERVER), argc - 1));
327
328     /* Send SERVER_SIGNOFF notify to our primary router */
329     if (server->router != entry) {
330       args = silc_argument_payload_encode(1, argv, argv_lens,
331                                           argv_types);
332       silc_server_send_notify_args(server, SILC_PRIMARY_ROUTE(server),
333                                    SILC_BROADCAST(server),
334                                    SILC_NOTIFY_TYPE_SERVER_SIGNOFF,
335                                    argc, args);
336       silc_buffer_free(args);
337     }
338
339     /* Send to local clients. We also send the list of client ID's that
340        is to be removed for those servers that would like to use that list. */
341     args = silc_argument_payload_encode(argc, argv, argv_lens,
342                                         argv_types);
343     not = silc_notify_payload_encode_args(SILC_NOTIFY_TYPE_SERVER_SIGNOFF,
344                                           argc, args);
345     silc_server_packet_send_clients(server, clients,
346                                     SILC_PACKET_NOTIFY, 0, FALSE,
347                                     not->data, silc_buffer_len(not));
348
349     /* Send notify also to local backup routers */
350     silc_server_backup_send(server, NULL, SILC_PACKET_NOTIFY, 0,
351                             not->data, silc_buffer_len(not), FALSE, TRUE);
352
353     silc_buffer_free(args);
354     silc_buffer_free(not);
355     for (i = 0; i < argc; i++)
356       silc_free(argv[i]);
357     silc_free(argv);
358     silc_free(argv_lens);
359     silc_free(argv_types);
360     silc_hash_table_free(clients);
361   }
362
363   /* We must now re-generate the channel key for all channels that had
364      this server's client(s) on the channel. As they left the channel we
365      must re-generate the channel key. */
366   silc_hash_table_list(channels, &htl);
367   while (silc_hash_table_get(&htl, NULL, (void *)&channel)) {
368     if (!silc_server_create_channel_key(server, channel, 0)) {
369       silc_hash_table_list_reset(&htl);
370       silc_hash_table_free(channels);
371       return FALSE;
372     }
373
374     /* Do not send the channel key if private channel key mode is set */
375     if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY || !channel->send_key)
376       continue;
377
378     silc_server_send_channel_key(server, NULL, channel,
379                                  server->server_type == SILC_ROUTER ?
380                                  FALSE : !server->standalone);
381   }
382   silc_hash_table_list_reset(&htl);
383   silc_hash_table_free(channels);
384
385   return TRUE;
386 }
387
388 static SilcServerEntry
389 silc_server_update_clients_by_real_server(SilcServer server,
390                                           SilcServerEntry from,
391                                           SilcServerEntry to,
392                                           SilcClientEntry client,
393                                           SilcBool local,
394                                           SilcIDCacheEntry client_cache)
395 {
396   SilcServerEntry server_entry;
397   SilcIDCacheEntry id_cache = NULL;
398   SilcList list;
399   SilcBool tolocal = (to == server->id_entry);
400
401   SILC_LOG_DEBUG(("Start"));
402
403   if (!silc_idcache_get_all(server->local_list->servers, &list))
404     return NULL;
405
406   silc_list_start(list);
407   while ((id_cache = silc_list_get(list))) {
408     server_entry = (SilcServerEntry)id_cache->context;
409     if (server_entry != from &&
410         (tolocal || server_entry != server->id_entry) &&
411         SILC_ID_COMPARE(server_entry->id, client->id,
412                         client->id->ip.data_len)) {
413       SILC_LOG_DEBUG(("Found (local) %s",
414                       silc_id_render(server_entry->id, SILC_ID_SERVER)));
415
416       if (!SILC_IS_LOCAL(server_entry) && server_entry->router) {
417         SILC_LOG_DEBUG(("Server not locally connected, use its router"));
418         /* If the client is not marked as local then move it to local list
419            since the server is local. */
420         if (!local) {
421           SILC_LOG_DEBUG(("Moving client to local list"));
422           silc_idcache_move(server->global_list->clients,
423                             server->local_list->clients, client_cache);
424         }
425         server_entry = server_entry->router;
426       } else {
427         SILC_LOG_DEBUG(("Server locally connected"));
428         /* If the client is not marked as local then move it to local list
429            since the server is local. */
430         if (server_entry->server_type != SILC_BACKUP_ROUTER && !local) {
431           SILC_LOG_DEBUG(("Moving client to local list"));
432           silc_idcache_move(server->global_list->clients,
433                             server->local_list->clients, client_cache);
434
435         } else if (server->server_type == SILC_BACKUP_ROUTER && local) {
436           /* If we are backup router and this client is on local list, we
437              must move it to global list, as it is not currently local to
438              us (we are not primary). */
439           SILC_LOG_DEBUG(("Moving client to global list"));
440           silc_idcache_move(server->local_list->clients,
441                             server->global_list->clients, client_cache);
442         }
443       }
444
445       return server_entry;
446     }
447   }
448
449   if (!silc_idcache_get_all(server->global_list->servers, &list))
450     return NULL;
451
452   silc_list_start(list);
453   while ((id_cache = silc_list_get(list))) {
454     server_entry = (SilcServerEntry)id_cache->context;
455     if (server_entry != from && server_entry != server->id_entry &&
456         (tolocal || server_entry != server->id_entry) &&
457         SILC_ID_COMPARE(server_entry->id, client->id,
458                         client->id->ip.data_len)) {
459       SILC_LOG_DEBUG(("Found (global) %s",
460                       silc_id_render(server_entry->id, SILC_ID_SERVER)));
461
462       if (!SILC_IS_LOCAL(server_entry) && server_entry->router) {
463         SILC_LOG_DEBUG(("Server not locally connected, use its router"));
464         /* If the client is marked as local then move it to global list
465            since the server is global. */
466         if (local) {
467           SILC_LOG_DEBUG(("Moving client to global list"));
468           silc_idcache_move(server->local_list->clients,
469                             server->global_list->clients, client_cache);
470         }
471         server_entry = server_entry->router;
472       } else {
473         SILC_LOG_DEBUG(("Server locally connected"));
474         /* If the client is marked as local then move it to global list
475            since the server is global. */
476         if (server_entry->server_type != SILC_BACKUP_ROUTER && local) {
477           SILC_LOG_DEBUG(("Moving client to global list"));
478           silc_idcache_move(server->local_list->clients,
479                             server->global_list->clients, client_cache);
480         }
481       }
482       return server_entry;
483     }
484   }
485
486   return NULL;
487 }
488
489 /* Updates the clients that are originated from the `from' to be originated
490    from the `to'. If the `resolve_real_server' is TRUE then this will
491    attempt to figure out which clients really are originated from the
492    `from' and which are originated from a server that we have connection
493    to, when we've acting as backup router. If it is FALSE the `to' will
494    be the new source. */
495
496 void silc_server_update_clients_by_server(SilcServer server,
497                                           SilcServerEntry from,
498                                           SilcServerEntry to,
499                                           SilcBool resolve_real_server)
500 {
501   SilcList list;
502   SilcIDCacheEntry id_cache = NULL;
503   SilcClientEntry client = NULL;
504   SilcBool local;
505
506   if (from && from->id) {
507     SILC_LOG_DEBUG(("Changing from server %s",
508                     silc_id_render(from->id, SILC_ID_SERVER)));
509   }
510   if (to && to->id) {
511     SILC_LOG_DEBUG(("Changing to server %s",
512                     silc_id_render(to->id, SILC_ID_SERVER)));
513   }
514
515   SILC_LOG_DEBUG(("global list"));
516   local = FALSE;
517   if (silc_idcache_get_all(server->global_list->clients, &list)) {
518     silc_list_start(list);
519     while ((id_cache = silc_list_get(list))) {
520       client = (SilcClientEntry)id_cache->context;
521
522       /* If entry is disabled skip it.  If entry is local to us, do not
523          switch it to anyone else, it is ours so skip it. */
524       if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) ||
525           SILC_IS_LOCAL(client))
526         continue;
527
528       SILC_LOG_DEBUG(("Client %s",
529                       silc_id_render(client->id, SILC_ID_CLIENT)));
530       if (client->router && client->router->id)
531         SILC_LOG_DEBUG(("Client->router %s",
532                         silc_id_render(client->router->id, SILC_ID_SERVER)));
533
534       if (from) {
535         if (client->router == from) {
536           if (resolve_real_server) {
537             client->router =
538               silc_server_update_clients_by_real_server(server, from, to,
539                                                         client, local,
540                                                         id_cache);
541             if (!client->router) {
542               if (server->server_type == SILC_ROUTER)
543                 client->router = from;
544               else
545                 client->router = to;
546             }
547           } else {
548             client->router = to;
549           }
550         }
551       } else {
552         /* All are changed */
553         if (resolve_real_server)
554           /* Call this so that the entry is moved to correct list if
555              needed.  No resolving by real server is actually done. */
556           silc_server_update_clients_by_real_server(server, NULL, to,
557                                                     client, local,
558                                                     id_cache);
559
560         client->router = to;
561       }
562
563       if (client->router && client->router->id)
564         SILC_LOG_DEBUG(("Client changed to %s",
565                         silc_id_render(client->router->id, SILC_ID_SERVER)));
566     }
567   }
568
569   SILC_LOG_DEBUG(("local list"));
570   local = TRUE;
571   if (silc_idcache_get_all(server->local_list->clients, &list)) {
572     silc_list_start(list);
573     while ((id_cache = silc_list_get(list))) {
574       client = (SilcClientEntry)id_cache->context;
575
576       /* If entry is disabled skip it.  If entry is local to us, do not
577          switch it to anyone else, it is ours so skip it. */
578       if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED) ||
579           SILC_IS_LOCAL(client))
580         continue;
581
582       SILC_LOG_DEBUG(("Client %s",
583                       silc_id_render(client->id, SILC_ID_CLIENT)));
584       if (client->router && client->router->id)
585         SILC_LOG_DEBUG(("Client->router %s",
586                         silc_id_render(client->router->id, SILC_ID_SERVER)));
587
588       if (from) {
589         if (client->router == from) {
590           if (resolve_real_server) {
591             client->router =
592               silc_server_update_clients_by_real_server(server, from, to,
593                                                         client, local,
594                                                         id_cache);
595             if (!client->router)
596               client->router = from;
597           } else {
598             client->router = to;
599           }
600         }
601       } else {
602         /* All are changed */
603         if (resolve_real_server)
604           /* Call this so that the entry is moved to correct list if
605              needed.  No resolving by real server is actually done. */
606           silc_server_update_clients_by_real_server(server, NULL, to,
607                                                     client, local,
608                                                     id_cache);
609
610         client->router = to;
611       }
612
613       if (client->router && client->router->id)
614         SILC_LOG_DEBUG(("Client changed to %s",
615                         silc_id_render(client->router->id, SILC_ID_SERVER)));
616     }
617   }
618 }
619
620 /* Updates servers that are from `from' to be originated from `to'.  This
621    will also update the server's connection to `to's connection. */
622
623 void silc_server_update_servers_by_server(SilcServer server,
624                                           SilcServerEntry from,
625                                           SilcServerEntry to)
626 {
627   SilcList list;
628   SilcIDCacheEntry id_cache = NULL;
629   SilcServerEntry server_entry = NULL;
630
631   SILC_LOG_DEBUG(("Updating servers"));
632
633   if (silc_idcache_get_all(server->local_list->servers, &list)) {
634     silc_list_start(list);
635     while ((id_cache = silc_list_get(list))) {
636       server_entry = (SilcServerEntry)id_cache->context;
637
638       /* If entry is local to us, do not switch it to any anyone else,
639          it is ours. */
640       if (SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry ||
641           server_entry == from)
642         continue;
643
644       /* If we are standalone router, any server that is not directly
645          connected to cannot exist anymore.  If we are not standalone
646          we update it correctly. */
647       if (server->server_type == SILC_ROUTER && server->standalone) {
648         silc_server_backup_del(server, server_entry);
649         silc_server_backup_replaced_del(server, server_entry);
650         silc_idlist_del_data(server_entry);
651         silc_idlist_del_server(server->local_list, server_entry);
652         server->stat.servers--;
653         server->stat.cell_servers--;
654       } else {
655         /* XXX if we are not standalone, do a check from local config
656            whether this server is in our cell, but not connected to
657            us (in which case we must remove it). */
658
659         if (from) {
660           if (server_entry->router == from) {
661             SILC_LOG_DEBUG(("Updating server (local) %s",
662                             server_entry->server_name ?
663                             server_entry->server_name : ""));
664             server_entry->router = to;
665             server_entry->connection = to->connection;
666           }
667         } else {
668           /* Update all */
669           SILC_LOG_DEBUG(("Updating server (local) %s",
670                           server_entry->server_name ?
671                           server_entry->server_name : ""));
672           server_entry->router = to;
673           server_entry->connection = to->connection;
674         }
675       }
676     }
677   }
678
679   if (silc_idcache_get_all(server->global_list->servers, &list)) {
680     silc_list_start(list);
681     while ((id_cache = silc_list_get(list))) {
682       server_entry = (SilcServerEntry)id_cache->context;
683
684       /* If entry is local to us, do not switch it to anyone else,
685          it is ours. */
686       if (SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry ||
687           server_entry == from)
688         continue;
689
690       /* If we are standalone router, any server that is not directly
691          connected to cannot exist anymore.  If we are not standalone
692          we update it correctly. */
693       if (server->server_type == SILC_ROUTER && server->standalone) {
694         silc_server_backup_del(server, server_entry);
695         silc_server_backup_replaced_del(server, server_entry);
696         silc_idlist_del_data(server_entry);
697         silc_idlist_del_server(server->global_list, server_entry);
698         server->stat.servers--;
699         server->stat.cell_servers--;
700       } else {
701         /* XXX if we are not standalone, do a check from local config
702            whether this server is in our cell, but not connected to
703            us (in which case we must remove it). */
704
705         if (from) {
706           if (server_entry->router == from) {
707             SILC_LOG_DEBUG(("Updating server (global) %s",
708                             server_entry->server_name ?
709                             server_entry->server_name : ""));
710             server_entry->router = to;
711             server_entry->connection = to->connection;
712           }
713         } else {
714           /* Update all */
715           SILC_LOG_DEBUG(("Updating server (global) %s",
716                           server_entry->server_name ?
717                           server_entry->server_name : ""));
718           server_entry->router = to;
719           server_entry->connection = to->connection;
720         }
721       }
722     }
723   }
724 }
725
726
727 /* Toggles the enabled/disabled status of local server connections.  Packets
728    can be sent to the servers when `toggle_enabled' is TRUE and will be
729    dropped if `toggle_enabled' is FALSE, after this function is called. */
730
731 void silc_server_local_servers_toggle_enabled(SilcServer server,
732                                               SilcBool toggle_enabled)
733 {
734   SilcList list;
735   SilcIDCacheEntry id_cache = NULL;
736   SilcServerEntry server_entry = NULL;
737
738   if (silc_idcache_get_all(server->local_list->servers, &list)) {
739     silc_list_start(list);
740     while ((id_cache = silc_list_get(list))) {
741       server_entry = (SilcServerEntry)id_cache->context;
742       if (!SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry)
743         continue;
744
745       if (toggle_enabled)
746         server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
747       else
748         server_entry->data.status |= SILC_IDLIST_STATUS_DISABLED;
749
750     }
751   }
752
753   if (silc_idcache_get_all(server->global_list->servers, &list)) {
754     silc_list_start(list);
755     while ((id_cache = silc_list_get(list))) {
756       server_entry = (SilcServerEntry)id_cache->context;
757       if (!SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry)
758         continue;
759
760       if (toggle_enabled)
761         server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED;
762       else
763         server_entry->data.status |= SILC_IDLIST_STATUS_DISABLED;
764
765     }
766   }
767 }
768
769 /* Removes servers that are originated from the `from'.  The server
770    entry is deleted in this function.  If `remove_clients' is TRUE then
771    all clients originated from the server are removed too, and server
772    signoff is sent.  Note that this does not remove the `from'.  This
773    also does not remove locally connected servers. */
774
775 void silc_server_remove_servers_by_server(SilcServer server,
776                                           SilcServerEntry from,
777                                           SilcBool remove_clients)
778 {
779   SilcList list;
780   SilcIDCacheEntry id_cache = NULL;
781   SilcServerEntry server_entry = NULL;
782
783   SILC_LOG_DEBUG(("Removing servers by %s",
784                   from->server_name ? from->server_name : "server"));
785
786   if (silc_idcache_get_all(server->local_list->servers, &list)) {
787     silc_list_start(list);
788     while ((id_cache = silc_list_get(list))) {
789       server_entry = (SilcServerEntry)id_cache->context;
790       if (SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry ||
791           server_entry->router != from || server_entry == from)
792         continue;
793
794       /* Remove clients owned by this server */
795       if (remove_clients)
796         silc_server_remove_clients_by_server(server, from, server_entry,
797                                              TRUE);
798
799       /* Remove the server */
800       silc_server_backup_del(server, server_entry);
801       silc_idlist_del_server(server->local_list, server_entry);
802     }
803   }
804
805   if (silc_idcache_get_all(server->global_list->servers, &list)) {
806     silc_list_start(list);
807     while ((id_cache = silc_list_get(list))) {
808       server_entry = (SilcServerEntry)id_cache->context;
809       if (SILC_IS_LOCAL(server_entry) || server_entry == server->id_entry ||
810           server_entry->router != from || server_entry == from)
811         continue;
812
813       /* Remove clients owned by this server */
814       if (remove_clients)
815         silc_server_remove_clients_by_server(server, from, server_entry,
816                                              TRUE);
817
818       /* Remove the server */
819       silc_server_backup_del(server, server_entry);
820       silc_idlist_del_server(server->global_list, server_entry);
821     }
822   }
823 }
824
825 /* Removes channels that are from `from. */
826
827 void silc_server_remove_channels_by_server(SilcServer server,
828                                            SilcServerEntry from)
829 {
830   SilcList list;
831   SilcIDCacheEntry id_cache = NULL;
832   SilcChannelEntry channel = NULL;
833
834   SILC_LOG_DEBUG(("Removing channels by server"));
835
836   if (silc_idcache_get_all(server->global_list->channels, &list)) {
837     silc_list_start(list);
838     while ((id_cache = silc_list_get(list))) {
839       channel = (SilcChannelEntry)id_cache->context;
840       if (channel->router == from)
841         silc_idlist_del_channel(server->global_list, channel);
842     }
843   }
844 }
845
846 /* Updates channels that are from `from' to be originated from `to'.  */
847
848 void silc_server_update_channels_by_server(SilcServer server,
849                                            SilcServerEntry from,
850                                            SilcServerEntry to)
851 {
852   SilcList list;
853   SilcIDCacheEntry id_cache = NULL;
854   SilcChannelEntry channel = NULL;
855
856   SILC_LOG_DEBUG(("Updating channels by server"));
857
858   if (silc_idcache_get_all(server->global_list->channels, &list)) {
859     silc_list_start(list);
860     while ((id_cache = silc_list_get(list))) {
861       channel = (SilcChannelEntry)id_cache->context;
862       if (from) {
863         if (channel->router == from)
864           channel->router = to;
865       } else {
866         /* Update all */
867         channel->router = to;
868       }
869     }
870   }
871 }
872
873 /* Checks whether given channel has global users.  If it does this returns
874    TRUE and FALSE if there is only locally connected clients on the channel. */
875
876 SilcBool silc_server_channel_has_global(SilcChannelEntry channel)
877 {
878   SilcChannelClientEntry chl;
879   SilcHashTableList htl;
880
881   silc_hash_table_list(channel->user_list, &htl);
882   while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
883     if (chl->client->router) {
884       silc_hash_table_list_reset(&htl);
885       return TRUE;
886     }
887   }
888   silc_hash_table_list_reset(&htl);
889
890   return FALSE;
891 }
892
893 /* Checks whether given channel has locally connected users.  If it does this
894    returns TRUE and FALSE if there is not one locally connected client. */
895
896 SilcBool silc_server_channel_has_local(SilcChannelEntry channel)
897 {
898   SilcChannelClientEntry chl;
899   SilcHashTableList htl;
900
901   silc_hash_table_list(channel->user_list, &htl);
902   while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
903     if (SILC_IS_LOCAL(chl->client)) {
904       silc_hash_table_list_reset(&htl);
905       return TRUE;
906     }
907   }
908   silc_hash_table_list_reset(&htl);
909
910   return FALSE;
911 }
912
913 /* This function removes the channel and all users on the channel, unless
914    the channel is permanent.  In this case the channel is disabled but all
915    users are removed from the channel.  Returns TRUE if the channel is
916    destroyed totally, and FALSE if it is permanent and remains. */
917
918 SilcBool silc_server_channel_delete(SilcServer server,
919                                     SilcChannelEntry channel)
920 {
921   SilcChannelClientEntry chl;
922   SilcHashTableList htl;
923   SilcBool delchan = !(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH);
924
925   SILC_LOG_DEBUG(("Deleting channel %s", channel->channel_name));
926
927   if (delchan) {
928     /* Update statistics */
929     if (server->server_type == SILC_ROUTER)
930       server->stat.chanclients -= channel->user_count;
931
932     /* Totally delete the channel and all users on the channel. The
933        users are deleted automatically in silc_idlist_del_channel. */
934     channel->disabled = TRUE;
935     silc_schedule_task_del_by_context(server->schedule, channel->rekey);
936     if (silc_idlist_del_channel(server->local_list, channel)) {
937       server->stat.my_channels--;
938       if (server->server_type == SILC_ROUTER) {
939         server->stat.channels--;
940         server->stat.cell_channels--;
941       }
942     } else {
943       if (silc_idlist_del_channel(server->global_list, channel))
944         if (server->server_type == SILC_ROUTER)
945           server->stat.channels--;
946     }
947
948     return FALSE;
949   }
950
951   /* Channel is permanent, do not remove it, remove only users */
952   channel->disabled = TRUE;
953   silc_hash_table_list(channel->user_list, &htl);
954   while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
955     silc_hash_table_del(chl->client->channels, channel);
956     silc_hash_table_del(channel->user_list, chl->client);
957     channel->user_count--;
958
959     /* Update statistics */
960     if (SILC_IS_LOCAL(chl->client))
961       server->stat.my_chanclients--;
962     if (server->server_type == SILC_ROUTER) {
963       server->stat.cell_chanclients--;
964       server->stat.chanclients--;
965     }
966
967     silc_free(chl);
968   }
969   silc_hash_table_list_reset(&htl);
970
971   SILC_LOG_DEBUG(("Channel %s remains (permanent)", channel->channel_name));
972
973   return TRUE;
974 }
975
976 /* Returns TRUE if the given client is on the channel.  FALSE if not.
977    This works because we assure that the user list on the channel is
978    always in up to date thus we can only check the channel list from
979    `client' which is faster than checking the user list from `channel'. */
980
981 SilcBool silc_server_client_on_channel(SilcClientEntry client,
982                                        SilcChannelEntry channel,
983                                        SilcChannelClientEntry *chl)
984 {
985   if (!client || !channel)
986     return FALSE;
987
988   return silc_hash_table_find(client->channels, channel, NULL,
989                               (void *)chl);
990 }
991
992 /* Find number of sockets by IP address indicated by `ip'. Returns 0 if
993    socket connections with the IP address does not exist.  Counts only
994    fully established connections. */
995
996 SilcUInt32 silc_server_num_sockets_by_ip(SilcServer server, const char *ip,
997                                          SilcConnectionType type)
998 {
999   SilcServerConnection conn;
1000   SilcIDListData idata;
1001   const char *ipaddr;
1002   int count = 0;
1003
1004   silc_dlist_start(server->conns);
1005   while ((conn = silc_dlist_get(server->conns))) {
1006     if (!conn->sock || !silc_packet_stream_is_valid(conn->sock))
1007       continue;
1008     silc_socket_stream_get_info(silc_packet_stream_get_stream(conn->sock),
1009                                 NULL, NULL, &ipaddr, NULL);
1010     idata = silc_packet_get_context(conn->sock);
1011     if (!strcmp(ipaddr, ip) && idata && idata->conn_type == type)
1012       count++;
1013   }
1014
1015   return count;
1016 }
1017
1018 /* Find active socket connection by the IP address and port indicated by
1019    `ip' and `port', and socket connection type of `type'. */
1020
1021 SilcPacketStream
1022 silc_server_find_socket_by_host(SilcServer server,
1023                                 SilcConnectionType type,
1024                                 const char *ip, SilcUInt16 port)
1025 {
1026   SilcServerConnection conn;
1027   SilcIDListData idata;
1028   const char *ipaddr;
1029
1030   silc_dlist_start(server->conns);
1031   while ((conn = silc_dlist_get(server->conns))) {
1032     if (!conn->sock || !silc_packet_stream_is_valid(conn->sock))
1033       continue;
1034     idata = silc_packet_get_context(conn->sock);
1035     silc_socket_stream_get_info(silc_packet_stream_get_stream(conn->sock),
1036                                 NULL, NULL, &ipaddr, NULL);
1037     if (!strcmp(ipaddr, ip) &&
1038         (!port || conn->remote_port == port) &&
1039         idata->conn_type == type)
1040       return conn->sock;
1041   }
1042
1043   return NULL;
1044 }
1045
1046 /* Find number of sockets by IP address indicated by remote host, indicatd
1047    by `ip' or `hostname', `port', and `type'.  Returns 0 if socket connections
1048    does not exist. If `ip' is provided then `hostname' is ignored. */
1049
1050 SilcUInt32 silc_server_num_sockets_by_remote(SilcServer server,
1051                                              const char *ip,
1052                                              const char *hostname,
1053                                              SilcUInt16 port,
1054                                              SilcConnectionType type)
1055 {
1056   SilcServerConnection conn;
1057   SilcIDListData idata;
1058   SilcConnectionType t = SILC_CONN_UNKNOWN;
1059   int count = 0;
1060
1061   if (!ip && !hostname)
1062     return 0;
1063
1064   SILC_LOG_DEBUG(("Num connections %d", silc_dlist_count(server->conns)));
1065
1066   silc_dlist_start(server->conns);
1067   while ((conn = silc_dlist_get(server->conns))) {
1068     if (conn->sock) {
1069       idata = silc_packet_get_context(conn->sock);
1070       if (idata)
1071         t = idata->conn_type;
1072     }
1073     if (((ip && !strcmp(conn->remote_host, ip)) ||
1074          (hostname && !strcmp(conn->remote_host, hostname))) &&
1075         conn->remote_port == port && t == type)
1076       count++;
1077   }
1078
1079   return count;
1080 }
1081
1082 /* SKR find callbcak */
1083
1084 static void find_callback(SilcSKR skr, SilcSKRFind find,
1085                           SilcSKRStatus status, SilcDList keys,
1086                           void *context)
1087 {
1088   SilcPublicKey *public_key = context;
1089   SilcSKRKey key;
1090
1091   if (keys) {
1092     silc_dlist_start(keys);
1093     key = silc_dlist_get(keys);
1094     *public_key = key->key;
1095     silc_dlist_uninit(keys);
1096   }
1097
1098   silc_skr_find_free(find);
1099 }
1100
1101 /* Get public key by key usage and key context. */
1102
1103 SilcPublicKey silc_server_get_public_key(SilcServer server,
1104                                          SilcSKRKeyUsage usage,
1105                                          void *key_context)
1106 {
1107   SilcSKRFind find;
1108   SilcPublicKey public_key = NULL;
1109
1110   SILC_LOG_DEBUG(("Start"));
1111
1112   find = silc_skr_find_alloc();
1113   if (!find)
1114     return NULL;
1115
1116   silc_skr_find_set_usage(find, usage);
1117   silc_skr_find_set_context(find, key_context);
1118   silc_skr_find(server->repository, server->schedule,
1119                 find, find_callback, &public_key);
1120
1121 #ifdef SILC_DEBUG
1122   if (public_key)
1123     SILC_LOG_DEBUG(("Found public key"));
1124   else
1125     SILC_LOG_DEBUG(("Public key not found"));
1126 #endif /* SILC_DEBUG */
1127
1128   return public_key;
1129 }
1130
1131 /* Find public key by client for identification purposes.  Finds keys
1132    with SILC_SKR_USAGE_IDENTIFICATION. */
1133
1134 SilcBool silc_server_get_public_key_by_client(SilcServer server,
1135                                               SilcClientEntry client,
1136                                               SilcPublicKey *public_key)
1137 {
1138   SilcPublicKey pubkey = NULL;
1139   SilcBool ret = FALSE;
1140
1141   pubkey = silc_server_get_public_key(server, SILC_SKR_USAGE_IDENTIFICATION,
1142                                       client);
1143   if (pubkey)
1144     ret = TRUE;
1145
1146   if (public_key)
1147     *public_key = pubkey;
1148
1149   return ret;
1150 }
1151
1152 /* Check whether the connection `sock' is allowed to connect to us.  This
1153    checks for example whether there is too much connections for this host,
1154    and required version for the host etc. */
1155
1156 SilcBool silc_server_connection_allowed(SilcServer server,
1157                                         SilcPacketStream sock,
1158                                         SilcConnectionType type,
1159                                         SilcServerConfigConnParams *global,
1160                                         SilcServerConfigConnParams *params,
1161                                         SilcSKE ske)
1162 {
1163   SilcUInt32 conn_number = (type == SILC_CONN_CLIENT ?
1164                             server->stat.my_clients :
1165                             type == SILC_CONN_SERVER ?
1166                             server->stat.my_servers :
1167                             server->stat.my_routers);
1168   SilcUInt32 num_sockets, max_hosts, max_per_host;
1169   SilcUInt32 r_protocol_version, l_protocol_version;
1170   SilcUInt32 r_software_version, l_software_version;
1171   char *r_vendor_version = NULL, *l_vendor_version;
1172   const char *hostname, *ip;
1173
1174   silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
1175                               NULL, &hostname, &ip, NULL);
1176
1177   SILC_LOG_DEBUG(("Checking whether connection is allowed"));
1178
1179   /* Check version */
1180
1181   l_protocol_version =
1182     silc_version_to_num(params && params->version_protocol ?
1183                         params->version_protocol :
1184                         global->version_protocol);
1185   l_software_version =
1186     silc_version_to_num(params && params->version_software ?
1187                         params->version_software :
1188                         global->version_software);
1189   l_vendor_version = (params && params->version_software_vendor ?
1190                       params->version_software_vendor :
1191                       global->version_software_vendor);
1192
1193   if (ske && silc_ske_parse_version(ske, &r_protocol_version, NULL,
1194                                     &r_software_version, NULL,
1195                                     &r_vendor_version)) {
1196     /* Match protocol version */
1197     if (l_protocol_version && r_protocol_version &&
1198         r_protocol_version < l_protocol_version) {
1199       SILC_LOG_INFO(("Connection %s (%s) is too old version",
1200                      hostname, ip));
1201       silc_server_disconnect_remote(server, sock,
1202                                     SILC_STATUS_ERR_BAD_VERSION,
1203                                     "You support too old protocol version");
1204       silc_server_free_sock_user_data(server, sock, NULL);
1205       return FALSE;
1206     }
1207
1208     /* Math software version */
1209     if (l_software_version && r_software_version &&
1210         r_software_version < l_software_version) {
1211       SILC_LOG_INFO(("Connection %s (%s) is too old version",
1212                      hostname, ip));
1213       silc_server_disconnect_remote(server, sock,
1214                                     SILC_STATUS_ERR_BAD_VERSION,
1215                                     "You support too old software version");
1216       silc_server_free_sock_user_data(server, sock, NULL);
1217       return FALSE;
1218     }
1219
1220     /* Regex match vendor version */
1221     if (l_vendor_version && r_vendor_version &&
1222         !silc_string_match(l_vendor_version, r_vendor_version)) {
1223       SILC_LOG_INFO(("Connection %s (%s) is unsupported version",
1224                      hostname, ip));
1225       silc_server_disconnect_remote(server, sock,
1226                                     SILC_STATUS_ERR_BAD_VERSION,
1227                                     "Your software is not supported");
1228       silc_server_free_sock_user_data(server, sock, NULL);
1229       return FALSE;
1230     }
1231   }
1232   silc_free(r_vendor_version);
1233
1234   /* Check for maximum connections limit */
1235
1236   num_sockets = silc_server_num_sockets_by_ip(server, ip, type);
1237   max_hosts = (params ? params->connections_max : global->connections_max);
1238   max_per_host = (params ? params->connections_max_per_host :
1239                   global->connections_max_per_host);
1240
1241   if (max_hosts && conn_number >= max_hosts) {
1242     SILC_LOG_DEBUG(("Server is full, %d >= %d", conn_number, max_hosts));
1243     SILC_LOG_INFO(("Server is full, closing %s (%s) connection",
1244                    hostname, ip));
1245     silc_server_disconnect_remote(server, sock,
1246                                   SILC_STATUS_ERR_RESOURCE_LIMIT,
1247                                   "Server is full, try again later");
1248     silc_server_free_sock_user_data(server, sock, NULL);
1249     return FALSE;
1250   }
1251
1252   if (num_sockets >= max_per_host) {
1253     SILC_LOG_DEBUG(("Too many connections, %d >= %d", num_sockets,
1254                     max_per_host));
1255     SILC_LOG_INFO(("Too many connections from %s (%s), closing connection",
1256                    hostname, ip));
1257     silc_server_disconnect_remote(server, sock,
1258                                   SILC_STATUS_ERR_RESOURCE_LIMIT,
1259                                   "Too many connections from your host");
1260     silc_server_free_sock_user_data(server, sock, NULL);
1261     return FALSE;
1262   }
1263
1264   return TRUE;
1265 }
1266
1267 /* Checks that client has rights to add or remove channel modes. If any
1268    of the checks fails FALSE is returned. */
1269
1270 SilcBool silc_server_check_cmode_rights(SilcServer server,
1271                                         SilcChannelEntry channel,
1272                                         SilcChannelClientEntry client,
1273                                         SilcUInt32 mode)
1274 {
1275   SilcBool is_op = client->mode & SILC_CHANNEL_UMODE_CHANOP;
1276   SilcBool is_fo = client->mode & SILC_CHANNEL_UMODE_CHANFO;
1277
1278   /* Check whether has rights to change anything */
1279   if (!is_op && !is_fo)
1280     return FALSE;
1281
1282   /* Check whether has rights to change everything */
1283   if (is_op && is_fo)
1284     return TRUE;
1285
1286   /* Founder implies operator */
1287   if (is_fo)
1288     is_op = TRUE;
1289
1290   /* We know that client is channel operator, check that they are not
1291      changing anything that requires channel founder rights. Rest of the
1292      modes are available automatically for channel operator. */
1293
1294   if (mode & SILC_CHANNEL_MODE_PRIVKEY) {
1295     if (is_op && !is_fo)
1296       return FALSE;
1297   } else {
1298     if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
1299       if (is_op && !is_fo)
1300         return FALSE;
1301     }
1302   }
1303
1304   if (mode & SILC_CHANNEL_MODE_PASSPHRASE) {
1305     if (!(channel->mode & SILC_CHANNEL_MODE_PASSPHRASE)) {
1306       if (is_op && !is_fo)
1307         return FALSE;
1308     }
1309   } else {
1310     if (channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
1311       if (is_op && !is_fo)
1312         return FALSE;
1313     }
1314   }
1315
1316   if (mode & SILC_CHANNEL_MODE_CIPHER) {
1317     if (!(channel->mode & SILC_CHANNEL_MODE_CIPHER)) {
1318       if (is_op && !is_fo)
1319         return FALSE;
1320     }
1321   } else {
1322     if (channel->mode & SILC_CHANNEL_MODE_CIPHER) {
1323       if (is_op && !is_fo)
1324         return FALSE;
1325     }
1326   }
1327
1328   if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
1329     if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
1330       if (is_op && !is_fo)
1331         return FALSE;
1332     }
1333   } else {
1334     if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
1335       if (is_op && !is_fo)
1336         return FALSE;
1337     }
1338   }
1339
1340   if (mode & SILC_CHANNEL_MODE_SILENCE_USERS) {
1341     if (!(channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS)) {
1342       if (is_op && !is_fo)
1343         return FALSE;
1344     }
1345   } else {
1346     if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS) {
1347       if (is_op && !is_fo)
1348         return FALSE;
1349     }
1350   }
1351
1352   if (mode & SILC_CHANNEL_MODE_SILENCE_OPERS) {
1353     if (!(channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS)) {
1354       if (is_op && !is_fo)
1355         return FALSE;
1356     }
1357   } else {
1358     if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS) {
1359       if (is_op && !is_fo)
1360         return FALSE;
1361     }
1362   }
1363
1364   if (mode & SILC_CHANNEL_MODE_CHANNEL_AUTH) {
1365     if (!(channel->mode & SILC_CHANNEL_MODE_CHANNEL_AUTH)) {
1366       if (is_op && !is_fo)
1367         return FALSE;
1368     }
1369   } else {
1370     if (channel->mode & SILC_CHANNEL_MODE_CHANNEL_AUTH) {
1371       if (is_op && !is_fo)
1372         return FALSE;
1373     }
1374   }
1375
1376   return TRUE;
1377 }
1378
1379 /* Check that the client has rights to change its user mode.  Returns
1380    FALSE if setting some mode is not allowed. */
1381
1382 SilcBool silc_server_check_umode_rights(SilcServer server,
1383                                         SilcClientEntry client,
1384                                         SilcUInt32 mode)
1385 {
1386   SilcBool server_op = FALSE, router_op = FALSE;
1387
1388   if (mode & SILC_UMODE_SERVER_OPERATOR) {
1389     /* Cannot set server operator mode (must use OPER command) */
1390     if (!(client->mode & SILC_UMODE_SERVER_OPERATOR))
1391       return FALSE;
1392   } else {
1393     /* Remove the server operator rights */
1394     if (client->mode & SILC_UMODE_SERVER_OPERATOR)
1395       server_op = TRUE;
1396   }
1397
1398   if (mode & SILC_UMODE_ROUTER_OPERATOR) {
1399     /* Cannot set router operator mode (must use SILCOPER command) */
1400     if (!(client->mode & SILC_UMODE_ROUTER_OPERATOR))
1401       return FALSE;
1402   } else {
1403     /* Remove the router operator rights */
1404     if (client->mode & SILC_UMODE_ROUTER_OPERATOR)
1405       router_op = TRUE;
1406   }
1407
1408   if (server_op)
1409     SILC_UMODE_STATS_UPDATE(server, SILC_UMODE_SERVER_OPERATOR);
1410   if (router_op)
1411     SILC_UMODE_STATS_UPDATE(router, SILC_UMODE_ROUTER_OPERATOR);
1412
1413   return TRUE;
1414 }
1415
1416 /* This function is used to send the notify packets and motd to the
1417    incoming client connection. */
1418
1419 void silc_server_send_connect_notifys(SilcServer server,
1420                                       SilcPacketStream sock,
1421                                       SilcClientEntry client)
1422 {
1423   SilcCipher key;
1424
1425   SILC_LOG_DEBUG(("Send welcome notifys"));
1426
1427   /* Send some nice info to the client */
1428   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1429                           ("Welcome to the SILC Network %s",
1430                            client->username));
1431   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1432                           ("Your host is %s, running version %s",
1433                            server->server_name, server_version));
1434
1435   if (server->server_type == SILC_ROUTER) {
1436     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1437                             ("There are %d clients, %d servers and %d "
1438                              "routers in SILC Network",
1439                              server->stat.clients, server->stat.servers,
1440                              server->stat.routers));
1441   } else {
1442     if (server->stat.clients && server->stat.servers + 1)
1443       SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1444                               ("There are %d clients, %d servers and %d "
1445                                "routers in SILC Network",
1446                                server->stat.clients, server->stat.servers,
1447                                (server->standalone ? 0 :
1448                                 !server->stat.routers ? 1 :
1449                                 server->stat.routers)));
1450   }
1451
1452   if (server->stat.cell_clients && server->stat.cell_servers + 1)
1453     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1454                             ("There are %d clients on %d servers in our cell",
1455                              server->stat.cell_clients,
1456                              server->stat.cell_servers));
1457   if (server->server_type == SILC_ROUTER) {
1458     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1459                             ("I have %d clients, %d channels, %d servers and "
1460                              "%d routers",
1461                              server->stat.my_clients,
1462                              server->stat.my_channels,
1463                              server->stat.my_servers,
1464                              server->stat.my_routers));
1465   } else {
1466     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1467                             ("I have %d clients and %d channels formed",
1468                              server->stat.my_clients,
1469                              server->stat.my_channels));
1470   }
1471
1472   if (server->stat.server_ops || server->stat.router_ops)
1473     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1474                             ("There are %d server operators and %d router "
1475                              "operators online",
1476                              server->stat.server_ops,
1477                              server->stat.router_ops));
1478   if (server->stat.my_router_ops + server->stat.my_server_ops)
1479     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1480                             ("I have %d operators online",
1481                              server->stat.my_router_ops +
1482                              server->stat.my_server_ops));
1483
1484   silc_packet_get_keys(sock, &key, NULL, NULL, NULL);
1485   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1486                           ("Your connection is secured with %s cipher, "
1487                            "key length %d bits",
1488                            silc_cipher_get_name(key),
1489                            silc_cipher_get_key_len(key)));
1490   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1491                           ("Your current nickname is %s",
1492                            client->nickname));
1493
1494   /* Send motd */
1495   silc_server_send_motd(server, sock);
1496 }
1497
1498 /* Kill the client indicated by `remote_client' sending KILLED notify
1499    to the client, to all channels client has joined and to primary
1500    router if needed.  The killed client is also removed from all channels. */
1501
1502 void silc_server_kill_client(SilcServer server,
1503                              SilcClientEntry remote_client,
1504                              const char *comment,
1505                              void *killer_id,
1506                              SilcIdType killer_id_type)
1507 {
1508   SilcBuffer killed, killer;
1509
1510   SILC_LOG_DEBUG(("Killing client %s",
1511                   silc_id_render(remote_client->id, SILC_ID_CLIENT)));
1512
1513   /* Send the KILL notify packets. First send it to the channel, then
1514      to our primary router and then directly to the client who is being
1515      killed right now. */
1516
1517   killed = silc_id_payload_encode(remote_client->id, SILC_ID_CLIENT);
1518   killer = silc_id_payload_encode(killer_id, killer_id_type);
1519
1520   /* Send KILLED notify to the channels. It is not sent to the client
1521      as it will be sent differently destined directly to the client and not
1522      to the channel. */
1523   silc_server_send_notify_on_channels(server, remote_client,
1524                                       remote_client, SILC_NOTIFY_TYPE_KILLED,
1525                                       3, killed->data, silc_buffer_len(killed),
1526                                       comment, comment ? strlen(comment) : 0,
1527                                       killer->data, silc_buffer_len(killer));
1528
1529   /* Send KILLED notify to primary route */
1530   silc_server_send_notify_killed(server, SILC_PRIMARY_ROUTE(server),
1531                                  SILC_BROADCAST(server), remote_client->id,
1532                                  comment, killer_id, killer_id_type);
1533
1534   /* Send KILLED notify to the client directly */
1535   if (remote_client->connection || remote_client->router)
1536     silc_server_send_notify_killed(server, remote_client->connection ?
1537                                    remote_client->connection :
1538                                    remote_client->router->connection, FALSE,
1539                                    remote_client->id, comment,
1540                                    killer_id, killer_id_type);
1541
1542   /* Remove the client from all channels. This generates new keys to the
1543      channels as well. */
1544   silc_server_remove_from_channels(server, NULL, remote_client, FALSE,
1545                                    NULL, TRUE, TRUE);
1546
1547   /* Remove the client entry, If it is locally connected then we will also
1548      disconnect the client here */
1549   if (remote_client->connection) {
1550     /* Remove locally conneted client */
1551     SilcPacketStream sock = remote_client->connection;
1552
1553     if (sock)
1554       silc_packet_stream_ref(sock);
1555
1556     silc_server_free_sock_user_data(server, sock, NULL);
1557
1558     if (sock) {
1559       silc_packet_set_context(sock, NULL);
1560       silc_server_close_connection(server, sock);
1561       silc_packet_stream_unref(sock);
1562     }
1563   } else {
1564     /* Update statistics */
1565     SILC_VERIFY(server->stat.clients > 0);
1566     server->stat.clients--;
1567     if (server->stat.cell_clients)
1568       server->stat.cell_clients--;
1569     SILC_OPER_STATS_UPDATE(remote_client, server, SILC_UMODE_SERVER_OPERATOR);
1570     SILC_OPER_STATS_UPDATE(remote_client, router, SILC_UMODE_ROUTER_OPERATOR);
1571
1572     /* Remove client's public key from repository, this will free it too. */
1573     if (remote_client->data.public_key) {
1574       silc_skr_del_public_key(server->repository,
1575                               remote_client->data.public_key, remote_client);
1576       remote_client->data.public_key = NULL;
1577     }
1578
1579     if (SILC_IS_LOCAL(remote_client)) {
1580       if (!remote_client->local_detached)
1581         server->stat.my_clients--;
1582       silc_schedule_task_del_by_context(server->schedule, remote_client);
1583     }
1584
1585     /* Remove remote client */
1586     silc_dlist_del(server->expired_clients, remote_client);
1587     silc_idlist_del_data(remote_client);
1588     if (!silc_idlist_del_client(server->global_list, remote_client)) {
1589       /* Remove this client from watcher list if it is */
1590       silc_server_del_from_watcher_list(server, remote_client);
1591       silc_idlist_del_client(server->local_list, remote_client);
1592     }
1593   }
1594
1595   silc_buffer_free(killer);
1596   silc_buffer_free(killed);
1597 }
1598
1599 typedef struct {
1600   SilcServer server;
1601   SilcClientEntry client;
1602   SilcNotifyType notify;
1603   const char *new_nick;
1604 } WatcherNotifyContext;
1605
1606 static void
1607 silc_server_check_watcher_list_foreach(void *key, void *context,
1608                                        void *user_context)
1609 {
1610   WatcherNotifyContext *notify = user_context;
1611   SilcClientEntry entry = context;
1612   SilcPacketStream sock;
1613
1614   if (!context)
1615     return;
1616
1617   if (entry == notify->client)
1618     return;
1619
1620   sock = silc_server_get_client_route(notify->server, NULL, 0, entry->id,
1621                                       NULL, NULL);
1622   if (sock) {
1623     SILC_LOG_DEBUG(("Sending WATCH notify to %s",
1624                     silc_id_render(entry->id, SILC_ID_CLIENT)));
1625
1626     /* Send the WATCH notify */
1627     silc_server_send_notify_watch(notify->server, sock, entry,
1628                                   notify->client,
1629                                   notify->new_nick ? notify->new_nick :
1630                                   (const char *)notify->client->nickname,
1631                                   notify->notify,
1632                                   notify->client->data.public_key);
1633   }
1634 }
1635
1636 /* This function checks whether the `client' nickname and/or 'client'
1637    public key is being watched by someone, and notifies the watcher of the
1638    notify change of notify type indicated by `notify'. */
1639
1640 SilcBool silc_server_check_watcher_list(SilcServer server,
1641                                         SilcClientEntry client,
1642                                         const char *new_nick,
1643                                         SilcNotifyType notify)
1644 {
1645   unsigned char hash[16];
1646   WatcherNotifyContext n;
1647
1648   SILC_LOG_DEBUG(("Checking watcher list %s",
1649                   client->nickname ? client->nickname : (unsigned char *)""));
1650
1651   /* If the watching is rejected by the client do nothing */
1652   if (client->mode & SILC_UMODE_REJECT_WATCHING)
1653     return FALSE;
1654
1655   /* Make hash from the nick, or take it from Client ID */
1656   if (client->nickname) {
1657     unsigned char *nickc;
1658     nickc = silc_identifier_check(client->nickname, strlen(client->nickname),
1659                                   SILC_STRING_UTF8, 128, NULL);
1660     if (!nickc)
1661       return FALSE;
1662     silc_hash_make(server->md5hash, nickc, strlen(nickc), hash);
1663     silc_free(nickc);
1664   } else {
1665     memset(hash, 0, sizeof(hash));
1666     memcpy(hash, client->id->hash, sizeof(client->id->hash));
1667   }
1668
1669   n.server = server;
1670   n.client = client;
1671   n.new_nick = new_nick;
1672   n.notify = notify;
1673
1674   /* Send notify to all watchers watching this nickname */
1675   silc_hash_table_find_foreach(server->watcher_list, hash,
1676                                silc_server_check_watcher_list_foreach, &n);
1677
1678   /* Send notify to all watchers watching this public key */
1679   if (client->data.public_key)
1680     silc_hash_table_find_foreach(server->watcher_list_pk,
1681                                  client->data.public_key,
1682                                  silc_server_check_watcher_list_foreach,
1683                                  &n);
1684
1685   return TRUE;
1686 }
1687
1688 /* Remove the `client' from watcher list. After calling this the `client'
1689    is not watching any nicknames. */
1690
1691 SilcBool silc_server_del_from_watcher_list(SilcServer server,
1692                                            SilcClientEntry client)
1693 {
1694   SilcHashTableList htl;
1695   void *key;
1696   SilcClientEntry entry;
1697   SilcBool found = FALSE;
1698
1699   silc_hash_table_list(server->watcher_list, &htl);
1700   while (silc_hash_table_get(&htl, &key, (void *)&entry)) {
1701     if (entry == client) {
1702       silc_hash_table_del_by_context(server->watcher_list, key, client);
1703
1704       if (client->id)
1705         SILC_LOG_DEBUG(("Removing %s from WATCH list",
1706                         silc_id_render(client->id, SILC_ID_CLIENT)));
1707
1708       /* Now check whether there still exists entries with this key, if not
1709          then free the key to not leak memory. */
1710       if (!silc_hash_table_find(server->watcher_list, key, NULL, NULL))
1711         silc_free(key);
1712
1713       found = TRUE;
1714     }
1715   }
1716   silc_hash_table_list_reset(&htl);
1717
1718   silc_hash_table_list(server->watcher_list_pk, &htl);
1719   while (silc_hash_table_get(&htl, &key, (void *)&entry)) {
1720     if (entry == client) {
1721       silc_hash_table_del_by_context(server->watcher_list_pk, key, client);
1722
1723       if (client->id)
1724         SILC_LOG_DEBUG(("Removing %s from WATCH list",
1725                         silc_id_render(client->id, SILC_ID_CLIENT)));
1726
1727       /* Now check whether there still exists entries with this key, if not
1728          then free the key to not leak memory. */
1729       if (!silc_hash_table_find(server->watcher_list_pk, key, NULL, NULL))
1730         silc_pkcs_public_key_free(key);
1731
1732       found = TRUE;
1733     }
1734   }
1735   silc_hash_table_list_reset(&htl);
1736
1737   return found;
1738 }
1739
1740 /* Force the client indicated by `chl' to change the channel user mode
1741    on channel indicated by `channel' to `forced_mode'. */
1742
1743 SilcBool silc_server_force_cumode_change(SilcServer server,
1744                                          SilcPacketStream sock,
1745                                          SilcChannelEntry channel,
1746                                          SilcChannelClientEntry chl,
1747                                          SilcUInt32 forced_mode)
1748 {
1749   SilcBuffer idp1, idp2;
1750   unsigned char cumode[4];
1751
1752   SILC_LOG_DEBUG(("Enforcing sender to change mode"));
1753
1754   if (sock)
1755     silc_server_send_notify_cumode(server, sock, FALSE, channel, forced_mode,
1756                                    server->id, SILC_ID_SERVER,
1757                                    chl->client->id, NULL);
1758
1759   idp1 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
1760   idp2 = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
1761   SILC_PUT32_MSB(forced_mode, cumode);
1762   silc_server_send_notify_to_channel(server, sock, channel, FALSE, TRUE,
1763                                      SILC_NOTIFY_TYPE_CUMODE_CHANGE,
1764                                      3, idp1->data, silc_buffer_len(idp1),
1765                                      cumode, sizeof(cumode),
1766                                      idp2->data, silc_buffer_len(idp2));
1767   silc_buffer_free(idp1);
1768   silc_buffer_free(idp2);
1769
1770   return TRUE;
1771 }
1772
1773 /* This function can be used to match the invite and ban lists. */
1774
1775 SilcBool silc_server_inviteban_match(SilcServer server, SilcHashTable list,
1776                                      SilcUInt8 type, void *check)
1777 {
1778   unsigned char *tmp = NULL;
1779   SilcUInt32 len = 0;
1780   SilcHashTableList htl;
1781   SilcBuffer entry, idp = NULL, pkp = NULL;
1782   SilcBool ret = FALSE;
1783   void *t;
1784
1785   SILC_LOG_DEBUG(("Matching invite/ban"));
1786
1787   if (type < 1 || type > 3 || !check)
1788     return FALSE;
1789
1790   if (type == 1) {
1791     tmp = strdup((char *)check);
1792     if (!tmp)
1793       return FALSE;
1794   }
1795   if (type == 2) {
1796     pkp = silc_public_key_payload_encode(check);
1797     if (!pkp)
1798       return FALSE;
1799     tmp = pkp->data;
1800     len = silc_buffer_len(pkp);
1801   }
1802   if (type == 3) {
1803     idp = silc_id_payload_encode(check, SILC_ID_CLIENT);
1804     if (!idp)
1805       return FALSE;
1806     tmp = idp->data;
1807     len = silc_buffer_len(idp);
1808   }
1809
1810   /* Compare the list */
1811   silc_hash_table_list(list, &htl);
1812   while (silc_hash_table_get(&htl, (void *)&t, (void *)&entry)) {
1813     if (type == SILC_PTR_TO_32(t)) {
1814       if (type == 1) {
1815         if (silc_string_match(entry->data, tmp)) {
1816           ret = TRUE;
1817           break;
1818         }
1819       } else if (silc_buffer_len(entry) == len &&
1820                  !memcmp(entry->data, tmp, len)) {
1821         ret = TRUE;
1822         break;
1823       }
1824     }
1825   }
1826   silc_hash_table_list_reset(&htl);
1827
1828   if (type == 1)
1829     silc_free(tmp);
1830   silc_buffer_free(idp);
1831   silc_buffer_free(pkp);
1832   return ret;
1833 }
1834
1835 /* Process invite or ban information */
1836
1837 SilcBool silc_server_inviteban_process(SilcServer server,
1838                                        SilcHashTable list,
1839                                        SilcUInt8 action,
1840                                        SilcArgumentPayload args)
1841 {
1842   unsigned char *tmp;
1843   SilcUInt32 type, len;
1844   void *ptype;
1845   SilcBuffer tmp2;
1846   SilcHashTableList htl;
1847
1848   SILC_LOG_DEBUG(("Processing invite/ban for %s action",
1849                   action == 0x01 ? "DEL" : "ADD"));
1850
1851   /* Add the information to invite list */
1852   if (action == 0x00 || action == 0x03) {
1853     /* Traverse all arguments and add to the hash table according to
1854        their type. */
1855     tmp = silc_argument_get_first_arg(args, &type, &len);
1856     while (tmp) {
1857       if (type == 1) {
1858         /* Check validity of the string.  Actually we should parse the
1859            whole string and verify all components individually. */
1860         if (!silc_utf8_valid(tmp, len) || !len) {
1861           tmp = silc_argument_get_next_arg(args, &type, &len);
1862           continue;
1863         }
1864         if (strchr(tmp, ',')) {
1865           tmp = silc_argument_get_next_arg(args, &type, &len);
1866           continue;
1867         }
1868
1869         /* Check if the string is added already */
1870         silc_hash_table_list(list, &htl);
1871         while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) {
1872           if (SILC_PTR_TO_32(ptype) == 1 &&
1873               silc_string_match(tmp2->data, tmp)) {
1874             tmp = NULL;
1875             break;
1876           }
1877         }
1878         silc_hash_table_list_reset(&htl);
1879
1880         if (tmp) {
1881           /* Add the string to hash table */
1882           tmp2 = silc_buffer_alloc_size(len + 1);
1883           if (tmp[len - 1] == ',')
1884             tmp[len - 1] = '\0';
1885           silc_buffer_put(tmp2, tmp, len);
1886           silc_hash_table_add(list, (void *)1, tmp2);
1887         }
1888
1889       } else if (type == 2) {
1890         /* Public key.  Check first if the public key is already on the
1891            list and ignore it if it is, otherwise, add it to hash table. */
1892         SilcPublicKey pk;
1893
1894         /* Verify validity of the public key */
1895         if (!silc_public_key_payload_decode(tmp, len, &pk)) {
1896           tmp = silc_argument_get_next_arg(args, &type, &len);
1897           continue;
1898         }
1899         silc_pkcs_public_key_free(pk);
1900
1901         /* Check if the public key is in the list already */
1902         silc_hash_table_list(list, &htl);
1903         while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) {
1904           if (SILC_PTR_TO_32(ptype) == 2 && !memcmp(tmp2->data, tmp, len)) {
1905             tmp = NULL;
1906             break;
1907           }
1908         }
1909         silc_hash_table_list_reset(&htl);
1910
1911         /* Add new public key to invite list */
1912         if (tmp) {
1913           tmp2 = silc_buffer_alloc_size(len);
1914           silc_buffer_put(tmp2, tmp, len);
1915           silc_hash_table_add(list, (void *)2, tmp2);
1916         }
1917
1918       } else if (type == 3) {
1919         /* Client ID */
1920
1921         /* Check if the ID is in the list already */
1922         silc_hash_table_list(list, &htl);
1923         while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) {
1924           if (SILC_PTR_TO_32(ptype) == 3 && !memcmp(tmp2->data, tmp, len)) {
1925             tmp = NULL;
1926             break;
1927           }
1928         }
1929         silc_hash_table_list_reset(&htl);
1930
1931         /* Add new Client ID to invite list */
1932         if (tmp) {
1933           tmp2 = silc_buffer_alloc_size(len);
1934           silc_buffer_put(tmp2, tmp, len);
1935           silc_hash_table_add(list, (void *)3, tmp2);
1936         }
1937       }
1938
1939       tmp = silc_argument_get_next_arg(args, &type, &len);
1940     }
1941   }
1942
1943   /* Delete information to invite list */
1944   if (action == 0x01 && list) {
1945     /* Now delete the arguments from invite list */
1946     tmp = silc_argument_get_first_arg(args, &type, &len);
1947     while (tmp) {
1948       if (type == 1) {
1949         /* Check validity of the string.  Actually we should parse the
1950            whole string and verify all components individually. */
1951         if (!silc_utf8_valid(tmp, len)) {
1952           tmp = silc_argument_get_next_arg(args, &type, &len);
1953           continue;
1954         }
1955         if (strchr(tmp, ',')) {
1956           tmp = silc_argument_get_next_arg(args, &type, &len);
1957           continue;
1958         }
1959
1960         /* Delete from the list */
1961         silc_hash_table_list(list, &htl);
1962         while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) {
1963           if (SILC_PTR_TO_32(ptype) == 1 &&
1964               silc_string_match(tmp2->data, tmp)) {
1965             silc_hash_table_del_by_context(list, (void *)1, tmp2);
1966             break;
1967           }
1968         }
1969         silc_hash_table_list_reset(&htl);
1970
1971       } else if (type == 2) {
1972         /* Public key. */
1973         SilcPublicKey pk;
1974
1975         /* Verify validity of the public key */
1976         if (!silc_public_key_payload_decode(tmp, len, &pk)) {
1977           tmp = silc_argument_get_next_arg(args, &type, &len);
1978           continue;
1979         }
1980         silc_pkcs_public_key_free(pk);
1981
1982         /* Delete from the invite list */
1983         silc_hash_table_list(list, &htl);
1984         while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) {
1985           if (SILC_PTR_TO_32(ptype) == 2 && !memcmp(tmp2->data, tmp, len)) {
1986             silc_hash_table_del_by_context(list, (void *)2, tmp2);
1987             break;
1988           }
1989         }
1990         silc_hash_table_list_reset(&htl);
1991
1992       } else if (type == 3) {
1993         /* Client ID */
1994
1995         /* Delete from the invite list */
1996         silc_hash_table_list(list, &htl);
1997         while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) {
1998           if (SILC_PTR_TO_32(ptype) == 3 && !memcmp(tmp2->data, tmp, len)) {
1999             silc_hash_table_del_by_context(list, (void *)3, tmp2);
2000             break;
2001           }
2002         }
2003         silc_hash_table_list_reset(&htl);
2004       }
2005
2006       tmp = silc_argument_get_next_arg(args, &type, &len);
2007     }
2008   }
2009
2010   return TRUE;
2011 }
2012
2013 /* Destructor for invite and ban list entrys */
2014
2015 void silc_server_inviteban_destruct(void *key, void *context,
2016                                     void *user_context)
2017 {
2018   silc_buffer_free(context);
2019 }
2020
2021 /* Creates connections accoring to configuration. */
2022
2023 void silc_server_create_connections(SilcServer server)
2024 {
2025   silc_schedule_task_del_by_callback(server->schedule,
2026                                      silc_server_connect_to_router_retry);
2027   silc_schedule_task_del_by_callback(server->schedule,
2028                                      silc_server_connect_to_router);
2029   silc_schedule_task_add_timeout(server->schedule,
2030                                  silc_server_connect_to_router, server, 1, 0);
2031 }
2032
2033 static void
2034 silc_server_process_channel_pk_destruct(void *key, void *context,
2035                                         void *user_context)
2036 {
2037   silc_free(key);
2038   silc_pkcs_public_key_free(context);
2039 }
2040
2041 /* Processes a channel public key, either adds or removes it. */
2042
2043 SilcStatus
2044 silc_server_process_channel_pk(SilcServer server,
2045                                SilcChannelEntry channel,
2046                                SilcUInt32 type, const unsigned char *pk,
2047                                SilcUInt32 pk_len)
2048 {
2049   unsigned char pkhash[20];
2050   SilcPublicKey chpk;
2051
2052   SILC_LOG_DEBUG(("Processing channel public key"));
2053
2054   if (!pk || !pk_len)
2055     return SILC_STATUS_ERR_NOT_ENOUGH_PARAMS;
2056
2057   /* Decode the public key */
2058   if (!silc_public_key_payload_decode((unsigned char *)pk, pk_len, &chpk))
2059     return SILC_STATUS_ERR_UNSUPPORTED_PUBLIC_KEY;
2060
2061   /* Create channel public key list (hash table) if needed */
2062   if (!channel->channel_pubkeys) {
2063     channel->channel_pubkeys =
2064       silc_hash_table_alloc(0, silc_hash_data, (void *)20,
2065                             silc_hash_data_compare, (void *)20,
2066                             silc_server_process_channel_pk_destruct, channel,
2067                             TRUE);
2068   }
2069
2070   /* Create SHA-1 digest of the public key data */
2071   silc_hash_make(server->sha1hash, pk + 4, pk_len - 4, pkhash);
2072
2073   if (type == 0x00) {
2074     /* Add new public key to channel public key list */
2075     SILC_LOG_DEBUG(("Add new channel public key to channel %s",
2076                     channel->channel_name));
2077
2078     /* Check for resource limit */
2079     if (silc_hash_table_count(channel->channel_pubkeys) > 64) {
2080       silc_pkcs_public_key_free(chpk);
2081       return SILC_STATUS_ERR_RESOURCE_LIMIT;
2082     }
2083
2084     /* Add if doesn't exist already */
2085     if (!silc_hash_table_find(channel->channel_pubkeys, pkhash,
2086                               NULL, NULL))
2087       silc_hash_table_add(channel->channel_pubkeys, silc_memdup(pkhash, 20),
2088                           chpk);
2089   } else if (type == 0x01) {
2090     /* Delete public key from channel public key list */
2091     SILC_LOG_DEBUG(("Delete a channel public key from channel %s",
2092                     channel->channel_name));
2093     if (!silc_hash_table_del(channel->channel_pubkeys, pkhash))
2094       silc_pkcs_public_key_free(chpk);
2095   } else {
2096     silc_pkcs_public_key_free(chpk);
2097     return SILC_STATUS_ERR_NOT_ENOUGH_PARAMS;
2098   }
2099
2100   return SILC_STATUS_OK;
2101 }
2102
2103 /* Returns the channel public keys as Argument List payload. */
2104
2105 SilcBuffer silc_server_get_channel_pk_list(SilcServer server,
2106                                            SilcChannelEntry channel,
2107                                            SilcBool announce,
2108                                            SilcBool delete)
2109 {
2110   SilcHashTableList htl;
2111   SilcBuffer list, pkp;
2112   SilcPublicKey pk;
2113
2114   SILC_LOG_DEBUG(("Encoding channel public keys list"));
2115
2116   if (!channel->channel_pubkeys ||
2117       !silc_hash_table_count(channel->channel_pubkeys))
2118     return NULL;
2119
2120   /* Encode the list */
2121   list = silc_buffer_alloc_size(2);
2122   silc_buffer_format(list,
2123                      SILC_STR_UI_SHORT(silc_hash_table_count(
2124                                        channel->channel_pubkeys)),
2125                      SILC_STR_END);
2126
2127   silc_hash_table_list(channel->channel_pubkeys, &htl);
2128   while (silc_hash_table_get(&htl, NULL, (void *)&pk)) {
2129     pkp = silc_public_key_payload_encode(pk);
2130     if (!pkp)
2131       continue;
2132     list = silc_argument_payload_encode_one(list, pkp->data,
2133                                             silc_buffer_len(pkp),
2134                                             announce ? 0x03 :
2135                                             delete ? 0x01 : 0x00);
2136     silc_buffer_free(pkp);
2137   }
2138   silc_hash_table_list_reset(&htl);
2139
2140   return list;
2141 }
2142
2143 /* Sets the channel public keys into channel from the list of public keys. */
2144
2145 SilcStatus silc_server_set_channel_pk_list(SilcServer server,
2146                                            SilcPacketStream sender,
2147                                            SilcChannelEntry channel,
2148                                            const unsigned char *pklist,
2149                                            SilcUInt32 pklist_len)
2150 {
2151   SilcUInt16 argc;
2152   SilcArgumentPayload args;
2153   unsigned char *chpk;
2154   SilcUInt32 chpklen, type;
2155   SilcStatus ret = SILC_STATUS_OK;
2156
2157   SILC_LOG_DEBUG(("Setting channel public keys list"));
2158
2159   if (!pklist || pklist_len < 2)
2160     return SILC_STATUS_ERR_NOT_ENOUGH_PARAMS;
2161
2162   /* Get the argument from the Argument List Payload */
2163   SILC_GET16_MSB(argc, pklist);
2164   args = silc_argument_payload_parse(pklist + 2, pklist_len - 2, argc);
2165   if (!args)
2166     return SILC_STATUS_ERR_NOT_ENOUGH_PARAMS;
2167
2168   /* Process the public keys one by one */
2169   chpk = silc_argument_get_first_arg(args, &type, &chpklen);
2170
2171   /* If announcing keys and we have them set already, do not allow this */
2172   if (chpk && type == 0x03 && channel->channel_pubkeys &&
2173       server->server_type == SILC_ROUTER &&
2174       sender != SILC_PRIMARY_ROUTE(server)) {
2175     SILC_LOG_DEBUG(("Channel public key list set already, enforce our list"));
2176     silc_argument_payload_free(args);
2177     return SILC_STATUS_ERR_OPERATION_ALLOWED;
2178   }
2179
2180   /* If we are normal server and receive announcement list and we already
2181      have keys set, we replace the old list with the announced one. */
2182   if (chpk && type == 0x03 && channel->channel_pubkeys &&
2183       server->server_type != SILC_ROUTER) {
2184     SilcBuffer sidp;
2185     unsigned char mask[4], ulimit[4];
2186
2187     SILC_LOG_DEBUG(("Router enforces its list, remove old list"));
2188     silc_hash_table_free(channel->channel_pubkeys);
2189     channel->channel_pubkeys = NULL;
2190
2191     /* Send notify that removes the old list */
2192     sidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
2193     SILC_PUT32_MSB((channel->mode & (~SILC_CHANNEL_MODE_CHANNEL_AUTH)), mask);
2194     if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
2195       SILC_PUT32_MSB(channel->user_limit, ulimit);
2196     silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
2197                                        SILC_NOTIFY_TYPE_CMODE_CHANGE, 8,
2198                                        sidp->data, silc_buffer_len(sidp),
2199                                        mask, 4,
2200                                        channel->cipher,
2201                                        channel->cipher ?
2202                                        strlen(channel->cipher) : 0,
2203                                        channel->hmac_name,
2204                                        channel->hmac_name ?
2205                                        strlen(channel->hmac_name) : 0,
2206                                        channel->passphrase,
2207                                        channel->passphrase ?
2208                                        strlen(channel->passphrase) : 0,
2209                                        NULL, 0, NULL, 0,
2210                                        (channel->mode &
2211                                         SILC_CHANNEL_MODE_ULIMIT ?
2212                                         ulimit : NULL),
2213                                        (channel->mode &
2214                                         SILC_CHANNEL_MODE_ULIMIT ?
2215                                         sizeof(ulimit) : 0));
2216     silc_buffer_free(sidp);
2217   }
2218
2219   while (chpk) {
2220     if (type == 0x03)
2221       type = 0x00;
2222     ret = silc_server_process_channel_pk(server, channel, type,
2223                                          chpk, chpklen);
2224     if (ret != SILC_STATUS_OK)
2225       break;
2226     chpk = silc_argument_get_next_arg(args, &type, &chpklen);
2227   }
2228
2229   silc_argument_payload_free(args);
2230   return ret;
2231 }
2232
2233 /* Verifies the Authentication Payload `auth' with one of the public keys
2234    on the `channel' public key list. */
2235
2236 SilcBool silc_server_verify_channel_auth(SilcServer server,
2237                                          SilcChannelEntry channel,
2238                                          SilcClientID *client_id,
2239                                          const unsigned char *auth,
2240                                          SilcUInt32 auth_len)
2241 {
2242   SilcAuthPayload ap;
2243   SilcPublicKey chpk;
2244   unsigned char *pkhash;
2245   SilcUInt32 pkhash_len;
2246   SilcBool ret = FALSE;
2247
2248   SILC_LOG_DEBUG(("Verifying channel authentication"));
2249
2250   if (!auth || !auth_len || !channel->channel_pubkeys)
2251     return FALSE;
2252
2253   /* Get the hash from the auth data which tells us what public key we
2254      must use in verification. */
2255
2256   ap = silc_auth_payload_parse(auth, auth_len);
2257   if (!ap)
2258     return FALSE;
2259
2260   pkhash = silc_auth_get_public_data(ap, &pkhash_len);
2261   if (pkhash_len < 128)
2262     goto out;
2263
2264   /* Find the public key with the hash */
2265   if (!silc_hash_table_find(channel->channel_pubkeys, pkhash,
2266                             NULL, (void *)&chpk)) {
2267     SILC_LOG_DEBUG(("Public key not found in channel public key list"));
2268     goto out;
2269   }
2270
2271   /* Verify the signature */
2272   if (!silc_auth_verify(ap, SILC_AUTH_PUBLIC_KEY, (void *)chpk, 0,
2273                         server->sha1hash, client_id, SILC_ID_CLIENT)) {
2274     SILC_LOG_DEBUG(("Authentication failed"));
2275     goto out;
2276   }
2277
2278   ret = TRUE;
2279
2280  out:
2281   silc_auth_payload_free(ap);
2282   return ret;
2283 }