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