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