Added support for the identifier strings and their validity
[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     silc_hash_make(server->md5hash, client->nickname,
1732                    strlen(client->nickname), hash);
1733   } else {
1734     memset(hash, 0, sizeof(hash));
1735     memcpy(hash, client->id->hash, sizeof(client->id->hash));
1736   }
1737
1738   n.server = server;
1739   n.client = client;
1740   n.new_nick = new_nick;
1741   n.notify = notify;
1742
1743   /* Send notify to all watchers watching this nickname */
1744   silc_hash_table_find_foreach(server->watcher_list, hash,
1745                                silc_server_check_watcher_list_foreach, &n);
1746
1747   /* Send notify to all watchers watching this public key */
1748   if (client->data.public_key)
1749     silc_hash_table_find_foreach(server->watcher_list_pk,
1750                                  client->data.public_key,
1751                                  silc_server_check_watcher_list_foreach,
1752                                  &n);
1753
1754   return TRUE;
1755 }
1756
1757 /* Remove the `client' from watcher list. After calling this the `client'
1758    is not watching any nicknames. */
1759
1760 bool silc_server_del_from_watcher_list(SilcServer server,
1761                                        SilcClientEntry client)
1762 {
1763   SilcHashTableList htl;
1764   void *key;
1765   SilcClientEntry entry;
1766   bool found = FALSE;
1767
1768   silc_hash_table_list(server->watcher_list, &htl);
1769   while (silc_hash_table_get(&htl, &key, (void *)&entry)) {
1770     if (entry == client) {
1771       silc_hash_table_del_by_context(server->watcher_list, key, client);
1772
1773       if (client->id)
1774         SILC_LOG_DEBUG(("Removing %s from WATCH list",
1775                         silc_id_render(client->id, SILC_ID_CLIENT)));
1776
1777       /* Now check whether there still exists entries with this key, if not
1778          then free the key to not leak memory. */
1779       if (!silc_hash_table_find(server->watcher_list, key, NULL, NULL))
1780         silc_free(key);
1781
1782       found = TRUE;
1783     }
1784   }
1785   silc_hash_table_list_reset(&htl);
1786
1787   silc_hash_table_list(server->watcher_list_pk, &htl);
1788   while (silc_hash_table_get(&htl, &key, (void *)&entry)) {
1789     if (entry == client) {
1790       silc_hash_table_del_by_context(server->watcher_list_pk, key, client);
1791
1792       if (client->id)
1793         SILC_LOG_DEBUG(("Removing %s from WATCH list",
1794                         silc_id_render(client->id, SILC_ID_CLIENT)));
1795
1796       /* Now check whether there still exists entries with this key, if not
1797          then free the key to not leak memory. */
1798       if (!silc_hash_table_find(server->watcher_list_pk, key, NULL, NULL))
1799         silc_pkcs_public_key_free(key);
1800
1801       found = TRUE;
1802     }
1803   }
1804   silc_hash_table_list_reset(&htl);
1805
1806   return found;
1807 }
1808
1809 /* Force the client indicated by `chl' to change the channel user mode
1810    on channel indicated by `channel' to `forced_mode'. */
1811
1812 bool silc_server_force_cumode_change(SilcServer server,
1813                                      SilcSocketConnection sock,
1814                                      SilcChannelEntry channel,
1815                                      SilcChannelClientEntry chl,
1816                                      SilcUInt32 forced_mode)
1817 {
1818   SilcBuffer idp1, idp2;
1819   unsigned char cumode[4];
1820
1821   SILC_LOG_DEBUG(("Enforcing sender to change mode"));
1822
1823   if (sock)
1824     silc_server_send_notify_cumode(server, sock, FALSE, channel, forced_mode,
1825                                    server->id, SILC_ID_SERVER,
1826                                    chl->client->id, NULL);
1827
1828   idp1 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
1829   idp2 = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
1830   SILC_PUT32_MSB(forced_mode, cumode);
1831   silc_server_send_notify_to_channel(server, sock, channel, FALSE, TRUE,
1832                                      SILC_NOTIFY_TYPE_CUMODE_CHANGE,
1833                                      3, idp1->data, idp1->len,
1834                                      cumode, sizeof(cumode),
1835                                      idp2->data, idp2->len);
1836   silc_buffer_free(idp1);
1837   silc_buffer_free(idp2);
1838
1839   return TRUE;
1840 }
1841
1842 /* Find active socket connection by the IP address and port indicated by
1843    `ip' and `port', and socket connection type of `type'. */
1844
1845 SilcSocketConnection
1846 silc_server_find_socket_by_host(SilcServer server,
1847                                 SilcSocketType type,
1848                                 const char *ip, SilcUInt16 port)
1849 {
1850   int i;
1851
1852   for (i = 0; i < server->config->param.connections_max; i++) {
1853     if (!server->sockets[i])
1854       continue;
1855     if (!strcmp(server->sockets[i]->ip, ip) &&
1856         (!port || server->sockets[i]->port == port) &&
1857         server->sockets[i]->type == type)
1858       return server->sockets[i];
1859   }
1860
1861   return NULL;
1862 }
1863
1864 /* This function can be used to match the invite and ban lists. */
1865
1866 bool silc_server_inviteban_match(SilcServer server, SilcHashTable list,
1867                                  SilcUInt8 type, void *check)
1868 {
1869   unsigned char *tmp = NULL;
1870   SilcUInt32 len = 0, t;
1871   SilcHashTableList htl;
1872   SilcBuffer entry, idp = NULL, pkp = NULL;
1873   bool ret = FALSE;
1874
1875   if (type < 1 || type > 3 || !check)
1876     return FALSE;
1877
1878   if (type == 1) {
1879     tmp = strdup((char *)check);
1880     if (!tmp)
1881       return FALSE;
1882   }
1883   if (type == 2) {
1884     pkp = silc_pkcs_public_key_payload_encode(check);
1885     if (!pkp)
1886       return FALSE;
1887     tmp = pkp->data;
1888     len = pkp->len;
1889   }
1890   if (type == 3) {
1891     idp = silc_id_payload_encode(check, SILC_ID_CLIENT);
1892     if (!idp)
1893       return FALSE;
1894     tmp = idp->data;
1895     len = idp->len;
1896   }
1897
1898   /* Compare the list */
1899   silc_hash_table_list(list, &htl);
1900   while (silc_hash_table_get(&htl, (void *)&t, (void *)&entry)) {
1901     if (type == t) {
1902       if (type == 1) {
1903         if (silc_string_match(entry->data, tmp)) {
1904           ret = TRUE;
1905           break;
1906         }
1907       } else if (!memcmp(entry->data, tmp, len)) {
1908         ret = TRUE;
1909         break;
1910       }
1911     }
1912   }
1913   silc_hash_table_list_reset(&htl);
1914
1915   if (type == 1)
1916     silc_free(tmp);
1917   silc_buffer_free(idp);
1918   silc_buffer_free(pkp);
1919   return ret;
1920 }
1921
1922 /* Process invite or ban information */
1923
1924 void silc_server_inviteban_process(SilcServer server, SilcHashTable list,
1925                                    SilcUInt8 action, SilcArgumentPayload args)
1926 {
1927   unsigned char *tmp;
1928   SilcUInt32 type, len;
1929   SilcBuffer tmp2;
1930   SilcHashTableList htl;
1931
1932   SILC_LOG_DEBUG(("Processing invite/ban for %s action",
1933                   action == 0x01 ? "DEL" : "ADD"));
1934
1935   /* Add the information to invite list */
1936   if (action == 0x00 || action == 0x03) {
1937     /* Traverse all arguments and add to the hash table according to
1938        their type. */
1939     tmp = silc_argument_get_first_arg(args, &type, &len);
1940     while (tmp) {
1941       if (type == 1) {
1942         /* Invite string.  Get the old invite string from hash table
1943            and append this at the end of the existing one. */
1944         if (!silc_hash_table_find(list, (void *)1, NULL, (void *)&tmp2)) {
1945           tmp2 = silc_calloc(1, sizeof(*tmp2));
1946           silc_hash_table_add(list, (void *)1, tmp2);
1947         }
1948
1949         /* Check that the string is not part of invite string already */
1950         if (action == 0x00) {
1951           if (silc_string_match(tmp2->data, tmp))
1952             break;
1953
1954           if (len) {
1955             if (tmp[len - 1] == ',')
1956               tmp[len - 1] = '\0';
1957             silc_buffer_strformat(tmp2, tmp, SILC_STRFMT_END);
1958             silc_buffer_strformat(tmp2, ",", SILC_STRFMT_END);
1959           }
1960         } else {
1961           /* Announced list.  Check each entry in the list */
1962           unsigned char e[256];
1963           char *start, *end, *n, *rtmp;
1964           int i, k;
1965
1966           rtmp = silc_memdup(tmp, len);
1967           for (i = 0, k = 0; i < len; i++) {
1968             if (tmp[i] != ',')
1969               continue;
1970
1971             memset(e, 0, sizeof(e));
1972             silc_strncat(e, sizeof(e), tmp + k, i - k);
1973             if (!silc_string_match(tmp2->data, e)) {
1974               k = i + 1;
1975               continue;
1976             }
1977
1978             /* Matches.  Delete it since we have it already */
1979             start = strstr(rtmp, e);
1980             if (start && strlen(start) >= (i - k)) {
1981               end = start + (i - k);
1982               n = silc_calloc(strlen(rtmp) - (i - k), sizeof(*n));
1983               strncat(n, rtmp, start - rtmp);
1984               if (strlen(end) > 1)
1985                 strncat(n, end + 1, ((rtmp + strlen(rtmp)) - end) - 1);
1986               silc_free(rtmp);
1987               rtmp = n;
1988             }
1989
1990             k = i + 1;
1991           }
1992
1993           /* Save the part that we didn't already have. */
1994           if (strlen(rtmp) > 1) {
1995             silc_buffer_strformat(tmp2, rtmp, SILC_STRFMT_END);
1996             silc_buffer_strformat(tmp2, ",", SILC_STRFMT_END);
1997           }
1998           silc_free(rtmp);
1999         }
2000
2001       } else if (type == 2) {
2002         /* Public key.  Check first if the public key is already on the
2003            list and ignore it if it is, otherwise, add it to hash table. */
2004
2005         /* Check if the public key is in the list already */
2006         silc_hash_table_list(list, &htl);
2007         while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) {
2008           if (type == 2 && !memcmp(tmp2->data, tmp, len)) {
2009             tmp = NULL;
2010             break;
2011           }
2012         }
2013         silc_hash_table_list_reset(&htl);
2014
2015         /* Add new public key to invite list */
2016         if (tmp) {
2017           tmp2 = silc_buffer_alloc_size(len);
2018           silc_buffer_put(tmp2, tmp, len);
2019           silc_hash_table_add(list, (void *)2, tmp2);
2020         }
2021
2022       } else if (type == 3) {
2023         /* Client ID */
2024
2025         /* Check if the ID is in the list already */
2026         silc_hash_table_list(list, &htl);
2027         while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) {
2028           if (type == 3 && !memcmp(tmp2->data, tmp, len)) {
2029             tmp = NULL;
2030             break;
2031           }
2032         }
2033         silc_hash_table_list_reset(&htl);
2034
2035         /* Add new Client ID to invite list */
2036         if (tmp) {
2037           tmp2 = silc_buffer_alloc_size(len);
2038           silc_buffer_put(tmp2, tmp, len);
2039           silc_hash_table_add(list, (void *)3, tmp2);
2040         }
2041       }
2042
2043       tmp = silc_argument_get_next_arg(args, &type, &len);
2044     }
2045   }
2046
2047   /* Delete information to invite list */
2048   if (action == 0x01 && list) {
2049     /* Now delete the arguments from invite list */
2050     tmp = silc_argument_get_first_arg(args, &type, &len);
2051     while (tmp) {
2052       if (type == 1) {
2053         /* Invite string.  Get the old string from hash table and delete
2054            the requested string. */
2055         char *string = NULL, *start, *end, *n;
2056
2057         if (silc_hash_table_find(list, (void *)1, NULL, (void *)&tmp2)) {
2058           string = tmp2->head;
2059           if (tmp2->truelen && !strncmp(string, tmp, tmp2->truelen - 1)) {
2060             /* Delete entire string */
2061             silc_hash_table_del(list, (void *)1);
2062           } else if (tmp2->truelen) {
2063             /* Delete part of the string */
2064             start = strstr(string, tmp);
2065             if (start && strlen(start) >= len) {
2066               end = start + len;
2067               n = silc_calloc(strlen(string) - len, sizeof(*n));
2068               strncat(n, string, start - string);
2069               if (strlen(end) > 1)
2070                 strncat(n, end + 1, ((string + strlen(string)) - end) - 1);
2071               silc_free(tmp2->head);
2072               silc_buffer_set(tmp2, n, strlen(n));
2073             }
2074           }
2075         }
2076
2077       } else if (type == 2) {
2078         /* Public key. */
2079
2080         /* Delete from the invite list */
2081         silc_hash_table_list(list, &htl);
2082         while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) {
2083           if (type == 2 && !memcmp(tmp2->data, tmp, len)) {
2084             silc_hash_table_del_by_context(list, (void *)2, tmp2);
2085             break;
2086           }
2087         }
2088         silc_hash_table_list_reset(&htl);
2089
2090       } else if (type == 3) {
2091         /* Client ID */
2092
2093         /* Delete from the invite list */
2094         silc_hash_table_list(list, &htl);
2095         while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) {
2096           if (type == 3 && !memcmp(tmp2->data, tmp, len)) {
2097             silc_hash_table_del_by_context(list, (void *)3, tmp2);
2098             break;
2099           }
2100         }
2101         silc_hash_table_list_reset(&htl);
2102       }
2103
2104       tmp = silc_argument_get_next_arg(args, &type, &len);
2105     }
2106   }
2107 }
2108
2109 /* Destructor for invite and ban list entrys */
2110
2111 void silc_server_inviteban_destruct(void *key, void *context,
2112                                     void *user_context)
2113 {
2114   silc_buffer_free(context);
2115 }
2116
2117 /* Creates connections accoring to configuration. */
2118
2119 void silc_server_create_connections(SilcServer server)
2120 {
2121   silc_schedule_task_del_by_callback(server->schedule,
2122                                      silc_server_connect_to_router);
2123   silc_schedule_task_add(server->schedule, 0,
2124                          silc_server_connect_to_router, server, 0, 1,
2125                          SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
2126 }
2127
2128 static void
2129 silc_server_process_channel_pk_destruct(void *key, void *context,
2130                                         void *user_context)
2131 {
2132   silc_free(key);
2133   silc_pkcs_public_key_free(context);
2134 }
2135
2136 /* Processes a channel public key, either adds or removes it. */
2137
2138 SilcStatus
2139 silc_server_process_channel_pk(SilcServer server,
2140                                SilcChannelEntry channel,
2141                                SilcUInt32 type, const unsigned char *pk,
2142                                SilcUInt32 pk_len)
2143 {
2144   unsigned char pkhash[20];
2145   SilcPublicKey chpk;
2146
2147   SILC_LOG_DEBUG(("Processing channel public key"));
2148
2149   if (!pk || !pk_len)
2150     return SILC_STATUS_ERR_NOT_ENOUGH_PARAMS;
2151
2152   /* Decode the public key */
2153   if (!silc_pkcs_public_key_payload_decode((unsigned char *)pk, pk_len, &chpk))
2154     return SILC_STATUS_ERR_UNSUPPORTED_PUBLIC_KEY;
2155
2156   /* Create channel public key list (hash table) if needed */
2157   if (!channel->channel_pubkeys) {
2158     channel->channel_pubkeys =
2159       silc_hash_table_alloc(0, silc_hash_data, (void *)20,
2160                             silc_hash_data_compare, (void *)20,
2161                             silc_server_process_channel_pk_destruct, channel,
2162                             TRUE);
2163   }
2164
2165   /* Create SHA-1 digest of the public key data */
2166   silc_hash_make(server->sha1hash, pk + 4, pk_len - 4, pkhash);
2167
2168   if (type == 0x00) {
2169     /* Add new public key to channel public key list */
2170     SILC_LOG_DEBUG(("Add new channel public key to channel %s",
2171                     channel->channel_name));
2172
2173     /* Check for resource limit */
2174     if (silc_hash_table_count(channel->channel_pubkeys) > 64) {
2175       silc_pkcs_public_key_free(chpk);
2176       return SILC_STATUS_ERR_RESOURCE_LIMIT;
2177     }
2178
2179     /* Add if doesn't exist already */
2180     if (!silc_hash_table_find(channel->channel_pubkeys, pkhash,
2181                               NULL, NULL))
2182       silc_hash_table_add(channel->channel_pubkeys, silc_memdup(pkhash, 20),
2183                           chpk);
2184   } else if (type == 0x01) {
2185     /* Delete public key from channel public key list */
2186     SILC_LOG_DEBUG(("Delete a channel public key from channel %s",
2187                     channel->channel_name));
2188     if (!silc_hash_table_del(channel->channel_pubkeys, pkhash))
2189       silc_pkcs_public_key_free(chpk);
2190   } else {
2191     silc_pkcs_public_key_free(chpk);
2192     return SILC_STATUS_ERR_NOT_ENOUGH_PARAMS;
2193   }
2194
2195   return SILC_STATUS_OK;
2196 }
2197
2198 /* Returns the channel public keys as Argument List payload. */
2199
2200 SilcBuffer silc_server_get_channel_pk_list(SilcServer server,
2201                                            SilcChannelEntry channel,
2202                                            bool announce,
2203                                            bool delete)
2204 {
2205   SilcHashTableList htl;
2206   SilcBuffer list, pkp;
2207   SilcPublicKey pk;
2208
2209   SILC_LOG_DEBUG(("Encoding channel public keys list"));
2210
2211   if (!channel->channel_pubkeys ||
2212       !silc_hash_table_count(channel->channel_pubkeys))
2213     return NULL;
2214
2215   /* Encode the list */
2216   list = silc_buffer_alloc_size(2);
2217   silc_buffer_format(list,
2218                      SILC_STR_UI_SHORT(silc_hash_table_count(
2219                                        channel->channel_pubkeys)),
2220                      SILC_STR_END);
2221
2222   silc_hash_table_list(channel->channel_pubkeys, &htl);
2223   while (silc_hash_table_get(&htl, NULL, (void *)&pk)) {
2224     pkp = silc_pkcs_public_key_payload_encode(pk);
2225     list = silc_argument_payload_encode_one(list, pkp->data, pkp->len,
2226                                             announce ? 0x03 :
2227                                             delete ? 0x01 : 0x00);
2228     silc_buffer_free(pkp);
2229   }
2230   silc_hash_table_list_reset(&htl);
2231
2232   return list;
2233 }
2234
2235 /* Sets the channel public keys into channel from the list of public keys. */
2236
2237 SilcStatus silc_server_set_channel_pk_list(SilcServer server,
2238                                            SilcSocketConnection sender,
2239                                            SilcChannelEntry channel,
2240                                            const unsigned char *pklist,
2241                                            SilcUInt32 pklist_len)
2242 {
2243   SilcUInt16 argc;
2244   SilcArgumentPayload args;
2245   unsigned char *chpk;
2246   SilcUInt32 chpklen, type;
2247   SilcStatus ret = SILC_STATUS_OK;
2248
2249   SILC_LOG_DEBUG(("Setting channel public keys list"));
2250
2251   if (!pklist || pklist_len < 2)
2252     return SILC_STATUS_ERR_NOT_ENOUGH_PARAMS;
2253
2254   /* Get the argument from the Argument List Payload */
2255   SILC_GET16_MSB(argc, pklist);
2256   args = silc_argument_payload_parse(pklist + 2, pklist_len - 2, argc);
2257   if (!args)
2258     return SILC_STATUS_ERR_NOT_ENOUGH_PARAMS;
2259
2260   /* Process the public keys one by one */
2261   chpk = silc_argument_get_first_arg(args, &type, &chpklen);
2262
2263   /* If announcing keys and we have them set already, do not allow this */
2264   if (chpk && type == 0x03 && channel->channel_pubkeys &&
2265       server->server_type == SILC_ROUTER &&
2266       sender != SILC_PRIMARY_ROUTE(server)) {
2267     SILC_LOG_DEBUG(("Channel public key list set already, enforce our list"));
2268     silc_argument_payload_free(args);
2269     return SILC_STATUS_ERR_OPERATION_ALLOWED;
2270   }
2271
2272   /* If we are normal server and receive announcement list and we already
2273      have keys set, we replace the old list with the announced one. */
2274   if (chpk && type == 0x03 && channel->channel_pubkeys &&
2275       server->server_type != SILC_ROUTER) {
2276     SilcBuffer sidp;
2277     unsigned char mask[4], ulimit[4];
2278
2279     SILC_LOG_DEBUG(("Router enforces its list, remove old list"));
2280     silc_hash_table_free(channel->channel_pubkeys);
2281     channel->channel_pubkeys = NULL;
2282
2283     /* Send notify that removes the old list */
2284     sidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
2285     SILC_PUT32_MSB((channel->mode & (~SILC_CHANNEL_MODE_CHANNEL_AUTH)), mask);
2286     if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
2287       SILC_PUT32_MSB(channel->user_limit, ulimit);
2288     silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
2289                                        SILC_NOTIFY_TYPE_CMODE_CHANGE, 8,
2290                                        sidp->data, sidp->len,
2291                                        mask, 4,
2292                                        channel->cipher,
2293                                        channel->cipher ?
2294                                        strlen(channel->cipher) : 0,
2295                                        channel->hmac_name,
2296                                        channel->hmac_name ?
2297                                        strlen(channel->hmac_name) : 0,
2298                                        channel->passphrase,
2299                                        channel->passphrase ?
2300                                        strlen(channel->passphrase) : 0,
2301                                        NULL, 0, NULL, 0,
2302                                        (channel->mode &
2303                                         SILC_CHANNEL_MODE_ULIMIT ?
2304                                         ulimit : NULL),
2305                                        (channel->mode &
2306                                         SILC_CHANNEL_MODE_ULIMIT ?
2307                                         sizeof(ulimit) : 0));
2308     silc_buffer_free(sidp);
2309   }
2310
2311   while (chpk) {
2312     if (type == 0x03)
2313       type = 0x00;
2314     ret = silc_server_process_channel_pk(server, channel, type,
2315                                          chpk, chpklen);
2316     if (ret != SILC_STATUS_OK)
2317       break;
2318     chpk = silc_argument_get_next_arg(args, &type, &chpklen);
2319   }
2320
2321   silc_argument_payload_free(args);
2322   return ret;
2323 }
2324
2325 /* Verifies the Authentication Payload `auth' with one of the public keys
2326    on the `channel' public key list. */
2327
2328 bool silc_server_verify_channel_auth(SilcServer server,
2329                                      SilcChannelEntry channel,
2330                                      SilcClientID *client_id,
2331                                      const unsigned char *auth,
2332                                      SilcUInt32 auth_len)
2333 {
2334   SilcAuthPayload ap;
2335   SilcPublicKey chpk;
2336   unsigned char *pkhash;
2337   SilcUInt32 pkhash_len;
2338   bool ret = FALSE;
2339
2340   SILC_LOG_DEBUG(("Verifying channel authentication"));
2341
2342   if (!auth || !auth_len || !channel->channel_pubkeys)
2343     return FALSE;
2344
2345   /* Get the hash from the auth data which tells us what public key we
2346      must use in verification. */
2347
2348   ap = silc_auth_payload_parse(auth, auth_len);
2349   if (!ap)
2350     return FALSE;
2351
2352   pkhash = silc_auth_get_public_data(ap, &pkhash_len);
2353   if (pkhash_len < 128)
2354     goto out;
2355
2356   /* Find the public key with the hash */
2357   if (!silc_hash_table_find(channel->channel_pubkeys, pkhash,
2358                             NULL, (void *)&chpk)) {
2359     SILC_LOG_DEBUG(("Public key not found in channel public key list"));
2360     goto out;
2361   }
2362
2363   /* Verify the signature */
2364   if (!silc_auth_verify(ap, SILC_AUTH_PUBLIC_KEY, (void *)chpk, 0,
2365                         server->sha1hash, client_id, SILC_ID_CLIENT)) {
2366     SILC_LOG_DEBUG(("Authentication failed"));
2367     goto out;
2368   }
2369
2370   ret = TRUE;
2371
2372  out:
2373   silc_auth_payload_free(ap);
2374   return ret;
2375 }