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