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