updates.
[silc.git] / apps / silcd / packet_receive.c
1 /*
2
3   packet_receive.c
4
5   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
6
7   Copyright (C) 1997 - 2001 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; either version 2 of the License, or
12   (at your option) any later version.
13   
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18
19 */
20 /*
21  * Server packet routines to handle received packets.
22  */
23 /* $Id$ */
24
25 #include "serverincludes.h"
26 #include "server_internal.h"
27
28 extern char *server_version;
29
30 /* Received notify packet. Server can receive notify packets from router. 
31    Server then relays the notify messages to clients if needed. */
32
33 void silc_server_notify(SilcServer server,
34                         SilcSocketConnection sock,
35                         SilcPacketContext *packet)
36 {
37   SilcNotifyPayload payload;
38   SilcNotifyType type;
39   SilcArgumentPayload args;
40   SilcChannelID *channel_id, *channel_id2;
41   SilcClientID *client_id, *client_id2;
42   SilcServerID *server_id;
43   SilcChannelEntry channel;
44   SilcClientEntry client;
45   SilcServerEntry server_entry;
46   SilcChannelClientEntry chl;
47   SilcIDCacheEntry cache;
48   SilcHashTableList htl;
49   uint32 mode;
50   unsigned char *tmp;
51   uint32 tmp_len;
52
53   SILC_LOG_DEBUG(("Start"));
54
55   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
56       packet->src_id_type != SILC_ID_SERVER)
57     return;
58
59   if (!packet->dst_id)
60     return;
61
62   /* If the packet is destined directly to a client then relay the packet
63      before processing it. */
64   if (packet->dst_id_type == SILC_ID_CLIENT) {
65     SilcIDListData idata;
66     SilcSocketConnection dst_sock;
67
68     /* Get the route to the client */
69     dst_sock = silc_server_get_client_route(server, packet->dst_id,
70                                             packet->dst_id_len, NULL, &idata);
71     if (dst_sock)
72       /* Relay the packet */
73       silc_server_relay_packet(server, dst_sock, idata->send_key,
74                                idata->hmac_receive, packet, TRUE);
75   }
76
77   /* If we are router and this packet is not already broadcast packet
78      we will broadcast it. The sending socket really cannot be router or
79      the router is buggy. If this packet is coming from router then it must
80      have the broadcast flag set already and we won't do anything. */
81   if (!server->standalone && server->server_type == SILC_ROUTER &&
82       sock->type == SILC_SOCKET_TYPE_SERVER &&
83       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
84     SILC_LOG_DEBUG(("Broadcasting received Notify packet"));
85     silc_server_packet_send(server, server->router->connection, packet->type,
86                             packet->flags | SILC_PACKET_FLAG_BROADCAST, 
87                             packet->buffer->data, packet->buffer->len, FALSE);
88   }
89
90   payload = silc_notify_payload_parse(packet->buffer);
91   if (!payload)
92     return;
93
94   type = silc_notify_get_type(payload);
95   args = silc_notify_get_args(payload);
96   if (!args)
97     goto out;
98
99   switch(type) {
100   case SILC_NOTIFY_TYPE_JOIN:
101     /* 
102      * Distribute the notify to local clients on the channel
103      */
104     SILC_LOG_DEBUG(("JOIN notify"));
105
106     /* Get Channel ID */
107     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
108     if (!tmp)
109       goto out;
110     channel_id = silc_id_payload_parse_id(tmp, tmp_len);
111     if (!channel_id)
112       goto out;
113
114     /* Get channel entry */
115     channel = silc_idlist_find_channel_by_id(server->global_list, 
116                                              channel_id, NULL);
117     if (!channel) {
118       channel = silc_idlist_find_channel_by_id(server->local_list, 
119                                                channel_id, NULL);
120       if (!channel) {
121         silc_free(channel_id);
122         goto out;
123       }
124     }
125     silc_free(channel_id);
126
127     /* Get client ID */
128     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
129     if (!tmp)
130       goto out;
131     client_id = silc_id_payload_parse_id(tmp, tmp_len);
132     if (!client_id)
133       goto out;
134
135     /* Send to channel */
136     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
137                                        FALSE, packet->buffer->data, 
138                                        packet->buffer->len, FALSE);
139
140     /* If the the client is not in local list we check global list (ie. the
141        channel will be global channel) and if it does not exist then create
142        entry for the client. */
143     client = silc_idlist_find_client_by_id(server->global_list, 
144                                            client_id, NULL);
145     if (!client) {
146       client = silc_idlist_find_client_by_id(server->local_list, 
147                                              client_id, NULL);
148       if (!client) {
149         /* If router did not find the client the it is bogus */
150         if (server->server_type == SILC_ROUTER)
151           goto out;
152
153         client = 
154           silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
155                                  silc_id_dup(client_id, SILC_ID_CLIENT), 
156                                  sock->user_data, NULL);
157         if (!client) {
158           silc_free(client_id);
159           goto out;
160         }
161
162         client->data.registered = TRUE;
163       }
164     }
165
166     /* Do not add client to channel if it is there already */
167     if (silc_server_client_on_channel(client, channel))
168       break;
169
170     if (server->server_type == SILC_SERVER && 
171         sock->type == SILC_SOCKET_TYPE_ROUTER)
172       /* The channel is global now */
173       channel->global_users = TRUE;
174
175     /* JOIN the global client to the channel (local clients (if router 
176        created the channel) is joined in the pending JOIN command). */
177     chl = silc_calloc(1, sizeof(*chl));
178     chl->client = client;
179     chl->channel = channel;
180     silc_hash_table_add(channel->user_list, client, chl);
181     silc_hash_table_add(client->channels, channel, chl);
182     silc_free(client_id);
183
184     break;
185
186   case SILC_NOTIFY_TYPE_LEAVE:
187     /* 
188      * Distribute the notify to local clients on the channel
189      */
190     SILC_LOG_DEBUG(("LEAVE notify"));
191
192     channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
193                                 packet->dst_id_type);
194     if (!channel_id)
195       goto out;
196
197     /* Get channel entry */
198     channel = silc_idlist_find_channel_by_id(server->global_list, 
199                                              channel_id, NULL);
200     if (!channel) { 
201       channel = silc_idlist_find_channel_by_id(server->local_list, 
202                                                channel_id, NULL);
203       if (!channel) {
204         silc_free(channel_id);
205         goto out;
206       }
207     }
208
209     /* Get client ID */
210     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
211     if (!tmp) {
212       silc_free(channel_id);
213       goto out;
214     }
215     client_id = silc_id_payload_parse_id(tmp, tmp_len);
216     if (!client_id) {
217       silc_free(channel_id);
218       goto out;
219     }
220
221     /* Send to channel */
222     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
223                                        FALSE, packet->buffer->data, 
224                                        packet->buffer->len, FALSE);
225
226     /* Get client entry */
227     client = silc_idlist_find_client_by_id(server->global_list, 
228                                            client_id, NULL);
229     if (!client) {
230       client = silc_idlist_find_client_by_id(server->local_list, 
231                                              client_id, NULL);
232       if (!client) {
233         silc_free(client_id);
234         silc_free(channel_id);
235         goto out;
236       }
237     }
238     silc_free(client_id);
239
240     /* Remove the user from channel */
241     silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
242     break;
243
244   case SILC_NOTIFY_TYPE_SIGNOFF:
245     /* 
246      * Distribute the notify to local clients on the channel
247      */
248     SILC_LOG_DEBUG(("SIGNOFF notify"));
249
250     /* Get client ID */
251     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
252     if (!tmp)
253       goto out;
254     client_id = silc_id_payload_parse_id(tmp, tmp_len);
255     if (!client_id)
256       goto out;
257
258     /* Get client entry */
259     client = silc_idlist_find_client_by_id(server->global_list, 
260                                            client_id, &cache);
261     if (!client) {
262       client = silc_idlist_find_client_by_id(server->local_list, 
263                                              client_id, &cache);
264       if (!client) {
265         silc_free(client_id);
266         goto out;
267       }
268     }
269     silc_free(client_id);
270
271     /* Get signoff message */
272     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
273     if (tmp_len > 128)
274       tmp = NULL;
275
276     /* Remove the client from all channels. */
277     silc_server_remove_from_channels(server, NULL, client, TRUE, tmp, FALSE);
278
279     client->data.registered = FALSE;
280     cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
281     break;
282
283   case SILC_NOTIFY_TYPE_TOPIC_SET:
284     /* 
285      * Distribute the notify to local clients on the channel
286      */
287
288     SILC_LOG_DEBUG(("TOPIC SET notify"));
289
290     channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
291                                 packet->dst_id_type);
292     if (!channel_id)
293       goto out;
294
295     /* Get channel entry */
296     channel = silc_idlist_find_channel_by_id(server->global_list, 
297                                              channel_id, NULL);
298     if (!channel) {
299       channel = silc_idlist_find_channel_by_id(server->local_list, 
300                                                channel_id, NULL);
301       if (!channel) {
302         silc_free(channel_id);
303         goto out;
304       }
305     }
306
307     /* Get the topic */
308     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
309     if (!tmp) {
310       silc_free(channel_id);
311       goto out;
312     }
313
314     if (channel->topic)
315       silc_free(channel->topic);
316     channel->topic = silc_calloc(tmp_len, sizeof(*channel->topic));
317     memcpy(channel->topic, tmp, tmp_len);
318
319     /* Send the same notify to the channel */
320     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
321                                        FALSE, packet->buffer->data, 
322                                        packet->buffer->len, FALSE);
323     silc_free(channel_id);
324     break;
325
326   case SILC_NOTIFY_TYPE_NICK_CHANGE:
327     {
328       /* 
329        * Distribute the notify to local clients on the channel
330        */
331       unsigned char *id, *id2;
332
333       SILC_LOG_DEBUG(("NICK CHANGE notify"));
334       
335       /* Get old client ID */
336       id = silc_argument_get_arg_type(args, 1, &tmp_len);
337       if (!id)
338         goto out;
339       client_id = silc_id_payload_parse_id(id, tmp_len);
340       if (!client_id)
341         goto out;
342       
343       /* Get new client ID */
344       id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
345       if (!id2)
346         goto out;
347       client_id2 = silc_id_payload_parse_id(id2, tmp_len);
348       if (!client_id2)
349         goto out;
350       
351       SILC_LOG_DEBUG(("Old Client ID id(%s)", 
352                       silc_id_render(client_id, SILC_ID_CLIENT)));
353       SILC_LOG_DEBUG(("New Client ID id(%s)", 
354                       silc_id_render(client_id2, SILC_ID_CLIENT)));
355
356       /* Replace the Client ID */
357       client = silc_idlist_replace_client_id(server->global_list, client_id,
358                                              client_id2);
359       if (!client)
360         client = silc_idlist_replace_client_id(server->local_list, client_id, 
361                                                client_id2);
362
363       if (client) {
364         /* The nickname is not valid anymore, set it NULL. This causes that
365            the nickname will be queried if someone wants to know it. */
366         if (client->nickname)
367           silc_free(client->nickname);
368         client->nickname = NULL;
369
370         /* Send the NICK_CHANGE notify type to local clients on the channels
371            this client is joined to. */
372         silc_server_send_notify_on_channels(server, NULL, client, 
373                                             SILC_NOTIFY_TYPE_NICK_CHANGE, 2,
374                                             id, tmp_len, 
375                                             id2, tmp_len);
376       }
377
378       silc_free(client_id);
379       if (!client)
380         silc_free(client_id2);
381       break;
382     }
383
384   case SILC_NOTIFY_TYPE_CMODE_CHANGE:
385     /* 
386      * Distribute the notify to local clients on the channel
387      */
388     
389     SILC_LOG_DEBUG(("CMODE CHANGE notify"));
390       
391     channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
392                                 packet->dst_id_type);
393     if (!channel_id)
394       goto out;
395
396     /* Get channel entry */
397     channel = silc_idlist_find_channel_by_id(server->global_list, 
398                                              channel_id, NULL);
399     if (!channel) {
400       channel = silc_idlist_find_channel_by_id(server->local_list, 
401                                                channel_id, NULL);
402       if (!channel) {
403         silc_free(channel_id);
404         goto out;
405       }
406     }
407
408     /* Send the same notify to the channel */
409     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
410                                        FALSE, packet->buffer->data, 
411                                        packet->buffer->len, FALSE);
412
413     /* Get the mode */
414     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
415     if (!tmp) {
416       silc_free(channel_id);
417       goto out;
418     }
419
420     SILC_GET32_MSB(mode, tmp);
421
422     /* If the channel had private keys set and the mode was removed then
423        we must re-generate and re-distribute a new channel key */
424     if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY &&
425         !(mode & SILC_CHANNEL_MODE_PRIVKEY)) {
426       /* Re-generate channel key */
427       silc_server_create_channel_key(server, channel, 0);
428       
429       /* Send the channel key. This sends it to our local clients and if
430          we are normal server to our router as well. */
431       silc_server_send_channel_key(server, NULL, channel, 
432                                    server->server_type == SILC_ROUTER ? 
433                                    FALSE : !server->standalone);
434     }
435
436     /* Change mode */
437     channel->mode = mode;
438     silc_free(channel_id);
439
440     /* Get the hmac */
441     tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
442     if (tmp) {
443       unsigned char hash[32];
444
445       if (channel->hmac)
446         silc_hmac_free(channel->hmac);
447       if (!silc_hmac_alloc(tmp, NULL, &channel->hmac))
448         goto out;
449
450       /* Set the HMAC key out of current channel key. The client must do
451          this locally. */
452       silc_hash_make(channel->hmac->hash, channel->key, channel->key_len / 8, 
453                      hash);
454       silc_hmac_set_key(channel->hmac, hash, 
455                         silc_hash_len(channel->hmac->hash));
456       memset(hash, 0, sizeof(hash));
457     }
458
459     break;
460
461   case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
462     /* 
463      * Distribute the notify to local clients on the channel
464      */
465
466     SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
467
468     channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
469                                 packet->dst_id_type);
470     if (!channel_id)
471       goto out;
472
473     /* Get channel entry */
474     channel = silc_idlist_find_channel_by_id(server->global_list, 
475                                              channel_id, NULL);
476     if (!channel) {
477       channel = silc_idlist_find_channel_by_id(server->local_list, 
478                                                channel_id, NULL);
479       if (!channel) {
480         silc_free(channel_id);
481         goto out;
482       }
483     }
484
485     /* Get the mode */
486     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
487     if (!tmp) {
488       silc_free(channel_id);
489       goto out;
490     }
491       
492     SILC_GET32_MSB(mode, tmp);
493
494     /* Get target client */
495     tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
496     if (!tmp)
497       goto out;
498     client_id = silc_id_payload_parse_id(tmp, tmp_len);
499     if (!client_id)
500       goto out;
501     
502     /* Get client entry */
503     client = silc_idlist_find_client_by_id(server->global_list, 
504                                            client_id, NULL);
505     if (!client) {
506       client = silc_idlist_find_client_by_id(server->local_list, 
507                                              client_id, NULL);
508       if (!client) {
509         silc_free(client_id);
510         goto out;
511       }
512     }
513     silc_free(client_id);
514
515     /* Get entry to the channel user list */
516     silc_hash_table_list(channel->user_list, &htl);
517     while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
518       SilcChannelClientEntry chl2 = NULL;
519
520       /* If the mode is channel founder and we already find a client 
521          to have that mode on the channel we will enforce the sender
522          to change the channel founder mode away. There can be only one
523          channel founder on the channel. */
524       if (server->server_type == SILC_ROUTER &&
525           mode & SILC_CHANNEL_UMODE_CHANFO &&
526           chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
527         silc_server_send_notify_cumode(server, sock, FALSE, channel,
528                                        (mode & (~SILC_CHANNEL_UMODE_CHANFO)),
529                                        server->id, SILC_ID_SERVER, 
530                                        client->id);
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 (memcmp(packet->dst_id, server->id_string, packet->dst_id_len)) {
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   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 original sender is
1208      not client (as it can be server as well) we don't do the check. */
1209   sender = silc_id_str2id(packet->src_id, packet->src_id_len, 
1210                           packet->src_id_type);
1211   if (!sender)
1212     goto out;
1213   if (packet->src_id_type == SILC_ID_CLIENT) {
1214     sender_entry = silc_idlist_find_client_by_id(server->local_list, 
1215                                                  sender, NULL);
1216     if (!sender_entry)
1217       sender_entry = silc_idlist_find_client_by_id(server->global_list, 
1218                                                    sender, NULL);
1219     if (!sender_entry || !silc_server_client_on_channel(sender_entry, 
1220                                                         channel)) {
1221       SILC_LOG_DEBUG(("Client not on channel"));
1222       goto out;
1223     }
1224   }
1225
1226   /* Distribute the packet to our local clients. This will send the
1227      packet for further routing as well, if needed. */
1228   silc_server_packet_relay_to_channel(server, sock, channel, sender,
1229                                       packet->src_id_type, sender_entry,
1230                                       packet->buffer->data,
1231                                       packet->buffer->len, FALSE);
1232
1233  out:
1234   if (sender)
1235     silc_free(sender);
1236   if (id)
1237     silc_free(id);
1238 }
1239
1240 /* Received channel key packet. We distribute the key to all of our locally
1241    connected clients on the channel. */
1242
1243 void silc_server_channel_key(SilcServer server,
1244                              SilcSocketConnection sock,
1245                              SilcPacketContext *packet)
1246 {
1247   SilcBuffer buffer = packet->buffer;
1248   SilcChannelEntry channel;
1249
1250   if (packet->src_id_type != SILC_ID_SERVER ||
1251       (server->server_type == SILC_ROUTER &&
1252        sock->type == SILC_SOCKET_TYPE_ROUTER))
1253     return;
1254
1255   /* Save the channel key */
1256   channel = silc_server_save_channel_key(server, buffer, NULL);
1257   if (!channel)
1258     return;
1259
1260   /* Distribute the key to everybody who is on the channel. If we are router
1261      we will also send it to locally connected servers. */
1262   silc_server_send_channel_key(server, sock, channel, FALSE);
1263 }
1264
1265 /* Received New Client packet and processes it.  Creates Client ID for the
1266    client. Client becomes registered after calling this functions. */
1267
1268 SilcClientEntry silc_server_new_client(SilcServer server,
1269                                        SilcSocketConnection sock,
1270                                        SilcPacketContext *packet)
1271 {
1272   SilcBuffer buffer = packet->buffer;
1273   SilcClientEntry client;
1274   SilcClientID *client_id;
1275   SilcBuffer reply;
1276   SilcIDListData idata;
1277   char *username = NULL, *realname = NULL, *id_string;
1278   uint32 id_len;
1279   int ret;
1280
1281   SILC_LOG_DEBUG(("Creating new client"));
1282
1283   if (sock->type != SILC_SOCKET_TYPE_CLIENT)
1284     return NULL;
1285
1286   /* Take client entry */
1287   client = (SilcClientEntry)sock->user_data;
1288   idata = (SilcIDListData)client;
1289
1290   /* Remove the old cache entry */
1291   if (!silc_idcache_del_by_context(server->local_list->clients, client)) {
1292     SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
1293     silc_server_disconnect_remote(server, sock, "Server closed connection: "
1294                                   "Unknown client");
1295     return NULL;
1296   }
1297
1298   /* Parse incoming packet */
1299   ret = silc_buffer_unformat(buffer,
1300                              SILC_STR_UI16_STRING_ALLOC(&username),
1301                              SILC_STR_UI16_STRING_ALLOC(&realname),
1302                              SILC_STR_END);
1303   if (ret == -1) {
1304     if (username)
1305       silc_free(username);
1306     if (realname)
1307       silc_free(realname);
1308     silc_server_disconnect_remote(server, sock, "Server closed connection: "
1309                                   "Incomplete client information");
1310     return NULL;
1311   }
1312
1313   if (!username) {
1314     silc_free(username);
1315     if (realname)
1316       silc_free(realname);
1317     silc_server_disconnect_remote(server, sock, "Server closed connection: "
1318                                   "Incomplete client information");
1319     return NULL;
1320   }
1321
1322   /* Create Client ID */
1323   silc_id_create_client_id(server->id, server->rng, server->md5hash,
1324                            username, &client_id);
1325
1326   if (strlen(username) > 128)
1327     username[127] = '\0';
1328
1329   /* Update client entry */
1330   idata->registered = TRUE;
1331   client->nickname = strdup(username);
1332   client->username = username;
1333   client->userinfo = realname ? realname : strdup(" ");
1334   client->id = client_id;
1335   id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
1336
1337   /* Add the client again to the ID cache */
1338   silc_idcache_add(server->local_list->clients, client->nickname,
1339                    client_id, client, FALSE);
1340
1341   /* Notify our router about new client on the SILC network */
1342   if (!server->standalone)
1343     silc_server_send_new_id(server, (SilcSocketConnection) 
1344                             server->router->connection, 
1345                             server->server_type == SILC_ROUTER ? TRUE : FALSE,
1346                             client->id, SILC_ID_CLIENT, id_len);
1347   
1348   /* Send the new client ID to the client. */
1349   id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
1350   reply = silc_buffer_alloc(2 + 2 + id_len);
1351   silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
1352   silc_buffer_format(reply,
1353                      SILC_STR_UI_SHORT(SILC_ID_CLIENT),
1354                      SILC_STR_UI_SHORT(id_len),
1355                      SILC_STR_UI_XNSTRING(id_string, id_len),
1356                      SILC_STR_END);
1357   silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0, 
1358                           reply->data, reply->len, FALSE);
1359   silc_free(id_string);
1360   silc_buffer_free(reply);
1361
1362   /* Send some nice info to the client */
1363   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1364                           ("Welcome to the SILC Network %s@%s",
1365                            username, sock->hostname));
1366   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1367                           ("Your host is %s, running version %s",
1368                            server->config->server_info->server_name,
1369                            server_version));
1370   if (server->server_type == SILC_ROUTER) {
1371     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1372                             ("There are %d clients on %d servers in SILC "
1373                              "Network", server->stat.clients,
1374                              server->stat.servers + 1));
1375     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1376                             ("There are %d clients on %d server in our cell",
1377                              server->stat.cell_clients,
1378                              server->stat.cell_servers + 1));
1379     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1380                             ("I have %d clients, %d channels, %d servers and "
1381                              "%d routers",
1382                              server->stat.my_clients, 
1383                              server->stat.my_channels,
1384                              server->stat.my_servers,
1385                              server->stat.my_routers));
1386     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1387                             ("%d server operators and %d router operators "
1388                              "online",
1389                              server->stat.my_server_ops,
1390                              server->stat.my_router_ops));
1391   } else {
1392     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1393                             ("I have %d clients and %d channels formed",
1394                              server->stat.my_clients,
1395                              server->stat.my_channels));
1396     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1397                             ("%d operators online",
1398                              server->stat.my_server_ops));
1399   }
1400   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1401                           ("Your connection is secured with %s cipher, "
1402                            "key length %d bits",
1403                            idata->send_key->cipher->name,
1404                            idata->send_key->cipher->key_len));
1405   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1406                           ("Your current nickname is %s",
1407                            client->nickname));
1408
1409   /* Send motd */
1410   silc_server_send_motd(server, sock);
1411
1412   return client;
1413 }
1414
1415 /* Create new server. This processes received New Server packet and
1416    saves the received Server ID. The server is our locally connected
1417    server thus we save all the information and save it to local list. 
1418    This funtion can be used by both normal server and router server.
1419    If normal server uses this it means that its router has connected
1420    to the server. If router uses this it means that one of the cell's
1421    servers is connected to the router. */
1422
1423 SilcServerEntry silc_server_new_server(SilcServer server,
1424                                        SilcSocketConnection sock,
1425                                        SilcPacketContext *packet)
1426 {
1427   SilcBuffer buffer = packet->buffer;
1428   SilcServerEntry new_server;
1429   SilcServerID *server_id;
1430   SilcIDListData idata;
1431   unsigned char *server_name, *id_string;
1432   uint16 id_len, name_len;
1433   int ret;
1434
1435   SILC_LOG_DEBUG(("Creating new server"));
1436
1437   if (sock->type != SILC_SOCKET_TYPE_SERVER &&
1438       sock->type != SILC_SOCKET_TYPE_ROUTER)
1439     return NULL;
1440
1441   /* Take server entry */
1442   new_server = (SilcServerEntry)sock->user_data;
1443   idata = (SilcIDListData)new_server;
1444
1445   /* Remove the old cache entry */
1446   silc_idcache_del_by_context(server->local_list->servers, new_server);
1447
1448   /* Parse the incoming packet */
1449   ret = silc_buffer_unformat(buffer,
1450                              SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
1451                              SILC_STR_UI16_NSTRING_ALLOC(&server_name, 
1452                                                          &name_len),
1453                              SILC_STR_END);
1454   if (ret == -1) {
1455     if (id_string)
1456       silc_free(id_string);
1457     if (server_name)
1458       silc_free(server_name);
1459     return NULL;
1460   }
1461
1462   if (id_len > buffer->len) {
1463     silc_free(id_string);
1464     silc_free(server_name);
1465     return NULL;
1466   }
1467
1468   if (name_len > 256)
1469     server_name[255] = '\0';
1470
1471   /* Get Server ID */
1472   server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
1473   if (!server_id) {
1474     silc_free(id_string);
1475     silc_free(server_name);
1476     return NULL;
1477   }
1478   silc_free(id_string);
1479
1480   /* Update server entry */
1481   idata->registered = TRUE;
1482   new_server->server_name = server_name;
1483   new_server->id = server_id;
1484
1485   /* Add again the entry to the ID cache. */
1486   silc_idcache_add(server->local_list->servers, server_name, server_id, 
1487                    server, FALSE);
1488
1489   /* Distribute the information about new server in the SILC network
1490      to our router. If we are normal server we won't send anything
1491      since this connection must be our router connection. */
1492   if (server->server_type == SILC_ROUTER && !server->standalone &&
1493       server->router->connection != sock)
1494     silc_server_send_new_id(server, server->router->connection,
1495                             TRUE, new_server->id, SILC_ID_SERVER, 
1496                             silc_id_get_len(server_id, SILC_ID_SERVER));
1497
1498   if (server->server_type == SILC_ROUTER)
1499     server->stat.cell_servers++;
1500
1501   return new_server;
1502 }
1503
1504 /* Processes incoming New ID packet. New ID Payload is used to distribute
1505    information about newly registered clients and servers. */
1506
1507 static void silc_server_new_id_real(SilcServer server, 
1508                                     SilcSocketConnection sock,
1509                                     SilcPacketContext *packet,
1510                                     int broadcast)
1511 {
1512   SilcBuffer buffer = packet->buffer;
1513   SilcIDList id_list;
1514   SilcServerEntry router;
1515   SilcSocketConnection router_sock;
1516   SilcIDPayload idp;
1517   SilcIdType id_type;
1518   void *id;
1519
1520   SILC_LOG_DEBUG(("Processing new ID"));
1521
1522   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1523       server->server_type == SILC_SERVER ||
1524       packet->src_id_type != SILC_ID_SERVER)
1525     return;
1526
1527   idp = silc_id_payload_parse(buffer);
1528   if (!idp)
1529     return;
1530
1531   id_type = silc_id_payload_get_type(idp);
1532
1533   /* Normal server cannot have other normal server connections */
1534   if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
1535     goto out;
1536
1537   id = silc_id_payload_get_id(idp);
1538   if (!id)
1539     goto out;
1540
1541   /* If the sender of this packet is server and we are router we need to
1542      broadcast this packet to other routers in the network. */
1543   if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
1544       sock->type == SILC_SOCKET_TYPE_SERVER &&
1545       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1546     SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
1547     silc_server_packet_send(server, server->router->connection,
1548                             packet->type, 
1549                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1550                             buffer->data, buffer->len, FALSE);
1551   }
1552
1553   if (sock->type == SILC_SOCKET_TYPE_SERVER)
1554     id_list = server->local_list;
1555   else
1556     id_list = server->global_list;
1557
1558   /* If the packet is coming from server then use the sender as the
1559      origin of the the packet. If it came from router then check the real
1560      sender of the packet and use that as the origin. */
1561   if (sock->type == SILC_SOCKET_TYPE_SERVER) {
1562     router_sock = sock;
1563     router = sock->user_data;
1564   } else {
1565     void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1566                                      packet->src_id_type);
1567     router = silc_idlist_find_server_by_id(server->global_list,
1568                                            sender_id, NULL);
1569     if (!router)
1570       router = silc_idlist_find_server_by_id(server->local_list,
1571                                              sender_id, NULL);
1572     silc_free(sender_id);
1573     if (!router)
1574       goto out;
1575     router_sock = sock;
1576   }
1577
1578   switch(id_type) {
1579   case SILC_ID_CLIENT:
1580     {
1581       SilcClientEntry entry;
1582
1583       SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
1584                       silc_id_render(id, SILC_ID_CLIENT),
1585                       sock->type == SILC_SOCKET_TYPE_SERVER ?
1586                       "Server" : "Router", sock->hostname));
1587     
1588       /* As a router we keep information of all global information in our
1589          global list. Cell wide information however is kept in the local
1590          list. */
1591       entry = silc_idlist_add_client(id_list, NULL, NULL, NULL, 
1592                                      id, router, NULL);
1593       entry->nickname = NULL;
1594       entry->data.registered = TRUE;
1595
1596       if (sock->type == SILC_SOCKET_TYPE_SERVER)
1597         server->stat.cell_clients++;
1598       server->stat.clients++;
1599     }
1600     break;
1601
1602   case SILC_ID_SERVER:
1603     /* If the ID is mine, ignore it. */
1604     if (SILC_ID_SERVER_COMPARE(id, server->id)) {
1605       SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
1606       break;
1607     }
1608
1609     SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
1610                     silc_id_render(id, SILC_ID_SERVER),
1611                     sock->type == SILC_SOCKET_TYPE_SERVER ?
1612                     "Server" : "Router", sock->hostname));
1613
1614     /* As a router we keep information of all global information in our global
1615        list. Cell wide information however is kept in the local list. */
1616     silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
1617
1618     if (sock->type == SILC_SOCKET_TYPE_SERVER)
1619       server->stat.cell_servers++;
1620     server->stat.servers++;
1621     break;
1622
1623   case SILC_ID_CHANNEL:
1624     SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
1625     break;
1626
1627   default:
1628     break;
1629   }
1630
1631  out:
1632   silc_id_payload_free(idp);
1633 }
1634
1635
1636 /* Processes incoming New ID packet. New ID Payload is used to distribute
1637    information about newly registered clients and servers. */
1638
1639 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
1640                         SilcPacketContext *packet)
1641 {
1642   silc_server_new_id_real(server, sock, packet, TRUE);
1643 }
1644
1645 /* Receoved New Id List packet, list of New ID payloads inside one
1646    packet. Process the New ID payloads one by one. */
1647
1648 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
1649                              SilcPacketContext *packet)
1650 {
1651   SilcPacketContext *new_id;
1652   SilcBuffer idp;
1653   uint16 id_len;
1654
1655   SILC_LOG_DEBUG(("Processing New ID List"));
1656
1657   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1658       packet->src_id_type != SILC_ID_SERVER)
1659     return;
1660
1661   /* If the sender of this packet is server and we are router we need to
1662      broadcast this packet to other routers in the network. Broadcast
1663      this list packet instead of multiple New ID packets. */
1664   if (!server->standalone && server->server_type == SILC_ROUTER &&
1665       sock->type == SILC_SOCKET_TYPE_SERVER &&
1666       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1667     SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
1668     silc_server_packet_send(server, server->router->connection,
1669                             packet->type, 
1670                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1671                             packet->buffer->data, packet->buffer->len, FALSE);
1672   }
1673
1674   /* Make copy of the original packet context, except for the actual
1675      data buffer, which we will here now fetch from the original buffer. */
1676   new_id = silc_packet_context_alloc();
1677   new_id->type = SILC_PACKET_NEW_ID;
1678   new_id->flags = packet->flags;
1679   new_id->src_id = packet->src_id;
1680   new_id->src_id_len = packet->src_id_len;
1681   new_id->src_id_type = packet->src_id_type;
1682   new_id->dst_id = packet->dst_id;
1683   new_id->dst_id_len = packet->dst_id_len;
1684   new_id->dst_id_type = packet->dst_id_type;
1685
1686   idp = silc_buffer_alloc(256);
1687   new_id->buffer = idp;
1688
1689   while (packet->buffer->len) {
1690     SILC_GET16_MSB(id_len, packet->buffer->data + 2);
1691     if ((id_len > packet->buffer->len) ||
1692         (id_len > idp->truelen))
1693       break;
1694
1695     silc_buffer_pull_tail(idp, 4 + id_len);
1696     silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
1697
1698     /* Process the New ID */
1699     silc_server_new_id_real(server, sock, new_id, FALSE);
1700
1701     silc_buffer_push_tail(idp, 4 + id_len);
1702     silc_buffer_pull(packet->buffer, 4 + id_len);
1703   }
1704
1705   silc_buffer_free(idp);
1706   silc_free(new_id);
1707 }
1708
1709 /* Received New Channel packet. Information about new channels in the 
1710    network are distributed using this packet. Save the information about
1711    the new channel. This usually comes from router but also normal server
1712    can send this to notify channels it has when it connects to us. */
1713
1714 void silc_server_new_channel(SilcServer server,
1715                              SilcSocketConnection sock,
1716                              SilcPacketContext *packet)
1717 {
1718   SilcChannelPayload payload;
1719   SilcChannelID *channel_id;
1720   char *channel_name;
1721   uint32 name_len;
1722   unsigned char *id;
1723   uint32 id_len;
1724   uint32 mode;
1725
1726   SILC_LOG_DEBUG(("Processing New Channel"));
1727
1728   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1729       packet->src_id_type != SILC_ID_SERVER ||
1730       server->server_type == SILC_SERVER)
1731     return;
1732
1733   /* Parse the channel payload */
1734   payload = silc_channel_payload_parse(packet->buffer);
1735   if (!payload)
1736     return;
1737     
1738   /* Get the channel ID */
1739   channel_id = silc_channel_get_id_parse(payload);
1740   if (!channel_id) {
1741     silc_channel_payload_free(payload);
1742     return;
1743   }
1744
1745   channel_name = silc_channel_get_name(payload, &name_len);
1746   if (name_len > 256)
1747     channel_name[255] = '\0';
1748
1749   id = silc_channel_get_id(payload, &id_len);
1750
1751   if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
1752     /* Add the server to global list as it is coming from router. It 
1753        cannot be our own channel as it is coming from router. */
1754
1755     SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
1756                     silc_id_render(channel_id, SILC_ID_CHANNEL), 
1757                     sock->hostname));
1758     
1759     silc_idlist_add_channel(server->global_list, strdup(channel_name), 
1760                             0, channel_id, server->router->connection, 
1761                             NULL, NULL);
1762
1763     server->stat.channels++;
1764   } else {
1765     /* The channel is coming from our server, thus it is in our cell
1766        we will add it to our local list. */
1767     SilcChannelEntry channel;
1768     SilcBuffer chk;
1769
1770     SILC_LOG_DEBUG(("New channel id(%s) from [Server] %s",
1771                     silc_id_render(channel_id, SILC_ID_CHANNEL), 
1772                     sock->hostname));
1773     
1774     /* Check that we don't already have this channel */
1775     channel = silc_idlist_find_channel_by_name(server->local_list, 
1776                                                channel_name, NULL);
1777     if (!channel)
1778       channel = silc_idlist_find_channel_by_name(server->global_list, 
1779                                                  channel_name, NULL);
1780
1781     /* If the channel does not exist, then create it. We create the channel
1782        with the channel ID provided by the server. This creates a new
1783        key to the channel as well that we will send to the server. */
1784     if (!channel) {
1785       channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
1786                                                        channel_name,
1787                                                        channel_id, FALSE);
1788       if (!channel) {
1789         silc_channel_payload_free(payload);
1790         silc_free(channel_id);
1791         return;
1792       }
1793
1794       /* Send the new channel key to the server */
1795       chk = silc_channel_key_payload_encode(id_len, id,
1796                                             strlen(channel->channel_key->
1797                                                    cipher->name),
1798                                             channel->channel_key->cipher->name,
1799                                             channel->key_len / 8, 
1800                                             channel->key);
1801       silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
1802                               chk->data, chk->len, FALSE);
1803       silc_buffer_free(chk);
1804
1805     } else {
1806       /* The channel exist by that name, check whether the ID's match.
1807          If they don't then we'll force the server to use the ID we have.
1808          We also create a new key for the channel. */
1809       SilcBuffer users = NULL, users_modes = NULL;
1810
1811       if (!channel->id)
1812         channel_id = silc_id_dup(channel_id, SILC_ID_CHANNEL);
1813
1814       if (!SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
1815         /* They don't match, send CHANNEL_CHANGE notify to the server to
1816            force the ID change. */
1817         SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
1818         silc_server_send_notify_channel_change(server, sock, FALSE, 
1819                                                channel_id, channel->id);
1820       }
1821
1822       /* If the mode is different from what we have then enforce the
1823          mode change. */
1824       mode = silc_channel_get_mode(payload);
1825       if (channel->mode != mode) {
1826         SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
1827         silc_server_send_notify_cmode(server, sock, FALSE, channel,
1828                                       channel->mode, server->id,
1829                                       SILC_ID_SERVER,
1830                                       channel->cipher, channel->hmac_name);
1831       }
1832
1833       /* Create new key for the channel and send it to the server and
1834          everybody else possibly on the channel. */
1835
1836       if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
1837         silc_server_create_channel_key(server, channel, 0);
1838         
1839         /* Send to the channel */
1840         silc_server_send_channel_key(server, sock, channel, FALSE);
1841         id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
1842         id_len = SILC_ID_CHANNEL_LEN;
1843         
1844         /* Send to the server */
1845         chk = silc_channel_key_payload_encode(id_len, id,
1846                                               strlen(channel->channel_key->
1847                                                      cipher->name),
1848                                               channel->channel_key->
1849                                               cipher->name,
1850                                               channel->key_len / 8, 
1851                                               channel->key);
1852         silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
1853                                 chk->data, chk->len, FALSE);
1854         silc_buffer_free(chk);
1855         silc_free(id);
1856       }
1857
1858       silc_free(channel_id);
1859
1860       /* Since the channel is coming from server and we also know about it
1861          then send the JOIN notify to the server so that it see's our
1862          users on the channel "joining" the channel. */
1863       silc_server_announce_get_channel_users(server, channel, &users,
1864                                              &users_modes);
1865       if (users) {
1866         silc_buffer_push(users, users->data - users->head);
1867         silc_server_packet_send(server, sock,
1868                                 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1869                                 users->data, users->len, FALSE);
1870         silc_buffer_free(users);
1871       }
1872       if (users_modes) {
1873         silc_buffer_push(users_modes, users_modes->data - users_modes->head);
1874         silc_server_packet_send(server, sock,
1875                                 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1876                                 users_modes->data, users_modes->len, FALSE);
1877         silc_buffer_free(users_modes);
1878       }
1879     }
1880   }
1881
1882   silc_channel_payload_free(payload);
1883 }
1884
1885 /* Received New Channel List packet, list of New Channel List payloads inside
1886    one packet. Process the New Channel payloads one by one. */
1887
1888 void silc_server_new_channel_list(SilcServer server,
1889                                   SilcSocketConnection sock,
1890                                   SilcPacketContext *packet)
1891 {
1892   SilcPacketContext *new;
1893   SilcBuffer buffer;
1894   uint16 len1, len2;
1895
1896   SILC_LOG_DEBUG(("Processing New Channel List"));
1897
1898   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1899       packet->src_id_type != SILC_ID_SERVER ||
1900       server->server_type == SILC_SERVER)
1901     return;
1902
1903   /* If the sender of this packet is server and we are router we need to
1904      broadcast this packet to other routers in the network. Broadcast
1905      this list packet instead of multiple New Channel packets. */
1906   if (!server->standalone && server->server_type == SILC_ROUTER &&
1907       sock->type == SILC_SOCKET_TYPE_SERVER &&
1908       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1909     SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
1910     silc_server_packet_send(server, server->router->connection,
1911                             packet->type, 
1912                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1913                             packet->buffer->data, packet->buffer->len, FALSE);
1914   }
1915
1916   /* Make copy of the original packet context, except for the actual
1917      data buffer, which we will here now fetch from the original buffer. */
1918   new = silc_packet_context_alloc();
1919   new->type = SILC_PACKET_NEW_CHANNEL;
1920   new->flags = packet->flags;
1921   new->src_id = packet->src_id;
1922   new->src_id_len = packet->src_id_len;
1923   new->src_id_type = packet->src_id_type;
1924   new->dst_id = packet->dst_id;
1925   new->dst_id_len = packet->dst_id_len;
1926   new->dst_id_type = packet->dst_id_type;
1927
1928   buffer = silc_buffer_alloc(512);
1929   new->buffer = buffer;
1930
1931   while (packet->buffer->len) {
1932     SILC_GET16_MSB(len1, packet->buffer->data);
1933     if ((len1 > packet->buffer->len) ||
1934         (len1 > buffer->truelen))
1935       break;
1936
1937     SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
1938     if ((len2 > packet->buffer->len) ||
1939         (len2 > buffer->truelen))
1940       break;
1941
1942     silc_buffer_pull_tail(buffer, 8 + len1 + len2);
1943     silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
1944
1945     /* Process the New Channel */
1946     silc_server_new_channel(server, sock, new);
1947
1948     silc_buffer_push_tail(buffer, 8 + len1 + len2);
1949     silc_buffer_pull(packet->buffer, 8 + len1 + len2);
1950   }
1951
1952   silc_buffer_free(buffer);
1953   silc_free(new);
1954 }
1955
1956 /* Received key agreement packet. This packet is never for us. It is to
1957    the client in the packet's destination ID. Sending of this sort of packet
1958    equals sending private message, ie. it is sent point to point from
1959    one client to another. */
1960
1961 void silc_server_key_agreement(SilcServer server,
1962                                SilcSocketConnection sock,
1963                                SilcPacketContext *packet)
1964 {
1965   SilcSocketConnection dst_sock;
1966   SilcIDListData idata;
1967
1968   SILC_LOG_DEBUG(("Start"));
1969
1970   if (packet->src_id_type != SILC_ID_CLIENT ||
1971       packet->dst_id_type != SILC_ID_CLIENT)
1972     return;
1973
1974   if (!packet->dst_id)
1975     return;
1976
1977   /* Get the route to the client */
1978   dst_sock = silc_server_get_client_route(server, packet->dst_id,
1979                                           packet->dst_id_len, NULL, &idata);
1980   if (!dst_sock)
1981     return;
1982
1983   /* Relay the packet */
1984   silc_server_relay_packet(server, dst_sock, idata->send_key,
1985                            idata->hmac_send, packet, FALSE);
1986 }
1987
1988 /* Received connection auth request packet that is used during connection
1989    phase to resolve the mandatory authentication method.  This packet can
1990    actually be received at anytime but usually it is used only during
1991    the connection authentication phase. Now, protocol says that this packet
1992    can come from client or server, however, we support only this coming
1993    from client and expect that server's always knows what authentication
1994    method to use. */
1995
1996 void silc_server_connection_auth_request(SilcServer server,
1997                                          SilcSocketConnection sock,
1998                                          SilcPacketContext *packet)
1999 {
2000   SilcServerConfigSectionClientConnection *client = NULL;
2001   uint16 conn_type;
2002   int ret;
2003   SilcAuthMethod auth_meth;
2004
2005   SILC_LOG_DEBUG(("Start"));
2006
2007   if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT)
2008     return;
2009
2010   /* Parse the payload */
2011   ret = silc_buffer_unformat(packet->buffer,
2012                              SILC_STR_UI_SHORT(&conn_type),
2013                              SILC_STR_UI_SHORT(NULL),
2014                              SILC_STR_END);
2015   if (ret == -1)
2016     return;
2017
2018   if (conn_type != SILC_SOCKET_TYPE_CLIENT)
2019     return;
2020
2021   /* Get the authentication method for the client */
2022   auth_meth = SILC_AUTH_NONE;
2023   client = silc_server_config_find_client_conn(server->config,
2024                                                sock->ip,
2025                                                sock->port);
2026   if (!client)
2027     client = silc_server_config_find_client_conn(server->config,
2028                                                  sock->hostname,
2029                                                  sock->port);
2030   if (client)
2031     auth_meth = client->auth_meth;
2032           
2033   /* Send it back to the client */
2034   silc_server_send_connection_auth_request(server, sock,
2035                                            conn_type,
2036                                            auth_meth);
2037 }
2038
2039 /* Received REKEY packet. The sender of the packet wants to regenerate
2040    its session keys. This starts the REKEY protocol. */
2041
2042 void silc_server_rekey(SilcServer server,
2043                        SilcSocketConnection sock,
2044                        SilcPacketContext *packet)
2045 {
2046   SilcProtocol protocol;
2047   SilcServerRekeyInternalContext *proto_ctx;
2048   SilcIDListData idata = (SilcIDListData)sock->user_data;
2049
2050   SILC_LOG_DEBUG(("Start"));
2051
2052   /* Allocate internal protocol context. This is sent as context
2053      to the protocol. */
2054   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
2055   proto_ctx->server = (void *)server;
2056   proto_ctx->sock = sock;
2057   proto_ctx->responder = TRUE;
2058   proto_ctx->pfs = idata->rekey->pfs;
2059       
2060   /* Perform rekey protocol. Will call the final callback after the
2061      protocol is over. */
2062   silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY, 
2063                       &protocol, proto_ctx, silc_server_rekey_final);
2064   sock->protocol = protocol;
2065
2066   if (proto_ctx->pfs == FALSE)
2067     /* Run the protocol */
2068     protocol->execute(server->timeout_queue, 0, protocol, sock->sock, 0, 0);
2069 }