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