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;
41   SilcClientID *client_id, *client_id2;
42   SilcChannelEntry channel;
43   SilcClientEntry client;
44   SilcChannelClientEntry chl;
45   unsigned int mode;
46   unsigned char *tmp;
47   unsigned int tmp_len;
48
49   SILC_LOG_DEBUG(("Start"));
50
51   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
52       packet->src_id_type != SILC_ID_SERVER)
53     return;
54
55   if (!packet->dst_id)
56     return;
57
58   /* If the packet is destined directly to a client then relay the packet
59      before processing it. */
60   if (packet->dst_id_type == SILC_ID_CLIENT) {
61     SilcIDListData idata;
62     SilcSocketConnection dst_sock;
63
64     /* Get the route to the client */
65     dst_sock = silc_server_get_client_route(server, packet->dst_id,
66                                             packet->dst_id_len, &idata);
67     if (dst_sock)
68       /* Relay the packet */
69       silc_server_relay_packet(server, dst_sock, idata->send_key,
70                                idata->hmac, packet, TRUE);
71   }
72
73   /* If we are router and this packet is not already broadcast packet
74      we will broadcast it. The sending socket really cannot be router or
75      the router is buggy. If this packet is coming from router then it must
76      have the broadcast flag set already and we won't do anything. */
77   if (!server->standalone && server->server_type == SILC_ROUTER &&
78       sock->type == SILC_SOCKET_TYPE_SERVER &&
79       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
80     SILC_LOG_DEBUG(("Broadcasting received Notify packet"));
81     silc_server_packet_send(server, server->router->connection, packet->type,
82                             packet->flags | SILC_PACKET_FLAG_BROADCAST, 
83                             packet->buffer->data, packet->buffer->len, FALSE);
84   }
85
86   payload = silc_notify_payload_parse(packet->buffer);
87   if (!payload)
88     return;
89
90   type = silc_notify_get_type(payload);
91   args = silc_notify_get_args(payload);
92   if (!args)
93     goto out;
94
95   switch(type) {
96   case SILC_NOTIFY_TYPE_JOIN:
97     /* 
98      * Distribute the notify to local clients on the channel
99      */
100     SILC_LOG_DEBUG(("JOIN notify"));
101
102     /* Get Channel ID */
103     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
104     if (!tmp)
105       goto out;
106     channel_id = silc_id_payload_parse_id(tmp, tmp_len);
107     if (!channel_id)
108       goto out;
109
110     /* Get channel entry */
111     channel = silc_idlist_find_channel_by_id(server->global_list, 
112                                              channel_id, NULL);
113     if (!channel) {
114       channel = silc_idlist_find_channel_by_id(server->local_list, 
115                                                channel_id, NULL);
116       if (!channel) {
117         silc_free(channel_id);
118         goto out;
119       }
120     }
121     silc_free(channel_id);
122
123     /* Get client ID */
124     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
125     if (!tmp)
126       goto out;
127     client_id = silc_id_payload_parse_id(tmp, tmp_len);
128     if (!client_id)
129       goto out;
130
131     /* Send to channel */
132     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
133                                        FALSE, packet->buffer->data, 
134                                        packet->buffer->len, FALSE);
135
136     /* If the the client is not in local list we check global list (ie. the
137        channel will be global channel) and if it does not exist then create
138        entry for the client. */
139     client = silc_idlist_find_client_by_id(server->global_list, 
140                                            client_id, NULL);
141     if (!client) {
142       client = silc_idlist_find_client_by_id(server->local_list, 
143                                              client_id, NULL);
144       if (!client) {
145         /* If router did not find the client the it is bogus */
146         if (server->server_type == SILC_ROUTER)
147           goto out;
148
149         client = 
150           silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
151                                  silc_id_dup(client_id, SILC_ID_CLIENT), 
152                                  sock->user_data, NULL);
153         if (!client) {
154           silc_free(client_id);
155           goto out;
156         }
157       }
158     }
159
160     /* Do not add client to channel if it is there already */
161     if (silc_server_client_on_channel(client, channel))
162       break;
163
164     if (server->server_type == SILC_SERVER && 
165         sock->type == SILC_SOCKET_TYPE_ROUTER)
166       /* The channel is global now */
167       channel->global_users = TRUE;
168
169     /* JOIN the global client to the channel (local clients (if router 
170        created the channel) is joined in the pending JOIN command). */
171     chl = silc_calloc(1, sizeof(*chl));
172     chl->client = client;
173     chl->channel = channel;
174     silc_list_add(channel->user_list, chl);
175     silc_list_add(client->channels, chl);
176     silc_free(client_id);
177
178     break;
179
180   case SILC_NOTIFY_TYPE_LEAVE:
181     /* 
182      * Distribute the notify to local clients on the channel
183      */
184     SILC_LOG_DEBUG(("LEAVE notify"));
185
186     channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
187                                 packet->dst_id_type);
188     if (!channel_id)
189       goto out;
190
191     /* Get channel entry */
192     channel = silc_idlist_find_channel_by_id(server->global_list, 
193                                              channel_id, NULL);
194     if (!channel) { 
195       channel = silc_idlist_find_channel_by_id(server->local_list, 
196                                                channel_id, NULL);
197       if (!channel) {
198         silc_free(channel_id);
199         goto out;
200       }
201     }
202
203     /* Get client ID */
204     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
205     if (!tmp) {
206       silc_free(channel_id);
207       goto out;
208     }
209     client_id = silc_id_payload_parse_id(tmp, tmp_len);
210     if (!client_id) {
211       silc_free(channel_id);
212       goto out;
213     }
214
215     /* Send to channel */
216     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
217                                        FALSE, packet->buffer->data, 
218                                        packet->buffer->len, FALSE);
219
220     /* Get client entry */
221     client = silc_idlist_find_client_by_id(server->global_list, 
222                                            client_id, NULL);
223     if (!client) {
224       client = silc_idlist_find_client_by_id(server->local_list, 
225                                              client_id, NULL);
226       if (!client) {
227         silc_free(client_id);
228         silc_free(channel_id);
229         goto out;
230       }
231     }
232     silc_free(client_id);
233
234     /* Remove the user from channel */
235     silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
236     break;
237
238   case SILC_NOTIFY_TYPE_SIGNOFF:
239     /* 
240      * Distribute the notify to local clients on the channel
241      */
242     SILC_LOG_DEBUG(("SIGNOFF notify"));
243
244     /* Get client ID */
245     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
246     if (!tmp)
247       goto out;
248     client_id = silc_id_payload_parse_id(tmp, tmp_len);
249     if (!client_id)
250       goto out;
251
252     /* Get client entry */
253     client = silc_idlist_find_client_by_id(server->global_list, 
254                                            client_id, NULL);
255     if (!client) {
256       client = silc_idlist_find_client_by_id(server->local_list, 
257                                              client_id, NULL);
258       if (!client) {
259         silc_free(client_id);
260         goto out;
261       }
262     }
263     silc_free(client_id);
264
265     /* Get signoff message */
266     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
267     if (tmp_len > 128)
268       tmp = NULL;
269
270     /* Remove the client from all channels */
271     silc_server_remove_from_channels(server, NULL, client, TRUE, tmp, TRUE);
272
273     /* Remove the client entry */
274     if (!silc_idlist_del_client(server->global_list, client))
275       silc_idlist_del_client(server->local_list, client);
276     break;
277
278   case SILC_NOTIFY_TYPE_TOPIC_SET:
279     /* 
280      * Distribute the notify to local clients on the channel
281      */
282
283     SILC_LOG_DEBUG(("TOPIC SET notify"));
284
285     channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
286                                 packet->dst_id_type);
287     if (!channel_id)
288       goto out;
289
290     /* Get channel entry */
291     channel = silc_idlist_find_channel_by_id(server->global_list, 
292                                              channel_id, NULL);
293     if (!channel) {
294       channel = silc_idlist_find_channel_by_id(server->local_list, 
295                                                channel_id, NULL);
296       if (!channel) {
297         silc_free(channel_id);
298         goto out;
299       }
300     }
301
302     /* Get the topic */
303     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
304     if (!tmp) {
305       silc_free(channel_id);
306       goto out;
307     }
308
309     if (channel->topic)
310       silc_free(channel->topic);
311     channel->topic = silc_calloc(tmp_len, sizeof(*channel->topic));
312     memcpy(channel->topic, tmp, tmp_len);
313
314     /* Send the same notify to the channel */
315     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
316                                        FALSE, packet->buffer->data, 
317                                        packet->buffer->len, FALSE);
318     silc_free(channel_id);
319     break;
320
321   case SILC_NOTIFY_TYPE_NICK_CHANGE:
322     {
323       /* 
324        * Distribute the notify to local clients on the channel
325        */
326       unsigned char *id, *id2;
327
328       SILC_LOG_DEBUG(("NICK CHANGE notify"));
329       
330       /* Get old client ID */
331       id = silc_argument_get_arg_type(args, 1, &tmp_len);
332       if (!id)
333         goto out;
334       client_id = silc_id_payload_parse_id(id, tmp_len);
335       if (!client_id)
336         goto out;
337       
338       /* Get new client ID */
339       id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
340       if (!id2)
341         goto out;
342       client_id2 = silc_id_payload_parse_id(id2, tmp_len);
343       if (!client_id2)
344         goto out;
345       
346       SILC_LOG_DEBUG(("Old Client ID id(%s)", 
347                       silc_id_render(client_id, SILC_ID_CLIENT)));
348       SILC_LOG_DEBUG(("New Client ID id(%s)", 
349                       silc_id_render(client_id2, SILC_ID_CLIENT)));
350
351       /* Replace the Client ID */
352       client = silc_idlist_replace_client_id(server->global_list, client_id,
353                                              client_id2);
354       if (!client)
355         client = silc_idlist_replace_client_id(server->local_list, client_id, 
356                                                client_id2);
357
358       if (client) {
359         /* The nickname is not valid anymore, set it NULL. This causes that
360            the nickname will be queried if someone wants to know it. */
361         if (client->nickname)
362           silc_free(client->nickname);
363         client->nickname = NULL;
364
365         /* Send the NICK_CHANGE notify type to local clients on the channels
366            this client is joined to. */
367         silc_server_send_notify_on_channels(server, NULL, client, 
368                                             SILC_NOTIFY_TYPE_NICK_CHANGE, 2,
369                                             id, tmp_len, 
370                                             id2, tmp_len);
371       }
372
373       silc_free(client_id);
374       if (!client)
375         silc_free(client_id2);
376       break;
377     }
378
379   case SILC_NOTIFY_TYPE_CMODE_CHANGE:
380     /* 
381      * Distribute the notify to local clients on the channel
382      */
383     
384     SILC_LOG_DEBUG(("CMODE CHANGE notify"));
385       
386     channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
387                                 packet->dst_id_type);
388     if (!channel_id)
389       goto out;
390
391     /* Get channel entry */
392     channel = silc_idlist_find_channel_by_id(server->global_list, 
393                                              channel_id, NULL);
394     if (!channel) {
395       channel = silc_idlist_find_channel_by_id(server->local_list, 
396                                                channel_id, NULL);
397       if (!channel) {
398         silc_free(channel_id);
399         goto out;
400       }
401     }
402
403     /* Send the same notify to the channel */
404     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
405                                        FALSE, packet->buffer->data, 
406                                        packet->buffer->len, FALSE);
407
408     /* Get the mode */
409     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
410     if (!tmp) {
411       silc_free(channel_id);
412       goto out;
413     }
414
415     SILC_GET32_MSB(mode, tmp);
416
417     /* Change mode */
418     channel->mode = mode;
419     silc_free(channel_id);
420     break;
421
422   case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
423     /* 
424      * Distribute the notify to local clients on the channel
425      */
426
427     SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
428
429     channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
430                                 packet->dst_id_type);
431     if (!channel_id)
432       goto out;
433
434     /* Get channel entry */
435     channel = silc_idlist_find_channel_by_id(server->global_list, 
436                                              channel_id, NULL);
437     if (!channel) {
438       channel = silc_idlist_find_channel_by_id(server->local_list, 
439                                                channel_id, NULL);
440       if (!channel) {
441         silc_free(channel_id);
442         goto out;
443       }
444     }
445
446     /* Get the mode */
447     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
448     if (!tmp) {
449       silc_free(channel_id);
450       goto out;
451     }
452       
453     SILC_GET32_MSB(mode, tmp);
454
455     /* Get target client */
456     tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
457     if (!tmp)
458       goto out;
459     client_id = silc_id_payload_parse_id(tmp, tmp_len);
460     if (!client_id)
461       goto out;
462     
463     /* Get client entry */
464     client = silc_idlist_find_client_by_id(server->global_list, 
465                                            client_id, NULL);
466     if (!client) {
467       client = silc_idlist_find_client_by_id(server->local_list, 
468                                              client_id, NULL);
469       if (!client) {
470         silc_free(client_id);
471         goto out;
472       }
473     }
474     silc_free(client_id);
475
476     /* Get entry to the channel user list */
477     silc_list_start(channel->user_list);
478     while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END)
479       if (chl->client == client) {
480         /* Change the mode */
481         chl->mode = mode;
482         break;
483       }
484
485     /* Send the same notify to the channel */
486     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
487                                        FALSE, packet->buffer->data, 
488                                        packet->buffer->len, FALSE);
489     silc_free(channel_id);
490     break;
491
492   case SILC_NOTIFY_TYPE_INVITE:
493     SILC_LOG_DEBUG(("INVITE notify (not-impl XXX)"));
494     break;
495
496   case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
497     SILC_LOG_DEBUG(("CHANNEL CHANGE notify (not-impl XXX)"));
498     break;
499
500   case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
501     SILC_LOG_DEBUG(("SERVER SIGNOFF notify (not-impl XXX)"));
502     break;
503
504   case SILC_NOTIFY_TYPE_KICKED:
505     /* 
506      * Distribute the notify to local clients on the channel
507      */
508     
509     SILC_LOG_DEBUG(("KICKED notify"));
510       
511     channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
512                                 packet->dst_id_type);
513     if (!channel_id)
514       goto out;
515
516     /* Get channel entry */
517     channel = silc_idlist_find_channel_by_id(server->global_list, 
518                                              channel_id, NULL);
519     if (!channel) {
520       channel = silc_idlist_find_channel_by_id(server->local_list, 
521                                                channel_id, NULL);
522       if (!channel) {
523         silc_free(channel_id);
524         goto out;
525       }
526     }
527     silc_free(channel_id);
528
529     /* Get client ID */
530     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
531     if (!tmp)
532       goto out;
533     client_id = silc_id_payload_parse_id(tmp, tmp_len);
534     if (!client_id)
535       goto out;
536
537     /* Send to channel */
538     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
539                                        FALSE, packet->buffer->data, 
540                                        packet->buffer->len, FALSE);
541
542     /* If the the client is not in local list we check global list */
543     client = silc_idlist_find_client_by_id(server->global_list, 
544                                            client_id, NULL);
545     if (!client) {
546       client = silc_idlist_find_client_by_id(server->local_list, 
547                                              client_id, NULL);
548       if (!client) {
549         silc_free(client_id);
550         goto out;
551       }
552     }
553
554     /* Remove the client from channel */
555     silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
556
557     break;
558
559   case SILC_NOTIFY_TYPE_KILLED:
560     {
561       /* 
562        * Distribute the notify to local clients on channels
563        */
564       unsigned char *id;
565       unsigned int id_len;
566     
567       SILC_LOG_DEBUG(("KILLED notify"));
568       
569       /* Get client ID */
570       id = silc_argument_get_arg_type(args, 1, &id_len);
571       if (!id)
572         goto out;
573       client_id = silc_id_payload_parse_id(id, id_len);
574       if (!client_id)
575         goto out;
576
577       /* If the the client is not in local list we check global list */
578       client = silc_idlist_find_client_by_id(server->global_list, 
579                                              client_id, NULL);
580       if (!client) {
581         client = silc_idlist_find_client_by_id(server->local_list, 
582                                                client_id, NULL);
583         if (!client) {
584           silc_free(client_id);
585           goto out;
586         }
587       }
588       silc_free(client_id);
589
590       /* If the client is one of ours, then close the connection to the
591          client now. This removes the client from all channels as well. */
592       if (packet->dst_id_type == SILC_ID_CLIENT && client->data.registered &&
593           client->connection) {
594         sock = client->connection;
595         silc_server_free_client_data(server, NULL, client, FALSE, NULL);
596         silc_server_close_connection(server, sock);
597         break;
598       }
599
600       /* Get comment */
601       tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
602       if (tmp_len > 128)
603         tmp = NULL;
604
605       /* Send the notify to local clients on the channels except to the
606          client who is killed. */
607       silc_server_send_notify_on_channels(server, client, client,
608                                           SILC_NOTIFY_TYPE_KILLED, 
609                                           tmp ? 2 : 1,
610                                           id, id_len, 
611                                           tmp, tmp_len);
612
613       /* Remove the client from all channels */
614       silc_server_remove_from_channels(server, NULL, client, FALSE, NULL, 
615                                        FALSE);
616
617       break;
618     }
619
620   case SILC_NOTIFY_TYPE_UMODE_CHANGE:
621     /*
622      * Save the mode of the client.
623      */
624
625     SILC_LOG_DEBUG(("UMODE_CHANGE notify"));
626       
627     /* Get client ID */
628     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
629     if (!tmp)
630       goto out;
631     client_id = silc_id_payload_parse_id(tmp, tmp_len);
632     if (!client_id)
633       goto out;
634
635     /* Get client entry */
636     client = silc_idlist_find_client_by_id(server->global_list, 
637                                            client_id, NULL);
638     if (!client) {
639       client = silc_idlist_find_client_by_id(server->local_list, 
640                                              client_id, NULL);
641       if (!client) {
642         silc_free(client_id);
643         goto out;
644       }
645     }
646     silc_free(client_id);
647
648     /* Get the mode */
649     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
650     if (!tmp)
651       goto out;
652
653     /* Save the mode */
654     SILC_GET32_MSB(client->mode, tmp);
655
656     break;
657
658     /* Ignore rest of the notify types for now */
659   case SILC_NOTIFY_TYPE_NONE:
660   case SILC_NOTIFY_TYPE_MOTD:
661     break;
662   default:
663     break;
664   }
665
666  out:
667   silc_notify_payload_free(payload);
668 }
669
670 void silc_server_notify_list(SilcServer server,
671                              SilcSocketConnection sock,
672                              SilcPacketContext *packet)
673 {
674   SilcPacketContext *new;
675   SilcBuffer buffer;
676   unsigned short len;
677
678   SILC_LOG_DEBUG(("Processing New Notify List"));
679
680   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
681       packet->src_id_type != SILC_ID_SERVER)
682     return;
683
684   /* Make copy of the original packet context, except for the actual
685      data buffer, which we will here now fetch from the original buffer. */
686   new = silc_packet_context_alloc();
687   new->type = SILC_PACKET_NOTIFY;
688   new->flags = packet->flags;
689   new->src_id = packet->src_id;
690   new->src_id_len = packet->src_id_len;
691   new->src_id_type = packet->src_id_type;
692   new->dst_id = packet->dst_id;
693   new->dst_id_len = packet->dst_id_len;
694   new->dst_id_type = packet->dst_id_type;
695
696   buffer = silc_buffer_alloc(1024);
697   new->buffer = buffer;
698
699   while (packet->buffer->len) {
700     SILC_GET16_MSB(len, packet->buffer->data + 2);
701     if (len > packet->buffer->len)
702       break;
703
704     if (len > buffer->truelen) {
705       silc_buffer_free(buffer);
706       buffer = silc_buffer_alloc(1024 + len);
707     }
708
709     silc_buffer_pull_tail(buffer, len);
710     silc_buffer_put(buffer, packet->buffer->data, len);
711
712     /* Process the Notify */
713     silc_server_notify(server, sock, new);
714
715     silc_buffer_push_tail(buffer, len);
716     silc_buffer_pull(packet->buffer, len);
717   }
718
719   silc_buffer_free(buffer);
720   silc_free(new);
721 }
722
723 /* Received private message. This resolves the destination of the message 
724    and sends the packet. This is used by both server and router.  If the
725    destination is our locally connected client this sends the packet to
726    the client. This may also send the message for further routing if
727    the destination is not in our server (or router). */
728
729 void silc_server_private_message(SilcServer server,
730                                  SilcSocketConnection sock,
731                                  SilcPacketContext *packet)
732 {
733   SilcSocketConnection dst_sock;
734   SilcIDListData idata;
735
736   SILC_LOG_DEBUG(("Start"));
737
738   if (packet->src_id_type != SILC_ID_CLIENT ||
739       packet->dst_id_type != SILC_ID_CLIENT)
740     return;
741
742   if (!packet->dst_id)
743     return;
744
745   /* Get the route to the client */
746   dst_sock = silc_server_get_client_route(server, packet->dst_id,
747                                           packet->dst_id_len, &idata);
748   if (!dst_sock)
749     return;
750
751   /* Send the private message */
752   silc_server_send_private_message(server, dst_sock, idata->send_key,
753                                    idata->hmac, packet);
754 }
755
756 /* Received private message key packet.. This packet is never for us. It is to
757    the client in the packet's destination ID. Sending of this sort of packet
758    equals sending private message, ie. it is sent point to point from
759    one client to another. */
760
761 void silc_server_private_message_key(SilcServer server,
762                                      SilcSocketConnection sock,
763                                      SilcPacketContext *packet)
764 {
765   SilcSocketConnection dst_sock;
766   SilcIDListData idata;
767
768   SILC_LOG_DEBUG(("Start"));
769
770   if (packet->src_id_type != SILC_ID_CLIENT ||
771       packet->dst_id_type != SILC_ID_CLIENT)
772     return;
773
774   if (!packet->dst_id)
775     return;
776
777   /* Get the route to the client */
778   dst_sock = silc_server_get_client_route(server, packet->dst_id,
779                                           packet->dst_id_len, &idata);
780   if (!dst_sock)
781     return;
782
783   /* Relay the packet */
784   silc_server_relay_packet(server, dst_sock, idata->send_key,
785                            idata->hmac, packet, FALSE);
786 }
787
788 /* Processes incoming command reply packet. The command reply packet may
789    be destined to one of our clients or it may directly for us. We will 
790    call the command reply routine after processing the packet. */
791
792 void silc_server_command_reply(SilcServer server,
793                                SilcSocketConnection sock,
794                                SilcPacketContext *packet)
795 {
796   SilcBuffer buffer = packet->buffer;
797   SilcClientEntry client = NULL;
798   SilcSocketConnection dst_sock;
799   SilcIDListData idata;
800   SilcClientID *id = NULL;
801
802   SILC_LOG_DEBUG(("Start"));
803
804   /* Source must be server or router */
805   if (packet->src_id_type != SILC_ID_SERVER &&
806       sock->type != SILC_SOCKET_TYPE_ROUTER)
807     return;
808
809   if (packet->dst_id_type == SILC_ID_CHANNEL)
810     return;
811
812   if (packet->dst_id_type == SILC_ID_CLIENT) {
813     /* Destination must be one of ours */
814     id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
815     if (!id)
816       return;
817     client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
818     if (!client) {
819       SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
820       silc_free(id);
821       return;
822     }
823   }
824
825   if (packet->dst_id_type == SILC_ID_SERVER) {
826     /* For now this must be for us */
827     if (SILC_ID_SERVER_COMPARE(packet->dst_id, server->id_string)) {
828       SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
829       return;
830     }
831   }
832
833   /* Execute command reply locally for the command */
834   silc_server_command_reply_process(server, sock, buffer);
835
836   if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
837     /* Relay the packet to the client */
838     
839     dst_sock = (SilcSocketConnection)client->connection;
840     silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len 
841                      + packet->dst_id_len + packet->padlen);
842     
843     silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
844     silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
845     
846     idata = (SilcIDListData)client;
847     
848     /* Encrypt packet */
849     silc_packet_encrypt(idata->send_key, idata->hmac, dst_sock->outbuf, 
850                         buffer->len);
851     
852     /* Send the packet */
853     silc_server_packet_send_real(server, dst_sock, TRUE);
854
855     silc_free(id);
856   }
857 }
858
859 /* Process received channel message. The message can be originated from
860    client or server. */
861
862 void silc_server_channel_message(SilcServer server,
863                                  SilcSocketConnection sock,
864                                  SilcPacketContext *packet)
865 {
866   SilcChannelEntry channel = NULL;
867   SilcChannelClientEntry chl;
868   SilcChannelID *id = NULL;
869   void *sender = NULL;
870
871   SILC_LOG_DEBUG(("Processing channel message"));
872
873   /* Sanity checks */
874   if (packet->dst_id_type != SILC_ID_CHANNEL) {
875     SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
876     goto out;
877   }
878
879   /* Find channel entry */
880   id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
881   if (!id)
882     goto out;
883   channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
884   if (!channel) {
885     channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
886     if (!channel) {
887       SILC_LOG_DEBUG(("Could not find channel"));
888       goto out;
889     }
890   }
891
892   /* See that this client is on the channel. If the message is coming
893      from router we won't do the check as the message is from client that
894      we don't know about. Also, if the original sender is not client
895      (as it can be server as well) we don't do the check. */
896   sender = silc_id_str2id(packet->src_id, packet->src_id_len, 
897                           packet->src_id_type);
898   if (!sender)
899     goto out;
900   if (sock->type != SILC_SOCKET_TYPE_ROUTER && 
901       packet->src_id_type == SILC_ID_CLIENT) {
902     silc_list_start(channel->user_list);
903     while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
904       if (chl->client && !SILC_ID_CLIENT_COMPARE(chl->client->id, sender))
905         break;
906     }
907     if (chl == SILC_LIST_END) {
908       SILC_LOG_DEBUG(("Client not on channel"));
909       goto out;
910     }
911   }
912
913   /* If we are router and the packet came from router and private key
914      has not been set for the channel then we must encrypt the packet
915      as it was decrypted with the session key shared between us and the
916      router which sent it. This is so, because cells does not share the
917      same channel key */
918   if (server->server_type == SILC_ROUTER &&
919       sock->type == SILC_SOCKET_TYPE_ROUTER &&
920       !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
921     SilcBuffer chp;
922     unsigned int iv_len, i, data_len;
923
924     iv_len = silc_cipher_get_block_len(channel->channel_key);
925     if (channel->iv[0] == '\0')
926       for (i = 0; i < iv_len; i++) channel->iv[i] = 
927                                      silc_rng_get_byte(server->rng);
928     else
929       silc_hash_make(server->md5hash, channel->iv, iv_len, channel->iv);
930     
931     /* Encode new payload. This encrypts it also. */
932     SILC_GET16_MSB(data_len, packet->buffer->data);
933     chp = silc_channel_message_payload_encode(data_len, 
934                                               packet->buffer->data + 2,
935                                               iv_len, channel->iv,
936                                               channel->channel_key,
937                                               channel->hmac, server->rng);
938     silc_buffer_put(packet->buffer, chp->data, chp->len);
939     silc_buffer_free(chp);
940   }
941
942   /* Distribute the packet to our local clients. This will send the
943      packet for further routing as well, if needed. */
944   silc_server_packet_relay_to_channel(server, sock, channel, sender,
945                                       packet->src_id_type,
946                                       packet->buffer->data,
947                                       packet->buffer->len, FALSE);
948
949  out:
950   if (sender)
951     silc_free(sender);
952   if (id)
953     silc_free(id);
954 }
955
956 /* Received channel key packet. We distribute the key to all of our locally
957    connected clients on the channel. */
958
959 void silc_server_channel_key(SilcServer server,
960                              SilcSocketConnection sock,
961                              SilcPacketContext *packet)
962 {
963   SilcBuffer buffer = packet->buffer;
964   SilcChannelEntry channel;
965
966   if (packet->src_id_type != SILC_ID_SERVER)
967     return;
968
969   /* Save the channel key */
970   channel = silc_server_save_channel_key(server, buffer, NULL);
971   if (!channel)
972     return;
973
974   /* Distribute the key to everybody who is on the channel. If we are router
975      we will also send it to locally connected servers. */
976   silc_server_send_channel_key(server, sock, channel, FALSE);
977 }
978
979 /* Received New Client packet and processes it.  Creates Client ID for the
980    client. Client becomes registered after calling this functions. */
981
982 SilcClientEntry silc_server_new_client(SilcServer server,
983                                        SilcSocketConnection sock,
984                                        SilcPacketContext *packet)
985 {
986   SilcBuffer buffer = packet->buffer;
987   SilcClientEntry client;
988   SilcIDCacheEntry cache;
989   SilcClientID *client_id;
990   SilcBuffer reply;
991   SilcIDListData idata;
992   char *username = NULL, *realname = NULL, *id_string;
993   int ret;
994
995   SILC_LOG_DEBUG(("Creating new client"));
996
997   if (sock->type != SILC_SOCKET_TYPE_CLIENT)
998     return NULL;
999
1000   /* Take client entry */
1001   client = (SilcClientEntry)sock->user_data;
1002   idata = (SilcIDListData)client;
1003
1004   /* Fetch the old client cache entry so that we can update it. */
1005   if (!silc_idcache_find_by_context(server->local_list->clients,
1006                                     sock->user_data, &cache)) {
1007     SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
1008     return NULL;
1009   }
1010
1011   /* Parse incoming packet */
1012   ret = silc_buffer_unformat(buffer,
1013                              SILC_STR_UI16_STRING_ALLOC(&username),
1014                              SILC_STR_UI16_STRING_ALLOC(&realname),
1015                              SILC_STR_END);
1016   if (ret == -1) {
1017     if (username)
1018       silc_free(username);
1019     if (realname)
1020       silc_free(realname);
1021     return NULL;
1022   }
1023
1024   if (!username) {
1025     silc_free(username);
1026     if (realname)
1027       silc_free(realname);
1028     silc_server_disconnect_remote(server, sock, "Server closed connection: "
1029                                   "Incomplete client information");
1030     return NULL;
1031   }
1032
1033   /* Create Client ID */
1034   silc_id_create_client_id(server->id, server->rng, server->md5hash,
1035                            username, &client_id);
1036
1037   if (strlen(username) > 128)
1038     username[127] = '\0';
1039
1040   /* Update client entry */
1041   idata->registered = TRUE;
1042   client->nickname = strdup(username);
1043   client->username = username;
1044   client->userinfo = realname ? realname : strdup(" ");
1045   client->id = client_id;
1046
1047   /* Update the cache entry */
1048   cache->id = (void *)client_id;
1049   cache->type = SILC_ID_CLIENT;
1050   cache->data = username;
1051   silc_idcache_sort_by_data(server->local_list->clients);
1052
1053   /* Notify our router about new client on the SILC network */
1054   if (!server->standalone)
1055     silc_server_send_new_id(server, (SilcSocketConnection) 
1056                             server->router->connection, 
1057                             server->server_type == SILC_ROUTER ? TRUE : FALSE,
1058                             client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
1059   
1060   /* Send the new client ID to the client. */
1061   id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
1062   reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
1063   silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
1064   silc_buffer_format(reply,
1065                      SILC_STR_UI_SHORT(SILC_ID_CLIENT),
1066                      SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
1067                      SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
1068                      SILC_STR_END);
1069   silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0, 
1070                           reply->data, reply->len, FALSE);
1071   silc_free(id_string);
1072   silc_buffer_free(reply);
1073
1074   /* Send some nice info to the client */
1075   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1076                           ("Welcome to the SILC Network %s@%s",
1077                            username, sock->hostname));
1078   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1079                           ("Your host is %s, running version %s",
1080                            server->config->server_info->server_name,
1081                            server_version));
1082   if (server->server_type == SILC_ROUTER) {
1083     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1084                             ("There are %d clients on %d servers in SILC "
1085                              "Network", server->stat.clients,
1086                              server->stat.servers + 1));
1087     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1088                             ("There are %d clients on %d server in our cell",
1089                              server->stat.cell_clients,
1090                              server->stat.cell_servers + 1));
1091     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1092                             ("I have %d clients, %d channels, %d servers and "
1093                              "%d routers",
1094                              server->stat.my_clients, 
1095                              server->stat.my_channels,
1096                              server->stat.my_servers,
1097                              server->stat.my_routers));
1098     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1099                             ("%d server operators and %d router operators "
1100                              "online",
1101                              server->stat.my_server_ops,
1102                              server->stat.my_router_ops));
1103   } else {
1104     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1105                             ("I have %d clients and %d channels formed",
1106                              server->stat.my_clients,
1107                              server->stat.my_channels));
1108     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1109                             ("%d operators online",
1110                              server->stat.my_server_ops));
1111   }
1112   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1113                           ("Your connection is secured with %s cipher, "
1114                            "key length %d bits",
1115                            idata->send_key->cipher->name,
1116                            idata->send_key->cipher->key_len));
1117   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1118                           ("Your current nickname is %s",
1119                            client->nickname));
1120
1121   /* Send motd */
1122   silc_server_send_motd(server, sock);
1123
1124   return client;
1125 }
1126
1127 /* Create new server. This processes received New Server packet and
1128    saves the received Server ID. The server is our locally connected
1129    server thus we save all the information and save it to local list. 
1130    This funtion can be used by both normal server and router server.
1131    If normal server uses this it means that its router has connected
1132    to the server. If router uses this it means that one of the cell's
1133    servers is connected to the router. */
1134
1135 SilcServerEntry silc_server_new_server(SilcServer server,
1136                                        SilcSocketConnection sock,
1137                                        SilcPacketContext *packet)
1138 {
1139   SilcBuffer buffer = packet->buffer;
1140   SilcServerEntry new_server;
1141   SilcIDCacheEntry cache;
1142   SilcServerID *server_id;
1143   SilcIDListData idata;
1144   unsigned char *server_name, *id_string;
1145   unsigned short id_len;
1146   int ret;
1147
1148   SILC_LOG_DEBUG(("Creating new server"));
1149
1150   if (sock->type != SILC_SOCKET_TYPE_SERVER &&
1151       sock->type != SILC_SOCKET_TYPE_ROUTER)
1152     return NULL;
1153
1154   /* Take server entry */
1155   new_server = (SilcServerEntry)sock->user_data;
1156   idata = (SilcIDListData)new_server;
1157
1158   /* Fetch the old server cache entry so that we can update it. */
1159   if (!silc_idcache_find_by_context(server->local_list->servers,
1160                                     sock->user_data, &cache)) {
1161     SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
1162     return NULL;
1163   }
1164
1165   /* Parse the incoming packet */
1166   ret = silc_buffer_unformat(buffer,
1167                              SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
1168                              SILC_STR_UI16_STRING_ALLOC(&server_name),
1169                              SILC_STR_END);
1170   if (ret == -1) {
1171     if (id_string)
1172       silc_free(id_string);
1173     if (server_name)
1174       silc_free(server_name);
1175     return NULL;
1176   }
1177
1178   if (id_len > buffer->len) {
1179     silc_free(id_string);
1180     silc_free(server_name);
1181     return NULL;
1182   }
1183
1184   /* Get Server ID */
1185   server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
1186   if (!server_id) {
1187     silc_free(id_string);
1188     silc_free(server_name);
1189     return NULL;
1190   }
1191   silc_free(id_string);
1192
1193   /* Update client entry */
1194   idata->registered = TRUE;
1195   new_server->server_name = server_name;
1196   new_server->id = server_id;
1197
1198   /* Update the cache entry */
1199   cache->id = (void *)server_id;
1200   cache->type = SILC_ID_SERVER;
1201   cache->data = server_name;
1202   silc_idcache_sort_by_data(server->local_list->servers);
1203
1204   /* Distribute the information about new server in the SILC network
1205      to our router. If we are normal server we won't send anything
1206      since this connection must be our router connection. */
1207   if (server->server_type == SILC_ROUTER && !server->standalone &&
1208       server->router->connection != sock)
1209     silc_server_send_new_id(server, server->router->connection,
1210                             TRUE, new_server->id, SILC_ID_SERVER, 
1211                             SILC_ID_SERVER_LEN);
1212
1213   if (server->server_type == SILC_ROUTER)
1214     server->stat.cell_servers++;
1215
1216   return new_server;
1217 }
1218
1219 /* Processes incoming New ID packet. New ID Payload is used to distribute
1220    information about newly registered clients and servers. */
1221
1222 static void silc_server_new_id_real(SilcServer server, 
1223                                     SilcSocketConnection sock,
1224                                     SilcPacketContext *packet,
1225                                     int broadcast)
1226 {
1227   SilcBuffer buffer = packet->buffer;
1228   SilcIDList id_list;
1229   SilcServerEntry router;
1230   SilcSocketConnection router_sock;
1231   SilcIDPayload idp;
1232   SilcIdType id_type;
1233   unsigned char *hash = NULL;
1234   void *id;
1235
1236   SILC_LOG_DEBUG(("Processing new ID"));
1237
1238   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1239       server->server_type == SILC_SERVER ||
1240       packet->src_id_type != SILC_ID_SERVER)
1241     return;
1242
1243   idp = silc_id_payload_parse(buffer);
1244   if (!idp)
1245     return;
1246
1247   id_type = silc_id_payload_get_type(idp);
1248
1249   /* Normal server cannot have other normal server connections */
1250   if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
1251     goto out;
1252
1253   id = silc_id_payload_get_id(idp);
1254   if (!id)
1255     goto out;
1256
1257   /* If the sender of this packet is server and we are router we need to
1258      broadcast this packet to other routers in the network. */
1259   if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
1260       sock->type == SILC_SOCKET_TYPE_SERVER &&
1261       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1262     SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
1263     silc_server_packet_send(server, server->router->connection,
1264                             packet->type, 
1265                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1266                             buffer->data, buffer->len, FALSE);
1267   }
1268
1269   if (sock->type == SILC_SOCKET_TYPE_SERVER)
1270     id_list = server->local_list;
1271   else
1272     id_list = server->global_list;
1273
1274   router_sock = sock;
1275   router = sock->user_data;
1276
1277   switch(id_type) {
1278   case SILC_ID_CLIENT:
1279     {
1280       SilcClientEntry entry;
1281
1282       SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
1283                       silc_id_render(id, SILC_ID_CLIENT),
1284                       sock->type == SILC_SOCKET_TYPE_SERVER ?
1285                       "Server" : "Router", sock->hostname));
1286     
1287       /* As a router we keep information of all global information in our
1288          global list. Cell wide information however is kept in the local
1289          list. The client is put to global list and we will take the hash
1290          value of the Client ID and save it to the ID Cache system for fast
1291          searching in the future. */
1292       hash = silc_calloc(sizeof(((SilcClientID *)id)->hash), 
1293                          sizeof(unsigned char));
1294       memcpy(hash, ((SilcClientID *)id)->hash, 
1295              sizeof(((SilcClientID *)id)->hash));
1296       entry = silc_idlist_add_client(id_list, hash, NULL, NULL, id, 
1297                                      router, NULL);
1298       entry->nickname = NULL;
1299
1300       if (sock->type == SILC_SOCKET_TYPE_SERVER)
1301         server->stat.cell_clients++;
1302       server->stat.clients++;
1303
1304 #if 0
1305       /* XXX Adding two ID's with same IP number replaces the old entry thus
1306          gives wrong route. Thus, now disabled until figured out a better way
1307          to do this or when removed the whole thing. This could be removed
1308          because entry->router->connection gives always the most optimal route
1309          for the ID anyway (unless new routes (faster perhaps) are established
1310          after receiving this ID, this we don't know however). */
1311       /* Add route cache for this ID */
1312       silc_server_route_add(silc_server_route_hash(
1313                             ((SilcClientID *)id)->ip.s_addr,
1314                             server->id->port), ((SilcClientID *)id)->ip.s_addr,
1315                             router);
1316 #endif
1317     }
1318     break;
1319
1320   case SILC_ID_SERVER:
1321     SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
1322                     silc_id_render(id, SILC_ID_SERVER),
1323                     sock->type == SILC_SOCKET_TYPE_SERVER ?
1324                     "Server" : "Router", sock->hostname));
1325     
1326     /* As a router we keep information of all global information in our global
1327        list. Cell wide information however is kept in the local list. */
1328     silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
1329
1330     if (sock->type == SILC_SOCKET_TYPE_SERVER)
1331       server->stat.cell_servers++;
1332     server->stat.servers++;
1333
1334 #if 0
1335     /* Add route cache for this ID */
1336     silc_server_route_add(silc_server_route_hash(
1337                           ((SilcServerID *)id)->ip.s_addr,
1338                           ((SilcServerID *)id)->port), 
1339                           ((SilcServerID *)id)->ip.s_addr,
1340                           router);
1341 #endif
1342     break;
1343
1344   case SILC_ID_CHANNEL:
1345     SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
1346     break;
1347
1348   default:
1349     break;
1350   }
1351
1352  out:
1353   silc_id_payload_free(idp);
1354 }
1355
1356
1357 /* Processes incoming New ID packet. New ID Payload is used to distribute
1358    information about newly registered clients and servers. */
1359
1360 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
1361                         SilcPacketContext *packet)
1362 {
1363   silc_server_new_id_real(server, sock, packet, TRUE);
1364 }
1365
1366 /* Receoved New Id List packet, list of New ID payloads inside one
1367    packet. Process the New ID payloads one by one. */
1368
1369 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
1370                              SilcPacketContext *packet)
1371 {
1372   SilcPacketContext *new_id;
1373   SilcBuffer idp;
1374   unsigned short id_len;
1375
1376   SILC_LOG_DEBUG(("Processing New ID List"));
1377
1378   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1379       packet->src_id_type != SILC_ID_SERVER)
1380     return;
1381
1382   /* If the sender of this packet is server and we are router we need to
1383      broadcast this packet to other routers in the network. Broadcast
1384      this list packet instead of multiple New ID packets. */
1385   if (!server->standalone && server->server_type == SILC_ROUTER &&
1386       sock->type == SILC_SOCKET_TYPE_SERVER &&
1387       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1388     SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
1389     silc_server_packet_send(server, server->router->connection,
1390                             packet->type, 
1391                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1392                             packet->buffer->data, packet->buffer->len, FALSE);
1393   }
1394
1395   /* Make copy of the original packet context, except for the actual
1396      data buffer, which we will here now fetch from the original buffer. */
1397   new_id = silc_packet_context_alloc();
1398   new_id->type = SILC_PACKET_NEW_ID;
1399   new_id->flags = packet->flags;
1400   new_id->src_id = packet->src_id;
1401   new_id->src_id_len = packet->src_id_len;
1402   new_id->src_id_type = packet->src_id_type;
1403   new_id->dst_id = packet->dst_id;
1404   new_id->dst_id_len = packet->dst_id_len;
1405   new_id->dst_id_type = packet->dst_id_type;
1406
1407   idp = silc_buffer_alloc(256);
1408   new_id->buffer = idp;
1409
1410   while (packet->buffer->len) {
1411     SILC_GET16_MSB(id_len, packet->buffer->data + 2);
1412     if ((id_len > packet->buffer->len) ||
1413         (id_len > idp->truelen))
1414       break;
1415
1416     silc_buffer_pull_tail(idp, 4 + id_len);
1417     silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
1418
1419     /* Process the New ID */
1420     silc_server_new_id_real(server, sock, new_id, FALSE);
1421
1422     silc_buffer_push_tail(idp, 4 + id_len);
1423     silc_buffer_pull(packet->buffer, 4 + id_len);
1424   }
1425
1426   silc_buffer_free(idp);
1427   silc_free(new_id);
1428 }
1429
1430 /* Received New Channel packet. Information about new channels in the 
1431    network are distributed using this packet. Save the information about
1432    the new channel. This usually comes from router but also normal server
1433    can send this to notify channels it has when it connects to us. */
1434
1435 void silc_server_new_channel(SilcServer server,
1436                              SilcSocketConnection sock,
1437                              SilcPacketContext *packet)
1438 {
1439   SilcChannelPayload payload;
1440   SilcChannelID *channel_id;
1441   char *channel_name;
1442   unsigned int name_len;
1443   unsigned char *id;
1444   unsigned int id_len;
1445
1446   SILC_LOG_DEBUG(("Processing New Channel"));
1447
1448   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1449       packet->src_id_type != SILC_ID_SERVER ||
1450       server->server_type == SILC_SERVER)
1451     return;
1452
1453   /* Parse the channel payload */
1454   payload = silc_channel_payload_parse(packet->buffer);
1455   if (!payload)
1456     return;
1457     
1458   /* Get the channel ID */
1459   channel_id = silc_channel_get_id_parse(payload);
1460   if (!channel_id) {
1461     silc_channel_payload_free(payload);
1462     return;
1463   }
1464
1465   channel_name = silc_channel_get_name(payload, &name_len);
1466   if (name_len > 256)
1467     channel_name[255] = '\0';
1468
1469   id = silc_channel_get_id(payload, &id_len);
1470
1471   if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
1472     /* Add the server to global list as it is coming from router. It 
1473        cannot be our own channel as it is coming from router. */
1474
1475     SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
1476                     silc_id_render(channel_id, SILC_ID_CHANNEL), 
1477                     sock->hostname));
1478     
1479     silc_idlist_add_channel(server->global_list, strdup(channel_name), 
1480                             0, channel_id, server->router->connection, 
1481                             NULL, NULL);
1482
1483     server->stat.channels++;
1484   } else {
1485     /* The channel is coming from our server, thus it is in our cell
1486        we will add it to our local list. */
1487     SilcChannelEntry channel;
1488     SilcBuffer chk;
1489
1490     SILC_LOG_DEBUG(("New channel id(%s) from [Server] %s",
1491                     silc_id_render(channel_id, SILC_ID_CHANNEL), 
1492                     sock->hostname));
1493     
1494     /* Check that we don't already have this channel */
1495     channel = silc_idlist_find_channel_by_name(server->local_list, 
1496                                                channel_name, NULL);
1497     if (!channel)
1498       channel = silc_idlist_find_channel_by_name(server->global_list, 
1499                                                  channel_name, NULL);
1500
1501     /* If the channel does not exist, then create it. We create the channel
1502        with the channel ID provided by the server. This creates a new
1503        key to the channel as well that we will send to the server. */
1504     if (!channel) {
1505       channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
1506                                                        channel_name,
1507                                                        channel_id, FALSE);
1508       if (!channel) {
1509         silc_channel_payload_free(payload);
1510         silc_free(channel_id);
1511         return;
1512       }
1513
1514       /* Send the new channel key to the server */
1515       chk = silc_channel_key_payload_encode(id_len, id,
1516                                             strlen(channel->channel_key->
1517                                                    cipher->name),
1518                                             channel->channel_key->cipher->name,
1519                                             channel->key_len / 8, 
1520                                             channel->key);
1521       silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
1522                               chk->data, chk->len, FALSE);
1523       silc_buffer_free(chk);
1524
1525     } else {
1526       /* The channel exist by that name, check whether the ID's match.
1527          If they don't then we'll force the server to use the ID we have.
1528          We also create a new key for the channel. */
1529
1530       if (SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
1531         /* They don't match, send CHANNEL_CHANGE notify to the server to
1532            force the ID change. */
1533         SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
1534         silc_server_send_notify_channel_change(server, sock, FALSE, 
1535                                                channel_id,
1536                                                channel->id, 
1537                                                SILC_ID_CHANNEL_LEN);
1538       }
1539
1540       /* Create new key for the channel and send it to the server and
1541          everybody else possibly on the channel. */
1542
1543       silc_server_create_channel_key(server, channel, 0);
1544
1545       /* Send to the channel */
1546       silc_server_send_channel_key(server, sock, channel, FALSE);
1547
1548       /* Send to the server */
1549       chk = silc_channel_key_payload_encode(id_len, id,
1550                                             strlen(channel->channel_key->
1551                                                    cipher->name),
1552                                             channel->channel_key->cipher->name,
1553                                             channel->key_len / 8, 
1554                                             channel->key);
1555       silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
1556                               chk->data, chk->len, FALSE);
1557       silc_buffer_free(chk);
1558       silc_free(channel_id);
1559
1560       /* Since the channel is coming from server and we also know about it
1561          then send the JOIN notify to the server so that it see's our
1562          users on the channel "joining" the channel. */
1563       /* XXX TODO **/
1564     }
1565   }
1566 }
1567
1568 /* Received New Channel List packet, list of New Channel List payloads inside
1569    one packet. Process the New Channel payloads one by one. */
1570
1571 void silc_server_new_channel_list(SilcServer server,
1572                                   SilcSocketConnection sock,
1573                                   SilcPacketContext *packet)
1574 {
1575   SilcPacketContext *new;
1576   SilcBuffer buffer;
1577   unsigned short len1, len2;
1578
1579   SILC_LOG_DEBUG(("Processing New Channel List"));
1580
1581   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1582       packet->src_id_type != SILC_ID_SERVER ||
1583       server->server_type == SILC_SERVER)
1584     return;
1585
1586   /* If the sender of this packet is server and we are router we need to
1587      broadcast this packet to other routers in the network. Broadcast
1588      this list packet instead of multiple New Channel packets. */
1589   if (!server->standalone && server->server_type == SILC_ROUTER &&
1590       sock->type == SILC_SOCKET_TYPE_SERVER &&
1591       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1592     SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
1593     silc_server_packet_send(server, server->router->connection,
1594                             packet->type, 
1595                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1596                             packet->buffer->data, packet->buffer->len, FALSE);
1597   }
1598
1599   /* Make copy of the original packet context, except for the actual
1600      data buffer, which we will here now fetch from the original buffer. */
1601   new = silc_packet_context_alloc();
1602   new->type = SILC_PACKET_NEW_CHANNEL;
1603   new->flags = packet->flags;
1604   new->src_id = packet->src_id;
1605   new->src_id_len = packet->src_id_len;
1606   new->src_id_type = packet->src_id_type;
1607   new->dst_id = packet->dst_id;
1608   new->dst_id_len = packet->dst_id_len;
1609   new->dst_id_type = packet->dst_id_type;
1610
1611   buffer = silc_buffer_alloc(512);
1612   new->buffer = buffer;
1613
1614   while (packet->buffer->len) {
1615     SILC_GET16_MSB(len1, packet->buffer->data);
1616     if ((len1 > packet->buffer->len) ||
1617         (len1 > buffer->truelen))
1618       break;
1619
1620     SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
1621     if ((len2 > packet->buffer->len) ||
1622         (len2 > buffer->truelen))
1623       break;
1624
1625     silc_buffer_pull_tail(buffer, 8 + len1 + len2);
1626     silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
1627
1628     /* Process the New Channel */
1629     silc_server_new_channel(server, sock, new);
1630
1631     silc_buffer_push_tail(buffer, 8 + len1 + len2);
1632     silc_buffer_pull(packet->buffer, 8 + len1 + len2);
1633   }
1634
1635   silc_buffer_free(buffer);
1636   silc_free(new);
1637 }
1638
1639 /* Received key agreement packet. This packet is never for us. It is to
1640    the client in the packet's destination ID. Sending of this sort of packet
1641    equals sending private message, ie. it is sent point to point from
1642    one client to another. */
1643
1644 void silc_server_key_agreement(SilcServer server,
1645                                SilcSocketConnection sock,
1646                                SilcPacketContext *packet)
1647 {
1648   SilcSocketConnection dst_sock;
1649   SilcIDListData idata;
1650
1651   SILC_LOG_DEBUG(("Start"));
1652
1653   if (packet->src_id_type != SILC_ID_CLIENT ||
1654       packet->dst_id_type != SILC_ID_CLIENT)
1655     return;
1656
1657   if (!packet->dst_id)
1658     return;
1659
1660   /* Get the route to the client */
1661   dst_sock = silc_server_get_client_route(server, packet->dst_id,
1662                                           packet->dst_id_len, &idata);
1663   if (!dst_sock)
1664     return;
1665
1666   /* Relay the packet */
1667   silc_server_relay_packet(server, dst_sock, idata->send_key,
1668                            idata->hmac, packet, FALSE);
1669 }