Fixed memory leaks around the tree.
[silc.git] / apps / silcd / packet_receive.c
1 /*
2
3   packet_receive.c
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 1997 - 2002 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; either version 2 of the License, or
12   (at your option) any later version.
13   
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18
19 */
20 /*
21  * Server packet routines to handle received packets.
22  */
23 /* $Id$ */
24
25 #include "serverincludes.h"
26 #include "server_internal.h"
27
28 /* Received notify packet. Server can receive notify packets from router. 
29    Server then relays the notify messages to clients if needed. */
30
31 void silc_server_notify(SilcServer server,
32                         SilcSocketConnection sock,
33                         SilcPacketContext *packet)
34 {
35   SilcNotifyPayload payload;
36   SilcNotifyType type;
37   SilcArgumentPayload args;
38   SilcChannelID *channel_id = NULL, *channel_id2;
39   SilcClientID *client_id, *client_id2;
40   SilcServerID *server_id;
41   SilcIdType id_type;
42   SilcChannelEntry channel = NULL;
43   SilcClientEntry client = NULL, client2 = NULL;
44   SilcServerEntry server_entry = NULL;
45   SilcChannelClientEntry chl;
46   SilcIDCacheEntry cache = NULL;
47   SilcHashTableList htl;
48   SilcUInt32 mode;
49   unsigned char *tmp;
50   SilcUInt32 tmp_len;
51   bool local;
52
53   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
54       packet->src_id_type != SILC_ID_SERVER || !packet->dst_id) {
55     SILC_LOG_DEBUG(("Bad notify packet received"));
56     return;
57   }
58
59   /* If the packet is destined directly to a client then relay the packet
60      before processing it. */
61   if (packet->dst_id_type == SILC_ID_CLIENT) {
62     SilcIDListData idata;
63     SilcSocketConnection dst_sock;
64
65     /* Get the route to the client */
66     dst_sock = silc_server_get_client_route(server, packet->dst_id,
67                                             packet->dst_id_len, NULL, 
68                                             &idata, NULL);
69     if (dst_sock)
70       /* Relay the packet */
71       silc_server_relay_packet(server, dst_sock, idata->send_key,
72                                idata->hmac_send, idata->psn_send++,
73                                packet, TRUE);
74   }
75
76   /* Parse the Notify Payload */
77   payload = silc_notify_payload_parse(packet->buffer->data,
78                                       packet->buffer->len);
79   if (!payload)
80     return;
81
82   /* If we are router and this packet is not already broadcast packet
83      we will broadcast it. The sending socket really cannot be router or
84      the router is buggy. If this packet is coming from router then it must
85      have the broadcast flag set already and we won't do anything. */
86   if (server->server_type == SILC_ROUTER &&
87       sock->type == SILC_SOCKET_TYPE_SERVER &&
88       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
89     SILC_LOG_DEBUG(("Broadcasting received Notify packet"));
90     if (packet->dst_id_type == SILC_ID_CHANNEL) {
91       /* Packet is destined to channel */
92       channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
93                                   packet->dst_id_type);
94       if (!channel_id)
95         goto out;
96
97       silc_server_packet_send_dest(server, SILC_PRIMARY_ROUTE(server), 
98                                    packet->type, packet->flags | 
99                                    SILC_PACKET_FLAG_BROADCAST, 
100                                    channel_id, SILC_ID_CHANNEL,
101                                    packet->buffer->data, 
102                                    packet->buffer->len, FALSE);
103       silc_server_backup_send_dest(server, sock->user_data, 
104                                    packet->type, packet->flags,
105                                    channel_id, SILC_ID_CHANNEL,
106                                    packet->buffer->data, packet->buffer->len, 
107                                    FALSE, TRUE);
108     } else {
109       /* Packet is destined to client or server */
110       silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server), 
111                               packet->type,
112                               packet->flags | SILC_PACKET_FLAG_BROADCAST, 
113                               packet->buffer->data, packet->buffer->len, 
114                               FALSE);
115       silc_server_backup_send(server, sock->user_data,
116                               packet->type, packet->flags,
117                               packet->buffer->data, packet->buffer->len, 
118                               FALSE, TRUE);
119     }
120   }
121
122   type = silc_notify_get_type(payload);
123   args = silc_notify_get_args(payload);
124   if (!args)
125     goto out;
126
127   switch(type) {
128   case SILC_NOTIFY_TYPE_JOIN:
129     /* 
130      * Distribute the notify to local clients on the channel
131      */
132     SILC_LOG_DEBUG(("JOIN notify"));
133
134     if (channel_id)
135       silc_free(channel_id);
136
137     /* Get Channel ID */
138     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
139     if (!tmp)
140       goto out;
141     channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
142     if (!channel_id)
143       goto out;
144
145     /* Get channel entry */
146     channel = silc_idlist_find_channel_by_id(server->global_list, 
147                                              channel_id, NULL);
148     if (!channel) {
149       channel = silc_idlist_find_channel_by_id(server->local_list, 
150                                                channel_id, NULL);
151       if (!channel) {
152         SILC_LOG_DEBUG(("Notify for unknown channel"));
153         silc_free(channel_id);
154         goto out;
155       }
156     }
157     silc_free(channel_id);
158
159     /* Get client ID */
160     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
161     if (!tmp)
162       goto out;
163     client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
164     if (!client_id)
165       goto out;
166
167     /* If the the client is not in local list we check global list (ie. the
168        channel will be global channel) and if it does not exist then create
169        entry for the client. */
170     client = silc_idlist_find_client_by_id(server->global_list, 
171                                            client_id, server->server_type, 
172                                            &cache);
173     if (!client) {
174       client = silc_idlist_find_client_by_id(server->local_list, 
175                                              client_id, server->server_type,
176                                              &cache);
177       if (!client) {
178         /* If router did not find the client the it is bogus */
179         if (server->server_type != SILC_SERVER) {
180           silc_free(client_id);
181           goto out;
182         }
183
184         client = 
185           silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
186                                  silc_id_dup(client_id, SILC_ID_CLIENT), 
187                                  sock->user_data, NULL, 0);
188         if (!client) {
189           SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
190           silc_free(client_id);
191           goto out;
192         }
193
194         client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
195       }
196     }
197     silc_free(client_id);
198
199     /* Do not process the notify if the client is not registered */
200     if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
201       break;
202
203     /* Do not add client to channel if it is there already */
204     if (silc_server_client_on_channel(client, channel, NULL)) {
205       SILC_LOG_DEBUG(("Client already on channel %s",
206                       channel->channel_name));
207       break;
208     }
209
210     /* Send to channel */
211     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
212                                        FALSE, packet->buffer->data, 
213                                        packet->buffer->len, FALSE);
214
215     if (server->server_type != SILC_ROUTER && 
216         sock->type == SILC_SOCKET_TYPE_ROUTER)
217       /* The channel is global now */
218       channel->global_users = TRUE;
219
220     SILC_LOG_DEBUG(("Joining to channel %s", channel->channel_name));
221
222     /* JOIN the global client to the channel (local clients (if router 
223        created the channel) is joined in the pending JOIN command). */
224     chl = silc_calloc(1, sizeof(*chl));
225     chl->client = client;
226     chl->channel = channel;
227
228     if (server->server_type != SILC_ROUTER ||
229         sock->type == SILC_SOCKET_TYPE_ROUTER) {
230       /* If this is the first one on the channel then it is the founder of
231          the channel. This is done on normal server and on router if this
232          notify is coming from router */
233       if (!silc_hash_table_count(channel->user_list)) {
234         SILC_LOG_DEBUG(("Client %s is founder on channel",
235                         silc_id_render(chl->client->id, SILC_ID_CLIENT)));
236         chl->mode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
237       }
238     }
239
240     silc_hash_table_add(channel->user_list, client, chl);
241     silc_hash_table_add(client->channels, channel, chl);
242     channel->user_count++;
243     channel->disabled = FALSE;
244
245     /* Make sure we don't expire clients that are on channel */
246     if (cache)
247       cache->expire = 0;
248
249     /* Update statistics */
250     if (server->server_type == SILC_ROUTER) {
251       if (sock->type != SILC_SOCKET_TYPE_ROUTER)
252         server->stat.cell_chanclients++;
253       server->stat.chanclients++;
254     }
255
256     break;
257
258   case SILC_NOTIFY_TYPE_LEAVE:
259     /* 
260      * Distribute the notify to local clients on the channel
261      */
262     SILC_LOG_DEBUG(("LEAVE notify"));
263
264     if (!channel_id) {
265       channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
266                                   packet->dst_id_type);
267       if (!channel_id)
268         goto out;
269     }
270
271     /* Get channel entry */
272     channel = silc_idlist_find_channel_by_id(server->global_list, 
273                                              channel_id, NULL);
274     if (!channel) { 
275       channel = silc_idlist_find_channel_by_id(server->local_list, 
276                                                channel_id, NULL);
277       if (!channel) {
278         SILC_LOG_DEBUG(("Notify for unknown channel"));
279         silc_free(channel_id);
280         goto out;
281       }
282     }
283
284     /* Get client ID */
285     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
286     if (!tmp) {
287       silc_free(channel_id);
288       goto out;
289     }
290     client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
291     if (!client_id) {
292       silc_free(channel_id);
293       goto out;
294     }
295
296     /* Get client entry */
297     client = silc_idlist_find_client_by_id(server->global_list, 
298                                            client_id, TRUE, NULL);
299     if (!client) {
300       client = silc_idlist_find_client_by_id(server->local_list, 
301                                              client_id, TRUE, NULL);
302       if (!client) {
303         silc_free(client_id);
304         silc_free(channel_id);
305         goto out;
306       }
307     }
308     silc_free(client_id);
309     silc_free(channel_id);
310
311     /* Check if on channel */
312     if (!silc_server_client_on_channel(client, channel, NULL))
313       break;
314
315     /* Send the leave notify to channel */
316     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
317                                        FALSE, packet->buffer->data, 
318                                        packet->buffer->len, FALSE);
319
320     /* Remove the user from channel */
321     silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
322     break;
323
324   case SILC_NOTIFY_TYPE_SIGNOFF:
325     /* 
326      * Distribute the notify to local clients on the channel
327      */
328     SILC_LOG_DEBUG(("SIGNOFF notify"));
329
330     /* Get client ID */
331     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
332     if (!tmp)
333       goto out;
334     client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
335     if (!client_id)
336       goto out;
337
338     /* Get client entry */
339     client = silc_idlist_find_client_by_id(server->global_list, 
340                                            client_id, TRUE, &cache);
341     if (!client) {
342       client = silc_idlist_find_client_by_id(server->local_list, 
343                                              client_id, TRUE, &cache);
344       if (!client) {
345         silc_free(client_id);
346         goto out;
347       }
348     }
349     silc_free(client_id);
350
351     /* Get signoff message */
352     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
353     if (tmp_len > 128)
354       tmp = NULL;
355
356     /* Update statistics */
357     server->stat.clients--;
358     if (server->stat.cell_clients)
359       server->stat.cell_clients--;
360     SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
361     SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
362     silc_schedule_task_del_by_context(server->schedule, client);
363
364     /* Remove the client from all channels. */
365     silc_server_remove_from_channels(server, NULL, client, TRUE, tmp, FALSE);
366
367     /* Check if anyone is watching this nickname */
368     if (server->server_type == SILC_ROUTER)
369       silc_server_check_watcher_list(server, client, NULL,
370                                      SILC_NOTIFY_TYPE_SIGNOFF);
371
372     /* Remove this client from watcher list if it is */
373     silc_server_del_from_watcher_list(server, client);
374
375     client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
376     cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
377     break;
378
379   case SILC_NOTIFY_TYPE_TOPIC_SET:
380     /* 
381      * Distribute the notify to local clients on the channel
382      */
383
384     SILC_LOG_DEBUG(("TOPIC SET notify"));
385
386     /* Get client ID */
387     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
388     if (!tmp)
389       goto out;
390     client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
391     if (!client_id)
392       goto out;
393
394     /* Get client entry */
395     if (id_type == SILC_ID_CLIENT) {
396       client = silc_idlist_find_client_by_id(server->global_list, 
397                                              client_id, TRUE, &cache);
398       if (!client) {
399         client = silc_idlist_find_client_by_id(server->local_list, 
400                                                client_id, TRUE, &cache);
401         if (!client) {
402           silc_free(client_id);
403           goto out;
404         }
405       }
406       silc_free(client_id);
407     }
408
409     /* Get the topic */
410     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
411     if (!tmp) {
412       silc_free(channel_id);
413       goto out;
414     }
415
416     if (!channel_id) {
417       channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
418                                   packet->dst_id_type);
419       if (!channel_id)
420         goto out;
421     }
422
423     /* Get channel entry */
424     channel = silc_idlist_find_channel_by_id(server->global_list, 
425                                              channel_id, NULL);
426     if (!channel) {
427       channel = silc_idlist_find_channel_by_id(server->local_list, 
428                                                channel_id, NULL);
429       if (!channel) {
430         SILC_LOG_DEBUG(("Notify for unknown channel"));
431         silc_free(channel_id);
432         goto out;
433       }
434     }
435     silc_free(channel_id);
436
437     if (channel->topic && !strcmp(channel->topic, tmp)) {
438       SILC_LOG_DEBUG(("Topic is already set and same"));
439       goto out;
440     }
441
442     if (client) {
443       /* Get user's channel entry and check that topic set is allowed. */
444       if (!silc_server_client_on_channel(client, channel, &chl))
445         goto out;
446       if (channel->mode & SILC_CHANNEL_MODE_TOPIC &&
447           !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
448           !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
449         SILC_LOG_DEBUG(("Topic change is not allowed"));
450         goto out;
451       }
452     }
453
454     /* Change the topic */
455     silc_free(channel->topic);
456     channel->topic = strdup(tmp);
457
458     /* Send the same notify to the channel */
459     silc_server_packet_send_to_channel(server, NULL, channel, packet->type, 
460                                        FALSE, packet->buffer->data, 
461                                        packet->buffer->len, FALSE);
462     break;
463
464   case SILC_NOTIFY_TYPE_NICK_CHANGE:
465     {
466       /* 
467        * Distribute the notify to local clients on the channel
468        */
469       unsigned char *id, *id2;
470       char *nickname;
471       SilcUInt32 nickname_len;
472
473       SILC_LOG_DEBUG(("NICK CHANGE notify"));
474       
475       /* Get old client ID */
476       id = silc_argument_get_arg_type(args, 1, &tmp_len);
477       if (!id)
478         goto out;
479       client_id = silc_id_payload_parse_id(id, tmp_len, NULL);
480       if (!client_id)
481         goto out;
482       
483       /* Get new client ID */
484       id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
485       if (!id2)
486         goto out;
487       client_id2 = silc_id_payload_parse_id(id2, tmp_len, NULL);
488       if (!client_id2) {
489         silc_free(client_id);
490         goto out;
491       }
492       
493       SILC_LOG_DEBUG(("Old Client ID id(%s)", 
494                       silc_id_render(client_id, SILC_ID_CLIENT)));
495       SILC_LOG_DEBUG(("New Client ID id(%s)", 
496                       silc_id_render(client_id2, SILC_ID_CLIENT)));
497
498       /* From protocol version 1.1 we also get the new nickname */
499       nickname = silc_argument_get_arg_type(args, 3, &nickname_len);;
500
501       /* Replace the Client ID */
502       client = silc_idlist_replace_client_id(server,
503                                              server->global_list, client_id,
504                                              client_id2, nickname);
505       if (!client)
506         client = silc_idlist_replace_client_id(server,
507                                                server->local_list, client_id, 
508                                                client_id2, nickname);
509
510       if (client) {
511         /* Send the NICK_CHANGE notify type to local clients on the channels
512            this client is joined to. */
513         silc_server_send_notify_on_channels(server, client, client,
514                                             SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
515                                             id, tmp_len, id2, tmp_len,
516                                             nickname, nickname ?
517                                             nickname_len : 0);
518       }
519
520       silc_free(client_id);
521       if (!client)
522         silc_free(client_id2);
523       break;
524     }
525
526   case SILC_NOTIFY_TYPE_CMODE_CHANGE:
527     /* 
528      * Distribute the notify to local clients on the channel
529      */
530
531     SILC_LOG_DEBUG(("CMODE CHANGE notify"));
532
533     /* Get client ID */
534     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
535     if (!tmp)
536       goto out;
537     client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
538     if (!client_id)
539       goto out;
540
541     /* Get client entry */
542     if (id_type == SILC_ID_CLIENT) {
543       client = silc_idlist_find_client_by_id(server->global_list, 
544                                              client_id, TRUE, &cache);
545       if (!client) {
546         client = silc_idlist_find_client_by_id(server->local_list, 
547                                                client_id, TRUE, &cache);
548         if (!client) {
549           silc_free(client_id);
550           goto out;
551         }
552       }
553     }
554     silc_free(client_id);
555
556     if (!channel_id) {
557       channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
558                                   packet->dst_id_type);
559       if (!channel_id)
560         goto out;
561     }
562
563     /* Get channel entry */
564     channel = silc_idlist_find_channel_by_id(server->global_list, 
565                                              channel_id, NULL);
566     if (!channel) {
567       channel = silc_idlist_find_channel_by_id(server->local_list, 
568                                                channel_id, NULL);
569       if (!channel) {
570         SILC_LOG_DEBUG(("Notify for unknown channel"));
571         silc_free(channel_id);
572         goto out;
573       }
574     }
575     silc_free(channel_id);
576
577     /* Get the mode */
578     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
579     if (!tmp)
580       goto out;
581     SILC_GET32_MSB(mode, tmp);
582
583     /* Check if mode changed */
584     if (channel->mode == mode) {
585       SILC_LOG_DEBUG(("Mode is changed already"));
586
587       /* If this mode change has founder mode then we'll enforce the
588          change so that the server gets the real founder public key */
589       if (server->server_type != SILC_SERVER &&
590           sock != SILC_PRIMARY_ROUTE(server) &&
591           mode & SILC_CHANNEL_MODE_FOUNDER_AUTH && channel->founder_key) {
592         SILC_LOG_DEBUG(("Sending founder public key to server"));
593         silc_server_send_notify_cmode(server, sock, FALSE, channel,
594                                       channel->mode, server->id,
595                                       SILC_ID_SERVER, channel->cipher,
596                                       channel->hmac_name,
597                                       channel->passphrase,
598                                       channel->founder_key);
599       }
600
601       /* If we received same mode from our primary check whether founder
602          mode and key in the notify is set.  We update the founder key
603          here since we may have wrong one */
604       if (server->server_type == SILC_SERVER &&
605           sock == SILC_PRIMARY_ROUTE(server) &&
606           mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
607         SILC_LOG_DEBUG(("Founder public key received from router"));
608         tmp = silc_argument_get_arg_type(args, 6, &tmp_len);
609         if (!tmp)
610           break;
611
612         if (channel->founder_key)
613           silc_pkcs_public_key_free(channel->founder_key);
614         channel->founder_key = NULL;
615         silc_pkcs_public_key_decode(tmp, tmp_len, &channel->founder_key);
616       }
617
618       break;
619     }
620
621     /* Get user's channel entry and check that mode change is allowed */
622     if (client) {
623       if (!silc_server_client_on_channel(client, channel, &chl))
624         goto out;
625       if (!silc_server_check_cmode_rights(server, channel, chl, mode)) {
626         SILC_LOG_DEBUG(("CMODE change is not allowed"));
627         silc_server_send_notify_cmode(server, sock, FALSE, channel,
628                                       channel->mode, server->id,
629                                       SILC_ID_SERVER, channel->cipher,
630                                       channel->hmac_name,
631                                       channel->passphrase,
632                                       channel->founder_key);
633         goto out;
634       }
635     } else {
636       /* Assure that server is not removing founder mode from us */
637       if (server->server_type == SILC_ROUTER &&
638           sock != SILC_PRIMARY_ROUTE(server) &&
639           channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH &&
640           !(mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
641         SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
642         silc_server_send_notify_cmode(server, sock, FALSE, channel,
643                                       channel->mode, server->id,
644                                       SILC_ID_SERVER, channel->cipher,
645                                       channel->hmac_name,
646                                       channel->passphrase,
647                                       channel->founder_key);
648         goto out;
649       }
650
651       /* If server is adding founder mode, check whether there is founder
652          on channel already and is not from this server */
653       if (server->server_type == SILC_ROUTER &&
654           sock != SILC_PRIMARY_ROUTE(server) &&
655           mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
656         silc_hash_table_list(channel->user_list, &htl);
657         while (silc_hash_table_get(&htl, NULL, (void *)&chl))
658           if (chl->mode & SILC_CHANNEL_UMODE_CHANFO &&
659               chl->client->router != sock->user_data) {
660             SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
661             silc_server_send_notify_cmode(server, sock, FALSE, channel,
662                                           channel->mode, server->id,
663                                           SILC_ID_SERVER, channel->cipher,
664                                           channel->hmac_name,
665                                           channel->passphrase,
666                                           channel->founder_key);
667             silc_hash_table_list_reset(&htl);
668             goto out;
669           }
670         silc_hash_table_list_reset(&htl);
671       }
672     }
673
674     /* If the channel had private keys set and the mode was removed then
675        we must re-generate and re-distribute a new channel key */
676     if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY &&
677         !(mode & SILC_CHANNEL_MODE_PRIVKEY)) {
678       /* Re-generate channel key */
679       if (!silc_server_create_channel_key(server, channel, 0))
680         goto out;
681       
682       /* Send the channel key. This sends it to our local clients and if
683          we are normal server to our router as well. */
684       silc_server_send_channel_key(server, NULL, channel, 
685                                    server->server_type == SILC_ROUTER ? 
686                                    FALSE : !server->standalone);
687     }
688
689     /* Get the hmac */
690     tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
691     if (tmp) {
692       unsigned char hash[32];
693
694       if (channel->hmac)
695         silc_hmac_free(channel->hmac);
696       if (!silc_hmac_alloc(tmp, NULL, &channel->hmac))
697         goto out;
698
699       /* Set the HMAC key out of current channel key. The client must do
700          this locally. */
701       silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, 
702                      channel->key_len / 8, hash);
703       silc_hmac_set_key(channel->hmac, hash, 
704                         silc_hash_len(silc_hmac_get_hash(channel->hmac)));
705       memset(hash, 0, sizeof(hash));
706     }
707
708     /* Get the passphrase */
709     tmp = silc_argument_get_arg_type(args, 5, &tmp_len);
710     if (tmp) {
711       silc_free(channel->passphrase);
712       channel->passphrase = silc_memdup(tmp, tmp_len);
713     }
714
715     /* Get founder public key */
716     tmp = silc_argument_get_arg_type(args, 6, &tmp_len);
717     if (tmp && mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
718       if (channel->founder_key)
719         silc_pkcs_public_key_free(channel->founder_key);
720       channel->founder_key = NULL;
721       silc_pkcs_public_key_decode(tmp, tmp_len, &channel->founder_key);
722
723       if (!channel->founder_key || 
724           (client && client->data.public_key && 
725            server->server_type == SILC_ROUTER &&
726            !silc_pkcs_public_key_compare(channel->founder_key,
727                                          client->data.public_key))) {
728         /* A really buggy server isn't checking public keys correctly.
729            It's not possible that the mode setter and founder wouldn't
730            have same public key. */
731         SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
732
733         mode &= ~SILC_CHANNEL_MODE_FOUNDER_AUTH;
734         silc_server_send_notify_cmode(server, sock, FALSE, channel,
735                                       mode, server->id, SILC_ID_SERVER,
736                                       channel->cipher, 
737                                       channel->hmac_name,
738                                       channel->passphrase, NULL);
739         if (channel->founder_key)
740           silc_pkcs_public_key_free(channel->founder_key);
741         channel->founder_key = NULL;
742       } else if (client && !client->data.public_key) {
743         client->data.public_key = 
744           silc_pkcs_public_key_copy(channel->founder_key);
745       }
746     }
747
748     if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH && !channel->founder_key &&
749         server->server_type == SILC_ROUTER) {
750       SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
751       mode &= ~SILC_CHANNEL_MODE_FOUNDER_AUTH;
752       silc_server_send_notify_cmode(server, sock, FALSE, channel,
753                                     mode, server->id, SILC_ID_SERVER,
754                                     channel->cipher, 
755                                     channel->hmac_name,
756                                     channel->passphrase, NULL);
757     }
758
759     /* Send the same notify to the channel */
760     silc_server_packet_send_to_channel(server, NULL, channel, packet->type, 
761                                        FALSE, packet->buffer->data, 
762                                        packet->buffer->len, FALSE);
763
764     /* Change mode */
765     channel->mode = mode;
766
767     if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) &&
768         channel->founder_key) {
769       silc_pkcs_public_key_free(channel->founder_key);
770       channel->founder_key = NULL;
771     }
772
773     break;
774
775   case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
776     {
777       /* 
778        * Distribute the notify to local clients on the channel
779        */
780       SilcChannelClientEntry chl2 = NULL;
781       bool notify_sent = FALSE;
782
783       SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
784
785       /* Get client ID */
786       tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
787       if (!tmp)
788         goto out;
789       client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
790       if (!client_id)
791         goto out;
792
793       /* Get client entry */
794       if (id_type == SILC_ID_CLIENT) {
795         client = silc_idlist_find_client_by_id(server->global_list, 
796                                                client_id, TRUE, &cache);
797         if (!client) {
798           client = silc_idlist_find_client_by_id(server->local_list, 
799                                                  client_id, TRUE, &cache);
800           if (!client) {
801             silc_free(client_id);
802             goto out;
803           }
804         }
805       }
806       silc_free(client_id);
807
808       if (!channel_id) {
809         channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
810                                     packet->dst_id_type);
811         if (!channel_id)
812           goto out;
813       }
814
815       /* Get channel entry */
816       channel = silc_idlist_find_channel_by_id(server->global_list, 
817                                                channel_id, NULL);
818       if (!channel) {
819         channel = silc_idlist_find_channel_by_id(server->local_list, 
820                                                  channel_id, NULL);
821         if (!channel) {
822           SILC_LOG_DEBUG(("Notify for unknown channel"));
823           silc_free(channel_id);
824           goto out;
825         }
826       }
827
828       /* Get the mode */
829       tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
830       if (!tmp) {
831         silc_free(channel_id);
832         goto out;
833       }
834       
835       SILC_GET32_MSB(mode, tmp);
836       
837       /* Get target client */
838       tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
839       if (!tmp)
840         goto out;
841       client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
842       if (!client_id)
843         goto out;
844       
845       /* Get client entry */
846       client2 = silc_idlist_find_client_by_id(server->global_list, 
847                                               client_id, TRUE, NULL);
848       if (!client2) {
849         client2 = silc_idlist_find_client_by_id(server->local_list, 
850                                                 client_id, TRUE, NULL);
851         if (!client2) {
852           silc_free(client_id);
853           goto out;
854         }
855       }
856       silc_free(client_id);
857
858       if (client) {
859         /* Check that sender is on channel */
860         if (!silc_server_client_on_channel(client, channel, &chl))
861           goto out;
862         
863         if (client != client2 && server->server_type == SILC_ROUTER) {
864           /* Sender must be operator */
865           if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
866               !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
867             SILC_LOG_DEBUG(("CUMODE change is not allowed"));
868             goto out;
869           }
870
871           if (!silc_server_client_on_channel(client2, channel, &chl))
872             goto out;
873
874           /* If target is founder mode change is not allowed. */
875           if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
876             SILC_LOG_DEBUG(("CUMODE change is not allowed"));
877             goto out;
878           }
879         }
880       }
881
882       /* Get target channel user entry */
883       if (!silc_server_client_on_channel(client2, channel, &chl))
884         goto out;
885
886       if (server->server_type == SILC_SERVER && chl->mode == mode) {
887         SILC_LOG_DEBUG(("Mode is changed already"));
888         break;
889       }
890
891       if (mode & SILC_CHANNEL_UMODE_CHANFO &&
892           !(chl->mode & SILC_CHANNEL_UMODE_CHANFO) &&
893           server->server_type == SILC_ROUTER &&
894           sock != SILC_PRIMARY_ROUTE(server)) {
895         SilcPublicKey founder_key = NULL;
896
897         /* If channel doesn't have founder auth mode then it's impossible
898            that someone would be getting founder rights with CUMODE command.
899            In that case there already either is founder or there isn't
900            founder at all on the channel. */
901         if (client && !(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
902           /* Force the mode to not have founder mode */
903           chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
904           silc_server_force_cumode_change(server, sock, channel, chl, mode);
905           notify_sent = TRUE;
906           break;
907         }
908
909         /* Get the founder of the channel and if found then this client
910            cannot be the founder since there already is one. */
911         silc_hash_table_list(channel->user_list, &htl);
912         while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
913           if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
914             /* If the founder on the channel is not the one whom has set
915                the founder mode, then it's possible that this CUMODE_CHANGE
916                is correct.  Due to netsplits it's possible that this
917                situation happens. */
918             if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) ||
919                 (channel->founder_key && chl2->client->data.public_key &&
920                  silc_pkcs_public_key_compare(
921                                         channel->founder_key,
922                                         chl2->client->data.public_key))) {
923               chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
924               silc_server_force_cumode_change(server, sock, channel,
925                                               chl, mode);
926               notify_sent = TRUE;
927             }
928             break;
929           }
930         silc_hash_table_list_reset(&htl);
931         if (!(mode & SILC_CHANNEL_UMODE_CHANFO))
932           break;
933
934         /* Founder not found of the channel.  Since the founder auth mode
935            is set on the channel now check whether this is the client that
936            originally set the mode. */
937
938         if (channel->founder_key) {
939           /* Get public key that must be present in notify */
940           tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
941           if (!tmp || !silc_pkcs_public_key_decode(tmp, tmp_len,
942                                                    &founder_key)) {
943             chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
944             silc_server_force_cumode_change(server, sock, channel, chl, mode);
945             notify_sent = TRUE;
946             break;
947           }
948
949           /* Now match the public key we have cached and public key sent.
950              They must match. */
951           if (client && client->data.public_key && 
952               !silc_pkcs_public_key_compare(channel->founder_key,
953                                             client->data.public_key)) {
954             chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
955             silc_server_force_cumode_change(server, sock, channel, chl, mode);
956             notify_sent = TRUE;
957             break;
958           }
959           if (!silc_pkcs_public_key_compare(channel->founder_key,
960                                             founder_key)) {
961             chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
962             silc_server_force_cumode_change(server, sock, channel, chl, mode);
963             notify_sent = TRUE;
964             break;
965           }
966         }
967
968         /* There cannot be anyone else as founder on the channel now.  This
969            client is definitely the founder due to this authentication */
970         silc_hash_table_list(channel->user_list, &htl);
971         while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
972           if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
973             chl2->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
974             silc_server_force_cumode_change(server, NULL, channel, chl2,
975                                             chl2->mode);
976             break;
977           }
978         silc_hash_table_list_reset(&htl);
979
980         if (founder_key)
981           silc_pkcs_public_key_free(founder_key);
982       }
983
984       if (server->server_type != SILC_SERVER && chl->mode == mode) {
985         SILC_LOG_DEBUG(("Mode is changed already"));
986         break;
987       }
988
989       SILC_LOG_DEBUG(("Changing %s channel user mode",
990                       chl->client->nickname ? chl->client->nickname :
991                       (unsigned char *)""));
992
993       /* Change the mode */
994       chl->mode = mode;
995
996       /* Send the same notify to the channel */
997       if (!notify_sent)
998         silc_server_packet_send_to_channel(server, NULL, channel,
999                                            packet->type,
1000                                            FALSE, packet->buffer->data,
1001                                            packet->buffer->len, FALSE);
1002       
1003       silc_free(channel_id);
1004       break;
1005     }
1006
1007   case SILC_NOTIFY_TYPE_INVITE:
1008
1009     if (packet->dst_id_type == SILC_ID_CLIENT)
1010       goto out;
1011
1012     SILC_LOG_DEBUG(("INVITE notify"));
1013
1014     /* Get Channel ID */
1015     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1016     if (!tmp)
1017       goto out;
1018     channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1019     if (!channel_id)
1020       goto out;
1021
1022     /* Get channel entry */
1023     channel = silc_idlist_find_channel_by_id(server->global_list, 
1024                                              channel_id, NULL);
1025     if (!channel) {
1026       channel = silc_idlist_find_channel_by_id(server->local_list, 
1027                                                channel_id, NULL);
1028       if (!channel) {
1029         SILC_LOG_DEBUG(("Notify for unknown channel"));
1030         silc_free(channel_id);
1031         goto out;
1032       }
1033     }
1034     silc_free(channel_id);
1035
1036     /* Get client ID */
1037     tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1038     if (!tmp)
1039       goto out;
1040     client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1041     if (!client_id)
1042       goto out;
1043
1044     /* Get client entry */
1045     client = silc_idlist_find_client_by_id(server->global_list, 
1046                                            client_id, TRUE, &cache);
1047     if (!client) {
1048       client = silc_idlist_find_client_by_id(server->local_list, 
1049                                              client_id, TRUE, &cache);
1050       if (!client) {
1051         silc_free(client_id);
1052         goto out;
1053       }
1054     }
1055     silc_free(client_id);
1056
1057     /* Get user's channel entry and check that inviting is allowed. */
1058     if (!silc_server_client_on_channel(client, channel, &chl))
1059       goto out;
1060     if (channel->mode & SILC_CHANNEL_MODE_INVITE &&
1061         !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
1062         !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1063       SILC_LOG_DEBUG(("Inviting is not allowed"));
1064       goto out;
1065     }
1066
1067     /* Get the added invite */
1068     tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
1069     if (tmp) {
1070       if (!channel->invite_list)
1071         channel->invite_list = silc_calloc(tmp_len + 2, 
1072                                            sizeof(*channel->invite_list));
1073       else
1074         channel->invite_list = silc_realloc(channel->invite_list, 
1075                                             sizeof(*channel->invite_list) * 
1076                                             (tmp_len + 
1077                                              strlen(channel->invite_list) + 
1078                                              2));
1079       if (tmp[tmp_len - 1] == ',')
1080         tmp[tmp_len - 1] = '\0';
1081       
1082       strncat(channel->invite_list, tmp, tmp_len);
1083       strncat(channel->invite_list, ",", 1);
1084     }
1085
1086     /* Get the deleted invite */
1087     tmp = silc_argument_get_arg_type(args, 5, &tmp_len);
1088     if (tmp && channel->invite_list) {
1089       char *start, *end, *n;
1090       
1091       if (!strncmp(channel->invite_list, tmp, 
1092                    strlen(channel->invite_list) - 1)) {
1093         silc_free(channel->invite_list);
1094         channel->invite_list = NULL;
1095       } else {
1096         start = strstr(channel->invite_list, tmp);
1097         if (start && strlen(start) >= tmp_len) {
1098           end = start + tmp_len;
1099           n = silc_calloc(strlen(channel->invite_list) - tmp_len, sizeof(*n));
1100           strncat(n, channel->invite_list, start - channel->invite_list);
1101           strncat(n, end + 1, ((channel->invite_list + 
1102                                 strlen(channel->invite_list)) - end) - 1);
1103           silc_free(channel->invite_list);
1104           channel->invite_list = n;
1105         }
1106       }
1107     }
1108
1109     break;
1110
1111   case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
1112     /*
1113      * Distribute to the local clients on the channel and change the
1114      * channel ID.
1115      */
1116
1117     SILC_LOG_DEBUG(("CHANNEL CHANGE"));
1118
1119     if (sock->type != SILC_SOCKET_TYPE_ROUTER)
1120       break;
1121
1122     /* Get the old Channel ID */
1123     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1124     if (!tmp)
1125       goto out;
1126     channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1127     if (!channel_id)
1128       goto out;
1129
1130     /* Get the channel entry */
1131     channel = silc_idlist_find_channel_by_id(server->local_list, 
1132                                              channel_id, NULL);
1133     if (!channel) {
1134       channel = silc_idlist_find_channel_by_id(server->global_list, 
1135                                                channel_id, NULL);
1136       if (!channel) {
1137         SILC_LOG_DEBUG(("Notify for unknown channel"));
1138         silc_free(channel_id);
1139         goto out;
1140       }
1141     }
1142
1143     /* Send the notify to the channel */
1144     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
1145                                        FALSE, packet->buffer->data, 
1146                                        packet->buffer->len, FALSE);
1147
1148     /* Get the new Channel ID */
1149     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1150     if (!tmp)
1151       goto out;
1152     channel_id2 = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1153     if (!channel_id2)
1154       goto out;
1155
1156     SILC_LOG_DEBUG(("Old Channel ID id(%s)", 
1157                     silc_id_render(channel_id, SILC_ID_CHANNEL)));
1158     SILC_LOG_DEBUG(("New Channel ID id(%s)", 
1159                     silc_id_render(channel_id2, SILC_ID_CHANNEL)));
1160
1161     /* Replace the Channel ID */
1162     if (!silc_idlist_replace_channel_id(server->local_list, channel_id,
1163                                         channel_id2))
1164       if (!silc_idlist_replace_channel_id(server->global_list, channel_id,
1165                                           channel_id2)) {
1166         silc_free(channel_id2);
1167         channel_id2 = NULL;
1168       }
1169
1170     if (channel_id2) {
1171       SilcBuffer modes = NULL, users = NULL, users_modes = NULL;
1172
1173       /* Re-announce this channel which ID was changed. */
1174       silc_server_send_new_channel(server, sock, FALSE, channel->channel_name,
1175                                    channel->id, 
1176                                    silc_id_get_len(channel->id, 
1177                                                    SILC_ID_CHANNEL),
1178                                    channel->mode);
1179
1180       /* Re-announce our clients on the channel as the ID has changed now */
1181       silc_server_announce_get_channel_users(server, channel, &modes, &users,
1182                                              &users_modes);
1183       if (users) {
1184         silc_buffer_push(users, users->data - users->head);
1185         silc_server_packet_send(server, sock,
1186                                 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1187                                 users->data, users->len, FALSE);
1188         silc_buffer_free(users);
1189       }
1190       if (modes) {
1191         silc_buffer_push(modes, modes->data - modes->head);
1192         silc_server_packet_send_dest(server, sock,
1193                                      SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1194                                      channel->id, SILC_ID_CHANNEL,
1195                                      modes->data, modes->len, FALSE);
1196         silc_buffer_free(modes);
1197       }
1198       if (users_modes) {
1199         silc_buffer_push(users_modes, users_modes->data - users_modes->head);
1200         silc_server_packet_send_dest(server, sock,
1201                                      SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1202                                      channel->id, SILC_ID_CHANNEL,
1203                                      users_modes->data, 
1204                                      users_modes->len, FALSE);
1205         silc_buffer_free(users_modes);
1206       }
1207
1208       /* Re-announce channel's topic */
1209       if (channel->topic) {
1210         silc_server_send_notify_topic_set(server, sock,
1211                                           server->server_type == SILC_ROUTER ?
1212                                           TRUE : FALSE, channel, 
1213                                           server->id, SILC_ID_SERVER,
1214                                           channel->topic);
1215       }
1216     }
1217
1218     silc_free(channel_id);
1219
1220     break;
1221
1222   case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
1223     /* 
1224      * Remove the server entry and all clients that this server owns.
1225      */
1226
1227     SILC_LOG_DEBUG(("SERVER SIGNOFF notify"));
1228
1229     /* Get Server ID */
1230     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1231     if (!tmp)
1232       goto out;
1233     server_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1234     if (!server_id)
1235       goto out;
1236
1237     /* If the ID is mine, this notify is not allowed. */
1238     if (SILC_ID_SERVER_COMPARE(server_id, server->id)) {
1239       SILC_LOG_DEBUG(("Ignoring my own ID for SERVER_SIGNOFF"));
1240       break;
1241     }
1242
1243     /* Get server entry */
1244     server_entry = silc_idlist_find_server_by_id(server->global_list, 
1245                                                  server_id, TRUE, NULL);
1246     local = FALSE;
1247     if (!server_entry) {
1248       server_entry = silc_idlist_find_server_by_id(server->local_list, 
1249                                                    server_id, TRUE, NULL);
1250       local = TRUE;
1251       if (!server_entry) {
1252         /* If we are normal server then we might not have the server. Check
1253            whether router was kind enough to send the list of all clients
1254            that actually was to be removed. Remove them if the list is
1255            available. */
1256         if (server->server_type != SILC_ROUTER &&
1257             silc_argument_get_arg_num(args) > 1) {
1258           int i;
1259
1260           for (i = 1; i < silc_argument_get_arg_num(args); i++) {
1261             /* Get Client ID */
1262             tmp = silc_argument_get_arg_type(args, i + 1, &tmp_len);
1263             if (!tmp)
1264               continue;
1265             client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1266             if (!client_id)
1267               continue;
1268
1269             /* Get client entry */
1270             client = silc_idlist_find_client_by_id(server->global_list, 
1271                                                    client_id, TRUE, &cache);
1272             local = TRUE;
1273             if (!client) {
1274               client = silc_idlist_find_client_by_id(server->local_list, 
1275                                                      client_id, TRUE, &cache);
1276               local = FALSE;
1277               if (!client) {
1278                 silc_free(client_id);
1279                 continue;
1280               }
1281             }
1282             silc_free(client_id);
1283
1284             /* Update statistics */
1285             server->stat.clients--;
1286             if (server->stat.cell_clients)
1287               server->stat.cell_clients--;
1288             SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
1289             SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
1290
1291             /* Remove the client from all channels. */
1292             silc_server_remove_from_channels(server, NULL, client, 
1293                                              TRUE, NULL, FALSE);
1294
1295             /* Check if anyone is watching this nickname */
1296             if (server->server_type == SILC_ROUTER)
1297               silc_server_check_watcher_list(server, client, NULL,
1298                                              SILC_NOTIFY_TYPE_SERVER_SIGNOFF);
1299
1300             /* Remove this client from watcher list if it is */
1301             if (local)
1302               silc_server_del_from_watcher_list(server, client);
1303
1304             /* Remove the client */
1305             silc_idlist_del_data(client);
1306             silc_idlist_del_client(local ? server->local_list :
1307                                    server->global_list, client);
1308           }
1309         }
1310
1311         silc_free(server_id);
1312         goto out;
1313       }
1314     }
1315     silc_free(server_id);
1316
1317     /* Sending SERVER_SIGNOFF is not right way to signoff local connection */
1318     if (SILC_IS_LOCAL(server_entry))
1319       break;
1320
1321     /* Remove all servers that are originated from this server, and
1322        remove the clients of those servers too. */
1323     silc_server_remove_servers_by_server(server, server_entry, TRUE);
1324
1325     /* Remove the clients that this server owns as they will become
1326        invalid now too. */
1327     silc_server_remove_clients_by_server(server, server_entry->router,
1328                                          server_entry, TRUE);
1329     silc_server_backup_del(server, server_entry);
1330
1331     /* Remove the server entry */
1332     silc_idlist_del_server(local ? server->local_list :
1333                            server->global_list, server_entry);
1334
1335     /* Update statistics */
1336     if (server->server_type == SILC_ROUTER)
1337       server->stat.servers--;
1338
1339     break;
1340
1341   case SILC_NOTIFY_TYPE_KICKED:
1342     /* 
1343      * Distribute the notify to local clients on the channel
1344      */
1345     
1346     SILC_LOG_DEBUG(("KICKED notify"));
1347       
1348     if (!channel_id) {
1349       channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
1350                                   packet->dst_id_type);
1351       if (!channel_id)
1352         goto out;
1353     }
1354
1355     /* Get channel entry */
1356     channel = silc_idlist_find_channel_by_id(server->global_list, 
1357                                              channel_id, NULL);
1358     if (!channel) {
1359       channel = silc_idlist_find_channel_by_id(server->local_list, 
1360                                                channel_id, NULL);
1361       if (!channel) {
1362         SILC_LOG_DEBUG(("Notify for unknown channel"));
1363         silc_free(channel_id);
1364         goto out;
1365       }
1366     }
1367     silc_free(channel_id);
1368
1369     /* Get client ID */
1370     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1371     if (!tmp)
1372       goto out;
1373     client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1374     if (!client_id)
1375       goto out;
1376
1377     /* If the the client is not in local list we check global list */
1378     client = silc_idlist_find_client_by_id(server->global_list, 
1379                                            client_id, TRUE, NULL);
1380     if (!client) {
1381       client = silc_idlist_find_client_by_id(server->local_list, 
1382                                              client_id, TRUE, NULL);
1383       if (!client) {
1384         silc_free(client_id);
1385         goto out;
1386       }
1387     }
1388     silc_free(client_id);
1389
1390     /* If target is founder they cannot be kicked */
1391     if (!silc_server_client_on_channel(client, channel, &chl))
1392       goto out;
1393     if (chl->mode & SILC_CHANNEL_UMODE_CHANFO)
1394       goto out;
1395     
1396     /* From protocol version 1.1 we get the kicker's ID as well. */
1397     tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1398     if (tmp) {
1399       client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1400       if (!client_id)
1401         goto out;
1402
1403       /* If the the client is not in local list we check global list */
1404       client2 = silc_idlist_find_client_by_id(server->global_list, 
1405                                               client_id, TRUE, NULL);
1406       if (!client2) {
1407         client2 = silc_idlist_find_client_by_id(server->local_list, 
1408                                                 client_id, TRUE, NULL);
1409         if (!client2) {
1410           silc_free(client_id);
1411           goto out;
1412         }
1413       }
1414       silc_free(client_id);
1415
1416       /* Kicker must be operator on channel */
1417       if (!silc_server_client_on_channel(client2, channel, &chl))
1418         goto out;
1419       if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
1420           !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1421         SILC_LOG_DEBUG(("Kicking is not allowed"));
1422         goto out;
1423       }
1424     }
1425
1426     /* Send to channel */
1427     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
1428                                        FALSE, packet->buffer->data, 
1429                                        packet->buffer->len, FALSE);
1430
1431     /* Remove the client from channel */
1432     silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
1433
1434     break;
1435
1436   case SILC_NOTIFY_TYPE_KILLED:
1437     {
1438       /* 
1439        * Distribute the notify to local clients on channels
1440        */
1441       unsigned char *id, *comment;
1442       SilcUInt32 id_len, comment_len;
1443     
1444       SILC_LOG_DEBUG(("KILLED notify"));
1445       
1446       /* Get client ID */
1447       id = silc_argument_get_arg_type(args, 1, &id_len);
1448       if (!id)
1449         goto out;
1450       client_id = silc_id_payload_parse_id(id, id_len, NULL);
1451       if (!client_id)
1452         goto out;
1453
1454       /* If the the client is not in local list we check global list */
1455       client = silc_idlist_find_client_by_id(server->global_list, 
1456                                              client_id, TRUE, &cache);
1457       if (!client) {
1458         client = silc_idlist_find_client_by_id(server->local_list, 
1459                                                client_id, TRUE, &cache);
1460         if (!client) {
1461           silc_free(client_id);
1462           goto out;
1463         }
1464       }
1465       silc_free(client_id);
1466
1467       /* If the client is one of ours, then close the connection to the
1468          client now. This removes the client from all channels as well. */
1469       if (packet->dst_id_type == SILC_ID_CLIENT && client->connection) {
1470         sock = client->connection;
1471         silc_server_free_client_data(server, NULL, client, FALSE, NULL);
1472         silc_server_close_connection(server, sock);
1473         break;
1474       }
1475
1476       /* Get comment */
1477       comment = silc_argument_get_arg_type(args, 2, &comment_len);
1478       if (comment_len > 128)
1479         comment_len = 127;
1480
1481       /* From protocol version 1.1 we get the killer's ID as well. */
1482       tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1483       if (tmp) {
1484         client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
1485         if (!client_id)
1486           goto out;
1487
1488         if (id_type == SILC_ID_CLIENT) {
1489           /* If the the client is not in local list we check global list */
1490           client2 = silc_idlist_find_client_by_id(server->global_list, 
1491                                                   client_id, TRUE, NULL);
1492           if (!client2) {
1493             client2 = silc_idlist_find_client_by_id(server->local_list, 
1494                                                     client_id, TRUE, NULL);
1495             if (!client2) {
1496               silc_free(client_id);
1497               goto out;
1498             }
1499           }
1500           silc_free(client_id);
1501
1502           /* Killer must be router operator */
1503           if (server->server_type != SILC_SERVER &&
1504               !(client2->mode & SILC_UMODE_ROUTER_OPERATOR)) {
1505             SILC_LOG_DEBUG(("Killing is not allowed"));
1506             goto out;
1507           }
1508         }
1509       }
1510
1511       /* Send the notify to local clients on the channels except to the
1512          client who is killed. */
1513       silc_server_send_notify_on_channels(server, client, client,
1514                                           SILC_NOTIFY_TYPE_KILLED, 3,
1515                                           id, id_len, comment, comment_len,
1516                                           tmp, tmp_len);
1517
1518       /* Remove the client from all channels */
1519       silc_server_remove_from_channels(server, NULL, client, FALSE, NULL, 
1520                                        FALSE);
1521
1522       /* Check if anyone is watching this nickname */
1523       silc_server_check_watcher_list(server, client, NULL,
1524                                      SILC_NOTIFY_TYPE_KILLED);
1525
1526       /* Update statistics */
1527       server->stat.clients--;
1528       if (server->stat.cell_clients)
1529         server->stat.cell_clients--;
1530       SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
1531       SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
1532
1533       if (SILC_IS_LOCAL(client)) {
1534         server->stat.my_clients--;
1535         silc_schedule_task_del_by_context(server->schedule, client);
1536         silc_idlist_del_data(client);
1537         client->mode = 0;
1538       }
1539
1540       client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
1541       cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
1542       break;
1543     }
1544
1545   case SILC_NOTIFY_TYPE_UMODE_CHANGE:
1546     /*
1547      * Save the mode of the client.
1548      */
1549
1550     SILC_LOG_DEBUG(("UMODE_CHANGE notify"));
1551
1552     /* Get client ID */
1553     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1554     if (!tmp)
1555       goto out;
1556     client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1557     if (!client_id)
1558       goto out;
1559
1560     /* Get client entry */
1561     client = silc_idlist_find_client_by_id(server->global_list, 
1562                                            client_id, TRUE, NULL);
1563     if (!client) {
1564       client = silc_idlist_find_client_by_id(server->local_list, 
1565                                              client_id, TRUE, NULL);
1566       if (!client) {
1567         silc_free(client_id);
1568         goto out;
1569       }
1570     }
1571     silc_free(client_id);
1572
1573     /* Get the mode */
1574     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1575     if (!tmp)
1576       goto out;
1577     SILC_GET32_MSB(mode, tmp);
1578
1579     /* Remove internal resumed flag if client is marked detached now */
1580     if (mode & SILC_UMODE_DETACHED)
1581       client->data.status &= ~SILC_IDLIST_STATUS_RESUMED;
1582
1583     /* Update statistics */
1584     if (server->server_type == SILC_ROUTER) {
1585       if (mode & SILC_UMODE_GONE) {
1586         if (!(client->mode & SILC_UMODE_GONE))
1587           server->stat.aways++;
1588       } else {
1589         if (client->mode & SILC_UMODE_GONE)
1590           server->stat.aways--;
1591       }
1592       if (mode & SILC_UMODE_DETACHED) {
1593         if (!(client->mode & SILC_UMODE_DETACHED))
1594           server->stat.detached++;
1595       } else {
1596         if (client->mode & SILC_UMODE_DETACHED)
1597           server->stat.detached--;
1598       }
1599     }
1600     SILC_UMODE_STATS_UPDATE(server, SILC_UMODE_SERVER_OPERATOR);
1601     SILC_UMODE_STATS_UPDATE(router, SILC_UMODE_ROUTER_OPERATOR);
1602
1603     /* Change the mode */
1604     client->mode = mode;
1605
1606     /* Check if anyone is watching this nickname */
1607     if (server->server_type == SILC_ROUTER)
1608       silc_server_check_watcher_list(server, client, NULL,
1609                                      SILC_NOTIFY_TYPE_UMODE_CHANGE);
1610
1611     break;
1612
1613   case SILC_NOTIFY_TYPE_BAN:
1614     /*
1615      * Save the ban
1616      */
1617
1618     SILC_LOG_DEBUG(("BAN notify"));
1619     
1620     /* Get Channel ID */
1621     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1622     if (!tmp)
1623       goto out;
1624     channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1625     if (!channel_id)
1626       goto out;
1627     
1628     /* Get channel entry */
1629     channel = silc_idlist_find_channel_by_id(server->global_list, 
1630                                              channel_id, NULL);
1631     if (!channel) {
1632       channel = silc_idlist_find_channel_by_id(server->local_list, 
1633                                                channel_id, NULL);
1634       if (!channel) {
1635         SILC_LOG_DEBUG(("Notify for unknown channel"));
1636         silc_free(channel_id);
1637         goto out;
1638       }
1639     }
1640     silc_free(channel_id);
1641
1642     /* Get the new ban and add it to the ban list */
1643     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1644     if (tmp) {
1645       if (!channel->ban_list)
1646         channel->ban_list = silc_calloc(tmp_len + 2, 
1647                                         sizeof(*channel->ban_list));
1648       else
1649         channel->ban_list = silc_realloc(channel->ban_list, 
1650                                          sizeof(*channel->ban_list) * 
1651                                          (tmp_len + 
1652                                           strlen(channel->ban_list) + 2));
1653       strncat(channel->ban_list, tmp, tmp_len);
1654       strncat(channel->ban_list, ",", 1);
1655     }
1656
1657     /* Get the ban to be removed and remove it from the list */
1658     tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1659     if (tmp && channel->ban_list) {
1660       char *start, *end, *n;
1661       
1662       if (!strncmp(channel->ban_list, tmp, strlen(channel->ban_list) - 1)) {
1663         silc_free(channel->ban_list);
1664         channel->ban_list = NULL;
1665       } else {
1666         start = strstr(channel->ban_list, tmp);
1667         if (start && strlen(start) >= tmp_len) {
1668           end = start + tmp_len;
1669           n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
1670           strncat(n, channel->ban_list, start - channel->ban_list);
1671           strncat(n, end + 1, ((channel->ban_list + 
1672                                 strlen(channel->ban_list)) - end) - 1);
1673           silc_free(channel->ban_list);
1674           channel->ban_list = n;
1675         }
1676       }
1677     }
1678     break;
1679
1680   case SILC_NOTIFY_TYPE_ERROR:
1681     {
1682       /*
1683        * Error notify
1684        */
1685       SilcStatus error;
1686
1687       tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1688       if (!tmp && tmp_len != 1)
1689         goto out;
1690       error = (SilcStatus)tmp[0];
1691
1692       SILC_LOG_DEBUG(("ERROR notify (%d)", error));
1693
1694       if (error == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID &&
1695           sock->type == SILC_SOCKET_TYPE_ROUTER) {
1696         tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1697         if (tmp) {
1698           SILC_LOG_DEBUG(("Received invalid client ID notification, deleting "
1699                           "the entry from cache"));
1700           client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1701           if (!client_id)
1702             goto out;
1703           client = silc_idlist_find_client_by_id(server->global_list, 
1704                                                  client_id, FALSE, NULL);
1705           if (client) {
1706             silc_server_remove_from_channels(server, NULL, client, TRUE, 
1707                                              NULL, TRUE);
1708             silc_idlist_del_data(client);
1709             silc_idlist_del_client(server->global_list, client);
1710           }
1711           silc_free(client_id);
1712         }
1713       }
1714     }
1715     break;
1716
1717     /* Ignore rest of the notify types for now */
1718   case SILC_NOTIFY_TYPE_NONE:
1719   case SILC_NOTIFY_TYPE_MOTD:
1720     break;
1721   default:
1722     break;
1723   }
1724
1725  out:
1726   silc_notify_payload_free(payload);
1727 }
1728
1729 void silc_server_notify_list(SilcServer server,
1730                              SilcSocketConnection sock,
1731                              SilcPacketContext *packet)
1732 {
1733   SilcPacketContext *new;
1734   SilcBuffer buffer;
1735   SilcUInt16 len;
1736
1737   SILC_LOG_DEBUG(("Processing Notify List"));
1738
1739   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1740       packet->src_id_type != SILC_ID_SERVER)
1741     return;
1742
1743   /* Make copy of the original packet context, except for the actual
1744      data buffer, which we will here now fetch from the original buffer. */
1745   new = silc_packet_context_alloc();
1746   new->type = SILC_PACKET_NOTIFY;
1747   new->flags = packet->flags;
1748   new->src_id = packet->src_id;
1749   new->src_id_len = packet->src_id_len;
1750   new->src_id_type = packet->src_id_type;
1751   new->dst_id = packet->dst_id;
1752   new->dst_id_len = packet->dst_id_len;
1753   new->dst_id_type = packet->dst_id_type;
1754
1755   buffer = silc_buffer_alloc(1024);
1756   new->buffer = buffer;
1757
1758   while (packet->buffer->len) {
1759     SILC_GET16_MSB(len, packet->buffer->data + 2);
1760     if (len > packet->buffer->len)
1761       break;
1762
1763     if (len > buffer->truelen) {
1764       silc_buffer_free(buffer);
1765       buffer = silc_buffer_alloc(1024 + len);
1766     }
1767
1768     silc_buffer_pull_tail(buffer, len);
1769     silc_buffer_put(buffer, packet->buffer->data, len);
1770
1771     /* Process the Notify */
1772     silc_server_notify(server, sock, new);
1773
1774     silc_buffer_push_tail(buffer, len);
1775     silc_buffer_pull(packet->buffer, len);
1776   }
1777
1778   silc_buffer_free(buffer);
1779   silc_free(new);
1780 }
1781
1782 /* Received private message. This resolves the destination of the message 
1783    and sends the packet. This is used by both server and router.  If the
1784    destination is our locally connected client this sends the packet to
1785    the client. This may also send the message for further routing if
1786    the destination is not in our server (or router). */
1787
1788 void silc_server_private_message(SilcServer server,
1789                                  SilcSocketConnection sock,
1790                                  SilcPacketContext *packet)
1791 {
1792   SilcSocketConnection dst_sock;
1793   SilcIDListData idata;
1794   SilcClientEntry client;
1795
1796   SILC_LOG_DEBUG(("Start"));
1797
1798   if (packet->src_id_type != SILC_ID_CLIENT ||
1799       packet->dst_id_type != SILC_ID_CLIENT || !packet->dst_id)
1800     return;
1801
1802   /* Get the route to the client */
1803   dst_sock = silc_server_get_client_route(server, packet->dst_id,
1804                                           packet->dst_id_len, NULL, 
1805                                           &idata, &client);
1806   if (!dst_sock) {
1807     SilcBuffer idp;
1808     unsigned char error;
1809
1810     if (client && client->mode & SILC_UMODE_DETACHED) {
1811       SILC_LOG_DEBUG(("Client is detached, discarding packet"));
1812       return;
1813     }
1814
1815     /* Send SILC_NOTIFY_TYPE_ERROR to indicate that such destination ID
1816        does not exist or is invalid. */
1817     idp = silc_id_payload_encode_data(packet->dst_id,
1818                                       packet->dst_id_len,
1819                                       packet->dst_id_type);
1820     if (!idp)
1821       return;
1822
1823     error = SILC_STATUS_ERR_NO_SUCH_CLIENT_ID;
1824     if (packet->src_id_type == SILC_ID_CLIENT) {
1825       SilcClientID *client_id = silc_id_str2id(packet->src_id,
1826                                                packet->src_id_len,
1827                                                packet->src_id_type);
1828       silc_server_send_notify_dest(server, sock, FALSE,
1829                                    client_id, SILC_ID_CLIENT,
1830                                    SILC_NOTIFY_TYPE_ERROR, 2,
1831                                    &error, 1,
1832                                    idp->data, idp->len);
1833       silc_free(client_id);
1834     } else {
1835       silc_server_send_notify(server, sock, FALSE,
1836                               SILC_NOTIFY_TYPE_ERROR, 2,
1837                               &error, 1,
1838                               idp->data, idp->len);
1839     }
1840
1841     silc_buffer_free(idp);
1842     return;
1843   }
1844
1845   /* Check whether destination client wishes to receive private messages */
1846   if (client && !(packet->flags & SILC_PACKET_FLAG_PRIVMSG_KEY) &&
1847       client->mode & SILC_UMODE_BLOCK_PRIVMSG) {
1848     SILC_LOG_DEBUG(("Client blocks private messages, discarding packet"));
1849     return;
1850   }
1851
1852   /* Send the private message */
1853   silc_server_send_private_message(server, dst_sock, idata->send_key,
1854                                    idata->hmac_send, idata->psn_send++,
1855                                    packet);
1856 }
1857
1858 /* Received private message key packet.. This packet is never for us. It is to
1859    the client in the packet's destination ID. Sending of this sort of packet
1860    equals sending private message, ie. it is sent point to point from
1861    one client to another. */
1862
1863 void silc_server_private_message_key(SilcServer server,
1864                                      SilcSocketConnection sock,
1865                                      SilcPacketContext *packet)
1866 {
1867   SilcSocketConnection dst_sock;
1868   SilcIDListData idata;
1869
1870   SILC_LOG_DEBUG(("Start"));
1871
1872   if (packet->src_id_type != SILC_ID_CLIENT ||
1873       packet->dst_id_type != SILC_ID_CLIENT)
1874     return;
1875
1876   if (!packet->dst_id)
1877     return;
1878
1879   /* Get the route to the client */
1880   dst_sock = silc_server_get_client_route(server, packet->dst_id,
1881                                           packet->dst_id_len, NULL, 
1882                                           &idata, NULL);
1883   if (!dst_sock)
1884     return;
1885
1886   /* Relay the packet */
1887   silc_server_relay_packet(server, dst_sock, idata->send_key,
1888                            idata->hmac_send, idata->psn_send++, packet, FALSE);
1889 }
1890
1891 /* Processes incoming command reply packet. The command reply packet may
1892    be destined to one of our clients or it may directly for us. We will 
1893    call the command reply routine after processing the packet. */
1894
1895 void silc_server_command_reply(SilcServer server,
1896                                SilcSocketConnection sock,
1897                                SilcPacketContext *packet)
1898 {
1899   SilcBuffer buffer = packet->buffer;
1900   SilcClientEntry client = NULL;
1901   SilcSocketConnection dst_sock;
1902   SilcIDListData idata;
1903   SilcClientID *id = NULL;
1904
1905   SILC_LOG_DEBUG(("Start"));
1906
1907   if (packet->dst_id_type == SILC_ID_CHANNEL)
1908     return;
1909
1910   if (packet->dst_id_type == SILC_ID_CLIENT) {
1911     /* Destination must be one of ours */
1912     id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
1913     if (!id)
1914       return;
1915     client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
1916     if (!client) {
1917       SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
1918       silc_free(id);
1919       return;
1920     }
1921   }
1922
1923   if (packet->dst_id_type == SILC_ID_SERVER) {
1924     /* For now this must be for us */
1925     if (memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
1926       SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
1927       return;
1928     }
1929   }
1930
1931   /* Execute command reply locally for the command */
1932   silc_server_command_reply_process(server, sock, buffer);
1933
1934   if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
1935     /* Relay the packet to the client */
1936     const SilcBufferStruct p;
1937     
1938     dst_sock = (SilcSocketConnection)client->connection;
1939     idata = (SilcIDListData)client;
1940     
1941     silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len 
1942                      + packet->dst_id_len + packet->padlen);
1943     if (!silc_packet_send_prepare(dst_sock, 0, 0, buffer->len,
1944                                   idata->hmac_send, (const SilcBuffer)&p)) {
1945       SILC_LOG_ERROR(("Cannot send packet"));
1946       return;
1947     }
1948     silc_buffer_put((SilcBuffer)&p, buffer->data, buffer->len);
1949     
1950     /* Encrypt packet */
1951     silc_packet_encrypt(idata->send_key, idata->hmac_send, idata->psn_send++,
1952                         (SilcBuffer)&p, buffer->len);
1953     
1954     /* Send the packet */
1955     silc_server_packet_send_real(server, dst_sock, TRUE);
1956
1957     silc_free(id);
1958   }
1959 }
1960
1961 /* Process received channel message. The message can be originated from
1962    client or server. */
1963
1964 void silc_server_channel_message(SilcServer server,
1965                                  SilcSocketConnection sock,
1966                                  SilcPacketContext *packet)
1967 {
1968   SilcChannelEntry channel = NULL;
1969   SilcChannelID *id = NULL;
1970   void *sender_id = NULL;
1971   SilcClientEntry sender_entry = NULL;
1972   SilcChannelClientEntry chl;
1973   bool local = TRUE;
1974
1975   SILC_LOG_DEBUG(("Processing channel message"));
1976
1977   /* Sanity checks */
1978   if (packet->dst_id_type != SILC_ID_CHANNEL) {
1979     SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1980     goto out;
1981   }
1982
1983   /* Find channel entry */
1984   id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
1985   if (!id)
1986     goto out;
1987   channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
1988   if (!channel) {
1989     channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
1990     if (!channel) {
1991       SilcBuffer idp;
1992       unsigned char error;
1993
1994       /* Send SILC_NOTIFY_TYPE_ERROR to indicate that such destination ID
1995          does not exist or is invalid. */
1996       idp = silc_id_payload_encode_data(packet->dst_id,
1997                                         packet->dst_id_len,
1998                                         packet->dst_id_type);
1999       if (!idp)
2000         goto out;
2001
2002       error = SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID;
2003       if (packet->src_id_type == SILC_ID_CLIENT) {
2004         SilcClientID *client_id = silc_id_str2id(packet->src_id,
2005                                                  packet->src_id_len,
2006                                                  packet->src_id_type);
2007         silc_server_send_notify_dest(server, sock, FALSE,
2008                                      client_id, SILC_ID_CLIENT,
2009                                      SILC_NOTIFY_TYPE_ERROR, 2,
2010                                      &error, 1, idp->data, idp->len);
2011         silc_free(client_id);
2012       } else {
2013         silc_server_send_notify(server, sock, FALSE,
2014                                 SILC_NOTIFY_TYPE_ERROR, 2,
2015                                 &error, 1, idp->data, idp->len);
2016       }
2017       
2018       silc_buffer_free(idp);
2019       goto out;
2020     }
2021   }
2022
2023   /* See that this client is on the channel. If the original sender is
2024      not client (as it can be server as well) we don't do the check. */
2025   sender_id = silc_id_str2id(packet->src_id, packet->src_id_len, 
2026                              packet->src_id_type);
2027   if (!sender_id)
2028     goto out;
2029   if (packet->src_id_type == SILC_ID_CLIENT) {
2030     sender_entry = silc_idlist_find_client_by_id(server->local_list, 
2031                                                  sender_id, TRUE, NULL);
2032     if (!sender_entry) {
2033       local = FALSE;
2034       sender_entry = silc_idlist_find_client_by_id(server->global_list, 
2035                                                    sender_id, TRUE, NULL);
2036     }
2037     if (!sender_entry || !silc_server_client_on_channel(sender_entry, 
2038                                                         channel, &chl)) {
2039       SILC_LOG_DEBUG(("Client not on channel"));
2040       goto out;
2041     }
2042
2043     /* If channel is moderated check that client is allowed to send
2044        messages. */
2045     if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS && 
2046         !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
2047         !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
2048       SILC_LOG_DEBUG(("Channel is silenced from normal users"));
2049       goto out;
2050     }
2051     if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS && 
2052         chl->mode & SILC_CHANNEL_UMODE_CHANOP &&
2053         !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
2054       SILC_LOG_DEBUG(("Channel is silenced from operators"));
2055       goto out;
2056     }
2057     if (chl->mode & SILC_CHANNEL_UMODE_QUIET) {
2058       SILC_LOG_DEBUG(("Sender is quieted on the channel"));
2059       goto out;
2060     }
2061
2062     /* If the packet is coming from router, but the client entry is local 
2063        entry to us then some router is rerouting this to us and it is not 
2064        allowed. When the client is local to us it means that we've routed
2065        this packet to network, and now someone is routing it back to us. */
2066     if (server->server_type == SILC_ROUTER &&
2067         sock->type == SILC_SOCKET_TYPE_ROUTER && local) {
2068       SILC_LOG_DEBUG(("Channel message rerouted to the sender, drop it"));
2069       goto out;
2070     }
2071   }
2072
2073   /* Distribute the packet to our local clients. This will send the
2074      packet for further routing as well, if needed. */
2075   silc_server_packet_relay_to_channel(server, sock, channel, sender_id,
2076                                       packet->src_id_type, sender_entry,
2077                                       packet->buffer->data,
2078                                       packet->buffer->len, FALSE);
2079
2080  out:
2081   silc_free(sender_id);
2082   silc_free(id);
2083 }
2084
2085 /* Received channel key packet. We distribute the key to all of our locally
2086    connected clients on the channel. */
2087
2088 void silc_server_channel_key(SilcServer server,
2089                              SilcSocketConnection sock,
2090                              SilcPacketContext *packet)
2091 {
2092   SilcBuffer buffer = packet->buffer;
2093   SilcChannelEntry channel;
2094
2095   if (packet->src_id_type != SILC_ID_SERVER ||
2096       (server->server_type == SILC_ROUTER && !server->backup_router &&
2097        sock->type == SILC_SOCKET_TYPE_ROUTER))
2098     return;
2099
2100   /* Save the channel key */
2101   channel = silc_server_save_channel_key(server, buffer, NULL);
2102   if (!channel)
2103     return;
2104
2105   /* Distribute the key to everybody who is on the channel. If we are router
2106      we will also send it to locally connected servers. */
2107   silc_server_send_channel_key(server, sock, channel, FALSE);
2108   
2109   if (server->server_type != SILC_BACKUP_ROUTER) {
2110     /* Distribute to local cell backup routers. */
2111     silc_server_backup_send(server, sock->user_data, 
2112                             SILC_PACKET_CHANNEL_KEY, 0,
2113                             buffer->data, buffer->len, FALSE, TRUE);
2114   }
2115 }
2116
2117 /* Received New Client packet and processes it.  Creates Client ID for the
2118    client. Client becomes registered after calling this functions. */
2119
2120 SilcClientEntry silc_server_new_client(SilcServer server,
2121                                        SilcSocketConnection sock,
2122                                        SilcPacketContext *packet)
2123 {
2124   SilcBuffer buffer = packet->buffer;
2125   SilcClientEntry client;
2126   SilcClientID *client_id;
2127   SilcIDListData idata;
2128   char *username = NULL, *realname = NULL;
2129   SilcUInt16 username_len;
2130   SilcUInt32 id_len;
2131   int ret;
2132   char *hostname, *nickname;
2133   int nickfail = 0;
2134
2135   SILC_LOG_DEBUG(("Creating new client"));
2136
2137   if (sock->type != SILC_SOCKET_TYPE_CLIENT)
2138     return NULL;
2139
2140   /* Take client entry */
2141   client = (SilcClientEntry)sock->user_data;
2142   idata = (SilcIDListData)client;
2143
2144   /* Remove the old cache entry. */
2145   if (!silc_idcache_del_by_context(server->local_list->clients, client)) {
2146     SILC_LOG_INFO(("Unauthenticated client attempted to register to network"));
2147     silc_server_disconnect_remote(server, sock, 
2148                                   SILC_STATUS_ERR_NOT_AUTHENTICATED, NULL);
2149     if (sock->user_data)
2150       silc_server_free_sock_user_data(server, sock, NULL);
2151     return NULL;
2152   }
2153
2154   /* Parse incoming packet */
2155   ret = silc_buffer_unformat(buffer,
2156                              SILC_STR_UI16_NSTRING_ALLOC(&username, 
2157                                                          &username_len),
2158                              SILC_STR_UI16_STRING_ALLOC(&realname),
2159                              SILC_STR_END);
2160   if (ret == -1) {
2161     silc_free(username);
2162     silc_free(realname);
2163     SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2164                     "connection", sock->hostname, sock->ip));
2165     silc_server_disconnect_remote(server, sock, 
2166                                   SILC_STATUS_ERR_INCOMPLETE_INFORMATION, 
2167                                   NULL);
2168     if (sock->user_data)
2169       silc_server_free_sock_user_data(server, sock, NULL);
2170     return NULL;
2171   }
2172
2173   if (!username) {
2174     silc_free(username);
2175     silc_free(realname);
2176     SILC_LOG_ERROR(("Client %s (%s) did not send its username, closing "
2177                     "connection", sock->hostname, sock->ip));
2178     silc_server_disconnect_remote(server, sock, 
2179                                   SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2180                                   NULL);
2181     if (sock->user_data)
2182       silc_server_free_sock_user_data(server, sock, NULL);
2183     return NULL;
2184   }
2185
2186   if (username_len > 128)
2187     username[128] = '\0';
2188
2189   /* Check for bad characters for nickname, and modify the nickname if
2190      it includes those. */
2191   if (silc_server_name_bad_chars(username, username_len)) {
2192     nickname = silc_server_name_modify_bad(username, username_len);
2193   } else {
2194     nickname = strdup(username);
2195   }
2196
2197   /* Make sanity checks for the hostname of the client. If the hostname
2198      is provided in the `username' check that it is the same than the
2199      resolved hostname, or if not resolved the hostname that appears in
2200      the client's public key. If the hostname is not present then put
2201      it from the resolved name or from the public key. */
2202   if (strchr(username, '@')) {
2203     SilcPublicKeyIdentifier pident;
2204     int tlen = strcspn(username, "@");
2205     char *phostname = NULL;
2206
2207     hostname = silc_memdup(username + tlen + 1, strlen(username) - tlen - 1);
2208
2209     if (strcmp(sock->hostname, sock->ip) && 
2210         strcmp(sock->hostname, hostname)) {
2211       silc_free(username);
2212       silc_free(hostname);
2213       silc_free(realname);
2214       SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2215                       "connection", sock->hostname, sock->ip));
2216       silc_server_disconnect_remote(server, sock, 
2217                                     SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2218                                     NULL);
2219       if (sock->user_data)
2220         silc_server_free_sock_user_data(server, sock, NULL);
2221       return NULL;
2222     }
2223     
2224     pident = silc_pkcs_decode_identifier(client->data.public_key->identifier);
2225     if (pident) {
2226       phostname = strdup(pident->host);
2227       silc_pkcs_free_identifier(pident);
2228     }
2229
2230     if (!strcmp(sock->hostname, sock->ip) && 
2231         phostname && strcmp(phostname, hostname)) {
2232       silc_free(username);
2233       silc_free(hostname);
2234       silc_free(phostname);
2235       silc_free(realname);
2236       SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2237                       "connection", sock->hostname, sock->ip));
2238       silc_server_disconnect_remote(server, sock, 
2239                                     SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2240                                     NULL);
2241       if (sock->user_data)
2242         silc_server_free_sock_user_data(server, sock, NULL);
2243       return NULL;
2244     }
2245     
2246     silc_free(phostname);
2247   } else {
2248     /* The hostname is not present, add it. */
2249     char *newusername;
2250     /* XXX For now we cannot take the host name from the public key since
2251        they are not trusted or we cannot verify them as trusted. Just take
2252        what the resolved name or address is. */
2253 #if 0
2254     if (strcmp(sock->hostname, sock->ip)) {
2255 #endif
2256       newusername = silc_calloc(strlen(username) + 
2257                                 strlen(sock->hostname) + 2,
2258                                 sizeof(*newusername));
2259       strncat(newusername, username, strlen(username));
2260       strncat(newusername, "@", 1);
2261       strncat(newusername, sock->hostname, strlen(sock->hostname));
2262       silc_free(username);
2263       username = newusername;
2264 #if 0
2265     } else {
2266       SilcPublicKeyIdentifier pident = 
2267         silc_pkcs_decode_identifier(client->data.public_key->identifier);
2268       
2269       if (pident) {
2270         newusername = silc_calloc(strlen(username) + 
2271                                   strlen(pident->host) + 2,
2272                                   sizeof(*newusername));
2273         strncat(newusername, username, strlen(username));
2274         strncat(newusername, "@", 1);
2275         strncat(newusername, pident->host, strlen(pident->host));
2276         silc_free(username);
2277         username = newusername;
2278         silc_pkcs_free_identifier(pident);
2279       }
2280     }
2281 #endif
2282   }
2283
2284   /* Create Client ID */
2285   while (!silc_id_create_client_id(server, server->id, server->rng, 
2286                                    server->md5hash, nickname, &client_id)) {
2287     nickfail++;
2288     if (nickfail > 9) {
2289       silc_server_disconnect_remote(server, sock, 
2290                                     SILC_STATUS_ERR_BAD_NICKNAME, NULL);
2291       if (sock->user_data)
2292         silc_server_free_sock_user_data(server, sock, NULL);
2293       return NULL;
2294     }
2295     snprintf(&nickname[strlen(nickname) - 1], 1, "%d", nickfail);
2296   }
2297
2298   /* If client marked as anonymous, scramble the username and hostname */
2299   if (client->mode & SILC_UMODE_ANONYMOUS) {
2300     char *scramble;
2301
2302     if (strlen(username) >= 2) {
2303       username[0] = silc_rng_get_byte_fast(server->rng);
2304       username[1] = silc_rng_get_byte_fast(server->rng);
2305     }
2306
2307     scramble = silc_hash_babbleprint(server->sha1hash, username,
2308                                      strlen(username));
2309     scramble[5] = '@';
2310     scramble[11] = '.';
2311     memcpy(&scramble[16], ".silc", 5);
2312     scramble[21] = '\0';
2313     silc_free(username);
2314     username = scramble;
2315   }
2316
2317   /* Update client entry */
2318   idata->status |= SILC_IDLIST_STATUS_REGISTERED;
2319   client->nickname = nickname;
2320   client->username = username;
2321   client->userinfo = realname ? realname : strdup(" ");
2322   client->id = client_id;
2323   id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
2324
2325   /* Add the client again to the ID cache */
2326   silc_idcache_add(server->local_list->clients, client->nickname,
2327                    client_id, client, 0, NULL);
2328
2329   /* Notify our router about new client on the SILC network */
2330   silc_server_send_new_id(server, SILC_PRIMARY_ROUTE(server),
2331                           SILC_BROADCAST(server), client->id,
2332                           SILC_ID_CLIENT, id_len);
2333
2334   /* Distribute to backup routers */
2335   if (server->server_type == SILC_ROUTER) {
2336     SilcBuffer idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
2337     silc_server_backup_send(server, sock->user_data, SILC_PACKET_NEW_ID, 0,
2338                             idp->data, idp->len, FALSE, TRUE);
2339     silc_buffer_free(idp);
2340   }
2341
2342   /* Send the new client ID to the client. */
2343   silc_server_send_new_id(server, sock, FALSE, client->id, SILC_ID_CLIENT,
2344                           silc_id_get_len(client->id, SILC_ID_CLIENT));
2345
2346   /* Send some nice info to the client */
2347   silc_server_send_connect_notifys(server, sock, client);
2348
2349   /* Check if anyone is watching this nickname */
2350   if (server->server_type == SILC_ROUTER)
2351     silc_server_check_watcher_list(server, client, NULL, 0);
2352
2353   return client;
2354 }
2355
2356 /* Create new server. This processes received New Server packet and
2357    saves the received Server ID. The server is our locally connected
2358    server thus we save all the information and save it to local list. 
2359    This funtion can be used by both normal server and router server.
2360    If normal server uses this it means that its router has connected
2361    to the server. If router uses this it means that one of the cell's
2362    servers is connected to the router. */
2363
2364 SilcServerEntry silc_server_new_server(SilcServer server,
2365                                        SilcSocketConnection sock,
2366                                        SilcPacketContext *packet)
2367 {
2368   SilcBuffer buffer = packet->buffer;
2369   SilcServerEntry new_server, server_entry;
2370   SilcServerID *server_id;
2371   SilcIDListData idata;
2372   unsigned char *server_name, *id_string;
2373   SilcUInt16 id_len, name_len;
2374   int ret;
2375   bool local = TRUE;
2376
2377   SILC_LOG_DEBUG(("Creating new server"));
2378
2379   if (sock->type != SILC_SOCKET_TYPE_SERVER &&
2380       sock->type != SILC_SOCKET_TYPE_ROUTER)
2381     return NULL;
2382
2383   /* Take server entry */
2384   new_server = (SilcServerEntry)sock->user_data;
2385   idata = (SilcIDListData)new_server;
2386
2387   /* Remove the old cache entry */
2388   if (!silc_idcache_del_by_context(server->local_list->servers, new_server)) {
2389     if (!silc_idcache_del_by_context(server->global_list->servers, 
2390                                      new_server)) {
2391       SILC_LOG_INFO(("Unauthenticated %s attempted to register to "
2392                      "network", (sock->type == SILC_SOCKET_TYPE_SERVER ?
2393                                  "server" : "router")));
2394       silc_server_disconnect_remote(server, sock, 
2395                                     SILC_STATUS_ERR_NOT_AUTHENTICATED, NULL);
2396       if (sock->user_data)
2397         silc_server_free_sock_user_data(server, sock, NULL);
2398       return NULL;
2399     }
2400     local = FALSE;
2401   }
2402
2403   /* Parse the incoming packet */
2404   ret = silc_buffer_unformat(buffer,
2405                              SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
2406                              SILC_STR_UI16_NSTRING_ALLOC(&server_name, 
2407                                                          &name_len),
2408                              SILC_STR_END);
2409   if (ret == -1) {
2410     silc_free(id_string);
2411     silc_free(server_name);
2412     silc_server_disconnect_remote(server, sock, 
2413                                   SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2414                                   NULL);
2415     if (sock->user_data)
2416       silc_server_free_sock_user_data(server, sock, NULL);
2417     return NULL;
2418   }
2419
2420   if (id_len > buffer->len) {
2421     silc_free(id_string);
2422     silc_free(server_name);
2423     silc_server_disconnect_remote(server, sock, 
2424                                   SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2425                                   NULL);
2426     if (sock->user_data)
2427       silc_server_free_sock_user_data(server, sock, NULL);
2428     return NULL;
2429   }
2430
2431   if (name_len > 256)
2432     server_name[255] = '\0';
2433
2434   /* Get Server ID */
2435   server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
2436   if (!server_id) {
2437     silc_free(id_string);
2438     silc_free(server_name);
2439     silc_server_disconnect_remote(server, sock, 
2440                                   SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2441                                   NULL);
2442     if (sock->user_data)
2443       silc_server_free_sock_user_data(server, sock, NULL);
2444     return NULL;
2445   }
2446   silc_free(id_string);
2447
2448   /* Check for valid server ID */
2449   if (!silc_id_is_valid_server_id(server, server_id, sock)) {
2450     SILC_LOG_INFO(("Invalid server ID sent by %s (%s)",
2451                    sock->ip, sock->hostname));
2452     silc_server_disconnect_remote(server, sock, 
2453                                   SILC_STATUS_ERR_BAD_SERVER_ID, NULL);
2454     if (sock->user_data)
2455       silc_server_free_sock_user_data(server, sock, NULL);
2456     silc_free(server_name);
2457     return NULL;
2458   }
2459
2460   /* Check that we do not have this ID already */
2461   server_entry = silc_idlist_find_server_by_id(server->local_list, 
2462                                                server_id, TRUE, NULL);
2463   if (server_entry) {
2464     silc_idcache_del_by_context(server->local_list->servers, server_entry);
2465   } else {
2466     server_entry = silc_idlist_find_server_by_id(server->global_list, 
2467                                                  server_id, TRUE, NULL);
2468     if (server_entry) 
2469       silc_idcache_del_by_context(server->global_list->servers, server_entry);
2470   }
2471
2472   /* Update server entry */
2473   idata->status |= SILC_IDLIST_STATUS_REGISTERED;
2474   new_server->server_name = server_name;
2475   new_server->id = server_id;
2476   
2477   SILC_LOG_DEBUG(("New server id(%s)",
2478                   silc_id_render(server_id, SILC_ID_SERVER)));
2479
2480   /* Add again the entry to the ID cache. */
2481   silc_idcache_add(local ? server->local_list->servers : 
2482                    server->global_list->servers, server_name, server_id, 
2483                    new_server, 0, NULL);
2484
2485   /* Distribute the information about new server in the SILC network
2486      to our router. If we are normal server we won't send anything
2487      since this connection must be our router connection. */
2488   if (server->server_type == SILC_ROUTER && !server->standalone &&
2489       SILC_PRIMARY_ROUTE(server) != sock)
2490     silc_server_send_new_id(server, SILC_PRIMARY_ROUTE(server),
2491                             TRUE, new_server->id, SILC_ID_SERVER, 
2492                             silc_id_get_len(server_id, SILC_ID_SERVER));
2493
2494   if (server->server_type == SILC_ROUTER) {
2495     /* Distribute to backup routers */
2496     SilcBuffer idp = silc_id_payload_encode(new_server->id, SILC_ID_SERVER);
2497     silc_server_backup_send(server, sock->user_data, SILC_PACKET_NEW_ID, 0,
2498                             idp->data, idp->len, FALSE, TRUE);
2499     silc_buffer_free(idp);
2500
2501     /* Statistics */
2502     server->stat.cell_servers++;
2503   }
2504
2505   /* Check whether this router connection has been replaced by an
2506      backup router. If it has been then we'll disable the server and will
2507      ignore everything it will send until the backup router resuming
2508      protocol has been completed. */
2509   if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
2510       silc_server_backup_replaced_get(server, server_id, NULL)) {
2511     /* Send packet to the server indicating that it cannot use this
2512        connection as it has been replaced by backup router. */
2513     SilcBuffer packet = silc_buffer_alloc(2);
2514     silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
2515     silc_buffer_format(packet,
2516                        SILC_STR_UI_CHAR(SILC_SERVER_BACKUP_REPLACED),
2517                        SILC_STR_UI_CHAR(0),
2518                        SILC_STR_END);
2519     silc_server_packet_send(server, sock, 
2520                             SILC_PACKET_RESUME_ROUTER, 0, 
2521                             packet->data, packet->len, TRUE);
2522     silc_buffer_free(packet);
2523
2524     /* Mark the router disabled. The data sent earlier will go but nothing
2525        after this does not go to this connection. */
2526     idata->status |= SILC_IDLIST_STATUS_DISABLED;
2527   } else {
2528     /* If it is router announce our stuff to it. */
2529     if (sock->type == SILC_SOCKET_TYPE_ROUTER && 
2530         server->server_type == SILC_ROUTER) {
2531       silc_server_announce_servers(server, FALSE, 0, sock);
2532       silc_server_announce_clients(server, 0, sock);
2533       silc_server_announce_channels(server, 0, sock);
2534     }
2535
2536     /* Announce our information to backup router */
2537     if (new_server->server_type == SILC_BACKUP_ROUTER &&
2538         sock->type == SILC_SOCKET_TYPE_SERVER &&
2539         server->server_type == SILC_ROUTER) {
2540       silc_server_announce_servers(server, TRUE, 0, sock);
2541       silc_server_announce_clients(server, 0, sock);
2542       silc_server_announce_channels(server, 0, sock);
2543     }
2544
2545     /* If backup router, mark it as one of ours.  This server is considered
2546        to be backup router after this setting. */
2547     if (new_server->server_type == SILC_BACKUP_ROUTER) {
2548       SilcServerConfigRouter *backup;
2549       backup = silc_server_config_find_backup_conn(server, sock->ip);
2550       if (!backup)
2551         backup = silc_server_config_find_backup_conn(server, sock->hostname);
2552       if (backup) {
2553         /* Add as our backup router */
2554         silc_server_backup_add(server, new_server, backup->backup_replace_ip,
2555                                backup->backup_replace_port,
2556                                backup->backup_local);
2557       }
2558     }
2559
2560     /* By default the servers connected to backup router are disabled
2561        until backup router has become the primary */
2562     if (server->server_type == SILC_BACKUP_ROUTER &&
2563         sock->type == SILC_SOCKET_TYPE_SERVER)
2564       idata->status |= SILC_IDLIST_STATUS_DISABLED;
2565   }
2566
2567   return new_server;
2568 }
2569
2570 /* Processes incoming New ID packet. New ID Payload is used to distribute
2571    information about newly registered clients and servers. */
2572
2573 static void silc_server_new_id_real(SilcServer server, 
2574                                     SilcSocketConnection sock,
2575                                     SilcPacketContext *packet,
2576                                     int broadcast)
2577 {
2578   SilcBuffer buffer = packet->buffer;
2579   SilcIDList id_list;
2580   SilcServerEntry router, server_entry;
2581   SilcSocketConnection router_sock;
2582   SilcIDPayload idp;
2583   SilcIdType id_type;
2584   void *id;
2585
2586   SILC_LOG_DEBUG(("Processing new ID"));
2587
2588   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2589       server->server_type == SILC_SERVER ||
2590       packet->src_id_type != SILC_ID_SERVER)
2591     return;
2592
2593   idp = silc_id_payload_parse(buffer->data, buffer->len);
2594   if (!idp)
2595     return;
2596
2597   id_type = silc_id_payload_get_type(idp);
2598
2599   /* Normal server cannot have other normal server connections */
2600   server_entry = (SilcServerEntry)sock->user_data;
2601   if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER &&
2602       server_entry->server_type == SILC_SERVER)
2603     goto out;
2604
2605   id = silc_id_payload_get_id(idp);
2606   if (!id)
2607     goto out;
2608
2609   /* If the packet is coming from server then use the sender as the
2610      origin of the the packet. If it came from router then check the real
2611      sender of the packet and use that as the origin. */
2612   if (sock->type == SILC_SOCKET_TYPE_SERVER) {
2613     id_list = server->local_list;
2614     router_sock = sock;
2615     router = sock->user_data;
2616
2617     /* If the sender is backup router and ID is server (and we are not
2618        backup router) then switch the entry to global list. */
2619     if (server_entry->server_type == SILC_BACKUP_ROUTER && 
2620         id_type == SILC_ID_SERVER && 
2621         server->id_entry->server_type != SILC_BACKUP_ROUTER) {
2622       id_list = server->global_list;
2623       router_sock = server->router ? SILC_PRIMARY_ROUTE(server) : sock;
2624     }
2625   } else {
2626     void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2627                                      packet->src_id_type);
2628     router = silc_idlist_find_server_by_id(server->global_list,
2629                                            sender_id, TRUE, NULL);
2630     if (!router)
2631       router = silc_idlist_find_server_by_id(server->local_list,
2632                                              sender_id, TRUE, NULL);
2633     silc_free(sender_id);
2634     router_sock = sock;
2635     id_list = server->global_list;
2636   }
2637
2638   if (!router)
2639     goto out;
2640
2641   switch(id_type) {
2642   case SILC_ID_CLIENT:
2643     {
2644       SilcClientEntry entry;
2645
2646       /* Check that we do not have this client already */
2647       entry = silc_idlist_find_client_by_id(server->global_list, 
2648                                             id, server->server_type, 
2649                                             NULL);
2650       if (!entry)
2651         entry = silc_idlist_find_client_by_id(server->local_list, 
2652                                               id, server->server_type,
2653                                               NULL);
2654       if (entry) {
2655         SILC_LOG_DEBUG(("Ignoring client that we already have"));
2656         goto out;
2657       }
2658
2659       SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
2660                       silc_id_render(id, SILC_ID_CLIENT),
2661                       sock->type == SILC_SOCKET_TYPE_SERVER ?
2662                       "Server" : "Router", sock->hostname));
2663     
2664       /* As a router we keep information of all global information in our
2665          global list. Cell wide information however is kept in the local
2666          list. */
2667       entry = silc_idlist_add_client(id_list, NULL, NULL, NULL, 
2668                                      id, router, NULL, 0);
2669       if (!entry) {
2670         SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
2671
2672         /* Inform the sender that the ID is not usable */
2673         silc_server_send_notify_signoff(server, sock, FALSE, id, NULL);
2674         goto out;
2675       }
2676       entry->nickname = NULL;
2677       entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2678
2679       if (sock->type == SILC_SOCKET_TYPE_SERVER)
2680         server->stat.cell_clients++;
2681       server->stat.clients++;
2682
2683       /* Check if anyone is watching this nickname */
2684       if (server->server_type == SILC_ROUTER && id_list == server->local_list)
2685         silc_server_check_watcher_list(server, entry, NULL, 0);
2686     }
2687     break;
2688
2689   case SILC_ID_SERVER:
2690     {
2691       SilcServerEntry entry;
2692
2693       /* If the ID is mine, ignore it. */
2694       if (SILC_ID_SERVER_COMPARE(id, server->id)) {
2695         SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
2696         break;
2697       }
2698
2699       /* If the ID is the sender's ID, ignore it (we have it already) */
2700       if (SILC_ID_SERVER_COMPARE(id, router->id)) {
2701         SILC_LOG_DEBUG(("Ignoring sender's own ID"));
2702         break;
2703       }
2704       
2705       /* Check that we do not have this server already */
2706       entry = silc_idlist_find_server_by_id(server->global_list, 
2707                                             id, server->server_type, 
2708                                             NULL);
2709       if (!entry)
2710         entry = silc_idlist_find_server_by_id(server->local_list, 
2711                                               id, server->server_type,
2712                                               NULL);
2713       if (entry) {
2714         SILC_LOG_DEBUG(("Ignoring server that we already have"));
2715         goto out;
2716       }
2717
2718       SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
2719                       silc_id_render(id, SILC_ID_SERVER),
2720                       sock->type == SILC_SOCKET_TYPE_SERVER ?
2721                       "Server" : "Router", sock->hostname));
2722       
2723       /* As a router we keep information of all global information in our 
2724          global list. Cell wide information however is kept in the local
2725          list. */
2726       entry = silc_idlist_add_server(id_list, NULL, 0, id, router, 
2727                                      router_sock);
2728       if (!entry) {
2729         SILC_LOG_ERROR(("Could not add new server to the ID Cache"));
2730         goto out;
2731       }
2732       entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2733       
2734       if (sock->type == SILC_SOCKET_TYPE_SERVER)
2735         server->stat.cell_servers++;
2736       server->stat.servers++;
2737     }
2738     break;
2739
2740   case SILC_ID_CHANNEL:
2741     SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
2742     goto out;
2743     break;
2744
2745   default:
2746     goto out;
2747     break;
2748   }
2749
2750   /* If the sender of this packet is server and we are router we need to
2751      broadcast this packet to other routers in the network. */
2752   if (broadcast && server->server_type == SILC_ROUTER &&
2753       sock->type == SILC_SOCKET_TYPE_SERVER &&
2754       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2755     SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
2756     silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
2757                             packet->type, 
2758                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
2759                             buffer->data, buffer->len, FALSE);
2760     silc_server_backup_send(server, sock->user_data, 
2761                             packet->type, packet->flags,
2762                             packet->buffer->data, packet->buffer->len, 
2763                             FALSE, TRUE);
2764   }
2765
2766  out:
2767   silc_id_payload_free(idp);
2768 }
2769
2770
2771 /* Processes incoming New ID packet. New ID Payload is used to distribute
2772    information about newly registered clients and servers. */
2773
2774 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
2775                         SilcPacketContext *packet)
2776 {
2777   silc_server_new_id_real(server, sock, packet, TRUE);
2778 }
2779
2780 /* Receoved New Id List packet, list of New ID payloads inside one
2781    packet. Process the New ID payloads one by one. */
2782
2783 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
2784                              SilcPacketContext *packet)
2785 {
2786   SilcPacketContext *new_id;
2787   SilcBuffer idp;
2788   SilcUInt16 id_len;
2789
2790   SILC_LOG_DEBUG(("Processing New ID List"));
2791
2792   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2793       packet->src_id_type != SILC_ID_SERVER)
2794     return;
2795
2796   /* If the sender of this packet is server and we are router we need to
2797      broadcast this packet to other routers in the network. Broadcast
2798      this list packet instead of multiple New ID packets. */
2799   if (server->server_type == SILC_ROUTER &&
2800       sock->type == SILC_SOCKET_TYPE_SERVER &&
2801       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2802     SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
2803     silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
2804                             packet->type, 
2805                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
2806                             packet->buffer->data, 
2807                             packet->buffer->len, FALSE);
2808     silc_server_backup_send(server, sock->user_data, 
2809                             packet->type, packet->flags,
2810                             packet->buffer->data, packet->buffer->len, 
2811                             FALSE, TRUE);
2812   }
2813
2814   /* Make copy of the original packet context, except for the actual
2815      data buffer, which we will here now fetch from the original buffer. */
2816   new_id = silc_packet_context_alloc();
2817   new_id->type = SILC_PACKET_NEW_ID;
2818   new_id->flags = packet->flags & (~SILC_PACKET_FLAG_LIST);
2819   new_id->src_id = packet->src_id;
2820   new_id->src_id_len = packet->src_id_len;
2821   new_id->src_id_type = packet->src_id_type;
2822   new_id->dst_id = packet->dst_id;
2823   new_id->dst_id_len = packet->dst_id_len;
2824   new_id->dst_id_type = packet->dst_id_type;
2825
2826   idp = silc_buffer_alloc(256);
2827   new_id->buffer = idp;
2828
2829   while (packet->buffer->len) {
2830     SILC_GET16_MSB(id_len, packet->buffer->data + 2);
2831     if ((id_len > packet->buffer->len) ||
2832         (id_len > idp->truelen))
2833       break;
2834
2835     silc_buffer_pull_tail(idp, 4 + id_len);
2836     silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
2837
2838     /* Process the New ID */
2839     silc_server_new_id_real(server, sock, new_id, FALSE);
2840
2841     silc_buffer_push_tail(idp, 4 + id_len);
2842     silc_buffer_pull(packet->buffer, 4 + id_len);
2843   }
2844
2845   silc_buffer_free(idp);
2846   silc_free(new_id);
2847 }
2848
2849 /* Received New Channel packet. Information about new channels in the 
2850    network are distributed using this packet. Save the information about
2851    the new channel. This usually comes from router but also normal server
2852    can send this to notify channels it has when it connects to us. */
2853
2854 void silc_server_new_channel(SilcServer server,
2855                              SilcSocketConnection sock,
2856                              SilcPacketContext *packet)
2857 {
2858   SilcChannelPayload payload;
2859   SilcChannelID *channel_id;
2860   char *channel_name;
2861   SilcUInt32 name_len;
2862   unsigned char *id;
2863   SilcUInt32 id_len;
2864   SilcServerEntry server_entry;
2865   SilcChannelEntry channel;
2866
2867   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2868       packet->src_id_type != SILC_ID_SERVER ||
2869       server->server_type == SILC_SERVER)
2870     return;
2871
2872   /* Parse the channel payload */
2873   payload = silc_channel_payload_parse(packet->buffer->data,
2874                                        packet->buffer->len);
2875   if (!payload)
2876     return;
2877     
2878   /* Get the channel ID */
2879   channel_id = silc_channel_get_id_parse(payload);
2880   if (!channel_id) {
2881     silc_channel_payload_free(payload);
2882     return;
2883   }
2884
2885   channel_name = silc_channel_get_name(payload, &name_len);
2886   if (name_len > 256)
2887     channel_name[255] = '\0';
2888
2889   id = silc_channel_get_id(payload, &id_len);
2890
2891   server_entry = (SilcServerEntry)sock->user_data;
2892
2893   if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
2894     /* Add the channel to global list as it is coming from router. It 
2895        cannot be our own channel as it is coming from router. */
2896
2897     /* Check that we don't already have this channel */
2898     channel = silc_idlist_find_channel_by_name(server->local_list, 
2899                                                channel_name, NULL);
2900     if (!channel)
2901       channel = silc_idlist_find_channel_by_name(server->global_list, 
2902                                                  channel_name, NULL);
2903     if (!channel) {
2904       SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
2905                       silc_id_render(channel_id, SILC_ID_CHANNEL), 
2906                       sock->hostname));
2907     
2908       channel = 
2909         silc_idlist_add_channel(server->global_list, strdup(channel_name), 
2910                                 0, channel_id, sock->user_data, NULL, NULL, 0);
2911       if (!channel) {
2912         silc_channel_payload_free(payload);
2913         silc_free(channel_id);
2914         return;
2915       }
2916       channel->disabled = TRUE;    /* Disabled until someone JOINs */
2917
2918       server->stat.channels++;
2919       if (server->server_type == SILC_ROUTER)
2920         channel->users_resolved = TRUE;
2921     }
2922   } else {
2923     /* The channel is coming from our server, thus it is in our cell
2924        we will add it to our local list. */
2925     SilcBuffer chk;
2926
2927     SILC_LOG_DEBUG(("Channel id(%s) from [Server] %s",
2928                     silc_id_render(channel_id, SILC_ID_CHANNEL), 
2929                     sock->hostname));
2930
2931     /* Check that we don't already have this channel */
2932     channel = silc_idlist_find_channel_by_name(server->local_list, 
2933                                                channel_name, NULL);
2934     if (!channel)
2935       channel = silc_idlist_find_channel_by_name(server->global_list, 
2936                                                  channel_name, NULL);
2937
2938     /* If the channel does not exist, then create it. This creates a new
2939        key to the channel as well that we will send to the server. */
2940     if (!channel) {
2941       SILC_LOG_DEBUG(("Channel is new to us"));
2942
2943       /* The protocol says that the Channel ID's IP address must be based
2944          on the router's IP address.  Check whether the ID is based in our
2945          IP and if it is not then create a new ID and enforce the server
2946          to switch the ID. */
2947       if (server_entry->server_type != SILC_BACKUP_ROUTER &&
2948           !SILC_ID_COMPARE(channel_id, server->id, server->id->ip.data_len)) {
2949         SilcChannelID *tmp;
2950         SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2951         if (silc_id_create_channel_id(server, server->id, server->rng, &tmp)) {
2952           silc_server_send_notify_channel_change(server, sock, FALSE, 
2953                                                  channel_id, tmp);
2954           silc_channel_payload_free(payload);
2955           silc_free(channel_id);
2956           silc_free(tmp);
2957         }
2958
2959         /* Wait that server re-announces this channel */
2960         return;
2961       }
2962
2963       /* Create the channel with the provided Channel ID */
2964       channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
2965                                                        channel_name,
2966                                                        channel_id, FALSE);
2967       if (!channel) {
2968         silc_channel_payload_free(payload);
2969         silc_free(channel_id);
2970         return;
2971       }
2972       channel->disabled = TRUE;    /* Disabled until someone JOINs */
2973
2974 #if 0 /* We assume that CMODE_CHANGE notify is sent to us after this. */
2975
2976       /* XXX Dunno if this is supposed to be set in any server type.  If set
2977          here the CMODE_CHANGE that may follow sets mode that we already
2978          have, and we may loose data from the CMODE_CHANGE notify. */
2979       if (server_entry->server_type != SILC_BACKUP_ROUTER)
2980         channel->mode = silc_channel_get_mode(payload);
2981 #endif
2982
2983       /* Send the new channel key to the server */
2984       id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2985       id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
2986       chk = silc_channel_key_payload_encode(id_len, id,
2987                                             strlen(channel->channel_key->
2988                                                    cipher->name),
2989                                             channel->channel_key->cipher->name,
2990                                             channel->key_len / 8, 
2991                                             channel->key);
2992       silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
2993                               chk->data, chk->len, FALSE);
2994       silc_buffer_free(chk);
2995       silc_free(id);
2996     } else {
2997       /* The channel exist by that name, check whether the ID's match.
2998          If they don't then we'll force the server to use the ID we have.
2999          We also create a new key for the channel. */
3000       SilcBuffer modes = NULL, users = NULL, users_modes = NULL;
3001
3002       SILC_LOG_DEBUG(("Channel already exists"));
3003
3004       if (!SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
3005         /* They don't match, send CHANNEL_CHANGE notify to the server to
3006            force the ID change. */
3007         SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
3008         silc_server_send_notify_channel_change(server, sock, FALSE, 
3009                                                channel_id, channel->id);
3010         silc_channel_payload_free(payload);
3011         silc_free(channel_id);
3012
3013         /* Wait that server re-announces this channel */
3014         return;
3015       }
3016
3017 #if 0 /* We will announce our CMODE anyway for this channel, so no need
3018          to check it (implicit enforce). */
3019
3020       /* If the mode is different from what we have then enforce the
3021          mode change. */
3022       mode = silc_channel_get_mode(payload);
3023       if (channel->mode != mode) {
3024         SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
3025         silc_server_send_notify_cmode(server, sock, FALSE, channel,
3026                                       channel->mode, server->id,
3027                                       SILC_ID_SERVER, channel->cipher,
3028                                       channel->hmac_name,
3029                                       channel->passphrase,
3030                                       channel->founder_key);
3031       }
3032 #endif
3033
3034       /* Create new key for the channel and send it to the server and
3035          everybody else possibly on the channel. */
3036       if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3037
3038         if (silc_hash_table_count(channel->user_list)) {
3039           if (!silc_server_create_channel_key(server, channel, 0)) {
3040             silc_channel_payload_free(payload);
3041             silc_free(channel_id);
3042             return;
3043           }
3044
3045           /* Send to the channel */
3046           silc_server_send_channel_key(server, sock, channel, FALSE);
3047         }
3048
3049         /* Send to the server */
3050         id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3051         id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
3052         chk = silc_channel_key_payload_encode(id_len, id,
3053                                               strlen(channel->channel_key->
3054                                                      cipher->name),
3055                                               channel->channel_key->
3056                                               cipher->name,
3057                                               channel->key_len / 8, 
3058                                               channel->key);
3059         silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
3060                                 chk->data, chk->len, FALSE);
3061         silc_buffer_free(chk);
3062         silc_free(id);
3063       }
3064
3065       silc_free(channel_id);
3066
3067       /* Update statistics */
3068       server->stat.channels++;
3069       server->stat.cell_channels++;
3070
3071       /* Since the channel is coming from server and we also know about it
3072          then send the JOIN notify to the server so that it see's our
3073          users on the channel "joining" the channel. */
3074       silc_server_announce_get_channel_users(server, channel, &modes, &users,
3075                                              &users_modes);
3076       if (users) {
3077         silc_buffer_push(users, users->data - users->head);
3078         silc_server_packet_send(server, sock,
3079                                 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3080                                 users->data, users->len, FALSE);
3081         silc_buffer_free(users);
3082       }
3083       if (modes) {
3084         silc_buffer_push(modes, modes->data - modes->head);
3085         silc_server_packet_send_dest(server, sock,
3086                                      SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3087                                      channel->id, SILC_ID_CHANNEL,
3088                                      modes->data, modes->len, FALSE);
3089         silc_buffer_free(modes);
3090       }
3091       if (users_modes) {
3092         silc_buffer_push(users_modes, users_modes->data - users_modes->head);
3093         silc_server_packet_send_dest(server, sock,
3094                                      SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3095                                      channel->id, SILC_ID_CHANNEL,
3096                                      users_modes->data, 
3097                                      users_modes->len, FALSE);
3098         silc_buffer_free(users_modes);
3099       }
3100       if (channel->topic) {
3101         silc_server_send_notify_topic_set(server, sock,
3102                                           server->server_type == SILC_ROUTER ?
3103                                           TRUE : FALSE, channel, 
3104                                           server->id, SILC_ID_SERVER,
3105                                           channel->topic);
3106       }
3107     }
3108   }
3109
3110   /* If the sender of this packet is server and we are router we need to
3111      broadcast this packet to other routers in the network. Broadcast
3112      this list packet instead of multiple New Channel packets. */
3113   if (server->server_type == SILC_ROUTER &&
3114       sock->type == SILC_SOCKET_TYPE_SERVER &&
3115       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
3116     SILC_LOG_DEBUG(("Broadcasting received New Channel packet"));
3117     silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
3118                             packet->type, 
3119                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
3120                             packet->buffer->data, 
3121                             packet->buffer->len, FALSE);
3122     silc_server_backup_send(server, sock->user_data, 
3123                             packet->type, packet->flags,
3124                             packet->buffer->data, packet->buffer->len, 
3125                             FALSE, TRUE);
3126   }
3127
3128   silc_channel_payload_free(payload);
3129 }
3130
3131 /* Received New Channel List packet, list of New Channel List payloads inside
3132    one packet. Process the New Channel payloads one by one. */
3133
3134 void silc_server_new_channel_list(SilcServer server,
3135                                   SilcSocketConnection sock,
3136                                   SilcPacketContext *packet)
3137 {
3138   SilcPacketContext *new;
3139   SilcBuffer buffer;
3140   SilcUInt16 len1, len2;
3141
3142   SILC_LOG_DEBUG(("Processing New Channel List"));
3143
3144   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
3145       packet->src_id_type != SILC_ID_SERVER ||
3146       server->server_type == SILC_SERVER)
3147     return;
3148
3149   /* Make copy of the original packet context, except for the actual
3150      data buffer, which we will here now fetch from the original buffer. */
3151   new = silc_packet_context_alloc();
3152   new->type = SILC_PACKET_NEW_CHANNEL;
3153   new->flags = packet->flags & (~SILC_PACKET_FLAG_LIST);
3154   new->src_id = packet->src_id;
3155   new->src_id_len = packet->src_id_len;
3156   new->src_id_type = packet->src_id_type;
3157   new->dst_id = packet->dst_id;
3158   new->dst_id_len = packet->dst_id_len;
3159   new->dst_id_type = packet->dst_id_type;
3160
3161   buffer = silc_buffer_alloc(512);
3162   new->buffer = buffer;
3163
3164   while (packet->buffer->len) {
3165     SILC_GET16_MSB(len1, packet->buffer->data);
3166     if ((len1 > packet->buffer->len) ||
3167         (len1 > buffer->truelen))
3168       break;
3169
3170     SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
3171     if ((len2 > packet->buffer->len) ||
3172         (len2 > buffer->truelen))
3173       break;
3174
3175     silc_buffer_pull_tail(buffer, 8 + len1 + len2);
3176     silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
3177
3178     /* Process the New Channel */
3179     silc_server_new_channel(server, sock, new);
3180
3181     silc_buffer_push_tail(buffer, 8 + len1 + len2);
3182     silc_buffer_pull(packet->buffer, 8 + len1 + len2);
3183   }
3184
3185   silc_buffer_free(buffer);
3186   silc_free(new);
3187 }
3188
3189 /* Received key agreement packet. This packet is never for us. It is to
3190    the client in the packet's destination ID. Sending of this sort of packet
3191    equals sending private message, ie. it is sent point to point from
3192    one client to another. */
3193
3194 void silc_server_key_agreement(SilcServer server,
3195                                SilcSocketConnection sock,
3196                                SilcPacketContext *packet)
3197 {
3198   SilcSocketConnection dst_sock;
3199   SilcIDListData idata;
3200
3201   SILC_LOG_DEBUG(("Start"));
3202
3203   if (packet->src_id_type != SILC_ID_CLIENT ||
3204       packet->dst_id_type != SILC_ID_CLIENT)
3205     return;
3206
3207   if (!packet->dst_id)
3208     return;
3209
3210   /* Get the route to the client */
3211   dst_sock = silc_server_get_client_route(server, packet->dst_id,
3212                                           packet->dst_id_len, NULL, 
3213                                           &idata, NULL);
3214   if (!dst_sock)
3215     return;
3216
3217   /* Relay the packet */
3218   silc_server_relay_packet(server, dst_sock, idata->send_key,
3219                            idata->hmac_send, idata->psn_send++,
3220                            packet, FALSE);
3221 }
3222
3223 /* Received connection auth request packet that is used during connection
3224    phase to resolve the mandatory authentication method.  This packet can
3225    actually be received at anytime but usually it is used only during
3226    the connection authentication phase. Now, protocol says that this packet
3227    can come from client or server, however, we support only this coming
3228    from client and expect that server always knows what authentication
3229    method to use. */
3230
3231 void silc_server_connection_auth_request(SilcServer server,
3232                                          SilcSocketConnection sock,
3233                                          SilcPacketContext *packet)
3234 {
3235   SilcServerConfigClient *client = NULL;
3236   SilcUInt16 conn_type;
3237   int ret;
3238   SilcAuthMethod auth_meth = SILC_AUTH_NONE;
3239
3240   if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT) {
3241     SILC_LOG_DEBUG(("Request not from client"));
3242     return;
3243   }
3244
3245   /* Parse the payload */
3246   ret = silc_buffer_unformat(packet->buffer,
3247                              SILC_STR_UI_SHORT(&conn_type),
3248                              SILC_STR_UI_SHORT(NULL),
3249                              SILC_STR_END);
3250   if (ret == -1)
3251     return;
3252
3253   if (conn_type != SILC_SOCKET_TYPE_CLIENT)
3254     return;
3255
3256   /* Get the authentication method for the client */
3257   auth_meth = SILC_AUTH_NONE;
3258   client = silc_server_config_find_client(server, sock->ip);
3259   if (!client)
3260     client = silc_server_config_find_client(server, sock->hostname);
3261   if (client) {
3262     if (client->passphrase) {
3263       if (client->publickeys && !server->config->prefer_passphrase_auth)
3264         auth_meth = SILC_AUTH_PUBLIC_KEY;
3265       else
3266         auth_meth = SILC_AUTH_PASSWORD;
3267     } else if (client->publickeys)
3268       auth_meth = SILC_AUTH_PUBLIC_KEY;
3269   }
3270
3271   SILC_LOG_DEBUG(("Authentication method is [%s]",
3272                   (auth_meth == SILC_AUTH_NONE ? "None" :
3273                    auth_meth == SILC_AUTH_PASSWORD ? "Passphrase" :
3274                    "Digital signatures")));
3275
3276   /* Send it back to the client */
3277   silc_server_send_connection_auth_request(server, sock, conn_type, auth_meth);
3278 }
3279
3280 /* Received REKEY packet. The sender of the packet wants to regenerate
3281    its session keys. This starts the REKEY protocol. */
3282
3283 void silc_server_rekey(SilcServer server,
3284                        SilcSocketConnection sock,
3285                        SilcPacketContext *packet)
3286 {
3287   SilcProtocol protocol;
3288   SilcServerRekeyInternalContext *proto_ctx;
3289   SilcIDListData idata = (SilcIDListData)sock->user_data;
3290
3291   SILC_LOG_DEBUG(("Start"));
3292
3293   /* Allocate internal protocol context. This is sent as context
3294      to the protocol. */
3295   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
3296   proto_ctx->server = (void *)server;
3297   proto_ctx->sock = sock;
3298   proto_ctx->responder = TRUE;
3299   proto_ctx->pfs = idata->rekey->pfs;
3300       
3301   /* Perform rekey protocol. Will call the final callback after the
3302      protocol is over. */
3303   silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY, 
3304                       &protocol, proto_ctx, silc_server_rekey_final);
3305   sock->protocol = protocol;
3306
3307   if (proto_ctx->pfs == FALSE)
3308     /* Run the protocol */
3309     silc_protocol_execute(protocol, server->schedule, 0, 0);
3310 }
3311
3312 /* Received file transger packet. This packet is never for us. It is to
3313    the client in the packet's destination ID. Sending of this sort of packet
3314    equals sending private message, ie. it is sent point to point from
3315    one client to another. */
3316
3317 void silc_server_ftp(SilcServer server,
3318                      SilcSocketConnection sock,
3319                      SilcPacketContext *packet)
3320 {
3321   SilcSocketConnection dst_sock;
3322   SilcIDListData idata;
3323
3324   SILC_LOG_DEBUG(("Start"));
3325
3326   if (packet->src_id_type != SILC_ID_CLIENT ||
3327       packet->dst_id_type != SILC_ID_CLIENT)
3328     return;
3329
3330   if (!packet->dst_id)
3331     return;
3332
3333   /* Get the route to the client */
3334   dst_sock = silc_server_get_client_route(server, packet->dst_id,
3335                                           packet->dst_id_len, NULL, 
3336                                           &idata, NULL);
3337   if (!dst_sock)
3338     return;
3339
3340   /* Relay the packet */
3341   silc_server_relay_packet(server, dst_sock, idata->send_key,
3342                            idata->hmac_send, idata->psn_send++,
3343                            packet, FALSE);
3344 }
3345
3346 typedef struct {
3347   SilcServer server;
3348   SilcSocketConnection sock;
3349   SilcPacketContext *packet;
3350   void *data;
3351 } *SilcServerResumeResolve;
3352
3353 SILC_SERVER_CMD_FUNC(resume_resolve)
3354 {
3355   SilcServerResumeResolve r = (SilcServerResumeResolve)context;
3356   SilcServer server = r->server;
3357   SilcSocketConnection sock = r->sock;
3358   SilcServerCommandReplyContext reply = context2;
3359   SilcClientEntry client;
3360
3361   SILC_LOG_DEBUG(("Start"));
3362
3363   if (!reply || !silc_command_get_status(reply->payload, NULL, NULL)) {
3364     SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3365                     "closing connection", sock->hostname, sock->ip));
3366     silc_server_disconnect_remote(server, sock,
3367                                   SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3368                                   "Resuming not possible");
3369     if (sock->user_data)
3370       silc_server_free_sock_user_data(server, sock, NULL);
3371     goto out;
3372   }
3373
3374   if (reply && silc_command_get(reply->payload) == SILC_COMMAND_WHOIS) {
3375     /* Get entry to the client, and resolve it if we don't have it. */
3376     client = silc_idlist_find_client_by_id(server->local_list, 
3377                                            r->data, TRUE, NULL);
3378     if (!client) {
3379       client = silc_idlist_find_client_by_id(server->global_list,
3380                                              r->data, TRUE, NULL);
3381       if (!client) {
3382         SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3383                         "closing connection", sock->hostname, sock->ip));
3384         silc_server_disconnect_remote(server, sock,
3385                                       SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3386                                       "Resuming not possible");
3387         if (sock->user_data)
3388           silc_server_free_sock_user_data(server, sock, NULL);
3389         goto out;
3390       }
3391     }
3392
3393     if (!(client->mode & SILC_UMODE_DETACHED)) {
3394       SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, "
3395                       "closing connection", sock->hostname, sock->ip));
3396       silc_server_disconnect_remote(server, sock,
3397                                     SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3398                                     "Resuming not possible");
3399       if (sock->user_data)
3400         silc_server_free_sock_user_data(server, sock, NULL);
3401       goto out;
3402     }
3403
3404     client->data.status |= SILC_IDLIST_STATUS_RESUME_RES;
3405   }
3406
3407   /* Reprocess the packet */
3408   silc_server_resume_client(server, sock, r->packet);
3409
3410  out:
3411   silc_socket_free(r->sock);
3412   silc_packet_context_free(r->packet);
3413   silc_free(r->data);
3414   silc_free(r);
3415 }
3416
3417 /* Received client resuming packet.  This is used to resume detached
3418    client session.  It can be sent by the client who wishes to resume
3419    but this is also sent by servers and routers to notify other routers
3420    that the client is not detached anymore. */
3421
3422 void silc_server_resume_client(SilcServer server,
3423                                SilcSocketConnection sock,
3424                                SilcPacketContext *packet)
3425 {
3426   SilcBuffer buffer = packet->buffer, buf;
3427   SilcIDListData idata;
3428   SilcIDCacheEntry id_cache = NULL;
3429   SilcClientEntry detached_client;
3430   SilcClientID *client_id = NULL;
3431   unsigned char *id_string, *auth = NULL;
3432   SilcUInt16 id_len, auth_len = 0;
3433   int ret, nickfail = 0;
3434   bool resolved, local, nick_change = FALSE, resolve = FALSE;
3435   SilcChannelEntry channel;
3436   SilcHashTableList htl;
3437   SilcChannelClientEntry chl;
3438   SilcServerResumeResolve r;
3439
3440   ret = silc_buffer_unformat(buffer,
3441                              SILC_STR_UI16_NSTRING(&id_string, &id_len),
3442                              SILC_STR_END);
3443   if (ret != -1)
3444     client_id = silc_id_str2id(id_string, id_len, SILC_ID_CLIENT);
3445
3446   if (sock->type == SILC_SOCKET_TYPE_CLIENT) {
3447     /* Client send this and is attempting to resume to old client session */
3448     SilcClientEntry client;
3449     SilcBuffer keyp;
3450
3451     if (ret != -1) {
3452       silc_buffer_pull(buffer, 2 + id_len);
3453       auth = buffer->data;
3454       auth_len = buffer->len;
3455       silc_buffer_push(buffer, 2 + id_len);
3456     }
3457
3458     if (!client_id || auth_len < 128) {
3459       SILC_LOG_ERROR(("Client %s (%s) sent incomplete resume information, "
3460                       "closing connection", sock->hostname, sock->ip));
3461       silc_server_disconnect_remote(server, sock,
3462                                     SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3463                                     "Resuming not possible");
3464       if (sock->user_data)
3465         silc_server_free_sock_user_data(server, sock, NULL);
3466       silc_free(client_id);
3467       return;
3468     }
3469
3470     /* Take client entry of this connection */
3471     client = (SilcClientEntry)sock->user_data;
3472     idata = (SilcIDListData)client;
3473
3474     /* Get entry to the client, and resolve it if we don't have it. */
3475     detached_client = silc_server_query_client(server, client_id, FALSE,
3476                                                &resolved);
3477     if (!detached_client) {
3478       if (resolved) {
3479         /* The client info is being resolved. Reprocess this packet after
3480            receiving the reply to the query. */
3481         SILC_LOG_DEBUG(("Resolving client"));
3482         r = silc_calloc(1, sizeof(*r));
3483         if (!r)
3484           return;
3485         r->server = server;
3486         r->sock = silc_socket_dup(sock);
3487         r->packet = silc_packet_context_dup(packet);
3488         r->data = client_id;
3489         silc_server_command_pending(server, SILC_COMMAND_WHOIS,
3490                                     server->cmd_ident,
3491                                     silc_server_command_resume_resolve, r);
3492       } else {
3493         SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3494                         "closing connection", sock->hostname, sock->ip));
3495         silc_server_disconnect_remote(server, sock,
3496                                       SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3497                                       "Resuming not possible");
3498         if (sock->user_data)
3499           silc_server_free_sock_user_data(server, sock, NULL);
3500         silc_free(client_id);
3501       }
3502       return;
3503     }
3504
3505     if (!(detached_client->mode & SILC_UMODE_DETACHED))
3506       resolve = TRUE;
3507     if (!silc_hash_table_count(detached_client->channels) &&
3508         detached_client->router)
3509       resolve = TRUE;
3510     if (!detached_client->nickname)
3511       resolve = TRUE;
3512     if (detached_client->data.status & SILC_IDLIST_STATUS_RESUME_RES)
3513       resolve = FALSE;
3514
3515     if (resolve) {
3516       if (server->server_type == SILC_SERVER && !server->standalone) {
3517         /* The client info is being resolved. Reprocess this packet after
3518            receiving the reply to the query. */
3519         SILC_LOG_DEBUG(("Resolving client info"));
3520         silc_server_query_client(server, client_id, TRUE, NULL);
3521         r = silc_calloc(1, sizeof(*r));
3522         if (!r)
3523           return;
3524         r->server = server;
3525         r->sock = silc_socket_dup(sock);
3526         r->packet = silc_packet_context_dup(packet);
3527         r->data = client_id;
3528         silc_server_command_pending(server, SILC_COMMAND_WHOIS,
3529                                     server->cmd_ident,
3530                                     silc_server_command_resume_resolve, r);
3531         return;
3532       }
3533       if (server->server_type == SILC_SERVER) {
3534         SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, "
3535                         "closing connection", sock->hostname, sock->ip));
3536         silc_server_disconnect_remote(server, sock,
3537                                       SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3538                                       "Resuming not possible");
3539         if (sock->user_data)
3540           silc_server_free_sock_user_data(server, sock, NULL);
3541         silc_free(client_id);
3542         return;
3543       }
3544     }
3545
3546     /* Check that we have the public key of the client, if not then we must
3547        resolve it first. */
3548     if (!detached_client->data.public_key) {
3549       if (server->server_type == SILC_SERVER && server->standalone) {
3550         SILC_LOG_ERROR(("Detached client's public key not present, "
3551                         "closing connection"));
3552         silc_server_disconnect_remote(server, sock,
3553                                       SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3554                                       "Resuming not possible");
3555         if (sock->user_data)
3556           silc_server_free_sock_user_data(server, sock, NULL);
3557         silc_free(client_id);
3558       } else {
3559         /* We must retrieve the detached client's public key by sending
3560            GETKEY command. Reprocess this packet after receiving the key */
3561         SilcBuffer idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
3562         SilcSocketConnection dest_sock = 
3563           silc_server_get_client_route(server, NULL, 0, client_id, NULL, NULL);
3564
3565         SILC_LOG_DEBUG(("Resolving client public key"));
3566
3567         silc_server_send_command(server, dest_sock ? dest_sock : 
3568                                  SILC_PRIMARY_ROUTE(server),
3569                                  SILC_COMMAND_GETKEY, ++server->cmd_ident,
3570                                  1, 1, idp->data, idp->len);
3571
3572         r = silc_calloc(1, sizeof(*r));
3573         if (!r) {
3574           silc_free(client_id);
3575           return;
3576         }
3577
3578         r->server = server;
3579         r->sock = silc_socket_dup(sock);
3580         r->packet = silc_packet_context_dup(packet);
3581         silc_server_command_pending(server, SILC_COMMAND_GETKEY,
3582                                     server->cmd_ident,
3583                                     silc_server_command_resume_resolve, r);
3584
3585         silc_buffer_free(idp);
3586       }
3587       silc_free(client_id);
3588       return;
3589     } else if (!silc_pkcs_public_key_compare(detached_client->data.public_key,
3590                                              idata->public_key)) {
3591       /* We require that the connection and resuming authentication data
3592          must be using same key pair. */
3593       SILC_LOG_ERROR(("Resuming attempted with wrong public key, "
3594                       "closing connection"));
3595       silc_server_disconnect_remote(server, sock,
3596                                     SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3597                                     "Resuming not possible");
3598       if (sock->user_data)
3599         silc_server_free_sock_user_data(server, sock, NULL);
3600       silc_free(client_id);
3601       return;
3602     }
3603
3604     /* Verify the authentication payload.  This has to be successful in
3605        order to allow the resuming */
3606     if (!idata->hash ||
3607         !silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
3608                                detached_client->data.public_key, 0,
3609                                idata->hash, detached_client->id, 
3610                                SILC_ID_CLIENT)) {
3611       SILC_LOG_ERROR(("Client %s (%s) resume authentication failed, "
3612                       "closing connection", sock->hostname, sock->ip));
3613       silc_server_disconnect_remote(server, sock,
3614                                     SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3615                                     "Resuming not possible");
3616       if (sock->user_data)
3617         silc_server_free_sock_user_data(server, sock, NULL);
3618       silc_free(client_id);
3619       return;
3620     }
3621
3622     /* Now resume the client to the network */
3623
3624     silc_schedule_task_del_by_context(server->schedule, detached_client);
3625     sock->user_data = detached_client;
3626     detached_client->connection = sock;
3627
3628     /* Take new keys and stuff into use in the old entry */
3629     silc_idlist_del_data(detached_client);
3630     silc_idlist_add_data(detached_client, idata);
3631     detached_client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
3632     detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
3633     detached_client->data.status &= ~SILC_IDLIST_STATUS_RESUME_RES;
3634     detached_client->mode &= ~SILC_UMODE_DETACHED;
3635     server->stat.my_detached--;
3636
3637     /* Send the RESUME_CLIENT packet to our primary router so that others
3638        know this client isn't detached anymore. */
3639     buf = silc_buffer_alloc_size(2 + id_len);
3640     silc_buffer_format(buf,
3641                        SILC_STR_UI_SHORT(id_len),
3642                        SILC_STR_UI_XNSTRING(id_string, id_len),
3643                        SILC_STR_END);
3644
3645     /* Send to primary router */
3646     silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
3647                             SILC_PACKET_RESUME_CLIENT, 0, 
3648                             buf->data, buf->len, TRUE);
3649
3650     /* As router we must deliver this packet directly to the original
3651        server whom this client was earlier. */
3652     if (server->server_type == SILC_ROUTER && detached_client->router &&
3653         detached_client->router->server_type != SILC_ROUTER)
3654       silc_server_packet_send(server, detached_client->router->connection,
3655                               SILC_PACKET_RESUME_CLIENT, 0, 
3656                               buf->data, buf->len, TRUE);
3657     silc_buffer_free(buf);
3658
3659     detached_client->router = NULL;
3660
3661     /* Delete this client entry since we're resuming to old one. */
3662     server->stat.my_clients--;
3663     server->stat.clients--;
3664     if (server->stat.cell_clients)
3665       server->stat.cell_clients--;
3666     silc_server_remove_from_channels(server, NULL, client, FALSE, NULL, FALSE);
3667     silc_server_del_from_watcher_list(server, client);
3668     if (!silc_idlist_del_client(server->local_list, client))
3669       silc_idlist_del_client(server->global_list, client);
3670     client = detached_client;
3671
3672     /* If the ID is not based in our ID then change it */
3673     if (!SILC_ID_COMPARE(client->id, server->id, server->id->ip.data_len)) {
3674       silc_free(client_id);
3675       while (!silc_id_create_client_id(server, server->id, server->rng, 
3676                                        server->md5hash, client->nickname, 
3677                                        &client_id)) {
3678         nickfail++;
3679         if (nickfail > 9) {
3680           silc_server_disconnect_remote(server, sock, 
3681                                         SILC_STATUS_ERR_BAD_NICKNAME, NULL);
3682           if (sock->user_data)
3683             silc_server_free_sock_user_data(server, sock, NULL);
3684           return;
3685         }
3686         snprintf(&client->nickname[strlen(client->nickname) - 1], 1, 
3687                  "%d", nickfail);
3688       }
3689       nick_change = TRUE;
3690     }
3691
3692     if (nick_change) {
3693       /* Notify about Client ID change, nickname doesn't actually change. */
3694       silc_server_send_notify_nick_change(server, SILC_PRIMARY_ROUTE(server),
3695                                           SILC_BROADCAST(server),
3696                                           client->id, client_id,
3697                                           client->nickname);
3698     }
3699
3700     /* Resolve users on those channels that client has joined but we
3701        haven't resolved user list yet. */
3702     if (server->server_type == SILC_SERVER && !server->standalone) {
3703       silc_hash_table_list(client->channels, &htl);
3704       while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
3705         channel = chl->channel;
3706         SILC_LOG_DEBUG(("Resolving users for %s channel", 
3707                         channel->channel_name));
3708         if (channel->disabled || !channel->users_resolved) {
3709           silc_server_send_command(server, SILC_PRIMARY_ROUTE(server),
3710                                    SILC_COMMAND_USERS, ++server->cmd_ident,
3711                                    1, 2, channel->channel_name,
3712                                    strlen(channel->channel_name));
3713         }
3714       }
3715       silc_hash_table_list_reset(&htl);
3716     }
3717
3718     /* Send the new client ID to the client. After this client may start
3719        receiving other packets, and may start sending packets too. */
3720     silc_server_send_new_id(server, sock, FALSE, client_id, SILC_ID_CLIENT,
3721                             silc_id_get_len(client_id, SILC_ID_CLIENT));
3722
3723     if (nick_change) {
3724       /* Send NICK change notify to channels as well. */
3725       SilcBuffer oidp, nidp;
3726       oidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3727       nidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
3728       silc_server_send_notify_on_channels(server, NULL, client, 
3729                                           SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
3730                                           oidp->data, oidp->len, 
3731                                           nidp->data, nidp->len,
3732                                           client->nickname, 
3733                                           strlen(client->nickname));
3734       silc_buffer_free(oidp);
3735       silc_buffer_free(nidp);
3736     }
3737
3738     /* Add the client again to the ID cache to get it to correct list */
3739     if (!silc_idcache_del_by_context(server->local_list->clients, client))
3740       silc_idcache_del_by_context(server->global_list->clients, client);
3741     silc_free(client->id);
3742     client->id = client_id;
3743     client_id = NULL;
3744     silc_idcache_add(server->local_list->clients, client->nickname,
3745                      client->id, client, 0, NULL);
3746
3747     /* Send some nice info to the client */
3748     silc_server_send_connect_notifys(server, sock, client);
3749
3750     /* Send all channel keys of channels the client has joined */
3751     silc_hash_table_list(client->channels, &htl);
3752     while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
3753       bool created = FALSE;
3754       channel = chl->channel;
3755
3756       if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY)
3757         continue;
3758
3759       /* If we don't have channel key, then create one */
3760       if (!channel->channel_key) {
3761         if (!silc_server_create_channel_key(server, channel, 0))
3762           continue;
3763         created = TRUE;
3764       }
3765
3766       id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3767       keyp = 
3768         silc_channel_key_payload_encode(silc_id_get_len(channel->id,
3769                                                         SILC_ID_CHANNEL), 
3770                                         id_string,
3771                                         strlen(channel->channel_key->
3772                                                cipher->name),
3773                                         channel->channel_key->cipher->name,
3774                                         channel->key_len / 8, channel->key);
3775       silc_free(id_string);
3776
3777       /* Send the key packet to client */
3778       silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
3779                               keyp->data, keyp->len, FALSE);
3780
3781       if (created && server->server_type == SILC_SERVER)
3782         silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server), 
3783                                 SILC_PACKET_CHANNEL_KEY, 0, 
3784                                 keyp->data, keyp->len, FALSE);
3785
3786       silc_buffer_free(keyp);
3787     }
3788     silc_hash_table_list_reset(&htl);
3789
3790   } else if (sock->type != SILC_SOCKET_TYPE_CLIENT) {
3791     /* Server or router sent this to us to notify that that a client has
3792        been resumed. */
3793     SilcServerEntry server_entry;
3794     SilcServerID *server_id;
3795
3796     if (!client_id) {
3797       SILC_LOG_DEBUG(("Malformed resuming packet"));
3798       return;
3799     }
3800
3801     /* Get entry to the client, and resolve it if we don't have it. */
3802     detached_client = silc_idlist_find_client_by_id(server->local_list, 
3803                                                     client_id, TRUE,
3804                                                     &id_cache);
3805     if (!detached_client) {
3806       detached_client = silc_idlist_find_client_by_id(server->global_list,
3807                                                       client_id, TRUE,
3808                                                       &id_cache);
3809       if (!detached_client) {
3810         SILC_LOG_DEBUG(("Resuming client is unknown"));
3811         silc_free(client_id);
3812         return;
3813       }
3814     }
3815
3816     /* Check that the client has not been resumed already because it is
3817        protocol error to attempt to resume more than once.  The client
3818        will be killed if this protocol error occurs. */
3819     if (detached_client->data.status & SILC_IDLIST_STATUS_RESUMED &&
3820         !(detached_client->mode & SILC_UMODE_DETACHED)) {
3821       /* The client is clearly attempting to resume more than once and
3822          perhaps playing around by resuming from several different places
3823          at the same time. */
3824       SILC_LOG_DEBUG(("Attempting to re-resume client, killing both"));
3825       silc_server_kill_client(server, detached_client, NULL,
3826                               server->id, SILC_ID_SERVER);
3827       silc_free(client_id);
3828       return;
3829     }
3830
3831     /* Check whether client is detached at all */
3832     if (!(detached_client->mode & SILC_UMODE_DETACHED)) {
3833       SILC_LOG_DEBUG(("Client is not detached"));
3834       silc_free(client_id);
3835       return;
3836     }
3837
3838     SILC_LOG_DEBUG(("Resuming detached client"));
3839
3840     /* If the sender of this packet is server and we are router we need to
3841        broadcast this packet to other routers in the network. */
3842     if (server->server_type == SILC_ROUTER &&
3843         sock->type == SILC_SOCKET_TYPE_SERVER &&
3844         !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
3845       SILC_LOG_DEBUG(("Broadcasting received Resume Client packet"));
3846       silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
3847                               packet->type, 
3848                               packet->flags | SILC_PACKET_FLAG_BROADCAST,
3849                               buffer->data, buffer->len, FALSE);
3850       silc_server_backup_send(server, sock->user_data, 
3851                               packet->type, packet->flags,
3852                               packet->buffer->data, packet->buffer->len, 
3853                               FALSE, TRUE);
3854     }
3855
3856     /* Client is detached, and now it is resumed.  Remove the detached
3857        mode and mark that it is resumed. */
3858     detached_client->mode &= ~SILC_UMODE_DETACHED;
3859     detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
3860     detached_client->data.status &= ~SILC_IDLIST_STATUS_LOCAL;
3861     id_cache->expire = 0;
3862
3863     /* Update channel information regarding global clients on channel. */
3864     if (server->server_type == SILC_SERVER) {
3865       silc_hash_table_list(detached_client->channels, &htl);
3866       while (silc_hash_table_get(&htl, NULL, (void **)&chl))
3867         chl->channel->global_users = 
3868           silc_server_channel_has_global(chl->channel);
3869       silc_hash_table_list_reset(&htl);
3870     }
3871
3872     silc_schedule_task_del_by_context(server->schedule, detached_client);
3873
3874     /* Get the new owner of the resumed client */
3875     server_id = silc_id_str2id(packet->src_id, packet->src_id_len,
3876                                packet->src_id_type);
3877     if (!server_id) {
3878       silc_free(client_id);
3879       return;
3880     }
3881
3882     /* Get server entry */
3883     server_entry = silc_idlist_find_server_by_id(server->global_list, 
3884                                                  server_id, TRUE, NULL);
3885     local = FALSE;
3886     if (!server_entry) {
3887       server_entry = silc_idlist_find_server_by_id(server->local_list, 
3888                                                    server_id, TRUE, NULL);
3889       local = TRUE;
3890       if (!server_entry) {
3891         silc_free(server_id);
3892         silc_free(client_id);
3893         return;
3894       }
3895     }
3896
3897     if (server->server_type == SILC_ROUTER &&
3898         sock->type == SILC_SOCKET_TYPE_ROUTER && 
3899         server_entry->server_type == SILC_ROUTER)
3900       local = FALSE;
3901
3902     /* Change the client to correct list. */
3903     if (!silc_idcache_del_by_context(server->local_list->clients,
3904                                      detached_client))
3905       silc_idcache_del_by_context(server->global_list->clients,
3906                                   detached_client);
3907     silc_idcache_add(local && server->server_type == SILC_ROUTER ? 
3908                      server->local_list->clients : 
3909                      server->global_list->clients, 
3910                      detached_client->nickname,
3911                      detached_client->id, detached_client, FALSE, NULL);
3912
3913     /* Change the owner of the client */
3914     detached_client->router = server_entry;
3915
3916     silc_free(server_id);
3917   }
3918
3919   silc_free(client_id);
3920 }