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     /* If the channel had private keys set and the mode was removed then
426        we must re-generate and re-distribute a new channel key */
427     if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY &&
428         !(mode & SILC_CHANNEL_MODE_PRIVKEY)) {
429       /* Re-generate channel key */
430       silc_server_create_channel_key(server, channel, 0);
431       
432       /* Send the channel key. This sends it to our local clients and if
433          we are normal server to our router as well. */
434       silc_server_send_channel_key(server, NULL, channel, 
435                                    server->server_type == SILC_ROUTER ? 
436                                    FALSE : !server->standalone);
437     }
438
439     /* Change mode */
440     channel->mode = mode;
441     silc_free(channel_id);
442
443     /* Get the hmac */
444     tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
445     if (tmp) {
446       unsigned char hash[32];
447
448       if (channel->hmac)
449         silc_hmac_free(channel->hmac);
450       if (!silc_hmac_alloc(tmp, NULL, &channel->hmac))
451         goto out;
452
453       /* Set the HMAC key out of current channel key. The client must do
454          this locally. */
455       silc_hash_make(channel->hmac->hash, channel->key, channel->key_len / 8, 
456                      hash);
457       silc_hmac_set_key(channel->hmac, hash, 
458                         silc_hash_len(channel->hmac->hash));
459       memset(hash, 0, sizeof(hash));
460     }
461
462     break;
463
464   case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
465     /* 
466      * Distribute the notify to local clients on the channel
467      */
468
469     SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
470
471     channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
472                                 packet->dst_id_type);
473     if (!channel_id)
474       goto out;
475
476     /* Get channel entry */
477     channel = silc_idlist_find_channel_by_id(server->global_list, 
478                                              channel_id, NULL);
479     if (!channel) {
480       channel = silc_idlist_find_channel_by_id(server->local_list, 
481                                                channel_id, NULL);
482       if (!channel) {
483         silc_free(channel_id);
484         goto out;
485       }
486     }
487
488     /* Get the mode */
489     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
490     if (!tmp) {
491       silc_free(channel_id);
492       goto out;
493     }
494       
495     SILC_GET32_MSB(mode, tmp);
496
497     /* Get target client */
498     tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
499     if (!tmp)
500       goto out;
501     client_id = silc_id_payload_parse_id(tmp, tmp_len);
502     if (!client_id)
503       goto out;
504     
505     /* Get client entry */
506     client = silc_idlist_find_client_by_id(server->global_list, 
507                                            client_id, NULL);
508     if (!client) {
509       client = silc_idlist_find_client_by_id(server->local_list, 
510                                              client_id, NULL);
511       if (!client) {
512         silc_free(client_id);
513         goto out;
514       }
515     }
516     silc_free(client_id);
517
518     /* Get entry to the channel user list */
519     silc_list_start(channel->user_list);
520     while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END)
521       if (chl->client == client) {
522         /* Change the mode */
523         chl->mode = mode;
524         break;
525       }
526
527     /* Send the same notify to the channel */
528     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
529                                        FALSE, packet->buffer->data, 
530                                        packet->buffer->len, FALSE);
531     silc_free(channel_id);
532     break;
533
534   case SILC_NOTIFY_TYPE_INVITE:
535
536     if (packet->dst_id_type == SILC_ID_CLIENT)
537       goto out;
538
539     SILC_LOG_DEBUG(("INVITE notify"));
540
541     /* Get Channel ID */
542     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
543     if (!tmp)
544       goto out;
545     channel_id = silc_id_payload_parse_id(tmp, tmp_len);
546     if (!channel_id)
547       goto out;
548
549     /* Get channel entry */
550     channel = silc_idlist_find_channel_by_id(server->global_list, 
551                                              channel_id, NULL);
552     if (!channel) {
553       channel = silc_idlist_find_channel_by_id(server->local_list, 
554                                                channel_id, NULL);
555       if (!channel) {
556         silc_free(channel_id);
557         goto out;
558       }
559     }
560     silc_free(channel_id);
561
562     /* Get the added invite */
563     tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
564     if (tmp) {
565       if (!channel->invite_list)
566         channel->invite_list = silc_calloc(tmp_len + 2, 
567                                            sizeof(*channel->invite_list));
568       else
569         channel->invite_list = silc_realloc(channel->invite_list, 
570                                             sizeof(*channel->invite_list) * 
571                                             (tmp_len + 
572                                              strlen(channel->invite_list) + 
573                                              2));
574       if (tmp[tmp_len - 1] == ',')
575         tmp[tmp_len - 1] = '\0';
576       
577       strncat(channel->invite_list, tmp, tmp_len);
578       strncat(channel->invite_list, ",", 1);
579     }
580
581     /* Get the deleted invite */
582     tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
583     if (tmp && channel->invite_list) {
584       char *start, *end, *n;
585       
586       if (!strncmp(channel->invite_list, tmp, 
587                    strlen(channel->invite_list) - 1)) {
588         silc_free(channel->invite_list);
589         channel->invite_list = NULL;
590       } else {
591         start = strstr(channel->invite_list, tmp);
592         if (start && strlen(start) >= tmp_len) {
593           end = start + tmp_len;
594           n = silc_calloc(strlen(channel->invite_list) - tmp_len, sizeof(*n));
595           strncat(n, channel->invite_list, start - channel->invite_list);
596           strncat(n, end + 1, ((channel->invite_list + 
597                                 strlen(channel->invite_list)) - end) - 1);
598           silc_free(channel->invite_list);
599           channel->invite_list = n;
600         }
601       }
602     }
603
604     break;
605
606   case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
607     /*
608      * Distribute to the local clients on the channel and change the
609      * channel ID.
610      */
611
612     SILC_LOG_DEBUG(("CHANNEL CHANGE"));
613
614     /* Get the old Channel ID */
615     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
616     if (!tmp)
617       goto out;
618     channel_id = silc_id_payload_parse_id(tmp, tmp_len);
619     if (!channel_id)
620       goto out;
621
622     /* Get the channel entry */
623     channel = silc_idlist_find_channel_by_id(server->global_list, 
624                                              channel_id, NULL);
625     if (!channel) {
626       channel = silc_idlist_find_channel_by_id(server->local_list, 
627                                                channel_id, NULL);
628       if (!channel) {
629         silc_free(channel_id);
630         goto out;
631       }
632     }
633
634     /* Send the notify to the channel */
635     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
636                                        FALSE, packet->buffer->data, 
637                                        packet->buffer->len, FALSE);
638
639     /* Get the new Channel ID */
640     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
641     if (!tmp)
642       goto out;
643     channel_id2 = silc_id_payload_parse_id(tmp, tmp_len);
644     if (!channel_id2)
645       goto out;
646
647     /* Replace the Channel ID */
648     if (!silc_idlist_replace_channel_id(server->global_list, channel_id,
649                                         channel_id2))
650       silc_idlist_replace_channel_id(server->local_list, channel_id,
651                                      channel_id2);
652
653     silc_free(channel_id);
654     silc_free(channel_id2);
655
656     break;
657
658   case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
659     SILC_LOG_DEBUG(("SERVER SIGNOFF notify (not-impl XXX)"));
660     break;
661
662   case SILC_NOTIFY_TYPE_KICKED:
663     /* 
664      * Distribute the notify to local clients on the channel
665      */
666     
667     SILC_LOG_DEBUG(("KICKED notify"));
668       
669     channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
670                                 packet->dst_id_type);
671     if (!channel_id)
672       goto out;
673
674     /* Get channel entry */
675     channel = silc_idlist_find_channel_by_id(server->global_list, 
676                                              channel_id, NULL);
677     if (!channel) {
678       channel = silc_idlist_find_channel_by_id(server->local_list, 
679                                                channel_id, NULL);
680       if (!channel) {
681         silc_free(channel_id);
682         goto out;
683       }
684     }
685     silc_free(channel_id);
686
687     /* Get client ID */
688     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
689     if (!tmp)
690       goto out;
691     client_id = silc_id_payload_parse_id(tmp, tmp_len);
692     if (!client_id)
693       goto out;
694
695     /* Send to channel */
696     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
697                                        FALSE, packet->buffer->data, 
698                                        packet->buffer->len, FALSE);
699
700     /* If the the client is not in local list we check global list */
701     client = silc_idlist_find_client_by_id(server->global_list, 
702                                            client_id, NULL);
703     if (!client) {
704       client = silc_idlist_find_client_by_id(server->local_list, 
705                                              client_id, NULL);
706       if (!client) {
707         silc_free(client_id);
708         goto out;
709       }
710     }
711
712     /* Remove the client from channel */
713     silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
714
715     break;
716
717   case SILC_NOTIFY_TYPE_KILLED:
718     {
719       /* 
720        * Distribute the notify to local clients on channels
721        */
722       unsigned char *id;
723       unsigned int id_len;
724     
725       SILC_LOG_DEBUG(("KILLED notify"));
726       
727       /* Get client ID */
728       id = silc_argument_get_arg_type(args, 1, &id_len);
729       if (!id)
730         goto out;
731       client_id = silc_id_payload_parse_id(id, id_len);
732       if (!client_id)
733         goto out;
734
735       /* If the the client is not in local list we check global list */
736       client = silc_idlist_find_client_by_id(server->global_list, 
737                                              client_id, NULL);
738       if (!client) {
739         client = silc_idlist_find_client_by_id(server->local_list, 
740                                                client_id, NULL);
741         if (!client) {
742           silc_free(client_id);
743           goto out;
744         }
745       }
746       silc_free(client_id);
747
748       /* If the client is one of ours, then close the connection to the
749          client now. This removes the client from all channels as well. */
750       if (packet->dst_id_type == SILC_ID_CLIENT && client->data.registered &&
751           client->connection) {
752         sock = client->connection;
753         silc_server_free_client_data(server, NULL, client, FALSE, NULL);
754         silc_server_close_connection(server, sock);
755         break;
756       }
757
758       /* Get comment */
759       tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
760       if (tmp_len > 128)
761         tmp = NULL;
762
763       /* Send the notify to local clients on the channels except to the
764          client who is killed. */
765       silc_server_send_notify_on_channels(server, client, client,
766                                           SILC_NOTIFY_TYPE_KILLED, 
767                                           tmp ? 2 : 1,
768                                           id, id_len, 
769                                           tmp, tmp_len);
770
771       /* Remove the client from all channels */
772       silc_server_remove_from_channels(server, NULL, client, FALSE, NULL, 
773                                        FALSE);
774
775       break;
776     }
777
778   case SILC_NOTIFY_TYPE_UMODE_CHANGE:
779     /*
780      * Save the mode of the client.
781      */
782
783     SILC_LOG_DEBUG(("UMODE_CHANGE notify"));
784       
785     /* Get client ID */
786     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
787     if (!tmp)
788       goto out;
789     client_id = silc_id_payload_parse_id(tmp, tmp_len);
790     if (!client_id)
791       goto out;
792
793     /* Get client entry */
794     client = silc_idlist_find_client_by_id(server->global_list, 
795                                            client_id, NULL);
796     if (!client) {
797       client = silc_idlist_find_client_by_id(server->local_list, 
798                                              client_id, NULL);
799       if (!client) {
800         silc_free(client_id);
801         goto out;
802       }
803     }
804     silc_free(client_id);
805
806     /* Get the mode */
807     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
808     if (!tmp)
809       goto out;
810
811     /* Save the mode */
812     SILC_GET32_MSB(client->mode, tmp);
813
814     break;
815
816   case SILC_NOTIFY_TYPE_BAN:
817     /*
818      * Save the ban
819      */
820
821     SILC_LOG_DEBUG(("BAN notify"));
822     
823     /* Get Channel ID */
824     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
825     if (!tmp)
826       goto out;
827     channel_id = silc_id_payload_parse_id(tmp, tmp_len);
828     if (!channel_id)
829       goto out;
830     
831     /* Get channel entry */
832     channel = silc_idlist_find_channel_by_id(server->global_list, 
833                                              channel_id, NULL);
834     if (!channel) {
835       channel = silc_idlist_find_channel_by_id(server->local_list, 
836                                                channel_id, NULL);
837       if (!channel) {
838         silc_free(channel_id);
839         goto out;
840       }
841     }
842     silc_free(channel_id);
843
844     /* Get the new ban and add it to the ban list */
845     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
846     if (tmp) {
847       if (!channel->ban_list)
848         channel->ban_list = silc_calloc(tmp_len + 2, 
849                                         sizeof(*channel->ban_list));
850       else
851         channel->ban_list = silc_realloc(channel->ban_list, 
852                                          sizeof(*channel->ban_list) * 
853                                          (tmp_len + 
854                                           strlen(channel->ban_list) + 2));
855       strncat(channel->ban_list, tmp, tmp_len);
856       strncat(channel->ban_list, ",", 1);
857     }
858
859     /* Get the ban to be removed and remove it from the list */
860     tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
861     if (tmp && channel->ban_list) {
862       char *start, *end, *n;
863       
864       if (!strcmp(channel->ban_list, tmp)) {
865         silc_free(channel->ban_list);
866         channel->ban_list = NULL;
867       } else {
868         start = strstr(channel->ban_list, tmp);
869         if (start && strlen(start) >= tmp_len) {
870           end = start + tmp_len;
871           n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
872           strncat(n, channel->ban_list, start - channel->ban_list);
873           strncat(n, end + 1, ((channel->ban_list + 
874                                 strlen(channel->ban_list)) - end) - 1);
875           silc_free(channel->ban_list);
876           channel->ban_list = n;
877         }
878       }
879     }
880
881     break;
882
883     /* Ignore rest of the notify types for now */
884   case SILC_NOTIFY_TYPE_NONE:
885   case SILC_NOTIFY_TYPE_MOTD:
886     break;
887   default:
888     break;
889   }
890
891  out:
892   silc_notify_payload_free(payload);
893 }
894
895 void silc_server_notify_list(SilcServer server,
896                              SilcSocketConnection sock,
897                              SilcPacketContext *packet)
898 {
899   SilcPacketContext *new;
900   SilcBuffer buffer;
901   unsigned short len;
902
903   SILC_LOG_DEBUG(("Processing New Notify List"));
904
905   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
906       packet->src_id_type != SILC_ID_SERVER)
907     return;
908
909   /* Make copy of the original packet context, except for the actual
910      data buffer, which we will here now fetch from the original buffer. */
911   new = silc_packet_context_alloc();
912   new->type = SILC_PACKET_NOTIFY;
913   new->flags = packet->flags;
914   new->src_id = packet->src_id;
915   new->src_id_len = packet->src_id_len;
916   new->src_id_type = packet->src_id_type;
917   new->dst_id = packet->dst_id;
918   new->dst_id_len = packet->dst_id_len;
919   new->dst_id_type = packet->dst_id_type;
920
921   buffer = silc_buffer_alloc(1024);
922   new->buffer = buffer;
923
924   while (packet->buffer->len) {
925     SILC_GET16_MSB(len, packet->buffer->data + 2);
926     if (len > packet->buffer->len)
927       break;
928
929     if (len > buffer->truelen) {
930       silc_buffer_free(buffer);
931       buffer = silc_buffer_alloc(1024 + len);
932     }
933
934     silc_buffer_pull_tail(buffer, len);
935     silc_buffer_put(buffer, packet->buffer->data, len);
936
937     /* Process the Notify */
938     silc_server_notify(server, sock, new);
939
940     silc_buffer_push_tail(buffer, len);
941     silc_buffer_pull(packet->buffer, len);
942   }
943
944   silc_buffer_free(buffer);
945   silc_free(new);
946 }
947
948 /* Received private message. This resolves the destination of the message 
949    and sends the packet. This is used by both server and router.  If the
950    destination is our locally connected client this sends the packet to
951    the client. This may also send the message for further routing if
952    the destination is not in our server (or router). */
953
954 void silc_server_private_message(SilcServer server,
955                                  SilcSocketConnection sock,
956                                  SilcPacketContext *packet)
957 {
958   SilcSocketConnection dst_sock;
959   SilcIDListData idata;
960
961   SILC_LOG_DEBUG(("Start"));
962
963   if (packet->src_id_type != SILC_ID_CLIENT ||
964       packet->dst_id_type != SILC_ID_CLIENT)
965     return;
966
967   if (!packet->dst_id)
968     return;
969
970   /* Get the route to the client */
971   dst_sock = silc_server_get_client_route(server, packet->dst_id,
972                                           packet->dst_id_len, NULL, &idata);
973   if (!dst_sock)
974     return;
975
976   /* Send the private message */
977   silc_server_send_private_message(server, dst_sock, idata->send_key,
978                                    idata->hmac, packet);
979 }
980
981 /* Received private message key packet.. This packet is never for us. It is to
982    the client in the packet's destination ID. Sending of this sort of packet
983    equals sending private message, ie. it is sent point to point from
984    one client to another. */
985
986 void silc_server_private_message_key(SilcServer server,
987                                      SilcSocketConnection sock,
988                                      SilcPacketContext *packet)
989 {
990   SilcSocketConnection dst_sock;
991   SilcIDListData idata;
992
993   SILC_LOG_DEBUG(("Start"));
994
995   if (packet->src_id_type != SILC_ID_CLIENT ||
996       packet->dst_id_type != SILC_ID_CLIENT)
997     return;
998
999   if (!packet->dst_id)
1000     return;
1001
1002   /* Get the route to the client */
1003   dst_sock = silc_server_get_client_route(server, packet->dst_id,
1004                                           packet->dst_id_len, NULL, &idata);
1005   if (!dst_sock)
1006     return;
1007
1008   /* Relay the packet */
1009   silc_server_relay_packet(server, dst_sock, idata->send_key,
1010                            idata->hmac, packet, FALSE);
1011 }
1012
1013 /* Processes incoming command reply packet. The command reply packet may
1014    be destined to one of our clients or it may directly for us. We will 
1015    call the command reply routine after processing the packet. */
1016
1017 void silc_server_command_reply(SilcServer server,
1018                                SilcSocketConnection sock,
1019                                SilcPacketContext *packet)
1020 {
1021   SilcBuffer buffer = packet->buffer;
1022   SilcClientEntry client = NULL;
1023   SilcSocketConnection dst_sock;
1024   SilcIDListData idata;
1025   SilcClientID *id = NULL;
1026
1027   SILC_LOG_DEBUG(("Start"));
1028
1029   /* Source must be server or router */
1030   if (packet->src_id_type != SILC_ID_SERVER &&
1031       sock->type != SILC_SOCKET_TYPE_ROUTER)
1032     return;
1033
1034   if (packet->dst_id_type == SILC_ID_CHANNEL)
1035     return;
1036
1037   if (packet->dst_id_type == SILC_ID_CLIENT) {
1038     /* Destination must be one of ours */
1039     id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
1040     if (!id)
1041       return;
1042     client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
1043     if (!client) {
1044       SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
1045       silc_free(id);
1046       return;
1047     }
1048   }
1049
1050   if (packet->dst_id_type == SILC_ID_SERVER) {
1051     /* For now this must be for us */
1052     if (SILC_ID_SERVER_COMPARE(packet->dst_id, server->id_string)) {
1053       SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
1054       return;
1055     }
1056   }
1057
1058   /* Execute command reply locally for the command */
1059   silc_server_command_reply_process(server, sock, buffer);
1060
1061   if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
1062     /* Relay the packet to the client */
1063     
1064     dst_sock = (SilcSocketConnection)client->connection;
1065     silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len 
1066                      + packet->dst_id_len + packet->padlen);
1067     
1068     silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
1069     silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
1070     
1071     idata = (SilcIDListData)client;
1072     
1073     /* Encrypt packet */
1074     silc_packet_encrypt(idata->send_key, idata->hmac, dst_sock->outbuf, 
1075                         buffer->len);
1076     
1077     /* Send the packet */
1078     silc_server_packet_send_real(server, dst_sock, TRUE);
1079
1080     silc_free(id);
1081   }
1082 }
1083
1084 /* Process received channel message. The message can be originated from
1085    client or server. */
1086
1087 void silc_server_channel_message(SilcServer server,
1088                                  SilcSocketConnection sock,
1089                                  SilcPacketContext *packet)
1090 {
1091   SilcChannelEntry channel = NULL;
1092   SilcChannelClientEntry chl;
1093   SilcChannelID *id = NULL;
1094   void *sender = NULL;
1095
1096   SILC_LOG_DEBUG(("Processing channel message"));
1097
1098   /* Sanity checks */
1099   if (packet->dst_id_type != SILC_ID_CHANNEL) {
1100     SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1101     goto out;
1102   }
1103
1104   /* Find channel entry */
1105   id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
1106   if (!id)
1107     goto out;
1108   channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
1109   if (!channel) {
1110     channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
1111     if (!channel) {
1112       SILC_LOG_DEBUG(("Could not find channel"));
1113       goto out;
1114     }
1115   }
1116
1117   /* See that this client is on the channel. If the message is coming
1118      from router we won't do the check as the message is from client that
1119      we don't know about. Also, if the original sender is not client
1120      (as it can be server as well) we don't do the check. */
1121   sender = silc_id_str2id(packet->src_id, packet->src_id_len, 
1122                           packet->src_id_type);
1123   if (!sender)
1124     goto out;
1125   if (sock->type != SILC_SOCKET_TYPE_ROUTER && 
1126       packet->src_id_type == SILC_ID_CLIENT) {
1127     silc_list_start(channel->user_list);
1128     while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
1129       if (chl->client && !SILC_ID_CLIENT_COMPARE(chl->client->id, sender))
1130         break;
1131     }
1132     if (chl == SILC_LIST_END) {
1133       SILC_LOG_DEBUG(("Client not on channel"));
1134       goto out;
1135     }
1136   }
1137
1138   /* If we are router and the packet came from router and private key
1139      has not been set for the channel then we must encrypt the packet
1140      as it was decrypted with the session key shared between us and the
1141      router which sent it. This is so, because cells does not share the
1142      same channel key */
1143   if (server->server_type == SILC_ROUTER &&
1144       sock->type == SILC_SOCKET_TYPE_ROUTER &&
1145       !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
1146     SilcBuffer chp;
1147     unsigned int iv_len, i;
1148     unsigned short data_len, flags;
1149
1150     iv_len = silc_cipher_get_block_len(channel->channel_key);
1151     if (channel->iv[0] == '\0')
1152       for (i = 0; i < iv_len; i++) channel->iv[i] = 
1153                                      silc_rng_get_byte(server->rng);
1154     else
1155       silc_hash_make(server->md5hash, channel->iv, iv_len, channel->iv);
1156     
1157     /* Encode new payload. This encrypts it also. */
1158     SILC_GET16_MSB(flags, packet->buffer->data);
1159     SILC_GET16_MSB(data_len, packet->buffer->data + 2);
1160     chp = silc_channel_message_payload_encode(flags, data_len, 
1161                                               packet->buffer->data + 4,
1162                                               iv_len, channel->iv,
1163                                               channel->channel_key,
1164                                               channel->hmac);
1165     silc_buffer_put(packet->buffer, chp->data, chp->len);
1166     silc_buffer_free(chp);
1167   }
1168
1169   /* Distribute the packet to our local clients. This will send the
1170      packet for further routing as well, if needed. */
1171   silc_server_packet_relay_to_channel(server, sock, channel, sender,
1172                                       packet->src_id_type,
1173                                       packet->buffer->data,
1174                                       packet->buffer->len, FALSE);
1175
1176  out:
1177   if (sender)
1178     silc_free(sender);
1179   if (id)
1180     silc_free(id);
1181 }
1182
1183 /* Received channel key packet. We distribute the key to all of our locally
1184    connected clients on the channel. */
1185
1186 void silc_server_channel_key(SilcServer server,
1187                              SilcSocketConnection sock,
1188                              SilcPacketContext *packet)
1189 {
1190   SilcBuffer buffer = packet->buffer;
1191   SilcChannelEntry channel;
1192
1193   if (packet->src_id_type != SILC_ID_SERVER ||
1194       (server->server_type == SILC_ROUTER &&
1195        sock->type == SILC_SOCKET_TYPE_ROUTER))
1196     return;
1197
1198   /* Save the channel key */
1199   channel = silc_server_save_channel_key(server, buffer, NULL);
1200   if (!channel)
1201     return;
1202
1203   /* Distribute the key to everybody who is on the channel. If we are router
1204      we will also send it to locally connected servers. */
1205   silc_server_send_channel_key(server, sock, channel, FALSE);
1206 }
1207
1208 /* Received New Client packet and processes it.  Creates Client ID for the
1209    client. Client becomes registered after calling this functions. */
1210
1211 SilcClientEntry silc_server_new_client(SilcServer server,
1212                                        SilcSocketConnection sock,
1213                                        SilcPacketContext *packet)
1214 {
1215   SilcBuffer buffer = packet->buffer;
1216   SilcClientEntry client;
1217   SilcIDCacheEntry cache;
1218   SilcClientID *client_id;
1219   SilcBuffer reply;
1220   SilcIDListData idata;
1221   char *username = NULL, *realname = NULL, *id_string;
1222   int ret;
1223
1224   SILC_LOG_DEBUG(("Creating new client"));
1225
1226   if (sock->type != SILC_SOCKET_TYPE_CLIENT)
1227     return NULL;
1228
1229   /* Take client entry */
1230   client = (SilcClientEntry)sock->user_data;
1231   idata = (SilcIDListData)client;
1232
1233   /* Fetch the old client cache entry so that we can update it. */
1234   if (!silc_idcache_find_by_context(server->local_list->clients,
1235                                     sock->user_data, &cache)) {
1236     SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
1237     return NULL;
1238   }
1239
1240   /* Parse incoming packet */
1241   ret = silc_buffer_unformat(buffer,
1242                              SILC_STR_UI16_STRING_ALLOC(&username),
1243                              SILC_STR_UI16_STRING_ALLOC(&realname),
1244                              SILC_STR_END);
1245   if (ret == -1) {
1246     if (username)
1247       silc_free(username);
1248     if (realname)
1249       silc_free(realname);
1250     return NULL;
1251   }
1252
1253   if (!username) {
1254     silc_free(username);
1255     if (realname)
1256       silc_free(realname);
1257     silc_server_disconnect_remote(server, sock, "Server closed connection: "
1258                                   "Incomplete client information");
1259     return NULL;
1260   }
1261
1262   /* Create Client ID */
1263   silc_id_create_client_id(server->id, server->rng, server->md5hash,
1264                            username, &client_id);
1265
1266   if (strlen(username) > 128)
1267     username[127] = '\0';
1268
1269   /* Update client entry */
1270   idata->registered = TRUE;
1271   client->nickname = strdup(username);
1272   client->username = username;
1273   client->userinfo = realname ? realname : strdup(" ");
1274   client->id = client_id;
1275
1276   /* Update the cache entry */
1277   cache->id = (void *)client_id;
1278   cache->type = SILC_ID_CLIENT;
1279   cache->data = username;
1280   silc_idcache_sort_by_data(server->local_list->clients);
1281
1282   /* Notify our router about new client on the SILC network */
1283   if (!server->standalone)
1284     silc_server_send_new_id(server, (SilcSocketConnection) 
1285                             server->router->connection, 
1286                             server->server_type == SILC_ROUTER ? TRUE : FALSE,
1287                             client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
1288   
1289   /* Send the new client ID to the client. */
1290   id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
1291   reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
1292   silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
1293   silc_buffer_format(reply,
1294                      SILC_STR_UI_SHORT(SILC_ID_CLIENT),
1295                      SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
1296                      SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
1297                      SILC_STR_END);
1298   silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0, 
1299                           reply->data, reply->len, FALSE);
1300   silc_free(id_string);
1301   silc_buffer_free(reply);
1302
1303   /* Send some nice info to the client */
1304   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1305                           ("Welcome to the SILC Network %s@%s",
1306                            username, sock->hostname));
1307   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1308                           ("Your host is %s, running version %s",
1309                            server->config->server_info->server_name,
1310                            server_version));
1311   if (server->server_type == SILC_ROUTER) {
1312     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1313                             ("There are %d clients on %d servers in SILC "
1314                              "Network", server->stat.clients,
1315                              server->stat.servers + 1));
1316     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1317                             ("There are %d clients on %d server in our cell",
1318                              server->stat.cell_clients,
1319                              server->stat.cell_servers + 1));
1320     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1321                             ("I have %d clients, %d channels, %d servers and "
1322                              "%d routers",
1323                              server->stat.my_clients, 
1324                              server->stat.my_channels,
1325                              server->stat.my_servers,
1326                              server->stat.my_routers));
1327     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1328                             ("%d server operators and %d router operators "
1329                              "online",
1330                              server->stat.my_server_ops,
1331                              server->stat.my_router_ops));
1332   } else {
1333     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1334                             ("I have %d clients and %d channels formed",
1335                              server->stat.my_clients,
1336                              server->stat.my_channels));
1337     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1338                             ("%d operators online",
1339                              server->stat.my_server_ops));
1340   }
1341   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1342                           ("Your connection is secured with %s cipher, "
1343                            "key length %d bits",
1344                            idata->send_key->cipher->name,
1345                            idata->send_key->cipher->key_len));
1346   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1347                           ("Your current nickname is %s",
1348                            client->nickname));
1349
1350   /* Send motd */
1351   silc_server_send_motd(server, sock);
1352
1353   return client;
1354 }
1355
1356 /* Create new server. This processes received New Server packet and
1357    saves the received Server ID. The server is our locally connected
1358    server thus we save all the information and save it to local list. 
1359    This funtion can be used by both normal server and router server.
1360    If normal server uses this it means that its router has connected
1361    to the server. If router uses this it means that one of the cell's
1362    servers is connected to the router. */
1363
1364 SilcServerEntry silc_server_new_server(SilcServer server,
1365                                        SilcSocketConnection sock,
1366                                        SilcPacketContext *packet)
1367 {
1368   SilcBuffer buffer = packet->buffer;
1369   SilcServerEntry new_server;
1370   SilcIDCacheEntry cache;
1371   SilcServerID *server_id;
1372   SilcIDListData idata;
1373   unsigned char *server_name, *id_string;
1374   unsigned short id_len, name_len;
1375   int ret;
1376
1377   SILC_LOG_DEBUG(("Creating new server"));
1378
1379   if (sock->type != SILC_SOCKET_TYPE_SERVER &&
1380       sock->type != SILC_SOCKET_TYPE_ROUTER)
1381     return NULL;
1382
1383   /* Take server entry */
1384   new_server = (SilcServerEntry)sock->user_data;
1385   idata = (SilcIDListData)new_server;
1386
1387   /* Fetch the old server cache entry so that we can update it. */
1388   if (!silc_idcache_find_by_context(server->local_list->servers,
1389                                     sock->user_data, &cache)) {
1390     SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
1391     return NULL;
1392   }
1393
1394   /* Parse the incoming packet */
1395   ret = silc_buffer_unformat(buffer,
1396                              SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
1397                              SILC_STR_UI16_NSTRING_ALLOC(&server_name, 
1398                                                          &name_len),
1399                              SILC_STR_END);
1400   if (ret == -1) {
1401     if (id_string)
1402       silc_free(id_string);
1403     if (server_name)
1404       silc_free(server_name);
1405     return NULL;
1406   }
1407
1408   if (id_len > buffer->len) {
1409     silc_free(id_string);
1410     silc_free(server_name);
1411     return NULL;
1412   }
1413
1414   if (name_len > 256)
1415     server_name[255] = '\0';
1416
1417   /* Get Server ID */
1418   server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
1419   if (!server_id) {
1420     silc_free(id_string);
1421     silc_free(server_name);
1422     return NULL;
1423   }
1424   silc_free(id_string);
1425
1426   /* Update client entry */
1427   idata->registered = TRUE;
1428   new_server->server_name = server_name;
1429   new_server->id = server_id;
1430
1431   /* Update the cache entry */
1432   cache->id = (void *)server_id;
1433   cache->type = SILC_ID_SERVER;
1434   cache->data = server_name;
1435   silc_idcache_sort_by_data(server->local_list->servers);
1436
1437   /* Distribute the information about new server in the SILC network
1438      to our router. If we are normal server we won't send anything
1439      since this connection must be our router connection. */
1440   if (server->server_type == SILC_ROUTER && !server->standalone &&
1441       server->router->connection != sock)
1442     silc_server_send_new_id(server, server->router->connection,
1443                             TRUE, new_server->id, SILC_ID_SERVER, 
1444                             SILC_ID_SERVER_LEN);
1445
1446   if (server->server_type == SILC_ROUTER)
1447     server->stat.cell_servers++;
1448
1449   return new_server;
1450 }
1451
1452 /* Processes incoming New ID packet. New ID Payload is used to distribute
1453    information about newly registered clients and servers. */
1454
1455 static void silc_server_new_id_real(SilcServer server, 
1456                                     SilcSocketConnection sock,
1457                                     SilcPacketContext *packet,
1458                                     int broadcast)
1459 {
1460   SilcBuffer buffer = packet->buffer;
1461   SilcIDList id_list;
1462   SilcServerEntry router;
1463   SilcSocketConnection router_sock;
1464   SilcIDPayload idp;
1465   SilcIdType id_type;
1466   unsigned char *hash = NULL;
1467   void *id;
1468
1469   SILC_LOG_DEBUG(("Processing new ID"));
1470
1471   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1472       server->server_type == SILC_SERVER ||
1473       packet->src_id_type != SILC_ID_SERVER)
1474     return;
1475
1476   idp = silc_id_payload_parse(buffer);
1477   if (!idp)
1478     return;
1479
1480   id_type = silc_id_payload_get_type(idp);
1481
1482   /* Normal server cannot have other normal server connections */
1483   if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
1484     goto out;
1485
1486   id = silc_id_payload_get_id(idp);
1487   if (!id)
1488     goto out;
1489
1490   /* If the sender of this packet is server and we are router we need to
1491      broadcast this packet to other routers in the network. */
1492   if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
1493       sock->type == SILC_SOCKET_TYPE_SERVER &&
1494       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1495     SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
1496     silc_server_packet_send(server, server->router->connection,
1497                             packet->type, 
1498                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1499                             buffer->data, buffer->len, FALSE);
1500   }
1501
1502   if (sock->type == SILC_SOCKET_TYPE_SERVER)
1503     id_list = server->local_list;
1504   else
1505     id_list = server->global_list;
1506
1507   router_sock = sock;
1508   router = sock->user_data;
1509
1510   switch(id_type) {
1511   case SILC_ID_CLIENT:
1512     {
1513       SilcClientEntry entry;
1514
1515       SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
1516                       silc_id_render(id, SILC_ID_CLIENT),
1517                       sock->type == SILC_SOCKET_TYPE_SERVER ?
1518                       "Server" : "Router", sock->hostname));
1519     
1520       /* As a router we keep information of all global information in our
1521          global list. Cell wide information however is kept in the local
1522          list. The client is put to global list and we will take the hash
1523          value of the Client ID and save it to the ID Cache system for fast
1524          searching in the future. */
1525       hash = silc_calloc(sizeof(((SilcClientID *)id)->hash),
1526                          sizeof(unsigned char));
1527       memcpy(hash, ((SilcClientID *)id)->hash, 
1528              sizeof(((SilcClientID *)id)->hash));
1529       entry = silc_idlist_add_client(id_list, hash, 
1530                                      sizeof(((SilcClientID *)id)->hash),
1531                                      NULL, NULL, id, router, NULL);
1532       entry->nickname = NULL;
1533       entry->data.registered = TRUE;
1534
1535       if (sock->type == SILC_SOCKET_TYPE_SERVER)
1536         server->stat.cell_clients++;
1537       server->stat.clients++;
1538     }
1539     break;
1540
1541   case SILC_ID_SERVER:
1542     SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
1543                     silc_id_render(id, SILC_ID_SERVER),
1544                     sock->type == SILC_SOCKET_TYPE_SERVER ?
1545                     "Server" : "Router", sock->hostname));
1546     
1547     /* As a router we keep information of all global information in our global
1548        list. Cell wide information however is kept in the local list. */
1549     silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
1550
1551     if (sock->type == SILC_SOCKET_TYPE_SERVER)
1552       server->stat.cell_servers++;
1553     server->stat.servers++;
1554     break;
1555
1556   case SILC_ID_CHANNEL:
1557     SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
1558     break;
1559
1560   default:
1561     break;
1562   }
1563
1564  out:
1565   silc_id_payload_free(idp);
1566 }
1567
1568
1569 /* Processes incoming New ID packet. New ID Payload is used to distribute
1570    information about newly registered clients and servers. */
1571
1572 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
1573                         SilcPacketContext *packet)
1574 {
1575   silc_server_new_id_real(server, sock, packet, TRUE);
1576 }
1577
1578 /* Receoved New Id List packet, list of New ID payloads inside one
1579    packet. Process the New ID payloads one by one. */
1580
1581 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
1582                              SilcPacketContext *packet)
1583 {
1584   SilcPacketContext *new_id;
1585   SilcBuffer idp;
1586   unsigned short id_len;
1587
1588   SILC_LOG_DEBUG(("Processing New ID List"));
1589
1590   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1591       packet->src_id_type != SILC_ID_SERVER)
1592     return;
1593
1594   /* If the sender of this packet is server and we are router we need to
1595      broadcast this packet to other routers in the network. Broadcast
1596      this list packet instead of multiple New ID packets. */
1597   if (!server->standalone && server->server_type == SILC_ROUTER &&
1598       sock->type == SILC_SOCKET_TYPE_SERVER &&
1599       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1600     SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
1601     silc_server_packet_send(server, server->router->connection,
1602                             packet->type, 
1603                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1604                             packet->buffer->data, packet->buffer->len, FALSE);
1605   }
1606
1607   /* Make copy of the original packet context, except for the actual
1608      data buffer, which we will here now fetch from the original buffer. */
1609   new_id = silc_packet_context_alloc();
1610   new_id->type = SILC_PACKET_NEW_ID;
1611   new_id->flags = packet->flags;
1612   new_id->src_id = packet->src_id;
1613   new_id->src_id_len = packet->src_id_len;
1614   new_id->src_id_type = packet->src_id_type;
1615   new_id->dst_id = packet->dst_id;
1616   new_id->dst_id_len = packet->dst_id_len;
1617   new_id->dst_id_type = packet->dst_id_type;
1618
1619   idp = silc_buffer_alloc(256);
1620   new_id->buffer = idp;
1621
1622   while (packet->buffer->len) {
1623     SILC_GET16_MSB(id_len, packet->buffer->data + 2);
1624     if ((id_len > packet->buffer->len) ||
1625         (id_len > idp->truelen))
1626       break;
1627
1628     silc_buffer_pull_tail(idp, 4 + id_len);
1629     silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
1630
1631     /* Process the New ID */
1632     silc_server_new_id_real(server, sock, new_id, FALSE);
1633
1634     silc_buffer_push_tail(idp, 4 + id_len);
1635     silc_buffer_pull(packet->buffer, 4 + id_len);
1636   }
1637
1638   silc_buffer_free(idp);
1639   silc_free(new_id);
1640 }
1641
1642 /* Received New Channel packet. Information about new channels in the 
1643    network are distributed using this packet. Save the information about
1644    the new channel. This usually comes from router but also normal server
1645    can send this to notify channels it has when it connects to us. */
1646
1647 void silc_server_new_channel(SilcServer server,
1648                              SilcSocketConnection sock,
1649                              SilcPacketContext *packet)
1650 {
1651   SilcChannelPayload payload;
1652   SilcChannelID *channel_id;
1653   char *channel_name;
1654   unsigned int name_len;
1655   unsigned char *id;
1656   unsigned int id_len;
1657
1658   SILC_LOG_DEBUG(("Processing New Channel"));
1659
1660   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1661       packet->src_id_type != SILC_ID_SERVER ||
1662       server->server_type == SILC_SERVER)
1663     return;
1664
1665   /* Parse the channel payload */
1666   payload = silc_channel_payload_parse(packet->buffer);
1667   if (!payload)
1668     return;
1669     
1670   /* Get the channel ID */
1671   channel_id = silc_channel_get_id_parse(payload);
1672   if (!channel_id) {
1673     silc_channel_payload_free(payload);
1674     return;
1675   }
1676
1677   channel_name = silc_channel_get_name(payload, &name_len);
1678   if (name_len > 256)
1679     channel_name[255] = '\0';
1680
1681   id = silc_channel_get_id(payload, &id_len);
1682
1683   if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
1684     /* Add the server to global list as it is coming from router. It 
1685        cannot be our own channel as it is coming from router. */
1686
1687     SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
1688                     silc_id_render(channel_id, SILC_ID_CHANNEL), 
1689                     sock->hostname));
1690     
1691     silc_idlist_add_channel(server->global_list, strdup(channel_name), 
1692                             0, channel_id, server->router->connection, 
1693                             NULL, NULL);
1694
1695     server->stat.channels++;
1696   } else {
1697     /* The channel is coming from our server, thus it is in our cell
1698        we will add it to our local list. */
1699     SilcChannelEntry channel;
1700     SilcBuffer chk;
1701
1702     SILC_LOG_DEBUG(("New channel id(%s) from [Server] %s",
1703                     silc_id_render(channel_id, SILC_ID_CHANNEL), 
1704                     sock->hostname));
1705     
1706     /* Check that we don't already have this channel */
1707     channel = silc_idlist_find_channel_by_name(server->local_list, 
1708                                                channel_name, NULL);
1709     if (!channel)
1710       channel = silc_idlist_find_channel_by_name(server->global_list, 
1711                                                  channel_name, NULL);
1712
1713     /* If the channel does not exist, then create it. We create the channel
1714        with the channel ID provided by the server. This creates a new
1715        key to the channel as well that we will send to the server. */
1716     if (!channel) {
1717       channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
1718                                                        channel_name,
1719                                                        channel_id, FALSE);
1720       if (!channel) {
1721         silc_channel_payload_free(payload);
1722         silc_free(channel_id);
1723         return;
1724       }
1725
1726       /* Send the new channel key to the server */
1727       chk = silc_channel_key_payload_encode(id_len, id,
1728                                             strlen(channel->channel_key->
1729                                                    cipher->name),
1730                                             channel->channel_key->cipher->name,
1731                                             channel->key_len / 8, 
1732                                             channel->key);
1733       silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
1734                               chk->data, chk->len, FALSE);
1735       silc_buffer_free(chk);
1736
1737     } else {
1738       /* The channel exist by that name, check whether the ID's match.
1739          If they don't then we'll force the server to use the ID we have.
1740          We also create a new key for the channel. */
1741
1742       if (SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
1743         /* They don't match, send CHANNEL_CHANGE notify to the server to
1744            force the ID change. */
1745         SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
1746         silc_server_send_notify_channel_change(server, sock, FALSE, 
1747                                                channel_id,
1748                                                channel->id, 
1749                                                SILC_ID_CHANNEL_LEN);
1750       }
1751
1752       /* Create new key for the channel and send it to the server and
1753          everybody else possibly on the channel. */
1754
1755       if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
1756         silc_server_create_channel_key(server, channel, 0);
1757         
1758         /* Send to the channel */
1759         silc_server_send_channel_key(server, sock, channel, FALSE);
1760         
1761         /* Send to the server */
1762         chk = silc_channel_key_payload_encode(id_len, id,
1763                                               strlen(channel->channel_key->
1764                                                      cipher->name),
1765                                               channel->channel_key->
1766                                               cipher->name,
1767                                               channel->key_len / 8, 
1768                                               channel->key);
1769         silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
1770                                 chk->data, chk->len, FALSE);
1771         silc_buffer_free(chk);
1772       }
1773
1774       silc_free(channel_id);
1775
1776       /* Since the channel is coming from server and we also know about it
1777          then send the JOIN notify to the server so that it see's our
1778          users on the channel "joining" the channel. */
1779       /* XXX TODO **/
1780     }
1781   }
1782 }
1783
1784 /* Received New Channel List packet, list of New Channel List payloads inside
1785    one packet. Process the New Channel payloads one by one. */
1786
1787 void silc_server_new_channel_list(SilcServer server,
1788                                   SilcSocketConnection sock,
1789                                   SilcPacketContext *packet)
1790 {
1791   SilcPacketContext *new;
1792   SilcBuffer buffer;
1793   unsigned short len1, len2;
1794
1795   SILC_LOG_DEBUG(("Processing New Channel List"));
1796
1797   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1798       packet->src_id_type != SILC_ID_SERVER ||
1799       server->server_type == SILC_SERVER)
1800     return;
1801
1802   /* If the sender of this packet is server and we are router we need to
1803      broadcast this packet to other routers in the network. Broadcast
1804      this list packet instead of multiple New Channel packets. */
1805   if (!server->standalone && server->server_type == SILC_ROUTER &&
1806       sock->type == SILC_SOCKET_TYPE_SERVER &&
1807       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1808     SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
1809     silc_server_packet_send(server, server->router->connection,
1810                             packet->type, 
1811                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1812                             packet->buffer->data, packet->buffer->len, FALSE);
1813   }
1814
1815   /* Make copy of the original packet context, except for the actual
1816      data buffer, which we will here now fetch from the original buffer. */
1817   new = silc_packet_context_alloc();
1818   new->type = SILC_PACKET_NEW_CHANNEL;
1819   new->flags = packet->flags;
1820   new->src_id = packet->src_id;
1821   new->src_id_len = packet->src_id_len;
1822   new->src_id_type = packet->src_id_type;
1823   new->dst_id = packet->dst_id;
1824   new->dst_id_len = packet->dst_id_len;
1825   new->dst_id_type = packet->dst_id_type;
1826
1827   buffer = silc_buffer_alloc(512);
1828   new->buffer = buffer;
1829
1830   while (packet->buffer->len) {
1831     SILC_GET16_MSB(len1, packet->buffer->data);
1832     if ((len1 > packet->buffer->len) ||
1833         (len1 > buffer->truelen))
1834       break;
1835
1836     SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
1837     if ((len2 > packet->buffer->len) ||
1838         (len2 > buffer->truelen))
1839       break;
1840
1841     silc_buffer_pull_tail(buffer, 8 + len1 + len2);
1842     silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
1843
1844     /* Process the New Channel */
1845     silc_server_new_channel(server, sock, new);
1846
1847     silc_buffer_push_tail(buffer, 8 + len1 + len2);
1848     silc_buffer_pull(packet->buffer, 8 + len1 + len2);
1849   }
1850
1851   silc_buffer_free(buffer);
1852   silc_free(new);
1853 }
1854
1855 /* Received key agreement packet. This packet is never for us. It is to
1856    the client in the packet's destination ID. Sending of this sort of packet
1857    equals sending private message, ie. it is sent point to point from
1858    one client to another. */
1859
1860 void silc_server_key_agreement(SilcServer server,
1861                                SilcSocketConnection sock,
1862                                SilcPacketContext *packet)
1863 {
1864   SilcSocketConnection dst_sock;
1865   SilcIDListData idata;
1866
1867   SILC_LOG_DEBUG(("Start"));
1868
1869   if (packet->src_id_type != SILC_ID_CLIENT ||
1870       packet->dst_id_type != SILC_ID_CLIENT)
1871     return;
1872
1873   if (!packet->dst_id)
1874     return;
1875
1876   /* Get the route to the client */
1877   dst_sock = silc_server_get_client_route(server, packet->dst_id,
1878                                           packet->dst_id_len, NULL, &idata);
1879   if (!dst_sock)
1880     return;
1881
1882   /* Relay the packet */
1883   silc_server_relay_packet(server, dst_sock, idata->send_key,
1884                            idata->hmac, packet, FALSE);
1885 }
1886
1887 /* Received connection auth request packet that is used during connection
1888    phase to resolve the mandatory authentication method.  This packet can
1889    actually be received at anytime but usually it is used only during
1890    the connection authentication phase. Now, protocol says that this packet
1891    can come from client or server, however, we support only this coming
1892    from client and expect that server's always knows what authentication
1893    method to use. */
1894
1895 void silc_server_connection_auth_request(SilcServer server,
1896                                          SilcSocketConnection sock,
1897                                          SilcPacketContext *packet)
1898 {
1899   SilcServerConfigSectionClientConnection *client = NULL;
1900   unsigned short conn_type;
1901   int ret;
1902   SilcAuthMethod auth_meth;
1903
1904   SILC_LOG_DEBUG(("Start"));
1905
1906   if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT)
1907     return;
1908
1909   /* Parse the payload */
1910   ret = silc_buffer_unformat(packet->buffer,
1911                              SILC_STR_UI_SHORT(&conn_type),
1912                              SILC_STR_UI_SHORT(NULL),
1913                              SILC_STR_END);
1914   if (ret == -1)
1915     return;
1916
1917   if (conn_type != SILC_SOCKET_TYPE_CLIENT)
1918     return;
1919
1920   /* Get the authentication method for the client */
1921   auth_meth = SILC_AUTH_NONE;
1922   client = silc_server_config_find_client_conn(server->config,
1923                                                sock->ip,
1924                                                sock->port);
1925   if (!client)
1926     client = silc_server_config_find_client_conn(server->config,
1927                                                  sock->hostname,
1928                                                  sock->port);
1929   if (client)
1930     auth_meth = client->auth_meth;
1931           
1932   /* Send it back to the client */
1933   silc_server_send_connection_auth_request(server, sock,
1934                                            conn_type,
1935                                            auth_meth);
1936 }