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