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