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