Merge branch 'master' of git://valera-ext.nynaeve.net/silc into silc.1.1.branch
[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       server->stat.my_clients--;
1581       silc_schedule_task_del_by_context(server->schedule, remote_client);
1582     }
1583
1584     /* Remove remote client */
1585     silc_dlist_del(server->expired_clients, remote_client);
1586     silc_idlist_del_data(remote_client);
1587     if (!silc_idlist_del_client(server->global_list, remote_client)) {
1588       /* Remove this client from watcher list if it is */
1589       silc_server_del_from_watcher_list(server, remote_client);
1590       silc_idlist_del_client(server->local_list, remote_client);
1591     }
1592   }
1593
1594   silc_buffer_free(killer);
1595   silc_buffer_free(killed);
1596 }
1597
1598 typedef struct {
1599   SilcServer server;
1600   SilcClientEntry client;
1601   SilcNotifyType notify;
1602   const char *new_nick;
1603 } WatcherNotifyContext;
1604
1605 static void
1606 silc_server_check_watcher_list_foreach(void *key, void *context,
1607                                        void *user_context)
1608 {
1609   WatcherNotifyContext *notify = user_context;
1610   SilcClientEntry entry = context;
1611   SilcPacketStream sock;
1612
1613   if (!context)
1614     return;
1615
1616   if (entry == notify->client)
1617     return;
1618
1619   sock = silc_server_get_client_route(notify->server, NULL, 0, entry->id,
1620                                       NULL, NULL);
1621   if (sock) {
1622     SILC_LOG_DEBUG(("Sending WATCH notify to %s",
1623                     silc_id_render(entry->id, SILC_ID_CLIENT)));
1624
1625     /* Send the WATCH notify */
1626     silc_server_send_notify_watch(notify->server, sock, entry,
1627                                   notify->client,
1628                                   notify->new_nick ? notify->new_nick :
1629                                   (const char *)notify->client->nickname,
1630                                   notify->notify,
1631                                   notify->client->data.public_key);
1632   }
1633 }
1634
1635 /* This function checks whether the `client' nickname and/or 'client'
1636    public key is being watched by someone, and notifies the watcher of the
1637    notify change of notify type indicated by `notify'. */
1638
1639 SilcBool silc_server_check_watcher_list(SilcServer server,
1640                                         SilcClientEntry client,
1641                                         const char *new_nick,
1642                                         SilcNotifyType notify)
1643 {
1644   unsigned char hash[16];
1645   WatcherNotifyContext n;
1646
1647   SILC_LOG_DEBUG(("Checking watcher list %s",
1648                   client->nickname ? client->nickname : (unsigned char *)""));
1649
1650   /* If the watching is rejected by the client do nothing */
1651   if (client->mode & SILC_UMODE_REJECT_WATCHING)
1652     return FALSE;
1653
1654   /* Make hash from the nick, or take it from Client ID */
1655   if (client->nickname) {
1656     unsigned char *nickc;
1657     nickc = silc_identifier_check(client->nickname, strlen(client->nickname),
1658                                   SILC_STRING_UTF8, 128, NULL);
1659     if (!nickc)
1660       return FALSE;
1661     silc_hash_make(server->md5hash, nickc, strlen(nickc), hash);
1662     silc_free(nickc);
1663   } else {
1664     memset(hash, 0, sizeof(hash));
1665     memcpy(hash, client->id->hash, sizeof(client->id->hash));
1666   }
1667
1668   n.server = server;
1669   n.client = client;
1670   n.new_nick = new_nick;
1671   n.notify = notify;
1672
1673   /* Send notify to all watchers watching this nickname */
1674   silc_hash_table_find_foreach(server->watcher_list, hash,
1675                                silc_server_check_watcher_list_foreach, &n);
1676
1677   /* Send notify to all watchers watching this public key */
1678   if (client->data.public_key)
1679     silc_hash_table_find_foreach(server->watcher_list_pk,
1680                                  client->data.public_key,
1681                                  silc_server_check_watcher_list_foreach,
1682                                  &n);
1683
1684   return TRUE;
1685 }
1686
1687 /* Remove the `client' from watcher list. After calling this the `client'
1688    is not watching any nicknames. */
1689
1690 SilcBool silc_server_del_from_watcher_list(SilcServer server,
1691                                            SilcClientEntry client)
1692 {
1693   SilcHashTableList htl;
1694   void *key;
1695   SilcClientEntry entry;
1696   SilcBool found = FALSE;
1697
1698   silc_hash_table_list(server->watcher_list, &htl);
1699   while (silc_hash_table_get(&htl, &key, (void *)&entry)) {
1700     if (entry == client) {
1701       silc_hash_table_del_by_context(server->watcher_list, key, client);
1702
1703       if (client->id)
1704         SILC_LOG_DEBUG(("Removing %s from WATCH list",
1705                         silc_id_render(client->id, SILC_ID_CLIENT)));
1706
1707       /* Now check whether there still exists entries with this key, if not
1708          then free the key to not leak memory. */
1709       if (!silc_hash_table_find(server->watcher_list, key, NULL, NULL))
1710         silc_free(key);
1711
1712       found = TRUE;
1713     }
1714   }
1715   silc_hash_table_list_reset(&htl);
1716
1717   silc_hash_table_list(server->watcher_list_pk, &htl);
1718   while (silc_hash_table_get(&htl, &key, (void *)&entry)) {
1719     if (entry == client) {
1720       silc_hash_table_del_by_context(server->watcher_list_pk, key, client);
1721
1722       if (client->id)
1723         SILC_LOG_DEBUG(("Removing %s from WATCH list",
1724                         silc_id_render(client->id, SILC_ID_CLIENT)));
1725
1726       /* Now check whether there still exists entries with this key, if not
1727          then free the key to not leak memory. */
1728       if (!silc_hash_table_find(server->watcher_list_pk, key, NULL, NULL))
1729         silc_pkcs_public_key_free(key);
1730
1731       found = TRUE;
1732     }
1733   }
1734   silc_hash_table_list_reset(&htl);
1735
1736   return found;
1737 }
1738
1739 /* Force the client indicated by `chl' to change the channel user mode
1740    on channel indicated by `channel' to `forced_mode'. */
1741
1742 SilcBool silc_server_force_cumode_change(SilcServer server,
1743                                          SilcPacketStream sock,
1744                                          SilcChannelEntry channel,
1745                                          SilcChannelClientEntry chl,
1746                                          SilcUInt32 forced_mode)
1747 {
1748   SilcBuffer idp1, idp2;
1749   unsigned char cumode[4];
1750
1751   SILC_LOG_DEBUG(("Enforcing sender to change mode"));
1752
1753   if (sock)
1754     silc_server_send_notify_cumode(server, sock, FALSE, channel, forced_mode,
1755                                    server->id, SILC_ID_SERVER,
1756                                    chl->client->id, NULL);
1757
1758   idp1 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
1759   idp2 = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
1760   SILC_PUT32_MSB(forced_mode, cumode);
1761   silc_server_send_notify_to_channel(server, sock, channel, FALSE, TRUE,
1762                                      SILC_NOTIFY_TYPE_CUMODE_CHANGE,
1763                                      3, idp1->data, silc_buffer_len(idp1),
1764                                      cumode, sizeof(cumode),
1765                                      idp2->data, silc_buffer_len(idp2));
1766   silc_buffer_free(idp1);
1767   silc_buffer_free(idp2);
1768
1769   return TRUE;
1770 }
1771
1772 /* This function can be used to match the invite and ban lists. */
1773
1774 SilcBool silc_server_inviteban_match(SilcServer server, SilcHashTable list,
1775                                      SilcUInt8 type, void *check)
1776 {
1777   unsigned char *tmp = NULL;
1778   SilcUInt32 len = 0;
1779   SilcHashTableList htl;
1780   SilcBuffer entry, idp = NULL, pkp = NULL;
1781   SilcBool ret = FALSE;
1782   void *t;
1783
1784   SILC_LOG_DEBUG(("Matching invite/ban"));
1785
1786   if (type < 1 || type > 3 || !check)
1787     return FALSE;
1788
1789   if (type == 1) {
1790     tmp = strdup((char *)check);
1791     if (!tmp)
1792       return FALSE;
1793   }
1794   if (type == 2) {
1795     pkp = silc_public_key_payload_encode(check);
1796     if (!pkp)
1797       return FALSE;
1798     tmp = pkp->data;
1799     len = silc_buffer_len(pkp);
1800   }
1801   if (type == 3) {
1802     idp = silc_id_payload_encode(check, SILC_ID_CLIENT);
1803     if (!idp)
1804       return FALSE;
1805     tmp = idp->data;
1806     len = silc_buffer_len(idp);
1807   }
1808
1809   /* Compare the list */
1810   silc_hash_table_list(list, &htl);
1811   while (silc_hash_table_get(&htl, (void *)&t, (void *)&entry)) {
1812     if (type == SILC_PTR_TO_32(t)) {
1813       if (type == 1) {
1814         if (silc_string_match(entry->data, tmp)) {
1815           ret = TRUE;
1816           break;
1817         }
1818       } else if (silc_buffer_len(entry) == len &&
1819                  !memcmp(entry->data, tmp, len)) {
1820         ret = TRUE;
1821         break;
1822       }
1823     }
1824   }
1825   silc_hash_table_list_reset(&htl);
1826
1827   if (type == 1)
1828     silc_free(tmp);
1829   silc_buffer_free(idp);
1830   silc_buffer_free(pkp);
1831   return ret;
1832 }
1833
1834 /* Process invite or ban information */
1835
1836 SilcBool silc_server_inviteban_process(SilcServer server,
1837                                        SilcHashTable list,
1838                                        SilcUInt8 action,
1839                                        SilcArgumentPayload args)
1840 {
1841   unsigned char *tmp;
1842   SilcUInt32 type, len;
1843   void *ptype;
1844   SilcBuffer tmp2;
1845   SilcHashTableList htl;
1846
1847   SILC_LOG_DEBUG(("Processing invite/ban for %s action",
1848                   action == 0x01 ? "DEL" : "ADD"));
1849
1850   /* Add the information to invite list */
1851   if (action == 0x00 || action == 0x03) {
1852     /* Traverse all arguments and add to the hash table according to
1853        their type. */
1854     tmp = silc_argument_get_first_arg(args, &type, &len);
1855     while (tmp) {
1856       if (type == 1) {
1857         /* Check validity of the string.  Actually we should parse the
1858            whole string and verify all components individually. */
1859         if (!silc_utf8_valid(tmp, len) || !len) {
1860           tmp = silc_argument_get_next_arg(args, &type, &len);
1861           continue;
1862         }
1863         if (strchr(tmp, ',')) {
1864           tmp = silc_argument_get_next_arg(args, &type, &len);
1865           continue;
1866         }
1867
1868         /* Check if the string is added already */
1869         silc_hash_table_list(list, &htl);
1870         while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) {
1871           if (SILC_PTR_TO_32(ptype) == 1 &&
1872               silc_string_match(tmp2->data, tmp)) {
1873             tmp = NULL;
1874             break;
1875           }
1876         }
1877         silc_hash_table_list_reset(&htl);
1878
1879         if (tmp) {
1880           /* Add the string to hash table */
1881           tmp2 = silc_buffer_alloc_size(len + 1);
1882           if (tmp[len - 1] == ',')
1883             tmp[len - 1] = '\0';
1884           silc_buffer_put(tmp2, tmp, len);
1885           silc_hash_table_add(list, (void *)1, tmp2);
1886         }
1887
1888       } else if (type == 2) {
1889         /* Public key.  Check first if the public key is already on the
1890            list and ignore it if it is, otherwise, add it to hash table. */
1891         SilcPublicKey pk;
1892
1893         /* Verify validity of the public key */
1894         if (!silc_public_key_payload_decode(tmp, len, &pk)) {
1895           tmp = silc_argument_get_next_arg(args, &type, &len);
1896           continue;
1897         }
1898         silc_pkcs_public_key_free(pk);
1899
1900         /* Check if the public key is in the list already */
1901         silc_hash_table_list(list, &htl);
1902         while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) {
1903           if (SILC_PTR_TO_32(ptype) == 2 && !memcmp(tmp2->data, tmp, len)) {
1904             tmp = NULL;
1905             break;
1906           }
1907         }
1908         silc_hash_table_list_reset(&htl);
1909
1910         /* Add new public key to invite list */
1911         if (tmp) {
1912           tmp2 = silc_buffer_alloc_size(len);
1913           silc_buffer_put(tmp2, tmp, len);
1914           silc_hash_table_add(list, (void *)2, tmp2);
1915         }
1916
1917       } else if (type == 3) {
1918         /* Client ID */
1919
1920         /* Check if the ID is in the list already */
1921         silc_hash_table_list(list, &htl);
1922         while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) {
1923           if (SILC_PTR_TO_32(ptype) == 3 && !memcmp(tmp2->data, tmp, len)) {
1924             tmp = NULL;
1925             break;
1926           }
1927         }
1928         silc_hash_table_list_reset(&htl);
1929
1930         /* Add new Client ID to invite list */
1931         if (tmp) {
1932           tmp2 = silc_buffer_alloc_size(len);
1933           silc_buffer_put(tmp2, tmp, len);
1934           silc_hash_table_add(list, (void *)3, tmp2);
1935         }
1936       }
1937
1938       tmp = silc_argument_get_next_arg(args, &type, &len);
1939     }
1940   }
1941
1942   /* Delete information to invite list */
1943   if (action == 0x01 && list) {
1944     /* Now delete the arguments from invite list */
1945     tmp = silc_argument_get_first_arg(args, &type, &len);
1946     while (tmp) {
1947       if (type == 1) {
1948         /* Check validity of the string.  Actually we should parse the
1949            whole string and verify all components individually. */
1950         if (!silc_utf8_valid(tmp, len)) {
1951           tmp = silc_argument_get_next_arg(args, &type, &len);
1952           continue;
1953         }
1954         if (strchr(tmp, ',')) {
1955           tmp = silc_argument_get_next_arg(args, &type, &len);
1956           continue;
1957         }
1958
1959         /* Delete from the list */
1960         silc_hash_table_list(list, &htl);
1961         while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) {
1962           if (SILC_PTR_TO_32(ptype) == 1 &&
1963               silc_string_match(tmp2->data, tmp)) {
1964             silc_hash_table_del_by_context(list, (void *)1, tmp2);
1965             break;
1966           }
1967         }
1968         silc_hash_table_list_reset(&htl);
1969
1970       } else if (type == 2) {
1971         /* Public key. */
1972         SilcPublicKey pk;
1973
1974         /* Verify validity of the public key */
1975         if (!silc_public_key_payload_decode(tmp, len, &pk)) {
1976           tmp = silc_argument_get_next_arg(args, &type, &len);
1977           continue;
1978         }
1979         silc_pkcs_public_key_free(pk);
1980
1981         /* Delete from the invite list */
1982         silc_hash_table_list(list, &htl);
1983         while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) {
1984           if (SILC_PTR_TO_32(ptype) == 2 && !memcmp(tmp2->data, tmp, len)) {
1985             silc_hash_table_del_by_context(list, (void *)2, tmp2);
1986             break;
1987           }
1988         }
1989         silc_hash_table_list_reset(&htl);
1990
1991       } else if (type == 3) {
1992         /* Client ID */
1993
1994         /* Delete from the invite list */
1995         silc_hash_table_list(list, &htl);
1996         while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) {
1997           if (SILC_PTR_TO_32(ptype) == 3 && !memcmp(tmp2->data, tmp, len)) {
1998             silc_hash_table_del_by_context(list, (void *)3, tmp2);
1999             break;
2000           }
2001         }
2002         silc_hash_table_list_reset(&htl);
2003       }
2004
2005       tmp = silc_argument_get_next_arg(args, &type, &len);
2006     }
2007   }
2008
2009   return TRUE;
2010 }
2011
2012 /* Destructor for invite and ban list entrys */
2013
2014 void silc_server_inviteban_destruct(void *key, void *context,
2015                                     void *user_context)
2016 {
2017   silc_buffer_free(context);
2018 }
2019
2020 /* Creates connections accoring to configuration. */
2021
2022 void silc_server_create_connections(SilcServer server)
2023 {
2024   silc_schedule_task_del_by_callback(server->schedule,
2025                                      silc_server_connect_to_router_retry);
2026   silc_schedule_task_del_by_callback(server->schedule,
2027                                      silc_server_connect_to_router);
2028   silc_schedule_task_add_timeout(server->schedule,
2029                                  silc_server_connect_to_router, server, 1, 0);
2030 }
2031
2032 static void
2033 silc_server_process_channel_pk_destruct(void *key, void *context,
2034                                         void *user_context)
2035 {
2036   silc_free(key);
2037   silc_pkcs_public_key_free(context);
2038 }
2039
2040 /* Processes a channel public key, either adds or removes it. */
2041
2042 SilcStatus
2043 silc_server_process_channel_pk(SilcServer server,
2044                                SilcChannelEntry channel,
2045                                SilcUInt32 type, const unsigned char *pk,
2046                                SilcUInt32 pk_len)
2047 {
2048   unsigned char pkhash[20];
2049   SilcPublicKey chpk;
2050
2051   SILC_LOG_DEBUG(("Processing channel public key"));
2052
2053   if (!pk || !pk_len)
2054     return SILC_STATUS_ERR_NOT_ENOUGH_PARAMS;
2055
2056   /* Decode the public key */
2057   if (!silc_public_key_payload_decode((unsigned char *)pk, pk_len, &chpk))
2058     return SILC_STATUS_ERR_UNSUPPORTED_PUBLIC_KEY;
2059
2060   /* Create channel public key list (hash table) if needed */
2061   if (!channel->channel_pubkeys) {
2062     channel->channel_pubkeys =
2063       silc_hash_table_alloc(0, silc_hash_data, (void *)20,
2064                             silc_hash_data_compare, (void *)20,
2065                             silc_server_process_channel_pk_destruct, channel,
2066                             TRUE);
2067   }
2068
2069   /* Create SHA-1 digest of the public key data */
2070   silc_hash_make(server->sha1hash, pk + 4, pk_len - 4, pkhash);
2071
2072   if (type == 0x00) {
2073     /* Add new public key to channel public key list */
2074     SILC_LOG_DEBUG(("Add new channel public key to channel %s",
2075                     channel->channel_name));
2076
2077     /* Check for resource limit */
2078     if (silc_hash_table_count(channel->channel_pubkeys) > 64) {
2079       silc_pkcs_public_key_free(chpk);
2080       return SILC_STATUS_ERR_RESOURCE_LIMIT;
2081     }
2082
2083     /* Add if doesn't exist already */
2084     if (!silc_hash_table_find(channel->channel_pubkeys, pkhash,
2085                               NULL, NULL))
2086       silc_hash_table_add(channel->channel_pubkeys, silc_memdup(pkhash, 20),
2087                           chpk);
2088   } else if (type == 0x01) {
2089     /* Delete public key from channel public key list */
2090     SILC_LOG_DEBUG(("Delete a channel public key from channel %s",
2091                     channel->channel_name));
2092     if (!silc_hash_table_del(channel->channel_pubkeys, pkhash))
2093       silc_pkcs_public_key_free(chpk);
2094   } else {
2095     silc_pkcs_public_key_free(chpk);
2096     return SILC_STATUS_ERR_NOT_ENOUGH_PARAMS;
2097   }
2098
2099   return SILC_STATUS_OK;
2100 }
2101
2102 /* Returns the channel public keys as Argument List payload. */
2103
2104 SilcBuffer silc_server_get_channel_pk_list(SilcServer server,
2105                                            SilcChannelEntry channel,
2106                                            SilcBool announce,
2107                                            SilcBool delete)
2108 {
2109   SilcHashTableList htl;
2110   SilcBuffer list, pkp;
2111   SilcPublicKey pk;
2112
2113   SILC_LOG_DEBUG(("Encoding channel public keys list"));
2114
2115   if (!channel->channel_pubkeys ||
2116       !silc_hash_table_count(channel->channel_pubkeys))
2117     return NULL;
2118
2119   /* Encode the list */
2120   list = silc_buffer_alloc_size(2);
2121   silc_buffer_format(list,
2122                      SILC_STR_UI_SHORT(silc_hash_table_count(
2123                                        channel->channel_pubkeys)),
2124                      SILC_STR_END);
2125
2126   silc_hash_table_list(channel->channel_pubkeys, &htl);
2127   while (silc_hash_table_get(&htl, NULL, (void *)&pk)) {
2128     pkp = silc_public_key_payload_encode(pk);
2129     if (!pkp)
2130       continue;
2131     list = silc_argument_payload_encode_one(list, pkp->data,
2132                                             silc_buffer_len(pkp),
2133                                             announce ? 0x03 :
2134                                             delete ? 0x01 : 0x00);
2135     silc_buffer_free(pkp);
2136   }
2137   silc_hash_table_list_reset(&htl);
2138
2139   return list;
2140 }
2141
2142 /* Sets the channel public keys into channel from the list of public keys. */
2143
2144 SilcStatus silc_server_set_channel_pk_list(SilcServer server,
2145                                            SilcPacketStream sender,
2146                                            SilcChannelEntry channel,
2147                                            const unsigned char *pklist,
2148                                            SilcUInt32 pklist_len)
2149 {
2150   SilcUInt16 argc;
2151   SilcArgumentPayload args;
2152   unsigned char *chpk;
2153   SilcUInt32 chpklen, type;
2154   SilcStatus ret = SILC_STATUS_OK;
2155
2156   SILC_LOG_DEBUG(("Setting channel public keys list"));
2157
2158   if (!pklist || pklist_len < 2)
2159     return SILC_STATUS_ERR_NOT_ENOUGH_PARAMS;
2160
2161   /* Get the argument from the Argument List Payload */
2162   SILC_GET16_MSB(argc, pklist);
2163   args = silc_argument_payload_parse(pklist + 2, pklist_len - 2, argc);
2164   if (!args)
2165     return SILC_STATUS_ERR_NOT_ENOUGH_PARAMS;
2166
2167   /* Process the public keys one by one */
2168   chpk = silc_argument_get_first_arg(args, &type, &chpklen);
2169
2170   /* If announcing keys and we have them set already, do not allow this */
2171   if (chpk && type == 0x03 && channel->channel_pubkeys &&
2172       server->server_type == SILC_ROUTER &&
2173       sender != SILC_PRIMARY_ROUTE(server)) {
2174     SILC_LOG_DEBUG(("Channel public key list set already, enforce our list"));
2175     silc_argument_payload_free(args);
2176     return SILC_STATUS_ERR_OPERATION_ALLOWED;
2177   }
2178
2179   /* If we are normal server and receive announcement list and we already
2180      have keys set, we replace the old list with the announced one. */
2181   if (chpk && type == 0x03 && channel->channel_pubkeys &&
2182       server->server_type != SILC_ROUTER) {
2183     SilcBuffer sidp;
2184     unsigned char mask[4], ulimit[4];
2185
2186     SILC_LOG_DEBUG(("Router enforces its list, remove old list"));
2187     silc_hash_table_free(channel->channel_pubkeys);
2188     channel->channel_pubkeys = NULL;
2189
2190     /* Send notify that removes the old list */
2191     sidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
2192     SILC_PUT32_MSB((channel->mode & (~SILC_CHANNEL_MODE_CHANNEL_AUTH)), mask);
2193     if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
2194       SILC_PUT32_MSB(channel->user_limit, ulimit);
2195     silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
2196                                        SILC_NOTIFY_TYPE_CMODE_CHANGE, 8,
2197                                        sidp->data, silc_buffer_len(sidp),
2198                                        mask, 4,
2199                                        channel->cipher,
2200                                        channel->cipher ?
2201                                        strlen(channel->cipher) : 0,
2202                                        channel->hmac_name,
2203                                        channel->hmac_name ?
2204                                        strlen(channel->hmac_name) : 0,
2205                                        channel->passphrase,
2206                                        channel->passphrase ?
2207                                        strlen(channel->passphrase) : 0,
2208                                        NULL, 0, NULL, 0,
2209                                        (channel->mode &
2210                                         SILC_CHANNEL_MODE_ULIMIT ?
2211                                         ulimit : NULL),
2212                                        (channel->mode &
2213                                         SILC_CHANNEL_MODE_ULIMIT ?
2214                                         sizeof(ulimit) : 0));
2215     silc_buffer_free(sidp);
2216   }
2217
2218   while (chpk) {
2219     if (type == 0x03)
2220       type = 0x00;
2221     ret = silc_server_process_channel_pk(server, channel, type,
2222                                          chpk, chpklen);
2223     if (ret != SILC_STATUS_OK)
2224       break;
2225     chpk = silc_argument_get_next_arg(args, &type, &chpklen);
2226   }
2227
2228   silc_argument_payload_free(args);
2229   return ret;
2230 }
2231
2232 /* Verifies the Authentication Payload `auth' with one of the public keys
2233    on the `channel' public key list. */
2234
2235 SilcBool silc_server_verify_channel_auth(SilcServer server,
2236                                          SilcChannelEntry channel,
2237                                          SilcClientID *client_id,
2238                                          const unsigned char *auth,
2239                                          SilcUInt32 auth_len)
2240 {
2241   SilcAuthPayload ap;
2242   SilcPublicKey chpk;
2243   unsigned char *pkhash;
2244   SilcUInt32 pkhash_len;
2245   SilcBool ret = FALSE;
2246
2247   SILC_LOG_DEBUG(("Verifying channel authentication"));
2248
2249   if (!auth || !auth_len || !channel->channel_pubkeys)
2250     return FALSE;
2251
2252   /* Get the hash from the auth data which tells us what public key we
2253      must use in verification. */
2254
2255   ap = silc_auth_payload_parse(auth, auth_len);
2256   if (!ap)
2257     return FALSE;
2258
2259   pkhash = silc_auth_get_public_data(ap, &pkhash_len);
2260   if (pkhash_len < 128)
2261     goto out;
2262
2263   /* Find the public key with the hash */
2264   if (!silc_hash_table_find(channel->channel_pubkeys, pkhash,
2265                             NULL, (void *)&chpk)) {
2266     SILC_LOG_DEBUG(("Public key not found in channel public key list"));
2267     goto out;
2268   }
2269
2270   /* Verify the signature */
2271   if (!silc_auth_verify(ap, SILC_AUTH_PUBLIC_KEY, (void *)chpk, 0,
2272                         server->sha1hash, client_id, SILC_ID_CLIENT)) {
2273     SILC_LOG_DEBUG(("Authentication failed"));
2274     goto out;
2275   }
2276
2277   ret = TRUE;
2278
2279  out:
2280   silc_auth_payload_free(ap);
2281   return ret;
2282 }