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