Added KILL command.
[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->local_list, 
112                                              channel_id, NULL);
113     if (!channel) {
114       channel = silc_idlist_find_channel_by_id(server->global_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->local_list, 
140                                            client_id, NULL);
141     if (!client) {
142       client = silc_idlist_find_client_by_id(server->global_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->local_list, 
193                                              channel_id, NULL);
194     if (!channel) { 
195       channel = silc_idlist_find_channel_by_id(server->global_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->local_list, 
292                                              channel_id, NULL);
293     if (!channel) {
294       channel = silc_idlist_find_channel_by_id(server->global_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->local_list, 
393                                              channel_id, NULL);
394     if (!channel) {
395       channel = silc_idlist_find_channel_by_id(server->global_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->local_list, 
436                                              channel_id, NULL);
437     if (!channel) {
438       channel = silc_idlist_find_channel_by_id(server->global_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->local_list, 
518                                              channel_id, NULL);
519     if (!channel) {
520       channel = silc_idlist_find_channel_by_id(server->global_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->local_list, 
544                                            client_id, NULL);
545     if (!client) {
546       client = silc_idlist_find_client_by_id(server->global_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->local_list, 
579                                              client_id, NULL);
580       if (!client) {
581         client = silc_idlist_find_client_by_id(server->global_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     /* Ignore rest of the notify types for now */
621   case SILC_NOTIFY_TYPE_NONE:
622   case SILC_NOTIFY_TYPE_MOTD:
623     break;
624   default:
625     break;
626   }
627
628  out:
629   silc_notify_payload_free(payload);
630 }
631
632 void silc_server_notify_list(SilcServer server,
633                              SilcSocketConnection sock,
634                              SilcPacketContext *packet)
635 {
636   SilcPacketContext *new;
637   SilcBuffer buffer;
638   unsigned short len;
639
640   SILC_LOG_DEBUG(("Processing New Notify List"));
641
642   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
643       packet->src_id_type != SILC_ID_SERVER)
644     return;
645
646   /* Make copy of the original packet context, except for the actual
647      data buffer, which we will here now fetch from the original buffer. */
648   new = silc_packet_context_alloc();
649   new->type = SILC_PACKET_NOTIFY;
650   new->flags = packet->flags;
651   new->src_id = packet->src_id;
652   new->src_id_len = packet->src_id_len;
653   new->src_id_type = packet->src_id_type;
654   new->dst_id = packet->dst_id;
655   new->dst_id_len = packet->dst_id_len;
656   new->dst_id_type = packet->dst_id_type;
657
658   buffer = silc_buffer_alloc(1024);
659   new->buffer = buffer;
660
661   while (packet->buffer->len) {
662     SILC_GET16_MSB(len, packet->buffer->data + 2);
663     if (len > packet->buffer->len)
664       break;
665
666     if (len > buffer->truelen) {
667       silc_buffer_free(buffer);
668       buffer = silc_buffer_alloc(1024 + len);
669     }
670
671     silc_buffer_pull_tail(buffer, len);
672     silc_buffer_put(buffer, packet->buffer->data, len);
673
674     /* Process the Notify */
675     silc_server_notify(server, sock, new);
676
677     silc_buffer_push_tail(buffer, len);
678     silc_buffer_pull(packet->buffer, len);
679   }
680
681   silc_buffer_free(buffer);
682   silc_free(new);
683 }
684
685 /* Received private message. This resolves the destination of the message 
686    and sends the packet. This is used by both server and router.  If the
687    destination is our locally connected client this sends the packet to
688    the client. This may also send the message for further routing if
689    the destination is not in our server (or router). */
690
691 void silc_server_private_message(SilcServer server,
692                                  SilcSocketConnection sock,
693                                  SilcPacketContext *packet)
694 {
695   SilcSocketConnection dst_sock;
696   SilcIDListData idata;
697
698   SILC_LOG_DEBUG(("Start"));
699
700   if (packet->src_id_type != SILC_ID_CLIENT ||
701       packet->dst_id_type != SILC_ID_CLIENT)
702     return;
703
704   if (!packet->dst_id)
705     return;
706
707   /* Get the route to the client */
708   dst_sock = silc_server_get_client_route(server, packet->dst_id,
709                                           packet->dst_id_len, &idata);
710   if (!dst_sock)
711     return;
712
713   /* Send the private message */
714   silc_server_send_private_message(server, dst_sock, idata->send_key,
715                                    idata->hmac, packet);
716 }
717
718 /* Received private message key packet.. This packet is never for us. It is to
719    the client in the packet's destination ID. Sending of this sort of packet
720    equals sending private message, ie. it is sent point to point from
721    one client to another. */
722
723 void silc_server_private_message_key(SilcServer server,
724                                      SilcSocketConnection sock,
725                                      SilcPacketContext *packet)
726 {
727   SilcSocketConnection dst_sock;
728   SilcIDListData idata;
729
730   SILC_LOG_DEBUG(("Start"));
731
732   if (packet->src_id_type != SILC_ID_CLIENT ||
733       packet->dst_id_type != SILC_ID_CLIENT)
734     return;
735
736   if (!packet->dst_id)
737     return;
738
739   /* Get the route to the client */
740   dst_sock = silc_server_get_client_route(server, packet->dst_id,
741                                           packet->dst_id_len, &idata);
742   if (!dst_sock)
743     return;
744
745   /* Relay the packet */
746   silc_server_relay_packet(server, dst_sock, idata->send_key,
747                            idata->hmac, packet, FALSE);
748 }
749
750 /* Processes incoming command reply packet. The command reply packet may
751    be destined to one of our clients or it may directly for us. We will 
752    call the command reply routine after processing the packet. */
753
754 void silc_server_command_reply(SilcServer server,
755                                SilcSocketConnection sock,
756                                SilcPacketContext *packet)
757 {
758   SilcBuffer buffer = packet->buffer;
759   SilcClientEntry client = NULL;
760   SilcSocketConnection dst_sock;
761   SilcIDListData idata;
762   SilcClientID *id = NULL;
763
764   SILC_LOG_DEBUG(("Start"));
765
766   /* Source must be server or router */
767   if (packet->src_id_type != SILC_ID_SERVER &&
768       sock->type != SILC_SOCKET_TYPE_ROUTER)
769     return;
770
771   if (packet->dst_id_type == SILC_ID_CHANNEL)
772     return;
773
774   if (packet->dst_id_type == SILC_ID_CLIENT) {
775     /* Destination must be one of ours */
776     id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
777     if (!id)
778       return;
779     client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
780     if (!client) {
781       SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
782       silc_free(id);
783       return;
784     }
785   }
786
787   if (packet->dst_id_type == SILC_ID_SERVER) {
788     /* For now this must be for us */
789     if (SILC_ID_SERVER_COMPARE(packet->dst_id, server->id_string)) {
790       SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
791       return;
792     }
793   }
794
795   /* Execute command reply locally for the command */
796   silc_server_command_reply_process(server, sock, buffer);
797
798   if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
799     /* Relay the packet to the client */
800     
801     dst_sock = (SilcSocketConnection)client->connection;
802     silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len 
803                      + packet->dst_id_len + packet->padlen);
804     
805     silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
806     silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
807     
808     idata = (SilcIDListData)client;
809     
810     /* Encrypt packet */
811     silc_packet_encrypt(idata->send_key, idata->hmac, dst_sock->outbuf, 
812                         buffer->len);
813     
814     /* Send the packet */
815     silc_server_packet_send_real(server, dst_sock, TRUE);
816
817     silc_free(id);
818   }
819 }
820
821 /* Process received channel message. The message can be originated from
822    client or server. */
823
824 void silc_server_channel_message(SilcServer server,
825                                  SilcSocketConnection sock,
826                                  SilcPacketContext *packet)
827 {
828   SilcChannelEntry channel = NULL;
829   SilcChannelClientEntry chl;
830   SilcChannelID *id = NULL;
831   void *sender = NULL;
832
833   SILC_LOG_DEBUG(("Processing channel message"));
834
835   /* Sanity checks */
836   if (packet->dst_id_type != SILC_ID_CHANNEL) {
837     SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
838     goto out;
839   }
840
841   /* Find channel entry */
842   id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
843   if (!id)
844     goto out;
845   channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
846   if (!channel) {
847     channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
848     if (!channel) {
849       SILC_LOG_DEBUG(("Could not find channel"));
850       goto out;
851     }
852   }
853
854   /* See that this client is on the channel. If the message is coming
855      from router we won't do the check as the message is from client that
856      we don't know about. Also, if the original sender is not client
857      (as it can be server as well) we don't do the check. */
858   sender = silc_id_str2id(packet->src_id, packet->src_id_len, 
859                           packet->src_id_type);
860   if (!sender)
861     goto out;
862   if (sock->type != SILC_SOCKET_TYPE_ROUTER && 
863       packet->src_id_type == SILC_ID_CLIENT) {
864     silc_list_start(channel->user_list);
865     while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
866       if (chl->client && !SILC_ID_CLIENT_COMPARE(chl->client->id, sender))
867         break;
868     }
869     if (chl == SILC_LIST_END) {
870       SILC_LOG_DEBUG(("Client not on channel"));
871       goto out;
872     }
873   }
874
875   /* If we are router and the packet came from router and private key
876      has not been set for the channel then we must encrypt the packet
877      as it was decrypted with the session key shared between us and the
878      router which sent it. This is so, because cells does not share the
879      same channel key */
880   if (server->server_type == SILC_ROUTER &&
881       sock->type == SILC_SOCKET_TYPE_ROUTER &&
882       !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
883     SilcBuffer chp;
884     unsigned int iv_len, i, data_len;
885
886     iv_len = silc_cipher_get_block_len(channel->channel_key);
887     if (channel->iv[0] == '\0')
888       for (i = 0; i < iv_len; i++) channel->iv[i] = 
889                                      silc_rng_get_byte(server->rng);
890     else
891       silc_hash_make(server->md5hash, channel->iv, iv_len, channel->iv);
892     
893     /* Encode new payload. This encrypts it also. */
894     SILC_GET16_MSB(data_len, packet->buffer->data);
895     chp = silc_channel_payload_encode(data_len, packet->buffer->data + 2,
896                                       iv_len, channel->iv,
897                                       channel->channel_key,
898                                       channel->hmac, server->rng);
899     silc_buffer_put(packet->buffer, chp->data, chp->len);
900     silc_buffer_free(chp);
901   }
902
903   /* Distribute the packet to our local clients. This will send the
904      packet for further routing as well, if needed. */
905   silc_server_packet_relay_to_channel(server, sock, channel, sender,
906                                       packet->src_id_type,
907                                       packet->buffer->data,
908                                       packet->buffer->len, FALSE);
909
910  out:
911   if (sender)
912     silc_free(sender);
913   if (id)
914     silc_free(id);
915 }
916
917 /* Received channel key packet. We distribute the key to all of our locally
918    connected clients on the channel. */
919
920 void silc_server_channel_key(SilcServer server,
921                              SilcSocketConnection sock,
922                              SilcPacketContext *packet)
923 {
924   SilcBuffer buffer = packet->buffer;
925   SilcChannelEntry channel;
926
927   if (packet->src_id_type != SILC_ID_SERVER)
928     return;
929
930   /* Save the channel key */
931   channel = silc_server_save_channel_key(server, buffer, NULL);
932   if (!channel)
933     return;
934
935   /* Distribute the key to everybody who is on the channel. If we are router
936      we will also send it to locally connected servers. */
937   silc_server_send_channel_key(server, sock, channel, FALSE);
938 }
939
940 /* Received New Client packet and processes it.  Creates Client ID for the
941    client. Client becomes registered after calling this functions. */
942
943 SilcClientEntry silc_server_new_client(SilcServer server,
944                                        SilcSocketConnection sock,
945                                        SilcPacketContext *packet)
946 {
947   SilcBuffer buffer = packet->buffer;
948   SilcClientEntry client;
949   SilcIDCacheEntry cache;
950   SilcClientID *client_id;
951   SilcBuffer reply;
952   SilcIDListData idata;
953   char *username = NULL, *realname = NULL, *id_string;
954   int ret;
955
956   SILC_LOG_DEBUG(("Creating new client"));
957
958   if (sock->type != SILC_SOCKET_TYPE_CLIENT)
959     return NULL;
960
961   /* Take client entry */
962   client = (SilcClientEntry)sock->user_data;
963   idata = (SilcIDListData)client;
964
965   /* Fetch the old client cache entry so that we can update it. */
966   if (!silc_idcache_find_by_context(server->local_list->clients,
967                                     sock->user_data, &cache)) {
968     SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
969     return NULL;
970   }
971
972   /* Parse incoming packet */
973   ret = silc_buffer_unformat(buffer,
974                              SILC_STR_UI16_STRING_ALLOC(&username),
975                              SILC_STR_UI16_STRING_ALLOC(&realname),
976                              SILC_STR_END);
977   if (ret == -1) {
978     if (username)
979       silc_free(username);
980     if (realname)
981       silc_free(realname);
982     return NULL;
983   }
984
985   if (!username) {
986     silc_free(username);
987     if (realname)
988       silc_free(realname);
989     silc_server_disconnect_remote(server, sock, "Server closed connection: "
990                                   "Incomplete client information");
991     return NULL;
992   }
993
994   /* Create Client ID */
995   silc_id_create_client_id(server->id, server->rng, server->md5hash,
996                            username, &client_id);
997
998   if (strlen(username) > 128)
999     username[127] = '\0';
1000
1001   /* Update client entry */
1002   idata->registered = TRUE;
1003   client->nickname = strdup(username);
1004   client->username = username;
1005   client->userinfo = realname ? realname : strdup(" ");
1006   client->id = client_id;
1007
1008   /* Update the cache entry */
1009   cache->id = (void *)client_id;
1010   cache->type = SILC_ID_CLIENT;
1011   cache->data = username;
1012   silc_idcache_sort_by_data(server->local_list->clients);
1013
1014   /* Notify our router about new client on the SILC network */
1015   if (!server->standalone)
1016     silc_server_send_new_id(server, (SilcSocketConnection) 
1017                             server->router->connection, 
1018                             server->server_type == SILC_ROUTER ? TRUE : FALSE,
1019                             client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
1020   
1021   /* Send the new client ID to the client. */
1022   id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
1023   reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
1024   silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
1025   silc_buffer_format(reply,
1026                      SILC_STR_UI_SHORT(SILC_ID_CLIENT),
1027                      SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
1028                      SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
1029                      SILC_STR_END);
1030   silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0, 
1031                           reply->data, reply->len, FALSE);
1032   silc_free(id_string);
1033   silc_buffer_free(reply);
1034
1035   /* Send some nice info to the client */
1036   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1037                           ("Welcome to the SILC Network %s@%s",
1038                            username, sock->hostname));
1039   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1040                           ("Your host is %s, running version %s",
1041                            server->config->server_info->server_name,
1042                            server_version));
1043   if (server->server_type == SILC_ROUTER) {
1044     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1045                             ("There are %d clients on %d servers in SILC "
1046                              "Network", server->stat.clients,
1047                              server->stat.servers + 1));
1048     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1049                             ("There are %d clients on %d server in our cell",
1050                              server->stat.cell_clients,
1051                              server->stat.cell_servers + 1));
1052     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1053                             ("I have %d clients, %d channels, %d servers and "
1054                              "%d routers",
1055                              server->stat.my_clients, 
1056                              server->stat.my_channels,
1057                              server->stat.my_servers,
1058                              server->stat.my_routers));
1059     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1060                             ("%d server operators and %d router operators "
1061                              "online",
1062                              server->stat.my_server_ops,
1063                              server->stat.my_router_ops));
1064   } else {
1065     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1066                             ("I have %d clients and %d channels formed",
1067                              server->stat.my_clients,
1068                              server->stat.my_channels));
1069     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1070                             ("%d operators online",
1071                              server->stat.my_server_ops));
1072   }
1073   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1074                           ("Your connection is secured with %s cipher, "
1075                            "key length %d bits",
1076                            idata->send_key->cipher->name,
1077                            idata->send_key->cipher->key_len));
1078   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1079                           ("Your current nickname is %s",
1080                            client->nickname));
1081
1082   /* Send motd */
1083   silc_server_send_motd(server, sock);
1084
1085   return client;
1086 }
1087
1088 /* Create new server. This processes received New Server packet and
1089    saves the received Server ID. The server is our locally connected
1090    server thus we save all the information and save it to local list. 
1091    This funtion can be used by both normal server and router server.
1092    If normal server uses this it means that its router has connected
1093    to the server. If router uses this it means that one of the cell's
1094    servers is connected to the router. */
1095
1096 SilcServerEntry silc_server_new_server(SilcServer server,
1097                                        SilcSocketConnection sock,
1098                                        SilcPacketContext *packet)
1099 {
1100   SilcBuffer buffer = packet->buffer;
1101   SilcServerEntry new_server;
1102   SilcIDCacheEntry cache;
1103   SilcServerID *server_id;
1104   SilcIDListData idata;
1105   unsigned char *server_name, *id_string;
1106   unsigned short id_len;
1107   int ret;
1108
1109   SILC_LOG_DEBUG(("Creating new server"));
1110
1111   if (sock->type != SILC_SOCKET_TYPE_SERVER &&
1112       sock->type != SILC_SOCKET_TYPE_ROUTER)
1113     return NULL;
1114
1115   /* Take server entry */
1116   new_server = (SilcServerEntry)sock->user_data;
1117   idata = (SilcIDListData)new_server;
1118
1119   /* Fetch the old server cache entry so that we can update it. */
1120   if (!silc_idcache_find_by_context(server->local_list->servers,
1121                                     sock->user_data, &cache)) {
1122     SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
1123     return NULL;
1124   }
1125
1126   /* Parse the incoming packet */
1127   ret = silc_buffer_unformat(buffer,
1128                              SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
1129                              SILC_STR_UI16_STRING_ALLOC(&server_name),
1130                              SILC_STR_END);
1131   if (ret == -1) {
1132     if (id_string)
1133       silc_free(id_string);
1134     if (server_name)
1135       silc_free(server_name);
1136     return NULL;
1137   }
1138
1139   if (id_len > buffer->len) {
1140     silc_free(id_string);
1141     silc_free(server_name);
1142     return NULL;
1143   }
1144
1145   /* Get Server ID */
1146   server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
1147   if (!server_id) {
1148     silc_free(id_string);
1149     silc_free(server_name);
1150     return NULL;
1151   }
1152   silc_free(id_string);
1153
1154   /* Update client entry */
1155   idata->registered = TRUE;
1156   new_server->server_name = server_name;
1157   new_server->id = server_id;
1158
1159   /* Update the cache entry */
1160   cache->id = (void *)server_id;
1161   cache->type = SILC_ID_SERVER;
1162   cache->data = server_name;
1163   silc_idcache_sort_by_data(server->local_list->servers);
1164
1165   /* Distribute the information about new server in the SILC network
1166      to our router. If we are normal server we won't send anything
1167      since this connection must be our router connection. */
1168   if (server->server_type == SILC_ROUTER && !server->standalone &&
1169       server->router->connection != sock)
1170     silc_server_send_new_id(server, server->router->connection,
1171                             TRUE, new_server->id, SILC_ID_SERVER, 
1172                             SILC_ID_SERVER_LEN);
1173
1174   if (server->server_type == SILC_ROUTER)
1175     server->stat.cell_servers++;
1176
1177   return new_server;
1178 }
1179
1180 /* Processes incoming New ID packet. New ID Payload is used to distribute
1181    information about newly registered clients and servers. */
1182
1183 static void silc_server_new_id_real(SilcServer server, 
1184                                     SilcSocketConnection sock,
1185                                     SilcPacketContext *packet,
1186                                     int broadcast)
1187 {
1188   SilcBuffer buffer = packet->buffer;
1189   SilcIDList id_list;
1190   SilcServerEntry router;
1191   SilcSocketConnection router_sock;
1192   SilcIDPayload idp;
1193   SilcIdType id_type;
1194   unsigned char *hash = NULL;
1195   void *id;
1196
1197   SILC_LOG_DEBUG(("Processing new ID"));
1198
1199   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1200       server->server_type == SILC_SERVER ||
1201       packet->src_id_type != SILC_ID_SERVER)
1202     return;
1203
1204   idp = silc_id_payload_parse(buffer);
1205   if (!idp)
1206     return;
1207
1208   id_type = silc_id_payload_get_type(idp);
1209
1210   /* Normal server cannot have other normal server connections */
1211   if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
1212     goto out;
1213
1214   id = silc_id_payload_get_id(idp);
1215   if (!id)
1216     goto out;
1217
1218   /* If the sender of this packet is server and we are router we need to
1219      broadcast this packet to other routers in the network. */
1220   if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
1221       sock->type == SILC_SOCKET_TYPE_SERVER &&
1222       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1223     SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
1224     silc_server_packet_send(server, server->router->connection,
1225                             packet->type, 
1226                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1227                             buffer->data, buffer->len, FALSE);
1228   }
1229
1230   if (sock->type == SILC_SOCKET_TYPE_SERVER)
1231     id_list = server->local_list;
1232   else
1233     id_list = server->global_list;
1234
1235   router_sock = sock;
1236   router = sock->user_data;
1237
1238   switch(id_type) {
1239   case SILC_ID_CLIENT:
1240     {
1241       SilcClientEntry entry;
1242
1243       SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
1244                       silc_id_render(id, SILC_ID_CLIENT),
1245                       sock->type == SILC_SOCKET_TYPE_SERVER ?
1246                       "Server" : "Router", sock->hostname));
1247     
1248       /* As a router we keep information of all global information in our
1249          global list. Cell wide information however is kept in the local
1250          list. The client is put to global list and we will take the hash
1251          value of the Client ID and save it to the ID Cache system for fast
1252          searching in the future. */
1253       hash = silc_calloc(sizeof(((SilcClientID *)id)->hash), 
1254                          sizeof(unsigned char));
1255       memcpy(hash, ((SilcClientID *)id)->hash, 
1256              sizeof(((SilcClientID *)id)->hash));
1257       entry = silc_idlist_add_client(id_list, hash, NULL, NULL, id, 
1258                                      router, NULL);
1259       entry->nickname = NULL;
1260
1261       if (sock->type == SILC_SOCKET_TYPE_SERVER)
1262         server->stat.cell_clients++;
1263       server->stat.clients++;
1264
1265 #if 0
1266       /* XXX Adding two ID's with same IP number replaces the old entry thus
1267          gives wrong route. Thus, now disabled until figured out a better way
1268          to do this or when removed the whole thing. This could be removed
1269          because entry->router->connection gives always the most optimal route
1270          for the ID anyway (unless new routes (faster perhaps) are established
1271          after receiving this ID, this we don't know however). */
1272       /* Add route cache for this ID */
1273       silc_server_route_add(silc_server_route_hash(
1274                             ((SilcClientID *)id)->ip.s_addr,
1275                             server->id->port), ((SilcClientID *)id)->ip.s_addr,
1276                             router);
1277 #endif
1278     }
1279     break;
1280
1281   case SILC_ID_SERVER:
1282     SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
1283                     silc_id_render(id, SILC_ID_SERVER),
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 global
1288        list. Cell wide information however is kept in the local list. */
1289     silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
1290
1291     if (sock->type == SILC_SOCKET_TYPE_SERVER)
1292       server->stat.cell_servers++;
1293     server->stat.servers++;
1294
1295 #if 0
1296     /* Add route cache for this ID */
1297     silc_server_route_add(silc_server_route_hash(
1298                           ((SilcServerID *)id)->ip.s_addr,
1299                           ((SilcServerID *)id)->port), 
1300                           ((SilcServerID *)id)->ip.s_addr,
1301                           router);
1302 #endif
1303     break;
1304
1305   case SILC_ID_CHANNEL:
1306     SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
1307     break;
1308
1309   default:
1310     break;
1311   }
1312
1313  out:
1314   silc_id_payload_free(idp);
1315 }
1316
1317
1318 /* Processes incoming New ID packet. New ID Payload is used to distribute
1319    information about newly registered clients and servers. */
1320
1321 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
1322                         SilcPacketContext *packet)
1323 {
1324   silc_server_new_id_real(server, sock, packet, TRUE);
1325 }
1326
1327 /* Receoved New Id List packet, list of New ID payloads inside one
1328    packet. Process the New ID payloads one by one. */
1329
1330 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
1331                              SilcPacketContext *packet)
1332 {
1333   SilcPacketContext *new_id;
1334   SilcBuffer idp;
1335   unsigned short id_len;
1336
1337   SILC_LOG_DEBUG(("Processing New ID List"));
1338
1339   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1340       packet->src_id_type != SILC_ID_SERVER)
1341     return;
1342
1343   /* If the sender of this packet is server and we are router we need to
1344      broadcast this packet to other routers in the network. Broadcast
1345      this list packet instead of multiple New ID packets. */
1346   if (!server->standalone && server->server_type == SILC_ROUTER &&
1347       sock->type == SILC_SOCKET_TYPE_SERVER &&
1348       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1349     SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
1350     silc_server_packet_send(server, server->router->connection,
1351                             packet->type, 
1352                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1353                             packet->buffer->data, packet->buffer->len, FALSE);
1354   }
1355
1356   /* Make copy of the original packet context, except for the actual
1357      data buffer, which we will here now fetch from the original buffer. */
1358   new_id = silc_packet_context_alloc();
1359   new_id->type = SILC_PACKET_NEW_ID;
1360   new_id->flags = packet->flags;
1361   new_id->src_id = packet->src_id;
1362   new_id->src_id_len = packet->src_id_len;
1363   new_id->src_id_type = packet->src_id_type;
1364   new_id->dst_id = packet->dst_id;
1365   new_id->dst_id_len = packet->dst_id_len;
1366   new_id->dst_id_type = packet->dst_id_type;
1367
1368   idp = silc_buffer_alloc(256);
1369   new_id->buffer = idp;
1370
1371   while (packet->buffer->len) {
1372     SILC_GET16_MSB(id_len, packet->buffer->data + 2);
1373     if ((id_len > packet->buffer->len) ||
1374         (id_len > idp->truelen))
1375       break;
1376
1377     silc_buffer_pull_tail(idp, 4 + id_len);
1378     silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
1379
1380     /* Process the New ID */
1381     silc_server_new_id_real(server, sock, new_id, FALSE);
1382
1383     silc_buffer_push_tail(idp, 4 + id_len);
1384     silc_buffer_pull(packet->buffer, 4 + id_len);
1385   }
1386
1387   silc_buffer_free(idp);
1388   silc_free(new_id);
1389 }
1390
1391 /* Received New Channel packet. Information about new channels in the 
1392    network are distributed using this packet. Save the information about
1393    the new channel. This usually comes from router but also normal server
1394    can send this to notify channels it has when it connects to us. */
1395
1396 void silc_server_new_channel(SilcServer server,
1397                              SilcSocketConnection sock,
1398                              SilcPacketContext *packet)
1399 {
1400   unsigned char *id;
1401   SilcChannelID *channel_id;
1402   unsigned short channel_id_len;
1403   char *channel_name;
1404   int ret;
1405
1406   SILC_LOG_DEBUG(("Processing New Channel"));
1407
1408   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1409       packet->src_id_type != SILC_ID_SERVER ||
1410       server->server_type == SILC_SERVER)
1411     return;
1412
1413   /* Parse payload */
1414   ret = silc_buffer_unformat(packet->buffer, 
1415                              SILC_STR_UI16_STRING_ALLOC(&channel_name),
1416                              SILC_STR_UI16_NSTRING_ALLOC(&id, &channel_id_len),
1417                              SILC_STR_END);
1418   if (ret == -1) {
1419     if (channel_name)
1420       silc_free(channel_name);
1421     if (id)
1422       silc_free(id);
1423     return;
1424   }
1425     
1426   /* Decode the channel ID */
1427   channel_id = silc_id_str2id(id, channel_id_len, SILC_ID_CHANNEL);
1428   if (!channel_id)
1429     return;
1430
1431   if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
1432     /* Add the server to global list as it is coming from router. It 
1433        cannot be our own channel as it is coming from router. */
1434
1435     SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
1436                     silc_id_render(channel_id, SILC_ID_CHANNEL), 
1437                     sock->hostname));
1438     
1439     silc_idlist_add_channel(server->global_list, channel_name, 0, channel_id, 
1440                             server->router->connection, NULL, NULL);
1441
1442     server->stat.channels++;
1443   } else {
1444     /* The channel is coming from our server, thus it is in our cell
1445        we will add it to our local list. */
1446     SilcChannelEntry channel;
1447     SilcBuffer chk;
1448
1449     SILC_LOG_DEBUG(("New channel id(%s) from [Server] %s",
1450                     silc_id_render(channel_id, SILC_ID_CHANNEL), 
1451                     sock->hostname));
1452     
1453     /* Check that we don't already have this channel */
1454     channel = silc_idlist_find_channel_by_name(server->local_list, 
1455                                                channel_name, NULL);
1456     if (!channel)
1457       channel = silc_idlist_find_channel_by_name(server->global_list, 
1458                                                  channel_name, NULL);
1459
1460     /* If the channel does not exist, then create it. We create the channel
1461        with the channel ID provided by the server. This creates a new
1462        key to the channel as well that we will send to the server. */
1463     if (!channel) {
1464       channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
1465                                                        channel_name,
1466                                                        channel_id, FALSE);
1467       if (!channel)
1468         return;
1469
1470       /* Send the new channel key to the server */
1471       chk = silc_channel_key_payload_encode(channel_id_len, id,
1472                                             strlen(channel->channel_key->
1473                                                    cipher->name),
1474                                             channel->channel_key->cipher->name,
1475                                             channel->key_len / 8, 
1476                                             channel->key);
1477       silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
1478                               chk->data, chk->len, FALSE);
1479       silc_buffer_free(chk);
1480
1481     } else {
1482       /* The channel exist by that name, check whether the ID's match.
1483          If they don't then we'll force the server to use the ID we have.
1484          We also create a new key for the channel. */
1485
1486       if (SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
1487         /* They don't match, send CHANNEL_CHANGE notify to the server to
1488            force the ID change. */
1489         SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
1490         silc_server_send_notify_channel_change(server, sock, FALSE, 
1491                                                channel_id,
1492                                                channel->id, 
1493                                                SILC_ID_CHANNEL_LEN);
1494       }
1495
1496       /* Create new key for the channel and send it to the server and
1497          everybody else possibly on the channel. */
1498
1499       silc_server_create_channel_key(server, channel, 0);
1500
1501       /* Send to the channel */
1502       silc_server_send_channel_key(server, sock, channel, FALSE);
1503
1504       /* Send to the server */
1505       chk = silc_channel_key_payload_encode(channel_id_len, id,
1506                                             strlen(channel->channel_key->
1507                                                    cipher->name),
1508                                             channel->channel_key->cipher->name,
1509                                             channel->key_len / 8, 
1510                                             channel->key);
1511       silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
1512                               chk->data, chk->len, FALSE);
1513       silc_buffer_free(chk);
1514
1515       /* Since the channel is coming from server and we also know about it
1516          then send the JOIN notify to the server so that it see's our
1517          users on the channel "joining" the channel. */
1518       /* XXX TODO **/
1519     }
1520   }
1521
1522   silc_free(id);
1523 }
1524
1525 /* Received New Channel List packet, list of New Channel List payloads inside
1526    one packet. Process the New Channel payloads one by one. */
1527
1528 void silc_server_new_channel_list(SilcServer server,
1529                                   SilcSocketConnection sock,
1530                                   SilcPacketContext *packet)
1531 {
1532   SilcPacketContext *new;
1533   SilcBuffer buffer;
1534   unsigned short len1, len2;
1535
1536   SILC_LOG_DEBUG(("Processing New Channel List"));
1537
1538   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1539       packet->src_id_type != SILC_ID_SERVER ||
1540       server->server_type == SILC_SERVER)
1541     return;
1542
1543   /* If the sender of this packet is server and we are router we need to
1544      broadcast this packet to other routers in the network. Broadcast
1545      this list packet instead of multiple New Channel packets. */
1546   if (!server->standalone && server->server_type == SILC_ROUTER &&
1547       sock->type == SILC_SOCKET_TYPE_SERVER &&
1548       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1549     SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
1550     silc_server_packet_send(server, server->router->connection,
1551                             packet->type, 
1552                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1553                             packet->buffer->data, packet->buffer->len, FALSE);
1554   }
1555
1556   /* Make copy of the original packet context, except for the actual
1557      data buffer, which we will here now fetch from the original buffer. */
1558   new = silc_packet_context_alloc();
1559   new->type = SILC_PACKET_NEW_CHANNEL;
1560   new->flags = packet->flags;
1561   new->src_id = packet->src_id;
1562   new->src_id_len = packet->src_id_len;
1563   new->src_id_type = packet->src_id_type;
1564   new->dst_id = packet->dst_id;
1565   new->dst_id_len = packet->dst_id_len;
1566   new->dst_id_type = packet->dst_id_type;
1567
1568   buffer = silc_buffer_alloc(512);
1569   new->buffer = buffer;
1570
1571   while (packet->buffer->len) {
1572     SILC_GET16_MSB(len1, packet->buffer->data);
1573     if ((len1 > packet->buffer->len) ||
1574         (len1 > buffer->truelen))
1575       break;
1576
1577     SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
1578     if ((len2 > packet->buffer->len) ||
1579         (len2 > buffer->truelen))
1580       break;
1581
1582     silc_buffer_pull_tail(buffer, 4 + len1 + len2);
1583     silc_buffer_put(buffer, packet->buffer->data, 4 + len1 + len2);
1584
1585     /* Process the New Channel */
1586     silc_server_new_channel(server, sock, new);
1587
1588     silc_buffer_push_tail(buffer, 4 + len1 + len2);
1589     silc_buffer_pull(packet->buffer, 4 + len1 + len2);
1590   }
1591
1592   silc_buffer_free(buffer);
1593   silc_free(new);
1594 }
1595
1596 /* Received key agreement packet. This packet is never for us. It is to
1597    the client in the packet's destination ID. Sending of this sort of packet
1598    equals sending private message, ie. it is sent point to point from
1599    one client to another. */
1600
1601 void silc_server_key_agreement(SilcServer server,
1602                                SilcSocketConnection sock,
1603                                SilcPacketContext *packet)
1604 {
1605   SilcSocketConnection dst_sock;
1606   SilcIDListData idata;
1607
1608   SILC_LOG_DEBUG(("Start"));
1609
1610   if (packet->src_id_type != SILC_ID_CLIENT ||
1611       packet->dst_id_type != SILC_ID_CLIENT)
1612     return;
1613
1614   if (!packet->dst_id)
1615     return;
1616
1617   /* Get the route to the client */
1618   dst_sock = silc_server_get_client_route(server, packet->dst_id,
1619                                           packet->dst_id_len, &idata);
1620   if (!dst_sock)
1621     return;
1622
1623   /* Relay the packet */
1624   silc_server_relay_packet(server, dst_sock, idata->send_key,
1625                            idata->hmac, packet, FALSE);
1626 }