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