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