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