54a95feb5ad86538488fd003e1dbded40835d0ad
[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   SILC_LOG_DEBUG(("Deleting channel %s", channel->channel_name));
1024
1025   if (delchan) {
1026     /* Update statistics */
1027     if (server->server_type == SILC_ROUTER)
1028       server->stat.chanclients -= channel->user_count;
1029
1030     /* Totally delete the channel and all users on the channel. The
1031        users are deleted automatically in silc_idlist_del_channel. */
1032     channel->disabled = TRUE;
1033     silc_schedule_task_del_by_context(server->schedule, channel->rekey);
1034     if (silc_idlist_del_channel(server->local_list, channel)) {
1035       server->stat.my_channels--;
1036       if (server->server_type == SILC_ROUTER) {
1037         server->stat.channels--;
1038         server->stat.cell_channels--;
1039       }
1040     } else {
1041       if (silc_idlist_del_channel(server->global_list, channel))
1042         if (server->server_type == SILC_ROUTER)
1043           server->stat.channels--;
1044     }
1045
1046     return FALSE;
1047   }
1048
1049   /* Channel is permanent, do not remove it, remove only users */
1050   channel->disabled = TRUE;
1051   silc_hash_table_list(channel->user_list, &htl);
1052   while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
1053     silc_hash_table_del(chl->client->channels, channel);
1054     silc_hash_table_del(channel->user_list, chl->client);
1055     channel->user_count--;
1056
1057     /* Update statistics */
1058     if (SILC_IS_LOCAL(chl->client))
1059       server->stat.my_chanclients--;
1060     if (server->server_type == SILC_ROUTER) {
1061       server->stat.cell_chanclients--;
1062       server->stat.chanclients--;
1063     }
1064
1065     silc_free(chl);
1066   }
1067   silc_hash_table_list_reset(&htl);
1068
1069   SILC_LOG_DEBUG(("Channel %s remains (permanent)", channel->channel_name));
1070
1071   return TRUE;
1072 }
1073
1074 /* Returns TRUE if the given client is on the channel.  FALSE if not.
1075    This works because we assure that the user list on the channel is
1076    always in up to date thus we can only check the channel list from
1077    `client' which is faster than checking the user list from `channel'. */
1078
1079 bool silc_server_client_on_channel(SilcClientEntry client,
1080                                    SilcChannelEntry channel,
1081                                    SilcChannelClientEntry *chl)
1082 {
1083   if (!client || !channel)
1084     return FALSE;
1085
1086   return silc_hash_table_find(client->channels, channel, NULL,
1087                               (void *)chl);
1088 }
1089
1090 /* Checks string for bad characters and returns TRUE if they are found. */
1091
1092 bool silc_server_name_bad_chars(const char *name, SilcUInt32 name_len)
1093 {
1094   int i;
1095
1096   for (i = 0; i < name_len; i++) {
1097     if (!isascii(name[i]))
1098       return TRUE;
1099     if (name[i] <= 32) 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     if (name[i] == '@') return TRUE;
1105     if (name[i] == '!') return TRUE;
1106   }
1107
1108   return FALSE;
1109 }
1110
1111 /* Same as silc_server_name_bad_chars but check for channel names. */
1112
1113 bool silc_server_name_bad_chchars(const char *name, SilcUInt32 name_len)
1114 {
1115   int i;
1116
1117   for (i = 0; i < name_len; i++) {
1118     if (!isascii(name[i]))
1119       return TRUE;
1120     if (name[i] <= 32) return TRUE;
1121     if (name[i] == ' ') return TRUE;
1122     if (name[i] == '*') return TRUE;
1123     if (name[i] == '?') return TRUE;
1124     if (name[i] == ',') return TRUE;
1125   }
1126
1127   return FALSE;
1128 }
1129
1130 /* Modifies the `name' if it includes bad characters and returns new
1131    allocated name that does not include bad characters. */
1132
1133 char *silc_server_name_modify_bad(const char *name, SilcUInt32 name_len)
1134 {
1135   int i;
1136   char *newname = strdup(name);
1137
1138   for (i = 0; i < name_len; i++) {
1139     if (!isascii(newname[i])) newname[i] = '_';
1140     if (newname[i] <= 32) newname[i] = '_';
1141     if (newname[i] == ' ') newname[i] = '_';
1142     if (newname[i] == '*') newname[i] = '_';
1143     if (newname[i] == '?') newname[i] = '_';
1144     if (newname[i] == ',') newname[i] = '_';
1145   }
1146
1147   return newname;
1148 }
1149
1150 /* Find number of sockets by IP address indicated by `ip'. Returns 0 if
1151    socket connections with the IP address does not exist. */
1152
1153 SilcUInt32 silc_server_num_sockets_by_ip(SilcServer server, const char *ip,
1154                                          SilcSocketType type)
1155 {
1156   int i, count;
1157
1158   for (i = 0, count = 0; i < server->config->param.connections_max; i++) {
1159     if (server->sockets[i] && !SILC_IS_LISTENER(server->sockets[i]) &&
1160         !strcmp(server->sockets[i]->ip, ip) &&
1161         server->sockets[i]->type == type)
1162       count++;
1163   }
1164
1165   return count;
1166 }
1167
1168 /* Find number of sockets by IP address indicated by remote host, indicatd
1169    by `ip' or `hostname', `port', and `type'.  Returns 0 if socket connections
1170    does not exist. If `ip' is provided then `hostname' is ignored. */
1171
1172 SilcUInt32 silc_server_num_sockets_by_remote(SilcServer server,
1173                                              const char *ip,
1174                                              const char *hostname,
1175                                              SilcUInt16 port,
1176                                              SilcSocketType type)
1177 {
1178   int i, count;
1179
1180   if (!ip && !hostname)
1181     return 0;
1182
1183   for (i = 0, count = 0; i < server->config->param.connections_max; i++) {
1184     if (server->sockets[i] && !SILC_IS_LISTENER(server->sockets[i]) &&
1185         ((ip && !strcmp(server->sockets[i]->ip, ip)) ||
1186          (hostname && !strcmp(server->sockets[i]->hostname, hostname))) &&
1187         server->sockets[i]->port == port &&
1188         server->sockets[i]->type == type)
1189       count++;
1190   }
1191
1192   return count;
1193 }
1194
1195 /* Finds locally cached public key by the public key received in the SKE.
1196    If we have it locally cached then we trust it and will use it in the
1197    authentication protocol.  Returns the locally cached public key or NULL
1198    if we do not find the public key.  */
1199
1200 SilcPublicKey silc_server_find_public_key(SilcServer server,
1201                                           SilcHashTable local_public_keys,
1202                                           SilcPublicKey remote_public_key)
1203 {
1204   SilcPublicKey cached_key;
1205
1206   SILC_LOG_DEBUG(("Find remote public key (%d keys in local cache)",
1207                   silc_hash_table_count(local_public_keys)));
1208
1209   if (!silc_hash_table_find_ext(local_public_keys, remote_public_key,
1210                                 (void *)&cached_key, NULL,
1211                                 silc_hash_public_key, NULL,
1212                                 silc_hash_public_key_compare, NULL)) {
1213     SILC_LOG_ERROR(("Public key not found"));
1214     return NULL;
1215   }
1216
1217   SILC_LOG_DEBUG(("Found public key"));
1218
1219   return cached_key;
1220 }
1221
1222 /* This returns the first public key from the table of public keys.  This
1223    is used only in cases where single public key exists in the table and
1224    we want to get a pointer to it.  For public key tables that has multiple
1225    keys in it the silc_server_find_public_key must be used. */
1226
1227 SilcPublicKey silc_server_get_public_key(SilcServer server,
1228                                          SilcHashTable local_public_keys)
1229 {
1230   SilcPublicKey cached_key;
1231   SilcHashTableList htl;
1232
1233   SILC_LOG_DEBUG(("Start"));
1234
1235   assert(silc_hash_table_count(local_public_keys) < 2);
1236
1237   silc_hash_table_list(local_public_keys, &htl);
1238   if (!silc_hash_table_get(&htl, NULL, (void *)&cached_key)) {
1239     silc_hash_table_list_reset(&htl);
1240     return NULL;
1241   }
1242   silc_hash_table_list_reset(&htl);
1243
1244   return cached_key;
1245 }
1246
1247 /* Check whether the connection `sock' is allowed to connect to us.  This
1248    checks for example whether there is too much connections for this host,
1249    and required version for the host etc. */
1250
1251 bool silc_server_connection_allowed(SilcServer server,
1252                                     SilcSocketConnection sock,
1253                                     SilcSocketType type,
1254                                     SilcServerConfigConnParams *global,
1255                                     SilcServerConfigConnParams *params,
1256                                     SilcSKE ske)
1257 {
1258   SilcUInt32 conn_number = (type == SILC_SOCKET_TYPE_CLIENT ?
1259                             server->stat.my_clients :
1260                             type == SILC_SOCKET_TYPE_SERVER ?
1261                             server->stat.my_servers :
1262                             server->stat.my_routers);
1263   SilcUInt32 num_sockets, max_hosts, max_per_host;
1264   SilcUInt32 r_protocol_version, l_protocol_version;
1265   SilcUInt32 r_software_version, l_software_version;
1266   char *r_vendor_version = NULL, *l_vendor_version;
1267
1268   SILC_LOG_DEBUG(("Checking whether connection is allowed"));
1269
1270   /* Check version */
1271
1272   l_protocol_version =
1273     silc_version_to_num(params && params->version_protocol ?
1274                         params->version_protocol :
1275                         global->version_protocol);
1276   l_software_version =
1277     silc_version_to_num(params && params->version_software ?
1278                         params->version_software :
1279                         global->version_software);
1280   l_vendor_version = (params && params->version_software_vendor ?
1281                       params->version_software_vendor :
1282                       global->version_software_vendor);
1283
1284   if (ske && silc_ske_parse_version(ske, &r_protocol_version, NULL,
1285                                     &r_software_version, NULL,
1286                                     &r_vendor_version)) {
1287     sock->version = r_protocol_version;
1288
1289     /* Match protocol version */
1290     if (l_protocol_version && r_protocol_version &&
1291         r_protocol_version < l_protocol_version) {
1292       SILC_LOG_INFO(("Connection %s (%s) is too old version",
1293                      sock->hostname, sock->ip));
1294       sock->protocol = NULL;
1295       silc_server_disconnect_remote(server, sock,
1296                                     SILC_STATUS_ERR_BAD_VERSION,
1297                                     "You support too old protocol version");
1298       return FALSE;
1299     }
1300
1301     /* Math software version */
1302     if (l_software_version && r_software_version &&
1303         r_software_version < l_software_version) {
1304       SILC_LOG_INFO(("Connection %s (%s) is too old version",
1305                      sock->hostname, sock->ip));
1306       sock->protocol = NULL;
1307       silc_server_disconnect_remote(server, sock,
1308                                     SILC_STATUS_ERR_BAD_VERSION,
1309                                     "You support too old software version");
1310       return FALSE;
1311     }
1312
1313     /* Regex match vendor version */
1314     if (l_vendor_version && r_vendor_version &&
1315         !silc_string_match(l_vendor_version, r_vendor_version)) {
1316       SILC_LOG_INFO(("Connection %s (%s) is unsupported version",
1317                      sock->hostname, sock->ip));
1318       sock->protocol = NULL;
1319       silc_server_disconnect_remote(server, sock,
1320                                     SILC_STATUS_ERR_BAD_VERSION,
1321                                     "Your software is not supported");
1322       return FALSE;
1323     }
1324   }
1325   silc_free(r_vendor_version);
1326
1327   /* Check for maximum connections limit */
1328
1329   num_sockets = silc_server_num_sockets_by_ip(server, sock->ip, type);
1330   max_hosts = (params ? params->connections_max : global->connections_max);
1331   max_per_host = (params ? params->connections_max_per_host :
1332                   global->connections_max_per_host);
1333
1334   if (max_hosts && conn_number >= max_hosts) {
1335     SILC_LOG_INFO(("Server is full, closing %s (%s) connection",
1336                    sock->hostname, sock->ip));
1337     sock->protocol = NULL;
1338     silc_server_disconnect_remote(server, sock,
1339                                   SILC_STATUS_ERR_RESOURCE_LIMIT,
1340                                   "Server is full, try again later");
1341     return FALSE;
1342   }
1343
1344   if (num_sockets >= max_per_host) {
1345     SILC_LOG_INFO(("Too many connections from %s (%s), closing connection",
1346                    sock->hostname, sock->ip));
1347     sock->protocol = NULL;
1348     silc_server_disconnect_remote(server, sock,
1349                                   SILC_STATUS_ERR_RESOURCE_LIMIT,
1350                                   "Too many connections from your host");
1351     return FALSE;
1352   }
1353
1354   return TRUE;
1355 }
1356
1357 /* Checks that client has rights to add or remove channel modes. If any
1358    of the checks fails FALSE is returned. */
1359
1360 bool silc_server_check_cmode_rights(SilcServer server,
1361                                     SilcChannelEntry channel,
1362                                     SilcChannelClientEntry client,
1363                                     SilcUInt32 mode)
1364 {
1365   bool is_op = client->mode & SILC_CHANNEL_UMODE_CHANOP;
1366   bool is_fo = client->mode & SILC_CHANNEL_UMODE_CHANFO;
1367
1368   /* Check whether has rights to change anything */
1369   if (!is_op && !is_fo)
1370     return FALSE;
1371
1372   /* Check whether has rights to change everything */
1373   if (is_op && is_fo)
1374     return TRUE;
1375
1376   /* Founder implies operator */
1377   if (is_fo)
1378     is_op = TRUE;
1379
1380   /* We know that client is channel operator, check that they are not
1381      changing anything that requires channel founder rights. Rest of the
1382      modes are available automatically for channel operator. */
1383
1384   if (mode & SILC_CHANNEL_MODE_PRIVKEY) {
1385     if (is_op && !is_fo)
1386       return FALSE;
1387   } else {
1388     if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
1389       if (is_op && !is_fo)
1390         return FALSE;
1391     }
1392   }
1393
1394   if (mode & SILC_CHANNEL_MODE_PASSPHRASE) {
1395     if (!(channel->mode & SILC_CHANNEL_MODE_PASSPHRASE)) {
1396       if (is_op && !is_fo)
1397         return FALSE;
1398     }
1399   } else {
1400     if (channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
1401       if (is_op && !is_fo)
1402         return FALSE;
1403     }
1404   }
1405
1406   if (mode & SILC_CHANNEL_MODE_CIPHER) {
1407     if (!(channel->mode & SILC_CHANNEL_MODE_CIPHER)) {
1408       if (is_op && !is_fo)
1409         return FALSE;
1410     }
1411   } else {
1412     if (channel->mode & SILC_CHANNEL_MODE_CIPHER) {
1413       if (is_op && !is_fo)
1414         return FALSE;
1415     }
1416   }
1417
1418   if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
1419     if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
1420       if (is_op && !is_fo)
1421         return FALSE;
1422     }
1423   } else {
1424     if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
1425       if (is_op && !is_fo)
1426         return FALSE;
1427     }
1428   }
1429
1430   if (mode & SILC_CHANNEL_MODE_SILENCE_USERS) {
1431     if (!(channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS)) {
1432       if (is_op && !is_fo)
1433         return FALSE;
1434     }
1435   } else {
1436     if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS) {
1437       if (is_op && !is_fo)
1438         return FALSE;
1439     }
1440   }
1441
1442   if (mode & SILC_CHANNEL_MODE_SILENCE_OPERS) {
1443     if (!(channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS)) {
1444       if (is_op && !is_fo)
1445         return FALSE;
1446     }
1447   } else {
1448     if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS) {
1449       if (is_op && !is_fo)
1450         return FALSE;
1451     }
1452   }
1453
1454   if (mode & SILC_CHANNEL_MODE_CHANNEL_AUTH) {
1455     if (!(channel->mode & SILC_CHANNEL_MODE_CHANNEL_AUTH)) {
1456       if (is_op && !is_fo)
1457         return FALSE;
1458     }
1459   } else {
1460     if (channel->mode & SILC_CHANNEL_MODE_CHANNEL_AUTH) {
1461       if (is_op && !is_fo)
1462         return FALSE;
1463     }
1464   }
1465
1466   return TRUE;
1467 }
1468
1469 /* Check that the client has rights to change its user mode.  Returns
1470    FALSE if setting some mode is not allowed. */
1471
1472 bool silc_server_check_umode_rights(SilcServer server,
1473                                     SilcClientEntry client,
1474                                     SilcUInt32 mode)
1475 {
1476   bool server_op = FALSE, router_op = FALSE;
1477
1478   if (mode & SILC_UMODE_SERVER_OPERATOR) {
1479     /* Cannot set server operator mode (must use OPER command) */
1480     if (!(client->mode & SILC_UMODE_SERVER_OPERATOR))
1481       return FALSE;
1482   } else {
1483     /* Remove the server operator rights */
1484     if (client->mode & SILC_UMODE_SERVER_OPERATOR)
1485       server_op = TRUE;
1486   }
1487
1488   if (mode & SILC_UMODE_ROUTER_OPERATOR) {
1489     /* Cannot set router operator mode (must use SILCOPER command) */
1490     if (!(client->mode & SILC_UMODE_ROUTER_OPERATOR))
1491       return FALSE;
1492   } else {
1493     /* Remove the router operator rights */
1494     if (client->mode & SILC_UMODE_ROUTER_OPERATOR)
1495       router_op = TRUE;
1496   }
1497
1498   if (server_op)
1499     SILC_UMODE_STATS_UPDATE(server, SILC_UMODE_SERVER_OPERATOR);
1500   if (router_op)
1501     SILC_UMODE_STATS_UPDATE(router, SILC_UMODE_ROUTER_OPERATOR);
1502
1503   return TRUE;
1504 }
1505
1506 /* This function is used to send the notify packets and motd to the
1507    incoming client connection. */
1508
1509 void silc_server_send_connect_notifys(SilcServer server,
1510                                       SilcSocketConnection sock,
1511                                       SilcClientEntry client)
1512 {
1513   SilcIDListData idata = (SilcIDListData)client;
1514
1515   SILC_LOG_DEBUG(("Send welcome notifys"));
1516
1517   /* Send some nice info to the client */
1518   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1519                           ("Welcome to the SILC Network %s",
1520                            client->username));
1521   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1522                           ("Your host is %s, running version %s",
1523                            server->server_name, server_version));
1524
1525   if (server->server_type == SILC_ROUTER) {
1526     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1527                             ("There are %d clients, %d servers and %d "
1528                              "routers in SILC Network",
1529                              server->stat.clients, server->stat.servers,
1530                              server->stat.routers));
1531   } else {
1532     if (server->stat.clients && server->stat.servers + 1)
1533       SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1534                               ("There are %d clients, %d servers and %d "
1535                                "routers in SILC Network",
1536                                server->stat.clients, server->stat.servers,
1537                                (server->standalone ? 0 :
1538                                 !server->stat.routers ? 1 :
1539                                 server->stat.routers)));
1540   }
1541
1542   if (server->stat.cell_clients && server->stat.cell_servers + 1)
1543     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1544                             ("There are %d clients on %d servers in our cell",
1545                              server->stat.cell_clients,
1546                              server->stat.cell_servers));
1547   if (server->server_type == SILC_ROUTER) {
1548     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1549                             ("I have %d clients, %d channels, %d servers and "
1550                              "%d routers",
1551                              server->stat.my_clients,
1552                              server->stat.my_channels,
1553                              server->stat.my_servers,
1554                              server->stat.my_routers));
1555   } else {
1556     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1557                             ("I have %d clients and %d channels formed",
1558                              server->stat.my_clients,
1559                              server->stat.my_channels));
1560   }
1561
1562   if (server->stat.server_ops || server->stat.router_ops)
1563     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1564                             ("There are %d server operators and %d router "
1565                              "operators online",
1566                              server->stat.server_ops,
1567                              server->stat.router_ops));
1568   if (server->stat.my_router_ops + server->stat.my_server_ops)
1569     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1570                             ("I have %d operators online",
1571                              server->stat.my_router_ops +
1572                              server->stat.my_server_ops));
1573
1574   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1575                           ("Your connection is secured with %s cipher, "
1576                            "key length %d bits",
1577                            silc_cipher_get_name(idata->send_key),
1578                            silc_cipher_get_key_len(idata->send_key)));
1579   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1580                           ("Your current nickname is %s",
1581                            client->nickname));
1582
1583   /* Send motd */
1584   silc_server_send_motd(server, sock);
1585 }
1586
1587 /* Kill the client indicated by `remote_client' sending KILLED notify
1588    to the client, to all channels client has joined and to primary
1589    router if needed.  The killed client is also removed from all channels. */
1590
1591 void silc_server_kill_client(SilcServer server,
1592                              SilcClientEntry remote_client,
1593                              const char *comment,
1594                              void *killer_id,
1595                              SilcIdType killer_id_type)
1596 {
1597   SilcBuffer killed, killer;
1598
1599   SILC_LOG_DEBUG(("Killing client %s",
1600                   silc_id_render(remote_client->id, SILC_ID_CLIENT)));
1601
1602   /* Send the KILL notify packets. First send it to the channel, then
1603      to our primary router and then directly to the client who is being
1604      killed right now. */
1605
1606   killed = silc_id_payload_encode(remote_client->id, SILC_ID_CLIENT);
1607   killer = silc_id_payload_encode(killer_id, killer_id_type);
1608
1609   /* Send KILLED notify to the channels. It is not sent to the client
1610      as it will be sent differently destined directly to the client and not
1611      to the channel. */
1612   silc_server_send_notify_on_channels(server, remote_client,
1613                                       remote_client, SILC_NOTIFY_TYPE_KILLED,
1614                                       3, killed->data, killed->len,
1615                                       comment, comment ? strlen(comment) : 0,
1616                                       killer->data, killer->len);
1617
1618   /* Send KILLED notify to primary route */
1619   silc_server_send_notify_killed(server, SILC_PRIMARY_ROUTE(server),
1620                                  SILC_BROADCAST(server), remote_client->id,
1621                                  comment, killer_id, killer_id_type);
1622
1623   /* Send KILLED notify to the client directly */
1624   if (remote_client->connection || remote_client->router)
1625     silc_server_send_notify_killed(server, remote_client->connection ?
1626                                    remote_client->connection :
1627                                    remote_client->router->connection, FALSE,
1628                                    remote_client->id, comment,
1629                                    killer_id, killer_id_type);
1630
1631   /* Remove the client from all channels. This generates new keys to the
1632      channels as well. */
1633   silc_server_remove_from_channels(server, NULL, remote_client, FALSE,
1634                                    NULL, TRUE, TRUE);
1635
1636   /* Remove the client entry, If it is locally connected then we will also
1637      disconnect the client here */
1638   if (remote_client->connection) {
1639     /* Remove locally conneted client */
1640     SilcSocketConnection sock = remote_client->connection;
1641     silc_server_free_client_data(server, sock, remote_client, FALSE, NULL);
1642     silc_server_close_connection(server, sock);
1643   } else {
1644     /* Update statistics */
1645     server->stat.clients--;
1646     if (server->stat.cell_clients)
1647       server->stat.cell_clients--;
1648     SILC_OPER_STATS_UPDATE(remote_client, server, SILC_UMODE_SERVER_OPERATOR);
1649     SILC_OPER_STATS_UPDATE(remote_client, router, SILC_UMODE_ROUTER_OPERATOR);
1650
1651     if (remote_client->data.public_key)
1652       silc_hash_table_del_by_context(server->pk_hash,
1653                                      remote_client->data.public_key,
1654                                      remote_client);
1655
1656     if (SILC_IS_LOCAL(remote_client)) {
1657       server->stat.my_clients--;
1658       silc_schedule_task_del_by_context(server->schedule, remote_client);
1659       silc_idlist_del_data(remote_client);
1660     }
1661
1662     /* Remove remote client */
1663     silc_idlist_del_data(remote_client);
1664     if (!silc_idlist_del_client(server->global_list, remote_client)) {
1665       /* Remove this client from watcher list if it is */
1666       silc_server_del_from_watcher_list(server, remote_client);
1667       silc_idlist_del_client(server->local_list, remote_client);
1668     }
1669   }
1670
1671   silc_buffer_free(killer);
1672   silc_buffer_free(killed);
1673 }
1674
1675 typedef struct {
1676   SilcServer server;
1677   SilcClientEntry client;
1678   SilcNotifyType notify;
1679   const char *new_nick;
1680 } WatcherNotifyContext;
1681
1682 static void
1683 silc_server_check_watcher_list_foreach(void *key, void *context,
1684                                        void *user_context)
1685 {
1686   WatcherNotifyContext *notify = user_context;
1687   SilcClientEntry entry = context;
1688   SilcSocketConnection sock;
1689
1690   if (!context)
1691     return;
1692
1693   if (entry == notify->client)
1694     return;
1695
1696   sock = silc_server_get_client_route(notify->server, NULL, 0, entry->id,
1697                                       NULL, NULL);
1698   if (sock) {
1699     SILC_LOG_DEBUG(("Sending WATCH notify to %s",
1700                     silc_id_render(entry->id, SILC_ID_CLIENT)));
1701
1702     /* Send the WATCH notify */
1703     silc_server_send_notify_watch(notify->server, sock, entry,
1704                                   notify->client,
1705                                   notify->new_nick ? notify->new_nick :
1706                                   (const char *)notify->client->nickname,
1707                                   notify->notify,
1708                                   notify->client->data.public_key);
1709   }
1710 }
1711
1712 /* This function checks whether the `client' nickname and/or 'client'
1713    public key is being watched by someone, and notifies the watcher of the
1714    notify change of notify type indicated by `notify'. */
1715
1716 bool silc_server_check_watcher_list(SilcServer server,
1717                                     SilcClientEntry client,
1718                                     const char *new_nick,
1719                                     SilcNotifyType notify)
1720 {
1721   unsigned char hash[16];
1722   WatcherNotifyContext n;
1723
1724   SILC_LOG_DEBUG(("Checking watcher list %s",
1725                   client->nickname ? client->nickname : (unsigned char *)""));
1726
1727   /* If the watching is rejected by the client do nothing */
1728   if (client->mode & SILC_UMODE_REJECT_WATCHING)
1729     return FALSE;
1730
1731   /* Make hash from the nick, or take it from Client ID */
1732   if (client->nickname) {
1733     unsigned char *nickc;
1734     nickc = silc_identifier_check(client->nickname, strlen(client->nickname),
1735                                   SILC_STRING_UTF8, 128, NULL);
1736     if (!nickc)
1737       return FALSE;
1738     silc_hash_make(server->md5hash, nickc, strlen(nickc), hash);
1739     silc_free(nickc);
1740   } else {
1741     memset(hash, 0, sizeof(hash));
1742     memcpy(hash, client->id->hash, sizeof(client->id->hash));
1743   }
1744
1745   n.server = server;
1746   n.client = client;
1747   n.new_nick = new_nick;
1748   n.notify = notify;
1749
1750   /* Send notify to all watchers watching this nickname */
1751   silc_hash_table_find_foreach(server->watcher_list, hash,
1752                                silc_server_check_watcher_list_foreach, &n);
1753
1754   /* Send notify to all watchers watching this public key */
1755   if (client->data.public_key)
1756     silc_hash_table_find_foreach(server->watcher_list_pk,
1757                                  client->data.public_key,
1758                                  silc_server_check_watcher_list_foreach,
1759                                  &n);
1760
1761   return TRUE;
1762 }
1763
1764 /* Remove the `client' from watcher list. After calling this the `client'
1765    is not watching any nicknames. */
1766
1767 bool silc_server_del_from_watcher_list(SilcServer server,
1768                                        SilcClientEntry client)
1769 {
1770   SilcHashTableList htl;
1771   void *key;
1772   SilcClientEntry entry;
1773   bool found = FALSE;
1774
1775   silc_hash_table_list(server->watcher_list, &htl);
1776   while (silc_hash_table_get(&htl, &key, (void *)&entry)) {
1777     if (entry == client) {
1778       silc_hash_table_del_by_context(server->watcher_list, key, client);
1779
1780       if (client->id)
1781         SILC_LOG_DEBUG(("Removing %s from WATCH list",
1782                         silc_id_render(client->id, SILC_ID_CLIENT)));
1783
1784       /* Now check whether there still exists entries with this key, if not
1785          then free the key to not leak memory. */
1786       if (!silc_hash_table_find(server->watcher_list, key, NULL, NULL))
1787         silc_free(key);
1788
1789       found = TRUE;
1790     }
1791   }
1792   silc_hash_table_list_reset(&htl);
1793
1794   silc_hash_table_list(server->watcher_list_pk, &htl);
1795   while (silc_hash_table_get(&htl, &key, (void *)&entry)) {
1796     if (entry == client) {
1797       silc_hash_table_del_by_context(server->watcher_list_pk, key, client);
1798
1799       if (client->id)
1800         SILC_LOG_DEBUG(("Removing %s from WATCH list",
1801                         silc_id_render(client->id, SILC_ID_CLIENT)));
1802
1803       /* Now check whether there still exists entries with this key, if not
1804          then free the key to not leak memory. */
1805       if (!silc_hash_table_find(server->watcher_list_pk, key, NULL, NULL))
1806         silc_pkcs_public_key_free(key);
1807
1808       found = TRUE;
1809     }
1810   }
1811   silc_hash_table_list_reset(&htl);
1812
1813   return found;
1814 }
1815
1816 /* Force the client indicated by `chl' to change the channel user mode
1817    on channel indicated by `channel' to `forced_mode'. */
1818
1819 bool silc_server_force_cumode_change(SilcServer server,
1820                                      SilcSocketConnection sock,
1821                                      SilcChannelEntry channel,
1822                                      SilcChannelClientEntry chl,
1823                                      SilcUInt32 forced_mode)
1824 {
1825   SilcBuffer idp1, idp2;
1826   unsigned char cumode[4];
1827
1828   SILC_LOG_DEBUG(("Enforcing sender to change mode"));
1829
1830   if (sock)
1831     silc_server_send_notify_cumode(server, sock, FALSE, channel, forced_mode,
1832                                    server->id, SILC_ID_SERVER,
1833                                    chl->client->id, NULL);
1834
1835   idp1 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
1836   idp2 = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
1837   SILC_PUT32_MSB(forced_mode, cumode);
1838   silc_server_send_notify_to_channel(server, sock, channel, FALSE, TRUE,
1839                                      SILC_NOTIFY_TYPE_CUMODE_CHANGE,
1840                                      3, idp1->data, idp1->len,
1841                                      cumode, sizeof(cumode),
1842                                      idp2->data, idp2->len);
1843   silc_buffer_free(idp1);
1844   silc_buffer_free(idp2);
1845
1846   return TRUE;
1847 }
1848
1849 /* Find active socket connection by the IP address and port indicated by
1850    `ip' and `port', and socket connection type of `type'. */
1851
1852 SilcSocketConnection
1853 silc_server_find_socket_by_host(SilcServer server,
1854                                 SilcSocketType type,
1855                                 const char *ip, SilcUInt16 port)
1856 {
1857   int i;
1858
1859   for (i = 0; i < server->config->param.connections_max; i++) {
1860     if (!server->sockets[i])
1861       continue;
1862     if (!strcmp(server->sockets[i]->ip, ip) &&
1863         (!port || server->sockets[i]->port == port) &&
1864         server->sockets[i]->type == type)
1865       return server->sockets[i];
1866   }
1867
1868   return NULL;
1869 }
1870
1871 /* This function can be used to match the invite and ban lists. */
1872
1873 bool silc_server_inviteban_match(SilcServer server, SilcHashTable list,
1874                                  SilcUInt8 type, void *check)
1875 {
1876   unsigned char *tmp = NULL;
1877   SilcUInt32 len = 0, t;
1878   SilcHashTableList htl;
1879   SilcBuffer entry, idp = NULL, pkp = NULL;
1880   bool ret = FALSE;
1881
1882   SILC_LOG_DEBUG(("Matching invite/ban"));
1883
1884   if (type < 1 || type > 3 || !check)
1885     return FALSE;
1886
1887   if (type == 1) {
1888     tmp = strdup((char *)check);
1889     if (!tmp)
1890       return FALSE;
1891   }
1892   if (type == 2) {
1893     pkp = silc_pkcs_public_key_payload_encode(check);
1894     if (!pkp)
1895       return FALSE;
1896     tmp = pkp->data;
1897     len = pkp->len;
1898   }
1899   if (type == 3) {
1900     idp = silc_id_payload_encode(check, SILC_ID_CLIENT);
1901     if (!idp)
1902       return FALSE;
1903     tmp = idp->data;
1904     len = idp->len;
1905   }
1906
1907   /* Compare the list */
1908   silc_hash_table_list(list, &htl);
1909   while (silc_hash_table_get(&htl, (void *)&t, (void *)&entry)) {
1910     if (type == t) {
1911       if (type == 1) {
1912         if (silc_string_match(entry->data, tmp)) {
1913           ret = TRUE;
1914           break;
1915         }
1916       } else if (!memcmp(entry->data, tmp, len)) {
1917         ret = TRUE;
1918         break;
1919       }
1920     }
1921   }
1922   silc_hash_table_list_reset(&htl);
1923
1924   if (type == 1)
1925     silc_free(tmp);
1926   silc_buffer_free(idp);
1927   silc_buffer_free(pkp);
1928   return ret;
1929 }
1930
1931 /* Process invite or ban information */
1932
1933 bool silc_server_inviteban_process(SilcServer server, SilcHashTable list,
1934                                    SilcUInt8 action, SilcArgumentPayload args)
1935 {
1936   unsigned char *tmp;
1937   SilcUInt32 type, len;
1938   SilcBuffer tmp2;
1939   SilcHashTableList htl;
1940
1941   SILC_LOG_DEBUG(("Processing invite/ban for %s action",
1942                   action == 0x01 ? "DEL" : "ADD"));
1943
1944   /* Add the information to invite list */
1945   if (action == 0x00 || action == 0x03) {
1946     /* Traverse all arguments and add to the hash table according to
1947        their type. */
1948     tmp = silc_argument_get_first_arg(args, &type, &len);
1949     while (tmp) {
1950       if (type == 1) {
1951         /* Check validity of the string */
1952         if (!silc_utf8_valid(tmp, len) || !len) {
1953           tmp = silc_argument_get_next_arg(args, &type, &len);
1954           continue;
1955         }
1956
1957         /* Check if the string is added already */
1958         silc_hash_table_list(list, &htl);
1959         while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) {
1960           if (type == 1 && silc_string_match(tmp2->data, tmp)) {
1961             tmp = NULL;
1962             break;
1963           }
1964         }
1965         silc_hash_table_list_reset(&htl);
1966
1967         if (tmp) {
1968           /* Add the string to hash table */
1969           tmp2 = silc_buffer_alloc_size(len + 1);
1970           if (tmp[len - 1] == ',')
1971             tmp[len - 1] = '\0';
1972           silc_buffer_put(tmp2, tmp, len);
1973           silc_hash_table_add(list, (void *)1, tmp2);
1974         }
1975
1976       } else if (type == 2) {
1977         /* Public key.  Check first if the public key is already on the
1978            list and ignore it if it is, otherwise, add it to hash table. */
1979         SilcPublicKey pk;
1980
1981         /* Verify validity of the public key */
1982         if (!silc_pkcs_public_key_payload_decode(tmp, len, &pk)) {
1983           tmp = silc_argument_get_next_arg(args, &type, &len);
1984           continue;
1985         }
1986         silc_pkcs_public_key_free(pk);
1987
1988         /* Check if the public key is in the list already */
1989         silc_hash_table_list(list, &htl);
1990         while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) {
1991           if (type == 2 && !memcmp(tmp2->data, tmp, len)) {
1992             tmp = NULL;
1993             break;
1994           }
1995         }
1996         silc_hash_table_list_reset(&htl);
1997
1998         /* Add new public key to invite list */
1999         if (tmp) {
2000           tmp2 = silc_buffer_alloc_size(len);
2001           silc_buffer_put(tmp2, tmp, len);
2002           silc_hash_table_add(list, (void *)2, tmp2);
2003         }
2004
2005       } else if (type == 3) {
2006         /* Client ID */
2007
2008         /* Check if the ID is in the list already */
2009         silc_hash_table_list(list, &htl);
2010         while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) {
2011           if (type == 3 && !memcmp(tmp2->data, tmp, len)) {
2012             tmp = NULL;
2013             break;
2014           }
2015         }
2016         silc_hash_table_list_reset(&htl);
2017
2018         /* Add new Client ID to invite list */
2019         if (tmp) {
2020           tmp2 = silc_buffer_alloc_size(len);
2021           silc_buffer_put(tmp2, tmp, len);
2022           silc_hash_table_add(list, (void *)3, tmp2);
2023         }
2024       }
2025
2026       tmp = silc_argument_get_next_arg(args, &type, &len);
2027     }
2028   }
2029
2030   /* Delete information to invite list */
2031   if (action == 0x01 && list) {
2032     /* Now delete the arguments from invite list */
2033     tmp = silc_argument_get_first_arg(args, &type, &len);
2034     while (tmp) {
2035       if (type == 1) {
2036         /* Check validity of the string */
2037         if (!silc_utf8_valid(tmp, len)) {
2038           tmp = silc_argument_get_next_arg(args, &type, &len);
2039           continue;
2040         }
2041
2042         /* Delete from the list */
2043         silc_hash_table_list(list, &htl);
2044         while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) {
2045           if (type == 1 && silc_string_match(tmp2->data, tmp)) {
2046             silc_hash_table_del_by_context(list, (void *)1, tmp2);
2047             break;
2048           }
2049         }
2050         silc_hash_table_list_reset(&htl);
2051
2052       } else if (type == 2) {
2053         /* Public key. */
2054         SilcPublicKey pk;
2055
2056         /* Verify validity of the public key */
2057         if (!silc_pkcs_public_key_payload_decode(tmp, len, &pk)) {
2058           tmp = silc_argument_get_next_arg(args, &type, &len);
2059           continue;
2060         }
2061         silc_pkcs_public_key_free(pk);
2062
2063         /* Delete from the invite list */
2064         silc_hash_table_list(list, &htl);
2065         while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) {
2066           if (type == 2 && !memcmp(tmp2->data, tmp, len)) {
2067             silc_hash_table_del_by_context(list, (void *)2, tmp2);
2068             break;
2069           }
2070         }
2071         silc_hash_table_list_reset(&htl);
2072
2073       } else if (type == 3) {
2074         /* Client ID */
2075
2076         /* Delete from the invite list */
2077         silc_hash_table_list(list, &htl);
2078         while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) {
2079           if (type == 3 && !memcmp(tmp2->data, tmp, len)) {
2080             silc_hash_table_del_by_context(list, (void *)3, tmp2);
2081             break;
2082           }
2083         }
2084         silc_hash_table_list_reset(&htl);
2085       }
2086
2087       tmp = silc_argument_get_next_arg(args, &type, &len);
2088     }
2089   }
2090
2091   return TRUE;
2092 }
2093
2094 /* Destructor for invite and ban list entrys */
2095
2096 void silc_server_inviteban_destruct(void *key, void *context,
2097                                     void *user_context)
2098 {
2099   silc_buffer_free(context);
2100 }
2101
2102 /* Creates connections accoring to configuration. */
2103
2104 void silc_server_create_connections(SilcServer server)
2105 {
2106   silc_schedule_task_del_by_callback(server->schedule,
2107                                      silc_server_connect_to_router);
2108   silc_schedule_task_add(server->schedule, 0,
2109                          silc_server_connect_to_router, server, 0, 1,
2110                          SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
2111 }
2112
2113 static void
2114 silc_server_process_channel_pk_destruct(void *key, void *context,
2115                                         void *user_context)
2116 {
2117   silc_free(key);
2118   silc_pkcs_public_key_free(context);
2119 }
2120
2121 /* Processes a channel public key, either adds or removes it. */
2122
2123 SilcStatus
2124 silc_server_process_channel_pk(SilcServer server,
2125                                SilcChannelEntry channel,
2126                                SilcUInt32 type, const unsigned char *pk,
2127                                SilcUInt32 pk_len)
2128 {
2129   unsigned char pkhash[20];
2130   SilcPublicKey chpk;
2131
2132   SILC_LOG_DEBUG(("Processing channel public key"));
2133
2134   if (!pk || !pk_len)
2135     return SILC_STATUS_ERR_NOT_ENOUGH_PARAMS;
2136
2137   /* Decode the public key */
2138   if (!silc_pkcs_public_key_payload_decode((unsigned char *)pk, pk_len, &chpk))
2139     return SILC_STATUS_ERR_UNSUPPORTED_PUBLIC_KEY;
2140
2141   /* Create channel public key list (hash table) if needed */
2142   if (!channel->channel_pubkeys) {
2143     channel->channel_pubkeys =
2144       silc_hash_table_alloc(0, silc_hash_data, (void *)20,
2145                             silc_hash_data_compare, (void *)20,
2146                             silc_server_process_channel_pk_destruct, channel,
2147                             TRUE);
2148   }
2149
2150   /* Create SHA-1 digest of the public key data */
2151   silc_hash_make(server->sha1hash, pk + 4, pk_len - 4, pkhash);
2152
2153   if (type == 0x00) {
2154     /* Add new public key to channel public key list */
2155     SILC_LOG_DEBUG(("Add new channel public key to channel %s",
2156                     channel->channel_name));
2157
2158     /* Check for resource limit */
2159     if (silc_hash_table_count(channel->channel_pubkeys) > 64) {
2160       silc_pkcs_public_key_free(chpk);
2161       return SILC_STATUS_ERR_RESOURCE_LIMIT;
2162     }
2163
2164     /* Add if doesn't exist already */
2165     if (!silc_hash_table_find(channel->channel_pubkeys, pkhash,
2166                               NULL, NULL))
2167       silc_hash_table_add(channel->channel_pubkeys, silc_memdup(pkhash, 20),
2168                           chpk);
2169   } else if (type == 0x01) {
2170     /* Delete public key from channel public key list */
2171     SILC_LOG_DEBUG(("Delete a channel public key from channel %s",
2172                     channel->channel_name));
2173     if (!silc_hash_table_del(channel->channel_pubkeys, pkhash))
2174       silc_pkcs_public_key_free(chpk);
2175   } else {
2176     silc_pkcs_public_key_free(chpk);
2177     return SILC_STATUS_ERR_NOT_ENOUGH_PARAMS;
2178   }
2179
2180   return SILC_STATUS_OK;
2181 }
2182
2183 /* Returns the channel public keys as Argument List payload. */
2184
2185 SilcBuffer silc_server_get_channel_pk_list(SilcServer server,
2186                                            SilcChannelEntry channel,
2187                                            bool announce,
2188                                            bool delete)
2189 {
2190   SilcHashTableList htl;
2191   SilcBuffer list, pkp;
2192   SilcPublicKey pk;
2193
2194   SILC_LOG_DEBUG(("Encoding channel public keys list"));
2195
2196   if (!channel->channel_pubkeys ||
2197       !silc_hash_table_count(channel->channel_pubkeys))
2198     return NULL;
2199
2200   /* Encode the list */
2201   list = silc_buffer_alloc_size(2);
2202   silc_buffer_format(list,
2203                      SILC_STR_UI_SHORT(silc_hash_table_count(
2204                                        channel->channel_pubkeys)),
2205                      SILC_STR_END);
2206
2207   silc_hash_table_list(channel->channel_pubkeys, &htl);
2208   while (silc_hash_table_get(&htl, NULL, (void *)&pk)) {
2209     pkp = silc_pkcs_public_key_payload_encode(pk);
2210     list = silc_argument_payload_encode_one(list, pkp->data, pkp->len,
2211                                             announce ? 0x03 :
2212                                             delete ? 0x01 : 0x00);
2213     silc_buffer_free(pkp);
2214   }
2215   silc_hash_table_list_reset(&htl);
2216
2217   return list;
2218 }
2219
2220 /* Sets the channel public keys into channel from the list of public keys. */
2221
2222 SilcStatus silc_server_set_channel_pk_list(SilcServer server,
2223                                            SilcSocketConnection sender,
2224                                            SilcChannelEntry channel,
2225                                            const unsigned char *pklist,
2226                                            SilcUInt32 pklist_len)
2227 {
2228   SilcUInt16 argc;
2229   SilcArgumentPayload args;
2230   unsigned char *chpk;
2231   SilcUInt32 chpklen, type;
2232   SilcStatus ret = SILC_STATUS_OK;
2233
2234   SILC_LOG_DEBUG(("Setting channel public keys list"));
2235
2236   if (!pklist || pklist_len < 2)
2237     return SILC_STATUS_ERR_NOT_ENOUGH_PARAMS;
2238
2239   /* Get the argument from the Argument List Payload */
2240   SILC_GET16_MSB(argc, pklist);
2241   args = silc_argument_payload_parse(pklist + 2, pklist_len - 2, argc);
2242   if (!args)
2243     return SILC_STATUS_ERR_NOT_ENOUGH_PARAMS;
2244
2245   /* Process the public keys one by one */
2246   chpk = silc_argument_get_first_arg(args, &type, &chpklen);
2247
2248   /* If announcing keys and we have them set already, do not allow this */
2249   if (chpk && type == 0x03 && channel->channel_pubkeys &&
2250       server->server_type == SILC_ROUTER &&
2251       sender != SILC_PRIMARY_ROUTE(server)) {
2252     SILC_LOG_DEBUG(("Channel public key list set already, enforce our list"));
2253     silc_argument_payload_free(args);
2254     return SILC_STATUS_ERR_OPERATION_ALLOWED;
2255   }
2256
2257   /* If we are normal server and receive announcement list and we already
2258      have keys set, we replace the old list with the announced one. */
2259   if (chpk && type == 0x03 && channel->channel_pubkeys &&
2260       server->server_type != SILC_ROUTER) {
2261     SilcBuffer sidp;
2262     unsigned char mask[4], ulimit[4];
2263
2264     SILC_LOG_DEBUG(("Router enforces its list, remove old list"));
2265     silc_hash_table_free(channel->channel_pubkeys);
2266     channel->channel_pubkeys = NULL;
2267
2268     /* Send notify that removes the old list */
2269     sidp = silc_id_payload_encode(server->id, SILC_ID_SERVER);
2270     SILC_PUT32_MSB((channel->mode & (~SILC_CHANNEL_MODE_CHANNEL_AUTH)), mask);
2271     if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
2272       SILC_PUT32_MSB(channel->user_limit, ulimit);
2273     silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
2274                                        SILC_NOTIFY_TYPE_CMODE_CHANGE, 8,
2275                                        sidp->data, sidp->len,
2276                                        mask, 4,
2277                                        channel->cipher,
2278                                        channel->cipher ?
2279                                        strlen(channel->cipher) : 0,
2280                                        channel->hmac_name,
2281                                        channel->hmac_name ?
2282                                        strlen(channel->hmac_name) : 0,
2283                                        channel->passphrase,
2284                                        channel->passphrase ?
2285                                        strlen(channel->passphrase) : 0,
2286                                        NULL, 0, NULL, 0,
2287                                        (channel->mode &
2288                                         SILC_CHANNEL_MODE_ULIMIT ?
2289                                         ulimit : NULL),
2290                                        (channel->mode &
2291                                         SILC_CHANNEL_MODE_ULIMIT ?
2292                                         sizeof(ulimit) : 0));
2293     silc_buffer_free(sidp);
2294   }
2295
2296   while (chpk) {
2297     if (type == 0x03)
2298       type = 0x00;
2299     ret = silc_server_process_channel_pk(server, channel, type,
2300                                          chpk, chpklen);
2301     if (ret != SILC_STATUS_OK)
2302       break;
2303     chpk = silc_argument_get_next_arg(args, &type, &chpklen);
2304   }
2305
2306   silc_argument_payload_free(args);
2307   return ret;
2308 }
2309
2310 /* Verifies the Authentication Payload `auth' with one of the public keys
2311    on the `channel' public key list. */
2312
2313 bool silc_server_verify_channel_auth(SilcServer server,
2314                                      SilcChannelEntry channel,
2315                                      SilcClientID *client_id,
2316                                      const unsigned char *auth,
2317                                      SilcUInt32 auth_len)
2318 {
2319   SilcAuthPayload ap;
2320   SilcPublicKey chpk;
2321   unsigned char *pkhash;
2322   SilcUInt32 pkhash_len;
2323   bool ret = FALSE;
2324
2325   SILC_LOG_DEBUG(("Verifying channel authentication"));
2326
2327   if (!auth || !auth_len || !channel->channel_pubkeys)
2328     return FALSE;
2329
2330   /* Get the hash from the auth data which tells us what public key we
2331      must use in verification. */
2332
2333   ap = silc_auth_payload_parse(auth, auth_len);
2334   if (!ap)
2335     return FALSE;
2336
2337   pkhash = silc_auth_get_public_data(ap, &pkhash_len);
2338   if (pkhash_len < 128)
2339     goto out;
2340
2341   /* Find the public key with the hash */
2342   if (!silc_hash_table_find(channel->channel_pubkeys, pkhash,
2343                             NULL, (void *)&chpk)) {
2344     SILC_LOG_DEBUG(("Public key not found in channel public key list"));
2345     goto out;
2346   }
2347
2348   /* Verify the signature */
2349   if (!silc_auth_verify(ap, SILC_AUTH_PUBLIC_KEY, (void *)chpk, 0,
2350                         server->sha1hash, client_id, SILC_ID_CLIENT)) {
2351     SILC_LOG_DEBUG(("Authentication failed"));
2352     goto out;
2353   }
2354
2355   ret = TRUE;
2356
2357  out:
2358   silc_auth_payload_free(ap);
2359   return ret;
2360 }