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