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