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