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