Memory leak fixes.
[silc.git] / apps / silcd / packet_receive.c
1 /*
2
3   packet_receive.c
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 1997 - 2002 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 /* Received notify packet. Server can receive notify packets from router. 
29    Server then relays the notify messages to clients if needed. */
30
31 void silc_server_notify(SilcServer server,
32                         SilcSocketConnection sock,
33                         SilcPacketContext *packet)
34 {
35   SilcNotifyPayload payload;
36   SilcNotifyType type;
37   SilcArgumentPayload args;
38   SilcChannelID *channel_id = NULL, *channel_id2;
39   SilcClientID *client_id, *client_id2;
40   SilcServerID *server_id;
41   SilcIdType id_type;
42   SilcChannelEntry channel = NULL;
43   SilcClientEntry client = NULL, client2 = NULL;
44   SilcServerEntry server_entry = NULL;
45   SilcChannelClientEntry chl;
46   SilcIDCacheEntry cache;
47   SilcHashTableList htl;
48   SilcUInt32 mode;
49   unsigned char *tmp;
50   SilcUInt32 tmp_len;
51   bool local;
52
53   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
54       packet->src_id_type != SILC_ID_SERVER || !packet->dst_id) {
55     SILC_LOG_DEBUG(("Bad notify packet received"));
56     return;
57   }
58
59   /* If the packet is destined directly to a client then relay the packet
60      before processing it. */
61   if (packet->dst_id_type == SILC_ID_CLIENT) {
62     SilcIDListData idata;
63     SilcSocketConnection dst_sock;
64
65     /* Get the route to the client */
66     dst_sock = silc_server_get_client_route(server, packet->dst_id,
67                                             packet->dst_id_len, NULL, 
68                                             &idata, NULL);
69     if (dst_sock)
70       /* Relay the packet */
71       silc_server_relay_packet(server, dst_sock, idata->send_key,
72                                idata->hmac_send, idata->psn_send++,
73                                packet, TRUE);
74   }
75
76   /* Parse the Notify Payload */
77   payload = silc_notify_payload_parse(packet->buffer->data,
78                                       packet->buffer->len);
79   if (!payload)
80     return;
81
82   /* If we are router and this packet is not already broadcast packet
83      we will broadcast it. The sending socket really cannot be router or
84      the router is buggy. If this packet is coming from router then it must
85      have the broadcast flag set already and we won't do anything. */
86   if (server->server_type == SILC_ROUTER &&
87       sock->type == SILC_SOCKET_TYPE_SERVER &&
88       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
89     SILC_LOG_DEBUG(("Broadcasting received Notify packet"));
90     if (packet->dst_id_type == SILC_ID_CHANNEL) {
91       /* Packet is destined to channel */
92       channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
93                                   packet->dst_id_type);
94       if (!channel_id)
95         goto out;
96
97       silc_server_packet_send_dest(server, SILC_PRIMARY_ROUTE(server), 
98                                    packet->type, packet->flags | 
99                                    SILC_PACKET_FLAG_BROADCAST, 
100                                    channel_id, SILC_ID_CHANNEL,
101                                    packet->buffer->data, 
102                                    packet->buffer->len, FALSE);
103       silc_server_backup_send_dest(server, sock->user_data, 
104                                    packet->type, packet->flags,
105                                    channel_id, SILC_ID_CHANNEL,
106                                    packet->buffer->data, packet->buffer->len, 
107                                    FALSE, TRUE);
108     } else {
109       /* Packet is destined to client or server */
110       silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server), 
111                               packet->type,
112                               packet->flags | SILC_PACKET_FLAG_BROADCAST, 
113                               packet->buffer->data, packet->buffer->len, 
114                               FALSE);
115       silc_server_backup_send(server, sock->user_data,
116                               packet->type, packet->flags,
117                               packet->buffer->data, packet->buffer->len, 
118                               FALSE, TRUE);
119     }
120   }
121
122   type = silc_notify_get_type(payload);
123   args = silc_notify_get_args(payload);
124   if (!args)
125     goto out;
126
127   switch(type) {
128   case SILC_NOTIFY_TYPE_JOIN:
129     /* 
130      * Distribute the notify to local clients on the channel
131      */
132     SILC_LOG_DEBUG(("JOIN notify"));
133
134     /* Get Channel ID */
135     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
136     if (!tmp)
137       goto out;
138     channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
139     if (!channel_id)
140       goto out;
141
142     /* Get channel entry */
143     channel = silc_idlist_find_channel_by_id(server->global_list, 
144                                              channel_id, NULL);
145     if (!channel) {
146       channel = silc_idlist_find_channel_by_id(server->local_list, 
147                                                channel_id, NULL);
148       if (!channel) {
149         SILC_LOG_DEBUG(("Notify for unknown channel"));
150         silc_free(channel_id);
151         goto out;
152       }
153     }
154     silc_free(channel_id);
155
156     /* Get client ID */
157     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
158     if (!tmp)
159       goto out;
160     client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
161     if (!client_id)
162       goto out;
163
164     /* If the the client is not in local list we check global list (ie. the
165        channel will be global channel) and if it does not exist then create
166        entry for the client. */
167     client = silc_idlist_find_client_by_id(server->global_list, 
168                                            client_id, server->server_type, 
169                                            NULL);
170     if (!client) {
171       client = silc_idlist_find_client_by_id(server->local_list, 
172                                              client_id, server->server_type,
173                                              NULL);
174       if (!client) {
175         /* If router did not find the client the it is bogus */
176         if (server->server_type != SILC_SERVER) {
177           silc_free(client_id);
178           goto out;
179         }
180
181         client = 
182           silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
183                                  silc_id_dup(client_id, SILC_ID_CLIENT), 
184                                  sock->user_data, NULL, 0);
185         if (!client) {
186           SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
187           silc_free(client_id);
188           goto out;
189         }
190
191         client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
192       }
193     }
194     silc_free(client_id);
195
196     /* Do not process the notify if the client is not registered */
197     if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
198       break;
199
200     /* Do not add client to channel if it is there already */
201     if (silc_server_client_on_channel(client, channel, NULL)) {
202       SILC_LOG_DEBUG(("Client already on channel %s",
203                       channel->channel_name));
204       break;
205     }
206
207     /* Send to channel */
208     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
209                                        FALSE, packet->buffer->data, 
210                                        packet->buffer->len, FALSE);
211
212     if (server->server_type != SILC_ROUTER && 
213         sock->type == SILC_SOCKET_TYPE_ROUTER)
214       /* The channel is global now */
215       channel->global_users = TRUE;
216
217     SILC_LOG_DEBUG(("Joining to channel %s", channel->channel_name));
218
219     /* JOIN the global client to the channel (local clients (if router 
220        created the channel) is joined in the pending JOIN command). */
221     chl = silc_calloc(1, sizeof(*chl));
222     chl->client = client;
223     chl->channel = channel;
224
225     if (server->server_type != SILC_ROUTER ||
226         sock->type == SILC_SOCKET_TYPE_ROUTER) {
227       /* If this is the first one on the channel then it is the founder of
228          the channel. This is done on normal server and on router if this
229          notify is coming from router */
230       if (!silc_hash_table_count(channel->user_list)) {
231         SILC_LOG_DEBUG(("Client %s is founder on channel",
232                         silc_id_render(chl->client->id, SILC_ID_CLIENT)));
233         chl->mode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
234       }
235     }
236
237     silc_hash_table_add(channel->user_list, client, chl);
238     silc_hash_table_add(client->channels, channel, chl);
239     channel->user_count++;
240     channel->disabled = FALSE;
241
242     /* Update statistics */
243     if (server->server_type == SILC_ROUTER) {
244       if (sock->type != SILC_SOCKET_TYPE_ROUTER)
245         server->stat.cell_chanclients++;
246       server->stat.chanclients++;
247     }
248
249     break;
250
251   case SILC_NOTIFY_TYPE_LEAVE:
252     /* 
253      * Distribute the notify to local clients on the channel
254      */
255     SILC_LOG_DEBUG(("LEAVE notify"));
256
257     if (!channel_id) {
258       channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
259                                   packet->dst_id_type);
260       if (!channel_id)
261         goto out;
262     }
263
264     /* Get channel entry */
265     channel = silc_idlist_find_channel_by_id(server->global_list, 
266                                              channel_id, NULL);
267     if (!channel) { 
268       channel = silc_idlist_find_channel_by_id(server->local_list, 
269                                                channel_id, NULL);
270       if (!channel) {
271         SILC_LOG_DEBUG(("Notify for unknown channel"));
272         silc_free(channel_id);
273         goto out;
274       }
275     }
276
277     /* Get client ID */
278     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
279     if (!tmp) {
280       silc_free(channel_id);
281       goto out;
282     }
283     client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
284     if (!client_id) {
285       silc_free(channel_id);
286       goto out;
287     }
288
289     /* Get client entry */
290     client = silc_idlist_find_client_by_id(server->global_list, 
291                                            client_id, TRUE, NULL);
292     if (!client) {
293       client = silc_idlist_find_client_by_id(server->local_list, 
294                                              client_id, TRUE, NULL);
295       if (!client) {
296         silc_free(client_id);
297         silc_free(channel_id);
298         goto out;
299       }
300     }
301     silc_free(client_id);
302
303     /* Check if on channel */
304     if (!silc_server_client_on_channel(client, channel, NULL))
305       break;
306
307     /* Send the leave notify to channel */
308     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
309                                        FALSE, packet->buffer->data, 
310                                        packet->buffer->len, FALSE);
311
312     /* Remove the user from channel */
313     silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
314     break;
315
316   case SILC_NOTIFY_TYPE_SIGNOFF:
317     /* 
318      * Distribute the notify to local clients on the channel
319      */
320     SILC_LOG_DEBUG(("SIGNOFF notify"));
321
322     /* Get client ID */
323     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
324     if (!tmp)
325       goto out;
326     client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
327     if (!client_id)
328       goto out;
329
330     /* Get client entry */
331     client = silc_idlist_find_client_by_id(server->global_list, 
332                                            client_id, TRUE, &cache);
333     if (!client) {
334       client = silc_idlist_find_client_by_id(server->local_list, 
335                                              client_id, TRUE, &cache);
336       if (!client) {
337         silc_free(client_id);
338         goto out;
339       }
340     }
341     silc_free(client_id);
342
343     /* Get signoff message */
344     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
345     if (tmp_len > 128)
346       tmp = NULL;
347
348     /* Update statistics */
349     server->stat.clients--;
350     if (server->stat.cell_clients)
351       server->stat.cell_clients--;
352     SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
353     SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
354     silc_schedule_task_del_by_context(server->schedule, client);
355
356     /* Remove the client from all channels. */
357     silc_server_remove_from_channels(server, NULL, client, TRUE, tmp, FALSE);
358
359     /* Check if anyone is watching this nickname */
360     if (server->server_type == SILC_ROUTER)
361       silc_server_check_watcher_list(server, client, NULL,
362                                      SILC_NOTIFY_TYPE_SIGNOFF);
363
364     /* Remove this client from watcher list if it is */
365     silc_server_del_from_watcher_list(server, client);
366
367     client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
368     cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
369     break;
370
371   case SILC_NOTIFY_TYPE_TOPIC_SET:
372     /* 
373      * Distribute the notify to local clients on the channel
374      */
375
376     SILC_LOG_DEBUG(("TOPIC SET notify"));
377
378     /* Get client ID */
379     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
380     if (!tmp)
381       goto out;
382     client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
383     if (!client_id)
384       goto out;
385
386     /* Get client entry */
387     if (id_type == SILC_ID_CLIENT) {
388       client = silc_idlist_find_client_by_id(server->global_list, 
389                                              client_id, TRUE, &cache);
390       if (!client) {
391         client = silc_idlist_find_client_by_id(server->local_list, 
392                                                client_id, TRUE, &cache);
393         if (!client) {
394           silc_free(client_id);
395           goto out;
396         }
397       }
398       silc_free(client_id);
399     }
400
401     /* Get the topic */
402     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
403     if (!tmp) {
404       silc_free(channel_id);
405       goto out;
406     }
407
408     if (!channel_id) {
409       channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
410                                   packet->dst_id_type);
411       if (!channel_id)
412         goto out;
413     }
414
415     /* Get channel entry */
416     channel = silc_idlist_find_channel_by_id(server->global_list, 
417                                              channel_id, NULL);
418     if (!channel) {
419       channel = silc_idlist_find_channel_by_id(server->local_list, 
420                                                channel_id, NULL);
421       if (!channel) {
422         SILC_LOG_DEBUG(("Notify for unknown channel"));
423         silc_free(channel_id);
424         goto out;
425       }
426     }
427     silc_free(channel_id);
428
429     if (channel->topic && !strcmp(channel->topic, tmp)) {
430       SILC_LOG_DEBUG(("Topic is already set and same"));
431       goto out;
432     }
433
434     if (client) {
435       /* Get user's channel entry and check that topic set is allowed. */
436       if (!silc_server_client_on_channel(client, channel, &chl))
437         goto out;
438       if (channel->mode & SILC_CHANNEL_MODE_TOPIC &&
439           !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
440           !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
441         SILC_LOG_DEBUG(("Topic change is not allowed"));
442         goto out;
443       }
444     }
445
446     /* Change the topic */
447     silc_free(channel->topic);
448     channel->topic = strdup(tmp);
449
450     /* Send the same notify to the channel */
451     silc_server_packet_send_to_channel(server, NULL, channel, packet->type, 
452                                        FALSE, packet->buffer->data, 
453                                        packet->buffer->len, FALSE);
454     break;
455
456   case SILC_NOTIFY_TYPE_NICK_CHANGE:
457     {
458       /* 
459        * Distribute the notify to local clients on the channel
460        */
461       unsigned char *id, *id2;
462       char *nickname;
463       SilcUInt32 nickname_len;
464
465       SILC_LOG_DEBUG(("NICK CHANGE notify"));
466       
467       /* Get old client ID */
468       id = silc_argument_get_arg_type(args, 1, &tmp_len);
469       if (!id)
470         goto out;
471       client_id = silc_id_payload_parse_id(id, tmp_len, NULL);
472       if (!client_id)
473         goto out;
474       
475       /* Get new client ID */
476       id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
477       if (!id2)
478         goto out;
479       client_id2 = silc_id_payload_parse_id(id2, tmp_len, NULL);
480       if (!client_id2) {
481         silc_free(client_id);
482         goto out;
483       }
484       
485       SILC_LOG_DEBUG(("Old Client ID id(%s)", 
486                       silc_id_render(client_id, SILC_ID_CLIENT)));
487       SILC_LOG_DEBUG(("New Client ID id(%s)", 
488                       silc_id_render(client_id2, SILC_ID_CLIENT)));
489
490       /* From protocol version 1.1 we also get the new nickname */
491       nickname = silc_argument_get_arg_type(args, 3, &nickname_len);;
492
493       /* Replace the Client ID */
494       client = silc_idlist_replace_client_id(server,
495                                              server->global_list, client_id,
496                                              client_id2, nickname);
497       if (!client)
498         client = silc_idlist_replace_client_id(server,
499                                                server->local_list, client_id, 
500                                                client_id2, nickname);
501
502       if (client) {
503         /* Send the NICK_CHANGE notify type to local clients on the channels
504            this client is joined to. */
505         silc_server_send_notify_on_channels(server, client, client,
506                                             SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
507                                             id, tmp_len, id2, tmp_len,
508                                             nickname, nickname ?
509                                             nickname_len : 0);
510       }
511
512       silc_free(client_id);
513       if (!client)
514         silc_free(client_id2);
515       break;
516     }
517
518   case SILC_NOTIFY_TYPE_CMODE_CHANGE:
519     /* 
520      * Distribute the notify to local clients on the channel
521      */
522
523     SILC_LOG_DEBUG(("CMODE CHANGE notify"));
524
525     /* Get client ID */
526     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
527     if (!tmp)
528       goto out;
529     client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
530     if (!client_id)
531       goto out;
532
533     /* Get client entry */
534     if (id_type == SILC_ID_CLIENT) {
535       client = silc_idlist_find_client_by_id(server->global_list, 
536                                              client_id, TRUE, &cache);
537       if (!client) {
538         client = silc_idlist_find_client_by_id(server->local_list, 
539                                                client_id, TRUE, &cache);
540         if (!client) {
541           silc_free(client_id);
542           goto out;
543         }
544       }
545       silc_free(client_id);
546     }
547
548     if (!channel_id) {
549       channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
550                                   packet->dst_id_type);
551       if (!channel_id)
552         goto out;
553     }
554
555     /* Get channel entry */
556     channel = silc_idlist_find_channel_by_id(server->global_list, 
557                                              channel_id, NULL);
558     if (!channel) {
559       channel = silc_idlist_find_channel_by_id(server->local_list, 
560                                                channel_id, NULL);
561       if (!channel) {
562         SILC_LOG_DEBUG(("Notify for unknown channel"));
563         silc_free(channel_id);
564         goto out;
565       }
566     }
567     silc_free(channel_id);
568
569     /* Get the mode */
570     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
571     if (!tmp)
572       goto out;
573     SILC_GET32_MSB(mode, tmp);
574
575     /* Check if mode changed */
576     if (channel->mode == mode) {
577       SILC_LOG_DEBUG(("Mode is changed already"));
578
579       /* If this mode change has founder mode then we'll enforce the
580          change so that the server gets the real founder public key */
581       if (server->server_type != SILC_SERVER &&
582           sock != SILC_PRIMARY_ROUTE(server) &&
583           mode & SILC_CHANNEL_MODE_FOUNDER_AUTH && channel->founder_key) {
584         SILC_LOG_DEBUG(("Sending founder public key to server"));
585         silc_server_send_notify_cmode(server, sock, FALSE, channel,
586                                       channel->mode, server->id,
587                                       SILC_ID_SERVER, channel->cipher,
588                                       channel->hmac_name,
589                                       channel->passphrase,
590                                       channel->founder_key);
591       }
592
593       /* If we received same mode from our primary check whether founder
594          mode and key in the notify is set.  We update the founder key
595          here since we may have wrong one */
596       if (server->server_type == SILC_SERVER &&
597           sock == SILC_PRIMARY_ROUTE(server) &&
598           mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
599         SILC_LOG_DEBUG(("Founder public key received from router"));
600         tmp = silc_argument_get_arg_type(args, 6, &tmp_len);
601         if (!tmp)
602           break;
603
604         if (channel->founder_key)
605           silc_pkcs_public_key_free(channel->founder_key);
606         channel->founder_key = NULL;
607         silc_pkcs_public_key_decode(tmp, tmp_len, &channel->founder_key);
608       }
609
610       break;
611     }
612
613     /* Get user's channel entry and check that mode change is allowed */
614     if (client) {
615       if (!silc_server_client_on_channel(client, channel, &chl))
616         goto out;
617       if (!silc_server_check_cmode_rights(server, channel, chl, mode)) {
618         SILC_LOG_DEBUG(("CMODE change is not allowed"));
619         silc_server_send_notify_cmode(server, sock, FALSE, channel,
620                                       channel->mode, server->id,
621                                       SILC_ID_SERVER, channel->cipher,
622                                       channel->hmac_name,
623                                       channel->passphrase,
624                                       channel->founder_key);
625         goto out;
626       }
627     } else {
628       /* Assure that server is not removing founder mode from us */
629       if (server->server_type == SILC_ROUTER &&
630           sock != SILC_PRIMARY_ROUTE(server) &&
631           channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH &&
632           !(mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
633         SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
634         silc_server_send_notify_cmode(server, sock, FALSE, channel,
635                                       channel->mode, server->id,
636                                       SILC_ID_SERVER, channel->cipher,
637                                       channel->hmac_name,
638                                       channel->passphrase,
639                                       channel->founder_key);
640         goto out;
641       }
642
643       /* If server is adding founder mode, check whether there is founder
644          on channel already and is not from this server */
645       if (server->server_type == SILC_ROUTER &&
646           sock != SILC_PRIMARY_ROUTE(server) &&
647           mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
648         silc_hash_table_list(channel->user_list, &htl);
649         while (silc_hash_table_get(&htl, NULL, (void *)&chl))
650           if (chl->mode & SILC_CHANNEL_UMODE_CHANFO &&
651               chl->client->router != sock->user_data) {
652             SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
653             silc_server_send_notify_cmode(server, sock, FALSE, channel,
654                                           channel->mode, server->id,
655                                           SILC_ID_SERVER, channel->cipher,
656                                           channel->hmac_name,
657                                           channel->passphrase,
658                                           channel->founder_key);
659             silc_hash_table_list_reset(&htl);
660             goto out;
661           }
662         silc_hash_table_list_reset(&htl);
663       }
664     }
665
666     /* If the channel had private keys set and the mode was removed then
667        we must re-generate and re-distribute a new channel key */
668     if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY &&
669         !(mode & SILC_CHANNEL_MODE_PRIVKEY)) {
670       /* Re-generate channel key */
671       if (!silc_server_create_channel_key(server, channel, 0))
672         goto out;
673       
674       /* Send the channel key. This sends it to our local clients and if
675          we are normal server to our router as well. */
676       silc_server_send_channel_key(server, NULL, channel, 
677                                    server->server_type == SILC_ROUTER ? 
678                                    FALSE : !server->standalone);
679     }
680
681     /* Get the hmac */
682     tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
683     if (tmp) {
684       unsigned char hash[32];
685
686       if (channel->hmac)
687         silc_hmac_free(channel->hmac);
688       if (!silc_hmac_alloc(tmp, NULL, &channel->hmac))
689         goto out;
690
691       /* Set the HMAC key out of current channel key. The client must do
692          this locally. */
693       silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, 
694                      channel->key_len / 8, hash);
695       silc_hmac_set_key(channel->hmac, hash, 
696                         silc_hash_len(silc_hmac_get_hash(channel->hmac)));
697       memset(hash, 0, sizeof(hash));
698     }
699
700     /* Get the passphrase */
701     tmp = silc_argument_get_arg_type(args, 5, &tmp_len);
702     if (tmp) {
703       silc_free(channel->passphrase);
704       channel->passphrase = silc_memdup(tmp, tmp_len);
705     }
706
707     /* Get founder public key */
708     tmp = silc_argument_get_arg_type(args, 6, &tmp_len);
709     if (tmp && mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
710       if (channel->founder_key)
711         silc_pkcs_public_key_free(channel->founder_key);
712       channel->founder_key = NULL;
713       silc_pkcs_public_key_decode(tmp, tmp_len, &channel->founder_key);
714
715       if (!channel->founder_key || 
716           (client && client->data.public_key && 
717            server->server_type == SILC_ROUTER &&
718            !silc_pkcs_public_key_compare(channel->founder_key,
719                                          client->data.public_key))) {
720         /* A really buggy server isn't checking public keys correctly.
721            It's not possible that the mode setter and founder wouldn't
722            have same public key. */
723         SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
724
725         mode &= ~SILC_CHANNEL_MODE_FOUNDER_AUTH;
726         silc_server_send_notify_cmode(server, sock, FALSE, channel,
727                                       mode, server->id, SILC_ID_SERVER,
728                                       channel->cipher, 
729                                       channel->hmac_name,
730                                       channel->passphrase, NULL);
731         if (channel->founder_key)
732           silc_pkcs_public_key_free(channel->founder_key);
733         channel->founder_key = NULL;
734       } else if (client && !client->data.public_key) {
735         client->data.public_key = 
736           silc_pkcs_public_key_copy(channel->founder_key);
737       }
738     }
739
740     if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH && !channel->founder_key &&
741         server->server_type == SILC_ROUTER) {
742       SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
743       mode &= ~SILC_CHANNEL_MODE_FOUNDER_AUTH;
744       silc_server_send_notify_cmode(server, sock, FALSE, channel,
745                                     mode, server->id, SILC_ID_SERVER,
746                                     channel->cipher, 
747                                     channel->hmac_name,
748                                     channel->passphrase, NULL);
749     }
750
751     /* Send the same notify to the channel */
752     silc_server_packet_send_to_channel(server, NULL, channel, packet->type, 
753                                        FALSE, packet->buffer->data, 
754                                        packet->buffer->len, FALSE);
755
756     /* Change mode */
757     channel->mode = mode;
758
759     if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) &&
760         channel->founder_key) {
761       silc_pkcs_public_key_free(channel->founder_key);
762       channel->founder_key = NULL;
763     }
764
765     break;
766
767   case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
768     {
769       /* 
770        * Distribute the notify to local clients on the channel
771        */
772       SilcChannelClientEntry chl2 = NULL;
773       bool notify_sent = FALSE;
774
775       SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
776
777       /* Get client ID */
778       tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
779       if (!tmp)
780         goto out;
781       client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
782       if (!client_id)
783         goto out;
784
785       /* Get client entry */
786       if (id_type == SILC_ID_CLIENT) {
787         client = silc_idlist_find_client_by_id(server->global_list, 
788                                                client_id, TRUE, &cache);
789         if (!client) {
790           client = silc_idlist_find_client_by_id(server->local_list, 
791                                                  client_id, TRUE, &cache);
792           if (!client) {
793             silc_free(client_id);
794             goto out;
795           }
796         }
797         silc_free(client_id);
798       }
799
800       if (!channel_id) {
801         channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
802                                     packet->dst_id_type);
803         if (!channel_id)
804           goto out;
805       }
806
807       /* Get channel entry */
808       channel = silc_idlist_find_channel_by_id(server->global_list, 
809                                                channel_id, NULL);
810       if (!channel) {
811         channel = silc_idlist_find_channel_by_id(server->local_list, 
812                                                  channel_id, NULL);
813         if (!channel) {
814           SILC_LOG_DEBUG(("Notify for unknown channel"));
815           silc_free(channel_id);
816           goto out;
817         }
818       }
819
820       /* Get the mode */
821       tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
822       if (!tmp) {
823         silc_free(channel_id);
824         goto out;
825       }
826       
827       SILC_GET32_MSB(mode, tmp);
828       
829       /* Get target client */
830       tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
831       if (!tmp)
832         goto out;
833       client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
834       if (!client_id)
835         goto out;
836       
837       /* Get client entry */
838       client2 = silc_idlist_find_client_by_id(server->global_list, 
839                                               client_id, TRUE, NULL);
840       if (!client2) {
841         client2 = silc_idlist_find_client_by_id(server->local_list, 
842                                                 client_id, TRUE, NULL);
843         if (!client2) {
844           silc_free(client_id);
845           goto out;
846         }
847       }
848       silc_free(client_id);
849
850       if (client) {
851         /* Check that sender is on channel */
852         if (!silc_server_client_on_channel(client, channel, &chl))
853           goto out;
854         
855         if (client != client2 && server->server_type == SILC_ROUTER) {
856           /* Sender must be operator */
857           if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
858               !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
859             SILC_LOG_DEBUG(("CUMODE change is not allowed"));
860             goto out;
861           }
862
863           if (!silc_server_client_on_channel(client2, channel, &chl))
864             goto out;
865
866           /* If target is founder mode change is not allowed. */
867           if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
868             SILC_LOG_DEBUG(("CUMODE change is not allowed"));
869             goto out;
870           }
871         }
872       }
873
874       /* Get target channel user entry */
875       if (!silc_server_client_on_channel(client2, channel, &chl))
876         goto out;
877
878       if (server->server_type == SILC_SERVER && chl->mode == mode) {
879         SILC_LOG_DEBUG(("Mode is changed already"));
880         break;
881       }
882
883       if (mode & SILC_CHANNEL_UMODE_CHANFO &&
884           !(chl->mode & SILC_CHANNEL_UMODE_CHANFO) &&
885           server->server_type == SILC_ROUTER &&
886           sock != SILC_PRIMARY_ROUTE(server)) {
887         SilcPublicKey founder_key = NULL;
888
889         /* If channel doesn't have founder auth mode then it's impossible
890            that someone would be getting founder rights with CUMODE command.
891            In that case there already either is founder or there isn't
892            founder at all on the channel. */
893         if (client && !(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
894           /* Force the mode to not have founder mode */
895           chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
896           silc_server_force_cumode_change(server, sock, channel, chl, mode);
897           notify_sent = TRUE;
898           break;
899         }
900
901         /* Get the founder of the channel and if found then this client
902            cannot be the founder since there already is one. */
903         silc_hash_table_list(channel->user_list, &htl);
904         while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
905           if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
906             /* If the founder on the channel is not the one whom has set
907                the founder mode, then it's possible that this CUMODE_CHANGE
908                is correct.  Due to netsplits it's possible that this
909                situation happens. */
910             if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) ||
911                 (channel->founder_key && chl2->client->data.public_key &&
912                  silc_pkcs_public_key_compare(
913                                         channel->founder_key,
914                                         chl2->client->data.public_key))) {
915               chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
916               silc_server_force_cumode_change(server, sock, channel,
917                                               chl, mode);
918               notify_sent = TRUE;
919             }
920             break;
921           }
922         silc_hash_table_list_reset(&htl);
923         if (!(mode & SILC_CHANNEL_UMODE_CHANFO))
924           break;
925
926         /* Founder not found of the channel.  Since the founder auth mode
927            is set on the channel now check whether this is the client that
928            originally set the mode. */
929
930         if (channel->founder_key) {
931           /* Get public key that must be present in notify */
932           tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
933           if (!tmp || !silc_pkcs_public_key_decode(tmp, tmp_len,
934                                                    &founder_key)) {
935             chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
936             silc_server_force_cumode_change(server, sock, channel, chl, mode);
937             notify_sent = TRUE;
938             break;
939           }
940
941           /* Now match the public key we have cached and public key sent.
942              They must match. */
943           if (client && client->data.public_key && 
944               !silc_pkcs_public_key_compare(channel->founder_key,
945                                             client->data.public_key)) {
946             chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
947             silc_server_force_cumode_change(server, sock, channel, chl, mode);
948             notify_sent = TRUE;
949             break;
950           }
951           if (!silc_pkcs_public_key_compare(channel->founder_key,
952                                             founder_key)) {
953             chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
954             silc_server_force_cumode_change(server, sock, channel, chl, mode);
955             notify_sent = TRUE;
956             break;
957           }
958         }
959
960         /* There cannot be anyone else as founder on the channel now.  This
961            client is definitely the founder due to this authentication */
962         silc_hash_table_list(channel->user_list, &htl);
963         while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
964           if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
965             chl2->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
966             silc_server_force_cumode_change(server, NULL, channel, chl2,
967                                             chl2->mode);
968             break;
969           }
970         silc_hash_table_list_reset(&htl);
971
972         if (founder_key)
973           silc_pkcs_public_key_free(founder_key);
974       }
975
976       if (server->server_type != SILC_SERVER && chl->mode == mode) {
977         SILC_LOG_DEBUG(("Mode is changed already"));
978         break;
979       }
980
981       SILC_LOG_DEBUG(("Changing %s channel user mode",
982                       chl->client->nickname ? chl->client->nickname :
983                       (unsigned char *)""));
984
985       /* Change the mode */
986       chl->mode = mode;
987
988       /* Send the same notify to the channel */
989       if (!notify_sent)
990         silc_server_packet_send_to_channel(server, NULL, channel,
991                                            packet->type,
992                                            FALSE, packet->buffer->data,
993                                            packet->buffer->len, FALSE);
994       
995       silc_free(channel_id);
996       break;
997     }
998
999   case SILC_NOTIFY_TYPE_INVITE:
1000
1001     if (packet->dst_id_type == SILC_ID_CLIENT)
1002       goto out;
1003
1004     SILC_LOG_DEBUG(("INVITE notify"));
1005
1006     /* Get Channel ID */
1007     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1008     if (!tmp)
1009       goto out;
1010     channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1011     if (!channel_id)
1012       goto out;
1013
1014     /* Get channel entry */
1015     channel = silc_idlist_find_channel_by_id(server->global_list, 
1016                                              channel_id, NULL);
1017     if (!channel) {
1018       channel = silc_idlist_find_channel_by_id(server->local_list, 
1019                                                channel_id, NULL);
1020       if (!channel) {
1021         SILC_LOG_DEBUG(("Notify for unknown channel"));
1022         silc_free(channel_id);
1023         goto out;
1024       }
1025     }
1026     silc_free(channel_id);
1027
1028     /* Get client ID */
1029     tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1030     if (!tmp)
1031       goto out;
1032     client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1033     if (!client_id)
1034       goto out;
1035
1036     /* Get client entry */
1037     client = silc_idlist_find_client_by_id(server->global_list, 
1038                                            client_id, TRUE, &cache);
1039     if (!client) {
1040       client = silc_idlist_find_client_by_id(server->local_list, 
1041                                              client_id, TRUE, &cache);
1042       if (!client) {
1043         silc_free(client_id);
1044         goto out;
1045       }
1046     }
1047     silc_free(client_id);
1048
1049     /* Get user's channel entry and check that inviting is allowed. */
1050     if (!silc_server_client_on_channel(client, channel, &chl))
1051       goto out;
1052     if (channel->mode & SILC_CHANNEL_MODE_INVITE &&
1053         !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
1054         !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1055       SILC_LOG_DEBUG(("Inviting is not allowed"));
1056       goto out;
1057     }
1058
1059     /* Get the added invite */
1060     tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
1061     if (tmp) {
1062       if (!channel->invite_list)
1063         channel->invite_list = silc_calloc(tmp_len + 2, 
1064                                            sizeof(*channel->invite_list));
1065       else
1066         channel->invite_list = silc_realloc(channel->invite_list, 
1067                                             sizeof(*channel->invite_list) * 
1068                                             (tmp_len + 
1069                                              strlen(channel->invite_list) + 
1070                                              2));
1071       if (tmp[tmp_len - 1] == ',')
1072         tmp[tmp_len - 1] = '\0';
1073       
1074       strncat(channel->invite_list, tmp, tmp_len);
1075       strncat(channel->invite_list, ",", 1);
1076     }
1077
1078     /* Get the deleted invite */
1079     tmp = silc_argument_get_arg_type(args, 5, &tmp_len);
1080     if (tmp && channel->invite_list) {
1081       char *start, *end, *n;
1082       
1083       if (!strncmp(channel->invite_list, tmp, 
1084                    strlen(channel->invite_list) - 1)) {
1085         silc_free(channel->invite_list);
1086         channel->invite_list = NULL;
1087       } else {
1088         start = strstr(channel->invite_list, tmp);
1089         if (start && strlen(start) >= tmp_len) {
1090           end = start + tmp_len;
1091           n = silc_calloc(strlen(channel->invite_list) - tmp_len, sizeof(*n));
1092           strncat(n, channel->invite_list, start - channel->invite_list);
1093           strncat(n, end + 1, ((channel->invite_list + 
1094                                 strlen(channel->invite_list)) - end) - 1);
1095           silc_free(channel->invite_list);
1096           channel->invite_list = n;
1097         }
1098       }
1099     }
1100
1101     break;
1102
1103   case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
1104     /*
1105      * Distribute to the local clients on the channel and change the
1106      * channel ID.
1107      */
1108
1109     SILC_LOG_DEBUG(("CHANNEL CHANGE"));
1110
1111     if (sock->type != SILC_SOCKET_TYPE_ROUTER)
1112       break;
1113
1114     /* Get the old Channel ID */
1115     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1116     if (!tmp)
1117       goto out;
1118     channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1119     if (!channel_id)
1120       goto out;
1121
1122     /* Get the channel entry */
1123     channel = silc_idlist_find_channel_by_id(server->local_list, 
1124                                              channel_id, NULL);
1125     if (!channel) {
1126       channel = silc_idlist_find_channel_by_id(server->global_list, 
1127                                                channel_id, NULL);
1128       if (!channel) {
1129         SILC_LOG_DEBUG(("Notify for unknown channel"));
1130         silc_free(channel_id);
1131         goto out;
1132       }
1133     }
1134
1135     /* Send the notify to the channel */
1136     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
1137                                        FALSE, packet->buffer->data, 
1138                                        packet->buffer->len, FALSE);
1139
1140     /* Get the new Channel ID */
1141     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1142     if (!tmp)
1143       goto out;
1144     channel_id2 = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1145     if (!channel_id2)
1146       goto out;
1147
1148     SILC_LOG_DEBUG(("Old Channel ID id(%s)", 
1149                     silc_id_render(channel_id, SILC_ID_CHANNEL)));
1150     SILC_LOG_DEBUG(("New Channel ID id(%s)", 
1151                     silc_id_render(channel_id2, SILC_ID_CHANNEL)));
1152
1153     /* Replace the Channel ID */
1154     if (!silc_idlist_replace_channel_id(server->local_list, channel_id,
1155                                         channel_id2))
1156       if (!silc_idlist_replace_channel_id(server->global_list, channel_id,
1157                                           channel_id2)) {
1158         silc_free(channel_id2);
1159         channel_id2 = NULL;
1160       }
1161
1162     if (channel_id2) {
1163       SilcBuffer modes = NULL, users = NULL, users_modes = NULL;
1164
1165       /* Re-announce this channel which ID was changed. */
1166       silc_server_send_new_channel(server, sock, FALSE, channel->channel_name,
1167                                    channel->id, 
1168                                    silc_id_get_len(channel->id, 
1169                                                    SILC_ID_CHANNEL),
1170                                    channel->mode);
1171
1172       /* Re-announce our clients on the channel as the ID has changed now */
1173       silc_server_announce_get_channel_users(server, channel, &modes, &users,
1174                                              &users_modes);
1175       if (users) {
1176         silc_buffer_push(users, users->data - users->head);
1177         silc_server_packet_send(server, sock,
1178                                 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1179                                 users->data, users->len, FALSE);
1180         silc_buffer_free(users);
1181       }
1182       if (modes) {
1183         silc_buffer_push(modes, modes->data - modes->head);
1184         silc_server_packet_send_dest(server, sock,
1185                                      SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1186                                      channel->id, SILC_ID_CHANNEL,
1187                                      modes->data, modes->len, FALSE);
1188         silc_buffer_free(modes);
1189       }
1190       if (users_modes) {
1191         silc_buffer_push(users_modes, users_modes->data - users_modes->head);
1192         silc_server_packet_send_dest(server, sock,
1193                                      SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1194                                      channel->id, SILC_ID_CHANNEL,
1195                                      users_modes->data, 
1196                                      users_modes->len, FALSE);
1197         silc_buffer_free(users_modes);
1198       }
1199
1200       /* Re-announce channel's topic */
1201       if (channel->topic) {
1202         silc_server_send_notify_topic_set(server, sock,
1203                                           server->server_type == SILC_ROUTER ?
1204                                           TRUE : FALSE, channel, 
1205                                           server->id, SILC_ID_SERVER,
1206                                           channel->topic);
1207       }
1208     }
1209
1210     silc_free(channel_id);
1211
1212     break;
1213
1214   case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
1215     /* 
1216      * Remove the server entry and all clients that this server owns.
1217      */
1218
1219     SILC_LOG_DEBUG(("SERVER SIGNOFF notify"));
1220
1221     /* Get Server ID */
1222     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1223     if (!tmp)
1224       goto out;
1225     server_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1226     if (!server_id)
1227       goto out;
1228
1229     /* Get server entry */
1230     server_entry = silc_idlist_find_server_by_id(server->global_list, 
1231                                                  server_id, TRUE, NULL);
1232     local = TRUE;
1233     if (!server_entry) {
1234       server_entry = silc_idlist_find_server_by_id(server->local_list, 
1235                                                    server_id, TRUE, NULL);
1236       local = TRUE;
1237       if (!server_entry) {
1238         /* If we are normal server then we might not have the server. Check
1239            whether router was kind enough to send the list of all clients
1240            that actually was to be removed. Remove them if the list is
1241            available. */
1242         if (server->server_type != SILC_ROUTER &&
1243             silc_argument_get_arg_num(args) > 1) {
1244           int i;
1245
1246           for (i = 1; i < silc_argument_get_arg_num(args); i++) {
1247             /* Get Client ID */
1248             tmp = silc_argument_get_arg_type(args, i + 1, &tmp_len);
1249             if (!tmp)
1250               continue;
1251             client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1252             if (!client_id)
1253               continue;
1254
1255             /* Get client entry */
1256             client = silc_idlist_find_client_by_id(server->global_list, 
1257                                                    client_id, TRUE, &cache);
1258             local = TRUE;
1259             if (!client) {
1260               client = silc_idlist_find_client_by_id(server->local_list, 
1261                                                      client_id, TRUE, &cache);
1262               local = FALSE;
1263               if (!client) {
1264                 silc_free(client_id);
1265                 continue;
1266               }
1267             }
1268             silc_free(client_id);
1269
1270             /* Update statistics */
1271             server->stat.clients--;
1272             if (server->stat.cell_clients)
1273               server->stat.cell_clients--;
1274             SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
1275             SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
1276
1277             /* Remove the client from all channels. */
1278             silc_server_remove_from_channels(server, NULL, client, 
1279                                              TRUE, NULL, FALSE);
1280
1281             /* Check if anyone is watching this nickname */
1282             if (server->server_type == SILC_ROUTER)
1283               silc_server_check_watcher_list(server, client, NULL,
1284                                              SILC_NOTIFY_TYPE_SERVER_SIGNOFF);
1285
1286             /* Remove this client from watcher list if it is */
1287             if (local)
1288               silc_server_del_from_watcher_list(server, client);
1289
1290             /* Remove the client */
1291             silc_idlist_del_data(client);
1292             silc_idlist_del_client(local ? server->local_list :
1293                                    server->global_list, client);
1294           }
1295         }
1296
1297         silc_free(server_id);
1298         goto out;
1299       }
1300     }
1301     silc_free(server_id);
1302
1303     /* Sending SERVER_SIGNOFF is not right way to signoff local connection */
1304     if (SILC_IS_LOCAL(server_entry))
1305       break;
1306
1307     /* Remove all servers that are originated from this server, and
1308        remove the clients of those servers too. */
1309     silc_server_remove_servers_by_server(server, server_entry, TRUE);
1310
1311     /* Remove the clients that this server owns as they will become
1312        invalid now too. */
1313     silc_server_remove_clients_by_server(server, server_entry->router,
1314                                          server_entry, TRUE);
1315     silc_server_backup_del(server, server_entry);
1316
1317     /* Remove the server entry */
1318     silc_idlist_del_server(local ? server->local_list :
1319                            server->global_list, server_entry);
1320
1321     /* Update statistics */
1322     if (server->server_type == SILC_ROUTER)
1323       server->stat.servers--;
1324
1325     break;
1326
1327   case SILC_NOTIFY_TYPE_KICKED:
1328     /* 
1329      * Distribute the notify to local clients on the channel
1330      */
1331     
1332     SILC_LOG_DEBUG(("KICKED notify"));
1333       
1334     if (!channel_id) {
1335       channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
1336                                   packet->dst_id_type);
1337       if (!channel_id)
1338         goto out;
1339     }
1340
1341     /* Get channel entry */
1342     channel = silc_idlist_find_channel_by_id(server->global_list, 
1343                                              channel_id, NULL);
1344     if (!channel) {
1345       channel = silc_idlist_find_channel_by_id(server->local_list, 
1346                                                channel_id, NULL);
1347       if (!channel) {
1348         SILC_LOG_DEBUG(("Notify for unknown channel"));
1349         silc_free(channel_id);
1350         goto out;
1351       }
1352     }
1353     silc_free(channel_id);
1354
1355     /* Get client ID */
1356     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1357     if (!tmp)
1358       goto out;
1359     client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1360     if (!client_id)
1361       goto out;
1362
1363     /* If the the client is not in local list we check global list */
1364     client = silc_idlist_find_client_by_id(server->global_list, 
1365                                            client_id, TRUE, NULL);
1366     if (!client) {
1367       client = silc_idlist_find_client_by_id(server->local_list, 
1368                                              client_id, TRUE, NULL);
1369       if (!client) {
1370         silc_free(client_id);
1371         goto out;
1372       }
1373     }
1374     silc_free(client_id);
1375
1376     /* If target is founder they cannot be kicked */
1377     if (!silc_server_client_on_channel(client, channel, &chl))
1378       goto out;
1379     if (chl->mode & SILC_CHANNEL_UMODE_CHANFO)
1380       goto out;
1381     
1382     /* From protocol version 1.1 we get the kicker's ID as well. */
1383     tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1384     if (tmp) {
1385       client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1386       if (!client_id)
1387         goto out;
1388
1389       /* If the the client is not in local list we check global list */
1390       client2 = silc_idlist_find_client_by_id(server->global_list, 
1391                                               client_id, TRUE, NULL);
1392       if (!client2) {
1393         client2 = silc_idlist_find_client_by_id(server->local_list, 
1394                                                 client_id, TRUE, NULL);
1395         if (!client2) {
1396           silc_free(client_id);
1397           goto out;
1398         }
1399       }
1400       silc_free(client_id);
1401
1402       /* Kicker must be operator on channel */
1403       if (!silc_server_client_on_channel(client2, channel, &chl))
1404         goto out;
1405       if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
1406           !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1407         SILC_LOG_DEBUG(("Kicking is not allowed"));
1408         goto out;
1409       }
1410     }
1411
1412     /* Send to channel */
1413     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
1414                                        FALSE, packet->buffer->data, 
1415                                        packet->buffer->len, FALSE);
1416
1417     /* Remove the client from channel */
1418     silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
1419
1420     break;
1421
1422   case SILC_NOTIFY_TYPE_KILLED:
1423     {
1424       /* 
1425        * Distribute the notify to local clients on channels
1426        */
1427       unsigned char *id, *comment;
1428       SilcUInt32 id_len, comment_len;
1429     
1430       SILC_LOG_DEBUG(("KILLED notify"));
1431       
1432       /* Get client ID */
1433       id = silc_argument_get_arg_type(args, 1, &id_len);
1434       if (!id)
1435         goto out;
1436       client_id = silc_id_payload_parse_id(id, id_len, NULL);
1437       if (!client_id)
1438         goto out;
1439
1440       /* If the the client is not in local list we check global list */
1441       client = silc_idlist_find_client_by_id(server->global_list, 
1442                                              client_id, TRUE, &cache);
1443       if (!client) {
1444         client = silc_idlist_find_client_by_id(server->local_list, 
1445                                                client_id, TRUE, &cache);
1446         if (!client) {
1447           silc_free(client_id);
1448           goto out;
1449         }
1450       }
1451       silc_free(client_id);
1452
1453       /* If the client is one of ours, then close the connection to the
1454          client now. This removes the client from all channels as well. */
1455       if (packet->dst_id_type == SILC_ID_CLIENT && client->connection) {
1456         sock = client->connection;
1457         silc_server_free_client_data(server, NULL, client, FALSE, NULL);
1458         silc_server_close_connection(server, sock);
1459         break;
1460       }
1461
1462       /* Get comment */
1463       comment = silc_argument_get_arg_type(args, 2, &comment_len);
1464       if (comment_len > 128)
1465         comment_len = 127;
1466
1467       /* From protocol version 1.1 we get the killer's ID as well. */
1468       tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1469       if (tmp) {
1470         client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
1471         if (!client_id)
1472           goto out;
1473
1474         if (id_type == SILC_ID_CLIENT) {
1475           /* If the the client is not in local list we check global list */
1476           client2 = silc_idlist_find_client_by_id(server->global_list, 
1477                                                   client_id, TRUE, NULL);
1478           if (!client2) {
1479             client2 = silc_idlist_find_client_by_id(server->local_list, 
1480                                                     client_id, TRUE, NULL);
1481             if (!client2) {
1482               silc_free(client_id);
1483               goto out;
1484             }
1485           }
1486           silc_free(client_id);
1487
1488           /* Killer must be router operator */
1489           if (server->server_type != SILC_SERVER &&
1490               !(client2->mode & SILC_UMODE_ROUTER_OPERATOR)) {
1491             SILC_LOG_DEBUG(("Killing is not allowed"));
1492             goto out;
1493           }
1494         }
1495       }
1496
1497       /* Send the notify to local clients on the channels except to the
1498          client who is killed. */
1499       silc_server_send_notify_on_channels(server, client, client,
1500                                           SILC_NOTIFY_TYPE_KILLED, 3,
1501                                           id, id_len, comment, comment_len,
1502                                           tmp, tmp_len);
1503
1504       /* Remove the client from all channels */
1505       silc_server_remove_from_channels(server, NULL, client, FALSE, NULL, 
1506                                        FALSE);
1507
1508       /* Check if anyone is watching this nickname */
1509       silc_server_check_watcher_list(server, client, NULL,
1510                                      SILC_NOTIFY_TYPE_KILLED);
1511
1512       /* Update statistics */
1513       server->stat.clients--;
1514       if (server->stat.cell_clients)
1515         server->stat.cell_clients--;
1516       SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
1517       SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
1518
1519       if (SILC_IS_LOCAL(client)) {
1520         server->stat.my_clients--;
1521         silc_schedule_task_del_by_context(server->schedule, client);
1522         silc_idlist_del_data(client);
1523         client->mode = 0;
1524       }
1525
1526       client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
1527       cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
1528       break;
1529     }
1530
1531   case SILC_NOTIFY_TYPE_UMODE_CHANGE:
1532     /*
1533      * Save the mode of the client.
1534      */
1535
1536     SILC_LOG_DEBUG(("UMODE_CHANGE notify"));
1537
1538     /* Get client ID */
1539     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1540     if (!tmp)
1541       goto out;
1542     client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1543     if (!client_id)
1544       goto out;
1545
1546     /* Get client entry */
1547     client = silc_idlist_find_client_by_id(server->global_list, 
1548                                            client_id, TRUE, NULL);
1549     if (!client) {
1550       client = silc_idlist_find_client_by_id(server->local_list, 
1551                                              client_id, TRUE, NULL);
1552       if (!client) {
1553         silc_free(client_id);
1554         goto out;
1555       }
1556     }
1557     silc_free(client_id);
1558
1559     /* Get the mode */
1560     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1561     if (!tmp)
1562       goto out;
1563     SILC_GET32_MSB(mode, tmp);
1564
1565     /* Remove internal resumed flag if client is marked detached now */
1566     if (mode & SILC_UMODE_DETACHED)
1567       client->data.status &= ~SILC_IDLIST_STATUS_RESUMED;
1568
1569     /* Update statistics */
1570     if (server->server_type == SILC_ROUTER) {
1571       if (mode & SILC_UMODE_GONE) {
1572         if (!(client->mode & SILC_UMODE_GONE))
1573           server->stat.aways++;
1574       } else {
1575         if (client->mode & SILC_UMODE_GONE)
1576           server->stat.aways--;
1577       }
1578       if (mode & SILC_UMODE_DETACHED) {
1579         if (!(client->mode & SILC_UMODE_DETACHED))
1580           server->stat.detached++;
1581       } else {
1582         if (client->mode & SILC_UMODE_DETACHED)
1583           server->stat.detached--;
1584       }
1585     }
1586     SILC_UMODE_STATS_UPDATE(server, SILC_UMODE_SERVER_OPERATOR);
1587     SILC_UMODE_STATS_UPDATE(router, SILC_UMODE_ROUTER_OPERATOR);
1588
1589     /* Change the mode */
1590     client->mode = mode;
1591
1592     /* Check if anyone is watching this nickname */
1593     if (server->server_type == SILC_ROUTER)
1594       silc_server_check_watcher_list(server, client, NULL,
1595                                      SILC_NOTIFY_TYPE_UMODE_CHANGE);
1596
1597     break;
1598
1599   case SILC_NOTIFY_TYPE_BAN:
1600     /*
1601      * Save the ban
1602      */
1603
1604     SILC_LOG_DEBUG(("BAN notify"));
1605     
1606     /* Get Channel ID */
1607     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1608     if (!tmp)
1609       goto out;
1610     channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1611     if (!channel_id)
1612       goto out;
1613     
1614     /* Get channel entry */
1615     channel = silc_idlist_find_channel_by_id(server->global_list, 
1616                                              channel_id, NULL);
1617     if (!channel) {
1618       channel = silc_idlist_find_channel_by_id(server->local_list, 
1619                                                channel_id, NULL);
1620       if (!channel) {
1621         SILC_LOG_DEBUG(("Notify for unknown channel"));
1622         silc_free(channel_id);
1623         goto out;
1624       }
1625     }
1626     silc_free(channel_id);
1627
1628     /* Get the new ban and add it to the ban list */
1629     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1630     if (tmp) {
1631       if (!channel->ban_list)
1632         channel->ban_list = silc_calloc(tmp_len + 2, 
1633                                         sizeof(*channel->ban_list));
1634       else
1635         channel->ban_list = silc_realloc(channel->ban_list, 
1636                                          sizeof(*channel->ban_list) * 
1637                                          (tmp_len + 
1638                                           strlen(channel->ban_list) + 2));
1639       strncat(channel->ban_list, tmp, tmp_len);
1640       strncat(channel->ban_list, ",", 1);
1641     }
1642
1643     /* Get the ban to be removed and remove it from the list */
1644     tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1645     if (tmp && channel->ban_list) {
1646       char *start, *end, *n;
1647       
1648       if (!strncmp(channel->ban_list, tmp, strlen(channel->ban_list) - 1)) {
1649         silc_free(channel->ban_list);
1650         channel->ban_list = NULL;
1651       } else {
1652         start = strstr(channel->ban_list, tmp);
1653         if (start && strlen(start) >= tmp_len) {
1654           end = start + tmp_len;
1655           n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
1656           strncat(n, channel->ban_list, start - channel->ban_list);
1657           strncat(n, end + 1, ((channel->ban_list + 
1658                                 strlen(channel->ban_list)) - end) - 1);
1659           silc_free(channel->ban_list);
1660           channel->ban_list = n;
1661         }
1662       }
1663     }
1664     break;
1665
1666   case SILC_NOTIFY_TYPE_ERROR:
1667     {
1668       /*
1669        * Error notify
1670        */
1671       SilcStatus error;
1672
1673       tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1674       if (!tmp && tmp_len != 1)
1675         goto out;
1676       error = (SilcStatus)tmp[0];
1677
1678       SILC_LOG_DEBUG(("ERROR notify (%d)", error));
1679
1680       if (error == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID &&
1681           sock->type == SILC_SOCKET_TYPE_ROUTER) {
1682         tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1683         if (tmp) {
1684           SILC_LOG_DEBUG(("Received invalid client ID notification, deleting "
1685                           "the entry from cache"));
1686           client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1687           if (!client_id)
1688             goto out;
1689           client = silc_idlist_find_client_by_id(server->global_list, 
1690                                                  client_id, FALSE, NULL);
1691           if (client) {
1692             silc_server_remove_from_channels(server, NULL, client, TRUE, 
1693                                              NULL, TRUE);
1694             silc_idlist_del_data(client);
1695             silc_idlist_del_client(server->global_list, client);
1696           }
1697           silc_free(client_id);
1698         }
1699       }
1700     }
1701     break;
1702
1703     /* Ignore rest of the notify types for now */
1704   case SILC_NOTIFY_TYPE_NONE:
1705   case SILC_NOTIFY_TYPE_MOTD:
1706     break;
1707   default:
1708     break;
1709   }
1710
1711  out:
1712   silc_notify_payload_free(payload);
1713 }
1714
1715 void silc_server_notify_list(SilcServer server,
1716                              SilcSocketConnection sock,
1717                              SilcPacketContext *packet)
1718 {
1719   SilcPacketContext *new;
1720   SilcBuffer buffer;
1721   SilcUInt16 len;
1722
1723   SILC_LOG_DEBUG(("Processing Notify List"));
1724
1725   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1726       packet->src_id_type != SILC_ID_SERVER)
1727     return;
1728
1729   /* Make copy of the original packet context, except for the actual
1730      data buffer, which we will here now fetch from the original buffer. */
1731   new = silc_packet_context_alloc();
1732   new->type = SILC_PACKET_NOTIFY;
1733   new->flags = packet->flags;
1734   new->src_id = packet->src_id;
1735   new->src_id_len = packet->src_id_len;
1736   new->src_id_type = packet->src_id_type;
1737   new->dst_id = packet->dst_id;
1738   new->dst_id_len = packet->dst_id_len;
1739   new->dst_id_type = packet->dst_id_type;
1740
1741   buffer = silc_buffer_alloc(1024);
1742   new->buffer = buffer;
1743
1744   while (packet->buffer->len) {
1745     SILC_GET16_MSB(len, packet->buffer->data + 2);
1746     if (len > packet->buffer->len)
1747       break;
1748
1749     if (len > buffer->truelen) {
1750       silc_buffer_free(buffer);
1751       buffer = silc_buffer_alloc(1024 + len);
1752     }
1753
1754     silc_buffer_pull_tail(buffer, len);
1755     silc_buffer_put(buffer, packet->buffer->data, len);
1756
1757     /* Process the Notify */
1758     silc_server_notify(server, sock, new);
1759
1760     silc_buffer_push_tail(buffer, len);
1761     silc_buffer_pull(packet->buffer, len);
1762   }
1763
1764   silc_buffer_free(buffer);
1765   silc_free(new);
1766 }
1767
1768 /* Received private message. This resolves the destination of the message 
1769    and sends the packet. This is used by both server and router.  If the
1770    destination is our locally connected client this sends the packet to
1771    the client. This may also send the message for further routing if
1772    the destination is not in our server (or router). */
1773
1774 void silc_server_private_message(SilcServer server,
1775                                  SilcSocketConnection sock,
1776                                  SilcPacketContext *packet)
1777 {
1778   SilcSocketConnection dst_sock;
1779   SilcIDListData idata;
1780   SilcClientEntry client;
1781
1782   SILC_LOG_DEBUG(("Start"));
1783
1784   if (packet->src_id_type != SILC_ID_CLIENT ||
1785       packet->dst_id_type != SILC_ID_CLIENT || !packet->dst_id)
1786     return;
1787
1788   /* Get the route to the client */
1789   dst_sock = silc_server_get_client_route(server, packet->dst_id,
1790                                           packet->dst_id_len, NULL, 
1791                                           &idata, &client);
1792   if (!dst_sock) {
1793     SilcBuffer idp;
1794     unsigned char error;
1795
1796     if (client && client->mode & SILC_UMODE_DETACHED) {
1797       SILC_LOG_DEBUG(("Client is detached, discarding packet"));
1798       return;
1799     }
1800
1801     /* Send SILC_NOTIFY_TYPE_ERROR to indicate that such destination ID
1802        does not exist or is invalid. */
1803     idp = silc_id_payload_encode_data(packet->dst_id,
1804                                       packet->dst_id_len,
1805                                       packet->dst_id_type);
1806     if (!idp)
1807       return;
1808
1809     error = SILC_STATUS_ERR_NO_SUCH_CLIENT_ID;
1810     if (packet->src_id_type == SILC_ID_CLIENT) {
1811       SilcClientID *client_id = silc_id_str2id(packet->src_id,
1812                                                packet->src_id_len,
1813                                                packet->src_id_type);
1814       silc_server_send_notify_dest(server, sock, FALSE,
1815                                    client_id, SILC_ID_CLIENT,
1816                                    SILC_NOTIFY_TYPE_ERROR, 2,
1817                                    &error, 1,
1818                                    idp->data, idp->len);
1819       silc_free(client_id);
1820     } else {
1821       silc_server_send_notify(server, sock, FALSE,
1822                               SILC_NOTIFY_TYPE_ERROR, 2,
1823                               &error, 1,
1824                               idp->data, idp->len);
1825     }
1826
1827     silc_buffer_free(idp);
1828     return;
1829   }
1830
1831   /* Check whether destination client wishes to receive private messages */
1832   if (client && !(packet->flags & SILC_PACKET_FLAG_PRIVMSG_KEY) &&
1833       client->mode & SILC_UMODE_BLOCK_PRIVMSG) {
1834     SILC_LOG_DEBUG(("Client blocks private messages, discarding packet"));
1835     return;
1836   }
1837
1838   /* Send the private message */
1839   silc_server_send_private_message(server, dst_sock, idata->send_key,
1840                                    idata->hmac_send, idata->psn_send++,
1841                                    packet);
1842 }
1843
1844 /* Received private message key packet.. This packet is never for us. It is to
1845    the client in the packet's destination ID. Sending of this sort of packet
1846    equals sending private message, ie. it is sent point to point from
1847    one client to another. */
1848
1849 void silc_server_private_message_key(SilcServer server,
1850                                      SilcSocketConnection sock,
1851                                      SilcPacketContext *packet)
1852 {
1853   SilcSocketConnection dst_sock;
1854   SilcIDListData idata;
1855
1856   SILC_LOG_DEBUG(("Start"));
1857
1858   if (packet->src_id_type != SILC_ID_CLIENT ||
1859       packet->dst_id_type != SILC_ID_CLIENT)
1860     return;
1861
1862   if (!packet->dst_id)
1863     return;
1864
1865   /* Get the route to the client */
1866   dst_sock = silc_server_get_client_route(server, packet->dst_id,
1867                                           packet->dst_id_len, NULL, 
1868                                           &idata, NULL);
1869   if (!dst_sock)
1870     return;
1871
1872   /* Relay the packet */
1873   silc_server_relay_packet(server, dst_sock, idata->send_key,
1874                            idata->hmac_send, idata->psn_send++, packet, FALSE);
1875 }
1876
1877 /* Processes incoming command reply packet. The command reply packet may
1878    be destined to one of our clients or it may directly for us. We will 
1879    call the command reply routine after processing the packet. */
1880
1881 void silc_server_command_reply(SilcServer server,
1882                                SilcSocketConnection sock,
1883                                SilcPacketContext *packet)
1884 {
1885   SilcBuffer buffer = packet->buffer;
1886   SilcClientEntry client = NULL;
1887   SilcSocketConnection dst_sock;
1888   SilcIDListData idata;
1889   SilcClientID *id = NULL;
1890
1891   SILC_LOG_DEBUG(("Start"));
1892
1893   /* Source must be server or router */
1894   if (packet->src_id_type != SILC_ID_SERVER &&
1895       sock->type != SILC_SOCKET_TYPE_ROUTER)
1896     return;
1897
1898   if (packet->dst_id_type == SILC_ID_CHANNEL)
1899     return;
1900
1901   if (packet->dst_id_type == SILC_ID_CLIENT) {
1902     /* Destination must be one of ours */
1903     id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
1904     if (!id)
1905       return;
1906     client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
1907     if (!client) {
1908       SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
1909       silc_free(id);
1910       return;
1911     }
1912   }
1913
1914   if (packet->dst_id_type == SILC_ID_SERVER) {
1915     /* For now this must be for us */
1916     if (memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
1917       SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
1918       return;
1919     }
1920   }
1921
1922   /* Execute command reply locally for the command */
1923   silc_server_command_reply_process(server, sock, buffer);
1924
1925   if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
1926     /* Relay the packet to the client */
1927     const SilcBufferStruct p;
1928     
1929     dst_sock = (SilcSocketConnection)client->connection;
1930     idata = (SilcIDListData)client;
1931     
1932     silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len 
1933                      + packet->dst_id_len + packet->padlen);
1934     if (!silc_packet_send_prepare(dst_sock, 0, 0, buffer->len,
1935                                   idata->hmac_send, (const SilcBuffer)&p)) {
1936       SILC_LOG_ERROR(("Cannot send packet"));
1937       return;
1938     }
1939     silc_buffer_put((SilcBuffer)&p, buffer->data, buffer->len);
1940     
1941     /* Encrypt packet */
1942     silc_packet_encrypt(idata->send_key, idata->hmac_send, idata->psn_send++,
1943                         (SilcBuffer)&p, buffer->len);
1944     
1945     /* Send the packet */
1946     silc_server_packet_send_real(server, dst_sock, TRUE);
1947
1948     silc_free(id);
1949   }
1950 }
1951
1952 /* Process received channel message. The message can be originated from
1953    client or server. */
1954
1955 void silc_server_channel_message(SilcServer server,
1956                                  SilcSocketConnection sock,
1957                                  SilcPacketContext *packet)
1958 {
1959   SilcChannelEntry channel = NULL;
1960   SilcChannelID *id = NULL;
1961   void *sender_id = NULL;
1962   SilcClientEntry sender_entry = NULL;
1963   SilcChannelClientEntry chl;
1964   bool local = TRUE;
1965
1966   SILC_LOG_DEBUG(("Processing channel message"));
1967
1968   /* Sanity checks */
1969   if (packet->dst_id_type != SILC_ID_CHANNEL) {
1970     SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1971     goto out;
1972   }
1973
1974   /* Find channel entry */
1975   id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
1976   if (!id)
1977     goto out;
1978   channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
1979   if (!channel) {
1980     channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
1981     if (!channel) {
1982       SilcBuffer idp;
1983       unsigned char error;
1984
1985       /* Send SILC_NOTIFY_TYPE_ERROR to indicate that such destination ID
1986          does not exist or is invalid. */
1987       idp = silc_id_payload_encode_data(packet->dst_id,
1988                                         packet->dst_id_len,
1989                                         packet->dst_id_type);
1990       if (!idp)
1991         goto out;
1992
1993       error = SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID;
1994       if (packet->src_id_type == SILC_ID_CLIENT) {
1995         SilcClientID *client_id = silc_id_str2id(packet->src_id,
1996                                                  packet->src_id_len,
1997                                                  packet->src_id_type);
1998         silc_server_send_notify_dest(server, sock, FALSE,
1999                                      client_id, SILC_ID_CLIENT,
2000                                      SILC_NOTIFY_TYPE_ERROR, 2,
2001                                      &error, 1, idp->data, idp->len);
2002         silc_free(client_id);
2003       } else {
2004         silc_server_send_notify(server, sock, FALSE,
2005                                 SILC_NOTIFY_TYPE_ERROR, 2,
2006                                 &error, 1, idp->data, idp->len);
2007       }
2008       
2009       silc_buffer_free(idp);
2010       goto out;
2011     }
2012   }
2013
2014   /* See that this client is on the channel. If the original sender is
2015      not client (as it can be server as well) we don't do the check. */
2016   sender_id = silc_id_str2id(packet->src_id, packet->src_id_len, 
2017                              packet->src_id_type);
2018   if (!sender_id)
2019     goto out;
2020   if (packet->src_id_type == SILC_ID_CLIENT) {
2021     sender_entry = silc_idlist_find_client_by_id(server->local_list, 
2022                                                  sender_id, TRUE, NULL);
2023     if (!sender_entry) {
2024       local = FALSE;
2025       sender_entry = silc_idlist_find_client_by_id(server->global_list, 
2026                                                    sender_id, TRUE, NULL);
2027     }
2028     if (!sender_entry || !silc_server_client_on_channel(sender_entry, 
2029                                                         channel, &chl)) {
2030       SILC_LOG_DEBUG(("Client not on channel"));
2031       goto out;
2032     }
2033
2034     /* If channel is moderated check that client is allowed to send
2035        messages. */
2036     if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS && 
2037         !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
2038         !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
2039       SILC_LOG_DEBUG(("Channel is silenced from normal users"));
2040       goto out;
2041     }
2042     if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS && 
2043         chl->mode & SILC_CHANNEL_UMODE_CHANOP &&
2044         !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
2045       SILC_LOG_DEBUG(("Channel is silenced from operators"));
2046       goto out;
2047     }
2048     if (chl->mode & SILC_CHANNEL_UMODE_QUIET) {
2049       SILC_LOG_DEBUG(("Sender is quieted on the channel"));
2050       goto out;
2051     }
2052
2053     /* If the packet is coming from router, but the client entry is local 
2054        entry to us then some router is rerouting this to us and it is not 
2055        allowed. When the client is local to us it means that we've routed
2056        this packet to network, and now someone is routing it back to us. */
2057     if (server->server_type == SILC_ROUTER &&
2058         sock->type == SILC_SOCKET_TYPE_ROUTER && local) {
2059       SILC_LOG_DEBUG(("Channel message rerouted to the sender, drop it"));
2060       goto out;
2061     }
2062   }
2063
2064   /* Distribute the packet to our local clients. This will send the
2065      packet for further routing as well, if needed. */
2066   silc_server_packet_relay_to_channel(server, sock, channel, sender_id,
2067                                       packet->src_id_type, sender_entry,
2068                                       packet->buffer->data,
2069                                       packet->buffer->len, FALSE);
2070
2071  out:
2072   silc_free(sender_id);
2073   silc_free(id);
2074 }
2075
2076 /* Received channel key packet. We distribute the key to all of our locally
2077    connected clients on the channel. */
2078
2079 void silc_server_channel_key(SilcServer server,
2080                              SilcSocketConnection sock,
2081                              SilcPacketContext *packet)
2082 {
2083   SilcBuffer buffer = packet->buffer;
2084   SilcChannelEntry channel;
2085
2086   if (packet->src_id_type != SILC_ID_SERVER ||
2087       (server->server_type == SILC_ROUTER &&
2088        sock->type == SILC_SOCKET_TYPE_ROUTER))
2089     return;
2090
2091   /* Save the channel key */
2092   channel = silc_server_save_channel_key(server, buffer, NULL);
2093   if (!channel)
2094     return;
2095
2096   /* Distribute the key to everybody who is on the channel. If we are router
2097      we will also send it to locally connected servers. */
2098   silc_server_send_channel_key(server, sock, channel, FALSE);
2099   
2100   if (server->server_type != SILC_BACKUP_ROUTER) {
2101     /* Distribute to local cell backup routers. */
2102     silc_server_backup_send(server, sock->user_data, 
2103                             SILC_PACKET_CHANNEL_KEY, 0,
2104                             buffer->data, buffer->len, FALSE, TRUE);
2105   }
2106 }
2107
2108 /* Received New Client packet and processes it.  Creates Client ID for the
2109    client. Client becomes registered after calling this functions. */
2110
2111 SilcClientEntry silc_server_new_client(SilcServer server,
2112                                        SilcSocketConnection sock,
2113                                        SilcPacketContext *packet)
2114 {
2115   SilcBuffer buffer = packet->buffer;
2116   SilcClientEntry client;
2117   SilcClientID *client_id;
2118   SilcIDListData idata;
2119   char *username = NULL, *realname = NULL;
2120   SilcUInt16 username_len;
2121   SilcUInt32 id_len;
2122   int ret;
2123   char *hostname, *nickname;
2124   int nickfail = 0;
2125
2126   SILC_LOG_DEBUG(("Creating new client"));
2127
2128   if (sock->type != SILC_SOCKET_TYPE_CLIENT)
2129     return NULL;
2130
2131   /* Take client entry */
2132   client = (SilcClientEntry)sock->user_data;
2133   idata = (SilcIDListData)client;
2134
2135   /* Remove the old cache entry. */
2136   if (!silc_idcache_del_by_context(server->local_list->clients, client)) {
2137     SILC_LOG_INFO(("Unauthenticated client attempted to register to network"));
2138     silc_server_disconnect_remote(server, sock, 
2139                                   SILC_STATUS_ERR_NOT_AUTHENTICATED, NULL);
2140     if (sock->user_data)
2141       silc_server_free_sock_user_data(server, sock, NULL);
2142     return NULL;
2143   }
2144
2145   /* Parse incoming packet */
2146   ret = silc_buffer_unformat(buffer,
2147                              SILC_STR_UI16_NSTRING_ALLOC(&username, 
2148                                                          &username_len),
2149                              SILC_STR_UI16_STRING_ALLOC(&realname),
2150                              SILC_STR_END);
2151   if (ret == -1) {
2152     silc_free(username);
2153     silc_free(realname);
2154     SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2155                     "connection", sock->hostname, sock->ip));
2156     silc_server_disconnect_remote(server, sock, 
2157                                   SILC_STATUS_ERR_INCOMPLETE_INFORMATION, 
2158                                   NULL);
2159     if (sock->user_data)
2160       silc_server_free_sock_user_data(server, sock, NULL);
2161     return NULL;
2162   }
2163
2164   if (!username) {
2165     silc_free(username);
2166     silc_free(realname);
2167     SILC_LOG_ERROR(("Client %s (%s) did not send its username, closing "
2168                     "connection", sock->hostname, sock->ip));
2169     silc_server_disconnect_remote(server, sock, 
2170                                   SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2171                                   NULL);
2172     if (sock->user_data)
2173       silc_server_free_sock_user_data(server, sock, NULL);
2174     return NULL;
2175   }
2176
2177   if (username_len > 128)
2178     username[128] = '\0';
2179
2180   /* Check for bad characters for nickname, and modify the nickname if
2181      it includes those. */
2182   if (silc_server_name_bad_chars(username, username_len)) {
2183     nickname = silc_server_name_modify_bad(username, username_len);
2184   } else {
2185     nickname = strdup(username);
2186   }
2187
2188   /* Make sanity checks for the hostname of the client. If the hostname
2189      is provided in the `username' check that it is the same than the
2190      resolved hostname, or if not resolved the hostname that appears in
2191      the client's public key. If the hostname is not present then put
2192      it from the resolved name or from the public key. */
2193   if (strchr(username, '@')) {
2194     SilcPublicKeyIdentifier pident;
2195     int tlen = strcspn(username, "@");
2196     char *phostname = NULL;
2197
2198     hostname = silc_memdup(username + tlen + 1, strlen(username) - tlen - 1);
2199
2200     if (strcmp(sock->hostname, sock->ip) && 
2201         strcmp(sock->hostname, hostname)) {
2202       silc_free(username);
2203       silc_free(hostname);
2204       silc_free(realname);
2205       SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2206                       "connection", sock->hostname, sock->ip));
2207       silc_server_disconnect_remote(server, sock, 
2208                                     SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2209                                     NULL);
2210       if (sock->user_data)
2211         silc_server_free_sock_user_data(server, sock, NULL);
2212       return NULL;
2213     }
2214     
2215     pident = silc_pkcs_decode_identifier(client->data.public_key->identifier);
2216     if (pident) {
2217       phostname = strdup(pident->host);
2218       silc_pkcs_free_identifier(pident);
2219     }
2220
2221     if (!strcmp(sock->hostname, sock->ip) && 
2222         phostname && strcmp(phostname, hostname)) {
2223       silc_free(username);
2224       silc_free(hostname);
2225       silc_free(phostname);
2226       silc_free(realname);
2227       SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2228                       "connection", sock->hostname, sock->ip));
2229       silc_server_disconnect_remote(server, sock, 
2230                                     SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2231                                     NULL);
2232       if (sock->user_data)
2233         silc_server_free_sock_user_data(server, sock, NULL);
2234       return NULL;
2235     }
2236     
2237     silc_free(phostname);
2238   } else {
2239     /* The hostname is not present, add it. */
2240     char *newusername;
2241     /* XXX For now we cannot take the host name from the public key since
2242        they are not trusted or we cannot verify them as trusted. Just take
2243        what the resolved name or address is. */
2244 #if 0
2245     if (strcmp(sock->hostname, sock->ip)) {
2246 #endif
2247       newusername = silc_calloc(strlen(username) + 
2248                                 strlen(sock->hostname) + 2,
2249                                 sizeof(*newusername));
2250       strncat(newusername, username, strlen(username));
2251       strncat(newusername, "@", 1);
2252       strncat(newusername, sock->hostname, strlen(sock->hostname));
2253       silc_free(username);
2254       username = newusername;
2255 #if 0
2256     } else {
2257       SilcPublicKeyIdentifier pident = 
2258         silc_pkcs_decode_identifier(client->data.public_key->identifier);
2259       
2260       if (pident) {
2261         newusername = silc_calloc(strlen(username) + 
2262                                   strlen(pident->host) + 2,
2263                                   sizeof(*newusername));
2264         strncat(newusername, username, strlen(username));
2265         strncat(newusername, "@", 1);
2266         strncat(newusername, pident->host, strlen(pident->host));
2267         silc_free(username);
2268         username = newusername;
2269         silc_pkcs_free_identifier(pident);
2270       }
2271     }
2272 #endif
2273   }
2274
2275   /* Create Client ID */
2276   while (!silc_id_create_client_id(server, server->id, server->rng, 
2277                                    server->md5hash, nickname, &client_id)) {
2278     nickfail++;
2279     if (nickfail > 9) {
2280       silc_server_disconnect_remote(server, sock, 
2281                                     SILC_STATUS_ERR_BAD_NICKNAME, NULL);
2282       if (sock->user_data)
2283         silc_server_free_sock_user_data(server, sock, NULL);
2284       return NULL;
2285     }
2286     snprintf(&nickname[strlen(nickname) - 1], 1, "%d", nickfail);
2287   }
2288
2289   /* Update client entry */
2290   idata->status |= SILC_IDLIST_STATUS_REGISTERED;
2291   client->nickname = nickname;
2292   client->username = username;
2293   client->userinfo = realname ? realname : strdup(" ");
2294   client->id = client_id;
2295   id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
2296
2297   /* Add the client again to the ID cache */
2298   silc_idcache_add(server->local_list->clients, client->nickname,
2299                    client_id, client, 0, NULL);
2300
2301   /* Notify our router about new client on the SILC network */
2302   silc_server_send_new_id(server, SILC_PRIMARY_ROUTE(server),
2303                           SILC_BROADCAST(server), client->id,
2304                           SILC_ID_CLIENT, id_len);
2305
2306   /* Distribute to backup routers */
2307   if (server->server_type == SILC_ROUTER) {
2308     SilcBuffer idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
2309     silc_server_backup_send(server, sock->user_data, SILC_PACKET_NEW_ID, 0,
2310                             idp->data, idp->len, FALSE, TRUE);
2311     silc_buffer_free(idp);
2312   }
2313
2314   /* Send the new client ID to the client. */
2315   silc_server_send_new_id(server, sock, FALSE, client->id, SILC_ID_CLIENT,
2316                           silc_id_get_len(client->id, SILC_ID_CLIENT));
2317
2318   /* Send some nice info to the client */
2319   silc_server_send_connect_notifys(server, sock, client);
2320
2321   /* Check if anyone is watching this nickname */
2322   if (server->server_type == SILC_ROUTER)
2323     silc_server_check_watcher_list(server, client, NULL, 0);
2324
2325   return client;
2326 }
2327
2328 /* Create new server. This processes received New Server packet and
2329    saves the received Server ID. The server is our locally connected
2330    server thus we save all the information and save it to local list. 
2331    This funtion can be used by both normal server and router server.
2332    If normal server uses this it means that its router has connected
2333    to the server. If router uses this it means that one of the cell's
2334    servers is connected to the router. */
2335
2336 SilcServerEntry silc_server_new_server(SilcServer server,
2337                                        SilcSocketConnection sock,
2338                                        SilcPacketContext *packet)
2339 {
2340   SilcBuffer buffer = packet->buffer;
2341   SilcServerEntry new_server, server_entry;
2342   SilcServerID *server_id;
2343   SilcIDListData idata;
2344   unsigned char *server_name, *id_string;
2345   SilcUInt16 id_len, name_len;
2346   int ret;
2347   bool local = TRUE;
2348
2349   SILC_LOG_DEBUG(("Creating new server"));
2350
2351   if (sock->type != SILC_SOCKET_TYPE_SERVER &&
2352       sock->type != SILC_SOCKET_TYPE_ROUTER)
2353     return NULL;
2354
2355   /* Take server entry */
2356   new_server = (SilcServerEntry)sock->user_data;
2357   idata = (SilcIDListData)new_server;
2358
2359   /* Remove the old cache entry */
2360   if (!silc_idcache_del_by_context(server->local_list->servers, new_server)) {
2361     if (!silc_idcache_del_by_context(server->global_list->servers, 
2362                                      new_server)) {
2363       SILC_LOG_INFO(("Unauthenticated %s attempted to register to "
2364                      "network", (sock->type == SILC_SOCKET_TYPE_SERVER ?
2365                                  "server" : "router")));
2366       silc_server_disconnect_remote(server, sock, 
2367                                     SILC_STATUS_ERR_NOT_AUTHENTICATED, NULL);
2368       if (sock->user_data)
2369         silc_server_free_sock_user_data(server, sock, NULL);
2370       return NULL;
2371     }
2372     local = FALSE;
2373   }
2374
2375   /* Parse the incoming packet */
2376   ret = silc_buffer_unformat(buffer,
2377                              SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
2378                              SILC_STR_UI16_NSTRING_ALLOC(&server_name, 
2379                                                          &name_len),
2380                              SILC_STR_END);
2381   if (ret == -1) {
2382     silc_free(id_string);
2383     silc_free(server_name);
2384     silc_server_disconnect_remote(server, sock, 
2385                                   SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2386                                   NULL);
2387     if (sock->user_data)
2388       silc_server_free_sock_user_data(server, sock, NULL);
2389     return NULL;
2390   }
2391
2392   if (id_len > buffer->len) {
2393     silc_free(id_string);
2394     silc_free(server_name);
2395     silc_server_disconnect_remote(server, sock, 
2396                                   SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2397                                   NULL);
2398     if (sock->user_data)
2399       silc_server_free_sock_user_data(server, sock, NULL);
2400     return NULL;
2401   }
2402
2403   if (name_len > 256)
2404     server_name[255] = '\0';
2405
2406   /* Get Server ID */
2407   server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
2408   if (!server_id) {
2409     silc_free(id_string);
2410     silc_free(server_name);
2411     silc_server_disconnect_remote(server, sock, 
2412                                   SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2413                                   NULL);
2414     if (sock->user_data)
2415       silc_server_free_sock_user_data(server, sock, NULL);
2416     return NULL;
2417   }
2418   silc_free(id_string);
2419
2420   /* Check for valid server ID */
2421   if (!silc_id_is_valid_server_id(server, server_id, sock)) {
2422     SILC_LOG_INFO(("Invalid server ID sent by %s (%s)",
2423                    sock->ip, sock->hostname));
2424     silc_server_disconnect_remote(server, sock, 
2425                                   SILC_STATUS_ERR_BAD_SERVER_ID, NULL);
2426     if (sock->user_data)
2427       silc_server_free_sock_user_data(server, sock, NULL);
2428     silc_free(server_name);
2429     return NULL;
2430   }
2431
2432   /* Check that we do not have this ID already */
2433   server_entry = silc_idlist_find_server_by_id(server->local_list, 
2434                                                server_id, TRUE, NULL);
2435   if (server_entry) {
2436     silc_idcache_del_by_context(server->local_list->servers, server_entry);
2437   } else {
2438     server_entry = silc_idlist_find_server_by_id(server->global_list, 
2439                                                  server_id, TRUE, NULL);
2440     if (server_entry) 
2441       silc_idcache_del_by_context(server->global_list->servers, server_entry);
2442   }
2443
2444   /* Update server entry */
2445   idata->status |= SILC_IDLIST_STATUS_REGISTERED;
2446   new_server->server_name = server_name;
2447   new_server->id = server_id;
2448   
2449   SILC_LOG_DEBUG(("New server id(%s)",
2450                   silc_id_render(server_id, SILC_ID_SERVER)));
2451
2452   /* Add again the entry to the ID cache. */
2453   silc_idcache_add(local ? server->local_list->servers : 
2454                    server->global_list->servers, server_name, server_id, 
2455                    new_server, 0, NULL);
2456
2457   /* Distribute the information about new server in the SILC network
2458      to our router. If we are normal server we won't send anything
2459      since this connection must be our router connection. */
2460   if (server->server_type == SILC_ROUTER && !server->standalone &&
2461       SILC_PRIMARY_ROUTE(server) != sock)
2462     silc_server_send_new_id(server, SILC_PRIMARY_ROUTE(server),
2463                             TRUE, new_server->id, SILC_ID_SERVER, 
2464                             silc_id_get_len(server_id, SILC_ID_SERVER));
2465
2466   if (server->server_type == SILC_ROUTER) {
2467     /* Distribute to backup routers */
2468     SilcBuffer idp = silc_id_payload_encode(new_server->id, SILC_ID_SERVER);
2469     silc_server_backup_send(server, sock->user_data, SILC_PACKET_NEW_ID, 0,
2470                             idp->data, idp->len, FALSE, TRUE);
2471     silc_buffer_free(idp);
2472
2473     /* Statistics */
2474     server->stat.cell_servers++;
2475   }
2476
2477   /* Check whether this router connection has been replaced by an
2478      backup router. If it has been then we'll disable the server and will
2479      ignore everything it will send until the backup router resuming
2480      protocol has been completed. */
2481   if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
2482       silc_server_backup_replaced_get(server, server_id, NULL)) {
2483     /* Send packet to the server indicating that it cannot use this
2484        connection as it has been replaced by backup router. */
2485     SilcBuffer packet = silc_buffer_alloc(2);
2486     silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
2487     silc_buffer_format(packet,
2488                        SILC_STR_UI_CHAR(SILC_SERVER_BACKUP_REPLACED),
2489                        SILC_STR_UI_CHAR(0),
2490                        SILC_STR_END);
2491     silc_server_packet_send(server, sock, 
2492                             SILC_PACKET_RESUME_ROUTER, 0, 
2493                             packet->data, packet->len, TRUE);
2494     silc_buffer_free(packet);
2495
2496     /* Mark the router disabled. The data sent earlier will go but nothing
2497        after this does not go to this connection. */
2498     idata->status |= SILC_IDLIST_STATUS_DISABLED;
2499   } else {
2500     /* If it is router announce our stuff to it. */
2501     if (sock->type == SILC_SOCKET_TYPE_ROUTER && 
2502         server->server_type == SILC_ROUTER) {
2503       silc_server_announce_servers(server, FALSE, 0, sock);
2504       silc_server_announce_clients(server, 0, sock);
2505       silc_server_announce_channels(server, 0, sock);
2506     }
2507
2508     /* Announce our information to backup router */
2509     if (new_server->server_type == SILC_BACKUP_ROUTER &&
2510         sock->type == SILC_SOCKET_TYPE_SERVER &&
2511         server->server_type == SILC_ROUTER) {
2512       silc_server_announce_servers(server, TRUE, 0, sock);
2513       silc_server_announce_clients(server, 0, sock);
2514       silc_server_announce_channels(server, 0, sock);
2515     }
2516
2517     /* If backup router, mark it as one of ours.  This server is considered
2518        to be backup router after this setting. */
2519     if (new_server->server_type == SILC_BACKUP_ROUTER) {
2520       SilcServerConfigRouter *backup;
2521       backup = silc_server_config_find_backup_conn(server, sock->ip);
2522       if (!backup)
2523         backup = silc_server_config_find_backup_conn(server, sock->hostname);
2524       if (backup) {
2525         /* Add as our backup router */
2526         silc_server_backup_add(server, new_server, backup->backup_replace_ip,
2527                                backup->backup_replace_port,
2528                                backup->backup_local);
2529       }
2530     }
2531
2532     /* By default the servers connected to backup router are disabled
2533        until backup router has become the primary */
2534     if (server->server_type == SILC_BACKUP_ROUTER &&
2535         sock->type == SILC_SOCKET_TYPE_SERVER)
2536       idata->status |= SILC_IDLIST_STATUS_DISABLED;
2537   }
2538
2539   return new_server;
2540 }
2541
2542 /* Processes incoming New ID packet. New ID Payload is used to distribute
2543    information about newly registered clients and servers. */
2544
2545 static void silc_server_new_id_real(SilcServer server, 
2546                                     SilcSocketConnection sock,
2547                                     SilcPacketContext *packet,
2548                                     int broadcast)
2549 {
2550   SilcBuffer buffer = packet->buffer;
2551   SilcIDList id_list;
2552   SilcServerEntry router, server_entry;
2553   SilcSocketConnection router_sock;
2554   SilcIDPayload idp;
2555   SilcIdType id_type;
2556   void *id;
2557
2558   SILC_LOG_DEBUG(("Processing new ID"));
2559
2560   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2561       server->server_type == SILC_SERVER ||
2562       packet->src_id_type != SILC_ID_SERVER)
2563     return;
2564
2565   idp = silc_id_payload_parse(buffer->data, buffer->len);
2566   if (!idp)
2567     return;
2568
2569   id_type = silc_id_payload_get_type(idp);
2570
2571   /* Normal server cannot have other normal server connections */
2572   server_entry = (SilcServerEntry)sock->user_data;
2573   if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER &&
2574       server_entry->server_type == SILC_SERVER)
2575     goto out;
2576
2577   id = silc_id_payload_get_id(idp);
2578   if (!id)
2579     goto out;
2580
2581   /* If the packet is coming from server then use the sender as the
2582      origin of the the packet. If it came from router then check the real
2583      sender of the packet and use that as the origin. */
2584   if (sock->type == SILC_SOCKET_TYPE_SERVER) {
2585     id_list = server->local_list;
2586     router_sock = sock;
2587     router = sock->user_data;
2588
2589     /* If the sender is backup router and ID is server (and we are not
2590        backup router) then switch the entry to global list. */
2591     if (server_entry->server_type == SILC_BACKUP_ROUTER && 
2592         id_type == SILC_ID_SERVER && 
2593         server->id_entry->server_type != SILC_BACKUP_ROUTER) {
2594       id_list = server->global_list;
2595       router_sock = server->router ? SILC_PRIMARY_ROUTE(server) : sock;
2596     }
2597   } else {
2598     void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2599                                      packet->src_id_type);
2600     router = silc_idlist_find_server_by_id(server->global_list,
2601                                            sender_id, TRUE, NULL);
2602     if (!router)
2603       router = silc_idlist_find_server_by_id(server->local_list,
2604                                              sender_id, TRUE, NULL);
2605     silc_free(sender_id);
2606     router_sock = sock;
2607     id_list = server->global_list;
2608   }
2609
2610   if (!router)
2611     goto out;
2612
2613   switch(id_type) {
2614   case SILC_ID_CLIENT:
2615     {
2616       SilcClientEntry entry;
2617
2618       /* Check that we do not have this client already */
2619       entry = silc_idlist_find_client_by_id(server->global_list, 
2620                                             id, server->server_type, 
2621                                             NULL);
2622       if (!entry)
2623         entry = silc_idlist_find_client_by_id(server->local_list, 
2624                                               id, server->server_type,
2625                                               NULL);
2626       if (entry) {
2627         SILC_LOG_DEBUG(("Ignoring client that we already have"));
2628         goto out;
2629       }
2630
2631       SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
2632                       silc_id_render(id, SILC_ID_CLIENT),
2633                       sock->type == SILC_SOCKET_TYPE_SERVER ?
2634                       "Server" : "Router", sock->hostname));
2635     
2636       /* As a router we keep information of all global information in our
2637          global list. Cell wide information however is kept in the local
2638          list. */
2639       entry = silc_idlist_add_client(id_list, NULL, NULL, NULL, 
2640                                      id, router, NULL, 0);
2641       if (!entry) {
2642         SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
2643
2644         /* Inform the sender that the ID is not usable */
2645         silc_server_send_notify_signoff(server, sock, FALSE, id, NULL);
2646         goto out;
2647       }
2648       entry->nickname = NULL;
2649       entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2650
2651       if (sock->type == SILC_SOCKET_TYPE_SERVER)
2652         server->stat.cell_clients++;
2653       server->stat.clients++;
2654
2655       /* Check if anyone is watching this nickname */
2656       if (server->server_type == SILC_ROUTER && id_list == server->local_list)
2657         silc_server_check_watcher_list(server, entry, NULL, 0);
2658     }
2659     break;
2660
2661   case SILC_ID_SERVER:
2662     {
2663       SilcServerEntry entry;
2664
2665       /* If the ID is mine, ignore it. */
2666       if (SILC_ID_SERVER_COMPARE(id, server->id)) {
2667         SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
2668         break;
2669       }
2670
2671       /* If the ID is the sender's ID, ignore it (we have it already) */
2672       if (SILC_ID_SERVER_COMPARE(id, router->id)) {
2673         SILC_LOG_DEBUG(("Ignoring sender's own ID"));
2674         break;
2675       }
2676       
2677       /* Check that we do not have this server already */
2678       entry = silc_idlist_find_server_by_id(server->global_list, 
2679                                             id, server->server_type, 
2680                                             NULL);
2681       if (!entry)
2682         entry = silc_idlist_find_server_by_id(server->local_list, 
2683                                               id, server->server_type,
2684                                               NULL);
2685       if (entry) {
2686         SILC_LOG_DEBUG(("Ignoring server that we already have"));
2687         goto out;
2688       }
2689
2690       SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
2691                       silc_id_render(id, SILC_ID_SERVER),
2692                       sock->type == SILC_SOCKET_TYPE_SERVER ?
2693                       "Server" : "Router", sock->hostname));
2694       
2695       /* As a router we keep information of all global information in our 
2696          global list. Cell wide information however is kept in the local
2697          list. */
2698       entry = silc_idlist_add_server(id_list, NULL, 0, id, router, 
2699                                      router_sock);
2700       if (!entry) {
2701         SILC_LOG_ERROR(("Could not add new server to the ID Cache"));
2702         goto out;
2703       }
2704       entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2705       
2706       if (sock->type == SILC_SOCKET_TYPE_SERVER)
2707         server->stat.cell_servers++;
2708       server->stat.servers++;
2709     }
2710     break;
2711
2712   case SILC_ID_CHANNEL:
2713     SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
2714     goto out;
2715     break;
2716
2717   default:
2718     goto out;
2719     break;
2720   }
2721
2722   /* If the sender of this packet is server and we are router we need to
2723      broadcast this packet to other routers in the network. */
2724   if (broadcast && server->server_type == SILC_ROUTER &&
2725       sock->type == SILC_SOCKET_TYPE_SERVER &&
2726       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2727     SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
2728     silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
2729                             packet->type, 
2730                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
2731                             buffer->data, buffer->len, FALSE);
2732     silc_server_backup_send(server, sock->user_data, 
2733                             packet->type, packet->flags,
2734                             packet->buffer->data, packet->buffer->len, 
2735                             FALSE, TRUE);
2736   }
2737
2738  out:
2739   silc_id_payload_free(idp);
2740 }
2741
2742
2743 /* Processes incoming New ID packet. New ID Payload is used to distribute
2744    information about newly registered clients and servers. */
2745
2746 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
2747                         SilcPacketContext *packet)
2748 {
2749   silc_server_new_id_real(server, sock, packet, TRUE);
2750 }
2751
2752 /* Receoved New Id List packet, list of New ID payloads inside one
2753    packet. Process the New ID payloads one by one. */
2754
2755 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
2756                              SilcPacketContext *packet)
2757 {
2758   SilcPacketContext *new_id;
2759   SilcBuffer idp;
2760   SilcUInt16 id_len;
2761
2762   SILC_LOG_DEBUG(("Processing New ID List"));
2763
2764   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2765       packet->src_id_type != SILC_ID_SERVER)
2766     return;
2767
2768   /* If the sender of this packet is server and we are router we need to
2769      broadcast this packet to other routers in the network. Broadcast
2770      this list packet instead of multiple New ID packets. */
2771   if (server->server_type == SILC_ROUTER &&
2772       sock->type == SILC_SOCKET_TYPE_SERVER &&
2773       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2774     SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
2775     silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
2776                             packet->type, 
2777                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
2778                             packet->buffer->data, 
2779                             packet->buffer->len, FALSE);
2780     silc_server_backup_send(server, sock->user_data, 
2781                             packet->type, packet->flags,
2782                             packet->buffer->data, packet->buffer->len, 
2783                             FALSE, TRUE);
2784   }
2785
2786   /* Make copy of the original packet context, except for the actual
2787      data buffer, which we will here now fetch from the original buffer. */
2788   new_id = silc_packet_context_alloc();
2789   new_id->type = SILC_PACKET_NEW_ID;
2790   new_id->flags = packet->flags & (~SILC_PACKET_FLAG_LIST);
2791   new_id->src_id = packet->src_id;
2792   new_id->src_id_len = packet->src_id_len;
2793   new_id->src_id_type = packet->src_id_type;
2794   new_id->dst_id = packet->dst_id;
2795   new_id->dst_id_len = packet->dst_id_len;
2796   new_id->dst_id_type = packet->dst_id_type;
2797
2798   idp = silc_buffer_alloc(256);
2799   new_id->buffer = idp;
2800
2801   while (packet->buffer->len) {
2802     SILC_GET16_MSB(id_len, packet->buffer->data + 2);
2803     if ((id_len > packet->buffer->len) ||
2804         (id_len > idp->truelen))
2805       break;
2806
2807     silc_buffer_pull_tail(idp, 4 + id_len);
2808     silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
2809
2810     /* Process the New ID */
2811     silc_server_new_id_real(server, sock, new_id, FALSE);
2812
2813     silc_buffer_push_tail(idp, 4 + id_len);
2814     silc_buffer_pull(packet->buffer, 4 + id_len);
2815   }
2816
2817   silc_buffer_free(idp);
2818   silc_free(new_id);
2819 }
2820
2821 /* Received New Channel packet. Information about new channels in the 
2822    network are distributed using this packet. Save the information about
2823    the new channel. This usually comes from router but also normal server
2824    can send this to notify channels it has when it connects to us. */
2825
2826 void silc_server_new_channel(SilcServer server,
2827                              SilcSocketConnection sock,
2828                              SilcPacketContext *packet)
2829 {
2830   SilcChannelPayload payload;
2831   SilcChannelID *channel_id;
2832   char *channel_name;
2833   SilcUInt32 name_len;
2834   unsigned char *id;
2835   SilcUInt32 id_len;
2836   SilcServerEntry server_entry;
2837   SilcChannelEntry channel;
2838
2839   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2840       packet->src_id_type != SILC_ID_SERVER ||
2841       server->server_type == SILC_SERVER)
2842     return;
2843
2844   /* Parse the channel payload */
2845   payload = silc_channel_payload_parse(packet->buffer->data,
2846                                        packet->buffer->len);
2847   if (!payload)
2848     return;
2849     
2850   /* Get the channel ID */
2851   channel_id = silc_channel_get_id_parse(payload);
2852   if (!channel_id) {
2853     silc_channel_payload_free(payload);
2854     return;
2855   }
2856
2857   channel_name = silc_channel_get_name(payload, &name_len);
2858   if (name_len > 256)
2859     channel_name[255] = '\0';
2860
2861   id = silc_channel_get_id(payload, &id_len);
2862
2863   server_entry = (SilcServerEntry)sock->user_data;
2864
2865   if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
2866     /* Add the channel to global list as it is coming from router. It 
2867        cannot be our own channel as it is coming from router. */
2868
2869     /* Check that we don't already have this channel */
2870     channel = silc_idlist_find_channel_by_name(server->local_list, 
2871                                                channel_name, NULL);
2872     if (!channel)
2873       channel = silc_idlist_find_channel_by_name(server->global_list, 
2874                                                  channel_name, NULL);
2875     if (!channel) {
2876       SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
2877                       silc_id_render(channel_id, SILC_ID_CHANNEL), 
2878                       sock->hostname));
2879     
2880       channel = 
2881         silc_idlist_add_channel(server->global_list, strdup(channel_name), 
2882                                 0, channel_id, sock->user_data, NULL, NULL, 0);
2883       if (!channel)
2884         return;
2885       channel->disabled = TRUE;    /* Disabled until someone JOINs */
2886
2887       server->stat.channels++;
2888       if (server->server_type == SILC_ROUTER)
2889         channel->users_resolved = TRUE;
2890     }
2891   } else {
2892     /* The channel is coming from our server, thus it is in our cell
2893        we will add it to our local list. */
2894     SilcBuffer chk;
2895
2896     SILC_LOG_DEBUG(("Channel id(%s) from [Server] %s",
2897                     silc_id_render(channel_id, SILC_ID_CHANNEL), 
2898                     sock->hostname));
2899
2900     /* Check that we don't already have this channel */
2901     channel = silc_idlist_find_channel_by_name(server->local_list, 
2902                                                channel_name, NULL);
2903     if (!channel)
2904       channel = silc_idlist_find_channel_by_name(server->global_list, 
2905                                                  channel_name, NULL);
2906
2907     /* If the channel does not exist, then create it. This creates a new
2908        key to the channel as well that we will send to the server. */
2909     if (!channel) {
2910       SILC_LOG_DEBUG(("Channel is new to us"));
2911
2912       /* The protocol says that the Channel ID's IP address must be based
2913          on the router's IP address.  Check whether the ID is based in our
2914          IP and if it is not then create a new ID and enforce the server
2915          to switch the ID. */
2916       if (server_entry->server_type != SILC_BACKUP_ROUTER &&
2917           !SILC_ID_COMPARE(channel_id, server->id, server->id->ip.data_len)) {
2918         SilcChannelID *tmp;
2919         SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2920         if (silc_id_create_channel_id(server, server->id, server->rng, &tmp)) {
2921           silc_server_send_notify_channel_change(server, sock, FALSE, 
2922                                                  channel_id, tmp);
2923           silc_free(channel_id);
2924           silc_free(tmp);
2925         }
2926
2927         /* Wait that server re-announces this channel */
2928         return;
2929       }
2930
2931       /* Create the channel with the provided Channel ID */
2932       channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
2933                                                        channel_name,
2934                                                        channel_id, FALSE);
2935       if (!channel) {
2936         silc_channel_payload_free(payload);
2937         silc_free(channel_id);
2938         return;
2939       }
2940       channel->disabled = TRUE;    /* Disabled until someone JOINs */
2941
2942 #if 0 /* We assume that CMODE_CHANGE notify is sent to us after this. */
2943
2944       /* XXX Dunno if this is supposed to be set in any server type.  If set
2945          here the CMODE_CHANGE that may follow sets mode that we already
2946          have, and we may loose data from the CMODE_CHANGE notify. */
2947       if (server_entry->server_type != SILC_BACKUP_ROUTER)
2948         channel->mode = silc_channel_get_mode(payload);
2949 #endif
2950
2951       /* Send the new channel key to the server */
2952       id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2953       id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
2954       chk = silc_channel_key_payload_encode(id_len, id,
2955                                             strlen(channel->channel_key->
2956                                                    cipher->name),
2957                                             channel->channel_key->cipher->name,
2958                                             channel->key_len / 8, 
2959                                             channel->key);
2960       silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
2961                               chk->data, chk->len, FALSE);
2962       silc_buffer_free(chk);
2963     } else {
2964       /* The channel exist by that name, check whether the ID's match.
2965          If they don't then we'll force the server to use the ID we have.
2966          We also create a new key for the channel. */
2967       SilcBuffer modes = NULL, users = NULL, users_modes = NULL;
2968
2969       SILC_LOG_DEBUG(("Channel already exists"));
2970
2971       if (!SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
2972         /* They don't match, send CHANNEL_CHANGE notify to the server to
2973            force the ID change. */
2974         SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2975         silc_server_send_notify_channel_change(server, sock, FALSE, 
2976                                                channel_id, channel->id);
2977
2978         /* Wait that server re-announces this channel */
2979         return;
2980       }
2981
2982 #if 0 /* We will announce our CMODE anyway for this channel, so no need
2983          to check it (implicit enforce). */
2984
2985       /* If the mode is different from what we have then enforce the
2986          mode change. */
2987       mode = silc_channel_get_mode(payload);
2988       if (channel->mode != mode) {
2989         SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
2990         silc_server_send_notify_cmode(server, sock, FALSE, channel,
2991                                       channel->mode, server->id,
2992                                       SILC_ID_SERVER, channel->cipher,
2993                                       channel->hmac_name,
2994                                       channel->passphrase,
2995                                       channel->founder_key);
2996       }
2997 #endif
2998
2999       /* Create new key for the channel and send it to the server and
3000          everybody else possibly on the channel. */
3001       if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3002
3003         if (silc_hash_table_count(channel->user_list)) {
3004           if (!silc_server_create_channel_key(server, channel, 0))
3005             return;
3006
3007           /* Send to the channel */
3008           silc_server_send_channel_key(server, sock, channel, FALSE);
3009         }
3010
3011         /* Send to the server */
3012         id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3013         id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
3014         chk = silc_channel_key_payload_encode(id_len, id,
3015                                               strlen(channel->channel_key->
3016                                                      cipher->name),
3017                                               channel->channel_key->
3018                                               cipher->name,
3019                                               channel->key_len / 8, 
3020                                               channel->key);
3021         silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
3022                                 chk->data, chk->len, FALSE);
3023         silc_buffer_free(chk);
3024         silc_free(id);
3025       }
3026
3027       silc_free(channel_id);
3028
3029       /* Update statistics */
3030       server->stat.channels++;
3031       server->stat.cell_channels++;
3032
3033       /* Since the channel is coming from server and we also know about it
3034          then send the JOIN notify to the server so that it see's our
3035          users on the channel "joining" the channel. */
3036       silc_server_announce_get_channel_users(server, channel, &modes, &users,
3037                                              &users_modes);
3038       if (users) {
3039         silc_buffer_push(users, users->data - users->head);
3040         silc_server_packet_send(server, sock,
3041                                 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3042                                 users->data, users->len, FALSE);
3043         silc_buffer_free(users);
3044       }
3045       if (modes) {
3046         silc_buffer_push(modes, modes->data - modes->head);
3047         silc_server_packet_send_dest(server, sock,
3048                                      SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3049                                      channel->id, SILC_ID_CHANNEL,
3050                                      modes->data, modes->len, FALSE);
3051         silc_buffer_free(modes);
3052       }
3053       if (users_modes) {
3054         silc_buffer_push(users_modes, users_modes->data - users_modes->head);
3055         silc_server_packet_send_dest(server, sock,
3056                                      SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3057                                      channel->id, SILC_ID_CHANNEL,
3058                                      users_modes->data, 
3059                                      users_modes->len, FALSE);
3060         silc_buffer_free(users_modes);
3061       }
3062       if (channel->topic) {
3063         silc_server_send_notify_topic_set(server, sock,
3064                                           server->server_type == SILC_ROUTER ?
3065                                           TRUE : FALSE, channel, 
3066                                           server->id, SILC_ID_SERVER,
3067                                           channel->topic);
3068       }
3069     }
3070   }
3071
3072   /* If the sender of this packet is server and we are router we need to
3073      broadcast this packet to other routers in the network. Broadcast
3074      this list packet instead of multiple New Channel packets. */
3075   if (server->server_type == SILC_ROUTER &&
3076       sock->type == SILC_SOCKET_TYPE_SERVER &&
3077       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
3078     SILC_LOG_DEBUG(("Broadcasting received New Channel packet"));
3079     silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
3080                             packet->type, 
3081                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
3082                             packet->buffer->data, 
3083                             packet->buffer->len, FALSE);
3084     silc_server_backup_send(server, sock->user_data, 
3085                             packet->type, packet->flags,
3086                             packet->buffer->data, packet->buffer->len, 
3087                             FALSE, TRUE);
3088   }
3089
3090   silc_channel_payload_free(payload);
3091 }
3092
3093 /* Received New Channel List packet, list of New Channel List payloads inside
3094    one packet. Process the New Channel payloads one by one. */
3095
3096 void silc_server_new_channel_list(SilcServer server,
3097                                   SilcSocketConnection sock,
3098                                   SilcPacketContext *packet)
3099 {
3100   SilcPacketContext *new;
3101   SilcBuffer buffer;
3102   SilcUInt16 len1, len2;
3103
3104   SILC_LOG_DEBUG(("Processing New Channel List"));
3105
3106   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
3107       packet->src_id_type != SILC_ID_SERVER ||
3108       server->server_type == SILC_SERVER)
3109     return;
3110
3111   /* Make copy of the original packet context, except for the actual
3112      data buffer, which we will here now fetch from the original buffer. */
3113   new = silc_packet_context_alloc();
3114   new->type = SILC_PACKET_NEW_CHANNEL;
3115   new->flags = packet->flags & (~SILC_PACKET_FLAG_LIST);
3116   new->src_id = packet->src_id;
3117   new->src_id_len = packet->src_id_len;
3118   new->src_id_type = packet->src_id_type;
3119   new->dst_id = packet->dst_id;
3120   new->dst_id_len = packet->dst_id_len;
3121   new->dst_id_type = packet->dst_id_type;
3122
3123   buffer = silc_buffer_alloc(512);
3124   new->buffer = buffer;
3125
3126   while (packet->buffer->len) {
3127     SILC_GET16_MSB(len1, packet->buffer->data);
3128     if ((len1 > packet->buffer->len) ||
3129         (len1 > buffer->truelen))
3130       break;
3131
3132     SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
3133     if ((len2 > packet->buffer->len) ||
3134         (len2 > buffer->truelen))
3135       break;
3136
3137     silc_buffer_pull_tail(buffer, 8 + len1 + len2);
3138     silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
3139
3140     /* Process the New Channel */
3141     silc_server_new_channel(server, sock, new);
3142
3143     silc_buffer_push_tail(buffer, 8 + len1 + len2);
3144     silc_buffer_pull(packet->buffer, 8 + len1 + len2);
3145   }
3146
3147   silc_buffer_free(buffer);
3148   silc_free(new);
3149 }
3150
3151 /* Received key agreement packet. This packet is never for us. It is to
3152    the client in the packet's destination ID. Sending of this sort of packet
3153    equals sending private message, ie. it is sent point to point from
3154    one client to another. */
3155
3156 void silc_server_key_agreement(SilcServer server,
3157                                SilcSocketConnection sock,
3158                                SilcPacketContext *packet)
3159 {
3160   SilcSocketConnection dst_sock;
3161   SilcIDListData idata;
3162
3163   SILC_LOG_DEBUG(("Start"));
3164
3165   if (packet->src_id_type != SILC_ID_CLIENT ||
3166       packet->dst_id_type != SILC_ID_CLIENT)
3167     return;
3168
3169   if (!packet->dst_id)
3170     return;
3171
3172   /* Get the route to the client */
3173   dst_sock = silc_server_get_client_route(server, packet->dst_id,
3174                                           packet->dst_id_len, NULL, 
3175                                           &idata, NULL);
3176   if (!dst_sock)
3177     return;
3178
3179   /* Relay the packet */
3180   silc_server_relay_packet(server, dst_sock, idata->send_key,
3181                            idata->hmac_send, idata->psn_send++,
3182                            packet, FALSE);
3183 }
3184
3185 /* Received connection auth request packet that is used during connection
3186    phase to resolve the mandatory authentication method.  This packet can
3187    actually be received at anytime but usually it is used only during
3188    the connection authentication phase. Now, protocol says that this packet
3189    can come from client or server, however, we support only this coming
3190    from client and expect that server always knows what authentication
3191    method to use. */
3192
3193 void silc_server_connection_auth_request(SilcServer server,
3194                                          SilcSocketConnection sock,
3195                                          SilcPacketContext *packet)
3196 {
3197   SilcServerConfigClient *client = NULL;
3198   SilcUInt16 conn_type;
3199   int ret;
3200   SilcAuthMethod auth_meth = SILC_AUTH_NONE;
3201
3202   if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT) {
3203     SILC_LOG_DEBUG(("Request not from client"));
3204     return;
3205   }
3206
3207   /* Parse the payload */
3208   ret = silc_buffer_unformat(packet->buffer,
3209                              SILC_STR_UI_SHORT(&conn_type),
3210                              SILC_STR_UI_SHORT(NULL),
3211                              SILC_STR_END);
3212   if (ret == -1)
3213     return;
3214
3215   if (conn_type != SILC_SOCKET_TYPE_CLIENT)
3216     return;
3217
3218   /* Get the authentication method for the client */
3219   auth_meth = SILC_AUTH_NONE;
3220   client = silc_server_config_find_client(server, sock->ip);
3221   if (!client)
3222     client = silc_server_config_find_client(server, sock->hostname);
3223   if (client) {
3224     if (client->passphrase) {
3225       if (client->publickeys && !server->config->prefer_passphrase_auth)
3226         auth_meth = SILC_AUTH_PUBLIC_KEY;
3227       else
3228         auth_meth = SILC_AUTH_PASSWORD;
3229     } else if (client->publickeys)
3230       auth_meth = SILC_AUTH_PUBLIC_KEY;
3231   }
3232
3233   SILC_LOG_DEBUG(("Authentication method is [%s]",
3234                   (auth_meth == SILC_AUTH_NONE ? "None" :
3235                    auth_meth == SILC_AUTH_PASSWORD ? "Passphrase" :
3236                    "Digital signatures")));
3237
3238   /* Send it back to the client */
3239   silc_server_send_connection_auth_request(server, sock, conn_type, auth_meth);
3240 }
3241
3242 /* Received REKEY packet. The sender of the packet wants to regenerate
3243    its session keys. This starts the REKEY protocol. */
3244
3245 void silc_server_rekey(SilcServer server,
3246                        SilcSocketConnection sock,
3247                        SilcPacketContext *packet)
3248 {
3249   SilcProtocol protocol;
3250   SilcServerRekeyInternalContext *proto_ctx;
3251   SilcIDListData idata = (SilcIDListData)sock->user_data;
3252
3253   SILC_LOG_DEBUG(("Start"));
3254
3255   /* Allocate internal protocol context. This is sent as context
3256      to the protocol. */
3257   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
3258   proto_ctx->server = (void *)server;
3259   proto_ctx->sock = sock;
3260   proto_ctx->responder = TRUE;
3261   proto_ctx->pfs = idata->rekey->pfs;
3262       
3263   /* Perform rekey protocol. Will call the final callback after the
3264      protocol is over. */
3265   silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY, 
3266                       &protocol, proto_ctx, silc_server_rekey_final);
3267   sock->protocol = protocol;
3268
3269   if (proto_ctx->pfs == FALSE)
3270     /* Run the protocol */
3271     silc_protocol_execute(protocol, server->schedule, 0, 0);
3272 }
3273
3274 /* Received file transger packet. This packet is never for us. It is to
3275    the client in the packet's destination ID. Sending of this sort of packet
3276    equals sending private message, ie. it is sent point to point from
3277    one client to another. */
3278
3279 void silc_server_ftp(SilcServer server,
3280                      SilcSocketConnection sock,
3281                      SilcPacketContext *packet)
3282 {
3283   SilcSocketConnection dst_sock;
3284   SilcIDListData idata;
3285
3286   SILC_LOG_DEBUG(("Start"));
3287
3288   if (packet->src_id_type != SILC_ID_CLIENT ||
3289       packet->dst_id_type != SILC_ID_CLIENT)
3290     return;
3291
3292   if (!packet->dst_id)
3293     return;
3294
3295   /* Get the route to the client */
3296   dst_sock = silc_server_get_client_route(server, packet->dst_id,
3297                                           packet->dst_id_len, NULL, 
3298                                           &idata, NULL);
3299   if (!dst_sock)
3300     return;
3301
3302   /* Relay the packet */
3303   silc_server_relay_packet(server, dst_sock, idata->send_key,
3304                            idata->hmac_send, idata->psn_send++,
3305                            packet, FALSE);
3306 }
3307
3308 typedef struct {
3309   SilcServer server;
3310   SilcSocketConnection sock;
3311   SilcPacketContext *packet;
3312   void *data;
3313 } *SilcServerResumeResolve;
3314
3315 SILC_SERVER_CMD_FUNC(resume_resolve)
3316 {
3317   SilcServerResumeResolve r = (SilcServerResumeResolve)context;
3318   SilcServer server = r->server;
3319   SilcSocketConnection sock = r->sock;
3320   SilcServerCommandReplyContext reply = context2;
3321   SilcClientEntry client;
3322
3323   SILC_LOG_DEBUG(("Start"));
3324
3325   if (!reply || !silc_command_get_status(reply->payload, NULL, NULL)) {
3326     SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3327                     "closing connection", sock->hostname, sock->ip));
3328     silc_server_disconnect_remote(server, sock,
3329                                   SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3330                                   "Resuming not possible");
3331     if (sock->user_data)
3332       silc_server_free_sock_user_data(server, sock, NULL);
3333     goto out;
3334   }
3335
3336   if (reply && silc_command_get(reply->payload) == SILC_COMMAND_WHOIS) {
3337     /* Get entry to the client, and resolve it if we don't have it. */
3338     client = silc_idlist_find_client_by_id(server->local_list, 
3339                                            r->data, TRUE, NULL);
3340     if (!client) {
3341       client = silc_idlist_find_client_by_id(server->global_list,
3342                                              r->data, TRUE, NULL);
3343       if (!client) {
3344         SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3345                         "closing connection", sock->hostname, sock->ip));
3346         silc_server_disconnect_remote(server, sock,
3347                                       SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3348                                       "Resuming not possible");
3349         if (sock->user_data)
3350           silc_server_free_sock_user_data(server, sock, NULL);
3351         goto out;
3352       }
3353     }
3354
3355     if (!(client->mode & SILC_UMODE_DETACHED)) {
3356       SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, "
3357                       "closing connection", sock->hostname, sock->ip));
3358       silc_server_disconnect_remote(server, sock,
3359                                     SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3360                                     "Resuming not possible");
3361       if (sock->user_data)
3362         silc_server_free_sock_user_data(server, sock, NULL);
3363       goto out;
3364     }
3365   }
3366
3367   /* Reprocess the packet */
3368   silc_server_resume_client(server, sock, r->packet);
3369
3370  out:
3371   silc_socket_free(r->sock);
3372   silc_packet_context_free(r->packet);
3373   silc_free(r->data);
3374   silc_free(r);
3375 }
3376
3377 /* Received client resuming packet.  This is used to resume detached
3378    client session.  It can be sent by the client who wishes to resume
3379    but this is also sent by servers and routers to notify other routers
3380    that the client is not detached anymore. */
3381
3382 void silc_server_resume_client(SilcServer server,
3383                                SilcSocketConnection sock,
3384                                SilcPacketContext *packet)
3385 {
3386   SilcBuffer buffer = packet->buffer, buf;
3387   SilcIDListData idata;
3388   SilcIDCacheEntry id_cache = NULL;
3389   SilcClientEntry detached_client;
3390   SilcClientID *client_id = NULL;
3391   unsigned char *id_string, *auth = NULL;
3392   SilcUInt16 id_len, auth_len = 0;
3393   int ret, nickfail = 0;
3394   bool resolved, local, nick_change = FALSE, resolve = FALSE;
3395   SilcChannelEntry channel;
3396   SilcHashTableList htl;
3397   SilcChannelClientEntry chl;
3398   SilcServerResumeResolve r;
3399
3400   ret = silc_buffer_unformat(buffer,
3401                              SILC_STR_UI16_NSTRING(&id_string, &id_len),
3402                              SILC_STR_END);
3403   if (ret != -1)
3404     client_id = silc_id_str2id(id_string, id_len, SILC_ID_CLIENT);
3405
3406   if (sock->type == SILC_SOCKET_TYPE_CLIENT) {
3407     /* Client send this and is attempting to resume to old client session */
3408     SilcClientEntry client;
3409     SilcBuffer keyp;
3410
3411     if (ret != -1) {
3412       silc_buffer_pull(buffer, 2 + id_len);
3413       auth = buffer->data;
3414       auth_len = buffer->len;
3415       silc_buffer_push(buffer, 2 + id_len);
3416     }
3417
3418     if (!client_id || auth_len < 128) {
3419       SILC_LOG_ERROR(("Client %s (%s) sent incomplete resume information, "
3420                       "closing connection", sock->hostname, sock->ip));
3421       silc_server_disconnect_remote(server, sock,
3422                                     SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3423                                     "Resuming not possible");
3424       if (sock->user_data)
3425         silc_server_free_sock_user_data(server, sock, NULL);
3426       silc_free(client_id);
3427       return;
3428     }
3429
3430     /* Take client entry of this connection */
3431     client = (SilcClientEntry)sock->user_data;
3432     idata = (SilcIDListData)client;
3433
3434     /* Get entry to the client, and resolve it if we don't have it. */
3435     detached_client = silc_server_get_client_resolve(server, client_id, FALSE,
3436                                                      &resolved);
3437     if (!detached_client) {
3438       if (resolved) {
3439         /* The client info is being resolved. Reprocess this packet after
3440            receiving the reply to the query. */
3441         SILC_LOG_DEBUG(("Resolving client"));
3442         r = silc_calloc(1, sizeof(*r));
3443         if (!r)
3444           return;
3445         r->server = server;
3446         r->sock = silc_socket_dup(sock);
3447         r->packet = silc_packet_context_dup(packet);
3448         r->data = client_id;
3449         silc_server_command_pending(server, SILC_COMMAND_WHOIS,
3450                                     server->cmd_ident,
3451                                     silc_server_command_resume_resolve, r);
3452       } else {
3453         SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3454                         "closing connection", sock->hostname, sock->ip));
3455         silc_server_disconnect_remote(server, sock,
3456                                       SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3457                                       "Resuming not possible");
3458         if (sock->user_data)
3459           silc_server_free_sock_user_data(server, sock, NULL);
3460         silc_free(client_id);
3461       }
3462       return;
3463     }
3464
3465     if (!(detached_client->mode & SILC_UMODE_DETACHED))
3466       resolve = TRUE;
3467     if (!silc_hash_table_count(detached_client->channels) &&
3468         detached_client->router)
3469       resolve = TRUE;
3470     if (!detached_client->nickname)
3471       resolve = TRUE;
3472
3473     if (resolve) {
3474       if (server->server_type == SILC_SERVER && !server->standalone) {
3475         /* The client info is being resolved. Reprocess this packet after
3476            receiving the reply to the query. */
3477         SILC_LOG_DEBUG(("Resolving client info"));
3478         silc_server_get_client_resolve(server, client_id, TRUE, NULL);
3479         r = silc_calloc(1, sizeof(*r));
3480         if (!r)
3481           return;
3482         r->server = server;
3483         r->sock = silc_socket_dup(sock);
3484         r->packet = silc_packet_context_dup(packet);
3485         r->data = client_id;
3486         silc_server_command_pending(server, SILC_COMMAND_WHOIS,
3487                                     server->cmd_ident,
3488                                     silc_server_command_resume_resolve, r);
3489         return;
3490       }
3491       if (server->server_type == SILC_SERVER) {
3492         SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, "
3493                         "closing connection", sock->hostname, sock->ip));
3494         silc_server_disconnect_remote(server, sock,
3495                                       SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3496                                       "Resuming not possible");
3497         if (sock->user_data)
3498           silc_server_free_sock_user_data(server, sock, NULL);
3499         silc_free(client_id);
3500         return;
3501       }
3502     }
3503
3504     /* Check that we have the public key of the client, if not then we must
3505        resolve it first. */
3506     if (!detached_client->data.public_key) {
3507       if (server->server_type == SILC_SERVER && server->standalone) {
3508         SILC_LOG_ERROR(("Detached client's public key not present, "
3509                         "closing connection"));
3510         silc_server_disconnect_remote(server, sock,
3511                                       SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3512                                       "Resuming not possible");
3513         if (sock->user_data)
3514           silc_server_free_sock_user_data(server, sock, NULL);
3515         silc_free(client_id);
3516       } else {
3517         /* We must retrieve the detached client's public key by sending
3518            GETKEY command. Reprocess this packet after receiving the key */
3519         SilcBuffer idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
3520         SilcSocketConnection dest_sock = 
3521           silc_server_get_client_route(server, NULL, 0, client_id, NULL, NULL);
3522
3523         SILC_LOG_DEBUG(("Resolving client public key"));
3524
3525         silc_server_send_command(server, dest_sock ? dest_sock : 
3526                                  SILC_PRIMARY_ROUTE(server),
3527                                  SILC_COMMAND_GETKEY, ++server->cmd_ident,
3528                                  1, 1, idp->data, idp->len);
3529
3530         r = silc_calloc(1, sizeof(*r));
3531         if (!r) {
3532           silc_free(client_id);
3533           return;
3534         }
3535
3536         r->server = server;
3537         r->sock = silc_socket_dup(sock);
3538         r->packet = silc_packet_context_dup(packet);
3539         silc_server_command_pending(server, SILC_COMMAND_GETKEY,
3540                                     server->cmd_ident,
3541                                     silc_server_command_resume_resolve, r);
3542
3543         silc_buffer_free(idp);
3544       }
3545       silc_free(client_id);
3546       return;
3547     } else if (!silc_pkcs_public_key_compare(detached_client->data.public_key,
3548                                              idata->public_key)) {
3549       /* We require that the connection and resuming authentication data
3550          must be using same key pair. */
3551       SILC_LOG_ERROR(("Resuming attempted with wrong public key, "
3552                       "closing connection"));
3553       silc_server_disconnect_remote(server, sock,
3554                                     SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3555                                     "Resuming not possible");
3556       if (sock->user_data)
3557         silc_server_free_sock_user_data(server, sock, NULL);
3558       silc_free(client_id);
3559       return;
3560     }
3561
3562     /* Verify the authentication payload.  This has to be successful in
3563        order to allow the resuming */
3564     if (!idata->hash ||
3565         !silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
3566                                detached_client->data.public_key, 0,
3567                                idata->hash, detached_client->id, 
3568                                SILC_ID_CLIENT)) {
3569       SILC_LOG_ERROR(("Client %s (%s) resume authentication failed, "
3570                       "closing connection", sock->hostname, sock->ip));
3571       silc_server_disconnect_remote(server, sock,
3572                                     SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3573                                     "Resuming not possible");
3574       if (sock->user_data)
3575         silc_server_free_sock_user_data(server, sock, NULL);
3576       silc_free(client_id);
3577       return;
3578     }
3579
3580     /* Now resume the client to the network */
3581
3582     silc_schedule_task_del_by_context(server->schedule, detached_client);
3583     sock->user_data = detached_client;
3584     detached_client->connection = sock;
3585
3586     /* Take new keys and stuff into use in the old entry */
3587     silc_idlist_del_data(detached_client);
3588     silc_idlist_add_data(detached_client, idata);
3589     detached_client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
3590     detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
3591     detached_client->mode &= ~SILC_UMODE_DETACHED;
3592     server->stat.my_detached--;
3593
3594     /* Send the RESUME_CLIENT packet to our primary router so that others
3595        know this client isn't detached anymore. */
3596     buf = silc_buffer_alloc_size(2 + id_len);
3597     silc_buffer_format(buf,
3598                        SILC_STR_UI_SHORT(id_len),
3599                        SILC_STR_UI_XNSTRING(id_string, id_len),
3600                        SILC_STR_END);
3601
3602     /* Send to primary router */
3603     silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
3604                             SILC_PACKET_RESUME_CLIENT, 0, 
3605                             buf->data, buf->len, TRUE);
3606
3607     /* As router we must deliver this packet directly to the original
3608        server whom this client was earlier. */
3609     if (server->server_type == SILC_ROUTER && detached_client->router &&
3610         detached_client->router->server_type != SILC_ROUTER)
3611       silc_server_packet_send(server, detached_client->router->connection,
3612                               SILC_PACKET_RESUME_CLIENT, 0, 
3613                               buf->data, buf->len, TRUE);
3614     silc_buffer_free(buf);
3615
3616     detached_client->router = NULL;
3617
3618     /* Delete this client entry since we're resuming to old one. */
3619     server->stat.my_clients--;
3620     server->stat.clients--;
3621     if (server->stat.cell_clients)
3622       server->stat.cell_clients--;
3623     silc_server_remove_from_channels(server, NULL, client, FALSE, NULL, FALSE);
3624     silc_server_del_from_watcher_list(server, client);
3625     if (!silc_idlist_del_client(server->local_list, client))
3626       silc_idlist_del_client(server->global_list, client);
3627     client = detached_client;
3628
3629     /* If the ID is not based in our ID then change it */
3630     if (!SILC_ID_COMPARE(client->id, server->id, server->id->ip.data_len)) {
3631       silc_free(client_id);
3632       while (!silc_id_create_client_id(server, server->id, server->rng, 
3633                                        server->md5hash, client->nickname, 
3634                                        &client_id)) {
3635         nickfail++;
3636         if (nickfail > 9) {
3637           silc_server_disconnect_remote(server, sock, 
3638                                         SILC_STATUS_ERR_BAD_NICKNAME, NULL);
3639           if (sock->user_data)
3640             silc_server_free_sock_user_data(server, sock, NULL);
3641           return;
3642         }
3643         snprintf(&client->nickname[strlen(client->nickname) - 1], 1, 
3644                  "%d", nickfail);
3645       }
3646       nick_change = TRUE;
3647     }
3648
3649     if (nick_change) {
3650       /* Notify about Client ID change, nickname doesn't actually change. */
3651       silc_server_send_notify_nick_change(server, SILC_PRIMARY_ROUTE(server),
3652                                           SILC_BROADCAST(server),
3653                                           client->id, client_id,
3654                                           client->nickname);
3655     }
3656
3657     /* Resolve users on those channels that client has joined but we
3658        haven't resolved user list yet. */
3659     if (server->server_type == SILC_SERVER && !server->standalone) {
3660       silc_hash_table_list(client->channels, &htl);
3661       while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
3662         channel = chl->channel;
3663         SILC_LOG_DEBUG(("Resolving users for %s channel", 
3664                         channel->channel_name));
3665         if (channel->disabled || !channel->users_resolved) {
3666           silc_server_send_command(server, SILC_PRIMARY_ROUTE(server),
3667                                    SILC_COMMAND_USERS, ++server->cmd_ident,
3668                                    1, 2, channel->channel_name,
3669                                    strlen(channel->channel_name));
3670         }
3671       }
3672       silc_hash_table_list_reset(&htl);
3673     }
3674
3675     /* Send the new client ID to the client. After this client may start
3676        receiving other packets, and may start sending packets too. */
3677     silc_server_send_new_id(server, sock, FALSE, client_id, SILC_ID_CLIENT,
3678                             silc_id_get_len(client_id, SILC_ID_CLIENT));
3679
3680     if (nick_change) {
3681       /* Send NICK change notify to channels as well. */
3682       SilcBuffer oidp, nidp;
3683       oidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3684       nidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
3685       silc_server_send_notify_on_channels(server, NULL, client, 
3686                                           SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
3687                                           oidp->data, oidp->len, 
3688                                           nidp->data, nidp->len,
3689                                           client->nickname, 
3690                                           strlen(client->nickname));
3691       silc_buffer_free(oidp);
3692       silc_buffer_free(nidp);
3693     }
3694
3695     /* Add the client again to the ID cache to get it to correct list */
3696     if (!silc_idcache_del_by_context(server->local_list->clients, client))
3697       silc_idcache_del_by_context(server->global_list->clients, client);
3698     silc_free(client->id);
3699     client->id = client_id;
3700     client_id = NULL;
3701     silc_idcache_add(server->local_list->clients, client->nickname,
3702                      client->id, client, 0, NULL);
3703
3704     /* Send some nice info to the client */
3705     silc_server_send_connect_notifys(server, sock, client);
3706
3707     /* Send all channel keys of channels the client has joined */
3708     silc_hash_table_list(client->channels, &htl);
3709     while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
3710       bool created = FALSE;
3711       channel = chl->channel;
3712
3713       if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY)
3714         continue;
3715
3716       /* If we don't have channel key, then create one */
3717       if (!channel->channel_key) {
3718         if (!silc_server_create_channel_key(server, channel, 0))
3719           continue;
3720         created = TRUE;
3721       }
3722
3723       id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3724       keyp = 
3725         silc_channel_key_payload_encode(silc_id_get_len(channel->id,
3726                                                         SILC_ID_CHANNEL), 
3727                                         id_string,
3728                                         strlen(channel->channel_key->
3729                                                cipher->name),
3730                                         channel->channel_key->cipher->name,
3731                                         channel->key_len / 8, channel->key);
3732       silc_free(id_string);
3733
3734       /* Send the key packet to client */
3735       silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
3736                               keyp->data, keyp->len, FALSE);
3737
3738       if (created && server->server_type == SILC_SERVER)
3739         silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server), 
3740                                 SILC_PACKET_CHANNEL_KEY, 0, 
3741                                 keyp->data, keyp->len, FALSE);
3742
3743       silc_buffer_free(keyp);
3744     }
3745     silc_hash_table_list_reset(&htl);
3746
3747   } else if (sock->type != SILC_SOCKET_TYPE_CLIENT) {
3748     /* Server or router sent this to us to notify that that a client has
3749        been resumed. */
3750     SilcServerEntry server_entry;
3751     SilcServerID *server_id;
3752
3753     if (!client_id) {
3754       SILC_LOG_DEBUG(("Malformed resuming packet"));
3755       return;
3756     }
3757
3758     /* Get entry to the client, and resolve it if we don't have it. */
3759     detached_client = silc_idlist_find_client_by_id(server->local_list, 
3760                                                     client_id, TRUE,
3761                                                     &id_cache);
3762     if (!detached_client) {
3763       detached_client = silc_idlist_find_client_by_id(server->global_list,
3764                                                       client_id, TRUE,
3765                                                       &id_cache);
3766       if (!detached_client) {
3767         SILC_LOG_DEBUG(("Resuming client is unknown"));
3768         silc_free(client_id);
3769         return;
3770       }
3771     }
3772
3773     /* Check that the client has not been resumed already because it is
3774        protocol error to attempt to resume more than once.  The client
3775        will be killed if this protocol error occurs. */
3776     if (detached_client->data.status & SILC_IDLIST_STATUS_RESUMED &&
3777         !(detached_client->mode & SILC_UMODE_DETACHED)) {
3778       /* The client is clearly attempting to resume more than once and
3779          perhaps playing around by resuming from several different places
3780          at the same time. */
3781       SILC_LOG_DEBUG(("Attempting to re-resume client, killing both"));
3782       silc_server_kill_client(server, detached_client, NULL,
3783                               server->id, SILC_ID_SERVER);
3784       silc_free(client_id);
3785       return;
3786     }
3787
3788     /* Check whether client is detached at all */
3789     if (!(detached_client->mode & SILC_UMODE_DETACHED)) {
3790       SILC_LOG_DEBUG(("Client is not detached"));
3791       silc_free(client_id);
3792       return;
3793     }
3794
3795     SILC_LOG_DEBUG(("Resuming detached client"));
3796
3797     /* If the sender of this packet is server and we are router we need to
3798        broadcast this packet to other routers in the network. */
3799     if (server->server_type == SILC_ROUTER &&
3800         sock->type == SILC_SOCKET_TYPE_SERVER &&
3801         !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
3802       SILC_LOG_DEBUG(("Broadcasting received Resume Client packet"));
3803       silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
3804                               packet->type, 
3805                               packet->flags | SILC_PACKET_FLAG_BROADCAST,
3806                               buffer->data, buffer->len, FALSE);
3807       silc_server_backup_send(server, sock->user_data, 
3808                               packet->type, packet->flags,
3809                               packet->buffer->data, packet->buffer->len, 
3810                               FALSE, TRUE);
3811     }
3812
3813     /* Client is detached, and now it is resumed.  Remove the detached
3814        mode and mark that it is resumed. */
3815     detached_client->mode &= ~SILC_UMODE_DETACHED;
3816     detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
3817     detached_client->data.status &= ~SILC_IDLIST_STATUS_LOCAL;
3818     id_cache->expire = 0;
3819
3820     /* Update channel information regarding global clients on channel. */
3821     if (server->server_type == SILC_SERVER) {
3822       silc_hash_table_list(detached_client->channels, &htl);
3823       while (silc_hash_table_get(&htl, NULL, (void **)&chl))
3824         chl->channel->global_users = 
3825           silc_server_channel_has_global(chl->channel);
3826       silc_hash_table_list_reset(&htl);
3827     }
3828
3829     silc_schedule_task_del_by_context(server->schedule, detached_client);
3830
3831     /* Get the new owner of the resumed client */
3832     server_id = silc_id_str2id(packet->src_id, packet->src_id_len,
3833                                packet->src_id_type);
3834     if (!server_id) {
3835       silc_free(client_id);
3836       return;
3837     }
3838
3839     /* Get server entry */
3840     server_entry = silc_idlist_find_server_by_id(server->global_list, 
3841                                                  server_id, TRUE, NULL);
3842     local = TRUE;
3843     if (!server_entry) {
3844       server_entry = silc_idlist_find_server_by_id(server->local_list, 
3845                                                    server_id, TRUE, NULL);
3846       local = FALSE;
3847       if (!server_entry) {
3848         silc_free(server_id);
3849         silc_free(client_id);
3850         return;
3851       }
3852     }
3853
3854     if (server->server_type == SILC_ROUTER &&
3855         sock->type == SILC_SOCKET_TYPE_ROUTER && 
3856         server_entry->server_type == SILC_ROUTER)
3857       local = FALSE;
3858
3859     /* Change the client to correct list. */
3860     if (!silc_idcache_del_by_context(server->local_list->clients,
3861                                      detached_client))
3862       silc_idcache_del_by_context(server->global_list->clients,
3863                                   detached_client);
3864     silc_idcache_add(local && server->server_type == SILC_ROUTER ? 
3865                      server->local_list->clients : 
3866                      server->global_list->clients, 
3867                      detached_client->nickname,
3868                      detached_client->id, detached_client, FALSE, NULL);
3869
3870     /* Change the owner of the client */
3871     detached_client->router = server_entry;
3872
3873     silc_free(server_id);
3874   }
3875
3876   silc_free(client_id);
3877 }