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