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