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