updates.
[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_receive, 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->topic && !strcmp(channel->topic, tmp))
382       goto out;
383
384     if (!channel_id) {
385       channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
386                                   packet->dst_id_type);
387       if (!channel_id)
388         goto out;
389     }
390
391     /* Get channel entry */
392     channel = silc_idlist_find_channel_by_id(server->global_list, 
393                                              channel_id, NULL);
394     if (!channel) {
395       channel = silc_idlist_find_channel_by_id(server->local_list, 
396                                                channel_id, NULL);
397       if (!channel) {
398         silc_free(channel_id);
399         goto out;
400       }
401     }
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->config->server_info->server_name,
1881                            server_version));
1882   if (server->server_type == SILC_ROUTER) {
1883     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1884                             ("There are %d clients on %d servers in SILC "
1885                              "Network", server->stat.clients,
1886                              server->stat.servers + 1));
1887     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1888                             ("There are %d clients on %d server in our cell",
1889                              server->stat.cell_clients,
1890                              server->stat.cell_servers + 1));
1891     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1892                             ("I have %d clients, %d channels, %d servers and "
1893                              "%d routers",
1894                              server->stat.my_clients, 
1895                              server->stat.my_channels,
1896                              server->stat.my_servers,
1897                              server->stat.my_routers));
1898     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1899                             ("There are %d server operators and %d router "
1900                              "operators online",
1901                              server->stat.server_ops,
1902                              server->stat.router_ops));
1903     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1904                             ("I have %d operators online",
1905                              server->stat.my_router_ops +
1906                              server->stat.my_server_ops));
1907   } else {
1908     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1909                             ("I have %d clients and %d channels formed",
1910                              server->stat.my_clients,
1911                              server->stat.my_channels));
1912     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1913                             ("%d operators online",
1914                              server->stat.my_server_ops));
1915   }
1916   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1917                           ("Your connection is secured with %s cipher, "
1918                            "key length %d bits",
1919                            idata->send_key->cipher->name,
1920                            idata->send_key->cipher->key_len));
1921   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1922                           ("Your current nickname is %s",
1923                            client->nickname));
1924
1925   /* Send motd */
1926   silc_server_send_motd(server, sock);
1927
1928   return client;
1929 }
1930
1931 /* Create new server. This processes received New Server packet and
1932    saves the received Server ID. The server is our locally connected
1933    server thus we save all the information and save it to local list. 
1934    This funtion can be used by both normal server and router server.
1935    If normal server uses this it means that its router has connected
1936    to the server. If router uses this it means that one of the cell's
1937    servers is connected to the router. */
1938
1939 SilcServerEntry silc_server_new_server(SilcServer server,
1940                                        SilcSocketConnection sock,
1941                                        SilcPacketContext *packet)
1942 {
1943   SilcBuffer buffer = packet->buffer;
1944   SilcServerEntry new_server, server_entry;
1945   SilcServerID *server_id;
1946   SilcIDListData idata;
1947   unsigned char *server_name, *id_string;
1948   SilcUInt16 id_len, name_len;
1949   int ret;
1950   bool local = TRUE;
1951
1952   SILC_LOG_DEBUG(("Creating new server"));
1953
1954   if (sock->type != SILC_SOCKET_TYPE_SERVER &&
1955       sock->type != SILC_SOCKET_TYPE_ROUTER)
1956     return NULL;
1957
1958   /* Take server entry */
1959   new_server = (SilcServerEntry)sock->user_data;
1960   idata = (SilcIDListData)new_server;
1961
1962   /* Remove the old cache entry */
1963   if (!silc_idcache_del_by_context(server->local_list->servers, new_server)) {
1964     if (!silc_idcache_del_by_context(server->global_list->servers, 
1965                                      new_server)) {
1966       SILC_LOG_INFO(("Unauthenticated %s attempted to register to "
1967                      "network", (sock->type == SILC_SOCKET_TYPE_SERVER ?
1968                                  "server" : "router")));
1969       silc_server_disconnect_remote(server, sock, "Server closed connection: "
1970                                     "You have not been authenticated");
1971       return NULL;
1972     }
1973     local = FALSE;
1974   }
1975
1976   /* Parse the incoming packet */
1977   ret = silc_buffer_unformat(buffer,
1978                              SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
1979                              SILC_STR_UI16_NSTRING_ALLOC(&server_name, 
1980                                                          &name_len),
1981                              SILC_STR_END);
1982   if (ret == -1) {
1983     if (id_string)
1984       silc_free(id_string);
1985     if (server_name)
1986       silc_free(server_name);
1987     return NULL;
1988   }
1989
1990   if (id_len > buffer->len) {
1991     silc_free(id_string);
1992     silc_free(server_name);
1993     return NULL;
1994   }
1995
1996   if (name_len > 256)
1997     server_name[255] = '\0';
1998
1999   /* Get Server ID */
2000   server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
2001   if (!server_id) {
2002     silc_free(id_string);
2003     silc_free(server_name);
2004     return NULL;
2005   }
2006   silc_free(id_string);
2007
2008   /* Check for valid server ID */
2009   if (!silc_id_is_valid_server_id(server, server_id, sock)) {
2010     SILC_LOG_INFO(("Invalid server ID sent by %s (%s)",
2011                    sock->ip, sock->hostname));
2012     silc_server_disconnect_remote(server, sock, "Server closed connection: "
2013                                   "Your Server ID is not valid");
2014     silc_free(server_name);
2015     return NULL;
2016   }
2017
2018   /* Check that we do not have this ID already */
2019   server_entry = silc_idlist_find_server_by_id(server->local_list, 
2020                                                server_id, TRUE, NULL);
2021   if (server_entry) {
2022     silc_idcache_del_by_context(server->local_list->servers, server_entry);
2023   } else {
2024     server_entry = silc_idlist_find_server_by_id(server->global_list, 
2025                                                  server_id, TRUE, NULL);
2026     if (server_entry) 
2027       silc_idcache_del_by_context(server->global_list->servers, server_entry);
2028   }
2029
2030   /* Update server entry */
2031   idata->status |= SILC_IDLIST_STATUS_REGISTERED;
2032   new_server->server_name = server_name;
2033   new_server->id = server_id;
2034   
2035   SILC_LOG_DEBUG(("New server id(%s)",
2036                   silc_id_render(server_id, SILC_ID_SERVER)));
2037
2038   /* Add again the entry to the ID cache. */
2039   silc_idcache_add(local ? server->local_list->servers : 
2040                    server->global_list->servers, server_name, server_id, 
2041                    new_server, 0, NULL);
2042
2043   /* Distribute the information about new server in the SILC network
2044      to our router. If we are normal server we won't send anything
2045      since this connection must be our router connection. */
2046   if (server->server_type == SILC_ROUTER && !server->standalone &&
2047       server->router->connection != sock)
2048     silc_server_send_new_id(server, server->router->connection,
2049                             TRUE, new_server->id, SILC_ID_SERVER, 
2050                             silc_id_get_len(server_id, SILC_ID_SERVER));
2051
2052   if (server->server_type == SILC_ROUTER)
2053     server->stat.cell_servers++;
2054
2055   /* Check whether this router connection has been replaced by an
2056      backup router. If it has been then we'll disable the server and will
2057      ignore everything it will send until the backup router resuming
2058      protocol has been completed. */
2059   if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
2060       silc_server_backup_replaced_get(server, server_id, NULL)) {
2061     /* Send packet to the server indicating that it cannot use this
2062        connection as it has been replaced by backup router. */
2063     SilcBuffer packet = silc_buffer_alloc(2);
2064     silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
2065     silc_buffer_format(packet,
2066                        SILC_STR_UI_CHAR(SILC_SERVER_BACKUP_REPLACED),
2067                        SILC_STR_UI_CHAR(0),
2068                        SILC_STR_END);
2069     silc_server_packet_send(server, sock, 
2070                             SILC_PACKET_RESUME_ROUTER, 0, 
2071                             packet->data, packet->len, TRUE);
2072     silc_buffer_free(packet);
2073
2074     /* Mark the router disabled. The data sent earlier will go but nothing
2075        after this does not go to this connection. */
2076     idata->status |= SILC_IDLIST_STATUS_DISABLED;
2077   } else {
2078     /* If it is router announce our stuff to it. */
2079     if (sock->type == SILC_SOCKET_TYPE_ROUTER && 
2080         server->server_type == SILC_ROUTER) {
2081       silc_server_announce_servers(server, FALSE, 0, sock);
2082       silc_server_announce_clients(server, 0, sock);
2083       silc_server_announce_channels(server, 0, sock);
2084     }
2085   }
2086
2087   return new_server;
2088 }
2089
2090 /* Processes incoming New ID packet. New ID Payload is used to distribute
2091    information about newly registered clients and servers. */
2092
2093 static void silc_server_new_id_real(SilcServer server, 
2094                                     SilcSocketConnection sock,
2095                                     SilcPacketContext *packet,
2096                                     int broadcast)
2097 {
2098   SilcBuffer buffer = packet->buffer;
2099   SilcIDList id_list;
2100   SilcServerEntry router, server_entry;
2101   SilcSocketConnection router_sock;
2102   SilcIDPayload idp;
2103   SilcIdType id_type;
2104   void *id;
2105
2106   SILC_LOG_DEBUG(("Processing new ID"));
2107
2108   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2109       server->server_type == SILC_SERVER ||
2110       packet->src_id_type != SILC_ID_SERVER)
2111     return;
2112
2113   idp = silc_id_payload_parse(buffer->data, buffer->len);
2114   if (!idp)
2115     return;
2116
2117   id_type = silc_id_payload_get_type(idp);
2118
2119   /* Normal server cannot have other normal server connections */
2120   server_entry = (SilcServerEntry)sock->user_data;
2121   if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER &&
2122       server_entry->server_type == SILC_SERVER)
2123     goto out;
2124
2125   id = silc_id_payload_get_id(idp);
2126   if (!id)
2127     goto out;
2128
2129   /* If the packet is coming from server then use the sender as the
2130      origin of the the packet. If it came from router then check the real
2131      sender of the packet and use that as the origin. */
2132   if (sock->type == SILC_SOCKET_TYPE_SERVER) {
2133     id_list = server->local_list;
2134     router_sock = sock;
2135     router = sock->user_data;
2136
2137     /* If the sender is backup router and ID is server (and we are not
2138        backup router) then switch the entry to global list. */
2139     if (server_entry->server_type == SILC_BACKUP_ROUTER && 
2140         id_type == SILC_ID_SERVER && 
2141         server->id_entry->server_type != SILC_BACKUP_ROUTER) {
2142       id_list = server->global_list;
2143       router_sock = server->router ? server->router->connection : sock;
2144     }
2145   } else {
2146     void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2147                                      packet->src_id_type);
2148     router = silc_idlist_find_server_by_id(server->global_list,
2149                                            sender_id, TRUE, NULL);
2150     if (!router)
2151       router = silc_idlist_find_server_by_id(server->local_list,
2152                                              sender_id, TRUE, NULL);
2153     silc_free(sender_id);
2154     router_sock = sock;
2155     id_list = server->global_list;
2156   }
2157
2158   if (!router)
2159     goto out;
2160
2161   switch(id_type) {
2162   case SILC_ID_CLIENT:
2163     {
2164       SilcClientEntry entry;
2165
2166       /* Check that we do not have this client already */
2167       entry = silc_idlist_find_client_by_id(server->global_list, 
2168                                             id, server->server_type, 
2169                                             NULL);
2170       if (!entry)
2171         entry = silc_idlist_find_client_by_id(server->local_list, 
2172                                               id, server->server_type,
2173                                               NULL);
2174       if (entry) {
2175         SILC_LOG_DEBUG(("Ignoring client that we already have"));
2176         goto out;
2177       }
2178
2179       SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
2180                       silc_id_render(id, SILC_ID_CLIENT),
2181                       sock->type == SILC_SOCKET_TYPE_SERVER ?
2182                       "Server" : "Router", sock->hostname));
2183     
2184       /* As a router we keep information of all global information in our
2185          global list. Cell wide information however is kept in the local
2186          list. */
2187       entry = silc_idlist_add_client(id_list, NULL, NULL, NULL, 
2188                                      id, router, NULL, 0);
2189       if (!entry) {
2190         SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
2191
2192         /* Inform the sender that the ID is not usable */
2193         silc_server_send_notify_signoff(server, sock, FALSE, id, NULL);
2194         goto out;
2195       }
2196       entry->nickname = NULL;
2197       entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2198
2199       if (sock->type == SILC_SOCKET_TYPE_SERVER)
2200         server->stat.cell_clients++;
2201       server->stat.clients++;
2202     }
2203     break;
2204
2205   case SILC_ID_SERVER:
2206     {
2207       SilcServerEntry entry;
2208
2209       /* If the ID is mine, ignore it. */
2210       if (SILC_ID_SERVER_COMPARE(id, server->id)) {
2211         SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
2212         break;
2213       }
2214
2215       /* If the ID is the sender's ID, ignore it (we have it already) */
2216       if (SILC_ID_SERVER_COMPARE(id, router->id)) {
2217         SILC_LOG_DEBUG(("Ignoring sender's own ID"));
2218         break;
2219       }
2220       
2221       /* Check that we do not have this server already */
2222       entry = silc_idlist_find_server_by_id(server->global_list, 
2223                                             id, server->server_type, 
2224                                             NULL);
2225       if (!entry)
2226         entry = silc_idlist_find_server_by_id(server->local_list, 
2227                                               id, server->server_type,
2228                                               NULL);
2229       if (entry) {
2230         SILC_LOG_DEBUG(("Ignoring server that we already have"));
2231         goto out;
2232       }
2233
2234       SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
2235                       silc_id_render(id, SILC_ID_SERVER),
2236                       sock->type == SILC_SOCKET_TYPE_SERVER ?
2237                       "Server" : "Router", sock->hostname));
2238       
2239       /* As a router we keep information of all global information in our 
2240          global list. Cell wide information however is kept in the local
2241          list. */
2242       entry = silc_idlist_add_server(id_list, NULL, 0, id, router, 
2243                                      router_sock);
2244       if (!entry) {
2245         SILC_LOG_ERROR(("Could not add new server to the ID Cache"));
2246         goto out;
2247       }
2248       entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2249       
2250       if (sock->type == SILC_SOCKET_TYPE_SERVER)
2251         server->stat.cell_servers++;
2252       server->stat.servers++;
2253     }
2254     break;
2255
2256   case SILC_ID_CHANNEL:
2257     SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
2258     goto out;
2259     break;
2260
2261   default:
2262     goto out;
2263     break;
2264   }
2265
2266   /* If the sender of this packet is server and we are router we need to
2267      broadcast this packet to other routers in the network. */
2268   if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
2269       sock->type == SILC_SOCKET_TYPE_SERVER &&
2270       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2271     SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
2272     silc_server_packet_send(server, server->router->connection,
2273                             packet->type, 
2274                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
2275                             buffer->data, buffer->len, FALSE);
2276     silc_server_backup_send(server, (SilcServerEntry)sock->user_data, 
2277                             packet->type, packet->flags,
2278                             packet->buffer->data, packet->buffer->len, 
2279                             FALSE, TRUE);
2280   }
2281
2282  out:
2283   silc_id_payload_free(idp);
2284 }
2285
2286
2287 /* Processes incoming New ID packet. New ID Payload is used to distribute
2288    information about newly registered clients and servers. */
2289
2290 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
2291                         SilcPacketContext *packet)
2292 {
2293   silc_server_new_id_real(server, sock, packet, TRUE);
2294 }
2295
2296 /* Receoved New Id List packet, list of New ID payloads inside one
2297    packet. Process the New ID payloads one by one. */
2298
2299 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
2300                              SilcPacketContext *packet)
2301 {
2302   SilcPacketContext *new_id;
2303   SilcBuffer idp;
2304   SilcUInt16 id_len;
2305
2306   SILC_LOG_DEBUG(("Processing New ID List"));
2307
2308   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2309       packet->src_id_type != SILC_ID_SERVER)
2310     return;
2311
2312   /* If the sender of this packet is server and we are router we need to
2313      broadcast this packet to other routers in the network. Broadcast
2314      this list packet instead of multiple New ID packets. */
2315   if (!server->standalone && server->server_type == SILC_ROUTER &&
2316       sock->type == SILC_SOCKET_TYPE_SERVER &&
2317       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2318     SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
2319     silc_server_packet_send(server, server->router->connection,
2320                             packet->type, 
2321                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
2322                             packet->buffer->data, packet->buffer->len, FALSE);
2323     silc_server_backup_send(server, (SilcServerEntry)sock->user_data, 
2324                             packet->type, packet->flags,
2325                             packet->buffer->data, packet->buffer->len, 
2326                             FALSE, TRUE);
2327   }
2328
2329   /* Make copy of the original packet context, except for the actual
2330      data buffer, which we will here now fetch from the original buffer. */
2331   new_id = silc_packet_context_alloc();
2332   new_id->type = SILC_PACKET_NEW_ID;
2333   new_id->flags = packet->flags;
2334   new_id->src_id = packet->src_id;
2335   new_id->src_id_len = packet->src_id_len;
2336   new_id->src_id_type = packet->src_id_type;
2337   new_id->dst_id = packet->dst_id;
2338   new_id->dst_id_len = packet->dst_id_len;
2339   new_id->dst_id_type = packet->dst_id_type;
2340
2341   idp = silc_buffer_alloc(256);
2342   new_id->buffer = idp;
2343
2344   while (packet->buffer->len) {
2345     SILC_GET16_MSB(id_len, packet->buffer->data + 2);
2346     if ((id_len > packet->buffer->len) ||
2347         (id_len > idp->truelen))
2348       break;
2349
2350     silc_buffer_pull_tail(idp, 4 + id_len);
2351     silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
2352
2353     /* Process the New ID */
2354     silc_server_new_id_real(server, sock, new_id, FALSE);
2355
2356     silc_buffer_push_tail(idp, 4 + id_len);
2357     silc_buffer_pull(packet->buffer, 4 + id_len);
2358   }
2359
2360   silc_buffer_free(idp);
2361   silc_free(new_id);
2362 }
2363
2364 /* Received New Channel packet. Information about new channels in the 
2365    network are distributed using this packet. Save the information about
2366    the new channel. This usually comes from router but also normal server
2367    can send this to notify channels it has when it connects to us. */
2368
2369 void silc_server_new_channel(SilcServer server,
2370                              SilcSocketConnection sock,
2371                              SilcPacketContext *packet)
2372 {
2373   SilcChannelPayload payload;
2374   SilcChannelID *channel_id;
2375   char *channel_name;
2376   SilcUInt32 name_len;
2377   unsigned char *id;
2378   SilcUInt32 id_len;
2379   SilcUInt32 mode;
2380   SilcServerEntry server_entry;
2381   SilcChannelEntry channel;
2382
2383   SILC_LOG_DEBUG(("Processing New Channel"));
2384
2385   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2386       packet->src_id_type != SILC_ID_SERVER ||
2387       server->server_type == SILC_SERVER)
2388     return;
2389
2390   /* Parse the channel payload */
2391   payload = silc_channel_payload_parse(packet->buffer->data,
2392                                        packet->buffer->len);
2393   if (!payload)
2394     return;
2395     
2396   /* Get the channel ID */
2397   channel_id = silc_channel_get_id_parse(payload);
2398   if (!channel_id) {
2399     silc_channel_payload_free(payload);
2400     return;
2401   }
2402
2403   channel_name = silc_channel_get_name(payload, &name_len);
2404   if (name_len > 256)
2405     channel_name[255] = '\0';
2406
2407   id = silc_channel_get_id(payload, &id_len);
2408
2409   server_entry = (SilcServerEntry)sock->user_data;
2410
2411   if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
2412     /* Add the channel to global list as it is coming from router. It 
2413        cannot be our own channel as it is coming from router. */
2414
2415     /* Check that we don't already have this channel */
2416     channel = silc_idlist_find_channel_by_name(server->local_list, 
2417                                                channel_name, NULL);
2418     if (!channel)
2419       channel = silc_idlist_find_channel_by_name(server->global_list, 
2420                                                  channel_name, NULL);
2421     if (!channel) {
2422       SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
2423                       silc_id_render(channel_id, SILC_ID_CHANNEL), 
2424                       sock->hostname));
2425     
2426       silc_idlist_add_channel(server->global_list, strdup(channel_name), 
2427                               0, channel_id, sock->user_data, NULL, NULL, 0);
2428       server->stat.channels++;
2429     }
2430   } else {
2431     /* The channel is coming from our server, thus it is in our cell
2432        we will add it to our local list. */
2433     SilcBuffer chk;
2434
2435     SILC_LOG_DEBUG(("Channel id(%s) from [Server] %s",
2436                     silc_id_render(channel_id, SILC_ID_CHANNEL), 
2437                     sock->hostname));
2438
2439     /* Check that we don't already have this channel */
2440     channel = silc_idlist_find_channel_by_name(server->local_list, 
2441                                                channel_name, NULL);
2442     if (!channel)
2443       channel = silc_idlist_find_channel_by_name(server->global_list, 
2444                                                  channel_name, NULL);
2445
2446     /* If the channel does not exist, then create it. This creates a new
2447        key to the channel as well that we will send to the server. */
2448     if (!channel) {
2449       /* The protocol says that the Channel ID's IP address must be based
2450          on the router's IP address.  Check whether the ID is based in our
2451          IP and if it is not then create a new ID and enforce the server
2452          to switch the ID. */
2453       if (server_entry->server_type != SILC_BACKUP_ROUTER &&
2454           !SILC_ID_COMPARE(channel_id, server->id, server->id->ip.data_len)) {
2455         SilcChannelID *tmp;
2456         SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2457         
2458         if (silc_id_create_channel_id(server, server->id, server->rng, &tmp)) {
2459           silc_server_send_notify_channel_change(server, sock, FALSE, 
2460                                                  channel_id, tmp);
2461           silc_free(channel_id);
2462           channel_id = tmp;
2463         }
2464       }
2465
2466       /* Create the channel with the provided Channel ID */
2467       channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
2468                                                        channel_name,
2469                                                        channel_id, FALSE);
2470       if (!channel) {
2471         silc_channel_payload_free(payload);
2472         silc_free(channel_id);
2473         return;
2474       }
2475
2476       /* Get the mode and set it to the channel */
2477       channel->mode = silc_channel_get_mode(payload);
2478
2479       /* Send the new channel key to the server */
2480       id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2481       id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
2482       chk = silc_channel_key_payload_encode(id_len, id,
2483                                             strlen(channel->channel_key->
2484                                                    cipher->name),
2485                                             channel->channel_key->cipher->name,
2486                                             channel->key_len / 8, 
2487                                             channel->key);
2488       silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
2489                               chk->data, chk->len, FALSE);
2490       silc_buffer_free(chk);
2491
2492     } else {
2493       /* The channel exist by that name, check whether the ID's match.
2494          If they don't then we'll force the server to use the ID we have.
2495          We also create a new key for the channel. */
2496       SilcBuffer users = NULL, users_modes = NULL;
2497
2498       if (!SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
2499         /* They don't match, send CHANNEL_CHANGE notify to the server to
2500            force the ID change. */
2501         SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2502         silc_server_send_notify_channel_change(server, sock, FALSE, 
2503                                                channel_id, channel->id);
2504       }
2505
2506       /* If the mode is different from what we have then enforce the
2507          mode change. */
2508       mode = silc_channel_get_mode(payload);
2509       if (channel->mode != mode) {
2510         SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
2511         silc_server_send_notify_cmode(server, sock, FALSE, channel,
2512                                       channel->mode, server->id,
2513                                       SILC_ID_SERVER,
2514                                       channel->cipher, channel->hmac_name,
2515                                       channel->passphrase);
2516       }
2517
2518       /* Create new key for the channel and send it to the server and
2519          everybody else possibly on the channel. */
2520
2521       if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
2522         if (!silc_server_create_channel_key(server, channel, 0))
2523           return;
2524         
2525         /* Send to the channel */
2526         silc_server_send_channel_key(server, sock, channel, FALSE);
2527         id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2528         id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
2529
2530         /* Send to the server */
2531         chk = silc_channel_key_payload_encode(id_len, id,
2532                                               strlen(channel->channel_key->
2533                                                      cipher->name),
2534                                               channel->channel_key->
2535                                               cipher->name,
2536                                               channel->key_len / 8, 
2537                                               channel->key);
2538         silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
2539                                 chk->data, chk->len, FALSE);
2540         silc_buffer_free(chk);
2541         silc_free(id);
2542       }
2543
2544       silc_free(channel_id);
2545
2546       /* Since the channel is coming from server and we also know about it
2547          then send the JOIN notify to the server so that it see's our
2548          users on the channel "joining" the channel. */
2549       silc_server_announce_get_channel_users(server, channel, &users,
2550                                              &users_modes);
2551       if (users) {
2552         silc_buffer_push(users, users->data - users->head);
2553         silc_server_packet_send(server, sock,
2554                                 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2555                                 users->data, users->len, FALSE);
2556         silc_buffer_free(users);
2557       }
2558       if (users_modes) {
2559         silc_buffer_push(users_modes, users_modes->data - users_modes->head);
2560         silc_server_packet_send_dest(server, sock,
2561                                      SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2562                                      channel->id, SILC_ID_CHANNEL,
2563                                      users_modes->data, 
2564                                      users_modes->len, FALSE);
2565         silc_buffer_free(users_modes);
2566       }
2567     }
2568   }
2569
2570   silc_channel_payload_free(payload);
2571 }
2572
2573 /* Received New Channel List packet, list of New Channel List payloads inside
2574    one packet. Process the New Channel payloads one by one. */
2575
2576 void silc_server_new_channel_list(SilcServer server,
2577                                   SilcSocketConnection sock,
2578                                   SilcPacketContext *packet)
2579 {
2580   SilcPacketContext *new;
2581   SilcBuffer buffer;
2582   SilcUInt16 len1, len2;
2583
2584   SILC_LOG_DEBUG(("Processing New Channel List"));
2585
2586   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2587       packet->src_id_type != SILC_ID_SERVER ||
2588       server->server_type == SILC_SERVER)
2589     return;
2590
2591   /* If the sender of this packet is server and we are router we need to
2592      broadcast this packet to other routers in the network. Broadcast
2593      this list packet instead of multiple New Channel packets. */
2594   if (!server->standalone && server->server_type == SILC_ROUTER &&
2595       sock->type == SILC_SOCKET_TYPE_SERVER &&
2596       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2597     SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
2598     silc_server_packet_send(server, server->router->connection,
2599                             packet->type, 
2600                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
2601                             packet->buffer->data, packet->buffer->len, FALSE);
2602     silc_server_backup_send(server, (SilcServerEntry)sock->user_data, 
2603                             packet->type, packet->flags,
2604                             packet->buffer->data, packet->buffer->len, 
2605                             FALSE, TRUE);
2606   }
2607
2608   /* Make copy of the original packet context, except for the actual
2609      data buffer, which we will here now fetch from the original buffer. */
2610   new = silc_packet_context_alloc();
2611   new->type = SILC_PACKET_NEW_CHANNEL;
2612   new->flags = packet->flags;
2613   new->src_id = packet->src_id;
2614   new->src_id_len = packet->src_id_len;
2615   new->src_id_type = packet->src_id_type;
2616   new->dst_id = packet->dst_id;
2617   new->dst_id_len = packet->dst_id_len;
2618   new->dst_id_type = packet->dst_id_type;
2619
2620   buffer = silc_buffer_alloc(512);
2621   new->buffer = buffer;
2622
2623   while (packet->buffer->len) {
2624     SILC_GET16_MSB(len1, packet->buffer->data);
2625     if ((len1 > packet->buffer->len) ||
2626         (len1 > buffer->truelen))
2627       break;
2628
2629     SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
2630     if ((len2 > packet->buffer->len) ||
2631         (len2 > buffer->truelen))
2632       break;
2633
2634     silc_buffer_pull_tail(buffer, 8 + len1 + len2);
2635     silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
2636
2637     /* Process the New Channel */
2638     silc_server_new_channel(server, sock, new);
2639
2640     silc_buffer_push_tail(buffer, 8 + len1 + len2);
2641     silc_buffer_pull(packet->buffer, 8 + len1 + len2);
2642   }
2643
2644   silc_buffer_free(buffer);
2645   silc_free(new);
2646 }
2647
2648 /* Received key agreement packet. This packet is never for us. It is to
2649    the client in the packet's destination ID. Sending of this sort of packet
2650    equals sending private message, ie. it is sent point to point from
2651    one client to another. */
2652
2653 void silc_server_key_agreement(SilcServer server,
2654                                SilcSocketConnection sock,
2655                                SilcPacketContext *packet)
2656 {
2657   SilcSocketConnection dst_sock;
2658   SilcIDListData idata;
2659
2660   SILC_LOG_DEBUG(("Start"));
2661
2662   if (packet->src_id_type != SILC_ID_CLIENT ||
2663       packet->dst_id_type != SILC_ID_CLIENT)
2664     return;
2665
2666   if (!packet->dst_id)
2667     return;
2668
2669   /* Get the route to the client */
2670   dst_sock = silc_server_get_client_route(server, packet->dst_id,
2671                                           packet->dst_id_len, NULL, &idata);
2672   if (!dst_sock)
2673     return;
2674
2675   /* Relay the packet */
2676   silc_server_relay_packet(server, dst_sock, idata->send_key,
2677                            idata->hmac_send, idata->psn_send++,
2678                            packet, FALSE);
2679 }
2680
2681 /* Received connection auth request packet that is used during connection
2682    phase to resolve the mandatory authentication method.  This packet can
2683    actually be received at anytime but usually it is used only during
2684    the connection authentication phase. Now, protocol says that this packet
2685    can come from client or server, however, we support only this coming
2686    from client and expect that server always knows what authentication
2687    method to use. */
2688
2689 void silc_server_connection_auth_request(SilcServer server,
2690                                          SilcSocketConnection sock,
2691                                          SilcPacketContext *packet)
2692 {
2693   SilcServerConfigClient *client = NULL;
2694   SilcUInt16 conn_type;
2695   int ret;
2696   SilcAuthMethod auth_meth = SILC_AUTH_NONE;
2697
2698   SILC_LOG_DEBUG(("Start"));
2699
2700   if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT)
2701     return;
2702
2703   /* Parse the payload */
2704   ret = silc_buffer_unformat(packet->buffer,
2705                              SILC_STR_UI_SHORT(&conn_type),
2706                              SILC_STR_UI_SHORT(NULL),
2707                              SILC_STR_END);
2708   if (ret == -1)
2709     return;
2710
2711   if (conn_type != SILC_SOCKET_TYPE_CLIENT)
2712     return;
2713
2714   /* Get the authentication method for the client */
2715   auth_meth = SILC_AUTH_NONE;
2716   client = silc_server_config_find_client(server, sock->ip);
2717   if (!client)
2718     client = silc_server_config_find_client(server, sock->hostname);
2719   if (client) {
2720     if (client->passphrase) {
2721       if (client->publickeys && !server->config->prefer_passphrase_auth)
2722         auth_meth = SILC_AUTH_PUBLIC_KEY;
2723       else
2724         auth_meth = SILC_AUTH_PASSWORD;
2725     } else if (client->publickeys)
2726       auth_meth = SILC_AUTH_PUBLIC_KEY;
2727   }
2728
2729   /* Send it back to the client */
2730   silc_server_send_connection_auth_request(server, sock, conn_type, auth_meth);
2731 }
2732
2733 /* Received REKEY packet. The sender of the packet wants to regenerate
2734    its session keys. This starts the REKEY protocol. */
2735
2736 void silc_server_rekey(SilcServer server,
2737                        SilcSocketConnection sock,
2738                        SilcPacketContext *packet)
2739 {
2740   SilcProtocol protocol;
2741   SilcServerRekeyInternalContext *proto_ctx;
2742   SilcIDListData idata = (SilcIDListData)sock->user_data;
2743
2744   SILC_LOG_DEBUG(("Start"));
2745
2746   /* Allocate internal protocol context. This is sent as context
2747      to the protocol. */
2748   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
2749   proto_ctx->server = (void *)server;
2750   proto_ctx->sock = sock;
2751   proto_ctx->responder = TRUE;
2752   proto_ctx->pfs = idata->rekey->pfs;
2753       
2754   /* Perform rekey protocol. Will call the final callback after the
2755      protocol is over. */
2756   silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY, 
2757                       &protocol, proto_ctx, silc_server_rekey_final);
2758   sock->protocol = protocol;
2759
2760   if (proto_ctx->pfs == FALSE)
2761     /* Run the protocol */
2762     silc_protocol_execute(protocol, server->schedule, 0, 0);
2763 }
2764
2765 /* Received file transger packet. This packet is never for us. It is to
2766    the client in the packet's destination ID. Sending of this sort of packet
2767    equals sending private message, ie. it is sent point to point from
2768    one client to another. */
2769
2770 void silc_server_ftp(SilcServer server,
2771                      SilcSocketConnection sock,
2772                      SilcPacketContext *packet)
2773 {
2774   SilcSocketConnection dst_sock;
2775   SilcIDListData idata;
2776
2777   SILC_LOG_DEBUG(("Start"));
2778
2779   if (packet->src_id_type != SILC_ID_CLIENT ||
2780       packet->dst_id_type != SILC_ID_CLIENT)
2781     return;
2782
2783   if (!packet->dst_id)
2784     return;
2785
2786   /* Get the route to the client */
2787   dst_sock = silc_server_get_client_route(server, packet->dst_id,
2788                                           packet->dst_id_len, NULL, &idata);
2789   if (!dst_sock)
2790     return;
2791
2792   /* Relay the packet */
2793   silc_server_relay_packet(server, dst_sock, idata->send_key,
2794                            idata->hmac_send, idata->psn_send++,
2795                            packet, FALSE);
2796 }