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->data.registered &&
873           client->connection) {
874         sock = client->connection;
875         silc_server_free_client_data(server, NULL, client, FALSE, NULL);
876         silc_server_close_connection(server, sock);
877         break;
878       }
879
880       /* Get comment */
881       tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
882       if (tmp_len > 128)
883         tmp = NULL;
884
885       /* Send the notify to local clients on the channels except to the
886          client who is killed. */
887       silc_server_send_notify_on_channels(server, client, client,
888                                           SILC_NOTIFY_TYPE_KILLED, 
889                                           tmp ? 2 : 1,
890                                           id, id_len, 
891                                           tmp, tmp_len);
892
893       /* Remove the client from all channels */
894       silc_server_remove_from_channels(server, NULL, client, FALSE, NULL, 
895                                        FALSE);
896
897       break;
898     }
899
900   case SILC_NOTIFY_TYPE_UMODE_CHANGE:
901     /*
902      * Save the mode of the client.
903      */
904
905     SILC_LOG_DEBUG(("UMODE_CHANGE notify"));
906       
907     /* Get client ID */
908     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
909     if (!tmp)
910       goto out;
911     client_id = silc_id_payload_parse_id(tmp, tmp_len);
912     if (!client_id)
913       goto out;
914
915     /* Get client entry */
916     client = silc_idlist_find_client_by_id(server->global_list, 
917                                            client_id, TRUE, NULL);
918     if (!client) {
919       client = silc_idlist_find_client_by_id(server->local_list, 
920                                              client_id, TRUE, NULL);
921       if (!client) {
922         silc_free(client_id);
923         goto out;
924       }
925     }
926     silc_free(client_id);
927
928     /* Get the mode */
929     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
930     if (!tmp)
931       goto out;
932
933     /* Save the mode */
934     SILC_GET32_MSB(client->mode, tmp);
935
936     break;
937
938   case SILC_NOTIFY_TYPE_BAN:
939     /*
940      * Save the ban
941      */
942
943     SILC_LOG_DEBUG(("BAN notify"));
944     
945     /* Get Channel ID */
946     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
947     if (!tmp)
948       goto out;
949     channel_id = silc_id_payload_parse_id(tmp, tmp_len);
950     if (!channel_id)
951       goto out;
952     
953     /* Get channel entry */
954     channel = silc_idlist_find_channel_by_id(server->global_list, 
955                                              channel_id, NULL);
956     if (!channel) {
957       channel = silc_idlist_find_channel_by_id(server->local_list, 
958                                                channel_id, NULL);
959       if (!channel) {
960         silc_free(channel_id);
961         goto out;
962       }
963     }
964     silc_free(channel_id);
965
966     /* Get the new ban and add it to the ban list */
967     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
968     if (tmp) {
969       if (!channel->ban_list)
970         channel->ban_list = silc_calloc(tmp_len + 2, 
971                                         sizeof(*channel->ban_list));
972       else
973         channel->ban_list = silc_realloc(channel->ban_list, 
974                                          sizeof(*channel->ban_list) * 
975                                          (tmp_len + 
976                                           strlen(channel->ban_list) + 2));
977       strncat(channel->ban_list, tmp, tmp_len);
978       strncat(channel->ban_list, ",", 1);
979     }
980
981     /* Get the ban to be removed and remove it from the list */
982     tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
983     if (tmp && channel->ban_list) {
984       char *start, *end, *n;
985       
986       if (!strcmp(channel->ban_list, tmp)) {
987         silc_free(channel->ban_list);
988         channel->ban_list = NULL;
989       } else {
990         start = strstr(channel->ban_list, tmp);
991         if (start && strlen(start) >= tmp_len) {
992           end = start + tmp_len;
993           n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
994           strncat(n, channel->ban_list, start - channel->ban_list);
995           strncat(n, end + 1, ((channel->ban_list + 
996                                 strlen(channel->ban_list)) - end) - 1);
997           silc_free(channel->ban_list);
998           channel->ban_list = n;
999         }
1000       }
1001     }
1002
1003     break;
1004
1005     /* Ignore rest of the notify types for now */
1006   case SILC_NOTIFY_TYPE_NONE:
1007   case SILC_NOTIFY_TYPE_MOTD:
1008     break;
1009   default:
1010     break;
1011   }
1012
1013  out:
1014   silc_notify_payload_free(payload);
1015 }
1016
1017 void silc_server_notify_list(SilcServer server,
1018                              SilcSocketConnection sock,
1019                              SilcPacketContext *packet)
1020 {
1021   SilcPacketContext *new;
1022   SilcBuffer buffer;
1023   uint16 len;
1024
1025   SILC_LOG_DEBUG(("Processing Notify List"));
1026
1027   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1028       packet->src_id_type != SILC_ID_SERVER)
1029     return;
1030
1031   /* Make copy of the original packet context, except for the actual
1032      data buffer, which we will here now fetch from the original buffer. */
1033   new = silc_packet_context_alloc();
1034   new->type = SILC_PACKET_NOTIFY;
1035   new->flags = packet->flags;
1036   new->src_id = packet->src_id;
1037   new->src_id_len = packet->src_id_len;
1038   new->src_id_type = packet->src_id_type;
1039   new->dst_id = packet->dst_id;
1040   new->dst_id_len = packet->dst_id_len;
1041   new->dst_id_type = packet->dst_id_type;
1042
1043   buffer = silc_buffer_alloc(1024);
1044   new->buffer = buffer;
1045
1046   while (packet->buffer->len) {
1047     SILC_GET16_MSB(len, packet->buffer->data + 2);
1048     if (len > packet->buffer->len)
1049       break;
1050
1051     if (len > buffer->truelen) {
1052       silc_buffer_free(buffer);
1053       buffer = silc_buffer_alloc(1024 + len);
1054     }
1055
1056     silc_buffer_pull_tail(buffer, len);
1057     silc_buffer_put(buffer, packet->buffer->data, len);
1058
1059     /* Process the Notify */
1060     silc_server_notify(server, sock, new);
1061
1062     silc_buffer_push_tail(buffer, len);
1063     silc_buffer_pull(packet->buffer, len);
1064   }
1065
1066   silc_buffer_free(buffer);
1067   silc_free(new);
1068 }
1069
1070 /* Received private message. This resolves the destination of the message 
1071    and sends the packet. This is used by both server and router.  If the
1072    destination is our locally connected client this sends the packet to
1073    the client. This may also send the message for further routing if
1074    the destination is not in our server (or router). */
1075
1076 void silc_server_private_message(SilcServer server,
1077                                  SilcSocketConnection sock,
1078                                  SilcPacketContext *packet)
1079 {
1080   SilcSocketConnection dst_sock;
1081   SilcIDListData idata;
1082
1083   SILC_LOG_DEBUG(("Start"));
1084
1085   if (packet->src_id_type != SILC_ID_CLIENT ||
1086       packet->dst_id_type != SILC_ID_CLIENT)
1087     return;
1088
1089   if (!packet->dst_id)
1090     return;
1091
1092   /* Get the route to the client */
1093   dst_sock = silc_server_get_client_route(server, packet->dst_id,
1094                                           packet->dst_id_len, NULL, &idata);
1095   if (!dst_sock)
1096     return;
1097
1098   /* Send the private message */
1099   silc_server_send_private_message(server, dst_sock, idata->send_key,
1100                                    idata->hmac_send, packet);
1101 }
1102
1103 /* Received private message key packet.. This packet is never for us. It is to
1104    the client in the packet's destination ID. Sending of this sort of packet
1105    equals sending private message, ie. it is sent point to point from
1106    one client to another. */
1107
1108 void silc_server_private_message_key(SilcServer server,
1109                                      SilcSocketConnection sock,
1110                                      SilcPacketContext *packet)
1111 {
1112   SilcSocketConnection dst_sock;
1113   SilcIDListData idata;
1114
1115   SILC_LOG_DEBUG(("Start"));
1116
1117   if (packet->src_id_type != SILC_ID_CLIENT ||
1118       packet->dst_id_type != SILC_ID_CLIENT)
1119     return;
1120
1121   if (!packet->dst_id)
1122     return;
1123
1124   /* Get the route to the client */
1125   dst_sock = silc_server_get_client_route(server, packet->dst_id,
1126                                           packet->dst_id_len, NULL, &idata);
1127   if (!dst_sock)
1128     return;
1129
1130   /* Relay the packet */
1131   silc_server_relay_packet(server, dst_sock, idata->send_key,
1132                            idata->hmac_send, packet, FALSE);
1133 }
1134
1135 /* Processes incoming command reply packet. The command reply packet may
1136    be destined to one of our clients or it may directly for us. We will 
1137    call the command reply routine after processing the packet. */
1138
1139 void silc_server_command_reply(SilcServer server,
1140                                SilcSocketConnection sock,
1141                                SilcPacketContext *packet)
1142 {
1143   SilcBuffer buffer = packet->buffer;
1144   SilcClientEntry client = NULL;
1145   SilcSocketConnection dst_sock;
1146   SilcIDListData idata;
1147   SilcClientID *id = NULL;
1148
1149   SILC_LOG_DEBUG(("Start"));
1150
1151   /* Source must be server or router */
1152   if (packet->src_id_type != SILC_ID_SERVER &&
1153       sock->type != SILC_SOCKET_TYPE_ROUTER)
1154     return;
1155
1156   if (packet->dst_id_type == SILC_ID_CHANNEL)
1157     return;
1158
1159   if (packet->dst_id_type == SILC_ID_CLIENT) {
1160     /* Destination must be one of ours */
1161     id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
1162     if (!id)
1163       return;
1164     client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
1165     if (!client) {
1166       SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
1167       silc_free(id);
1168       return;
1169     }
1170   }
1171
1172   if (packet->dst_id_type == SILC_ID_SERVER) {
1173     /* For now this must be for us */
1174     if (memcmp(packet->dst_id, server->id_string, packet->dst_id_len)) {
1175       SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
1176       return;
1177     }
1178   }
1179
1180   /* Execute command reply locally for the command */
1181   silc_server_command_reply_process(server, sock, buffer);
1182
1183   if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
1184     /* Relay the packet to the client */
1185     
1186     dst_sock = (SilcSocketConnection)client->connection;
1187     silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len 
1188                      + packet->dst_id_len + packet->padlen);
1189     
1190     silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
1191     silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
1192     
1193     idata = (SilcIDListData)client;
1194     
1195     /* Encrypt packet */
1196     silc_packet_encrypt(idata->send_key, idata->hmac_send, dst_sock->outbuf, 
1197                         buffer->len);
1198     
1199     /* Send the packet */
1200     silc_server_packet_send_real(server, dst_sock, TRUE);
1201
1202     silc_free(id);
1203   }
1204 }
1205
1206 /* Process received channel message. The message can be originated from
1207    client or server. */
1208
1209 void silc_server_channel_message(SilcServer server,
1210                                  SilcSocketConnection sock,
1211                                  SilcPacketContext *packet)
1212 {
1213   SilcChannelEntry channel = NULL;
1214   SilcChannelID *id = NULL;
1215   void *sender = NULL;
1216   void *sender_entry = NULL;
1217
1218   SILC_LOG_DEBUG(("Processing channel message"));
1219
1220   /* Sanity checks */
1221   if (packet->dst_id_type != SILC_ID_CHANNEL) {
1222     SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1223     goto out;
1224   }
1225
1226   /* Find channel entry */
1227   id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
1228   if (!id)
1229     goto out;
1230   channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
1231   if (!channel) {
1232     channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
1233     if (!channel) {
1234       SILC_LOG_DEBUG(("Could not find channel"));
1235       goto out;
1236     }
1237   }
1238
1239   /* See that this client is on the channel. If the original sender is
1240      not client (as it can be server as well) we don't do the check. */
1241   sender = silc_id_str2id(packet->src_id, packet->src_id_len, 
1242                           packet->src_id_type);
1243   if (!sender)
1244     goto out;
1245   if (packet->src_id_type == SILC_ID_CLIENT) {
1246     sender_entry = silc_idlist_find_client_by_id(server->local_list, 
1247                                                  sender, TRUE, NULL);
1248     if (!sender_entry)
1249       sender_entry = silc_idlist_find_client_by_id(server->global_list, 
1250                                                    sender, TRUE, NULL);
1251     if (!sender_entry || !silc_server_client_on_channel(sender_entry, 
1252                                                         channel)) {
1253       SILC_LOG_DEBUG(("Client not on channel"));
1254       goto out;
1255     }
1256   }
1257
1258   /* Distribute the packet to our local clients. This will send the
1259      packet for further routing as well, if needed. */
1260   silc_server_packet_relay_to_channel(server, sock, channel, sender,
1261                                       packet->src_id_type, sender_entry,
1262                                       packet->buffer->data,
1263                                       packet->buffer->len, FALSE);
1264
1265  out:
1266   if (sender)
1267     silc_free(sender);
1268   if (id)
1269     silc_free(id);
1270 }
1271
1272 /* Received channel key packet. We distribute the key to all of our locally
1273    connected clients on the channel. */
1274
1275 void silc_server_channel_key(SilcServer server,
1276                              SilcSocketConnection sock,
1277                              SilcPacketContext *packet)
1278 {
1279   SilcBuffer buffer = packet->buffer;
1280   SilcChannelEntry channel;
1281
1282   if (packet->src_id_type != SILC_ID_SERVER ||
1283       (server->server_type == SILC_ROUTER &&
1284        sock->type == SILC_SOCKET_TYPE_ROUTER))
1285     return;
1286
1287   /* Save the channel key */
1288   channel = silc_server_save_channel_key(server, buffer, NULL);
1289   if (!channel)
1290     return;
1291
1292   /* Distribute the key to everybody who is on the channel. If we are router
1293      we will also send it to locally connected servers. */
1294   silc_server_send_channel_key(server, sock, channel, FALSE);
1295 }
1296
1297 /* Received New Client packet and processes it.  Creates Client ID for the
1298    client. Client becomes registered after calling this functions. */
1299
1300 SilcClientEntry silc_server_new_client(SilcServer server,
1301                                        SilcSocketConnection sock,
1302                                        SilcPacketContext *packet)
1303 {
1304   SilcBuffer buffer = packet->buffer;
1305   SilcClientEntry client;
1306   SilcClientID *client_id;
1307   SilcBuffer reply;
1308   SilcIDListData idata;
1309   char *username = NULL, *realname = NULL, *id_string;
1310   uint32 id_len;
1311   int ret;
1312   char *hostname, *nickname;
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   silc_id_create_client_id(server->id, server->rng, server->md5hash,
1446                            nickname, &client_id);
1447
1448   /* Update client entry */
1449   idata->registered = TRUE;
1450   client->nickname = nickname;
1451   client->username = username;
1452   client->userinfo = realname ? realname : strdup(" ");
1453   client->id = client_id;
1454   id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
1455
1456   /* Add the client again to the ID cache */
1457   silc_idcache_add(server->local_list->clients, client->nickname,
1458                    client_id, client, FALSE);
1459
1460   /* Notify our router about new client on the SILC network */
1461   if (!server->standalone)
1462     silc_server_send_new_id(server, (SilcSocketConnection) 
1463                             server->router->connection, 
1464                             server->server_type == SILC_ROUTER ? TRUE : FALSE,
1465                             client->id, SILC_ID_CLIENT, id_len);
1466   
1467   /* Send the new client ID to the client. */
1468   id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
1469   reply = silc_buffer_alloc(2 + 2 + id_len);
1470   silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
1471   silc_buffer_format(reply,
1472                      SILC_STR_UI_SHORT(SILC_ID_CLIENT),
1473                      SILC_STR_UI_SHORT(id_len),
1474                      SILC_STR_UI_XNSTRING(id_string, id_len),
1475                      SILC_STR_END);
1476   silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0, 
1477                           reply->data, reply->len, FALSE);
1478   silc_free(id_string);
1479   silc_buffer_free(reply);
1480
1481   /* Send some nice info to the client */
1482   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1483                           ("Welcome to the SILC Network %s",
1484                            username));
1485   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1486                           ("Your host is %s, running version %s",
1487                            server->config->server_info->server_name,
1488                            server_version));
1489   if (server->server_type == SILC_ROUTER) {
1490     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1491                             ("There are %d clients on %d servers in SILC "
1492                              "Network", server->stat.clients,
1493                              server->stat.servers + 1));
1494     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1495                             ("There are %d clients on %d server in our cell",
1496                              server->stat.cell_clients,
1497                              server->stat.cell_servers + 1));
1498     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1499                             ("I have %d clients, %d channels, %d servers and "
1500                              "%d routers",
1501                              server->stat.my_clients, 
1502                              server->stat.my_channels,
1503                              server->stat.my_servers,
1504                              server->stat.my_routers));
1505     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1506                             ("%d server operators and %d router operators "
1507                              "online",
1508                              server->stat.my_server_ops,
1509                              server->stat.my_router_ops));
1510   } else {
1511     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1512                             ("I have %d clients and %d channels formed",
1513                              server->stat.my_clients,
1514                              server->stat.my_channels));
1515     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1516                             ("%d operators online",
1517                              server->stat.my_server_ops));
1518   }
1519   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1520                           ("Your connection is secured with %s cipher, "
1521                            "key length %d bits",
1522                            idata->send_key->cipher->name,
1523                            idata->send_key->cipher->key_len));
1524   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1525                           ("Your current nickname is %s",
1526                            client->nickname));
1527
1528   /* Send motd */
1529   silc_server_send_motd(server, sock);
1530
1531   return client;
1532 }
1533
1534 /* Create new server. This processes received New Server packet and
1535    saves the received Server ID. The server is our locally connected
1536    server thus we save all the information and save it to local list. 
1537    This funtion can be used by both normal server and router server.
1538    If normal server uses this it means that its router has connected
1539    to the server. If router uses this it means that one of the cell's
1540    servers is connected to the router. */
1541
1542 SilcServerEntry silc_server_new_server(SilcServer server,
1543                                        SilcSocketConnection sock,
1544                                        SilcPacketContext *packet)
1545 {
1546   SilcBuffer buffer = packet->buffer;
1547   SilcServerEntry new_server;
1548   SilcServerID *server_id;
1549   SilcIDListData idata;
1550   unsigned char *server_name, *id_string;
1551   uint16 id_len, name_len;
1552   int ret;
1553
1554   SILC_LOG_DEBUG(("Creating new server"));
1555
1556   if (sock->type != SILC_SOCKET_TYPE_SERVER &&
1557       sock->type != SILC_SOCKET_TYPE_ROUTER)
1558     return NULL;
1559
1560   /* Take server entry */
1561   new_server = (SilcServerEntry)sock->user_data;
1562   idata = (SilcIDListData)new_server;
1563
1564   /* Remove the old cache entry */
1565   silc_idcache_del_by_context(server->local_list->servers, new_server);
1566
1567   /* Parse the incoming packet */
1568   ret = silc_buffer_unformat(buffer,
1569                              SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
1570                              SILC_STR_UI16_NSTRING_ALLOC(&server_name, 
1571                                                          &name_len),
1572                              SILC_STR_END);
1573   if (ret == -1) {
1574     if (id_string)
1575       silc_free(id_string);
1576     if (server_name)
1577       silc_free(server_name);
1578     return NULL;
1579   }
1580
1581   if (id_len > buffer->len) {
1582     silc_free(id_string);
1583     silc_free(server_name);
1584     return NULL;
1585   }
1586
1587   if (name_len > 256)
1588     server_name[255] = '\0';
1589
1590   /* Get Server ID */
1591   server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
1592   if (!server_id) {
1593     silc_free(id_string);
1594     silc_free(server_name);
1595     return NULL;
1596   }
1597   silc_free(id_string);
1598
1599   /* Update server entry */
1600   idata->registered = TRUE;
1601   new_server->server_name = server_name;
1602   new_server->id = server_id;
1603
1604   /* Add again the entry to the ID cache. */
1605   silc_idcache_add(server->local_list->servers, server_name, server_id, 
1606                    new_server, FALSE);
1607
1608   /* Distribute the information about new server in the SILC network
1609      to our router. If we are normal server we won't send anything
1610      since this connection must be our router connection. */
1611   if (server->server_type == SILC_ROUTER && !server->standalone &&
1612       server->router->connection != sock)
1613     silc_server_send_new_id(server, server->router->connection,
1614                             TRUE, new_server->id, SILC_ID_SERVER, 
1615                             silc_id_get_len(server_id, SILC_ID_SERVER));
1616
1617   if (server->server_type == SILC_ROUTER)
1618     server->stat.cell_servers++;
1619
1620   return new_server;
1621 }
1622
1623 /* Processes incoming New ID packet. New ID Payload is used to distribute
1624    information about newly registered clients and servers. */
1625
1626 static void silc_server_new_id_real(SilcServer server, 
1627                                     SilcSocketConnection sock,
1628                                     SilcPacketContext *packet,
1629                                     int broadcast)
1630 {
1631   SilcBuffer buffer = packet->buffer;
1632   SilcIDList id_list;
1633   SilcServerEntry router;
1634   SilcSocketConnection router_sock;
1635   SilcIDPayload idp;
1636   SilcIdType id_type;
1637   void *id;
1638
1639   SILC_LOG_DEBUG(("Processing new ID"));
1640
1641   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1642       server->server_type == SILC_SERVER ||
1643       packet->src_id_type != SILC_ID_SERVER)
1644     return;
1645
1646   idp = silc_id_payload_parse(buffer);
1647   if (!idp)
1648     return;
1649
1650   id_type = silc_id_payload_get_type(idp);
1651
1652   /* Normal server cannot have other normal server connections */
1653   if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
1654     goto out;
1655
1656   id = silc_id_payload_get_id(idp);
1657   if (!id)
1658     goto out;
1659
1660   /* If the sender of this packet is server and we are router we need to
1661      broadcast this packet to other routers in the network. */
1662   if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
1663       sock->type == SILC_SOCKET_TYPE_SERVER &&
1664       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1665     SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
1666     silc_server_packet_send(server, server->router->connection,
1667                             packet->type, 
1668                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1669                             buffer->data, buffer->len, FALSE);
1670   }
1671
1672   if (sock->type == SILC_SOCKET_TYPE_SERVER)
1673     id_list = server->local_list;
1674   else
1675     id_list = server->global_list;
1676
1677   /* If the packet is coming from server then use the sender as the
1678      origin of the the packet. If it came from router then check the real
1679      sender of the packet and use that as the origin. */
1680   if (sock->type == SILC_SOCKET_TYPE_SERVER) {
1681     router_sock = sock;
1682     router = sock->user_data;
1683   } else {
1684     void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1685                                      packet->src_id_type);
1686     router = silc_idlist_find_server_by_id(server->global_list,
1687                                            sender_id, TRUE, NULL);
1688     if (!router)
1689       router = silc_idlist_find_server_by_id(server->local_list,
1690                                              sender_id, TRUE, NULL);
1691     silc_free(sender_id);
1692     if (!router)
1693       goto out;
1694     router_sock = sock;
1695   }
1696
1697   switch(id_type) {
1698   case SILC_ID_CLIENT:
1699     {
1700       SilcClientEntry entry;
1701
1702       SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
1703                       silc_id_render(id, SILC_ID_CLIENT),
1704                       sock->type == SILC_SOCKET_TYPE_SERVER ?
1705                       "Server" : "Router", sock->hostname));
1706     
1707       /* As a router we keep information of all global information in our
1708          global list. Cell wide information however is kept in the local
1709          list. */
1710       entry = silc_idlist_add_client(id_list, NULL, NULL, NULL, 
1711                                      id, router, NULL);
1712       if (!entry) {
1713         SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
1714         goto out;
1715       }
1716       entry->nickname = NULL;
1717       entry->data.registered = TRUE;
1718
1719       if (sock->type == SILC_SOCKET_TYPE_SERVER)
1720         server->stat.cell_clients++;
1721       server->stat.clients++;
1722     }
1723     break;
1724
1725   case SILC_ID_SERVER:
1726     {
1727       SilcServerEntry entry;
1728
1729       /* If the ID is mine, ignore it. */
1730       if (SILC_ID_SERVER_COMPARE(id, server->id)) {
1731         SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
1732         break;
1733       }
1734       
1735       SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
1736                       silc_id_render(id, SILC_ID_SERVER),
1737                       sock->type == SILC_SOCKET_TYPE_SERVER ?
1738                       "Server" : "Router", sock->hostname));
1739       
1740       /* As a router we keep information of all global information in our 
1741          global list. Cell wide information however is kept in the local
1742          list. */
1743       entry = silc_idlist_add_server(id_list, NULL, 0, id, router, 
1744                                      router_sock);
1745       if (!entry) {
1746         SILC_LOG_ERROR(("Could not add new server to the ID Cache"));
1747         goto out;
1748       }
1749       entry->data.registered = TRUE;
1750       
1751       if (sock->type == SILC_SOCKET_TYPE_SERVER)
1752         server->stat.cell_servers++;
1753       server->stat.servers++;
1754     }
1755     break;
1756
1757   case SILC_ID_CHANNEL:
1758     SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
1759     break;
1760
1761   default:
1762     break;
1763   }
1764
1765  out:
1766   silc_id_payload_free(idp);
1767 }
1768
1769
1770 /* Processes incoming New ID packet. New ID Payload is used to distribute
1771    information about newly registered clients and servers. */
1772
1773 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
1774                         SilcPacketContext *packet)
1775 {
1776   silc_server_new_id_real(server, sock, packet, TRUE);
1777 }
1778
1779 /* Receoved New Id List packet, list of New ID payloads inside one
1780    packet. Process the New ID payloads one by one. */
1781
1782 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
1783                              SilcPacketContext *packet)
1784 {
1785   SilcPacketContext *new_id;
1786   SilcBuffer idp;
1787   uint16 id_len;
1788
1789   SILC_LOG_DEBUG(("Processing New ID List"));
1790
1791   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1792       packet->src_id_type != SILC_ID_SERVER)
1793     return;
1794
1795   /* If the sender of this packet is server and we are router we need to
1796      broadcast this packet to other routers in the network. Broadcast
1797      this list packet instead of multiple New ID packets. */
1798   if (!server->standalone && server->server_type == SILC_ROUTER &&
1799       sock->type == SILC_SOCKET_TYPE_SERVER &&
1800       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1801     SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
1802     silc_server_packet_send(server, server->router->connection,
1803                             packet->type, 
1804                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1805                             packet->buffer->data, packet->buffer->len, FALSE);
1806   }
1807
1808   /* Make copy of the original packet context, except for the actual
1809      data buffer, which we will here now fetch from the original buffer. */
1810   new_id = silc_packet_context_alloc();
1811   new_id->type = SILC_PACKET_NEW_ID;
1812   new_id->flags = packet->flags;
1813   new_id->src_id = packet->src_id;
1814   new_id->src_id_len = packet->src_id_len;
1815   new_id->src_id_type = packet->src_id_type;
1816   new_id->dst_id = packet->dst_id;
1817   new_id->dst_id_len = packet->dst_id_len;
1818   new_id->dst_id_type = packet->dst_id_type;
1819
1820   idp = silc_buffer_alloc(256);
1821   new_id->buffer = idp;
1822
1823   while (packet->buffer->len) {
1824     SILC_GET16_MSB(id_len, packet->buffer->data + 2);
1825     if ((id_len > packet->buffer->len) ||
1826         (id_len > idp->truelen))
1827       break;
1828
1829     silc_buffer_pull_tail(idp, 4 + id_len);
1830     silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
1831
1832     /* Process the New ID */
1833     silc_server_new_id_real(server, sock, new_id, FALSE);
1834
1835     silc_buffer_push_tail(idp, 4 + id_len);
1836     silc_buffer_pull(packet->buffer, 4 + id_len);
1837   }
1838
1839   silc_buffer_free(idp);
1840   silc_free(new_id);
1841 }
1842
1843 /* Received New Channel packet. Information about new channels in the 
1844    network are distributed using this packet. Save the information about
1845    the new channel. This usually comes from router but also normal server
1846    can send this to notify channels it has when it connects to us. */
1847
1848 void silc_server_new_channel(SilcServer server,
1849                              SilcSocketConnection sock,
1850                              SilcPacketContext *packet)
1851 {
1852   SilcChannelPayload payload;
1853   SilcChannelID *channel_id;
1854   char *channel_name;
1855   uint32 name_len;
1856   unsigned char *id;
1857   uint32 id_len;
1858   uint32 mode;
1859
1860   SILC_LOG_DEBUG(("Processing New Channel"));
1861
1862   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1863       packet->src_id_type != SILC_ID_SERVER ||
1864       server->server_type == SILC_SERVER)
1865     return;
1866
1867   /* Parse the channel payload */
1868   payload = silc_channel_payload_parse(packet->buffer);
1869   if (!payload)
1870     return;
1871     
1872   /* Get the channel ID */
1873   channel_id = silc_channel_get_id_parse(payload);
1874   if (!channel_id) {
1875     silc_channel_payload_free(payload);
1876     return;
1877   }
1878
1879   channel_name = silc_channel_get_name(payload, &name_len);
1880   if (name_len > 256)
1881     channel_name[255] = '\0';
1882
1883   id = silc_channel_get_id(payload, &id_len);
1884
1885   if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
1886     /* Add the channel to global list as it is coming from router. It 
1887        cannot be our own channel as it is coming from router. */
1888
1889     SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
1890                     silc_id_render(channel_id, SILC_ID_CHANNEL), 
1891                     sock->hostname));
1892     
1893     silc_idlist_add_channel(server->global_list, strdup(channel_name), 
1894                             0, channel_id, sock->user_data, NULL, NULL);
1895
1896     server->stat.channels++;
1897   } else {
1898     /* The channel is coming from our server, thus it is in our cell
1899        we will add it to our local list. */
1900     SilcChannelEntry channel;
1901     SilcBuffer chk;
1902
1903     SILC_LOG_DEBUG(("New channel id(%s) from [Server] %s",
1904                     silc_id_render(channel_id, SILC_ID_CHANNEL), 
1905                     sock->hostname));
1906     
1907     /* Check that we don't already have this channel */
1908     channel = silc_idlist_find_channel_by_name(server->local_list, 
1909                                                channel_name, NULL);
1910     if (!channel)
1911       channel = silc_idlist_find_channel_by_name(server->global_list, 
1912                                                  channel_name, NULL);
1913
1914     /* If the channel does not exist, then create it. We create the channel
1915        with the channel ID provided by the server. This creates a new
1916        key to the channel as well that we will send to the server. */
1917     if (!channel) {
1918       channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
1919                                                        channel_name,
1920                                                        channel_id, FALSE);
1921       if (!channel) {
1922         silc_channel_payload_free(payload);
1923         silc_free(channel_id);
1924         return;
1925       }
1926
1927       /* Get the mode and set it to the channel */
1928       channel->mode = silc_channel_get_mode(payload);
1929
1930       /* Send the new channel key to the server */
1931       chk = silc_channel_key_payload_encode(id_len, id,
1932                                             strlen(channel->channel_key->
1933                                                    cipher->name),
1934                                             channel->channel_key->cipher->name,
1935                                             channel->key_len / 8, 
1936                                             channel->key);
1937       silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
1938                               chk->data, chk->len, FALSE);
1939       silc_buffer_free(chk);
1940
1941     } else {
1942       /* The channel exist by that name, check whether the ID's match.
1943          If they don't then we'll force the server to use the ID we have.
1944          We also create a new key for the channel. */
1945       SilcBuffer users = NULL, users_modes = NULL;
1946
1947       if (!channel->id)
1948         channel_id = silc_id_dup(channel_id, SILC_ID_CHANNEL);
1949
1950       if (!SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
1951         /* They don't match, send CHANNEL_CHANGE notify to the server to
1952            force the ID change. */
1953         SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
1954         silc_server_send_notify_channel_change(server, sock, FALSE, 
1955                                                channel_id, channel->id);
1956       }
1957
1958       /* If the mode is different from what we have then enforce the
1959          mode change. */
1960       mode = silc_channel_get_mode(payload);
1961       if (channel->mode != mode) {
1962         SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
1963         silc_server_send_notify_cmode(server, sock, FALSE, channel,
1964                                       channel->mode, server->id,
1965                                       SILC_ID_SERVER,
1966                                       channel->cipher, channel->hmac_name);
1967       }
1968
1969       /* Create new key for the channel and send it to the server and
1970          everybody else possibly on the channel. */
1971
1972       if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
1973         if (!silc_server_create_channel_key(server, channel, 0))
1974           return;
1975         
1976         /* Send to the channel */
1977         silc_server_send_channel_key(server, sock, channel, FALSE);
1978         id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
1979         id_len = SILC_ID_CHANNEL_LEN;
1980         
1981         /* Send to the server */
1982         chk = silc_channel_key_payload_encode(id_len, id,
1983                                               strlen(channel->channel_key->
1984                                                      cipher->name),
1985                                               channel->channel_key->
1986                                               cipher->name,
1987                                               channel->key_len / 8, 
1988                                               channel->key);
1989         silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
1990                                 chk->data, chk->len, FALSE);
1991         silc_buffer_free(chk);
1992         silc_free(id);
1993       }
1994
1995       silc_free(channel_id);
1996
1997       /* Since the channel is coming from server and we also know about it
1998          then send the JOIN notify to the server so that it see's our
1999          users on the channel "joining" the channel. */
2000       silc_server_announce_get_channel_users(server, channel, &users,
2001                                              &users_modes);
2002       if (users) {
2003         silc_buffer_push(users, users->data - users->head);
2004         silc_server_packet_send(server, sock,
2005                                 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2006                                 users->data, users->len, FALSE);
2007         silc_buffer_free(users);
2008       }
2009       if (users_modes) {
2010         silc_buffer_push(users_modes, users_modes->data - users_modes->head);
2011         silc_server_packet_send_dest(server, sock,
2012                                      SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2013                                      channel->id, SILC_ID_CHANNEL,
2014                                      users_modes->data, 
2015                                      users_modes->len, FALSE);
2016         silc_buffer_free(users_modes);
2017       }
2018     }
2019   }
2020
2021   silc_channel_payload_free(payload);
2022 }
2023
2024 /* Received New Channel List packet, list of New Channel List payloads inside
2025    one packet. Process the New Channel payloads one by one. */
2026
2027 void silc_server_new_channel_list(SilcServer server,
2028                                   SilcSocketConnection sock,
2029                                   SilcPacketContext *packet)
2030 {
2031   SilcPacketContext *new;
2032   SilcBuffer buffer;
2033   uint16 len1, len2;
2034
2035   SILC_LOG_DEBUG(("Processing New Channel List"));
2036
2037   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2038       packet->src_id_type != SILC_ID_SERVER ||
2039       server->server_type == SILC_SERVER)
2040     return;
2041
2042   /* If the sender of this packet is server and we are router we need to
2043      broadcast this packet to other routers in the network. Broadcast
2044      this list packet instead of multiple New Channel packets. */
2045   if (!server->standalone && server->server_type == SILC_ROUTER &&
2046       sock->type == SILC_SOCKET_TYPE_SERVER &&
2047       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2048     SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
2049     silc_server_packet_send(server, server->router->connection,
2050                             packet->type, 
2051                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
2052                             packet->buffer->data, packet->buffer->len, FALSE);
2053   }
2054
2055   /* Make copy of the original packet context, except for the actual
2056      data buffer, which we will here now fetch from the original buffer. */
2057   new = silc_packet_context_alloc();
2058   new->type = SILC_PACKET_NEW_CHANNEL;
2059   new->flags = packet->flags;
2060   new->src_id = packet->src_id;
2061   new->src_id_len = packet->src_id_len;
2062   new->src_id_type = packet->src_id_type;
2063   new->dst_id = packet->dst_id;
2064   new->dst_id_len = packet->dst_id_len;
2065   new->dst_id_type = packet->dst_id_type;
2066
2067   buffer = silc_buffer_alloc(512);
2068   new->buffer = buffer;
2069
2070   while (packet->buffer->len) {
2071     SILC_GET16_MSB(len1, packet->buffer->data);
2072     if ((len1 > packet->buffer->len) ||
2073         (len1 > buffer->truelen))
2074       break;
2075
2076     SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
2077     if ((len2 > packet->buffer->len) ||
2078         (len2 > buffer->truelen))
2079       break;
2080
2081     silc_buffer_pull_tail(buffer, 8 + len1 + len2);
2082     silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
2083
2084     /* Process the New Channel */
2085     silc_server_new_channel(server, sock, new);
2086
2087     silc_buffer_push_tail(buffer, 8 + len1 + len2);
2088     silc_buffer_pull(packet->buffer, 8 + len1 + len2);
2089   }
2090
2091   silc_buffer_free(buffer);
2092   silc_free(new);
2093 }
2094
2095 /* Received key agreement packet. This packet is never for us. It is to
2096    the client in the packet's destination ID. Sending of this sort of packet
2097    equals sending private message, ie. it is sent point to point from
2098    one client to another. */
2099
2100 void silc_server_key_agreement(SilcServer server,
2101                                SilcSocketConnection sock,
2102                                SilcPacketContext *packet)
2103 {
2104   SilcSocketConnection dst_sock;
2105   SilcIDListData idata;
2106
2107   SILC_LOG_DEBUG(("Start"));
2108
2109   if (packet->src_id_type != SILC_ID_CLIENT ||
2110       packet->dst_id_type != SILC_ID_CLIENT)
2111     return;
2112
2113   if (!packet->dst_id)
2114     return;
2115
2116   /* Get the route to the client */
2117   dst_sock = silc_server_get_client_route(server, packet->dst_id,
2118                                           packet->dst_id_len, NULL, &idata);
2119   if (!dst_sock)
2120     return;
2121
2122   /* Relay the packet */
2123   silc_server_relay_packet(server, dst_sock, idata->send_key,
2124                            idata->hmac_send, packet, FALSE);
2125 }
2126
2127 /* Received connection auth request packet that is used during connection
2128    phase to resolve the mandatory authentication method.  This packet can
2129    actually be received at anytime but usually it is used only during
2130    the connection authentication phase. Now, protocol says that this packet
2131    can come from client or server, however, we support only this coming
2132    from client and expect that server's always knows what authentication
2133    method to use. */
2134
2135 void silc_server_connection_auth_request(SilcServer server,
2136                                          SilcSocketConnection sock,
2137                                          SilcPacketContext *packet)
2138 {
2139   SilcServerConfigSectionClientConnection *client = NULL;
2140   uint16 conn_type;
2141   int ret;
2142   SilcAuthMethod auth_meth;
2143
2144   SILC_LOG_DEBUG(("Start"));
2145
2146   if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT)
2147     return;
2148
2149   /* Parse the payload */
2150   ret = silc_buffer_unformat(packet->buffer,
2151                              SILC_STR_UI_SHORT(&conn_type),
2152                              SILC_STR_UI_SHORT(NULL),
2153                              SILC_STR_END);
2154   if (ret == -1)
2155     return;
2156
2157   if (conn_type != SILC_SOCKET_TYPE_CLIENT)
2158     return;
2159
2160   /* Get the authentication method for the client */
2161   auth_meth = SILC_AUTH_NONE;
2162   client = silc_server_config_find_client_conn(server->config,
2163                                                sock->ip,
2164                                                sock->port);
2165   if (!client)
2166     client = silc_server_config_find_client_conn(server->config,
2167                                                  sock->hostname,
2168                                                  sock->port);
2169   if (client)
2170     auth_meth = client->auth_meth;
2171           
2172   /* Send it back to the client */
2173   silc_server_send_connection_auth_request(server, sock,
2174                                            conn_type,
2175                                            auth_meth);
2176 }
2177
2178 /* Received REKEY packet. The sender of the packet wants to regenerate
2179    its session keys. This starts the REKEY protocol. */
2180
2181 void silc_server_rekey(SilcServer server,
2182                        SilcSocketConnection sock,
2183                        SilcPacketContext *packet)
2184 {
2185   SilcProtocol protocol;
2186   SilcServerRekeyInternalContext *proto_ctx;
2187   SilcIDListData idata = (SilcIDListData)sock->user_data;
2188
2189   SILC_LOG_DEBUG(("Start"));
2190
2191   /* Allocate internal protocol context. This is sent as context
2192      to the protocol. */
2193   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
2194   proto_ctx->server = (void *)server;
2195   proto_ctx->sock = sock;
2196   proto_ctx->responder = TRUE;
2197   proto_ctx->pfs = idata->rekey->pfs;
2198       
2199   /* Perform rekey protocol. Will call the final callback after the
2200      protocol is over. */
2201   silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY, 
2202                       &protocol, proto_ctx, silc_server_rekey_final);
2203   sock->protocol = protocol;
2204
2205   if (proto_ctx->pfs == FALSE)
2206     /* Run the protocol */
2207     silc_protocol_execute(protocol, server->schedule, 0, 0);
2208 }