47d7cf0a135fba1b4bdc0c013bc1a71fe9290946
[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
1281   SILC_LOG_DEBUG(("Processing channel message"));
1282
1283   /* Sanity checks */
1284   if (packet->dst_id_type != SILC_ID_CHANNEL) {
1285     SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1286     goto out;
1287   }
1288
1289   /* Find channel entry */
1290   id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
1291   if (!id)
1292     goto out;
1293   channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
1294   if (!channel) {
1295     channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
1296     if (!channel) {
1297       SILC_LOG_DEBUG(("Could not find channel"));
1298       goto out;
1299     }
1300   }
1301
1302   /* See that this client is on the channel. If the original sender is
1303      not client (as it can be server as well) we don't do the check. */
1304   sender = silc_id_str2id(packet->src_id, packet->src_id_len, 
1305                           packet->src_id_type);
1306   if (!sender)
1307     goto out;
1308   if (packet->src_id_type == SILC_ID_CLIENT) {
1309     sender_entry = silc_idlist_find_client_by_id(server->local_list, 
1310                                                  sender, TRUE, NULL);
1311     if (!sender_entry)
1312       sender_entry = silc_idlist_find_client_by_id(server->global_list, 
1313                                                    sender, TRUE, NULL);
1314     if (!sender_entry || !silc_server_client_on_channel(sender_entry, 
1315                                                         channel)) {
1316       SILC_LOG_DEBUG(("Client not on channel"));
1317       goto out;
1318     }
1319   }
1320
1321   /* Distribute the packet to our local clients. This will send the
1322      packet for further routing as well, if needed. */
1323   silc_server_packet_relay_to_channel(server, sock, channel, sender,
1324                                       packet->src_id_type, sender_entry,
1325                                       packet->buffer->data,
1326                                       packet->buffer->len, FALSE);
1327
1328  out:
1329   if (sender)
1330     silc_free(sender);
1331   if (id)
1332     silc_free(id);
1333 }
1334
1335 /* Received channel key packet. We distribute the key to all of our locally
1336    connected clients on the channel. */
1337
1338 void silc_server_channel_key(SilcServer server,
1339                              SilcSocketConnection sock,
1340                              SilcPacketContext *packet)
1341 {
1342   SilcBuffer buffer = packet->buffer;
1343   SilcChannelEntry channel;
1344
1345   if (packet->src_id_type != SILC_ID_SERVER ||
1346       (server->server_type == SILC_ROUTER &&
1347        sock->type == SILC_SOCKET_TYPE_ROUTER))
1348     return;
1349
1350   /* Save the channel key */
1351   channel = silc_server_save_channel_key(server, buffer, NULL);
1352   if (!channel)
1353     return;
1354
1355   /* Distribute the key to everybody who is on the channel. If we are router
1356      we will also send it to locally connected servers. */
1357   silc_server_send_channel_key(server, sock, channel, FALSE);
1358   
1359   if (server->server_type != SILC_BACKUP_ROUTER) {
1360     /* Distribute to local cell backup routers. */
1361     silc_server_backup_send(server, (SilcServerEntry)sock->user_data, 
1362                             SILC_PACKET_CHANNEL_KEY, 0,
1363                             buffer->data, buffer->len, FALSE, TRUE);
1364   }
1365 }
1366
1367 /* Received New Client packet and processes it.  Creates Client ID for the
1368    client. Client becomes registered after calling this functions. */
1369
1370 SilcClientEntry silc_server_new_client(SilcServer server,
1371                                        SilcSocketConnection sock,
1372                                        SilcPacketContext *packet)
1373 {
1374   SilcBuffer buffer = packet->buffer;
1375   SilcClientEntry client;
1376   SilcClientID *client_id;
1377   SilcBuffer reply;
1378   SilcIDListData idata;
1379   char *username = NULL, *realname = NULL, *id_string;
1380   uint32 id_len;
1381   int ret;
1382   char *hostname, *nickname;
1383   int nickfail = 0;
1384
1385   SILC_LOG_DEBUG(("Creating new client"));
1386
1387   if (sock->type != SILC_SOCKET_TYPE_CLIENT)
1388     return NULL;
1389
1390   /* Take client entry */
1391   client = (SilcClientEntry)sock->user_data;
1392   idata = (SilcIDListData)client;
1393
1394   /* Remove the old cache entry */
1395   if (!silc_idcache_del_by_context(server->local_list->clients, client)) {
1396     SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
1397     silc_server_disconnect_remote(server, sock, "Server closed connection: "
1398                                   "Unknown client");
1399     return NULL;
1400   }
1401
1402   /* Parse incoming packet */
1403   ret = silc_buffer_unformat(buffer,
1404                              SILC_STR_UI16_STRING_ALLOC(&username),
1405                              SILC_STR_UI16_STRING_ALLOC(&realname),
1406                              SILC_STR_END);
1407   if (ret == -1) {
1408     if (username)
1409       silc_free(username);
1410     if (realname)
1411       silc_free(realname);
1412     silc_server_disconnect_remote(server, sock, "Server closed connection: "
1413                                   "Incomplete client information");
1414     return NULL;
1415   }
1416
1417   if (!username) {
1418     silc_free(username);
1419     if (realname)
1420       silc_free(realname);
1421     silc_server_disconnect_remote(server, sock, "Server closed connection: "
1422                                   "Incomplete client information");
1423     return NULL;
1424   }
1425
1426   if (strlen(username) > 128)
1427     username[127] = '\0';
1428
1429   nickname = strdup(username);
1430
1431   /* Make sanity checks for the hostname of the client. If the hostname
1432      is provided in the `username' check that it is the same than the
1433      resolved hostname, or if not resolved the hostname that appears in
1434      the client's public key. If the hostname is not present then put
1435      it from the resolved name or from the public key. */
1436   if (strchr(username, '@')) {
1437     SilcPublicKeyIdentifier pident;
1438     int tlen = strcspn(username, "@");
1439     char *phostname = NULL;
1440
1441     hostname = silc_calloc((strlen(username) - tlen) + 1, sizeof(char));
1442     memcpy(hostname, username + tlen + 1, strlen(username) - tlen - 1);
1443
1444     if (strcmp(sock->hostname, sock->ip) && 
1445         strcmp(sock->hostname, hostname)) {
1446       silc_free(username);
1447       silc_free(hostname);
1448       if (realname)
1449         silc_free(realname);
1450       silc_server_disconnect_remote(server, sock, 
1451                                     "Server closed connection: "
1452                                     "Incomplete client information");
1453       return NULL;
1454     }
1455     
1456     pident = silc_pkcs_decode_identifier(client->data.public_key->identifier);
1457     if (pident) {
1458       phostname = strdup(pident->host);
1459       silc_pkcs_free_identifier(pident);
1460     }
1461
1462     if (!strcmp(sock->hostname, sock->ip) && 
1463         phostname && strcmp(phostname, hostname)) {
1464       silc_free(username);
1465       silc_free(hostname);
1466       if (phostname)
1467         silc_free(phostname);
1468       if (realname)
1469         silc_free(realname);
1470       silc_server_disconnect_remote(server, sock, 
1471                                     "Server closed connection: "
1472                                     "Incomplete client information");
1473       return NULL;
1474     }
1475     
1476     if (phostname)
1477       silc_free(phostname);
1478   } else {
1479     /* The hostname is not present, add it. */
1480     char *newusername;
1481     /* XXX For now we cannot take the host name from the public key since
1482        they are not trusted or we cannot verify them as trusted. Just take
1483        what the resolved name or address is. */
1484 #if 0
1485     if (strcmp(sock->hostname, sock->ip)) {
1486 #endif
1487       newusername = silc_calloc(strlen(username) + 
1488                                 strlen(sock->hostname) + 2,
1489                                 sizeof(*newusername));
1490       strncat(newusername, username, strlen(username));
1491       strncat(newusername, "@", 1);
1492       strncat(newusername, sock->hostname, strlen(sock->hostname));
1493       silc_free(username);
1494       username = newusername;
1495 #if 0
1496     } else {
1497       SilcPublicKeyIdentifier pident = 
1498         silc_pkcs_decode_identifier(client->data.public_key->identifier);
1499       
1500       if (pident) {
1501         newusername = silc_calloc(strlen(username) + 
1502                                   strlen(pident->host) + 2,
1503                                   sizeof(*newusername));
1504         strncat(newusername, username, strlen(username));
1505         strncat(newusername, "@", 1);
1506         strncat(newusername, pident->host, strlen(pident->host));
1507         silc_free(username);
1508         username = newusername;
1509         silc_pkcs_free_identifier(pident);
1510       }
1511     }
1512 #endif
1513   }
1514
1515   /* Create Client ID */
1516   while (!silc_id_create_client_id(server, server->id, server->rng, 
1517                                    server->md5hash, nickname, &client_id)) {
1518     nickfail++;
1519     snprintf(&nickname[strlen(nickname) - 1], 1, "%d", nickfail);
1520   }
1521
1522   /* Update client entry */
1523   idata->status |= SILC_IDLIST_STATUS_REGISTERED;
1524   client->nickname = nickname;
1525   client->username = username;
1526   client->userinfo = realname ? realname : strdup(" ");
1527   client->id = client_id;
1528   id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
1529
1530   /* Add the client again to the ID cache */
1531   silc_idcache_add(server->local_list->clients, client->nickname,
1532                    client_id, client, FALSE);
1533
1534   /* Notify our router about new client on the SILC network */
1535   if (!server->standalone)
1536     silc_server_send_new_id(server, (SilcSocketConnection) 
1537                             server->router->connection, 
1538                             server->server_type == SILC_ROUTER ? TRUE : FALSE,
1539                             client->id, SILC_ID_CLIENT, id_len);
1540   
1541   /* Send the new client ID to the client. */
1542   id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
1543   reply = silc_buffer_alloc(2 + 2 + id_len);
1544   silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
1545   silc_buffer_format(reply,
1546                      SILC_STR_UI_SHORT(SILC_ID_CLIENT),
1547                      SILC_STR_UI_SHORT(id_len),
1548                      SILC_STR_UI_XNSTRING(id_string, id_len),
1549                      SILC_STR_END);
1550   silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0, 
1551                           reply->data, reply->len, FALSE);
1552   silc_free(id_string);
1553   silc_buffer_free(reply);
1554
1555   /* Send some nice info to the client */
1556   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1557                           ("Welcome to the SILC Network %s",
1558                            username));
1559   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1560                           ("Your host is %s, running version %s",
1561                            server->config->server_info->server_name,
1562                            server_version));
1563   if (server->server_type == SILC_ROUTER) {
1564     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1565                             ("There are %d clients on %d servers in SILC "
1566                              "Network", server->stat.clients,
1567                              server->stat.servers + 1));
1568     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1569                             ("There are %d clients on %d server in our cell",
1570                              server->stat.cell_clients,
1571                              server->stat.cell_servers + 1));
1572     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1573                             ("I have %d clients, %d channels, %d servers and "
1574                              "%d routers",
1575                              server->stat.my_clients, 
1576                              server->stat.my_channels,
1577                              server->stat.my_servers,
1578                              server->stat.my_routers));
1579     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1580                             ("%d server operators and %d router operators "
1581                              "online",
1582                              server->stat.my_server_ops,
1583                              server->stat.my_router_ops));
1584   } else {
1585     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1586                             ("I have %d clients and %d channels formed",
1587                              server->stat.my_clients,
1588                              server->stat.my_channels));
1589     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1590                             ("%d operators online",
1591                              server->stat.my_server_ops));
1592   }
1593   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1594                           ("Your connection is secured with %s cipher, "
1595                            "key length %d bits",
1596                            idata->send_key->cipher->name,
1597                            idata->send_key->cipher->key_len));
1598   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1599                           ("Your current nickname is %s",
1600                            client->nickname));
1601
1602   /* Send motd */
1603   silc_server_send_motd(server, sock);
1604
1605   return client;
1606 }
1607
1608 /* Create new server. This processes received New Server packet and
1609    saves the received Server ID. The server is our locally connected
1610    server thus we save all the information and save it to local list. 
1611    This funtion can be used by both normal server and router server.
1612    If normal server uses this it means that its router has connected
1613    to the server. If router uses this it means that one of the cell's
1614    servers is connected to the router. */
1615
1616 SilcServerEntry silc_server_new_server(SilcServer server,
1617                                        SilcSocketConnection sock,
1618                                        SilcPacketContext *packet)
1619 {
1620   SilcBuffer buffer = packet->buffer;
1621   SilcServerEntry new_server, server_entry;
1622   SilcServerID *server_id;
1623   SilcIDListData idata;
1624   unsigned char *server_name, *id_string;
1625   uint16 id_len, name_len;
1626   int ret;
1627
1628   SILC_LOG_DEBUG(("Creating new server"));
1629
1630   if (sock->type != SILC_SOCKET_TYPE_SERVER &&
1631       sock->type != SILC_SOCKET_TYPE_ROUTER)
1632     return NULL;
1633
1634   /* Take server entry */
1635   new_server = (SilcServerEntry)sock->user_data;
1636   idata = (SilcIDListData)new_server;
1637
1638   /* Remove the old cache entry */
1639   silc_idcache_del_by_context(server->local_list->servers, new_server);
1640
1641   /* Parse the incoming packet */
1642   ret = silc_buffer_unformat(buffer,
1643                              SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
1644                              SILC_STR_UI16_NSTRING_ALLOC(&server_name, 
1645                                                          &name_len),
1646                              SILC_STR_END);
1647   if (ret == -1) {
1648     if (id_string)
1649       silc_free(id_string);
1650     if (server_name)
1651       silc_free(server_name);
1652     return NULL;
1653   }
1654
1655   if (id_len > buffer->len) {
1656     silc_free(id_string);
1657     silc_free(server_name);
1658     return NULL;
1659   }
1660
1661   if (name_len > 256)
1662     server_name[255] = '\0';
1663
1664   /* Get Server ID */
1665   server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
1666   if (!server_id) {
1667     silc_free(id_string);
1668     silc_free(server_name);
1669     return NULL;
1670   }
1671   silc_free(id_string);
1672
1673   /* Check that we do not have this ID already */
1674   server_entry = silc_idlist_find_server_by_id(server->local_list, 
1675                                                server_id, TRUE, NULL);
1676   if (server_entry) {
1677     silc_idcache_del_by_context(server->local_list->servers, server_entry);
1678   } else {
1679     server_entry = silc_idlist_find_server_by_id(server->global_list, 
1680                                                  server_id, TRUE, NULL);
1681     if (server_entry) 
1682       silc_idcache_del_by_context(server->global_list->servers, server_entry);
1683   }
1684
1685   /* Update server entry */
1686   idata->status |= SILC_IDLIST_STATUS_REGISTERED;
1687   new_server->server_name = server_name;
1688   new_server->id = server_id;
1689   
1690   SILC_LOG_DEBUG(("New server id(%s)",
1691                   silc_id_render(server_id, SILC_ID_SERVER)));
1692
1693   /* Add again the entry to the ID cache. */
1694   silc_idcache_add(server->local_list->servers, server_name, server_id, 
1695                    new_server, FALSE);
1696
1697   /* Distribute the information about new server in the SILC network
1698      to our router. If we are normal server we won't send anything
1699      since this connection must be our router connection. */
1700   if (server->server_type == SILC_ROUTER && !server->standalone &&
1701       server->router->connection != sock)
1702     silc_server_send_new_id(server, server->router->connection,
1703                             TRUE, new_server->id, SILC_ID_SERVER, 
1704                             silc_id_get_len(server_id, SILC_ID_SERVER));
1705
1706   if (server->server_type == SILC_ROUTER)
1707     server->stat.cell_servers++;
1708
1709   /* Check whether this router connection has been replaced by an
1710      backup router. If it has been then we'll disable the server and will
1711      ignore everything it will send until the backup router resuming
1712      protocol has been completed. */
1713   if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
1714       silc_server_backup_replaced_get(server, server_id, NULL)) {
1715     /* Send packet to the server indicating that it cannot use this
1716        connection as it has been replaced by backup router. */
1717     SilcBuffer packet = silc_buffer_alloc(2);
1718     silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
1719     silc_buffer_format(packet,
1720                        SILC_STR_UI_CHAR(SILC_SERVER_BACKUP_REPLACED),
1721                        SILC_STR_UI_CHAR(0),
1722                        SILC_STR_END);
1723     silc_server_packet_send(server, sock, 
1724                             SILC_PACKET_RESUME_ROUTER, 0, 
1725                             packet->data, packet->len, TRUE);
1726     silc_buffer_free(packet);
1727
1728     /* Mark the server disabled. The data sent earlier will go but nothing
1729        after this does not go to this connection. */
1730     idata->status |= SILC_IDLIST_STATUS_DISABLED;
1731   }
1732
1733   return new_server;
1734 }
1735
1736 /* Processes incoming New ID packet. New ID Payload is used to distribute
1737    information about newly registered clients and servers. */
1738
1739 static void silc_server_new_id_real(SilcServer server, 
1740                                     SilcSocketConnection sock,
1741                                     SilcPacketContext *packet,
1742                                     int broadcast)
1743 {
1744   SilcBuffer buffer = packet->buffer;
1745   SilcIDList id_list;
1746   SilcServerEntry router;
1747   SilcSocketConnection router_sock;
1748   SilcIDPayload idp;
1749   SilcIdType id_type;
1750   void *id;
1751
1752   SILC_LOG_DEBUG(("Processing new ID"));
1753
1754   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1755       server->server_type == SILC_SERVER ||
1756       packet->src_id_type != SILC_ID_SERVER)
1757     return;
1758
1759   idp = silc_id_payload_parse(buffer);
1760   if (!idp)
1761     return;
1762
1763   id_type = silc_id_payload_get_type(idp);
1764
1765   /* Normal server cannot have other normal server connections */
1766   if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
1767     goto out;
1768
1769   id = silc_id_payload_get_id(idp);
1770   if (!id)
1771     goto out;
1772
1773   if (sock->type == SILC_SOCKET_TYPE_SERVER)
1774     id_list = server->local_list;
1775   else
1776     id_list = server->global_list;
1777
1778   /* If the packet is coming from server then use the sender as the
1779      origin of the the packet. If it came from router then check the real
1780      sender of the packet and use that as the origin. */
1781   if (sock->type == SILC_SOCKET_TYPE_SERVER) {
1782     router_sock = sock;
1783     router = sock->user_data;
1784   } else {
1785     void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1786                                      packet->src_id_type);
1787     router = silc_idlist_find_server_by_id(server->global_list,
1788                                            sender_id, TRUE, NULL);
1789     if (!router)
1790       router = silc_idlist_find_server_by_id(server->local_list,
1791                                              sender_id, TRUE, NULL);
1792     silc_free(sender_id);
1793     if (!router)
1794       goto out;
1795     router_sock = sock;
1796   }
1797
1798   switch(id_type) {
1799   case SILC_ID_CLIENT:
1800     {
1801       SilcClientEntry entry;
1802
1803       /* Check that we do not have this client already */
1804       entry = silc_idlist_find_client_by_id(server->global_list, 
1805                                             id, server->server_type, 
1806                                             NULL);
1807       if (!entry)
1808         entry = silc_idlist_find_client_by_id(server->local_list, 
1809                                               id, server->server_type,
1810                                               NULL);
1811       if (entry) {
1812         SILC_LOG_DEBUG(("Ignoring client that we already have"));
1813         goto out;
1814       }
1815
1816       SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
1817                       silc_id_render(id, SILC_ID_CLIENT),
1818                       sock->type == SILC_SOCKET_TYPE_SERVER ?
1819                       "Server" : "Router", sock->hostname));
1820     
1821       /* As a router we keep information of all global information in our
1822          global list. Cell wide information however is kept in the local
1823          list. */
1824       entry = silc_idlist_add_client(id_list, NULL, NULL, NULL, 
1825                                      id, router, NULL);
1826       if (!entry) {
1827         SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
1828
1829         /* Inform the sender that the ID is not usable */
1830         silc_server_send_notify_signoff(server, sock, FALSE, id, NULL);
1831         goto out;
1832       }
1833       entry->nickname = NULL;
1834       entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
1835
1836       if (sock->type == SILC_SOCKET_TYPE_SERVER)
1837         server->stat.cell_clients++;
1838       server->stat.clients++;
1839     }
1840     break;
1841
1842   case SILC_ID_SERVER:
1843     {
1844       SilcServerEntry entry;
1845
1846       /* If the ID is mine, ignore it. */
1847       if (SILC_ID_SERVER_COMPARE(id, server->id)) {
1848         SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
1849         break;
1850       }
1851
1852       /* If the ID is the sender's ID, ignore it (we have it already) */
1853       if (SILC_ID_SERVER_COMPARE(id, router->id)) {
1854         SILC_LOG_DEBUG(("Ignoring sender's own ID"));
1855         break;
1856       }
1857       
1858       /* Check that we do not have this server already */
1859       entry = silc_idlist_find_server_by_id(server->global_list, 
1860                                             id, server->server_type, 
1861                                             NULL);
1862       if (!entry)
1863         entry = silc_idlist_find_server_by_id(server->local_list, 
1864                                               id, server->server_type,
1865                                               NULL);
1866       if (entry) {
1867         SILC_LOG_DEBUG(("Ignoring server that we already have"));
1868         goto out;
1869       }
1870
1871       SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
1872                       silc_id_render(id, SILC_ID_SERVER),
1873                       sock->type == SILC_SOCKET_TYPE_SERVER ?
1874                       "Server" : "Router", sock->hostname));
1875       
1876       /* As a router we keep information of all global information in our 
1877          global list. Cell wide information however is kept in the local
1878          list. */
1879       entry = silc_idlist_add_server(id_list, NULL, 0, id, router, 
1880                                      router_sock);
1881       if (!entry) {
1882         SILC_LOG_ERROR(("Could not add new server to the ID Cache"));
1883         goto out;
1884       }
1885       entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
1886       
1887       if (sock->type == SILC_SOCKET_TYPE_SERVER)
1888         server->stat.cell_servers++;
1889       server->stat.servers++;
1890     }
1891     break;
1892
1893   case SILC_ID_CHANNEL:
1894     SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
1895     goto out;
1896     break;
1897
1898   default:
1899     goto out;
1900     break;
1901   }
1902
1903   /* If the sender of this packet is server and we are router we need to
1904      broadcast this packet to other routers in the network. */
1905   if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
1906       sock->type == SILC_SOCKET_TYPE_SERVER &&
1907       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1908     SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
1909     silc_server_packet_send(server, server->router->connection,
1910                             packet->type, 
1911                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1912                             buffer->data, buffer->len, FALSE);
1913     silc_server_backup_send(server, (SilcServerEntry)sock->user_data, 
1914                             packet->type, packet->flags,
1915                             packet->buffer->data, packet->buffer->len, 
1916                             FALSE, TRUE);
1917   }
1918
1919  out:
1920   silc_id_payload_free(idp);
1921 }
1922
1923
1924 /* Processes incoming New ID packet. New ID Payload is used to distribute
1925    information about newly registered clients and servers. */
1926
1927 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
1928                         SilcPacketContext *packet)
1929 {
1930   silc_server_new_id_real(server, sock, packet, TRUE);
1931 }
1932
1933 /* Receoved New Id List packet, list of New ID payloads inside one
1934    packet. Process the New ID payloads one by one. */
1935
1936 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
1937                              SilcPacketContext *packet)
1938 {
1939   SilcPacketContext *new_id;
1940   SilcBuffer idp;
1941   uint16 id_len;
1942
1943   SILC_LOG_DEBUG(("Processing New ID List"));
1944
1945   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1946       packet->src_id_type != SILC_ID_SERVER)
1947     return;
1948
1949   /* If the sender of this packet is server and we are router we need to
1950      broadcast this packet to other routers in the network. Broadcast
1951      this list packet instead of multiple New ID packets. */
1952   if (!server->standalone && server->server_type == SILC_ROUTER &&
1953       sock->type == SILC_SOCKET_TYPE_SERVER &&
1954       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1955     SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
1956     silc_server_packet_send(server, server->router->connection,
1957                             packet->type, 
1958                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1959                             packet->buffer->data, packet->buffer->len, FALSE);
1960     silc_server_backup_send(server, (SilcServerEntry)sock->user_data, 
1961                             packet->type, packet->flags,
1962                             packet->buffer->data, packet->buffer->len, 
1963                             FALSE, TRUE);
1964   }
1965
1966   /* Make copy of the original packet context, except for the actual
1967      data buffer, which we will here now fetch from the original buffer. */
1968   new_id = silc_packet_context_alloc();
1969   new_id->type = SILC_PACKET_NEW_ID;
1970   new_id->flags = packet->flags;
1971   new_id->src_id = packet->src_id;
1972   new_id->src_id_len = packet->src_id_len;
1973   new_id->src_id_type = packet->src_id_type;
1974   new_id->dst_id = packet->dst_id;
1975   new_id->dst_id_len = packet->dst_id_len;
1976   new_id->dst_id_type = packet->dst_id_type;
1977
1978   idp = silc_buffer_alloc(256);
1979   new_id->buffer = idp;
1980
1981   while (packet->buffer->len) {
1982     SILC_GET16_MSB(id_len, packet->buffer->data + 2);
1983     if ((id_len > packet->buffer->len) ||
1984         (id_len > idp->truelen))
1985       break;
1986
1987     silc_buffer_pull_tail(idp, 4 + id_len);
1988     silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
1989
1990     /* Process the New ID */
1991     silc_server_new_id_real(server, sock, new_id, FALSE);
1992
1993     silc_buffer_push_tail(idp, 4 + id_len);
1994     silc_buffer_pull(packet->buffer, 4 + id_len);
1995   }
1996
1997   silc_buffer_free(idp);
1998   silc_free(new_id);
1999 }
2000
2001 /* Received New Channel packet. Information about new channels in the 
2002    network are distributed using this packet. Save the information about
2003    the new channel. This usually comes from router but also normal server
2004    can send this to notify channels it has when it connects to us. */
2005
2006 void silc_server_new_channel(SilcServer server,
2007                              SilcSocketConnection sock,
2008                              SilcPacketContext *packet)
2009 {
2010   SilcChannelPayload payload;
2011   SilcChannelID *channel_id;
2012   char *channel_name;
2013   uint32 name_len;
2014   unsigned char *id;
2015   uint32 id_len;
2016   uint32 mode;
2017   SilcServerEntry server_entry;
2018   SilcChannelEntry channel;
2019
2020   SILC_LOG_DEBUG(("Processing New Channel"));
2021
2022   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2023       packet->src_id_type != SILC_ID_SERVER ||
2024       server->server_type == SILC_SERVER)
2025     return;
2026
2027   /* Parse the channel payload */
2028   payload = silc_channel_payload_parse(packet->buffer);
2029   if (!payload)
2030     return;
2031     
2032   /* Get the channel ID */
2033   channel_id = silc_channel_get_id_parse(payload);
2034   if (!channel_id) {
2035     silc_channel_payload_free(payload);
2036     return;
2037   }
2038
2039   channel_name = silc_channel_get_name(payload, &name_len);
2040   if (name_len > 256)
2041     channel_name[255] = '\0';
2042
2043   id = silc_channel_get_id(payload, &id_len);
2044
2045   server_entry = (SilcServerEntry)sock->user_data;
2046
2047   if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
2048     /* Add the channel to global list as it is coming from router. It 
2049        cannot be our own channel as it is coming from router. */
2050
2051     /* Check that we don't already have this channel */
2052     channel = silc_idlist_find_channel_by_name(server->local_list, 
2053                                                channel_name, NULL);
2054     if (!channel)
2055       channel = silc_idlist_find_channel_by_name(server->global_list, 
2056                                                  channel_name, NULL);
2057     if (!channel) {
2058       SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
2059                       silc_id_render(channel_id, SILC_ID_CHANNEL), 
2060                       sock->hostname));
2061     
2062       silc_idlist_add_channel(server->global_list, strdup(channel_name), 
2063                               0, channel_id, sock->user_data, NULL, NULL);
2064       server->stat.channels++;
2065     }
2066   } else {
2067     /* The channel is coming from our server, thus it is in our cell
2068        we will add it to our local list. */
2069     SilcBuffer chk;
2070
2071     SILC_LOG_DEBUG(("Channel id(%s) from [Server] %s",
2072                     silc_id_render(channel_id, SILC_ID_CHANNEL), 
2073                     sock->hostname));
2074
2075     /* Check that we don't already have this channel */
2076     channel = silc_idlist_find_channel_by_name(server->local_list, 
2077                                                channel_name, NULL);
2078     if (!channel)
2079       channel = silc_idlist_find_channel_by_name(server->global_list, 
2080                                                  channel_name, NULL);
2081
2082     /* If the channel does not exist, then create it. This creates a new
2083        key to the channel as well that we will send to the server. */
2084     if (!channel) {
2085       /* The protocol says that the Channel ID's IP address must be based
2086          on the router's IP address.  Check whether the ID is based in our
2087          IP and if it is not then create a new ID and enforce the server
2088          to switch the ID. */
2089       if (server_entry->server_type != SILC_BACKUP_ROUTER &&
2090           !SILC_ID_COMPARE(channel_id, server->id, server->id->ip.data_len)) {
2091         SilcChannelID *tmp;
2092         SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2093         
2094         if (silc_id_create_channel_id(server, server->id, server->rng, &tmp)) {
2095           silc_server_send_notify_channel_change(server, sock, FALSE, 
2096                                                  channel_id, tmp);
2097           silc_free(channel_id);
2098           channel_id = tmp;
2099         }
2100       }
2101
2102       /* Create the channel with the provided Channel ID */
2103       channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
2104                                                        channel_name,
2105                                                        channel_id, FALSE);
2106       if (!channel) {
2107         silc_channel_payload_free(payload);
2108         silc_free(channel_id);
2109         return;
2110       }
2111
2112       /* Get the mode and set it to the channel */
2113       channel->mode = silc_channel_get_mode(payload);
2114
2115       /* Send the new channel key to the server */
2116       chk = silc_channel_key_payload_encode(id_len, id,
2117                                             strlen(channel->channel_key->
2118                                                    cipher->name),
2119                                             channel->channel_key->cipher->name,
2120                                             channel->key_len / 8, 
2121                                             channel->key);
2122       silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
2123                               chk->data, chk->len, FALSE);
2124       silc_buffer_free(chk);
2125
2126     } else {
2127       /* The channel exist by that name, check whether the ID's match.
2128          If they don't then we'll force the server to use the ID we have.
2129          We also create a new key for the channel. */
2130       SilcBuffer users = NULL, users_modes = NULL;
2131
2132       if (!channel->id)
2133         channel->id = silc_id_dup(channel_id, SILC_ID_CHANNEL);
2134
2135       if (!SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
2136         /* They don't match, send CHANNEL_CHANGE notify to the server to
2137            force the ID change. */
2138         SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2139         silc_server_send_notify_channel_change(server, sock, FALSE, 
2140                                                channel_id, channel->id);
2141       }
2142
2143       /* If the mode is different from what we have then enforce the
2144          mode change. */
2145       mode = silc_channel_get_mode(payload);
2146       if (channel->mode != mode) {
2147         SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
2148         silc_server_send_notify_cmode(server, sock, FALSE, channel,
2149                                       channel->mode, server->id,
2150                                       SILC_ID_SERVER,
2151                                       channel->cipher, channel->hmac_name);
2152       }
2153
2154       /* Create new key for the channel and send it to the server and
2155          everybody else possibly on the channel. */
2156
2157       if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
2158         if (!silc_server_create_channel_key(server, channel, 0))
2159           return;
2160         
2161         /* Send to the channel */
2162         silc_server_send_channel_key(server, sock, channel, FALSE);
2163         id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2164         id_len = SILC_ID_CHANNEL_LEN;
2165         
2166         /* Send to the server */
2167         chk = silc_channel_key_payload_encode(id_len, id,
2168                                               strlen(channel->channel_key->
2169                                                      cipher->name),
2170                                               channel->channel_key->
2171                                               cipher->name,
2172                                               channel->key_len / 8, 
2173                                               channel->key);
2174         silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
2175                                 chk->data, chk->len, FALSE);
2176         silc_buffer_free(chk);
2177         silc_free(id);
2178       }
2179
2180       silc_free(channel_id);
2181
2182       /* Since the channel is coming from server and we also know about it
2183          then send the JOIN notify to the server so that it see's our
2184          users on the channel "joining" the channel. */
2185       silc_server_announce_get_channel_users(server, channel, &users,
2186                                              &users_modes);
2187       if (users) {
2188         silc_buffer_push(users, users->data - users->head);
2189         silc_server_packet_send(server, sock,
2190                                 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2191                                 users->data, users->len, FALSE);
2192         silc_buffer_free(users);
2193       }
2194       if (users_modes) {
2195         silc_buffer_push(users_modes, users_modes->data - users_modes->head);
2196         silc_server_packet_send_dest(server, sock,
2197                                      SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2198                                      channel->id, SILC_ID_CHANNEL,
2199                                      users_modes->data, 
2200                                      users_modes->len, FALSE);
2201         silc_buffer_free(users_modes);
2202       }
2203     }
2204   }
2205
2206   silc_channel_payload_free(payload);
2207 }
2208
2209 /* Received New Channel List packet, list of New Channel List payloads inside
2210    one packet. Process the New Channel payloads one by one. */
2211
2212 void silc_server_new_channel_list(SilcServer server,
2213                                   SilcSocketConnection sock,
2214                                   SilcPacketContext *packet)
2215 {
2216   SilcPacketContext *new;
2217   SilcBuffer buffer;
2218   uint16 len1, len2;
2219
2220   SILC_LOG_DEBUG(("Processing New Channel List"));
2221
2222   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2223       packet->src_id_type != SILC_ID_SERVER ||
2224       server->server_type == SILC_SERVER)
2225     return;
2226
2227   /* If the sender of this packet is server and we are router we need to
2228      broadcast this packet to other routers in the network. Broadcast
2229      this list packet instead of multiple New Channel packets. */
2230   if (!server->standalone && server->server_type == SILC_ROUTER &&
2231       sock->type == SILC_SOCKET_TYPE_SERVER &&
2232       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2233     SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
2234     silc_server_packet_send(server, server->router->connection,
2235                             packet->type, 
2236                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
2237                             packet->buffer->data, packet->buffer->len, FALSE);
2238     silc_server_backup_send(server, (SilcServerEntry)sock->user_data, 
2239                             packet->type, packet->flags,
2240                             packet->buffer->data, packet->buffer->len, 
2241                             FALSE, TRUE);
2242   }
2243
2244   /* Make copy of the original packet context, except for the actual
2245      data buffer, which we will here now fetch from the original buffer. */
2246   new = silc_packet_context_alloc();
2247   new->type = SILC_PACKET_NEW_CHANNEL;
2248   new->flags = packet->flags;
2249   new->src_id = packet->src_id;
2250   new->src_id_len = packet->src_id_len;
2251   new->src_id_type = packet->src_id_type;
2252   new->dst_id = packet->dst_id;
2253   new->dst_id_len = packet->dst_id_len;
2254   new->dst_id_type = packet->dst_id_type;
2255
2256   buffer = silc_buffer_alloc(512);
2257   new->buffer = buffer;
2258
2259   while (packet->buffer->len) {
2260     SILC_GET16_MSB(len1, packet->buffer->data);
2261     if ((len1 > packet->buffer->len) ||
2262         (len1 > buffer->truelen))
2263       break;
2264
2265     SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
2266     if ((len2 > packet->buffer->len) ||
2267         (len2 > buffer->truelen))
2268       break;
2269
2270     silc_buffer_pull_tail(buffer, 8 + len1 + len2);
2271     silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
2272
2273     /* Process the New Channel */
2274     silc_server_new_channel(server, sock, new);
2275
2276     silc_buffer_push_tail(buffer, 8 + len1 + len2);
2277     silc_buffer_pull(packet->buffer, 8 + len1 + len2);
2278   }
2279
2280   silc_buffer_free(buffer);
2281   silc_free(new);
2282 }
2283
2284 /* Received key agreement packet. This packet is never for us. It is to
2285    the client in the packet's destination ID. Sending of this sort of packet
2286    equals sending private message, ie. it is sent point to point from
2287    one client to another. */
2288
2289 void silc_server_key_agreement(SilcServer server,
2290                                SilcSocketConnection sock,
2291                                SilcPacketContext *packet)
2292 {
2293   SilcSocketConnection dst_sock;
2294   SilcIDListData idata;
2295
2296   SILC_LOG_DEBUG(("Start"));
2297
2298   if (packet->src_id_type != SILC_ID_CLIENT ||
2299       packet->dst_id_type != SILC_ID_CLIENT)
2300     return;
2301
2302   if (!packet->dst_id)
2303     return;
2304
2305   /* Get the route to the client */
2306   dst_sock = silc_server_get_client_route(server, packet->dst_id,
2307                                           packet->dst_id_len, NULL, &idata);
2308   if (!dst_sock)
2309     return;
2310
2311   /* Relay the packet */
2312   silc_server_relay_packet(server, dst_sock, idata->send_key,
2313                            idata->hmac_send, packet, FALSE);
2314 }
2315
2316 /* Received connection auth request packet that is used during connection
2317    phase to resolve the mandatory authentication method.  This packet can
2318    actually be received at anytime but usually it is used only during
2319    the connection authentication phase. Now, protocol says that this packet
2320    can come from client or server, however, we support only this coming
2321    from client and expect that server always knows what authentication
2322    method to use. */
2323
2324 void silc_server_connection_auth_request(SilcServer server,
2325                                          SilcSocketConnection sock,
2326                                          SilcPacketContext *packet)
2327 {
2328   SilcServerConfigSectionClientConnection *client = NULL;
2329   uint16 conn_type;
2330   int ret, port;
2331   SilcAuthMethod auth_meth;
2332
2333   SILC_LOG_DEBUG(("Start"));
2334
2335   if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT)
2336     return;
2337
2338   /* Parse the payload */
2339   ret = silc_buffer_unformat(packet->buffer,
2340                              SILC_STR_UI_SHORT(&conn_type),
2341                              SILC_STR_UI_SHORT(NULL),
2342                              SILC_STR_END);
2343   if (ret == -1)
2344     return;
2345
2346   if (conn_type != SILC_SOCKET_TYPE_CLIENT)
2347     return;
2348
2349   /* Get the authentication method for the client */
2350   auth_meth = SILC_AUTH_NONE;
2351   port = server->sockets[server->sock]->port; /* Listenning port */
2352   client = silc_server_config_find_client_conn(server->config,
2353                                                sock->ip,
2354                                                port);
2355   if (!client)
2356     client = silc_server_config_find_client_conn(server->config,
2357                                                  sock->hostname,
2358                                                  port);
2359   if (client)
2360     auth_meth = client->auth_meth;
2361           
2362   /* Send it back to the client */
2363   silc_server_send_connection_auth_request(server, sock,
2364                                            conn_type,
2365                                            auth_meth);
2366 }
2367
2368 /* Received REKEY packet. The sender of the packet wants to regenerate
2369    its session keys. This starts the REKEY protocol. */
2370
2371 void silc_server_rekey(SilcServer server,
2372                        SilcSocketConnection sock,
2373                        SilcPacketContext *packet)
2374 {
2375   SilcProtocol protocol;
2376   SilcServerRekeyInternalContext *proto_ctx;
2377   SilcIDListData idata = (SilcIDListData)sock->user_data;
2378
2379   SILC_LOG_DEBUG(("Start"));
2380
2381   /* Allocate internal protocol context. This is sent as context
2382      to the protocol. */
2383   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
2384   proto_ctx->server = (void *)server;
2385   proto_ctx->sock = sock;
2386   proto_ctx->responder = TRUE;
2387   proto_ctx->pfs = idata->rekey->pfs;
2388       
2389   /* Perform rekey protocol. Will call the final callback after the
2390      protocol is over. */
2391   silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY, 
2392                       &protocol, proto_ctx, silc_server_rekey_final);
2393   sock->protocol = protocol;
2394
2395   if (proto_ctx->pfs == FALSE)
2396     /* Run the protocol */
2397     silc_protocol_execute(protocol, server->schedule, 0, 0);
2398 }