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