updates.
[silc.git] / apps / silcd / packet_receive.c
1 /*
2
3   packet_receive.c
4
5   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
6
7   Copyright (C) 1997 - 2001 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 extern char *server_version;
29
30 /* Received notify packet. Server can receive notify packets from router. 
31    Server then relays the notify messages to clients if needed. */
32
33 void silc_server_notify(SilcServer server,
34                         SilcSocketConnection sock,
35                         SilcPacketContext *packet)
36 {
37   SilcNotifyPayload payload;
38   SilcNotifyType type;
39   SilcArgumentPayload args;
40   SilcChannelID *channel_id = NULL, *channel_id2;
41   SilcClientID *client_id, *client_id2;
42   SilcServerID *server_id;
43   SilcChannelEntry channel;
44   SilcClientEntry client;
45   SilcServerEntry server_entry;
46   SilcChannelClientEntry chl;
47   SilcIDCacheEntry cache;
48   SilcHashTableList htl;
49   uint32 mode;
50   unsigned char *tmp;
51   uint32 tmp_len;
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, &idata);
71     if (dst_sock)
72       /* Relay the packet */
73       silc_server_relay_packet(server, dst_sock, idata->send_key,
74                                idata->hmac_receive, packet, TRUE);
75   }
76
77   /* Parse the Notify Payload */
78   payload = silc_notify_payload_parse(packet->buffer);
79   if (!payload)
80     return;
81
82   /* If we are router and this packet is not already broadcast packet
83      we will broadcast it. The sending socket really cannot be router or
84      the router is buggy. If this packet is coming from router then it must
85      have the broadcast flag set already and we won't do anything. */
86   if (!server->standalone && server->server_type == SILC_ROUTER &&
87       sock->type == SILC_SOCKET_TYPE_SERVER &&
88       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
89     SILC_LOG_DEBUG(("Broadcasting received Notify packet"));
90     if (packet->dst_id_type == SILC_ID_CHANNEL) {
91       /* Packet is destined to channel */
92       channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
93                                   packet->dst_id_type);
94       if (!channel_id)
95         goto out;
96
97       silc_server_packet_send_dest(server, server->router->connection, 
98                                    packet->type,
99                                    packet->flags | SILC_PACKET_FLAG_BROADCAST, 
100                                    channel_id, SILC_ID_CHANNEL,
101                                    packet->buffer->data, packet->buffer->len, 
102                                    FALSE);
103       silc_server_backup_send_dest(server, (SilcServerEntry)sock->user_data, 
104                                    packet->type, packet->flags,
105                                    channel_id, SILC_ID_CHANNEL,
106                                    packet->buffer->data, packet->buffer->len, 
107                                    FALSE, TRUE);
108     } else {
109       /* Packet is destined to client or server */
110       silc_server_packet_send(server, server->router->connection, 
111                               packet->type,
112                               packet->flags | SILC_PACKET_FLAG_BROADCAST, 
113                               packet->buffer->data, packet->buffer->len, 
114                               FALSE);
115       silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
116                               packet->type, packet->flags,
117                               packet->buffer->data, packet->buffer->len, 
118                               FALSE, TRUE);
119     }
120   }
121
122   type = silc_notify_get_type(payload);
123   args = silc_notify_get_args(payload);
124   if (!args)
125     goto out;
126
127   switch(type) {
128   case SILC_NOTIFY_TYPE_JOIN:
129     /* 
130      * Distribute the notify to local clients on the channel
131      */
132     SILC_LOG_DEBUG(("JOIN notify"));
133
134     /* Get Channel ID */
135     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
136     if (!tmp)
137       goto out;
138     channel_id = silc_id_payload_parse_id(tmp, tmp_len);
139     if (!channel_id)
140       goto out;
141
142     /* Get channel entry */
143     channel = silc_idlist_find_channel_by_id(server->global_list, 
144                                              channel_id, NULL);
145     if (!channel) {
146       channel = silc_idlist_find_channel_by_id(server->local_list, 
147                                                channel_id, NULL);
148       if (!channel) {
149         silc_free(channel_id);
150         goto out;
151       }
152     }
153     silc_free(channel_id);
154
155     /* Get client ID */
156     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
157     if (!tmp)
158       goto out;
159     client_id = silc_id_payload_parse_id(tmp, tmp_len);
160     if (!client_id)
161       goto out;
162
163     /* If the the client is not in local list we check global list (ie. the
164        channel will be global channel) and if it does not exist then create
165        entry for the client. */
166     client = silc_idlist_find_client_by_id(server->global_list, 
167                                            client_id, server->server_type, 
168                                            NULL);
169     if (!client) {
170       client = silc_idlist_find_client_by_id(server->local_list, 
171                                              client_id, server->server_type,
172                                              NULL);
173       if (!client) {
174         /* If router did not find the client the it is bogus */
175         if (server->server_type != SILC_SERVER)
176           goto out;
177
178         client = 
179           silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
180                                  silc_id_dup(client_id, SILC_ID_CLIENT), 
181                                  sock->user_data, NULL);
182         if (!client) {
183           SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
184           silc_free(client_id);
185           goto out;
186         }
187
188         client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
189       }
190     }
191
192     /* Do not process the notify if the client is not registered */
193     if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
194       break;
195
196     /* Do not add client to channel if it is there already */
197     if (silc_server_client_on_channel(client, channel)) {
198       SILC_LOG_DEBUG(("Client already on channel"));
199       break;
200     }
201
202     /* Send to channel */
203     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
204                                        FALSE, packet->buffer->data, 
205                                        packet->buffer->len, FALSE);
206
207     if (server->server_type != SILC_ROUTER && 
208         sock->type == SILC_SOCKET_TYPE_ROUTER)
209       /* The channel is global now */
210       channel->global_users = TRUE;
211
212     /* JOIN the global client to the channel (local clients (if router 
213        created the channel) is joined in the pending JOIN command). */
214     chl = silc_calloc(1, sizeof(*chl));
215     chl->client = client;
216     chl->channel = channel;
217
218     /* If this is the first one on the channel then it is the founder of
219        the channel. */
220     if (!silc_hash_table_count(channel->user_list))
221       chl->mode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
222
223     silc_hash_table_add(channel->user_list, client, chl);
224     silc_hash_table_add(client->channels, channel, chl);
225     silc_free(client_id);
226
227     break;
228
229   case SILC_NOTIFY_TYPE_LEAVE:
230     /* 
231      * Distribute the notify to local clients on the channel
232      */
233     SILC_LOG_DEBUG(("LEAVE notify"));
234
235     if (!channel_id) {
236       channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
237                                   packet->dst_id_type);
238       if (!channel_id)
239         goto out;
240     }
241
242     /* Get channel entry */
243     channel = silc_idlist_find_channel_by_id(server->global_list, 
244                                              channel_id, NULL);
245     if (!channel) { 
246       channel = silc_idlist_find_channel_by_id(server->local_list, 
247                                                channel_id, NULL);
248       if (!channel) {
249         silc_free(channel_id);
250         goto out;
251       }
252     }
253
254     /* Get client ID */
255     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
256     if (!tmp) {
257       silc_free(channel_id);
258       goto out;
259     }
260     client_id = silc_id_payload_parse_id(tmp, tmp_len);
261     if (!client_id) {
262       silc_free(channel_id);
263       goto out;
264     }
265
266     /* Get client entry */
267     client = silc_idlist_find_client_by_id(server->global_list, 
268                                            client_id, TRUE, NULL);
269     if (!client) {
270       client = silc_idlist_find_client_by_id(server->local_list, 
271                                              client_id, TRUE, NULL);
272       if (!client) {
273         silc_free(client_id);
274         silc_free(channel_id);
275         goto out;
276       }
277     }
278     silc_free(client_id);
279
280     /* Check if on channel */
281     if (!silc_server_client_on_channel(client, channel))
282       break;
283
284     /* Send the leave notify to channel */
285     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
286                                        FALSE, packet->buffer->data, 
287                                        packet->buffer->len, FALSE);
288
289     /* Remove the user from channel */
290     silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
291     break;
292
293   case SILC_NOTIFY_TYPE_SIGNOFF:
294     /* 
295      * Distribute the notify to local clients on the channel
296      */
297     SILC_LOG_DEBUG(("SIGNOFF notify"));
298
299     /* Get client ID */
300     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
301     if (!tmp)
302       goto out;
303     client_id = silc_id_payload_parse_id(tmp, tmp_len);
304     if (!client_id)
305       goto out;
306
307     /* Get client entry */
308     client = silc_idlist_find_client_by_id(server->global_list, 
309                                            client_id, TRUE, &cache);
310     if (!client) {
311       client = silc_idlist_find_client_by_id(server->local_list, 
312                                              client_id, TRUE, &cache);
313       if (!client) {
314         silc_free(client_id);
315         goto out;
316       }
317     }
318     silc_free(client_id);
319
320     /* Get signoff message */
321     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
322     if (tmp_len > 128)
323       tmp = NULL;
324
325     /* Remove the client from all channels. */
326     silc_server_remove_from_channels(server, NULL, client, TRUE, tmp, FALSE);
327
328     client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
329     cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
330     server->stat.clients--;
331     if (server->server_type == SILC_ROUTER)
332       server->stat.cell_clients--;
333     break;
334
335   case SILC_NOTIFY_TYPE_TOPIC_SET:
336     /* 
337      * Distribute the notify to local clients on the channel
338      */
339
340     SILC_LOG_DEBUG(("TOPIC SET notify"));
341
342     if (!channel_id) {
343       channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
344                                   packet->dst_id_type);
345       if (!channel_id)
346         goto out;
347     }
348
349     /* Get channel entry */
350     channel = silc_idlist_find_channel_by_id(server->global_list, 
351                                              channel_id, NULL);
352     if (!channel) {
353       channel = silc_idlist_find_channel_by_id(server->local_list, 
354                                                channel_id, NULL);
355       if (!channel) {
356         silc_free(channel_id);
357         goto out;
358       }
359     }
360
361     /* Get the topic */
362     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
363     if (!tmp) {
364       silc_free(channel_id);
365       goto out;
366     }
367
368     if (channel->topic)
369       silc_free(channel->topic);
370     channel->topic = silc_calloc(tmp_len + 1, sizeof(*channel->topic));
371     memcpy(channel->topic, tmp, tmp_len);
372
373     /* Send the same notify to the channel */
374     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
375                                        FALSE, packet->buffer->data, 
376                                        packet->buffer->len, FALSE);
377     silc_free(channel_id);
378     break;
379
380   case SILC_NOTIFY_TYPE_NICK_CHANGE:
381     {
382       /* 
383        * Distribute the notify to local clients on the channel
384        */
385       unsigned char *id, *id2;
386
387       SILC_LOG_DEBUG(("NICK CHANGE notify"));
388       
389       /* Get old client ID */
390       id = silc_argument_get_arg_type(args, 1, &tmp_len);
391       if (!id)
392         goto out;
393       client_id = silc_id_payload_parse_id(id, tmp_len);
394       if (!client_id)
395         goto out;
396       
397       /* Get new client ID */
398       id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
399       if (!id2)
400         goto out;
401       client_id2 = silc_id_payload_parse_id(id2, tmp_len);
402       if (!client_id2)
403         goto out;
404       
405       SILC_LOG_DEBUG(("Old Client ID id(%s)", 
406                       silc_id_render(client_id, SILC_ID_CLIENT)));
407       SILC_LOG_DEBUG(("New Client ID id(%s)", 
408                       silc_id_render(client_id2, SILC_ID_CLIENT)));
409
410       /* Replace the Client ID */
411       client = silc_idlist_replace_client_id(server->global_list, client_id,
412                                              client_id2);
413       if (!client)
414         client = silc_idlist_replace_client_id(server->local_list, client_id, 
415                                                client_id2);
416
417       if (client) {
418         /* The nickname is not valid anymore, set it NULL. This causes that
419            the nickname will be queried if someone wants to know it. */
420         if (client->nickname)
421           silc_free(client->nickname);
422         client->nickname = NULL;
423
424         /* Send the NICK_CHANGE notify type to local clients on the channels
425            this client is joined to. */
426         silc_server_send_notify_on_channels(server, NULL, client, 
427                                             SILC_NOTIFY_TYPE_NICK_CHANGE, 2,
428                                             id, tmp_len, 
429                                             id2, tmp_len);
430       }
431
432       silc_free(client_id);
433       if (!client)
434         silc_free(client_id2);
435       break;
436     }
437
438   case SILC_NOTIFY_TYPE_CMODE_CHANGE:
439     /* 
440      * Distribute the notify to local clients on the channel
441      */
442     
443     SILC_LOG_DEBUG(("CMODE CHANGE notify"));
444       
445     if (!channel_id) {
446       channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
447                                   packet->dst_id_type);
448       if (!channel_id)
449         goto out;
450     }
451
452     /* Get channel entry */
453     channel = silc_idlist_find_channel_by_id(server->global_list, 
454                                              channel_id, NULL);
455     if (!channel) {
456       channel = silc_idlist_find_channel_by_id(server->local_list, 
457                                                channel_id, NULL);
458       if (!channel) {
459         silc_free(channel_id);
460         goto out;
461       }
462     }
463
464     /* Get the mode */
465     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
466     if (!tmp) {
467       silc_free(channel_id);
468       goto out;
469     }
470
471     SILC_GET32_MSB(mode, tmp);
472
473     /* Check if mode changed */
474     if (channel->mode == mode)
475       break;
476
477     /* Send the same notify to the channel */
478     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
479                                        FALSE, packet->buffer->data, 
480                                        packet->buffer->len, FALSE);
481
482     /* If the channel had private keys set and the mode was removed then
483        we must re-generate and re-distribute a new channel key */
484     if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY &&
485         !(mode & SILC_CHANNEL_MODE_PRIVKEY)) {
486       /* Re-generate channel key */
487       if (!silc_server_create_channel_key(server, channel, 0))
488         goto out;
489       
490       /* Send the channel key. This sends it to our local clients and if
491          we are normal server to our router as well. */
492       silc_server_send_channel_key(server, NULL, channel, 
493                                    server->server_type == SILC_ROUTER ? 
494                                    FALSE : !server->standalone);
495     }
496
497     /* Change mode */
498     channel->mode = mode;
499     silc_free(channel_id);
500
501     /* Get the hmac */
502     tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
503     if (tmp) {
504       unsigned char hash[32];
505
506       if (channel->hmac)
507         silc_hmac_free(channel->hmac);
508       if (!silc_hmac_alloc(tmp, NULL, &channel->hmac))
509         goto out;
510
511       /* Set the HMAC key out of current channel key. The client must do
512          this locally. */
513       silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, 
514                      channel->key_len / 8, 
515                      hash);
516       silc_hmac_set_key(channel->hmac, hash, 
517                         silc_hash_len(silc_hmac_get_hash(channel->hmac)));
518       memset(hash, 0, sizeof(hash));
519     }
520
521     break;
522
523   case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
524     {
525       /* 
526        * Distribute the notify to local clients on the channel
527        */
528       SilcChannelClientEntry chl2 = NULL;
529       bool notify_sent = FALSE;
530       
531       SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
532       
533       if (!channel_id) {
534         channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
535                                     packet->dst_id_type);
536         if (!channel_id)
537           goto out;
538       }
539
540       /* Get channel entry */
541       channel = silc_idlist_find_channel_by_id(server->global_list, 
542                                                channel_id, NULL);
543       if (!channel) {
544         channel = silc_idlist_find_channel_by_id(server->local_list, 
545                                                  channel_id, NULL);
546         if (!channel) {
547           silc_free(channel_id);
548           goto out;
549         }
550       }
551
552       /* Get the mode */
553       tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
554       if (!tmp) {
555         silc_free(channel_id);
556         goto out;
557       }
558       
559       SILC_GET32_MSB(mode, tmp);
560       
561       /* Get target client */
562       tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
563       if (!tmp)
564         goto out;
565       client_id = silc_id_payload_parse_id(tmp, tmp_len);
566       if (!client_id)
567         goto out;
568       
569       /* Get client entry */
570       client = silc_idlist_find_client_by_id(server->global_list, 
571                                              client_id, TRUE, NULL);
572       if (!client) {
573         client = silc_idlist_find_client_by_id(server->local_list, 
574                                                client_id, TRUE, NULL);
575         if (!client) {
576           silc_free(client_id);
577           goto out;
578         }
579       }
580       silc_free(client_id);
581
582       /* Get entry to the channel user list */
583       silc_hash_table_list(channel->user_list, &htl);
584       while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
585         /* If the mode is channel founder and we already find a client 
586            to have that mode on the channel we will enforce the sender
587            to change the channel founder mode away. There can be only one
588            channel founder on the channel. */
589         if (server->server_type == SILC_ROUTER &&
590             mode & SILC_CHANNEL_UMODE_CHANFO &&
591             chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
592           SilcBuffer idp;
593           unsigned char cumode[4];
594
595           if (chl->client == client && chl->mode == mode) {
596             notify_sent = TRUE;
597             break;
598           }
599
600           mode &= ~SILC_CHANNEL_UMODE_CHANFO;
601           silc_server_send_notify_cumode(server, sock, FALSE, channel, mode,
602                                          client->id, SILC_ID_CLIENT,
603                                          client->id);
604           
605           idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
606           SILC_PUT32_MSB(mode, cumode);
607           silc_server_send_notify_to_channel(server, sock, channel, FALSE, 
608                                              SILC_NOTIFY_TYPE_CUMODE_CHANGE,
609                                              3, idp->data, idp->len,
610                                              cumode, 4,
611                                              idp->data, idp->len);
612           silc_buffer_free(idp);
613           notify_sent = TRUE;
614
615           /* Force the mode change if we alredy set the mode */
616           if (chl2) {
617             chl2->mode = mode;
618             silc_free(channel_id);
619             goto out;
620           }
621         }
622         
623         if (chl->client == client) {
624           if (chl->mode == mode) {
625             notify_sent = TRUE;
626             break;
627           }
628
629           /* Change the mode */
630           chl->mode = mode;
631           if (!(mode & SILC_CHANNEL_UMODE_CHANFO))
632             break;
633           
634           chl2 = chl;
635         }
636       }
637       
638       /* Send the same notify to the channel */
639       if (!notify_sent)
640         silc_server_packet_send_to_channel(server, sock, channel, 
641                                            packet->type, 
642                                            FALSE, packet->buffer->data, 
643                                            packet->buffer->len, FALSE);
644       
645       silc_free(channel_id);
646       break;
647     }
648
649   case SILC_NOTIFY_TYPE_INVITE:
650
651     if (packet->dst_id_type == SILC_ID_CLIENT)
652       goto out;
653
654     SILC_LOG_DEBUG(("INVITE notify"));
655
656     /* Get Channel ID */
657     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
658     if (!tmp)
659       goto out;
660     channel_id = silc_id_payload_parse_id(tmp, tmp_len);
661     if (!channel_id)
662       goto out;
663
664     /* Get channel entry */
665     channel = silc_idlist_find_channel_by_id(server->global_list, 
666                                              channel_id, NULL);
667     if (!channel) {
668       channel = silc_idlist_find_channel_by_id(server->local_list, 
669                                                channel_id, NULL);
670       if (!channel) {
671         silc_free(channel_id);
672         goto out;
673       }
674     }
675     silc_free(channel_id);
676
677     /* Get the added invite */
678     tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
679     if (tmp) {
680       if (!channel->invite_list)
681         channel->invite_list = silc_calloc(tmp_len + 2, 
682                                            sizeof(*channel->invite_list));
683       else
684         channel->invite_list = silc_realloc(channel->invite_list, 
685                                             sizeof(*channel->invite_list) * 
686                                             (tmp_len + 
687                                              strlen(channel->invite_list) + 
688                                              2));
689       if (tmp[tmp_len - 1] == ',')
690         tmp[tmp_len - 1] = '\0';
691       
692       strncat(channel->invite_list, tmp, tmp_len);
693       strncat(channel->invite_list, ",", 1);
694     }
695
696     /* Get the deleted invite */
697     tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
698     if (tmp && channel->invite_list) {
699       char *start, *end, *n;
700       
701       if (!strncmp(channel->invite_list, tmp, 
702                    strlen(channel->invite_list) - 1)) {
703         silc_free(channel->invite_list);
704         channel->invite_list = NULL;
705       } else {
706         start = strstr(channel->invite_list, tmp);
707         if (start && strlen(start) >= tmp_len) {
708           end = start + tmp_len;
709           n = silc_calloc(strlen(channel->invite_list) - tmp_len, sizeof(*n));
710           strncat(n, channel->invite_list, start - channel->invite_list);
711           strncat(n, end + 1, ((channel->invite_list + 
712                                 strlen(channel->invite_list)) - end) - 1);
713           silc_free(channel->invite_list);
714           channel->invite_list = n;
715         }
716       }
717     }
718
719     break;
720
721   case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
722     /*
723      * Distribute to the local clients on the channel and change the
724      * channel ID.
725      */
726
727     SILC_LOG_DEBUG(("CHANNEL CHANGE"));
728
729     if (sock->type != SILC_SOCKET_TYPE_ROUTER)
730       break;
731
732     /* Get the old Channel ID */
733     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
734     if (!tmp)
735       goto out;
736     channel_id = silc_id_payload_parse_id(tmp, tmp_len);
737     if (!channel_id)
738       goto out;
739
740     /* Get the channel entry */
741     channel = silc_idlist_find_channel_by_id(server->global_list, 
742                                              channel_id, NULL);
743     if (!channel) {
744       channel = silc_idlist_find_channel_by_id(server->local_list, 
745                                                channel_id, NULL);
746       if (!channel) {
747         silc_free(channel_id);
748         goto out;
749       }
750     }
751
752     /* Send the notify to the channel */
753     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
754                                        FALSE, packet->buffer->data, 
755                                        packet->buffer->len, FALSE);
756
757     /* Get the new Channel ID */
758     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
759     if (!tmp)
760       goto out;
761     channel_id2 = silc_id_payload_parse_id(tmp, tmp_len);
762     if (!channel_id2)
763       goto out;
764
765     SILC_LOG_DEBUG(("Old Channel ID id(%s)", 
766                     silc_id_render(channel_id, SILC_ID_CHANNEL)));
767     SILC_LOG_DEBUG(("New Channel ID id(%s)", 
768                     silc_id_render(channel_id2, SILC_ID_CHANNEL)));
769
770     /* Replace the Channel ID */
771     if (!silc_idlist_replace_channel_id(server->global_list, channel_id,
772                                         channel_id2))
773       if (!silc_idlist_replace_channel_id(server->local_list, channel_id,
774                                           channel_id2)) {
775         silc_free(channel_id2);
776         channel_id2 = NULL;
777       }
778
779     if (channel_id2) {
780       SilcBuffer users = NULL, users_modes = NULL;
781       
782       /* Re-announce our clients on the channel as the ID has changed now */
783       silc_server_announce_get_channel_users(server, channel, &users,
784                                              &users_modes);
785       if (users) {
786         silc_buffer_push(users, users->data - users->head);
787         silc_server_packet_send(server, sock,
788                                 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
789                                 users->data, users->len, FALSE);
790         silc_buffer_free(users);
791       }
792       if (users_modes) {
793         silc_buffer_push(users_modes, users_modes->data - users_modes->head);
794         silc_server_packet_send_dest(server, sock,
795                                      SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
796                                      channel->id, SILC_ID_CHANNEL,
797                                      users_modes->data, 
798                                      users_modes->len, FALSE);
799         silc_buffer_free(users_modes);
800       }
801     }
802
803     silc_free(channel_id);
804
805     break;
806
807   case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
808     /* 
809      * Remove the server entry and all clients that this server owns.
810      */
811
812     SILC_LOG_DEBUG(("SERVER SIGNOFF notify"));
813
814     /* Get Server ID */
815     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
816     if (!tmp)
817       goto out;
818     server_id = silc_id_payload_parse_id(tmp, tmp_len);
819     if (!server_id)
820       goto out;
821
822     /* Get server entry */
823     server_entry = silc_idlist_find_server_by_id(server->global_list, 
824                                                  server_id, TRUE, NULL);
825     if (!server_entry) {
826       server_entry = silc_idlist_find_server_by_id(server->local_list, 
827                                                    server_id, TRUE, NULL);
828       if (!server_entry) {
829         silc_free(server_id);
830         goto out;
831       }
832     }
833     silc_free(server_id);
834
835     /* Free all client entries that this server owns as they will
836        become invalid now as well. */
837     silc_server_remove_clients_by_server(server, server_entry, TRUE);
838
839     /* Remove the server entry */
840     if (!silc_idlist_del_server(server->global_list, server_entry))
841       silc_idlist_del_server(server->local_list, server_entry);
842
843     /* XXX update statistics */
844
845     break;
846
847   case SILC_NOTIFY_TYPE_KICKED:
848     /* 
849      * Distribute the notify to local clients on the channel
850      */
851     
852     SILC_LOG_DEBUG(("KICKED notify"));
853       
854     if (!channel_id) {
855       channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
856                                   packet->dst_id_type);
857       if (!channel_id)
858         goto out;
859     }
860
861     /* Get channel entry */
862     channel = silc_idlist_find_channel_by_id(server->global_list, 
863                                              channel_id, NULL);
864     if (!channel) {
865       channel = silc_idlist_find_channel_by_id(server->local_list, 
866                                                channel_id, NULL);
867       if (!channel) {
868         silc_free(channel_id);
869         goto out;
870       }
871     }
872     silc_free(channel_id);
873
874     /* Get client ID */
875     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
876     if (!tmp)
877       goto out;
878     client_id = silc_id_payload_parse_id(tmp, tmp_len);
879     if (!client_id)
880       goto out;
881
882     /* If the the client is not in local list we check global list */
883     client = silc_idlist_find_client_by_id(server->global_list, 
884                                            client_id, TRUE, NULL);
885     if (!client) {
886       client = silc_idlist_find_client_by_id(server->local_list, 
887                                              client_id, TRUE, NULL);
888       if (!client) {
889         silc_free(client_id);
890         goto out;
891       }
892     }
893
894     /* Send to channel */
895     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
896                                        FALSE, packet->buffer->data, 
897                                        packet->buffer->len, FALSE);
898
899     /* Remove the client from channel */
900     silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
901
902     break;
903
904   case SILC_NOTIFY_TYPE_KILLED:
905     {
906       /* 
907        * Distribute the notify to local clients on channels
908        */
909       unsigned char *id;
910       uint32 id_len;
911     
912       SILC_LOG_DEBUG(("KILLED notify"));
913       
914       /* Get client ID */
915       id = silc_argument_get_arg_type(args, 1, &id_len);
916       if (!id)
917         goto out;
918       client_id = silc_id_payload_parse_id(id, id_len);
919       if (!client_id)
920         goto out;
921
922       /* If the the client is not in local list we check global list */
923       client = silc_idlist_find_client_by_id(server->global_list, 
924                                              client_id, TRUE, NULL);
925       if (!client) {
926         client = silc_idlist_find_client_by_id(server->local_list, 
927                                                client_id, TRUE, NULL);
928         if (!client) {
929           silc_free(client_id);
930           goto out;
931         }
932       }
933       silc_free(client_id);
934
935       /* If the client is one of ours, then close the connection to the
936          client now. This removes the client from all channels as well. */
937       if (packet->dst_id_type == SILC_ID_CLIENT && client->connection) {
938         sock = client->connection;
939         silc_server_free_client_data(server, NULL, client, FALSE, NULL);
940         silc_server_close_connection(server, sock);
941         break;
942       }
943
944       /* Get comment */
945       tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
946       if (tmp_len > 128)
947         tmp = NULL;
948
949       /* Send the notify to local clients on the channels except to the
950          client who is killed. */
951       silc_server_send_notify_on_channels(server, client, client,
952                                           SILC_NOTIFY_TYPE_KILLED, 
953                                           tmp ? 2 : 1,
954                                           id, id_len, 
955                                           tmp, tmp_len);
956
957       /* Remove the client from all channels */
958       silc_server_remove_from_channels(server, NULL, client, FALSE, NULL, 
959                                        FALSE);
960
961       break;
962     }
963
964   case SILC_NOTIFY_TYPE_UMODE_CHANGE:
965     /*
966      * Save the mode of the client.
967      */
968
969     SILC_LOG_DEBUG(("UMODE_CHANGE notify"));
970       
971     /* Get client ID */
972     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
973     if (!tmp)
974       goto out;
975     client_id = silc_id_payload_parse_id(tmp, tmp_len);
976     if (!client_id)
977       goto out;
978
979     /* Get client entry */
980     client = silc_idlist_find_client_by_id(server->global_list, 
981                                            client_id, TRUE, NULL);
982     if (!client) {
983       client = silc_idlist_find_client_by_id(server->local_list, 
984                                              client_id, TRUE, NULL);
985       if (!client) {
986         silc_free(client_id);
987         goto out;
988       }
989     }
990     silc_free(client_id);
991
992     /* Get the mode */
993     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
994     if (!tmp)
995       goto out;
996
997     /* Save the mode */
998     SILC_GET32_MSB(client->mode, tmp);
999
1000     break;
1001
1002   case SILC_NOTIFY_TYPE_BAN:
1003     /*
1004      * Save the ban
1005      */
1006
1007     SILC_LOG_DEBUG(("BAN notify"));
1008     
1009     /* Get Channel ID */
1010     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1011     if (!tmp)
1012       goto out;
1013     channel_id = silc_id_payload_parse_id(tmp, tmp_len);
1014     if (!channel_id)
1015       goto out;
1016     
1017     /* Get channel entry */
1018     channel = silc_idlist_find_channel_by_id(server->global_list, 
1019                                              channel_id, NULL);
1020     if (!channel) {
1021       channel = silc_idlist_find_channel_by_id(server->local_list, 
1022                                                channel_id, NULL);
1023       if (!channel) {
1024         silc_free(channel_id);
1025         goto out;
1026       }
1027     }
1028     silc_free(channel_id);
1029
1030     /* Get the new ban and add it to the ban list */
1031     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1032     if (tmp) {
1033       if (!channel->ban_list)
1034         channel->ban_list = silc_calloc(tmp_len + 2, 
1035                                         sizeof(*channel->ban_list));
1036       else
1037         channel->ban_list = silc_realloc(channel->ban_list, 
1038                                          sizeof(*channel->ban_list) * 
1039                                          (tmp_len + 
1040                                           strlen(channel->ban_list) + 2));
1041       strncat(channel->ban_list, tmp, tmp_len);
1042       strncat(channel->ban_list, ",", 1);
1043     }
1044
1045     /* Get the ban to be removed and remove it from the list */
1046     tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1047     if (tmp && channel->ban_list) {
1048       char *start, *end, *n;
1049       
1050       if (!strcmp(channel->ban_list, tmp)) {
1051         silc_free(channel->ban_list);
1052         channel->ban_list = NULL;
1053       } else {
1054         start = strstr(channel->ban_list, tmp);
1055         if (start && strlen(start) >= tmp_len) {
1056           end = start + tmp_len;
1057           n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
1058           strncat(n, channel->ban_list, start - channel->ban_list);
1059           strncat(n, end + 1, ((channel->ban_list + 
1060                                 strlen(channel->ban_list)) - end) - 1);
1061           silc_free(channel->ban_list);
1062           channel->ban_list = n;
1063         }
1064       }
1065     }
1066
1067     break;
1068
1069     /* Ignore rest of the notify types for now */
1070   case SILC_NOTIFY_TYPE_NONE:
1071   case SILC_NOTIFY_TYPE_MOTD:
1072     break;
1073   default:
1074     break;
1075   }
1076
1077  out:
1078   silc_notify_payload_free(payload);
1079 }
1080
1081 void silc_server_notify_list(SilcServer server,
1082                              SilcSocketConnection sock,
1083                              SilcPacketContext *packet)
1084 {
1085   SilcPacketContext *new;
1086   SilcBuffer buffer;
1087   uint16 len;
1088
1089   SILC_LOG_DEBUG(("Processing Notify List"));
1090
1091   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1092       packet->src_id_type != SILC_ID_SERVER)
1093     return;
1094
1095   /* Make copy of the original packet context, except for the actual
1096      data buffer, which we will here now fetch from the original buffer. */
1097   new = silc_packet_context_alloc();
1098   new->type = SILC_PACKET_NOTIFY;
1099   new->flags = packet->flags;
1100   new->src_id = packet->src_id;
1101   new->src_id_len = packet->src_id_len;
1102   new->src_id_type = packet->src_id_type;
1103   new->dst_id = packet->dst_id;
1104   new->dst_id_len = packet->dst_id_len;
1105   new->dst_id_type = packet->dst_id_type;
1106
1107   buffer = silc_buffer_alloc(1024);
1108   new->buffer = buffer;
1109
1110   while (packet->buffer->len) {
1111     SILC_GET16_MSB(len, packet->buffer->data + 2);
1112     if (len > packet->buffer->len)
1113       break;
1114
1115     if (len > buffer->truelen) {
1116       silc_buffer_free(buffer);
1117       buffer = silc_buffer_alloc(1024 + len);
1118     }
1119
1120     silc_buffer_pull_tail(buffer, len);
1121     silc_buffer_put(buffer, packet->buffer->data, len);
1122
1123     /* Process the Notify */
1124     silc_server_notify(server, sock, new);
1125
1126     silc_buffer_push_tail(buffer, len);
1127     silc_buffer_pull(packet->buffer, len);
1128   }
1129
1130   silc_buffer_free(buffer);
1131   silc_free(new);
1132 }
1133
1134 /* Received private message. This resolves the destination of the message 
1135    and sends the packet. This is used by both server and router.  If the
1136    destination is our locally connected client this sends the packet to
1137    the client. This may also send the message for further routing if
1138    the destination is not in our server (or router). */
1139
1140 void silc_server_private_message(SilcServer server,
1141                                  SilcSocketConnection sock,
1142                                  SilcPacketContext *packet)
1143 {
1144   SilcSocketConnection dst_sock;
1145   SilcIDListData idata;
1146
1147   SILC_LOG_DEBUG(("Start"));
1148
1149   if (packet->src_id_type != SILC_ID_CLIENT ||
1150       packet->dst_id_type != SILC_ID_CLIENT)
1151     return;
1152
1153   if (!packet->dst_id)
1154     return;
1155
1156   /* Get the route to the client */
1157   dst_sock = silc_server_get_client_route(server, packet->dst_id,
1158                                           packet->dst_id_len, NULL, &idata);
1159   if (!dst_sock)
1160     return;
1161
1162   /* Send the private message */
1163   silc_server_send_private_message(server, dst_sock, idata->send_key,
1164                                    idata->hmac_send, packet);
1165 }
1166
1167 /* Received private message key packet.. This packet is never for us. It is to
1168    the client in the packet's destination ID. Sending of this sort of packet
1169    equals sending private message, ie. it is sent point to point from
1170    one client to another. */
1171
1172 void silc_server_private_message_key(SilcServer server,
1173                                      SilcSocketConnection sock,
1174                                      SilcPacketContext *packet)
1175 {
1176   SilcSocketConnection dst_sock;
1177   SilcIDListData idata;
1178
1179   SILC_LOG_DEBUG(("Start"));
1180
1181   if (packet->src_id_type != SILC_ID_CLIENT ||
1182       packet->dst_id_type != SILC_ID_CLIENT)
1183     return;
1184
1185   if (!packet->dst_id)
1186     return;
1187
1188   /* Get the route to the client */
1189   dst_sock = silc_server_get_client_route(server, packet->dst_id,
1190                                           packet->dst_id_len, NULL, &idata);
1191   if (!dst_sock)
1192     return;
1193
1194   /* Relay the packet */
1195   silc_server_relay_packet(server, dst_sock, idata->send_key,
1196                            idata->hmac_send, packet, FALSE);
1197 }
1198
1199 /* Processes incoming command reply packet. The command reply packet may
1200    be destined to one of our clients or it may directly for us. We will 
1201    call the command reply routine after processing the packet. */
1202
1203 void silc_server_command_reply(SilcServer server,
1204                                SilcSocketConnection sock,
1205                                SilcPacketContext *packet)
1206 {
1207   SilcBuffer buffer = packet->buffer;
1208   SilcClientEntry client = NULL;
1209   SilcSocketConnection dst_sock;
1210   SilcIDListData idata;
1211   SilcClientID *id = NULL;
1212
1213   SILC_LOG_DEBUG(("Start"));
1214
1215   /* Source must be server or router */
1216   if (packet->src_id_type != SILC_ID_SERVER &&
1217       sock->type != SILC_SOCKET_TYPE_ROUTER)
1218     return;
1219
1220   if (packet->dst_id_type == SILC_ID_CHANNEL)
1221     return;
1222
1223   if (packet->dst_id_type == SILC_ID_CLIENT) {
1224     /* Destination must be one of ours */
1225     id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
1226     if (!id)
1227       return;
1228     client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
1229     if (!client) {
1230       SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
1231       silc_free(id);
1232       return;
1233     }
1234   }
1235
1236   if (packet->dst_id_type == SILC_ID_SERVER) {
1237     /* For now this must be for us */
1238     if (memcmp(packet->dst_id, server->id_string, packet->dst_id_len)) {
1239       SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
1240       return;
1241     }
1242   }
1243
1244   /* Execute command reply locally for the command */
1245   silc_server_command_reply_process(server, sock, buffer);
1246
1247   if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
1248     /* Relay the packet to the client */
1249     
1250     dst_sock = (SilcSocketConnection)client->connection;
1251     silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len 
1252                      + packet->dst_id_len + packet->padlen);
1253     
1254     silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
1255     silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
1256     
1257     idata = (SilcIDListData)client;
1258     
1259     /* Encrypt packet */
1260     silc_packet_encrypt(idata->send_key, idata->hmac_send, dst_sock->outbuf, 
1261                         buffer->len);
1262     
1263     /* Send the packet */
1264     silc_server_packet_send_real(server, dst_sock, TRUE);
1265
1266     silc_free(id);
1267   }
1268 }
1269
1270 /* Process received channel message. The message can be originated from
1271    client or server. */
1272
1273 void silc_server_channel_message(SilcServer server,
1274                                  SilcSocketConnection sock,
1275                                  SilcPacketContext *packet)
1276 {
1277   SilcChannelEntry channel = NULL;
1278   SilcChannelID *id = NULL;
1279   void *sender = NULL;
1280   void *sender_entry = NULL;
1281   bool local = TRUE;
1282
1283   SILC_LOG_DEBUG(("Processing channel message"));
1284
1285   /* Sanity checks */
1286   if (packet->dst_id_type != SILC_ID_CHANNEL) {
1287     SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1288     goto out;
1289   }
1290
1291   /* Find channel entry */
1292   id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
1293   if (!id)
1294     goto out;
1295   channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
1296   if (!channel) {
1297     channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
1298     if (!channel) {
1299       SILC_LOG_DEBUG(("Could not find channel"));
1300       goto out;
1301     }
1302   }
1303
1304   /* See that this client is on the channel. If the original sender is
1305      not client (as it can be server as well) we don't do the check. */
1306   sender = silc_id_str2id(packet->src_id, packet->src_id_len, 
1307                           packet->src_id_type);
1308   if (!sender)
1309     goto out;
1310   if (packet->src_id_type == SILC_ID_CLIENT) {
1311     sender_entry = silc_idlist_find_client_by_id(server->local_list, 
1312                                                  sender, TRUE, NULL);
1313     if (!sender_entry) {
1314       local = FALSE;
1315       sender_entry = silc_idlist_find_client_by_id(server->global_list, 
1316                                                    sender, TRUE, NULL);
1317     }
1318     if (!sender_entry || !silc_server_client_on_channel(sender_entry, 
1319                                                         channel)) {
1320       SILC_LOG_DEBUG(("Client not on channel"));
1321       goto out;
1322     }
1323
1324     /* If the packet is coming from router, but the client entry is
1325        local entry to us then some router is rerouting this to us and it is
1326        not allowed. */
1327     if (server->server_type == SILC_ROUTER &&
1328         sock->type == SILC_SOCKET_TYPE_ROUTER && local) {
1329       SILC_LOG_DEBUG(("Channel message rerouted to the sender, drop it"));
1330       goto out;
1331     }
1332   }
1333
1334   /* Distribute the packet to our local clients. This will send the
1335      packet for further routing as well, if needed. */
1336   silc_server_packet_relay_to_channel(server, sock, channel, sender,
1337                                       packet->src_id_type, sender_entry,
1338                                       packet->buffer->data,
1339                                       packet->buffer->len, FALSE);
1340
1341  out:
1342   if (sender)
1343     silc_free(sender);
1344   if (id)
1345     silc_free(id);
1346 }
1347
1348 /* Received channel key packet. We distribute the key to all of our locally
1349    connected clients on the channel. */
1350
1351 void silc_server_channel_key(SilcServer server,
1352                              SilcSocketConnection sock,
1353                              SilcPacketContext *packet)
1354 {
1355   SilcBuffer buffer = packet->buffer;
1356   SilcChannelEntry channel;
1357
1358   if (packet->src_id_type != SILC_ID_SERVER ||
1359       (server->server_type == SILC_ROUTER &&
1360        sock->type == SILC_SOCKET_TYPE_ROUTER))
1361     return;
1362
1363   /* Save the channel key */
1364   channel = silc_server_save_channel_key(server, buffer, NULL);
1365   if (!channel)
1366     return;
1367
1368   /* Distribute the key to everybody who is on the channel. If we are router
1369      we will also send it to locally connected servers. */
1370   silc_server_send_channel_key(server, sock, channel, FALSE);
1371   
1372   if (server->server_type != SILC_BACKUP_ROUTER) {
1373     /* Distribute to local cell backup routers. */
1374     silc_server_backup_send(server, (SilcServerEntry)sock->user_data, 
1375                             SILC_PACKET_CHANNEL_KEY, 0,
1376                             buffer->data, buffer->len, FALSE, TRUE);
1377   }
1378 }
1379
1380 /* Received New Client packet and processes it.  Creates Client ID for the
1381    client. Client becomes registered after calling this functions. */
1382
1383 SilcClientEntry silc_server_new_client(SilcServer server,
1384                                        SilcSocketConnection sock,
1385                                        SilcPacketContext *packet)
1386 {
1387   SilcBuffer buffer = packet->buffer;
1388   SilcClientEntry client;
1389   SilcClientID *client_id;
1390   SilcBuffer reply;
1391   SilcIDListData idata;
1392   char *username = NULL, *realname = NULL, *id_string;
1393   uint32 id_len;
1394   int ret;
1395   char *hostname, *nickname;
1396   int nickfail = 0;
1397
1398   SILC_LOG_DEBUG(("Creating new client"));
1399
1400   if (sock->type != SILC_SOCKET_TYPE_CLIENT)
1401     return NULL;
1402
1403   /* Take client entry */
1404   client = (SilcClientEntry)sock->user_data;
1405   idata = (SilcIDListData)client;
1406
1407   /* Remove the old cache entry */
1408   if (!silc_idcache_del_by_context(server->local_list->clients, client)) {
1409     SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
1410     silc_server_disconnect_remote(server, sock, "Server closed connection: "
1411                                   "Unknown client");
1412     return NULL;
1413   }
1414
1415   /* Parse incoming packet */
1416   ret = silc_buffer_unformat(buffer,
1417                              SILC_STR_UI16_STRING_ALLOC(&username),
1418                              SILC_STR_UI16_STRING_ALLOC(&realname),
1419                              SILC_STR_END);
1420   if (ret == -1) {
1421     if (username)
1422       silc_free(username);
1423     if (realname)
1424       silc_free(realname);
1425     silc_server_disconnect_remote(server, sock, "Server closed connection: "
1426                                   "Incomplete client information");
1427     return NULL;
1428   }
1429
1430   if (!username) {
1431     silc_free(username);
1432     if (realname)
1433       silc_free(realname);
1434     silc_server_disconnect_remote(server, sock, "Server closed connection: "
1435                                   "Incomplete client information");
1436     return NULL;
1437   }
1438
1439   if (strlen(username) > 128)
1440     username[127] = '\0';
1441
1442   nickname = strdup(username);
1443
1444   /* Make sanity checks for the hostname of the client. If the hostname
1445      is provided in the `username' check that it is the same than the
1446      resolved hostname, or if not resolved the hostname that appears in
1447      the client's public key. If the hostname is not present then put
1448      it from the resolved name or from the public key. */
1449   if (strchr(username, '@')) {
1450     SilcPublicKeyIdentifier pident;
1451     int tlen = strcspn(username, "@");
1452     char *phostname = NULL;
1453
1454     hostname = silc_calloc((strlen(username) - tlen) + 1, sizeof(char));
1455     memcpy(hostname, username + tlen + 1, strlen(username) - tlen - 1);
1456
1457     if (strcmp(sock->hostname, sock->ip) && 
1458         strcmp(sock->hostname, hostname)) {
1459       silc_free(username);
1460       silc_free(hostname);
1461       if (realname)
1462         silc_free(realname);
1463       silc_server_disconnect_remote(server, sock, 
1464                                     "Server closed connection: "
1465                                     "Incomplete client information");
1466       return NULL;
1467     }
1468     
1469     pident = silc_pkcs_decode_identifier(client->data.public_key->identifier);
1470     if (pident) {
1471       phostname = strdup(pident->host);
1472       silc_pkcs_free_identifier(pident);
1473     }
1474
1475     if (!strcmp(sock->hostname, sock->ip) && 
1476         phostname && strcmp(phostname, hostname)) {
1477       silc_free(username);
1478       silc_free(hostname);
1479       if (phostname)
1480         silc_free(phostname);
1481       if (realname)
1482         silc_free(realname);
1483       silc_server_disconnect_remote(server, sock, 
1484                                     "Server closed connection: "
1485                                     "Incomplete client information");
1486       return NULL;
1487     }
1488     
1489     if (phostname)
1490       silc_free(phostname);
1491   } else {
1492     /* The hostname is not present, add it. */
1493     char *newusername;
1494     /* XXX For now we cannot take the host name from the public key since
1495        they are not trusted or we cannot verify them as trusted. Just take
1496        what the resolved name or address is. */
1497 #if 0
1498     if (strcmp(sock->hostname, sock->ip)) {
1499 #endif
1500       newusername = silc_calloc(strlen(username) + 
1501                                 strlen(sock->hostname) + 2,
1502                                 sizeof(*newusername));
1503       strncat(newusername, username, strlen(username));
1504       strncat(newusername, "@", 1);
1505       strncat(newusername, sock->hostname, strlen(sock->hostname));
1506       silc_free(username);
1507       username = newusername;
1508 #if 0
1509     } else {
1510       SilcPublicKeyIdentifier pident = 
1511         silc_pkcs_decode_identifier(client->data.public_key->identifier);
1512       
1513       if (pident) {
1514         newusername = silc_calloc(strlen(username) + 
1515                                   strlen(pident->host) + 2,
1516                                   sizeof(*newusername));
1517         strncat(newusername, username, strlen(username));
1518         strncat(newusername, "@", 1);
1519         strncat(newusername, pident->host, strlen(pident->host));
1520         silc_free(username);
1521         username = newusername;
1522         silc_pkcs_free_identifier(pident);
1523       }
1524     }
1525 #endif
1526   }
1527
1528   /* Create Client ID */
1529   while (!silc_id_create_client_id(server, server->id, server->rng, 
1530                                    server->md5hash, nickname, &client_id)) {
1531     nickfail++;
1532     snprintf(&nickname[strlen(nickname) - 1], 1, "%d", nickfail);
1533   }
1534
1535   /* Update client entry */
1536   idata->status |= SILC_IDLIST_STATUS_REGISTERED;
1537   client->nickname = nickname;
1538   client->username = username;
1539   client->userinfo = realname ? realname : strdup(" ");
1540   client->id = client_id;
1541   id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
1542
1543   /* Add the client again to the ID cache */
1544   silc_idcache_add(server->local_list->clients, client->nickname,
1545                    client_id, client, FALSE);
1546
1547   /* Notify our router about new client on the SILC network */
1548   if (!server->standalone)
1549     silc_server_send_new_id(server, (SilcSocketConnection) 
1550                             server->router->connection, 
1551                             server->server_type == SILC_ROUTER ? TRUE : FALSE,
1552                             client->id, SILC_ID_CLIENT, id_len);
1553   
1554   /* Send the new client ID to the client. */
1555   id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
1556   reply = silc_buffer_alloc(2 + 2 + id_len);
1557   silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
1558   silc_buffer_format(reply,
1559                      SILC_STR_UI_SHORT(SILC_ID_CLIENT),
1560                      SILC_STR_UI_SHORT(id_len),
1561                      SILC_STR_UI_XNSTRING(id_string, id_len),
1562                      SILC_STR_END);
1563   silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0, 
1564                           reply->data, reply->len, FALSE);
1565   silc_free(id_string);
1566   silc_buffer_free(reply);
1567
1568   /* Send some nice info to the client */
1569   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1570                           ("Welcome to the SILC Network %s",
1571                            username));
1572   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1573                           ("Your host is %s, running version %s",
1574                            server->config->server_info->server_name,
1575                            server_version));
1576   if (server->server_type == SILC_ROUTER) {
1577     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1578                             ("There are %d clients on %d servers in SILC "
1579                              "Network", server->stat.clients,
1580                              server->stat.servers + 1));
1581     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1582                             ("There are %d clients on %d server in our cell",
1583                              server->stat.cell_clients,
1584                              server->stat.cell_servers + 1));
1585     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1586                             ("I have %d clients, %d channels, %d servers and "
1587                              "%d routers",
1588                              server->stat.my_clients, 
1589                              server->stat.my_channels,
1590                              server->stat.my_servers,
1591                              server->stat.my_routers));
1592     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1593                             ("%d server operators and %d router operators "
1594                              "online",
1595                              server->stat.my_server_ops,
1596                              server->stat.my_router_ops));
1597   } else {
1598     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1599                             ("I have %d clients and %d channels formed",
1600                              server->stat.my_clients,
1601                              server->stat.my_channels));
1602     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1603                             ("%d operators online",
1604                              server->stat.my_server_ops));
1605   }
1606   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1607                           ("Your connection is secured with %s cipher, "
1608                            "key length %d bits",
1609                            idata->send_key->cipher->name,
1610                            idata->send_key->cipher->key_len));
1611   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1612                           ("Your current nickname is %s",
1613                            client->nickname));
1614
1615   /* Send motd */
1616   silc_server_send_motd(server, sock);
1617
1618   return client;
1619 }
1620
1621 /* Create new server. This processes received New Server packet and
1622    saves the received Server ID. The server is our locally connected
1623    server thus we save all the information and save it to local list. 
1624    This funtion can be used by both normal server and router server.
1625    If normal server uses this it means that its router has connected
1626    to the server. If router uses this it means that one of the cell's
1627    servers is connected to the router. */
1628
1629 SilcServerEntry silc_server_new_server(SilcServer server,
1630                                        SilcSocketConnection sock,
1631                                        SilcPacketContext *packet)
1632 {
1633   SilcBuffer buffer = packet->buffer;
1634   SilcServerEntry new_server, server_entry;
1635   SilcServerID *server_id;
1636   SilcIDListData idata;
1637   unsigned char *server_name, *id_string;
1638   uint16 id_len, name_len;
1639   int ret;
1640   bool local = TRUE;
1641
1642   SILC_LOG_DEBUG(("Creating new server"));
1643
1644   if (sock->type != SILC_SOCKET_TYPE_SERVER &&
1645       sock->type != SILC_SOCKET_TYPE_ROUTER)
1646     return NULL;
1647
1648   /* Take server entry */
1649   new_server = (SilcServerEntry)sock->user_data;
1650   idata = (SilcIDListData)new_server;
1651
1652   /* Remove the old cache entry */
1653   if (!silc_idcache_del_by_context(server->local_list->servers, new_server)) {
1654     silc_idcache_del_by_context(server->global_list->servers, new_server);
1655     local = FALSE;
1656   }
1657
1658   /* Parse the incoming packet */
1659   ret = silc_buffer_unformat(buffer,
1660                              SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
1661                              SILC_STR_UI16_NSTRING_ALLOC(&server_name, 
1662                                                          &name_len),
1663                              SILC_STR_END);
1664   if (ret == -1) {
1665     if (id_string)
1666       silc_free(id_string);
1667     if (server_name)
1668       silc_free(server_name);
1669     return NULL;
1670   }
1671
1672   if (id_len > buffer->len) {
1673     silc_free(id_string);
1674     silc_free(server_name);
1675     return NULL;
1676   }
1677
1678   if (name_len > 256)
1679     server_name[255] = '\0';
1680
1681   /* Get Server ID */
1682   server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
1683   if (!server_id) {
1684     silc_free(id_string);
1685     silc_free(server_name);
1686     return NULL;
1687   }
1688   silc_free(id_string);
1689
1690   /* Check that we do not have this ID already */
1691   server_entry = silc_idlist_find_server_by_id(server->local_list, 
1692                                                server_id, TRUE, NULL);
1693   if (server_entry) {
1694     silc_idcache_del_by_context(server->local_list->servers, server_entry);
1695   } else {
1696     server_entry = silc_idlist_find_server_by_id(server->global_list, 
1697                                                  server_id, TRUE, NULL);
1698     if (server_entry) 
1699       silc_idcache_del_by_context(server->global_list->servers, server_entry);
1700   }
1701
1702   /* Update server entry */
1703   idata->status |= SILC_IDLIST_STATUS_REGISTERED;
1704   new_server->server_name = server_name;
1705   new_server->id = server_id;
1706   
1707   SILC_LOG_DEBUG(("New server id(%s)",
1708                   silc_id_render(server_id, SILC_ID_SERVER)));
1709
1710   /* Add again the entry to the ID cache. */
1711   silc_idcache_add(local ? server->local_list->servers : 
1712                    server->global_list->servers, server_name, server_id, 
1713                    new_server, FALSE);
1714
1715   /* Distribute the information about new server in the SILC network
1716      to our router. If we are normal server we won't send anything
1717      since this connection must be our router connection. */
1718   if (server->server_type == SILC_ROUTER && !server->standalone &&
1719       server->router->connection != sock)
1720     silc_server_send_new_id(server, server->router->connection,
1721                             TRUE, new_server->id, SILC_ID_SERVER, 
1722                             silc_id_get_len(server_id, SILC_ID_SERVER));
1723
1724   if (server->server_type == SILC_ROUTER)
1725     server->stat.cell_servers++;
1726
1727   /* Check whether this router connection has been replaced by an
1728      backup router. If it has been then we'll disable the server and will
1729      ignore everything it will send until the backup router resuming
1730      protocol has been completed. */
1731   if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
1732       silc_server_backup_replaced_get(server, server_id, NULL)) {
1733     /* Send packet to the server indicating that it cannot use this
1734        connection as it has been replaced by backup router. */
1735     SilcBuffer packet = silc_buffer_alloc(2);
1736     silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
1737     silc_buffer_format(packet,
1738                        SILC_STR_UI_CHAR(SILC_SERVER_BACKUP_REPLACED),
1739                        SILC_STR_UI_CHAR(0),
1740                        SILC_STR_END);
1741     silc_server_packet_send(server, sock, 
1742                             SILC_PACKET_RESUME_ROUTER, 0, 
1743                             packet->data, packet->len, TRUE);
1744     silc_buffer_free(packet);
1745
1746     /* Mark the router disabled. The data sent earlier will go but nothing
1747        after this does not go to this connection. */
1748     idata->status |= SILC_IDLIST_STATUS_DISABLED;
1749   } else {
1750     /* If it is router announce our stuff to it. */
1751     if (sock->type == SILC_SOCKET_TYPE_ROUTER && 
1752         server->server_type == SILC_ROUTER) {
1753       silc_server_announce_servers(server, FALSE, 0, sock);
1754       silc_server_announce_clients(server, 0, sock);
1755       silc_server_announce_channels(server, 0, sock);
1756     }
1757   }
1758
1759   return new_server;
1760 }
1761
1762 /* Processes incoming New ID packet. New ID Payload is used to distribute
1763    information about newly registered clients and servers. */
1764
1765 static void silc_server_new_id_real(SilcServer server, 
1766                                     SilcSocketConnection sock,
1767                                     SilcPacketContext *packet,
1768                                     int broadcast)
1769 {
1770   SilcBuffer buffer = packet->buffer;
1771   SilcIDList id_list;
1772   SilcServerEntry router, server_entry;
1773   SilcSocketConnection router_sock;
1774   SilcIDPayload idp;
1775   SilcIdType id_type;
1776   void *id;
1777
1778   SILC_LOG_DEBUG(("Processing new ID"));
1779
1780   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1781       server->server_type == SILC_SERVER ||
1782       packet->src_id_type != SILC_ID_SERVER)
1783     return;
1784
1785   idp = silc_id_payload_parse(buffer);
1786   if (!idp)
1787     return;
1788
1789   id_type = silc_id_payload_get_type(idp);
1790
1791   /* Normal server cannot have other normal server connections */
1792   server_entry = (SilcServerEntry)sock->user_data;
1793   if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER &&
1794       server_entry->server_type == SILC_SERVER)
1795     goto out;
1796
1797   id = silc_id_payload_get_id(idp);
1798   if (!id)
1799     goto out;
1800
1801   /* If the packet is coming from server then use the sender as the
1802      origin of the the packet. If it came from router then check the real
1803      sender of the packet and use that as the origin. */
1804   if (sock->type == SILC_SOCKET_TYPE_SERVER) {
1805     id_list = server->local_list;
1806     router_sock = sock;
1807     router = sock->user_data;
1808
1809     /* If the sender is backup router and ID is server (and we are not
1810        backup router) then switch the entry to global list. */
1811     if (server_entry->server_type == SILC_BACKUP_ROUTER && 
1812         id_type == SILC_ID_SERVER && 
1813         server->id_entry->server_type != SILC_BACKUP_ROUTER) {
1814       id_list = server->global_list;
1815       router_sock = server->router ? server->router->connection : sock;
1816     }
1817   } else {
1818     void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1819                                      packet->src_id_type);
1820     router = silc_idlist_find_server_by_id(server->global_list,
1821                                            sender_id, TRUE, NULL);
1822     if (!router)
1823       router = silc_idlist_find_server_by_id(server->local_list,
1824                                              sender_id, TRUE, NULL);
1825     silc_free(sender_id);
1826     if (!router)
1827       goto out;
1828     router_sock = sock;
1829     id_list = server->global_list;
1830   }
1831
1832   switch(id_type) {
1833   case SILC_ID_CLIENT:
1834     {
1835       SilcClientEntry entry;
1836
1837       /* Check that we do not have this client already */
1838       entry = silc_idlist_find_client_by_id(server->global_list, 
1839                                             id, server->server_type, 
1840                                             NULL);
1841       if (!entry)
1842         entry = silc_idlist_find_client_by_id(server->local_list, 
1843                                               id, server->server_type,
1844                                               NULL);
1845       if (entry) {
1846         SILC_LOG_DEBUG(("Ignoring client that we already have"));
1847         goto out;
1848       }
1849
1850       SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
1851                       silc_id_render(id, SILC_ID_CLIENT),
1852                       sock->type == SILC_SOCKET_TYPE_SERVER ?
1853                       "Server" : "Router", sock->hostname));
1854     
1855       /* As a router we keep information of all global information in our
1856          global list. Cell wide information however is kept in the local
1857          list. */
1858       entry = silc_idlist_add_client(id_list, NULL, NULL, NULL, 
1859                                      id, router, NULL);
1860       if (!entry) {
1861         SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
1862
1863         /* Inform the sender that the ID is not usable */
1864         silc_server_send_notify_signoff(server, sock, FALSE, id, NULL);
1865         goto out;
1866       }
1867       entry->nickname = NULL;
1868       entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
1869
1870       if (sock->type == SILC_SOCKET_TYPE_SERVER)
1871         server->stat.cell_clients++;
1872       server->stat.clients++;
1873     }
1874     break;
1875
1876   case SILC_ID_SERVER:
1877     {
1878       SilcServerEntry entry;
1879
1880       /* If the ID is mine, ignore it. */
1881       if (SILC_ID_SERVER_COMPARE(id, server->id)) {
1882         SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
1883         break;
1884       }
1885
1886       /* If the ID is the sender's ID, ignore it (we have it already) */
1887       if (SILC_ID_SERVER_COMPARE(id, router->id)) {
1888         SILC_LOG_DEBUG(("Ignoring sender's own ID"));
1889         break;
1890       }
1891       
1892       /* Check that we do not have this server already */
1893       entry = silc_idlist_find_server_by_id(server->global_list, 
1894                                             id, server->server_type, 
1895                                             NULL);
1896       if (!entry)
1897         entry = silc_idlist_find_server_by_id(server->local_list, 
1898                                               id, server->server_type,
1899                                               NULL);
1900       if (entry) {
1901         SILC_LOG_DEBUG(("Ignoring server that we already have"));
1902         goto out;
1903       }
1904
1905       SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
1906                       silc_id_render(id, SILC_ID_SERVER),
1907                       sock->type == SILC_SOCKET_TYPE_SERVER ?
1908                       "Server" : "Router", sock->hostname));
1909       
1910       /* As a router we keep information of all global information in our 
1911          global list. Cell wide information however is kept in the local
1912          list. */
1913       entry = silc_idlist_add_server(id_list, NULL, 0, id, router, 
1914                                      router_sock);
1915       if (!entry) {
1916         SILC_LOG_ERROR(("Could not add new server to the ID Cache"));
1917         goto out;
1918       }
1919       entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
1920       
1921       if (sock->type == SILC_SOCKET_TYPE_SERVER)
1922         server->stat.cell_servers++;
1923       server->stat.servers++;
1924     }
1925     break;
1926
1927   case SILC_ID_CHANNEL:
1928     SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
1929     goto out;
1930     break;
1931
1932   default:
1933     goto out;
1934     break;
1935   }
1936
1937   /* If the sender of this packet is server and we are router we need to
1938      broadcast this packet to other routers in the network. */
1939   if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
1940       sock->type == SILC_SOCKET_TYPE_SERVER &&
1941       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1942     SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
1943     silc_server_packet_send(server, server->router->connection,
1944                             packet->type, 
1945                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1946                             buffer->data, buffer->len, FALSE);
1947     silc_server_backup_send(server, (SilcServerEntry)sock->user_data, 
1948                             packet->type, packet->flags,
1949                             packet->buffer->data, packet->buffer->len, 
1950                             FALSE, TRUE);
1951   }
1952
1953  out:
1954   silc_id_payload_free(idp);
1955 }
1956
1957
1958 /* Processes incoming New ID packet. New ID Payload is used to distribute
1959    information about newly registered clients and servers. */
1960
1961 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
1962                         SilcPacketContext *packet)
1963 {
1964   silc_server_new_id_real(server, sock, packet, TRUE);
1965 }
1966
1967 /* Receoved New Id List packet, list of New ID payloads inside one
1968    packet. Process the New ID payloads one by one. */
1969
1970 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
1971                              SilcPacketContext *packet)
1972 {
1973   SilcPacketContext *new_id;
1974   SilcBuffer idp;
1975   uint16 id_len;
1976
1977   SILC_LOG_DEBUG(("Processing New ID List"));
1978
1979   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1980       packet->src_id_type != SILC_ID_SERVER)
1981     return;
1982
1983   /* If the sender of this packet is server and we are router we need to
1984      broadcast this packet to other routers in the network. Broadcast
1985      this list packet instead of multiple New ID packets. */
1986   if (!server->standalone && server->server_type == SILC_ROUTER &&
1987       sock->type == SILC_SOCKET_TYPE_SERVER &&
1988       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1989     SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
1990     silc_server_packet_send(server, server->router->connection,
1991                             packet->type, 
1992                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1993                             packet->buffer->data, packet->buffer->len, FALSE);
1994     silc_server_backup_send(server, (SilcServerEntry)sock->user_data, 
1995                             packet->type, packet->flags,
1996                             packet->buffer->data, packet->buffer->len, 
1997                             FALSE, TRUE);
1998   }
1999
2000   /* Make copy of the original packet context, except for the actual
2001      data buffer, which we will here now fetch from the original buffer. */
2002   new_id = silc_packet_context_alloc();
2003   new_id->type = SILC_PACKET_NEW_ID;
2004   new_id->flags = packet->flags;
2005   new_id->src_id = packet->src_id;
2006   new_id->src_id_len = packet->src_id_len;
2007   new_id->src_id_type = packet->src_id_type;
2008   new_id->dst_id = packet->dst_id;
2009   new_id->dst_id_len = packet->dst_id_len;
2010   new_id->dst_id_type = packet->dst_id_type;
2011
2012   idp = silc_buffer_alloc(256);
2013   new_id->buffer = idp;
2014
2015   while (packet->buffer->len) {
2016     SILC_GET16_MSB(id_len, packet->buffer->data + 2);
2017     if ((id_len > packet->buffer->len) ||
2018         (id_len > idp->truelen))
2019       break;
2020
2021     silc_buffer_pull_tail(idp, 4 + id_len);
2022     silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
2023
2024     /* Process the New ID */
2025     silc_server_new_id_real(server, sock, new_id, FALSE);
2026
2027     silc_buffer_push_tail(idp, 4 + id_len);
2028     silc_buffer_pull(packet->buffer, 4 + id_len);
2029   }
2030
2031   silc_buffer_free(idp);
2032   silc_free(new_id);
2033 }
2034
2035 /* Received New Channel packet. Information about new channels in the 
2036    network are distributed using this packet. Save the information about
2037    the new channel. This usually comes from router but also normal server
2038    can send this to notify channels it has when it connects to us. */
2039
2040 void silc_server_new_channel(SilcServer server,
2041                              SilcSocketConnection sock,
2042                              SilcPacketContext *packet)
2043 {
2044   SilcChannelPayload payload;
2045   SilcChannelID *channel_id;
2046   char *channel_name;
2047   uint32 name_len;
2048   unsigned char *id;
2049   uint32 id_len;
2050   uint32 mode;
2051   SilcServerEntry server_entry;
2052   SilcChannelEntry channel;
2053
2054   SILC_LOG_DEBUG(("Processing New Channel"));
2055
2056   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2057       packet->src_id_type != SILC_ID_SERVER ||
2058       server->server_type == SILC_SERVER)
2059     return;
2060
2061   /* Parse the channel payload */
2062   payload = silc_channel_payload_parse(packet->buffer);
2063   if (!payload)
2064     return;
2065     
2066   /* Get the channel ID */
2067   channel_id = silc_channel_get_id_parse(payload);
2068   if (!channel_id) {
2069     silc_channel_payload_free(payload);
2070     return;
2071   }
2072
2073   channel_name = silc_channel_get_name(payload, &name_len);
2074   if (name_len > 256)
2075     channel_name[255] = '\0';
2076
2077   id = silc_channel_get_id(payload, &id_len);
2078
2079   server_entry = (SilcServerEntry)sock->user_data;
2080
2081   if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
2082     /* Add the channel to global list as it is coming from router. It 
2083        cannot be our own channel as it is coming from router. */
2084
2085     /* Check that we don't already have this channel */
2086     channel = silc_idlist_find_channel_by_name(server->local_list, 
2087                                                channel_name, NULL);
2088     if (!channel)
2089       channel = silc_idlist_find_channel_by_name(server->global_list, 
2090                                                  channel_name, NULL);
2091     if (!channel) {
2092       SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
2093                       silc_id_render(channel_id, SILC_ID_CHANNEL), 
2094                       sock->hostname));
2095     
2096       silc_idlist_add_channel(server->global_list, strdup(channel_name), 
2097                               0, channel_id, sock->user_data, NULL, NULL);
2098       server->stat.channels++;
2099     }
2100   } else {
2101     /* The channel is coming from our server, thus it is in our cell
2102        we will add it to our local list. */
2103     SilcBuffer chk;
2104
2105     SILC_LOG_DEBUG(("Channel id(%s) from [Server] %s",
2106                     silc_id_render(channel_id, SILC_ID_CHANNEL), 
2107                     sock->hostname));
2108
2109     /* Check that we don't already have this channel */
2110     channel = silc_idlist_find_channel_by_name(server->local_list, 
2111                                                channel_name, NULL);
2112     if (!channel)
2113       channel = silc_idlist_find_channel_by_name(server->global_list, 
2114                                                  channel_name, NULL);
2115
2116     /* If the channel does not exist, then create it. This creates a new
2117        key to the channel as well that we will send to the server. */
2118     if (!channel) {
2119       /* The protocol says that the Channel ID's IP address must be based
2120          on the router's IP address.  Check whether the ID is based in our
2121          IP and if it is not then create a new ID and enforce the server
2122          to switch the ID. */
2123       if (server_entry->server_type != SILC_BACKUP_ROUTER &&
2124           !SILC_ID_COMPARE(channel_id, server->id, server->id->ip.data_len)) {
2125         SilcChannelID *tmp;
2126         SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2127         
2128         if (silc_id_create_channel_id(server, server->id, server->rng, &tmp)) {
2129           silc_server_send_notify_channel_change(server, sock, FALSE, 
2130                                                  channel_id, tmp);
2131           silc_free(channel_id);
2132           channel_id = tmp;
2133         }
2134       }
2135
2136       /* Create the channel with the provided Channel ID */
2137       channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
2138                                                        channel_name,
2139                                                        channel_id, FALSE);
2140       if (!channel) {
2141         silc_channel_payload_free(payload);
2142         silc_free(channel_id);
2143         return;
2144       }
2145
2146       /* Get the mode and set it to the channel */
2147       channel->mode = silc_channel_get_mode(payload);
2148
2149       /* Send the new channel key to the server */
2150       chk = silc_channel_key_payload_encode(id_len, id,
2151                                             strlen(channel->channel_key->
2152                                                    cipher->name),
2153                                             channel->channel_key->cipher->name,
2154                                             channel->key_len / 8, 
2155                                             channel->key);
2156       silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
2157                               chk->data, chk->len, FALSE);
2158       silc_buffer_free(chk);
2159
2160     } else {
2161       /* The channel exist by that name, check whether the ID's match.
2162          If they don't then we'll force the server to use the ID we have.
2163          We also create a new key for the channel. */
2164       SilcBuffer users = NULL, users_modes = NULL;
2165
2166       if (!channel->id)
2167         channel->id = silc_id_dup(channel_id, SILC_ID_CHANNEL);
2168
2169       if (!SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
2170         /* They don't match, send CHANNEL_CHANGE notify to the server to
2171            force the ID change. */
2172         SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2173         silc_server_send_notify_channel_change(server, sock, FALSE, 
2174                                                channel_id, channel->id);
2175       }
2176
2177       /* If the mode is different from what we have then enforce the
2178          mode change. */
2179       mode = silc_channel_get_mode(payload);
2180       if (channel->mode != mode) {
2181         SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
2182         silc_server_send_notify_cmode(server, sock, FALSE, channel,
2183                                       channel->mode, server->id,
2184                                       SILC_ID_SERVER,
2185                                       channel->cipher, channel->hmac_name);
2186       }
2187
2188       /* Create new key for the channel and send it to the server and
2189          everybody else possibly on the channel. */
2190
2191       if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
2192         if (!silc_server_create_channel_key(server, channel, 0))
2193           return;
2194         
2195         /* Send to the channel */
2196         silc_server_send_channel_key(server, sock, channel, FALSE);
2197         id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2198         id_len = SILC_ID_CHANNEL_LEN;
2199         
2200         /* Send to the server */
2201         chk = silc_channel_key_payload_encode(id_len, id,
2202                                               strlen(channel->channel_key->
2203                                                      cipher->name),
2204                                               channel->channel_key->
2205                                               cipher->name,
2206                                               channel->key_len / 8, 
2207                                               channel->key);
2208         silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
2209                                 chk->data, chk->len, FALSE);
2210         silc_buffer_free(chk);
2211         silc_free(id);
2212       }
2213
2214       silc_free(channel_id);
2215
2216       /* Since the channel is coming from server and we also know about it
2217          then send the JOIN notify to the server so that it see's our
2218          users on the channel "joining" the channel. */
2219       silc_server_announce_get_channel_users(server, channel, &users,
2220                                              &users_modes);
2221       if (users) {
2222         silc_buffer_push(users, users->data - users->head);
2223         silc_server_packet_send(server, sock,
2224                                 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2225                                 users->data, users->len, FALSE);
2226         silc_buffer_free(users);
2227       }
2228       if (users_modes) {
2229         silc_buffer_push(users_modes, users_modes->data - users_modes->head);
2230         silc_server_packet_send_dest(server, sock,
2231                                      SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2232                                      channel->id, SILC_ID_CHANNEL,
2233                                      users_modes->data, 
2234                                      users_modes->len, FALSE);
2235         silc_buffer_free(users_modes);
2236       }
2237     }
2238   }
2239
2240   silc_channel_payload_free(payload);
2241 }
2242
2243 /* Received New Channel List packet, list of New Channel List payloads inside
2244    one packet. Process the New Channel payloads one by one. */
2245
2246 void silc_server_new_channel_list(SilcServer server,
2247                                   SilcSocketConnection sock,
2248                                   SilcPacketContext *packet)
2249 {
2250   SilcPacketContext *new;
2251   SilcBuffer buffer;
2252   uint16 len1, len2;
2253
2254   SILC_LOG_DEBUG(("Processing New Channel List"));
2255
2256   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2257       packet->src_id_type != SILC_ID_SERVER ||
2258       server->server_type == SILC_SERVER)
2259     return;
2260
2261   /* If the sender of this packet is server and we are router we need to
2262      broadcast this packet to other routers in the network. Broadcast
2263      this list packet instead of multiple New Channel packets. */
2264   if (!server->standalone && server->server_type == SILC_ROUTER &&
2265       sock->type == SILC_SOCKET_TYPE_SERVER &&
2266       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2267     SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
2268     silc_server_packet_send(server, server->router->connection,
2269                             packet->type, 
2270                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
2271                             packet->buffer->data, packet->buffer->len, FALSE);
2272     silc_server_backup_send(server, (SilcServerEntry)sock->user_data, 
2273                             packet->type, packet->flags,
2274                             packet->buffer->data, packet->buffer->len, 
2275                             FALSE, TRUE);
2276   }
2277
2278   /* Make copy of the original packet context, except for the actual
2279      data buffer, which we will here now fetch from the original buffer. */
2280   new = silc_packet_context_alloc();
2281   new->type = SILC_PACKET_NEW_CHANNEL;
2282   new->flags = packet->flags;
2283   new->src_id = packet->src_id;
2284   new->src_id_len = packet->src_id_len;
2285   new->src_id_type = packet->src_id_type;
2286   new->dst_id = packet->dst_id;
2287   new->dst_id_len = packet->dst_id_len;
2288   new->dst_id_type = packet->dst_id_type;
2289
2290   buffer = silc_buffer_alloc(512);
2291   new->buffer = buffer;
2292
2293   while (packet->buffer->len) {
2294     SILC_GET16_MSB(len1, packet->buffer->data);
2295     if ((len1 > packet->buffer->len) ||
2296         (len1 > buffer->truelen))
2297       break;
2298
2299     SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
2300     if ((len2 > packet->buffer->len) ||
2301         (len2 > buffer->truelen))
2302       break;
2303
2304     silc_buffer_pull_tail(buffer, 8 + len1 + len2);
2305     silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
2306
2307     /* Process the New Channel */
2308     silc_server_new_channel(server, sock, new);
2309
2310     silc_buffer_push_tail(buffer, 8 + len1 + len2);
2311     silc_buffer_pull(packet->buffer, 8 + len1 + len2);
2312   }
2313
2314   silc_buffer_free(buffer);
2315   silc_free(new);
2316 }
2317
2318 /* Received key agreement packet. This packet is never for us. It is to
2319    the client in the packet's destination ID. Sending of this sort of packet
2320    equals sending private message, ie. it is sent point to point from
2321    one client to another. */
2322
2323 void silc_server_key_agreement(SilcServer server,
2324                                SilcSocketConnection sock,
2325                                SilcPacketContext *packet)
2326 {
2327   SilcSocketConnection dst_sock;
2328   SilcIDListData idata;
2329
2330   SILC_LOG_DEBUG(("Start"));
2331
2332   if (packet->src_id_type != SILC_ID_CLIENT ||
2333       packet->dst_id_type != SILC_ID_CLIENT)
2334     return;
2335
2336   if (!packet->dst_id)
2337     return;
2338
2339   /* Get the route to the client */
2340   dst_sock = silc_server_get_client_route(server, packet->dst_id,
2341                                           packet->dst_id_len, NULL, &idata);
2342   if (!dst_sock)
2343     return;
2344
2345   /* Relay the packet */
2346   silc_server_relay_packet(server, dst_sock, idata->send_key,
2347                            idata->hmac_send, packet, FALSE);
2348 }
2349
2350 /* Received connection auth request packet that is used during connection
2351    phase to resolve the mandatory authentication method.  This packet can
2352    actually be received at anytime but usually it is used only during
2353    the connection authentication phase. Now, protocol says that this packet
2354    can come from client or server, however, we support only this coming
2355    from client and expect that server always knows what authentication
2356    method to use. */
2357
2358 void silc_server_connection_auth_request(SilcServer server,
2359                                          SilcSocketConnection sock,
2360                                          SilcPacketContext *packet)
2361 {
2362   SilcServerConfigSectionClientConnection *client = NULL;
2363   uint16 conn_type;
2364   int ret, port;
2365   SilcAuthMethod auth_meth;
2366
2367   SILC_LOG_DEBUG(("Start"));
2368
2369   if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT)
2370     return;
2371
2372   /* Parse the payload */
2373   ret = silc_buffer_unformat(packet->buffer,
2374                              SILC_STR_UI_SHORT(&conn_type),
2375                              SILC_STR_UI_SHORT(NULL),
2376                              SILC_STR_END);
2377   if (ret == -1)
2378     return;
2379
2380   if (conn_type != SILC_SOCKET_TYPE_CLIENT)
2381     return;
2382
2383   /* Get the authentication method for the client */
2384   auth_meth = SILC_AUTH_NONE;
2385   port = server->sockets[server->sock]->port; /* Listenning port */
2386   client = silc_server_config_find_client_conn(server->config,
2387                                                sock->ip,
2388                                                port);
2389   if (!client)
2390     client = silc_server_config_find_client_conn(server->config,
2391                                                  sock->hostname,
2392                                                  port);
2393   if (client)
2394     auth_meth = client->auth_meth;
2395           
2396   /* Send it back to the client */
2397   silc_server_send_connection_auth_request(server, sock,
2398                                            conn_type,
2399                                            auth_meth);
2400 }
2401
2402 /* Received REKEY packet. The sender of the packet wants to regenerate
2403    its session keys. This starts the REKEY protocol. */
2404
2405 void silc_server_rekey(SilcServer server,
2406                        SilcSocketConnection sock,
2407                        SilcPacketContext *packet)
2408 {
2409   SilcProtocol protocol;
2410   SilcServerRekeyInternalContext *proto_ctx;
2411   SilcIDListData idata = (SilcIDListData)sock->user_data;
2412
2413   SILC_LOG_DEBUG(("Start"));
2414
2415   /* Allocate internal protocol context. This is sent as context
2416      to the protocol. */
2417   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
2418   proto_ctx->server = (void *)server;
2419   proto_ctx->sock = sock;
2420   proto_ctx->responder = TRUE;
2421   proto_ctx->pfs = idata->rekey->pfs;
2422       
2423   /* Perform rekey protocol. Will call the final callback after the
2424      protocol is over. */
2425   silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY, 
2426                       &protocol, proto_ctx, silc_server_rekey_final);
2427   sock->protocol = protocol;
2428
2429   if (proto_ctx->pfs == FALSE)
2430     /* Run the protocol */
2431     silc_protocol_execute(protocol, server->schedule, 0, 0);
2432 }