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