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     return NULL;
1300   }
1301
1302   /* Parse incoming packet */
1303   ret = silc_buffer_unformat(buffer,
1304                              SILC_STR_UI16_STRING_ALLOC(&username),
1305                              SILC_STR_UI16_STRING_ALLOC(&realname),
1306                              SILC_STR_END);
1307   if (ret == -1) {
1308     if (username)
1309       silc_free(username);
1310     if (realname)
1311       silc_free(realname);
1312     return NULL;
1313   }
1314
1315   if (!username) {
1316     silc_free(username);
1317     if (realname)
1318       silc_free(realname);
1319     silc_server_disconnect_remote(server, sock, "Server closed connection: "
1320                                   "Incomplete client information");
1321     return NULL;
1322   }
1323
1324   /* Create Client ID */
1325   silc_id_create_client_id(server->id, server->rng, server->md5hash,
1326                            username, &client_id);
1327
1328   if (strlen(username) > 128)
1329     username[127] = '\0';
1330
1331   /* Update client entry */
1332   idata->registered = TRUE;
1333   client->nickname = strdup(username);
1334   client->username = username;
1335   client->userinfo = realname ? realname : strdup(" ");
1336   client->id = client_id;
1337
1338   /* Update the cache entry */
1339   cache->id = (void *)client_id;
1340   cache->type = SILC_ID_CLIENT;
1341   cache->data = username;
1342   cache->data_len = strlen(username);
1343   silc_idcache_sort_by_data(server->local_list->clients);
1344
1345   /* Notify our router about new client on the SILC network */
1346   if (!server->standalone)
1347     silc_server_send_new_id(server, (SilcSocketConnection) 
1348                             server->router->connection, 
1349                             server->server_type == SILC_ROUTER ? TRUE : FALSE,
1350                             client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
1351   
1352   /* Send the new client ID to the client. */
1353   id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
1354   reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
1355   silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
1356   silc_buffer_format(reply,
1357                      SILC_STR_UI_SHORT(SILC_ID_CLIENT),
1358                      SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
1359                      SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
1360                      SILC_STR_END);
1361   silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0, 
1362                           reply->data, reply->len, FALSE);
1363   silc_free(id_string);
1364   silc_buffer_free(reply);
1365
1366   /* Send some nice info to the client */
1367   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1368                           ("Welcome to the SILC Network %s@%s",
1369                            username, sock->hostname));
1370   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1371                           ("Your host is %s, running version %s",
1372                            server->config->server_info->server_name,
1373                            server_version));
1374   if (server->server_type == SILC_ROUTER) {
1375     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1376                             ("There are %d clients on %d servers in SILC "
1377                              "Network", server->stat.clients,
1378                              server->stat.servers + 1));
1379     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1380                             ("There are %d clients on %d server in our cell",
1381                              server->stat.cell_clients,
1382                              server->stat.cell_servers + 1));
1383     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1384                             ("I have %d clients, %d channels, %d servers and "
1385                              "%d routers",
1386                              server->stat.my_clients, 
1387                              server->stat.my_channels,
1388                              server->stat.my_servers,
1389                              server->stat.my_routers));
1390     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1391                             ("%d server operators and %d router operators "
1392                              "online",
1393                              server->stat.my_server_ops,
1394                              server->stat.my_router_ops));
1395   } else {
1396     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1397                             ("I have %d clients and %d channels formed",
1398                              server->stat.my_clients,
1399                              server->stat.my_channels));
1400     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1401                             ("%d operators online",
1402                              server->stat.my_server_ops));
1403   }
1404   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1405                           ("Your connection is secured with %s cipher, "
1406                            "key length %d bits",
1407                            idata->send_key->cipher->name,
1408                            idata->send_key->cipher->key_len));
1409   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1410                           ("Your current nickname is %s",
1411                            client->nickname));
1412
1413   /* Send motd */
1414   silc_server_send_motd(server, sock);
1415
1416   return client;
1417 }
1418
1419 /* Create new server. This processes received New Server packet and
1420    saves the received Server ID. The server is our locally connected
1421    server thus we save all the information and save it to local list. 
1422    This funtion can be used by both normal server and router server.
1423    If normal server uses this it means that its router has connected
1424    to the server. If router uses this it means that one of the cell's
1425    servers is connected to the router. */
1426
1427 SilcServerEntry silc_server_new_server(SilcServer server,
1428                                        SilcSocketConnection sock,
1429                                        SilcPacketContext *packet)
1430 {
1431   SilcBuffer buffer = packet->buffer;
1432   SilcServerEntry new_server;
1433   SilcIDCacheEntry cache;
1434   SilcServerID *server_id;
1435   SilcIDListData idata;
1436   unsigned char *server_name, *id_string;
1437   uint16 id_len, name_len;
1438   int ret;
1439
1440   SILC_LOG_DEBUG(("Creating new server"));
1441
1442   if (sock->type != SILC_SOCKET_TYPE_SERVER &&
1443       sock->type != SILC_SOCKET_TYPE_ROUTER)
1444     return NULL;
1445
1446   /* Take server entry */
1447   new_server = (SilcServerEntry)sock->user_data;
1448   idata = (SilcIDListData)new_server;
1449
1450   /* Fetch the old server cache entry so that we can update it. */
1451   if (!silc_idcache_find_by_context(server->local_list->servers,
1452                                     sock->user_data, &cache)) {
1453     SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
1454     return NULL;
1455   }
1456
1457   /* Parse the incoming packet */
1458   ret = silc_buffer_unformat(buffer,
1459                              SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
1460                              SILC_STR_UI16_NSTRING_ALLOC(&server_name, 
1461                                                          &name_len),
1462                              SILC_STR_END);
1463   if (ret == -1) {
1464     if (id_string)
1465       silc_free(id_string);
1466     if (server_name)
1467       silc_free(server_name);
1468     return NULL;
1469   }
1470
1471   if (id_len > buffer->len) {
1472     silc_free(id_string);
1473     silc_free(server_name);
1474     return NULL;
1475   }
1476
1477   if (name_len > 256)
1478     server_name[255] = '\0';
1479
1480   /* Get Server ID */
1481   server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
1482   if (!server_id) {
1483     silc_free(id_string);
1484     silc_free(server_name);
1485     return NULL;
1486   }
1487   silc_free(id_string);
1488
1489   /* Update client entry */
1490   idata->registered = TRUE;
1491   new_server->server_name = server_name;
1492   new_server->id = server_id;
1493
1494   /* Update the cache entry */
1495   cache->id = (void *)server_id;
1496   cache->type = SILC_ID_SERVER;
1497   cache->data = server_name;
1498   cache->data_len = strlen(server_name);
1499   silc_idcache_sort_by_data(server->local_list->servers);
1500
1501   /* Distribute the information about new server in the SILC network
1502      to our router. If we are normal server we won't send anything
1503      since this connection must be our router connection. */
1504   if (server->server_type == SILC_ROUTER && !server->standalone &&
1505       server->router->connection != sock)
1506     silc_server_send_new_id(server, server->router->connection,
1507                             TRUE, new_server->id, SILC_ID_SERVER, 
1508                             SILC_ID_SERVER_LEN);
1509
1510   if (server->server_type == SILC_ROUTER)
1511     server->stat.cell_servers++;
1512
1513   return new_server;
1514 }
1515
1516 /* Processes incoming New ID packet. New ID Payload is used to distribute
1517    information about newly registered clients and servers. */
1518
1519 static void silc_server_new_id_real(SilcServer server, 
1520                                     SilcSocketConnection sock,
1521                                     SilcPacketContext *packet,
1522                                     int broadcast)
1523 {
1524   SilcBuffer buffer = packet->buffer;
1525   SilcIDList id_list;
1526   SilcServerEntry router;
1527   SilcSocketConnection router_sock;
1528   SilcIDPayload idp;
1529   SilcIdType id_type;
1530   unsigned char *hash = NULL;
1531   void *id;
1532
1533   SILC_LOG_DEBUG(("Processing new ID"));
1534
1535   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1536       server->server_type == SILC_SERVER ||
1537       packet->src_id_type != SILC_ID_SERVER)
1538     return;
1539
1540   idp = silc_id_payload_parse(buffer);
1541   if (!idp)
1542     return;
1543
1544   id_type = silc_id_payload_get_type(idp);
1545
1546   /* Normal server cannot have other normal server connections */
1547   if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
1548     goto out;
1549
1550   id = silc_id_payload_get_id(idp);
1551   if (!id)
1552     goto out;
1553
1554   /* If the sender of this packet is server and we are router we need to
1555      broadcast this packet to other routers in the network. */
1556   if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
1557       sock->type == SILC_SOCKET_TYPE_SERVER &&
1558       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1559     SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
1560     silc_server_packet_send(server, server->router->connection,
1561                             packet->type, 
1562                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1563                             buffer->data, buffer->len, FALSE);
1564   }
1565
1566   if (sock->type == SILC_SOCKET_TYPE_SERVER)
1567     id_list = server->local_list;
1568   else
1569     id_list = server->global_list;
1570
1571   router_sock = sock;
1572   router = sock->user_data;
1573
1574   switch(id_type) {
1575   case SILC_ID_CLIENT:
1576     {
1577       SilcClientEntry entry;
1578
1579       SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
1580                       silc_id_render(id, SILC_ID_CLIENT),
1581                       sock->type == SILC_SOCKET_TYPE_SERVER ?
1582                       "Server" : "Router", sock->hostname));
1583     
1584       /* As a router we keep information of all global information in our
1585          global list. Cell wide information however is kept in the local
1586          list. The client is put to global list and we will take the hash
1587          value of the Client ID and save it to the ID Cache system for fast
1588          searching in the future. */
1589       hash = silc_calloc(sizeof(((SilcClientID *)id)->hash),
1590                          sizeof(unsigned char));
1591       memcpy(hash, ((SilcClientID *)id)->hash, 
1592              sizeof(((SilcClientID *)id)->hash));
1593       entry = silc_idlist_add_client(id_list, hash, 
1594                                      sizeof(((SilcClientID *)id)->hash),
1595                                      NULL, NULL, 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     SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
1607                     silc_id_render(id, SILC_ID_SERVER),
1608                     sock->type == SILC_SOCKET_TYPE_SERVER ?
1609                     "Server" : "Router", sock->hostname));
1610     
1611     /* As a router we keep information of all global information in our global
1612        list. Cell wide information however is kept in the local list. */
1613     silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
1614
1615     if (sock->type == SILC_SOCKET_TYPE_SERVER)
1616       server->stat.cell_servers++;
1617     server->stat.servers++;
1618     break;
1619
1620   case SILC_ID_CHANNEL:
1621     SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
1622     break;
1623
1624   default:
1625     break;
1626   }
1627
1628  out:
1629   silc_id_payload_free(idp);
1630 }
1631
1632
1633 /* Processes incoming New ID packet. New ID Payload is used to distribute
1634    information about newly registered clients and servers. */
1635
1636 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
1637                         SilcPacketContext *packet)
1638 {
1639   silc_server_new_id_real(server, sock, packet, TRUE);
1640 }
1641
1642 /* Receoved New Id List packet, list of New ID payloads inside one
1643    packet. Process the New ID payloads one by one. */
1644
1645 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
1646                              SilcPacketContext *packet)
1647 {
1648   SilcPacketContext *new_id;
1649   SilcBuffer idp;
1650   uint16 id_len;
1651
1652   SILC_LOG_DEBUG(("Processing New ID List"));
1653
1654   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1655       packet->src_id_type != SILC_ID_SERVER)
1656     return;
1657
1658   /* If the sender of this packet is server and we are router we need to
1659      broadcast this packet to other routers in the network. Broadcast
1660      this list packet instead of multiple New ID packets. */
1661   if (!server->standalone && server->server_type == SILC_ROUTER &&
1662       sock->type == SILC_SOCKET_TYPE_SERVER &&
1663       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1664     SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
1665     silc_server_packet_send(server, server->router->connection,
1666                             packet->type, 
1667                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1668                             packet->buffer->data, packet->buffer->len, FALSE);
1669   }
1670
1671   /* Make copy of the original packet context, except for the actual
1672      data buffer, which we will here now fetch from the original buffer. */
1673   new_id = silc_packet_context_alloc();
1674   new_id->type = SILC_PACKET_NEW_ID;
1675   new_id->flags = packet->flags;
1676   new_id->src_id = packet->src_id;
1677   new_id->src_id_len = packet->src_id_len;
1678   new_id->src_id_type = packet->src_id_type;
1679   new_id->dst_id = packet->dst_id;
1680   new_id->dst_id_len = packet->dst_id_len;
1681   new_id->dst_id_type = packet->dst_id_type;
1682
1683   idp = silc_buffer_alloc(256);
1684   new_id->buffer = idp;
1685
1686   while (packet->buffer->len) {
1687     SILC_GET16_MSB(id_len, packet->buffer->data + 2);
1688     if ((id_len > packet->buffer->len) ||
1689         (id_len > idp->truelen))
1690       break;
1691
1692     silc_buffer_pull_tail(idp, 4 + id_len);
1693     silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
1694
1695     /* Process the New ID */
1696     silc_server_new_id_real(server, sock, new_id, FALSE);
1697
1698     silc_buffer_push_tail(idp, 4 + id_len);
1699     silc_buffer_pull(packet->buffer, 4 + id_len);
1700   }
1701
1702   silc_buffer_free(idp);
1703   silc_free(new_id);
1704 }
1705
1706 /* Received New Channel packet. Information about new channels in the 
1707    network are distributed using this packet. Save the information about
1708    the new channel. This usually comes from router but also normal server
1709    can send this to notify channels it has when it connects to us. */
1710
1711 void silc_server_new_channel(SilcServer server,
1712                              SilcSocketConnection sock,
1713                              SilcPacketContext *packet)
1714 {
1715   SilcChannelPayload payload;
1716   SilcChannelID *channel_id;
1717   char *channel_name;
1718   uint32 name_len;
1719   unsigned char *id;
1720   uint32 id_len;
1721   uint32 mode;
1722
1723   SILC_LOG_DEBUG(("Processing New Channel"));
1724
1725   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1726       packet->src_id_type != SILC_ID_SERVER ||
1727       server->server_type == SILC_SERVER)
1728     return;
1729
1730   /* Parse the channel payload */
1731   payload = silc_channel_payload_parse(packet->buffer);
1732   if (!payload)
1733     return;
1734     
1735   /* Get the channel ID */
1736   channel_id = silc_channel_get_id_parse(payload);
1737   if (!channel_id) {
1738     silc_channel_payload_free(payload);
1739     return;
1740   }
1741
1742   channel_name = silc_channel_get_name(payload, &name_len);
1743   if (name_len > 256)
1744     channel_name[255] = '\0';
1745
1746   id = silc_channel_get_id(payload, &id_len);
1747
1748   if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
1749     /* Add the server to global list as it is coming from router. It 
1750        cannot be our own channel as it is coming from router. */
1751
1752     SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
1753                     silc_id_render(channel_id, SILC_ID_CHANNEL), 
1754                     sock->hostname));
1755     
1756     silc_idlist_add_channel(server->global_list, strdup(channel_name), 
1757                             0, channel_id, server->router->connection, 
1758                             NULL, NULL);
1759
1760     server->stat.channels++;
1761   } else {
1762     /* The channel is coming from our server, thus it is in our cell
1763        we will add it to our local list. */
1764     SilcChannelEntry channel;
1765     SilcBuffer chk;
1766
1767     SILC_LOG_DEBUG(("New channel id(%s) from [Server] %s",
1768                     silc_id_render(channel_id, SILC_ID_CHANNEL), 
1769                     sock->hostname));
1770     
1771     /* Check that we don't already have this channel */
1772     channel = silc_idlist_find_channel_by_name(server->local_list, 
1773                                                channel_name, NULL);
1774     if (!channel)
1775       channel = silc_idlist_find_channel_by_name(server->global_list, 
1776                                                  channel_name, NULL);
1777
1778     /* If the channel does not exist, then create it. We create the channel
1779        with the channel ID provided by the server. This creates a new
1780        key to the channel as well that we will send to the server. */
1781     if (!channel) {
1782       channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
1783                                                        channel_name,
1784                                                        channel_id, FALSE);
1785       if (!channel) {
1786         silc_channel_payload_free(payload);
1787         silc_free(channel_id);
1788         return;
1789       }
1790
1791       /* Send the new channel key to the server */
1792       chk = silc_channel_key_payload_encode(id_len, id,
1793                                             strlen(channel->channel_key->
1794                                                    cipher->name),
1795                                             channel->channel_key->cipher->name,
1796                                             channel->key_len / 8, 
1797                                             channel->key);
1798       silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
1799                               chk->data, chk->len, FALSE);
1800       silc_buffer_free(chk);
1801
1802     } else {
1803       /* The channel exist by that name, check whether the ID's match.
1804          If they don't then we'll force the server to use the ID we have.
1805          We also create a new key for the channel. */
1806       SilcBuffer users = NULL;
1807
1808       if (!channel->id)
1809         channel_id = silc_id_dup(channel_id, SILC_ID_CHANNEL);
1810
1811       if (SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
1812         /* They don't match, send CHANNEL_CHANGE notify to the server to
1813            force the ID change. */
1814         SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
1815         silc_server_send_notify_channel_change(server, sock, FALSE, 
1816                                                channel_id,
1817                                                channel->id, 
1818                                                SILC_ID_CHANNEL_LEN);
1819       }
1820
1821       /* If the mode is different from what we have then enforce the
1822          mode change. */
1823       mode = silc_channel_get_mode(payload);
1824       if (channel->mode != mode) {
1825         SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
1826         silc_server_send_notify_cmode(server, sock, FALSE, channel,
1827                                       channel->mode, server->id,
1828                                       SILC_ID_SERVER, SILC_ID_SERVER_LEN,
1829                                       channel->cipher, channel->hmac_name);
1830       }
1831
1832       /* Create new key for the channel and send it to the server and
1833          everybody else possibly on the channel. */
1834
1835       if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
1836         silc_server_create_channel_key(server, channel, 0);
1837         
1838         /* Send to the channel */
1839         silc_server_send_channel_key(server, sock, channel, FALSE);
1840         id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
1841         id_len = SILC_ID_CHANNEL_LEN;
1842         
1843         /* Send to the server */
1844         chk = silc_channel_key_payload_encode(id_len, id,
1845                                               strlen(channel->channel_key->
1846                                                      cipher->name),
1847                                               channel->channel_key->
1848                                               cipher->name,
1849                                               channel->key_len / 8, 
1850                                               channel->key);
1851         silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
1852                                 chk->data, chk->len, FALSE);
1853         silc_buffer_free(chk);
1854         silc_free(id);
1855       }
1856
1857       silc_free(channel_id);
1858
1859       /* Since the channel is coming from server and we also know about it
1860          then send the JOIN notify to the server so that it see's our
1861          users on the channel "joining" the channel. */
1862       silc_server_announce_get_channel_users(server, channel, &users);
1863       if (users) {
1864         silc_buffer_push(users, users->data - users->head);
1865         silc_server_packet_send(server, sock,
1866                                 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1867                                 users->data, users->len, FALSE);
1868         silc_buffer_free(users);
1869       }
1870     }
1871   }
1872
1873   silc_channel_payload_free(payload);
1874 }
1875
1876 /* Received New Channel List packet, list of New Channel List payloads inside
1877    one packet. Process the New Channel payloads one by one. */
1878
1879 void silc_server_new_channel_list(SilcServer server,
1880                                   SilcSocketConnection sock,
1881                                   SilcPacketContext *packet)
1882 {
1883   SilcPacketContext *new;
1884   SilcBuffer buffer;
1885   uint16 len1, len2;
1886
1887   SILC_LOG_DEBUG(("Processing New Channel List"));
1888
1889   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1890       packet->src_id_type != SILC_ID_SERVER ||
1891       server->server_type == SILC_SERVER)
1892     return;
1893
1894   /* If the sender of this packet is server and we are router we need to
1895      broadcast this packet to other routers in the network. Broadcast
1896      this list packet instead of multiple New Channel packets. */
1897   if (!server->standalone && server->server_type == SILC_ROUTER &&
1898       sock->type == SILC_SOCKET_TYPE_SERVER &&
1899       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1900     SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
1901     silc_server_packet_send(server, server->router->connection,
1902                             packet->type, 
1903                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1904                             packet->buffer->data, packet->buffer->len, FALSE);
1905   }
1906
1907   /* Make copy of the original packet context, except for the actual
1908      data buffer, which we will here now fetch from the original buffer. */
1909   new = silc_packet_context_alloc();
1910   new->type = SILC_PACKET_NEW_CHANNEL;
1911   new->flags = packet->flags;
1912   new->src_id = packet->src_id;
1913   new->src_id_len = packet->src_id_len;
1914   new->src_id_type = packet->src_id_type;
1915   new->dst_id = packet->dst_id;
1916   new->dst_id_len = packet->dst_id_len;
1917   new->dst_id_type = packet->dst_id_type;
1918
1919   buffer = silc_buffer_alloc(512);
1920   new->buffer = buffer;
1921
1922   while (packet->buffer->len) {
1923     SILC_GET16_MSB(len1, packet->buffer->data);
1924     if ((len1 > packet->buffer->len) ||
1925         (len1 > buffer->truelen))
1926       break;
1927
1928     SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
1929     if ((len2 > packet->buffer->len) ||
1930         (len2 > buffer->truelen))
1931       break;
1932
1933     silc_buffer_pull_tail(buffer, 8 + len1 + len2);
1934     silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
1935
1936     /* Process the New Channel */
1937     silc_server_new_channel(server, sock, new);
1938
1939     silc_buffer_push_tail(buffer, 8 + len1 + len2);
1940     silc_buffer_pull(packet->buffer, 8 + len1 + len2);
1941   }
1942
1943   silc_buffer_free(buffer);
1944   silc_free(new);
1945 }
1946
1947 /* Received key agreement packet. This packet is never for us. It is to
1948    the client in the packet's destination ID. Sending of this sort of packet
1949    equals sending private message, ie. it is sent point to point from
1950    one client to another. */
1951
1952 void silc_server_key_agreement(SilcServer server,
1953                                SilcSocketConnection sock,
1954                                SilcPacketContext *packet)
1955 {
1956   SilcSocketConnection dst_sock;
1957   SilcIDListData idata;
1958
1959   SILC_LOG_DEBUG(("Start"));
1960
1961   if (packet->src_id_type != SILC_ID_CLIENT ||
1962       packet->dst_id_type != SILC_ID_CLIENT)
1963     return;
1964
1965   if (!packet->dst_id)
1966     return;
1967
1968   /* Get the route to the client */
1969   dst_sock = silc_server_get_client_route(server, packet->dst_id,
1970                                           packet->dst_id_len, NULL, &idata);
1971   if (!dst_sock)
1972     return;
1973
1974   /* Relay the packet */
1975   silc_server_relay_packet(server, dst_sock, idata->send_key,
1976                            idata->hmac, packet, FALSE);
1977 }
1978
1979 /* Received connection auth request packet that is used during connection
1980    phase to resolve the mandatory authentication method.  This packet can
1981    actually be received at anytime but usually it is used only during
1982    the connection authentication phase. Now, protocol says that this packet
1983    can come from client or server, however, we support only this coming
1984    from client and expect that server's always knows what authentication
1985    method to use. */
1986
1987 void silc_server_connection_auth_request(SilcServer server,
1988                                          SilcSocketConnection sock,
1989                                          SilcPacketContext *packet)
1990 {
1991   SilcServerConfigSectionClientConnection *client = NULL;
1992   uint16 conn_type;
1993   int ret;
1994   SilcAuthMethod auth_meth;
1995
1996   SILC_LOG_DEBUG(("Start"));
1997
1998   if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT)
1999     return;
2000
2001   /* Parse the payload */
2002   ret = silc_buffer_unformat(packet->buffer,
2003                              SILC_STR_UI_SHORT(&conn_type),
2004                              SILC_STR_UI_SHORT(NULL),
2005                              SILC_STR_END);
2006   if (ret == -1)
2007     return;
2008
2009   if (conn_type != SILC_SOCKET_TYPE_CLIENT)
2010     return;
2011
2012   /* Get the authentication method for the client */
2013   auth_meth = SILC_AUTH_NONE;
2014   client = silc_server_config_find_client_conn(server->config,
2015                                                sock->ip,
2016                                                sock->port);
2017   if (!client)
2018     client = silc_server_config_find_client_conn(server->config,
2019                                                  sock->hostname,
2020                                                  sock->port);
2021   if (client)
2022     auth_meth = client->auth_meth;
2023           
2024   /* Send it back to the client */
2025   silc_server_send_connection_auth_request(server, sock,
2026                                            conn_type,
2027                                            auth_meth);
2028 }
2029
2030 /* Received REKEY packet. The sender of the packet wants to regenerate
2031    its session keys. This starts the REKEY protocol. */
2032
2033 void silc_server_rekey(SilcServer server,
2034                        SilcSocketConnection sock,
2035                        SilcPacketContext *packet)
2036 {
2037   SilcProtocol protocol;
2038   SilcServerRekeyInternalContext *proto_ctx;
2039
2040   SILC_LOG_DEBUG(("Start"));
2041
2042   /* Allocate internal protocol context. This is sent as context
2043      to the protocol. */
2044   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
2045   proto_ctx->server = (void *)server;
2046   proto_ctx->sock = sock;
2047   proto_ctx->responder = TRUE;
2048       
2049   /* Perform rekey protocol. Will call the final callback after the
2050      protocol is over. */
2051   silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY, 
2052                       &protocol, proto_ctx, silc_server_rekey_final);
2053   sock->protocol = protocol;
2054
2055   /* Run the protocol */
2056   protocol->execute(server->timeout_queue, 0, protocol, sock->sock, 0, 0);
2057 }