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