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