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