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