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