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