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