updates.
[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;
47   SilcHashTableList htl;
48   SilcUInt32 mode;
49   unsigned char *tmp;
50   SilcUInt32 tmp_len;
51   bool local;
52
53   SILC_LOG_DEBUG(("Start"));
54
55   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
56       packet->src_id_type != SILC_ID_SERVER)
57     return;
58
59   if (!packet->dst_id)
60     return;
61
62   /* If the packet is destined directly to a client then relay the packet
63      before processing it. */
64   if (packet->dst_id_type == SILC_ID_CLIENT) {
65     SilcIDListData idata;
66     SilcSocketConnection dst_sock;
67
68     /* Get the route to the client */
69     dst_sock = silc_server_get_client_route(server, packet->dst_id,
70                                             packet->dst_id_len, NULL, 
71                                             &idata, NULL);
72     if (dst_sock)
73       /* Relay the packet */
74       silc_server_relay_packet(server, dst_sock, idata->send_key,
75                                idata->hmac_send, idata->psn_send++,
76                                packet, TRUE);
77   }
78
79   /* Parse the Notify Payload */
80   payload = silc_notify_payload_parse(packet->buffer->data,
81                                       packet->buffer->len);
82   if (!payload)
83     return;
84
85   /* If we are router and this packet is not already broadcast packet
86      we will broadcast it. The sending socket really cannot be router or
87      the router is buggy. If this packet is coming from router then it must
88      have the broadcast flag set already and we won't do anything. */
89   if (!server->standalone && server->server_type == SILC_ROUTER &&
90       sock->type == SILC_SOCKET_TYPE_SERVER &&
91       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
92     SILC_LOG_DEBUG(("Broadcasting received Notify packet"));
93     if (packet->dst_id_type == SILC_ID_CHANNEL) {
94       /* Packet is destined to channel */
95       channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
96                                   packet->dst_id_type);
97       if (!channel_id)
98         goto out;
99
100       silc_server_packet_send_dest(server, server->router->connection, 
101                                    packet->type,
102                                    packet->flags | SILC_PACKET_FLAG_BROADCAST, 
103                                    channel_id, SILC_ID_CHANNEL,
104                                    packet->buffer->data, packet->buffer->len, 
105                                    FALSE);
106       silc_server_backup_send_dest(server, (SilcServerEntry)sock->user_data, 
107                                    packet->type, packet->flags,
108                                    channel_id, SILC_ID_CHANNEL,
109                                    packet->buffer->data, packet->buffer->len, 
110                                    FALSE, TRUE);
111     } else {
112       /* Packet is destined to client or server */
113       silc_server_packet_send(server, server->router->connection, 
114                               packet->type,
115                               packet->flags | SILC_PACKET_FLAG_BROADCAST, 
116                               packet->buffer->data, packet->buffer->len, 
117                               FALSE);
118       silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
119                               packet->type, packet->flags,
120                               packet->buffer->data, packet->buffer->len, 
121                               FALSE, TRUE);
122     }
123   }
124
125   type = silc_notify_get_type(payload);
126   args = silc_notify_get_args(payload);
127   if (!args)
128     goto out;
129
130   switch(type) {
131   case SILC_NOTIFY_TYPE_JOIN:
132     /* 
133      * Distribute the notify to local clients on the channel
134      */
135     SILC_LOG_DEBUG(("JOIN notify"));
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_free(channel_id);
153         goto out;
154       }
155     }
156     silc_free(channel_id);
157
158     /* Get client ID */
159     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
160     if (!tmp)
161       goto out;
162     client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
163     if (!client_id)
164       goto out;
165
166     /* If the the client is not in local list we check global list (ie. the
167        channel will be global channel) and if it does not exist then create
168        entry for the client. */
169     client = silc_idlist_find_client_by_id(server->global_list, 
170                                            client_id, server->server_type, 
171                                            NULL);
172     if (!client) {
173       client = silc_idlist_find_client_by_id(server->local_list, 
174                                              client_id, server->server_type,
175                                              NULL);
176       if (!client) {
177         /* If router did not find the client the it is bogus */
178         if (server->server_type != SILC_SERVER)
179           goto out;
180
181         client = 
182           silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
183                                  silc_id_dup(client_id, SILC_ID_CLIENT), 
184                                  sock->user_data, NULL, 0);
185         if (!client) {
186           SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
187           silc_free(client_id);
188           goto out;
189         }
190
191         client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
192       }
193     }
194
195     /* Do not process the notify if the client is not registered */
196     if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
197       break;
198
199     /* Do not add client to channel if it is there already */
200     if (silc_server_client_on_channel(client, channel, NULL)) {
201       SILC_LOG_DEBUG(("Client already on channel"));
202       break;
203     }
204
205     /* Send to channel */
206     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
207                                        FALSE, packet->buffer->data, 
208                                        packet->buffer->len, FALSE);
209
210     if (server->server_type != SILC_ROUTER && 
211         sock->type == SILC_SOCKET_TYPE_ROUTER)
212       /* The channel is global now */
213       channel->global_users = TRUE;
214
215     SILC_LOG_DEBUG(("Joining to channel %s", channel->channel_name));
216
217     /* JOIN the global client to the channel (local clients (if router 
218        created the channel) is joined in the pending JOIN command). */
219     chl = silc_calloc(1, sizeof(*chl));
220     chl->client = client;
221     chl->channel = channel;
222
223     /* If this is the first one on the channel then it is the founder of
224        the channel. */
225     if (!silc_hash_table_count(channel->user_list))
226       chl->mode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
227
228     silc_hash_table_add(channel->user_list, client, chl);
229     silc_hash_table_add(client->channels, channel, chl);
230     silc_free(client_id);
231     channel->user_count++;
232
233     break;
234
235   case SILC_NOTIFY_TYPE_LEAVE:
236     /* 
237      * Distribute the notify to local clients on the channel
238      */
239     SILC_LOG_DEBUG(("LEAVE notify"));
240
241     if (!channel_id) {
242       channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
243                                   packet->dst_id_type);
244       if (!channel_id)
245         goto out;
246     }
247
248     /* Get channel entry */
249     channel = silc_idlist_find_channel_by_id(server->global_list, 
250                                              channel_id, NULL);
251     if (!channel) { 
252       channel = silc_idlist_find_channel_by_id(server->local_list, 
253                                                channel_id, NULL);
254       if (!channel) {
255         silc_free(channel_id);
256         goto out;
257       }
258     }
259
260     /* Get client ID */
261     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
262     if (!tmp) {
263       silc_free(channel_id);
264       goto out;
265     }
266     client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
267     if (!client_id) {
268       silc_free(channel_id);
269       goto out;
270     }
271
272     /* Get client entry */
273     client = silc_idlist_find_client_by_id(server->global_list, 
274                                            client_id, TRUE, NULL);
275     if (!client) {
276       client = silc_idlist_find_client_by_id(server->local_list, 
277                                              client_id, TRUE, NULL);
278       if (!client) {
279         silc_free(client_id);
280         silc_free(channel_id);
281         goto out;
282       }
283     }
284     silc_free(client_id);
285
286     /* Check if on channel */
287     if (!silc_server_client_on_channel(client, channel, NULL))
288       break;
289
290     /* Send the leave notify to channel */
291     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
292                                        FALSE, packet->buffer->data, 
293                                        packet->buffer->len, FALSE);
294
295     /* Remove the user from channel */
296     silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
297     break;
298
299   case SILC_NOTIFY_TYPE_SIGNOFF:
300     /* 
301      * Distribute the notify to local clients on the channel
302      */
303     SILC_LOG_DEBUG(("SIGNOFF notify"));
304
305     /* Get client ID */
306     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
307     if (!tmp)
308       goto out;
309     client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
310     if (!client_id)
311       goto out;
312
313     /* Get client entry */
314     client = silc_idlist_find_client_by_id(server->global_list, 
315                                            client_id, TRUE, &cache);
316     if (!client) {
317       client = silc_idlist_find_client_by_id(server->local_list, 
318                                              client_id, TRUE, &cache);
319       if (!client) {
320         silc_free(client_id);
321         goto out;
322       }
323     }
324     silc_free(client_id);
325
326     /* Get signoff message */
327     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
328     if (tmp_len > 128)
329       tmp = NULL;
330
331     /* Update statistics */
332     server->stat.clients--;
333     if (server->stat.cell_clients)
334       server->stat.cell_clients--;
335     SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
336     SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
337
338     /* Remove the client from all channels. */
339     silc_server_remove_from_channels(server, NULL, client, TRUE, tmp, FALSE);
340
341     client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
342     cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
343     break;
344
345   case SILC_NOTIFY_TYPE_TOPIC_SET:
346     /* 
347      * Distribute the notify to local clients on the channel
348      */
349
350     SILC_LOG_DEBUG(("TOPIC SET notify"));
351
352     /* Get client ID */
353     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
354     if (!tmp)
355       goto out;
356     client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
357     if (!client_id)
358       goto out;
359
360     /* Get client entry */
361     client = silc_idlist_find_client_by_id(server->global_list, 
362                                            client_id, TRUE, &cache);
363     if (!client) {
364       client = silc_idlist_find_client_by_id(server->local_list, 
365                                              client_id, TRUE, &cache);
366       if (!client) {
367         silc_free(client_id);
368         goto out;
369       }
370     }
371     silc_free(client_id);
372
373     /* Get the topic */
374     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
375     if (!tmp) {
376       silc_free(channel_id);
377       goto out;
378     }
379
380     if (!channel_id) {
381       channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
382                                   packet->dst_id_type);
383       if (!channel_id)
384         goto out;
385     }
386
387     /* Get channel entry */
388     channel = silc_idlist_find_channel_by_id(server->global_list, 
389                                              channel_id, NULL);
390     if (!channel) {
391       channel = silc_idlist_find_channel_by_id(server->local_list, 
392                                                channel_id, NULL);
393       if (!channel) {
394         silc_free(channel_id);
395         goto out;
396       }
397     }
398
399     if (channel->topic && !strcmp(channel->topic, tmp))
400       goto out;
401
402     /* Get user's channel entry and check that topic set is allowed. */
403     if (!silc_server_client_on_channel(client, channel, &chl))
404       goto out;
405     if (chl->mode == SILC_CHANNEL_UMODE_NONE && 
406         channel->mode & SILC_CHANNEL_MODE_TOPIC) {
407       SILC_LOG_DEBUG(("Topic change is not allowed"));
408       goto out;
409     }
410
411     /* Change the topic */
412     silc_free(channel->topic);
413     channel->topic = strdup(tmp);
414
415     /* Send the same notify to the channel */
416     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
417                                        FALSE, packet->buffer->data, 
418                                        packet->buffer->len, FALSE);
419     silc_free(channel_id);
420     break;
421
422   case SILC_NOTIFY_TYPE_NICK_CHANGE:
423     {
424       /* 
425        * Distribute the notify to local clients on the channel
426        */
427       unsigned char *id, *id2;
428       char *nickname;
429       SilcUInt32 nickname_len;
430
431       SILC_LOG_DEBUG(("NICK CHANGE notify"));
432       
433       /* Get old client ID */
434       id = silc_argument_get_arg_type(args, 1, &tmp_len);
435       if (!id)
436         goto out;
437       client_id = silc_id_payload_parse_id(id, tmp_len, NULL);
438       if (!client_id)
439         goto out;
440       
441       /* Get new client ID */
442       id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
443       if (!id2)
444         goto out;
445       client_id2 = silc_id_payload_parse_id(id2, tmp_len, NULL);
446       if (!client_id2)
447         goto out;
448       
449       SILC_LOG_DEBUG(("Old Client ID id(%s)", 
450                       silc_id_render(client_id, SILC_ID_CLIENT)));
451       SILC_LOG_DEBUG(("New Client ID id(%s)", 
452                       silc_id_render(client_id2, SILC_ID_CLIENT)));
453
454       /* From protocol version 1.1 we also get the new nickname */
455       nickname = silc_argument_get_arg_type(args, 3, &nickname_len);;
456
457       /* Replace the Client ID */
458       client = silc_idlist_replace_client_id(server->global_list, client_id,
459                                              client_id2, nickname);
460       if (!client)
461         client = silc_idlist_replace_client_id(server->local_list, client_id, 
462                                                client_id2, nickname);
463
464       if (client) {
465         /* Send the NICK_CHANGE notify type to local clients on the channels
466            this client is joined to. */
467         silc_server_send_notify_on_channels(server, NULL, client,
468                                             SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
469                                             id, tmp_len, id2, tmp_len,
470                                             nickname, nickname ?
471                                             nickname_len : 0);
472       }
473
474       silc_free(client_id);
475       if (!client)
476         silc_free(client_id2);
477       break;
478     }
479
480   case SILC_NOTIFY_TYPE_CMODE_CHANGE:
481     /* 
482      * Distribute the notify to local clients on the channel
483      */
484     
485     SILC_LOG_DEBUG(("CMODE CHANGE notify"));
486       
487     /* Get client ID */
488     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
489     if (!tmp)
490       goto out;
491     client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
492     if (!client_id)
493       goto out;
494
495     /* Get client entry */
496     if (id_type == SILC_ID_CLIENT) {
497       client = silc_idlist_find_client_by_id(server->global_list, 
498                                              client_id, TRUE, &cache);
499       if (!client) {
500         client = silc_idlist_find_client_by_id(server->local_list, 
501                                                client_id, TRUE, &cache);
502         if (!client) {
503           silc_free(client_id);
504           goto out;
505         }
506       }
507       silc_free(client_id);
508     }
509
510     if (!channel_id) {
511       channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
512                                   packet->dst_id_type);
513       if (!channel_id)
514         goto out;
515     }
516
517     /* Get channel entry */
518     channel = silc_idlist_find_channel_by_id(server->global_list, 
519                                              channel_id, NULL);
520     if (!channel) {
521       channel = silc_idlist_find_channel_by_id(server->local_list, 
522                                                channel_id, NULL);
523       if (!channel) {
524         silc_free(channel_id);
525         goto out;
526       }
527     }
528     silc_free(channel_id);
529
530     /* Get the mode */
531     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
532     if (!tmp)
533       goto out;
534     SILC_GET32_MSB(mode, tmp);
535
536     /* Check if mode changed */
537     if (channel->mode == mode)
538       break;
539
540     /* Get user's channel entry and check that mode change is allowed */
541     if (client) {
542       if (!silc_server_client_on_channel(client, channel, &chl))
543         goto out;
544       if (!silc_server_check_cmode_rights(server, channel, chl, mode)) {
545         SILC_LOG_DEBUG(("CMODE change is not allowed"));
546         goto out;
547       }
548     }
549
550     /* Send the same notify to the channel */
551     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
552                                        FALSE, packet->buffer->data, 
553                                        packet->buffer->len, FALSE);
554
555     /* If the channel had private keys set and the mode was removed then
556        we must re-generate and re-distribute a new channel key */
557     if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY &&
558         !(mode & SILC_CHANNEL_MODE_PRIVKEY)) {
559       /* Re-generate channel key */
560       if (!silc_server_create_channel_key(server, channel, 0))
561         goto out;
562       
563       /* Send the channel key. This sends it to our local clients and if
564          we are normal server to our router as well. */
565       silc_server_send_channel_key(server, NULL, channel, 
566                                    server->server_type == SILC_ROUTER ? 
567                                    FALSE : !server->standalone);
568     }
569
570     /* Change mode */
571     channel->mode = mode;
572
573     /* Get the hmac */
574     tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
575     if (tmp) {
576       unsigned char hash[32];
577
578       if (channel->hmac)
579         silc_hmac_free(channel->hmac);
580       if (!silc_hmac_alloc(tmp, NULL, &channel->hmac))
581         goto out;
582
583       /* Set the HMAC key out of current channel key. The client must do
584          this locally. */
585       silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, 
586                      channel->key_len / 8, 
587                      hash);
588       silc_hmac_set_key(channel->hmac, hash, 
589                         silc_hash_len(silc_hmac_get_hash(channel->hmac)));
590       memset(hash, 0, sizeof(hash));
591     }
592
593     /* Get the passphrase */
594     tmp = silc_argument_get_arg_type(args, 5, &tmp_len);
595     if (tmp) {
596       silc_free(channel->passphrase);
597       channel->passphrase = silc_memdup(tmp, tmp_len);
598     }
599
600     break;
601
602   case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
603     {
604       /* 
605        * Distribute the notify to local clients on the channel
606        */
607       SilcChannelClientEntry chl2 = NULL;
608       bool notify_sent = FALSE;
609       
610       SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
611       
612       /* Get client ID */
613       tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
614       if (!tmp)
615         goto out;
616       client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
617       if (!client_id)
618         goto out;
619
620       /* Get client entry */
621       if (id_type == SILC_ID_CLIENT) {
622         client = silc_idlist_find_client_by_id(server->global_list, 
623                                                client_id, TRUE, &cache);
624         if (!client) {
625           client = silc_idlist_find_client_by_id(server->local_list, 
626                                                  client_id, TRUE, &cache);
627           if (!client) {
628             silc_free(client_id);
629             goto out;
630           }
631         }
632         silc_free(client_id);
633       }
634
635       if (!channel_id) {
636         channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
637                                     packet->dst_id_type);
638         if (!channel_id)
639           goto out;
640       }
641
642       /* Get channel entry */
643       channel = silc_idlist_find_channel_by_id(server->global_list, 
644                                                channel_id, NULL);
645       if (!channel) {
646         channel = silc_idlist_find_channel_by_id(server->local_list, 
647                                                  channel_id, NULL);
648         if (!channel) {
649           silc_free(channel_id);
650           goto out;
651         }
652       }
653
654       /* Get the mode */
655       tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
656       if (!tmp) {
657         silc_free(channel_id);
658         goto out;
659       }
660       
661       SILC_GET32_MSB(mode, tmp);
662       
663       /* Get target client */
664       tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
665       if (!tmp)
666         goto out;
667       client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
668       if (!client_id)
669         goto out;
670       
671       /* Get client entry */
672       client2 = silc_idlist_find_client_by_id(server->global_list, 
673                                               client_id, TRUE, NULL);
674       if (!client2) {
675         client2 = silc_idlist_find_client_by_id(server->local_list, 
676                                                 client_id, TRUE, NULL);
677         if (!client2) {
678           silc_free(client_id);
679           goto out;
680         }
681       }
682       silc_free(client_id);
683
684       if (client) {
685         /* Check that sender is on channel */
686         if (!silc_server_client_on_channel(client, channel, &chl))
687           goto out;
688         
689         if (client != client2) {
690           /* Sender must be operator */
691           if (chl->mode == SILC_CHANNEL_UMODE_NONE) {
692             SILC_LOG_DEBUG(("CUMODE change is not allowed"));
693             goto out;
694           }
695
696           /* Check that target is on channel */
697           if (!silc_server_client_on_channel(client2, channel, &chl))
698             goto out;
699
700           /* If target is founder mode change is not allowed. */
701           if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
702             SILC_LOG_DEBUG(("CUMODE change is not allowed"));
703             goto out;
704           }
705         }
706       }
707
708       /* Get entry to the channel user list */
709       silc_hash_table_list(channel->user_list, &htl);
710       while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
711         /* If the mode is channel founder and we already find a client 
712            to have that mode on the channel we will enforce the sender
713            to change the channel founder mode away. There can be only one
714            channel founder on the channel. */
715         if (server->server_type == SILC_ROUTER &&
716             mode & SILC_CHANNEL_UMODE_CHANFO &&
717             chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
718           SilcBuffer idp;
719           unsigned char cumode[4];
720
721           if (chl->client == client && chl->mode == mode) {
722             notify_sent = TRUE;
723             break;
724           }
725
726           mode &= ~SILC_CHANNEL_UMODE_CHANFO;
727           silc_server_send_notify_cumode(server, sock, FALSE, channel, mode,
728                                          client2->id, SILC_ID_CLIENT,
729                                          client2->id);
730           
731           idp = silc_id_payload_encode(client2->id, SILC_ID_CLIENT);
732           SILC_PUT32_MSB(mode, cumode);
733           silc_server_send_notify_to_channel(server, sock, channel, FALSE, 
734                                              SILC_NOTIFY_TYPE_CUMODE_CHANGE,
735                                              3, idp->data, idp->len,
736                                              cumode, 4,
737                                              idp->data, idp->len);
738           silc_buffer_free(idp);
739           notify_sent = TRUE;
740
741           /* Force the mode change if we alredy set the mode */
742           if (chl2) {
743             chl2->mode = mode;
744             silc_free(channel_id);
745             silc_hash_table_list_reset(&htl);
746             goto out;
747           }
748         }
749         
750         if (chl->client == client2) {
751           if (chl->mode == mode) {
752             notify_sent = TRUE;
753             break;
754           }
755
756           SILC_LOG_DEBUG(("Changing the channel user mode"));
757
758           /* Change the mode */
759           chl->mode = mode;
760           if (!(mode & SILC_CHANNEL_UMODE_CHANFO))
761             break;
762           
763           chl2 = chl;
764         }
765       }
766       silc_hash_table_list_reset(&htl);
767       
768       /* Send the same notify to the channel */
769       if (!notify_sent)
770         silc_server_packet_send_to_channel(server, sock, channel, 
771                                            packet->type, 
772                                            FALSE, packet->buffer->data, 
773                                            packet->buffer->len, FALSE);
774       
775       silc_free(channel_id);
776       break;
777     }
778
779   case SILC_NOTIFY_TYPE_INVITE:
780
781     if (packet->dst_id_type == SILC_ID_CLIENT)
782       goto out;
783
784     SILC_LOG_DEBUG(("INVITE notify"));
785
786     /* Get Channel ID */
787     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
788     if (!tmp)
789       goto out;
790     channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
791     if (!channel_id)
792       goto out;
793
794     /* Get channel entry */
795     channel = silc_idlist_find_channel_by_id(server->global_list, 
796                                              channel_id, NULL);
797     if (!channel) {
798       channel = silc_idlist_find_channel_by_id(server->local_list, 
799                                                channel_id, NULL);
800       if (!channel) {
801         silc_free(channel_id);
802         goto out;
803       }
804     }
805     silc_free(channel_id);
806
807     /* Get client ID */
808     tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
809     if (!tmp)
810       goto out;
811     client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
812     if (!client_id)
813       goto out;
814
815     /* Get client entry */
816     client = silc_idlist_find_client_by_id(server->global_list, 
817                                            client_id, TRUE, &cache);
818     if (!client) {
819       client = silc_idlist_find_client_by_id(server->local_list, 
820                                              client_id, TRUE, &cache);
821       if (!client) {
822         silc_free(client_id);
823         goto out;
824       }
825     }
826     silc_free(client_id);
827
828     /* Get user's channel entry and check that inviting is allowed. */
829     if (!silc_server_client_on_channel(client, channel, &chl))
830       goto out;
831     if (chl->mode == SILC_CHANNEL_UMODE_NONE && 
832         channel->mode & SILC_CHANNEL_MODE_INVITE) {
833       SILC_LOG_DEBUG(("Inviting is not allowed"));
834       goto out;
835     }
836
837     /* Get the added invite */
838     tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
839     if (tmp) {
840       if (!channel->invite_list)
841         channel->invite_list = silc_calloc(tmp_len + 2, 
842                                            sizeof(*channel->invite_list));
843       else
844         channel->invite_list = silc_realloc(channel->invite_list, 
845                                             sizeof(*channel->invite_list) * 
846                                             (tmp_len + 
847                                              strlen(channel->invite_list) + 
848                                              2));
849       if (tmp[tmp_len - 1] == ',')
850         tmp[tmp_len - 1] = '\0';
851       
852       strncat(channel->invite_list, tmp, tmp_len);
853       strncat(channel->invite_list, ",", 1);
854     }
855
856     /* Get the deleted invite */
857     tmp = silc_argument_get_arg_type(args, 5, &tmp_len);
858     if (tmp && channel->invite_list) {
859       char *start, *end, *n;
860       
861       if (!strncmp(channel->invite_list, tmp, 
862                    strlen(channel->invite_list) - 1)) {
863         silc_free(channel->invite_list);
864         channel->invite_list = NULL;
865       } else {
866         start = strstr(channel->invite_list, tmp);
867         if (start && strlen(start) >= tmp_len) {
868           end = start + tmp_len;
869           n = silc_calloc(strlen(channel->invite_list) - tmp_len, sizeof(*n));
870           strncat(n, channel->invite_list, start - channel->invite_list);
871           strncat(n, end + 1, ((channel->invite_list + 
872                                 strlen(channel->invite_list)) - end) - 1);
873           silc_free(channel->invite_list);
874           channel->invite_list = n;
875         }
876       }
877     }
878
879     break;
880
881   case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
882     /*
883      * Distribute to the local clients on the channel and change the
884      * channel ID.
885      */
886
887     SILC_LOG_DEBUG(("CHANNEL CHANGE"));
888
889     if (sock->type != SILC_SOCKET_TYPE_ROUTER)
890       break;
891
892     /* Get the old Channel ID */
893     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
894     if (!tmp)
895       goto out;
896     channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
897     if (!channel_id)
898       goto out;
899
900     /* Get the channel entry */
901     channel = silc_idlist_find_channel_by_id(server->local_list, 
902                                              channel_id, NULL);
903     if (!channel) {
904       channel = silc_idlist_find_channel_by_id(server->global_list, 
905                                                channel_id, NULL);
906       if (!channel) {
907         silc_free(channel_id);
908         goto out;
909       }
910     }
911
912     /* Send the notify to the channel */
913     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
914                                        FALSE, packet->buffer->data, 
915                                        packet->buffer->len, FALSE);
916
917     /* Get the new Channel ID */
918     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
919     if (!tmp)
920       goto out;
921     channel_id2 = silc_id_payload_parse_id(tmp, tmp_len, NULL);
922     if (!channel_id2)
923       goto out;
924
925     SILC_LOG_DEBUG(("Old Channel ID id(%s)", 
926                     silc_id_render(channel_id, SILC_ID_CHANNEL)));
927     SILC_LOG_DEBUG(("New Channel ID id(%s)", 
928                     silc_id_render(channel_id2, SILC_ID_CHANNEL)));
929
930     /* Replace the Channel ID */
931     if (!silc_idlist_replace_channel_id(server->local_list, channel_id,
932                                         channel_id2))
933       if (!silc_idlist_replace_channel_id(server->global_list, channel_id,
934                                           channel_id2)) {
935         silc_free(channel_id2);
936         channel_id2 = NULL;
937       }
938
939     if (channel_id2) {
940       SilcBuffer users = NULL, users_modes = NULL;
941
942       /* Re-announce this channel which ID was changed. */
943       silc_server_send_new_channel(server, sock, FALSE, channel->channel_name,
944                                    channel->id, 
945                                    silc_id_get_len(channel->id, 
946                                                    SILC_ID_CHANNEL),
947                                    channel->mode);
948
949       /* Re-announce our clients on the channel as the ID has changed now */
950       silc_server_announce_get_channel_users(server, channel, &users,
951                                              &users_modes);
952       if (users) {
953         silc_buffer_push(users, users->data - users->head);
954         silc_server_packet_send(server, sock,
955                                 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
956                                 users->data, users->len, FALSE);
957         silc_buffer_free(users);
958       }
959       if (users_modes) {
960         silc_buffer_push(users_modes, users_modes->data - users_modes->head);
961         silc_server_packet_send_dest(server, sock,
962                                      SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
963                                      channel->id, SILC_ID_CHANNEL,
964                                      users_modes->data, 
965                                      users_modes->len, FALSE);
966         silc_buffer_free(users_modes);
967       }
968
969       /* Re-announce channel's topic */
970       if (channel->topic) {
971         silc_server_send_notify_topic_set(server, sock,
972                                           server->server_type == SILC_ROUTER ?
973                                           TRUE : FALSE, channel, 
974                                           channel->id, SILC_ID_CHANNEL,
975                                           channel->topic);
976       }
977     }
978
979     silc_free(channel_id);
980
981     break;
982
983   case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
984     /* 
985      * Remove the server entry and all clients that this server owns.
986      */
987
988     SILC_LOG_DEBUG(("SERVER SIGNOFF notify"));
989
990     /* Get Server ID */
991     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
992     if (!tmp)
993       goto out;
994     server_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
995     if (!server_id)
996       goto out;
997
998     /* Get server entry */
999     server_entry = silc_idlist_find_server_by_id(server->global_list, 
1000                                                  server_id, TRUE, NULL);
1001     local = TRUE;
1002     if (!server_entry) {
1003       server_entry = silc_idlist_find_server_by_id(server->local_list, 
1004                                                    server_id, TRUE, NULL);
1005       local = TRUE;
1006       if (!server_entry) {
1007         /* If we are normal server then we might not have the server. Check
1008            whether router was kind enough to send the list of all clients
1009            that actually was to be removed. Remove them if the list is
1010            available. */
1011         if (server->server_type != SILC_ROUTER &&
1012             silc_argument_get_arg_num(args) > 1) {
1013           int i;
1014
1015           for (i = 1; i < silc_argument_get_arg_num(args); i++) {
1016             /* Get Client ID */
1017             tmp = silc_argument_get_arg_type(args, i + 1, &tmp_len);
1018             if (!tmp)
1019               continue;
1020             client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1021             if (!client_id)
1022               continue;
1023
1024             /* Get client entry */
1025             client = silc_idlist_find_client_by_id(server->global_list, 
1026                                                    client_id, TRUE, &cache);
1027             local = TRUE;
1028             if (!client) {
1029               client = silc_idlist_find_client_by_id(server->local_list, 
1030                                                      client_id, TRUE, &cache);
1031               local = FALSE;
1032               if (!client) {
1033                 silc_free(client_id);
1034                 continue;
1035               }
1036             }
1037             silc_free(client_id);
1038
1039             /* Update statistics */
1040             server->stat.clients--;
1041             if (server->stat.cell_clients)
1042               server->stat.cell_clients--;
1043             SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
1044             SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
1045
1046             /* Remove the client from all channels. */
1047             silc_server_remove_from_channels(server, NULL, client, 
1048                                              TRUE, NULL, FALSE);
1049
1050             /* Remove the client */
1051             silc_idlist_del_client(local ? server->local_list :
1052                                    server->global_list, client);
1053           }
1054         }
1055
1056         silc_free(server_id);
1057         goto out;
1058       }
1059     }
1060     silc_free(server_id);
1061
1062     /* Free all client entries that this server owns as they will
1063        become invalid now as well. */
1064     silc_server_remove_clients_by_server(server, server_entry, TRUE);
1065
1066     /* Remove the server entry */
1067     silc_idlist_del_server(local ? server->local_list :
1068                            server->global_list, server_entry);
1069
1070     /* XXX update statistics */
1071
1072     break;
1073
1074   case SILC_NOTIFY_TYPE_KICKED:
1075     /* 
1076      * Distribute the notify to local clients on the channel
1077      */
1078     
1079     SILC_LOG_DEBUG(("KICKED notify"));
1080       
1081     if (!channel_id) {
1082       channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
1083                                   packet->dst_id_type);
1084       if (!channel_id)
1085         goto out;
1086     }
1087
1088     /* Get channel entry */
1089     channel = silc_idlist_find_channel_by_id(server->global_list, 
1090                                              channel_id, NULL);
1091     if (!channel) {
1092       channel = silc_idlist_find_channel_by_id(server->local_list, 
1093                                                channel_id, NULL);
1094       if (!channel) {
1095         silc_free(channel_id);
1096         goto out;
1097       }
1098     }
1099     silc_free(channel_id);
1100
1101     /* Get client ID */
1102     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1103     if (!tmp)
1104       goto out;
1105     client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1106     if (!client_id)
1107       goto out;
1108
1109     /* If the the client is not in local list we check global list */
1110     client = silc_idlist_find_client_by_id(server->global_list, 
1111                                            client_id, TRUE, NULL);
1112     if (!client) {
1113       client = silc_idlist_find_client_by_id(server->local_list, 
1114                                              client_id, TRUE, NULL);
1115       if (!client) {
1116         silc_free(client_id);
1117         goto out;
1118       }
1119     }
1120     silc_free(client_id);
1121
1122     /* If target is founder they cannot be kicked */
1123     if (!silc_server_client_on_channel(client, channel, &chl))
1124       goto out;
1125     if (chl->mode & SILC_CHANNEL_UMODE_CHANFO)
1126       goto out;
1127     
1128     /* From protocol version 1.1 we get the kicker's ID as well. */
1129     tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1130     if (tmp) {
1131       client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1132       if (!client_id)
1133         goto out;
1134
1135       /* If the the client is not in local list we check global list */
1136       client2 = silc_idlist_find_client_by_id(server->global_list, 
1137                                               client_id, TRUE, NULL);
1138       if (!client2) {
1139         client2 = silc_idlist_find_client_by_id(server->local_list, 
1140                                                 client_id, TRUE, NULL);
1141         if (!client2) {
1142           silc_free(client_id);
1143           goto out;
1144         }
1145       }
1146       silc_free(client_id);
1147
1148       /* Kicker must be operator on channel */
1149       if (!silc_server_client_on_channel(client2, channel, &chl))
1150         goto out;
1151       if (chl->mode == SILC_CHANNEL_UMODE_NONE) {
1152         SILC_LOG_DEBUG(("Kicking is not allowed"));
1153         goto out;
1154       }
1155     }
1156
1157     /* Send to channel */
1158     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
1159                                        FALSE, packet->buffer->data, 
1160                                        packet->buffer->len, FALSE);
1161
1162     /* Remove the client from channel */
1163     silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
1164
1165     break;
1166
1167   case SILC_NOTIFY_TYPE_KILLED:
1168     {
1169       /* 
1170        * Distribute the notify to local clients on channels
1171        */
1172       unsigned char *id, *comment;
1173       SilcUInt32 id_len, comment_len;
1174     
1175       SILC_LOG_DEBUG(("KILLED notify"));
1176       
1177       /* Get client ID */
1178       id = silc_argument_get_arg_type(args, 1, &id_len);
1179       if (!id)
1180         goto out;
1181       client_id = silc_id_payload_parse_id(id, id_len, NULL);
1182       if (!client_id)
1183         goto out;
1184
1185       /* If the the client is not in local list we check global list */
1186       client = silc_idlist_find_client_by_id(server->global_list, 
1187                                              client_id, TRUE, NULL);
1188       if (!client) {
1189         client = silc_idlist_find_client_by_id(server->local_list, 
1190                                                client_id, TRUE, NULL);
1191         if (!client) {
1192           silc_free(client_id);
1193           goto out;
1194         }
1195       }
1196       silc_free(client_id);
1197
1198       /* If the client is one of ours, then close the connection to the
1199          client now. This removes the client from all channels as well. */
1200       if (packet->dst_id_type == SILC_ID_CLIENT && client->connection) {
1201         sock = client->connection;
1202         silc_server_free_client_data(server, NULL, client, FALSE, NULL);
1203         silc_server_close_connection(server, sock);
1204         break;
1205       }
1206
1207       /* Get comment */
1208       comment = silc_argument_get_arg_type(args, 2, &comment_len);
1209       if (comment_len > 128)
1210         comment_len = 127;
1211
1212       /* From protocol version 1.1 we get the killer's ID as well. */
1213       tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1214       if (tmp) {
1215         client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
1216         if (!client_id)
1217           goto out;
1218
1219         if (id_type == SILC_ID_CLIENT) {
1220           /* If the the client is not in local list we check global list */
1221           client2 = silc_idlist_find_client_by_id(server->global_list, 
1222                                                   client_id, TRUE, NULL);
1223           if (!client2) {
1224             client2 = silc_idlist_find_client_by_id(server->local_list, 
1225                                                     client_id, TRUE, NULL);
1226             if (!client2) {
1227               silc_free(client_id);
1228               goto out;
1229             }
1230           }
1231           silc_free(client_id);
1232
1233           /* Killer must be router operator */
1234           if (!(client2->mode & SILC_UMODE_ROUTER_OPERATOR)) {
1235             SILC_LOG_DEBUG(("Killing is not allowed"));
1236             goto out;
1237           }
1238         }
1239       }
1240
1241       /* Send the notify to local clients on the channels except to the
1242          client who is killed. */
1243       silc_server_send_notify_on_channels(server, client, client,
1244                                           SILC_NOTIFY_TYPE_KILLED, 3,
1245                                           id, id_len, comment, comment_len,
1246                                           tmp, tmp_len);
1247
1248       /* Remove the client from all channels */
1249       silc_server_remove_from_channels(server, NULL, client, FALSE, NULL, 
1250                                        FALSE);
1251
1252       break;
1253     }
1254
1255   case SILC_NOTIFY_TYPE_UMODE_CHANGE:
1256     /*
1257      * Save the mode of the client.
1258      */
1259
1260     SILC_LOG_DEBUG(("UMODE_CHANGE notify"));
1261
1262     /* Get client ID */
1263     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1264     if (!tmp)
1265       goto out;
1266     client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1267     if (!client_id)
1268       goto out;
1269
1270     /* Get client entry */
1271     client = silc_idlist_find_client_by_id(server->global_list, 
1272                                            client_id, TRUE, NULL);
1273     if (!client) {
1274       client = silc_idlist_find_client_by_id(server->local_list, 
1275                                              client_id, TRUE, NULL);
1276       if (!client) {
1277         silc_free(client_id);
1278         goto out;
1279       }
1280     }
1281     silc_free(client_id);
1282
1283     /* Get the mode */
1284     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1285     if (!tmp)
1286       goto out;
1287     SILC_GET32_MSB(mode, tmp);
1288
1289     /* Check that mode changing is allowed. */
1290     if (!silc_server_check_umode_rights(server, client, mode)) {
1291       SILC_LOG_DEBUG(("UMODE change is not allowed"));
1292       goto out;
1293     }
1294
1295     /* Remove internal resumed flag if client is marked detached now */
1296     if (mode & SILC_UMODE_DETACHED)
1297       client->data.status &= ~SILC_IDLIST_STATUS_RESUMED;
1298
1299     /* Change the mode */
1300     client->mode = mode;
1301
1302     break;
1303
1304   case SILC_NOTIFY_TYPE_BAN:
1305     /*
1306      * Save the ban
1307      */
1308
1309     SILC_LOG_DEBUG(("BAN notify"));
1310     
1311     /* Get Channel ID */
1312     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1313     if (!tmp)
1314       goto out;
1315     channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1316     if (!channel_id)
1317       goto out;
1318     
1319     /* Get channel entry */
1320     channel = silc_idlist_find_channel_by_id(server->global_list, 
1321                                              channel_id, NULL);
1322     if (!channel) {
1323       channel = silc_idlist_find_channel_by_id(server->local_list, 
1324                                                channel_id, NULL);
1325       if (!channel) {
1326         silc_free(channel_id);
1327         goto out;
1328       }
1329     }
1330     silc_free(channel_id);
1331
1332     /* Get the new ban and add it to the ban list */
1333     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1334     if (tmp) {
1335       if (!channel->ban_list)
1336         channel->ban_list = silc_calloc(tmp_len + 2, 
1337                                         sizeof(*channel->ban_list));
1338       else
1339         channel->ban_list = silc_realloc(channel->ban_list, 
1340                                          sizeof(*channel->ban_list) * 
1341                                          (tmp_len + 
1342                                           strlen(channel->ban_list) + 2));
1343       strncat(channel->ban_list, tmp, tmp_len);
1344       strncat(channel->ban_list, ",", 1);
1345     }
1346
1347     /* Get the ban to be removed and remove it from the list */
1348     tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1349     if (tmp && channel->ban_list) {
1350       char *start, *end, *n;
1351       
1352       if (!strncmp(channel->ban_list, tmp, strlen(channel->ban_list) - 1)) {
1353         silc_free(channel->ban_list);
1354         channel->ban_list = NULL;
1355       } else {
1356         start = strstr(channel->ban_list, tmp);
1357         if (start && strlen(start) >= tmp_len) {
1358           end = start + tmp_len;
1359           n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
1360           strncat(n, channel->ban_list, start - channel->ban_list);
1361           strncat(n, end + 1, ((channel->ban_list + 
1362                                 strlen(channel->ban_list)) - end) - 1);
1363           silc_free(channel->ban_list);
1364           channel->ban_list = n;
1365         }
1366       }
1367     }
1368     break;
1369
1370     /* Ignore rest of the notify types for now */
1371   case SILC_NOTIFY_TYPE_NONE:
1372   case SILC_NOTIFY_TYPE_MOTD:
1373     break;
1374   default:
1375     break;
1376   }
1377
1378  out:
1379   silc_notify_payload_free(payload);
1380 }
1381
1382 void silc_server_notify_list(SilcServer server,
1383                              SilcSocketConnection sock,
1384                              SilcPacketContext *packet)
1385 {
1386   SilcPacketContext *new;
1387   SilcBuffer buffer;
1388   SilcUInt16 len;
1389
1390   SILC_LOG_DEBUG(("Processing Notify List"));
1391
1392   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1393       packet->src_id_type != SILC_ID_SERVER)
1394     return;
1395
1396   /* Make copy of the original packet context, except for the actual
1397      data buffer, which we will here now fetch from the original buffer. */
1398   new = silc_packet_context_alloc();
1399   new->type = SILC_PACKET_NOTIFY;
1400   new->flags = packet->flags;
1401   new->src_id = packet->src_id;
1402   new->src_id_len = packet->src_id_len;
1403   new->src_id_type = packet->src_id_type;
1404   new->dst_id = packet->dst_id;
1405   new->dst_id_len = packet->dst_id_len;
1406   new->dst_id_type = packet->dst_id_type;
1407
1408   buffer = silc_buffer_alloc(1024);
1409   new->buffer = buffer;
1410
1411   while (packet->buffer->len) {
1412     SILC_GET16_MSB(len, packet->buffer->data + 2);
1413     if (len > packet->buffer->len)
1414       break;
1415
1416     if (len > buffer->truelen) {
1417       silc_buffer_free(buffer);
1418       buffer = silc_buffer_alloc(1024 + len);
1419     }
1420
1421     silc_buffer_pull_tail(buffer, len);
1422     silc_buffer_put(buffer, packet->buffer->data, len);
1423
1424     /* Process the Notify */
1425     silc_server_notify(server, sock, new);
1426
1427     silc_buffer_push_tail(buffer, len);
1428     silc_buffer_pull(packet->buffer, len);
1429   }
1430
1431   silc_buffer_free(buffer);
1432   silc_free(new);
1433 }
1434
1435 /* Received private message. This resolves the destination of the message 
1436    and sends the packet. This is used by both server and router.  If the
1437    destination is our locally connected client this sends the packet to
1438    the client. This may also send the message for further routing if
1439    the destination is not in our server (or router). */
1440
1441 void silc_server_private_message(SilcServer server,
1442                                  SilcSocketConnection sock,
1443                                  SilcPacketContext *packet)
1444 {
1445   SilcSocketConnection dst_sock;
1446   SilcIDListData idata;
1447   SilcClientEntry client;
1448
1449   SILC_LOG_DEBUG(("Start"));
1450
1451   if (packet->src_id_type != SILC_ID_CLIENT ||
1452       packet->dst_id_type != SILC_ID_CLIENT || !packet->dst_id)
1453     return;
1454
1455   /* Get the route to the client */
1456   dst_sock = silc_server_get_client_route(server, packet->dst_id,
1457                                           packet->dst_id_len, NULL, 
1458                                           &idata, &client);
1459   if (!dst_sock) {
1460     SilcBuffer idp;
1461
1462     if (client && client->mode & SILC_UMODE_DETACHED) {
1463       SILC_LOG_DEBUG(("Locally connected client is detached, "
1464                       "discarding packet"));
1465       return;
1466     }
1467
1468     /* Send IDENTIFY command reply with error status to indicate that
1469        such destination ID does not exist or is invalid */
1470     idp = silc_id_payload_encode_data(packet->dst_id,
1471                                       packet->dst_id_len,
1472                                       packet->dst_id_type);
1473     if (!idp)
1474       return;
1475
1476     if (packet->src_id_type == SILC_ID_CLIENT) {
1477       SilcClientID *client_id = silc_id_str2id(packet->src_id,
1478                                                packet->src_id_len,
1479                                                packet->src_id_type);
1480       silc_server_send_dest_command_reply(server, sock, 
1481                                           client_id, SILC_ID_CLIENT,
1482                                           SILC_COMMAND_IDENTIFY,
1483                                           SILC_STATUS_ERR_NO_SUCH_CLIENT_ID, 
1484                                           0, 0, 1, 2, idp->data, idp->len);
1485       silc_free(client_id);
1486     } else {
1487       silc_server_send_command_reply(server, sock, SILC_COMMAND_IDENTIFY,
1488                                      SILC_STATUS_ERR_NO_SUCH_CLIENT_ID, 0,
1489                                      0, 1, 2, idp->data, idp->len);
1490     }
1491
1492     silc_buffer_free(idp);
1493     return;
1494   }
1495
1496   /* Check whether destination client wishes to receive private messages */
1497   if (client && !(packet->flags & SILC_PACKET_FLAG_PRIVMSG_KEY) &&
1498       client->mode & SILC_UMODE_BLOCK_PRIVMSG) {
1499     SILC_LOG_DEBUG(("Client blocks private messages, discarding packet"));
1500     return;
1501   }
1502
1503   /* Send the private message */
1504   silc_server_send_private_message(server, dst_sock, idata->send_key,
1505                                    idata->hmac_send, idata->psn_send++,
1506                                    packet);
1507 }
1508
1509 /* Received private message key packet.. This packet is never for us. It is to
1510    the client in the packet's destination ID. Sending of this sort of packet
1511    equals sending private message, ie. it is sent point to point from
1512    one client to another. */
1513
1514 void silc_server_private_message_key(SilcServer server,
1515                                      SilcSocketConnection sock,
1516                                      SilcPacketContext *packet)
1517 {
1518   SilcSocketConnection dst_sock;
1519   SilcIDListData idata;
1520
1521   SILC_LOG_DEBUG(("Start"));
1522
1523   if (packet->src_id_type != SILC_ID_CLIENT ||
1524       packet->dst_id_type != SILC_ID_CLIENT)
1525     return;
1526
1527   if (!packet->dst_id)
1528     return;
1529
1530   /* Get the route to the client */
1531   dst_sock = silc_server_get_client_route(server, packet->dst_id,
1532                                           packet->dst_id_len, NULL, 
1533                                           &idata, NULL);
1534   if (!dst_sock)
1535     return;
1536
1537   /* Relay the packet */
1538   silc_server_relay_packet(server, dst_sock, idata->send_key,
1539                            idata->hmac_send, idata->psn_send++, packet, FALSE);
1540 }
1541
1542 /* Processes incoming command reply packet. The command reply packet may
1543    be destined to one of our clients or it may directly for us. We will 
1544    call the command reply routine after processing the packet. */
1545
1546 void silc_server_command_reply(SilcServer server,
1547                                SilcSocketConnection sock,
1548                                SilcPacketContext *packet)
1549 {
1550   SilcBuffer buffer = packet->buffer;
1551   SilcClientEntry client = NULL;
1552   SilcSocketConnection dst_sock;
1553   SilcIDListData idata;
1554   SilcClientID *id = NULL;
1555
1556   SILC_LOG_DEBUG(("Start"));
1557
1558   /* Source must be server or router */
1559   if (packet->src_id_type != SILC_ID_SERVER &&
1560       sock->type != SILC_SOCKET_TYPE_ROUTER)
1561     return;
1562
1563   if (packet->dst_id_type == SILC_ID_CHANNEL)
1564     return;
1565
1566   if (packet->dst_id_type == SILC_ID_CLIENT) {
1567     /* Destination must be one of ours */
1568     id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
1569     if (!id)
1570       return;
1571     client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
1572     if (!client) {
1573       SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
1574       silc_free(id);
1575       return;
1576     }
1577   }
1578
1579   if (packet->dst_id_type == SILC_ID_SERVER) {
1580     /* For now this must be for us */
1581     if (memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
1582       SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
1583       return;
1584     }
1585   }
1586
1587   /* Execute command reply locally for the command */
1588   silc_server_command_reply_process(server, sock, buffer);
1589
1590   if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
1591     /* Relay the packet to the client */
1592     const SilcBufferStruct p;
1593     
1594     dst_sock = (SilcSocketConnection)client->connection;
1595     idata = (SilcIDListData)client;
1596     
1597     silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len 
1598                      + packet->dst_id_len + packet->padlen);
1599     if (!silc_packet_send_prepare(dst_sock, 0, 0, buffer->len,
1600                                   idata->hmac_send, (const SilcBuffer)&p)) {
1601       SILC_LOG_ERROR(("Cannot send packet"));
1602       return;
1603     }
1604     silc_buffer_put((SilcBuffer)&p, buffer->data, buffer->len);
1605     
1606     /* Encrypt packet */
1607     silc_packet_encrypt(idata->send_key, idata->hmac_send, idata->psn_send++,
1608                         (SilcBuffer)&p, buffer->len);
1609     
1610     /* Send the packet */
1611     silc_server_packet_send_real(server, dst_sock, TRUE);
1612
1613     silc_free(id);
1614   }
1615 }
1616
1617 /* Process received channel message. The message can be originated from
1618    client or server. */
1619
1620 void silc_server_channel_message(SilcServer server,
1621                                  SilcSocketConnection sock,
1622                                  SilcPacketContext *packet)
1623 {
1624   SilcChannelEntry channel = NULL;
1625   SilcChannelID *id = NULL;
1626   void *sender_id = NULL;
1627   SilcClientEntry sender_entry = NULL;
1628   SilcChannelClientEntry chl;
1629   bool local = TRUE;
1630
1631   SILC_LOG_DEBUG(("Processing channel message"));
1632
1633   /* Sanity checks */
1634   if (packet->dst_id_type != SILC_ID_CHANNEL) {
1635     SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1636     goto out;
1637   }
1638
1639   /* Find channel entry */
1640   id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
1641   if (!id)
1642     goto out;
1643   channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
1644   if (!channel) {
1645     channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
1646     if (!channel) {
1647       SILC_LOG_DEBUG(("Could not find channel"));
1648       goto out;
1649     }
1650   }
1651
1652   /* See that this client is on the channel. If the original sender is
1653      not client (as it can be server as well) we don't do the check. */
1654   sender_id = silc_id_str2id(packet->src_id, packet->src_id_len, 
1655                              packet->src_id_type);
1656   if (!sender_id)
1657     goto out;
1658   if (packet->src_id_type == SILC_ID_CLIENT) {
1659     sender_entry = silc_idlist_find_client_by_id(server->local_list, 
1660                                                  sender_id, TRUE, NULL);
1661     if (!sender_entry) {
1662       local = FALSE;
1663       sender_entry = silc_idlist_find_client_by_id(server->global_list, 
1664                                                    sender_id, TRUE, NULL);
1665     }
1666     if (!sender_entry || !silc_server_client_on_channel(sender_entry, 
1667                                                         channel, &chl)) {
1668       SILC_LOG_DEBUG(("Client not on channel"));
1669       goto out;
1670     }
1671
1672     /* If channel is moderated check that client is allowed to send
1673        messages. */
1674     if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS && !chl->mode) {
1675       SILC_LOG_DEBUG(("Channel is silenced from normal users"));
1676       goto out;
1677     }
1678     if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS && 
1679         chl->mode & SILC_CHANNEL_UMODE_CHANOP &&
1680         !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1681       SILC_LOG_DEBUG(("Channel is silenced from operators"));
1682       goto out;
1683     }
1684
1685     /* If the packet is coming from router, but the client entry is local 
1686        entry to us then some router is rerouting this to us and it is not 
1687        allowed. When the client is local to us it means that we've routed
1688        this packet to network, and now someone is routing it back to us. */
1689     if (server->server_type == SILC_ROUTER &&
1690         sock->type == SILC_SOCKET_TYPE_ROUTER && local) {
1691       SILC_LOG_DEBUG(("Channel message rerouted to the sender, drop it"));
1692       goto out;
1693     }
1694   }
1695
1696   /* Distribute the packet to our local clients. This will send the
1697      packet for further routing as well, if needed. */
1698   silc_server_packet_relay_to_channel(server, sock, channel, sender_id,
1699                                       packet->src_id_type, sender_entry,
1700                                       packet->buffer->data,
1701                                       packet->buffer->len, FALSE);
1702
1703  out:
1704   silc_free(sender_id);
1705   silc_free(id);
1706 }
1707
1708 /* Received channel key packet. We distribute the key to all of our locally
1709    connected clients on the channel. */
1710
1711 void silc_server_channel_key(SilcServer server,
1712                              SilcSocketConnection sock,
1713                              SilcPacketContext *packet)
1714 {
1715   SilcBuffer buffer = packet->buffer;
1716   SilcChannelEntry channel;
1717
1718   if (packet->src_id_type != SILC_ID_SERVER ||
1719       (server->server_type == SILC_ROUTER &&
1720        sock->type == SILC_SOCKET_TYPE_ROUTER))
1721     return;
1722
1723   /* Save the channel key */
1724   channel = silc_server_save_channel_key(server, buffer, NULL);
1725   if (!channel)
1726     return;
1727
1728   /* Distribute the key to everybody who is on the channel. If we are router
1729      we will also send it to locally connected servers. */
1730   silc_server_send_channel_key(server, sock, channel, FALSE);
1731   
1732   if (server->server_type != SILC_BACKUP_ROUTER) {
1733     /* Distribute to local cell backup routers. */
1734     silc_server_backup_send(server, (SilcServerEntry)sock->user_data, 
1735                             SILC_PACKET_CHANNEL_KEY, 0,
1736                             buffer->data, buffer->len, FALSE, TRUE);
1737   }
1738 }
1739
1740 /* Received New Client packet and processes it.  Creates Client ID for the
1741    client. Client becomes registered after calling this functions. */
1742
1743 SilcClientEntry silc_server_new_client(SilcServer server,
1744                                        SilcSocketConnection sock,
1745                                        SilcPacketContext *packet)
1746 {
1747   SilcBuffer buffer = packet->buffer;
1748   SilcClientEntry client;
1749   SilcClientID *client_id;
1750   SilcBuffer reply;
1751   SilcIDListData idata;
1752   char *username = NULL, *realname = NULL, *id_string;
1753   SilcUInt16 username_len;
1754   SilcUInt32 id_len;
1755   int ret;
1756   char *hostname, *nickname;
1757   int nickfail = 0;
1758
1759   SILC_LOG_DEBUG(("Creating new client"));
1760
1761   if (sock->type != SILC_SOCKET_TYPE_CLIENT)
1762     return NULL;
1763
1764   /* Take client entry */
1765   client = (SilcClientEntry)sock->user_data;
1766   idata = (SilcIDListData)client;
1767
1768   /* Remove the old cache entry. */
1769   if (!silc_idcache_del_by_context(server->local_list->clients, client)) {
1770     SILC_LOG_INFO(("Unauthenticated client attempted to register to network"));
1771     silc_server_disconnect_remote(server, sock, "Server closed connection: "
1772                                   "You have not been authenticated");
1773     return NULL;
1774   }
1775
1776   /* Parse incoming packet */
1777   ret = silc_buffer_unformat(buffer,
1778                              SILC_STR_UI16_NSTRING_ALLOC(&username, 
1779                                                          &username_len),
1780                              SILC_STR_UI16_STRING_ALLOC(&realname),
1781                              SILC_STR_END);
1782   if (ret == -1) {
1783     silc_free(username);
1784     silc_free(realname);
1785     SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
1786                     "connection", sock->hostname, sock->ip));
1787     silc_server_disconnect_remote(server, sock, "Server closed connection: "
1788                                   "Incomplete client information");
1789     return NULL;
1790   }
1791
1792   if (!username) {
1793     silc_free(username);
1794     silc_free(realname);
1795     SILC_LOG_ERROR(("Client %s (%s) did not send its username, closing "
1796                     "connection", sock->hostname, sock->ip));
1797     silc_server_disconnect_remote(server, sock, "Server closed connection: "
1798                                   "Incomplete client information");
1799     return NULL;
1800   }
1801
1802   if (username_len > 128)
1803     username[128] = '\0';
1804
1805   /* Check for bad characters for nickname, and modify the nickname if
1806      it includes those. */
1807   if (silc_server_name_bad_chars(username, username_len)) {
1808     nickname = silc_server_name_modify_bad(username, username_len);
1809   } else {
1810     nickname = strdup(username);
1811   }
1812
1813   /* Make sanity checks for the hostname of the client. If the hostname
1814      is provided in the `username' check that it is the same than the
1815      resolved hostname, or if not resolved the hostname that appears in
1816      the client's public key. If the hostname is not present then put
1817      it from the resolved name or from the public key. */
1818   if (strchr(username, '@')) {
1819     SilcPublicKeyIdentifier pident;
1820     int tlen = strcspn(username, "@");
1821     char *phostname = NULL;
1822
1823     hostname = silc_memdup(username + tlen + 1, strlen(username) - tlen - 1);
1824
1825     if (strcmp(sock->hostname, sock->ip) && 
1826         strcmp(sock->hostname, hostname)) {
1827       silc_free(username);
1828       silc_free(hostname);
1829       silc_free(realname);
1830       SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
1831                       "connection", sock->hostname, sock->ip));
1832       silc_server_disconnect_remote(server, sock, 
1833                                     "Server closed connection: "
1834                                     "Incomplete client information");
1835       return NULL;
1836     }
1837     
1838     pident = silc_pkcs_decode_identifier(client->data.public_key->identifier);
1839     if (pident) {
1840       phostname = strdup(pident->host);
1841       silc_pkcs_free_identifier(pident);
1842     }
1843
1844     if (!strcmp(sock->hostname, sock->ip) && 
1845         phostname && strcmp(phostname, hostname)) {
1846       silc_free(username);
1847       silc_free(hostname);
1848       silc_free(phostname);
1849       silc_free(realname);
1850       SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
1851                       "connection", sock->hostname, sock->ip));
1852       silc_server_disconnect_remote(server, sock, 
1853                                     "Server closed connection: "
1854                                     "Incomplete client information");
1855       return NULL;
1856     }
1857     
1858     silc_free(phostname);
1859   } else {
1860     /* The hostname is not present, add it. */
1861     char *newusername;
1862     /* XXX For now we cannot take the host name from the public key since
1863        they are not trusted or we cannot verify them as trusted. Just take
1864        what the resolved name or address is. */
1865 #if 0
1866     if (strcmp(sock->hostname, sock->ip)) {
1867 #endif
1868       newusername = silc_calloc(strlen(username) + 
1869                                 strlen(sock->hostname) + 2,
1870                                 sizeof(*newusername));
1871       strncat(newusername, username, strlen(username));
1872       strncat(newusername, "@", 1);
1873       strncat(newusername, sock->hostname, strlen(sock->hostname));
1874       silc_free(username);
1875       username = newusername;
1876 #if 0
1877     } else {
1878       SilcPublicKeyIdentifier pident = 
1879         silc_pkcs_decode_identifier(client->data.public_key->identifier);
1880       
1881       if (pident) {
1882         newusername = silc_calloc(strlen(username) + 
1883                                   strlen(pident->host) + 2,
1884                                   sizeof(*newusername));
1885         strncat(newusername, username, strlen(username));
1886         strncat(newusername, "@", 1);
1887         strncat(newusername, pident->host, strlen(pident->host));
1888         silc_free(username);
1889         username = newusername;
1890         silc_pkcs_free_identifier(pident);
1891       }
1892     }
1893 #endif
1894   }
1895
1896   /* Create Client ID */
1897   while (!silc_id_create_client_id(server, server->id, server->rng, 
1898                                    server->md5hash, nickname, &client_id)) {
1899     nickfail++;
1900     if (nickfail > 9) {
1901       silc_server_disconnect_remote(server, sock, 
1902                                     "Server closed connection: Bad nickname");
1903       return NULL;
1904     }
1905     snprintf(&nickname[strlen(nickname) - 1], 1, "%d", nickfail);
1906   }
1907
1908   /* Update client entry */
1909   idata->status |= SILC_IDLIST_STATUS_REGISTERED;
1910   client->nickname = nickname;
1911   client->username = username;
1912   client->userinfo = realname ? realname : strdup(" ");
1913   client->id = client_id;
1914   id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
1915
1916   /* Add the client again to the ID cache */
1917   silc_idcache_add(server->local_list->clients, client->nickname,
1918                    client_id, client, 0, NULL);
1919
1920   /* Notify our router about new client on the SILC network */
1921   if (!server->standalone)
1922     silc_server_send_new_id(server, (SilcSocketConnection) 
1923                             server->router->connection, 
1924                             server->server_type == SILC_ROUTER ? TRUE : FALSE,
1925                             client->id, SILC_ID_CLIENT, id_len);
1926   
1927   /* Send the new client ID to the client. */
1928   id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
1929   reply = silc_buffer_alloc_size(2 + 2 + id_len);
1930   silc_buffer_format(reply,
1931                      SILC_STR_UI_SHORT(SILC_ID_CLIENT),
1932                      SILC_STR_UI_SHORT(id_len),
1933                      SILC_STR_UI_XNSTRING(id_string, id_len),
1934                      SILC_STR_END);
1935   silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0, 
1936                           reply->data, reply->len, FALSE);
1937   silc_free(id_string);
1938   silc_buffer_free(reply);
1939
1940   /* Send some nice info to the client */
1941   silc_server_send_connect_notifys(server, sock, client);
1942
1943   return client;
1944 }
1945
1946 /* Create new server. This processes received New Server packet and
1947    saves the received Server ID. The server is our locally connected
1948    server thus we save all the information and save it to local list. 
1949    This funtion can be used by both normal server and router server.
1950    If normal server uses this it means that its router has connected
1951    to the server. If router uses this it means that one of the cell's
1952    servers is connected to the router. */
1953
1954 SilcServerEntry silc_server_new_server(SilcServer server,
1955                                        SilcSocketConnection sock,
1956                                        SilcPacketContext *packet)
1957 {
1958   SilcBuffer buffer = packet->buffer;
1959   SilcServerEntry new_server, server_entry;
1960   SilcServerID *server_id;
1961   SilcIDListData idata;
1962   unsigned char *server_name, *id_string;
1963   SilcUInt16 id_len, name_len;
1964   int ret;
1965   bool local = TRUE;
1966
1967   SILC_LOG_DEBUG(("Creating new server"));
1968
1969   if (sock->type != SILC_SOCKET_TYPE_SERVER &&
1970       sock->type != SILC_SOCKET_TYPE_ROUTER)
1971     return NULL;
1972
1973   /* Take server entry */
1974   new_server = (SilcServerEntry)sock->user_data;
1975   idata = (SilcIDListData)new_server;
1976
1977   /* Remove the old cache entry */
1978   if (!silc_idcache_del_by_context(server->local_list->servers, new_server)) {
1979     if (!silc_idcache_del_by_context(server->global_list->servers, 
1980                                      new_server)) {
1981       SILC_LOG_INFO(("Unauthenticated %s attempted to register to "
1982                      "network", (sock->type == SILC_SOCKET_TYPE_SERVER ?
1983                                  "server" : "router")));
1984       silc_server_disconnect_remote(server, sock, "Server closed connection: "
1985                                     "You have not been authenticated");
1986       return NULL;
1987     }
1988     local = FALSE;
1989   }
1990
1991   /* Parse the incoming packet */
1992   ret = silc_buffer_unformat(buffer,
1993                              SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
1994                              SILC_STR_UI16_NSTRING_ALLOC(&server_name, 
1995                                                          &name_len),
1996                              SILC_STR_END);
1997   if (ret == -1) {
1998     if (id_string)
1999       silc_free(id_string);
2000     if (server_name)
2001       silc_free(server_name);
2002     return NULL;
2003   }
2004
2005   if (id_len > buffer->len) {
2006     silc_free(id_string);
2007     silc_free(server_name);
2008     return NULL;
2009   }
2010
2011   if (name_len > 256)
2012     server_name[255] = '\0';
2013
2014   /* Get Server ID */
2015   server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
2016   if (!server_id) {
2017     silc_free(id_string);
2018     silc_free(server_name);
2019     return NULL;
2020   }
2021   silc_free(id_string);
2022
2023   /* Check for valid server ID */
2024   if (!silc_id_is_valid_server_id(server, server_id, sock)) {
2025     SILC_LOG_INFO(("Invalid server ID sent by %s (%s)",
2026                    sock->ip, sock->hostname));
2027     silc_server_disconnect_remote(server, sock, "Server closed connection: "
2028                                   "Your Server ID is not valid");
2029     silc_free(server_name);
2030     return NULL;
2031   }
2032
2033   /* Check that we do not have this ID already */
2034   server_entry = silc_idlist_find_server_by_id(server->local_list, 
2035                                                server_id, TRUE, NULL);
2036   if (server_entry) {
2037     silc_idcache_del_by_context(server->local_list->servers, server_entry);
2038   } else {
2039     server_entry = silc_idlist_find_server_by_id(server->global_list, 
2040                                                  server_id, TRUE, NULL);
2041     if (server_entry) 
2042       silc_idcache_del_by_context(server->global_list->servers, server_entry);
2043   }
2044
2045   /* Update server entry */
2046   idata->status |= SILC_IDLIST_STATUS_REGISTERED;
2047   new_server->server_name = server_name;
2048   new_server->id = server_id;
2049   
2050   SILC_LOG_DEBUG(("New server id(%s)",
2051                   silc_id_render(server_id, SILC_ID_SERVER)));
2052
2053   /* Add again the entry to the ID cache. */
2054   silc_idcache_add(local ? server->local_list->servers : 
2055                    server->global_list->servers, server_name, server_id, 
2056                    new_server, 0, NULL);
2057
2058   /* Distribute the information about new server in the SILC network
2059      to our router. If we are normal server we won't send anything
2060      since this connection must be our router connection. */
2061   if (server->server_type == SILC_ROUTER && !server->standalone &&
2062       server->router->connection != sock)
2063     silc_server_send_new_id(server, server->router->connection,
2064                             TRUE, new_server->id, SILC_ID_SERVER, 
2065                             silc_id_get_len(server_id, SILC_ID_SERVER));
2066
2067   if (server->server_type == SILC_ROUTER)
2068     server->stat.cell_servers++;
2069
2070   /* Check whether this router connection has been replaced by an
2071      backup router. If it has been then we'll disable the server and will
2072      ignore everything it will send until the backup router resuming
2073      protocol has been completed. */
2074   if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
2075       silc_server_backup_replaced_get(server, server_id, NULL)) {
2076     /* Send packet to the server indicating that it cannot use this
2077        connection as it has been replaced by backup router. */
2078     SilcBuffer packet = silc_buffer_alloc(2);
2079     silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
2080     silc_buffer_format(packet,
2081                        SILC_STR_UI_CHAR(SILC_SERVER_BACKUP_REPLACED),
2082                        SILC_STR_UI_CHAR(0),
2083                        SILC_STR_END);
2084     silc_server_packet_send(server, sock, 
2085                             SILC_PACKET_RESUME_ROUTER, 0, 
2086                             packet->data, packet->len, TRUE);
2087     silc_buffer_free(packet);
2088
2089     /* Mark the router disabled. The data sent earlier will go but nothing
2090        after this does not go to this connection. */
2091     idata->status |= SILC_IDLIST_STATUS_DISABLED;
2092   } else {
2093     /* If it is router announce our stuff to it. */
2094     if (sock->type == SILC_SOCKET_TYPE_ROUTER && 
2095         server->server_type == SILC_ROUTER) {
2096       silc_server_announce_servers(server, FALSE, 0, sock);
2097       silc_server_announce_clients(server, 0, sock);
2098       silc_server_announce_channels(server, 0, sock);
2099     }
2100   }
2101
2102   return new_server;
2103 }
2104
2105 /* Processes incoming New ID packet. New ID Payload is used to distribute
2106    information about newly registered clients and servers. */
2107
2108 static void silc_server_new_id_real(SilcServer server, 
2109                                     SilcSocketConnection sock,
2110                                     SilcPacketContext *packet,
2111                                     int broadcast)
2112 {
2113   SilcBuffer buffer = packet->buffer;
2114   SilcIDList id_list;
2115   SilcServerEntry router, server_entry;
2116   SilcSocketConnection router_sock;
2117   SilcIDPayload idp;
2118   SilcIdType id_type;
2119   void *id;
2120
2121   SILC_LOG_DEBUG(("Processing new ID"));
2122
2123   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2124       server->server_type == SILC_SERVER ||
2125       packet->src_id_type != SILC_ID_SERVER)
2126     return;
2127
2128   idp = silc_id_payload_parse(buffer->data, buffer->len);
2129   if (!idp)
2130     return;
2131
2132   id_type = silc_id_payload_get_type(idp);
2133
2134   /* Normal server cannot have other normal server connections */
2135   server_entry = (SilcServerEntry)sock->user_data;
2136   if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER &&
2137       server_entry->server_type == SILC_SERVER)
2138     goto out;
2139
2140   id = silc_id_payload_get_id(idp);
2141   if (!id)
2142     goto out;
2143
2144   /* If the packet is coming from server then use the sender as the
2145      origin of the the packet. If it came from router then check the real
2146      sender of the packet and use that as the origin. */
2147   if (sock->type == SILC_SOCKET_TYPE_SERVER) {
2148     id_list = server->local_list;
2149     router_sock = sock;
2150     router = sock->user_data;
2151
2152     /* If the sender is backup router and ID is server (and we are not
2153        backup router) then switch the entry to global list. */
2154     if (server_entry->server_type == SILC_BACKUP_ROUTER && 
2155         id_type == SILC_ID_SERVER && 
2156         server->id_entry->server_type != SILC_BACKUP_ROUTER) {
2157       id_list = server->global_list;
2158       router_sock = server->router ? server->router->connection : sock;
2159     }
2160   } else {
2161     void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2162                                      packet->src_id_type);
2163     router = silc_idlist_find_server_by_id(server->global_list,
2164                                            sender_id, TRUE, NULL);
2165     if (!router)
2166       router = silc_idlist_find_server_by_id(server->local_list,
2167                                              sender_id, TRUE, NULL);
2168     silc_free(sender_id);
2169     router_sock = sock;
2170     id_list = server->global_list;
2171   }
2172
2173   if (!router)
2174     goto out;
2175
2176   switch(id_type) {
2177   case SILC_ID_CLIENT:
2178     {
2179       SilcClientEntry entry;
2180
2181       /* Check that we do not have this client already */
2182       entry = silc_idlist_find_client_by_id(server->global_list, 
2183                                             id, server->server_type, 
2184                                             NULL);
2185       if (!entry)
2186         entry = silc_idlist_find_client_by_id(server->local_list, 
2187                                               id, server->server_type,
2188                                               NULL);
2189       if (entry) {
2190         SILC_LOG_DEBUG(("Ignoring client that we already have"));
2191         goto out;
2192       }
2193
2194       SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
2195                       silc_id_render(id, SILC_ID_CLIENT),
2196                       sock->type == SILC_SOCKET_TYPE_SERVER ?
2197                       "Server" : "Router", sock->hostname));
2198     
2199       /* As a router we keep information of all global information in our
2200          global list. Cell wide information however is kept in the local
2201          list. */
2202       entry = silc_idlist_add_client(id_list, NULL, NULL, NULL, 
2203                                      id, router, NULL, 0);
2204       if (!entry) {
2205         SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
2206
2207         /* Inform the sender that the ID is not usable */
2208         silc_server_send_notify_signoff(server, sock, FALSE, id, NULL);
2209         goto out;
2210       }
2211       entry->nickname = NULL;
2212       entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2213
2214       if (sock->type == SILC_SOCKET_TYPE_SERVER)
2215         server->stat.cell_clients++;
2216       server->stat.clients++;
2217     }
2218     break;
2219
2220   case SILC_ID_SERVER:
2221     {
2222       SilcServerEntry entry;
2223
2224       /* If the ID is mine, ignore it. */
2225       if (SILC_ID_SERVER_COMPARE(id, server->id)) {
2226         SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
2227         break;
2228       }
2229
2230       /* If the ID is the sender's ID, ignore it (we have it already) */
2231       if (SILC_ID_SERVER_COMPARE(id, router->id)) {
2232         SILC_LOG_DEBUG(("Ignoring sender's own ID"));
2233         break;
2234       }
2235       
2236       /* Check that we do not have this server already */
2237       entry = silc_idlist_find_server_by_id(server->global_list, 
2238                                             id, server->server_type, 
2239                                             NULL);
2240       if (!entry)
2241         entry = silc_idlist_find_server_by_id(server->local_list, 
2242                                               id, server->server_type,
2243                                               NULL);
2244       if (entry) {
2245         SILC_LOG_DEBUG(("Ignoring server that we already have"));
2246         goto out;
2247       }
2248
2249       SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
2250                       silc_id_render(id, SILC_ID_SERVER),
2251                       sock->type == SILC_SOCKET_TYPE_SERVER ?
2252                       "Server" : "Router", sock->hostname));
2253       
2254       /* As a router we keep information of all global information in our 
2255          global list. Cell wide information however is kept in the local
2256          list. */
2257       entry = silc_idlist_add_server(id_list, NULL, 0, id, router, 
2258                                      router_sock);
2259       if (!entry) {
2260         SILC_LOG_ERROR(("Could not add new server to the ID Cache"));
2261         goto out;
2262       }
2263       entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2264       
2265       if (sock->type == SILC_SOCKET_TYPE_SERVER)
2266         server->stat.cell_servers++;
2267       server->stat.servers++;
2268     }
2269     break;
2270
2271   case SILC_ID_CHANNEL:
2272     SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
2273     goto out;
2274     break;
2275
2276   default:
2277     goto out;
2278     break;
2279   }
2280
2281   /* If the sender of this packet is server and we are router we need to
2282      broadcast this packet to other routers in the network. */
2283   if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
2284       sock->type == SILC_SOCKET_TYPE_SERVER &&
2285       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2286     SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
2287     silc_server_packet_send(server, server->router->connection,
2288                             packet->type, 
2289                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
2290                             buffer->data, buffer->len, FALSE);
2291     silc_server_backup_send(server, (SilcServerEntry)sock->user_data, 
2292                             packet->type, packet->flags,
2293                             packet->buffer->data, packet->buffer->len, 
2294                             FALSE, TRUE);
2295   }
2296
2297  out:
2298   silc_id_payload_free(idp);
2299 }
2300
2301
2302 /* Processes incoming New ID packet. New ID Payload is used to distribute
2303    information about newly registered clients and servers. */
2304
2305 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
2306                         SilcPacketContext *packet)
2307 {
2308   silc_server_new_id_real(server, sock, packet, TRUE);
2309 }
2310
2311 /* Receoved New Id List packet, list of New ID payloads inside one
2312    packet. Process the New ID payloads one by one. */
2313
2314 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
2315                              SilcPacketContext *packet)
2316 {
2317   SilcPacketContext *new_id;
2318   SilcBuffer idp;
2319   SilcUInt16 id_len;
2320
2321   SILC_LOG_DEBUG(("Processing New ID List"));
2322
2323   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2324       packet->src_id_type != SILC_ID_SERVER)
2325     return;
2326
2327   /* If the sender of this packet is server and we are router we need to
2328      broadcast this packet to other routers in the network. Broadcast
2329      this list packet instead of multiple New ID packets. */
2330   if (!server->standalone && server->server_type == SILC_ROUTER &&
2331       sock->type == SILC_SOCKET_TYPE_SERVER &&
2332       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2333     SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
2334     silc_server_packet_send(server, server->router->connection,
2335                             packet->type, 
2336                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
2337                             packet->buffer->data, packet->buffer->len, FALSE);
2338     silc_server_backup_send(server, (SilcServerEntry)sock->user_data, 
2339                             packet->type, packet->flags,
2340                             packet->buffer->data, packet->buffer->len, 
2341                             FALSE, TRUE);
2342   }
2343
2344   /* Make copy of the original packet context, except for the actual
2345      data buffer, which we will here now fetch from the original buffer. */
2346   new_id = silc_packet_context_alloc();
2347   new_id->type = SILC_PACKET_NEW_ID;
2348   new_id->flags = packet->flags;
2349   new_id->src_id = packet->src_id;
2350   new_id->src_id_len = packet->src_id_len;
2351   new_id->src_id_type = packet->src_id_type;
2352   new_id->dst_id = packet->dst_id;
2353   new_id->dst_id_len = packet->dst_id_len;
2354   new_id->dst_id_type = packet->dst_id_type;
2355
2356   idp = silc_buffer_alloc(256);
2357   new_id->buffer = idp;
2358
2359   while (packet->buffer->len) {
2360     SILC_GET16_MSB(id_len, packet->buffer->data + 2);
2361     if ((id_len > packet->buffer->len) ||
2362         (id_len > idp->truelen))
2363       break;
2364
2365     silc_buffer_pull_tail(idp, 4 + id_len);
2366     silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
2367
2368     /* Process the New ID */
2369     silc_server_new_id_real(server, sock, new_id, FALSE);
2370
2371     silc_buffer_push_tail(idp, 4 + id_len);
2372     silc_buffer_pull(packet->buffer, 4 + id_len);
2373   }
2374
2375   silc_buffer_free(idp);
2376   silc_free(new_id);
2377 }
2378
2379 /* Received New Channel packet. Information about new channels in the 
2380    network are distributed using this packet. Save the information about
2381    the new channel. This usually comes from router but also normal server
2382    can send this to notify channels it has when it connects to us. */
2383
2384 void silc_server_new_channel(SilcServer server,
2385                              SilcSocketConnection sock,
2386                              SilcPacketContext *packet)
2387 {
2388   SilcChannelPayload payload;
2389   SilcChannelID *channel_id;
2390   char *channel_name;
2391   SilcUInt32 name_len;
2392   unsigned char *id;
2393   SilcUInt32 id_len;
2394   SilcUInt32 mode;
2395   SilcServerEntry server_entry;
2396   SilcChannelEntry channel;
2397
2398   SILC_LOG_DEBUG(("Processing New Channel"));
2399
2400   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2401       packet->src_id_type != SILC_ID_SERVER ||
2402       server->server_type == SILC_SERVER)
2403     return;
2404
2405   /* Parse the channel payload */
2406   payload = silc_channel_payload_parse(packet->buffer->data,
2407                                        packet->buffer->len);
2408   if (!payload)
2409     return;
2410     
2411   /* Get the channel ID */
2412   channel_id = silc_channel_get_id_parse(payload);
2413   if (!channel_id) {
2414     silc_channel_payload_free(payload);
2415     return;
2416   }
2417
2418   channel_name = silc_channel_get_name(payload, &name_len);
2419   if (name_len > 256)
2420     channel_name[255] = '\0';
2421
2422   id = silc_channel_get_id(payload, &id_len);
2423
2424   server_entry = (SilcServerEntry)sock->user_data;
2425
2426   if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
2427     /* Add the channel to global list as it is coming from router. It 
2428        cannot be our own channel as it is coming from router. */
2429
2430     /* Check that we don't already have this channel */
2431     channel = silc_idlist_find_channel_by_name(server->local_list, 
2432                                                channel_name, NULL);
2433     if (!channel)
2434       channel = silc_idlist_find_channel_by_name(server->global_list, 
2435                                                  channel_name, NULL);
2436     if (!channel) {
2437       SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
2438                       silc_id_render(channel_id, SILC_ID_CHANNEL), 
2439                       sock->hostname));
2440     
2441       silc_idlist_add_channel(server->global_list, strdup(channel_name), 
2442                               0, channel_id, sock->user_data, NULL, NULL, 0);
2443       server->stat.channels++;
2444     }
2445   } else {
2446     /* The channel is coming from our server, thus it is in our cell
2447        we will add it to our local list. */
2448     SilcBuffer chk;
2449
2450     SILC_LOG_DEBUG(("Channel id(%s) from [Server] %s",
2451                     silc_id_render(channel_id, SILC_ID_CHANNEL), 
2452                     sock->hostname));
2453
2454     /* Check that we don't already have this channel */
2455     channel = silc_idlist_find_channel_by_name(server->local_list, 
2456                                                channel_name, NULL);
2457     if (!channel)
2458       channel = silc_idlist_find_channel_by_name(server->global_list, 
2459                                                  channel_name, NULL);
2460
2461     /* If the channel does not exist, then create it. This creates a new
2462        key to the channel as well that we will send to the server. */
2463     if (!channel) {
2464       /* The protocol says that the Channel ID's IP address must be based
2465          on the router's IP address.  Check whether the ID is based in our
2466          IP and if it is not then create a new ID and enforce the server
2467          to switch the ID. */
2468       if (server_entry->server_type != SILC_BACKUP_ROUTER &&
2469           !SILC_ID_COMPARE(channel_id, server->id, server->id->ip.data_len)) {
2470         SilcChannelID *tmp;
2471         SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2472         
2473         if (silc_id_create_channel_id(server, server->id, server->rng, &tmp)) {
2474           silc_server_send_notify_channel_change(server, sock, FALSE, 
2475                                                  channel_id, tmp);
2476           silc_free(channel_id);
2477           channel_id = tmp;
2478         }
2479       }
2480
2481       /* Create the channel with the provided Channel ID */
2482       channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
2483                                                        channel_name,
2484                                                        channel_id, FALSE);
2485       if (!channel) {
2486         silc_channel_payload_free(payload);
2487         silc_free(channel_id);
2488         return;
2489       }
2490
2491       /* Get the mode and set it to the channel */
2492       channel->mode = silc_channel_get_mode(payload);
2493
2494       /* Send the new channel key to the server */
2495       id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2496       id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
2497       chk = silc_channel_key_payload_encode(id_len, id,
2498                                             strlen(channel->channel_key->
2499                                                    cipher->name),
2500                                             channel->channel_key->cipher->name,
2501                                             channel->key_len / 8, 
2502                                             channel->key);
2503       silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
2504                               chk->data, chk->len, FALSE);
2505       silc_buffer_free(chk);
2506
2507     } else {
2508       /* The channel exist by that name, check whether the ID's match.
2509          If they don't then we'll force the server to use the ID we have.
2510          We also create a new key for the channel. */
2511       SilcBuffer users = NULL, users_modes = NULL;
2512
2513       if (!SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
2514         /* They don't match, send CHANNEL_CHANGE notify to the server to
2515            force the ID change. */
2516         SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2517         silc_server_send_notify_channel_change(server, sock, FALSE, 
2518                                                channel_id, channel->id);
2519       }
2520
2521       /* If the mode is different from what we have then enforce the
2522          mode change. */
2523       mode = silc_channel_get_mode(payload);
2524       if (channel->mode != mode) {
2525         SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
2526         silc_server_send_notify_cmode(server, sock, FALSE, channel,
2527                                       channel->mode, server->id,
2528                                       SILC_ID_SERVER,
2529                                       channel->cipher, channel->hmac_name,
2530                                       channel->passphrase);
2531       }
2532
2533       /* Create new key for the channel and send it to the server and
2534          everybody else possibly on the channel. */
2535
2536       if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
2537         if (!silc_server_create_channel_key(server, channel, 0))
2538           return;
2539         
2540         /* Send to the channel */
2541         silc_server_send_channel_key(server, sock, channel, FALSE);
2542         id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2543         id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
2544
2545         /* Send to the server */
2546         chk = silc_channel_key_payload_encode(id_len, id,
2547                                               strlen(channel->channel_key->
2548                                                      cipher->name),
2549                                               channel->channel_key->
2550                                               cipher->name,
2551                                               channel->key_len / 8, 
2552                                               channel->key);
2553         silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
2554                                 chk->data, chk->len, FALSE);
2555         silc_buffer_free(chk);
2556         silc_free(id);
2557       }
2558
2559       silc_free(channel_id);
2560
2561       /* Since the channel is coming from server and we also know about it
2562          then send the JOIN notify to the server so that it see's our
2563          users on the channel "joining" the channel. */
2564       silc_server_announce_get_channel_users(server, channel, &users,
2565                                              &users_modes);
2566       if (users) {
2567         silc_buffer_push(users, users->data - users->head);
2568         silc_server_packet_send(server, sock,
2569                                 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2570                                 users->data, users->len, FALSE);
2571         silc_buffer_free(users);
2572       }
2573       if (users_modes) {
2574         silc_buffer_push(users_modes, users_modes->data - users_modes->head);
2575         silc_server_packet_send_dest(server, sock,
2576                                      SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2577                                      channel->id, SILC_ID_CHANNEL,
2578                                      users_modes->data, 
2579                                      users_modes->len, FALSE);
2580         silc_buffer_free(users_modes);
2581       }
2582     }
2583   }
2584
2585   silc_channel_payload_free(payload);
2586 }
2587
2588 /* Received New Channel List packet, list of New Channel List payloads inside
2589    one packet. Process the New Channel payloads one by one. */
2590
2591 void silc_server_new_channel_list(SilcServer server,
2592                                   SilcSocketConnection sock,
2593                                   SilcPacketContext *packet)
2594 {
2595   SilcPacketContext *new;
2596   SilcBuffer buffer;
2597   SilcUInt16 len1, len2;
2598
2599   SILC_LOG_DEBUG(("Processing New Channel List"));
2600
2601   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2602       packet->src_id_type != SILC_ID_SERVER ||
2603       server->server_type == SILC_SERVER)
2604     return;
2605
2606   /* If the sender of this packet is server and we are router we need to
2607      broadcast this packet to other routers in the network. Broadcast
2608      this list packet instead of multiple New Channel packets. */
2609   if (!server->standalone && server->server_type == SILC_ROUTER &&
2610       sock->type == SILC_SOCKET_TYPE_SERVER &&
2611       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2612     SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
2613     silc_server_packet_send(server, server->router->connection,
2614                             packet->type, 
2615                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
2616                             packet->buffer->data, packet->buffer->len, FALSE);
2617     silc_server_backup_send(server, (SilcServerEntry)sock->user_data, 
2618                             packet->type, packet->flags,
2619                             packet->buffer->data, packet->buffer->len, 
2620                             FALSE, TRUE);
2621   }
2622
2623   /* Make copy of the original packet context, except for the actual
2624      data buffer, which we will here now fetch from the original buffer. */
2625   new = silc_packet_context_alloc();
2626   new->type = SILC_PACKET_NEW_CHANNEL;
2627   new->flags = packet->flags;
2628   new->src_id = packet->src_id;
2629   new->src_id_len = packet->src_id_len;
2630   new->src_id_type = packet->src_id_type;
2631   new->dst_id = packet->dst_id;
2632   new->dst_id_len = packet->dst_id_len;
2633   new->dst_id_type = packet->dst_id_type;
2634
2635   buffer = silc_buffer_alloc(512);
2636   new->buffer = buffer;
2637
2638   while (packet->buffer->len) {
2639     SILC_GET16_MSB(len1, packet->buffer->data);
2640     if ((len1 > packet->buffer->len) ||
2641         (len1 > buffer->truelen))
2642       break;
2643
2644     SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
2645     if ((len2 > packet->buffer->len) ||
2646         (len2 > buffer->truelen))
2647       break;
2648
2649     silc_buffer_pull_tail(buffer, 8 + len1 + len2);
2650     silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
2651
2652     /* Process the New Channel */
2653     silc_server_new_channel(server, sock, new);
2654
2655     silc_buffer_push_tail(buffer, 8 + len1 + len2);
2656     silc_buffer_pull(packet->buffer, 8 + len1 + len2);
2657   }
2658
2659   silc_buffer_free(buffer);
2660   silc_free(new);
2661 }
2662
2663 /* Received key agreement packet. This packet is never for us. It is to
2664    the client in the packet's destination ID. Sending of this sort of packet
2665    equals sending private message, ie. it is sent point to point from
2666    one client to another. */
2667
2668 void silc_server_key_agreement(SilcServer server,
2669                                SilcSocketConnection sock,
2670                                SilcPacketContext *packet)
2671 {
2672   SilcSocketConnection dst_sock;
2673   SilcIDListData idata;
2674
2675   SILC_LOG_DEBUG(("Start"));
2676
2677   if (packet->src_id_type != SILC_ID_CLIENT ||
2678       packet->dst_id_type != SILC_ID_CLIENT)
2679     return;
2680
2681   if (!packet->dst_id)
2682     return;
2683
2684   /* Get the route to the client */
2685   dst_sock = silc_server_get_client_route(server, packet->dst_id,
2686                                           packet->dst_id_len, NULL, 
2687                                           &idata, NULL);
2688   if (!dst_sock)
2689     return;
2690
2691   /* Relay the packet */
2692   silc_server_relay_packet(server, dst_sock, idata->send_key,
2693                            idata->hmac_send, idata->psn_send++,
2694                            packet, FALSE);
2695 }
2696
2697 /* Received connection auth request packet that is used during connection
2698    phase to resolve the mandatory authentication method.  This packet can
2699    actually be received at anytime but usually it is used only during
2700    the connection authentication phase. Now, protocol says that this packet
2701    can come from client or server, however, we support only this coming
2702    from client and expect that server always knows what authentication
2703    method to use. */
2704
2705 void silc_server_connection_auth_request(SilcServer server,
2706                                          SilcSocketConnection sock,
2707                                          SilcPacketContext *packet)
2708 {
2709   SilcServerConfigClient *client = NULL;
2710   SilcUInt16 conn_type;
2711   int ret;
2712   SilcAuthMethod auth_meth = SILC_AUTH_NONE;
2713
2714   SILC_LOG_DEBUG(("Start"));
2715
2716   if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT)
2717     return;
2718
2719   /* Parse the payload */
2720   ret = silc_buffer_unformat(packet->buffer,
2721                              SILC_STR_UI_SHORT(&conn_type),
2722                              SILC_STR_UI_SHORT(NULL),
2723                              SILC_STR_END);
2724   if (ret == -1)
2725     return;
2726
2727   if (conn_type != SILC_SOCKET_TYPE_CLIENT)
2728     return;
2729
2730   /* Get the authentication method for the client */
2731   auth_meth = SILC_AUTH_NONE;
2732   client = silc_server_config_find_client(server, sock->ip);
2733   if (!client)
2734     client = silc_server_config_find_client(server, sock->hostname);
2735   if (client) {
2736     if (client->passphrase) {
2737       if (client->publickeys && !server->config->prefer_passphrase_auth)
2738         auth_meth = SILC_AUTH_PUBLIC_KEY;
2739       else
2740         auth_meth = SILC_AUTH_PASSWORD;
2741     } else if (client->publickeys)
2742       auth_meth = SILC_AUTH_PUBLIC_KEY;
2743   }
2744
2745   /* Send it back to the client */
2746   silc_server_send_connection_auth_request(server, sock, conn_type, auth_meth);
2747 }
2748
2749 /* Received REKEY packet. The sender of the packet wants to regenerate
2750    its session keys. This starts the REKEY protocol. */
2751
2752 void silc_server_rekey(SilcServer server,
2753                        SilcSocketConnection sock,
2754                        SilcPacketContext *packet)
2755 {
2756   SilcProtocol protocol;
2757   SilcServerRekeyInternalContext *proto_ctx;
2758   SilcIDListData idata = (SilcIDListData)sock->user_data;
2759
2760   SILC_LOG_DEBUG(("Start"));
2761
2762   /* Allocate internal protocol context. This is sent as context
2763      to the protocol. */
2764   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
2765   proto_ctx->server = (void *)server;
2766   proto_ctx->sock = sock;
2767   proto_ctx->responder = TRUE;
2768   proto_ctx->pfs = idata->rekey->pfs;
2769       
2770   /* Perform rekey protocol. Will call the final callback after the
2771      protocol is over. */
2772   silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY, 
2773                       &protocol, proto_ctx, silc_server_rekey_final);
2774   sock->protocol = protocol;
2775
2776   if (proto_ctx->pfs == FALSE)
2777     /* Run the protocol */
2778     silc_protocol_execute(protocol, server->schedule, 0, 0);
2779 }
2780
2781 /* Received file transger packet. This packet is never for us. It is to
2782    the client in the packet's destination ID. Sending of this sort of packet
2783    equals sending private message, ie. it is sent point to point from
2784    one client to another. */
2785
2786 void silc_server_ftp(SilcServer server,
2787                      SilcSocketConnection sock,
2788                      SilcPacketContext *packet)
2789 {
2790   SilcSocketConnection dst_sock;
2791   SilcIDListData idata;
2792
2793   SILC_LOG_DEBUG(("Start"));
2794
2795   if (packet->src_id_type != SILC_ID_CLIENT ||
2796       packet->dst_id_type != SILC_ID_CLIENT)
2797     return;
2798
2799   if (!packet->dst_id)
2800     return;
2801
2802   /* Get the route to the client */
2803   dst_sock = silc_server_get_client_route(server, packet->dst_id,
2804                                           packet->dst_id_len, NULL, 
2805                                           &idata, NULL);
2806   if (!dst_sock)
2807     return;
2808
2809   /* Relay the packet */
2810   silc_server_relay_packet(server, dst_sock, idata->send_key,
2811                            idata->hmac_send, idata->psn_send++,
2812                            packet, FALSE);
2813 }
2814
2815 typedef struct {
2816   SilcServer server;
2817   SilcSocketConnection sock;
2818   SilcPacketContext *packet;
2819 } *SilcServerResumeResolve;
2820
2821 SILC_SERVER_CMD_FUNC(resume_resolve)
2822 {
2823   SilcServerResumeResolve r = (SilcServerResumeResolve)context;
2824   SilcServer server = r->server;
2825   SilcSocketConnection sock = r->sock;
2826   SilcServerCommandReplyContext reply = context2;
2827
2828   if (!context2 || !silc_command_get_status(reply->payload, NULL, NULL)) {
2829     SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
2830                     "closing connection", sock->hostname, sock->ip));
2831     silc_server_disconnect_remote(server, sock, 
2832                                   "Server closed connection: "
2833                                   "Incomplete resume information");
2834     goto out;
2835   }
2836
2837   /* Reprocess the packet */
2838   silc_server_resume_client(server, sock, r->packet);
2839
2840  out:
2841   silc_socket_free(r->sock);
2842   silc_packet_context_free(r->packet);
2843   silc_free(r);
2844 }
2845
2846 /* Received client resuming packet.  This is used to resume detached
2847    client session.  It can be sent by the client who wishes to resume
2848    but this is also sent by servers and routers to notify other routers
2849    that the client is not detached anymore. */
2850
2851 void silc_server_resume_client(SilcServer server,
2852                                SilcSocketConnection sock,
2853                                SilcPacketContext *packet)
2854 {
2855   SilcBuffer buffer = packet->buffer, buf;
2856   SilcIDListData idata;
2857   SilcClientEntry detached_client;
2858   SilcClientID *client_id = NULL;
2859   unsigned char *id_string, *auth = NULL;
2860   SilcUInt16 id_len, auth_len = 0;
2861   int ret, nickfail = 0;
2862   bool resolved, local;
2863   SilcServerResumeResolve r;
2864
2865   ret = silc_buffer_unformat(buffer,
2866                              SILC_STR_UI16_NSTRING(&id_string, &id_len),
2867                              SILC_STR_END);
2868   if (ret != -1)
2869     client_id = silc_id_str2id(id_string, id_len, SILC_ID_CLIENT);
2870
2871   if (sock->type == SILC_SOCKET_TYPE_CLIENT) {
2872     /* Client send this and is attempting to resume to old client session */
2873     SilcClientEntry client;
2874     SilcChannelEntry channel;
2875     SilcHashTableList htl;
2876     SilcChannelClientEntry chl;
2877     SilcBuffer keyp;
2878
2879     if (ret != -1) {
2880       silc_buffer_pull(buffer, 2 + id_len);
2881       auth = buffer->data;
2882       auth_len = buffer->len;
2883       silc_buffer_push(buffer, 2 + id_len);
2884     }
2885
2886     if (!client_id || auth_len < 128) {
2887       SILC_LOG_ERROR(("Client %s (%s) sent incomplete resume information, "
2888                       "closing connection", sock->hostname, sock->ip));
2889       silc_server_disconnect_remote(server, sock, "Server closed connection: "
2890                                     "Incomplete resume information");
2891       return;
2892     }
2893
2894     /* Take client entry of this connection */
2895     client = (SilcClientEntry)sock->user_data;
2896     idata = (SilcIDListData)client;
2897
2898     /* Get entry to the client, and resolve it if we don't have it. */
2899     detached_client = silc_server_get_client_resolve(server, client_id, 
2900                                                      &resolved);
2901     if (!detached_client) {
2902       if (resolved) {
2903         /* The client info is being resolved. Reprocess this packet after
2904            receiving the reply to the query. */
2905         r = silc_calloc(1, sizeof(*r));
2906         if (!r)
2907           return;
2908
2909         r->server = server;
2910         r->sock = silc_socket_dup(sock);
2911         r->packet = silc_packet_context_dup(packet);
2912         silc_server_command_pending(server, SILC_COMMAND_WHOIS,
2913                                     server->cmd_ident,
2914                                     silc_server_command_resume_resolve, r);
2915       } else {
2916         SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
2917                         "closing connection", sock->hostname, sock->ip));
2918         silc_server_disconnect_remote(server, sock, 
2919                                       "Server closed connection: "
2920                                       "Incomplete resume information");
2921       }
2922       return;
2923     }
2924
2925     /* Check that the client is detached */
2926     if (!(detached_client->mode & SILC_UMODE_DETACHED)) {
2927       SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, "
2928                       "closing connection", sock->hostname, sock->ip));
2929       silc_server_disconnect_remote(server, sock, "Server closed connection: "
2930                                     "Incomplete resume information");
2931       return;
2932     }
2933
2934     /* Check that we have the public key of the client, if not then we must
2935        resolve it first. */
2936     if (!detached_client->data.public_key) {
2937       if (server->standalone) {
2938         silc_server_disconnect_remote(server, sock, 
2939                                       "Server closed connection: "
2940                                       "Incomplete resume information");
2941       } else {
2942         /* We must retrieve the detached client's public key by sending
2943            GETKEY command. Reprocess this packet after receiving the key */
2944         SilcBuffer idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
2945         SilcSocketConnection dest_sock = 
2946           silc_server_get_client_route(server, NULL, 0, client_id, NULL, NULL);
2947
2948         silc_server_send_command(server, dest_sock ? dest_sock : 
2949                                  server->router->connection,
2950                                  SILC_COMMAND_GETKEY, ++server->cmd_ident,
2951                                  1, idp->data, idp->len);
2952
2953         r = silc_calloc(1, sizeof(*r));
2954         if (!r)
2955           return;
2956
2957         r->server = server;
2958         r->sock = silc_socket_dup(sock);
2959         r->packet = silc_packet_context_dup(packet);
2960         silc_server_command_pending(server, SILC_COMMAND_GETKEY,
2961                                     server->cmd_ident,
2962                                     silc_server_command_resume_resolve, r);
2963
2964         silc_buffer_free(idp);
2965       }
2966       return;
2967     }
2968
2969     /* Verify the authentication payload.  This has to be successful in
2970        order to allow the resuming */
2971     if (!silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
2972                                detached_client->data.public_key, 0,
2973                                idata->hash, detached_client->id, 
2974                                SILC_ID_CLIENT)) {
2975       SILC_LOG_ERROR(("Client %s (%s) resume authentication failed, "
2976                       "closing connection", sock->hostname, sock->ip));
2977       silc_server_disconnect_remote(server, sock, "Server closed connection: "
2978                                     "Incomplete resume information");
2979       return;
2980     }
2981
2982     /* Now resume the client to the network */
2983
2984     sock->user_data = detached_client;
2985     detached_client->connection = sock;
2986
2987     /* Take new keys and stuff into use in the old entry */
2988     silc_idlist_del_data(detached_client);
2989     silc_idlist_add_data(detached_client, idata);
2990     detached_client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2991     detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
2992     detached_client->mode &= ~SILC_UMODE_DETACHED;
2993
2994     /* Send the RESUME_CLIENT packet to our primary router so that others
2995        know this client isn't detached anymore. */
2996     if (!server->standalone) {
2997       buf = silc_buffer_alloc_size(2 + id_len);
2998       silc_buffer_format(buf,
2999                          SILC_STR_UI_SHORT(id_len),
3000                          SILC_STR_UI_XNSTRING(id_string, id_len),
3001                          SILC_STR_END);
3002       silc_server_packet_send(server, server->router->connection,
3003                               SILC_PACKET_RESUME_CLIENT, 0, 
3004                               buf->data, buf->len, TRUE);
3005       silc_buffer_free(buf);
3006     }
3007
3008     /* Delete this client entry since we're resuming to old one. */
3009     server->stat.my_clients--;
3010     server->stat.clients--;
3011     if (server->stat.cell_clients)
3012       server->stat.cell_clients--;
3013     silc_idlist_del_client(server->local_list, client);
3014     client = detached_client;
3015
3016     /* If the ID is not based in our ID then change it */
3017     if (!SILC_ID_COMPARE(client->id, server->id, server->id->ip.data_len)) {
3018       while (!silc_id_create_client_id(server, server->id, server->rng, 
3019                                        server->md5hash, client->nickname, 
3020                                        &client_id)) {
3021         nickfail++;
3022         if (nickfail > 9) {
3023           silc_server_disconnect_remote(server, sock, 
3024                                         "Server closed connection: "
3025                                         "Bad nickname");
3026           return;
3027         }
3028         snprintf(&client->nickname[strlen(client->nickname) - 1], 1, 
3029                  "%d", nickfail);
3030       }
3031
3032       /* Notify about Client ID change, nickname doesn't actually change. */
3033       if (!server->standalone)
3034         silc_server_send_notify_nick_change(server, server->router->connection,
3035                                             FALSE, client->id, client_id,
3036                                             client->nickname);
3037       
3038       silc_free(client->id);
3039       client->id = client_id;
3040     }
3041
3042     /* Add the client again to the ID cache to get it to correct list */
3043     if (!silc_idcache_del_by_context(server->local_list->clients, client))
3044       silc_idcache_del_by_context(server->global_list->clients, client);
3045     silc_idcache_add(server->local_list->clients, client->nickname,
3046                      client->id, client, client->mode, NULL);
3047
3048     /* Send the new client ID to the client. */
3049     id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
3050     buf = silc_buffer_alloc_size(2 + 2 + id_len);
3051     silc_buffer_format(buf,
3052                        SILC_STR_UI_SHORT(SILC_ID_CLIENT),
3053                        SILC_STR_UI_SHORT(id_len),
3054                        SILC_STR_UI_XNSTRING(id_string, id_len),
3055                        SILC_STR_END);
3056     silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0, 
3057                             buf->data, buf->len, FALSE);
3058     silc_free(id_string);
3059     silc_buffer_free(buf);
3060
3061     /* Send some nice info to the client */
3062     silc_server_send_connect_notifys(server, sock, client);
3063
3064     /* Send all channel keys of channels the client has joined */
3065     silc_hash_table_list(client->channels, &htl);
3066     while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
3067       channel = chl->channel;
3068       id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3069       keyp = 
3070         silc_channel_key_payload_encode(silc_id_get_len(channel->id,
3071                                                         SILC_ID_CHANNEL), 
3072                                         id_string,
3073                                         strlen(channel->channel_key->
3074                                                cipher->name),
3075                                         channel->channel_key->cipher->name,
3076                                         channel->key_len / 8, channel->key);
3077       silc_free(id_string);
3078
3079       /* Send the key packet to client */
3080       silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
3081                               keyp->data, keyp->len, FALSE);
3082     }
3083     silc_hash_table_list_reset(&htl);
3084
3085     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
3086                             ("Your session is successfully resumed"));
3087
3088   } else if (sock->type != SILC_SOCKET_TYPE_CLIENT) {
3089     /* Server or router sent this to us to notify that that a client has
3090        been resumed. */
3091     SilcServerEntry server_entry;
3092     SilcServerID *server_id;
3093
3094     if (!client_id)
3095       return;
3096
3097     /* Get entry to the client, and resolve it if we don't have it. */
3098     detached_client = silc_idlist_find_client_by_id(server->local_list, 
3099                                                     client_id, TRUE, NULL);
3100     if (!detached_client) {
3101       detached_client = silc_idlist_find_client_by_id(server->global_list,
3102                                                       client_id, TRUE, NULL);
3103       if (!detached_client)
3104         return;
3105     }
3106
3107     /* Check that the client has not been resumed already because it is
3108        protocol error to attempt to resume more than once.  The client
3109        will be killed if this protocol error occurs. */
3110     if (detached_client->data.status & SILC_IDLIST_STATUS_RESUMED &&
3111         !(detached_client->mode & SILC_UMODE_DETACHED)) {
3112       /* The client is clearly attempting to resume more than once and
3113          perhaps playing around by resuming from several different places
3114          at the same time. */
3115       silc_server_kill_client(server, detached_client, NULL,
3116                               server->id, SILC_ID_SERVER);
3117       return;
3118     }
3119
3120     /* Check whether client is detached at all */
3121     if (!(detached_client->mode & SILC_UMODE_DETACHED))
3122       return;
3123
3124     /* Client is detached, and now it is resumed.  Remove the detached
3125        mode and mark that it is resumed. */
3126     detached_client->mode &= ~SILC_UMODE_DETACHED;
3127     detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
3128
3129     /* Get the new owner of the resumed client */
3130     server_id = silc_id_str2id(packet->src_id, packet->src_id_len,
3131                                packet->src_id_type);
3132     if (!server_id)
3133       return;
3134
3135     /* Get server entry */
3136     server_entry = silc_idlist_find_server_by_id(server->global_list, 
3137                                                  server_id, TRUE, NULL);
3138     local = TRUE;
3139     if (!server_entry) {
3140       server_entry = silc_idlist_find_server_by_id(server->local_list, 
3141                                                    server_id, TRUE, NULL);
3142       local = FALSE;
3143       if (!server_entry) {
3144         silc_free(server_id);
3145         return;
3146       }
3147     }
3148
3149     /* Change the client to correct list. */
3150     if (!silc_idcache_del_by_context(server->local_list->clients,
3151                                      detached_client))
3152       silc_idcache_del_by_context(server->global_list->clients,
3153                                   detached_client);
3154     silc_idcache_add(local ? server->local_list->clients :
3155                      server->global_list->clients, detached_client->nickname,
3156                      detached_client->id, detached_client, FALSE, NULL);
3157
3158     /* Change the owner of the client if needed */
3159     if (detached_client->router != server_entry)
3160       detached_client->router = server_entry;
3161
3162     /* If the sender of this packet is server and we are router we need to
3163        broadcast this packet to other routers in the network. */
3164     if (!server->standalone && server->server_type == SILC_ROUTER &&
3165         sock->type == SILC_SOCKET_TYPE_SERVER &&
3166         !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
3167       SILC_LOG_DEBUG(("Broadcasting received Resume Client packet"));
3168       silc_server_packet_send(server, server->router->connection,
3169                               packet->type, 
3170                               packet->flags | SILC_PACKET_FLAG_BROADCAST,
3171                               buffer->data, buffer->len, FALSE);
3172       silc_server_backup_send(server, (SilcServerEntry)sock->user_data, 
3173                               packet->type, packet->flags,
3174                               packet->buffer->data, packet->buffer->len, 
3175                               FALSE, TRUE);
3176     }
3177
3178     silc_free(server_id);
3179   }
3180
3181   silc_free(client_id);
3182 }