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