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