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