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, *channel_id2;
41   SilcClientID *client_id, *client_id2;
42   SilcChannelEntry channel;
43   SilcClientEntry client;
44   SilcChannelClientEntry chl;
45   SilcIDCacheEntry cache;
46   unsigned int mode;
47   unsigned char *tmp;
48   unsigned int tmp_len;
49
50   SILC_LOG_DEBUG(("Start"));
51
52   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
53       packet->src_id_type != SILC_ID_SERVER)
54     return;
55
56   if (!packet->dst_id)
57     return;
58
59   /* If the packet is destined directly to a client then relay the packet
60      before processing it. */
61   if (packet->dst_id_type == SILC_ID_CLIENT) {
62     SilcIDListData idata;
63     SilcSocketConnection dst_sock;
64
65     /* Get the route to the client */
66     dst_sock = silc_server_get_client_route(server, packet->dst_id,
67                                             packet->dst_id_len, NULL, &idata);
68     if (dst_sock)
69       /* Relay the packet */
70       silc_server_relay_packet(server, dst_sock, idata->send_key,
71                                idata->hmac, packet, TRUE);
72   }
73
74   /* If we are router and this packet is not already broadcast packet
75      we will broadcast it. The sending socket really cannot be router or
76      the router is buggy. If this packet is coming from router then it must
77      have the broadcast flag set already and we won't do anything. */
78   if (!server->standalone && server->server_type == SILC_ROUTER &&
79       sock->type == SILC_SOCKET_TYPE_SERVER &&
80       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
81     SILC_LOG_DEBUG(("Broadcasting received Notify packet"));
82     silc_server_packet_send(server, server->router->connection, packet->type,
83                             packet->flags | SILC_PACKET_FLAG_BROADCAST, 
84                             packet->buffer->data, packet->buffer->len, FALSE);
85   }
86
87   payload = silc_notify_payload_parse(packet->buffer);
88   if (!payload)
89     return;
90
91   type = silc_notify_get_type(payload);
92   args = silc_notify_get_args(payload);
93   if (!args)
94     goto out;
95
96   switch(type) {
97   case SILC_NOTIFY_TYPE_JOIN:
98     /* 
99      * Distribute the notify to local clients on the channel
100      */
101     SILC_LOG_DEBUG(("JOIN notify"));
102
103     /* Get Channel ID */
104     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
105     if (!tmp)
106       goto out;
107     channel_id = silc_id_payload_parse_id(tmp, tmp_len);
108     if (!channel_id)
109       goto out;
110
111     /* Get channel entry */
112     channel = silc_idlist_find_channel_by_id(server->global_list, 
113                                              channel_id, NULL);
114     if (!channel) {
115       channel = silc_idlist_find_channel_by_id(server->local_list, 
116                                                channel_id, NULL);
117       if (!channel) {
118         silc_free(channel_id);
119         goto out;
120       }
121     }
122     silc_free(channel_id);
123
124     /* Get client ID */
125     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
126     if (!tmp)
127       goto out;
128     client_id = silc_id_payload_parse_id(tmp, tmp_len);
129     if (!client_id)
130       goto out;
131
132     /* Send to channel */
133     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
134                                        FALSE, packet->buffer->data, 
135                                        packet->buffer->len, FALSE);
136
137     /* If the the client is not in local list we check global list (ie. the
138        channel will be global channel) and if it does not exist then create
139        entry for the client. */
140     client = silc_idlist_find_client_by_id(server->global_list, 
141                                            client_id, NULL);
142     if (!client) {
143       client = silc_idlist_find_client_by_id(server->local_list, 
144                                              client_id, NULL);
145       if (!client) {
146         /* If router did not find the client the it is bogus */
147         if (server->server_type == SILC_ROUTER)
148           goto out;
149
150         client = 
151           silc_idlist_add_client(server->global_list, NULL, 0, NULL, NULL,
152                                  silc_id_dup(client_id, SILC_ID_CLIENT), 
153                                  sock->user_data, NULL);
154         if (!client) {
155           silc_free(client_id);
156           goto out;
157         }
158
159         client->data.registered = TRUE;
160       }
161     }
162
163     /* Do not add client to channel if it is there already */
164     if (silc_server_client_on_channel(client, channel))
165       break;
166
167     if (server->server_type == SILC_SERVER && 
168         sock->type == SILC_SOCKET_TYPE_ROUTER)
169       /* The channel is global now */
170       channel->global_users = TRUE;
171
172     /* JOIN the global client to the channel (local clients (if router 
173        created the channel) is joined in the pending JOIN command). */
174     chl = silc_calloc(1, sizeof(*chl));
175     chl->client = client;
176     chl->channel = channel;
177     silc_list_add(channel->user_list, chl);
178     silc_list_add(client->channels, chl);
179     silc_free(client_id);
180
181     break;
182
183   case SILC_NOTIFY_TYPE_LEAVE:
184     /* 
185      * Distribute the notify to local clients on the channel
186      */
187     SILC_LOG_DEBUG(("LEAVE notify"));
188
189     channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
190                                 packet->dst_id_type);
191     if (!channel_id)
192       goto out;
193
194     /* Get channel entry */
195     channel = silc_idlist_find_channel_by_id(server->global_list, 
196                                              channel_id, NULL);
197     if (!channel) { 
198       channel = silc_idlist_find_channel_by_id(server->local_list, 
199                                                channel_id, NULL);
200       if (!channel) {
201         silc_free(channel_id);
202         goto out;
203       }
204     }
205
206     /* Get client ID */
207     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
208     if (!tmp) {
209       silc_free(channel_id);
210       goto out;
211     }
212     client_id = silc_id_payload_parse_id(tmp, tmp_len);
213     if (!client_id) {
214       silc_free(channel_id);
215       goto out;
216     }
217
218     /* Send to channel */
219     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
220                                        FALSE, packet->buffer->data, 
221                                        packet->buffer->len, FALSE);
222
223     /* Get client entry */
224     client = silc_idlist_find_client_by_id(server->global_list, 
225                                            client_id, NULL);
226     if (!client) {
227       client = silc_idlist_find_client_by_id(server->local_list, 
228                                              client_id, NULL);
229       if (!client) {
230         silc_free(client_id);
231         silc_free(channel_id);
232         goto out;
233       }
234     }
235     silc_free(client_id);
236
237     /* Remove the user from channel */
238     silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
239     break;
240
241   case SILC_NOTIFY_TYPE_SIGNOFF:
242     /* 
243      * Distribute the notify to local clients on the channel
244      */
245     SILC_LOG_DEBUG(("SIGNOFF notify"));
246
247     /* Get client ID */
248     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
249     if (!tmp)
250       goto out;
251     client_id = silc_id_payload_parse_id(tmp, tmp_len);
252     if (!client_id)
253       goto out;
254
255     /* Get client entry */
256     client = silc_idlist_find_client_by_id(server->global_list, 
257                                            client_id, &cache);
258     if (!client) {
259       client = silc_idlist_find_client_by_id(server->local_list, 
260                                              client_id, &cache);
261       if (!client) {
262         silc_free(client_id);
263         goto out;
264       }
265     }
266     silc_free(client_id);
267
268     /* Get signoff message */
269     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
270     if (tmp_len > 128)
271       tmp = NULL;
272
273     /* Remove the client from all channels */
274     silc_server_remove_from_channels(server, NULL, client, TRUE, tmp, TRUE);
275
276     client->data.registered = FALSE;
277     cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
278
279 #if 0
280     /* Remove the client entry */
281     if (!silc_idlist_del_client(server->global_list, client))
282       silc_idlist_del_client(server->local_list, client);
283 #endif
284     break;
285
286   case SILC_NOTIFY_TYPE_TOPIC_SET:
287     /* 
288      * Distribute the notify to local clients on the channel
289      */
290
291     SILC_LOG_DEBUG(("TOPIC SET notify"));
292
293     channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
294                                 packet->dst_id_type);
295     if (!channel_id)
296       goto out;
297
298     /* Get channel entry */
299     channel = silc_idlist_find_channel_by_id(server->global_list, 
300                                              channel_id, NULL);
301     if (!channel) {
302       channel = silc_idlist_find_channel_by_id(server->local_list, 
303                                                channel_id, NULL);
304       if (!channel) {
305         silc_free(channel_id);
306         goto out;
307       }
308     }
309
310     /* Get the topic */
311     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
312     if (!tmp) {
313       silc_free(channel_id);
314       goto out;
315     }
316
317     if (channel->topic)
318       silc_free(channel->topic);
319     channel->topic = silc_calloc(tmp_len, sizeof(*channel->topic));
320     memcpy(channel->topic, tmp, tmp_len);
321
322     /* Send the same notify to the channel */
323     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
324                                        FALSE, packet->buffer->data, 
325                                        packet->buffer->len, FALSE);
326     silc_free(channel_id);
327     break;
328
329   case SILC_NOTIFY_TYPE_NICK_CHANGE:
330     {
331       /* 
332        * Distribute the notify to local clients on the channel
333        */
334       unsigned char *id, *id2;
335
336       SILC_LOG_DEBUG(("NICK CHANGE notify"));
337       
338       /* Get old client ID */
339       id = silc_argument_get_arg_type(args, 1, &tmp_len);
340       if (!id)
341         goto out;
342       client_id = silc_id_payload_parse_id(id, tmp_len);
343       if (!client_id)
344         goto out;
345       
346       /* Get new client ID */
347       id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
348       if (!id2)
349         goto out;
350       client_id2 = silc_id_payload_parse_id(id2, tmp_len);
351       if (!client_id2)
352         goto out;
353       
354       SILC_LOG_DEBUG(("Old Client ID id(%s)", 
355                       silc_id_render(client_id, SILC_ID_CLIENT)));
356       SILC_LOG_DEBUG(("New Client ID id(%s)", 
357                       silc_id_render(client_id2, SILC_ID_CLIENT)));
358
359       /* Replace the Client ID */
360       client = silc_idlist_replace_client_id(server->global_list, client_id,
361                                              client_id2);
362       if (!client)
363         client = silc_idlist_replace_client_id(server->local_list, client_id, 
364                                                client_id2);
365
366       if (client) {
367         /* The nickname is not valid anymore, set it NULL. This causes that
368            the nickname will be queried if someone wants to know it. */
369         if (client->nickname)
370           silc_free(client->nickname);
371         client->nickname = NULL;
372
373         /* Send the NICK_CHANGE notify type to local clients on the channels
374            this client is joined to. */
375         silc_server_send_notify_on_channels(server, NULL, client, 
376                                             SILC_NOTIFY_TYPE_NICK_CHANGE, 2,
377                                             id, tmp_len, 
378                                             id2, tmp_len);
379       }
380
381       silc_free(client_id);
382       if (!client)
383         silc_free(client_id2);
384       break;
385     }
386
387   case SILC_NOTIFY_TYPE_CMODE_CHANGE:
388     /* 
389      * Distribute the notify to local clients on the channel
390      */
391     
392     SILC_LOG_DEBUG(("CMODE CHANGE notify"));
393       
394     channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
395                                 packet->dst_id_type);
396     if (!channel_id)
397       goto out;
398
399     /* Get channel entry */
400     channel = silc_idlist_find_channel_by_id(server->global_list, 
401                                              channel_id, NULL);
402     if (!channel) {
403       channel = silc_idlist_find_channel_by_id(server->local_list, 
404                                                channel_id, NULL);
405       if (!channel) {
406         silc_free(channel_id);
407         goto out;
408       }
409     }
410
411     /* Send the same notify to the channel */
412     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
413                                        FALSE, packet->buffer->data, 
414                                        packet->buffer->len, FALSE);
415
416     /* Get the mode */
417     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
418     if (!tmp) {
419       silc_free(channel_id);
420       goto out;
421     }
422
423     SILC_GET32_MSB(mode, tmp);
424
425     /* If the channel had private keys set and the mode was removed then
426        we must re-generate and re-distribute a new channel key */
427     if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY &&
428         !(mode & SILC_CHANNEL_MODE_PRIVKEY)) {
429       /* Re-generate channel key */
430       silc_server_create_channel_key(server, channel, 0);
431       
432       /* Send the channel key. This sends it to our local clients and if
433          we are normal server to our router as well. */
434       silc_server_send_channel_key(server, NULL, channel, 
435                                    server->server_type == SILC_ROUTER ? 
436                                    FALSE : !server->standalone);
437     }
438
439     /* Change mode */
440     channel->mode = mode;
441     silc_free(channel_id);
442
443     /* Get the hmac */
444     tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
445     if (tmp) {
446       unsigned char hash[32];
447
448       if (channel->hmac)
449         silc_hmac_free(channel->hmac);
450       if (!silc_hmac_alloc(tmp, NULL, &channel->hmac))
451         goto out;
452
453       /* Set the HMAC key out of current channel key. The client must do
454          this locally. */
455       silc_hash_make(channel->hmac->hash, channel->key, channel->key_len / 8, 
456                      hash);
457       silc_hmac_set_key(channel->hmac, hash, 
458                         silc_hash_len(channel->hmac->hash));
459       memset(hash, 0, sizeof(hash));
460     }
461
462     break;
463
464   case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
465     /* 
466      * Distribute the notify to local clients on the channel
467      */
468
469     SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
470
471     channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
472                                 packet->dst_id_type);
473     if (!channel_id)
474       goto out;
475
476     /* Get channel entry */
477     channel = silc_idlist_find_channel_by_id(server->global_list, 
478                                              channel_id, NULL);
479     if (!channel) {
480       channel = silc_idlist_find_channel_by_id(server->local_list, 
481                                                channel_id, NULL);
482       if (!channel) {
483         silc_free(channel_id);
484         goto out;
485       }
486     }
487
488     /* Get the mode */
489     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
490     if (!tmp) {
491       silc_free(channel_id);
492       goto out;
493     }
494       
495     SILC_GET32_MSB(mode, tmp);
496
497     /* Get target client */
498     tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
499     if (!tmp)
500       goto out;
501     client_id = silc_id_payload_parse_id(tmp, tmp_len);
502     if (!client_id)
503       goto out;
504     
505     /* Get client entry */
506     client = silc_idlist_find_client_by_id(server->global_list, 
507                                            client_id, NULL);
508     if (!client) {
509       client = silc_idlist_find_client_by_id(server->local_list, 
510                                              client_id, NULL);
511       if (!client) {
512         silc_free(client_id);
513         goto out;
514       }
515     }
516     silc_free(client_id);
517
518     /* Get entry to the channel user list */
519     silc_list_start(channel->user_list);
520     while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END)
521       if (chl->client == client) {
522         /* Change the mode */
523         chl->mode = mode;
524         break;
525       }
526
527     /* Send the same notify to the channel */
528     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
529                                        FALSE, packet->buffer->data, 
530                                        packet->buffer->len, FALSE);
531     silc_free(channel_id);
532     break;
533
534   case SILC_NOTIFY_TYPE_INVITE:
535
536     if (packet->dst_id_type == SILC_ID_CLIENT)
537       goto out;
538
539     SILC_LOG_DEBUG(("INVITE notify"));
540
541     /* Get Channel ID */
542     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
543     if (!tmp)
544       goto out;
545     channel_id = silc_id_payload_parse_id(tmp, tmp_len);
546     if (!channel_id)
547       goto out;
548
549     /* Get channel entry */
550     channel = silc_idlist_find_channel_by_id(server->global_list, 
551                                              channel_id, NULL);
552     if (!channel) {
553       channel = silc_idlist_find_channel_by_id(server->local_list, 
554                                                channel_id, NULL);
555       if (!channel) {
556         silc_free(channel_id);
557         goto out;
558       }
559     }
560     silc_free(channel_id);
561
562     /* Get the added invite */
563     tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
564     if (tmp) {
565       if (!channel->invite_list)
566         channel->invite_list = silc_calloc(tmp_len + 2, 
567                                            sizeof(*channel->invite_list));
568       else
569         channel->invite_list = silc_realloc(channel->invite_list, 
570                                             sizeof(*channel->invite_list) * 
571                                             (tmp_len + 
572                                              strlen(channel->invite_list) + 
573                                              2));
574       if (tmp[tmp_len - 1] == ',')
575         tmp[tmp_len - 1] = '\0';
576       
577       strncat(channel->invite_list, tmp, tmp_len);
578       strncat(channel->invite_list, ",", 1);
579     }
580
581     /* Get the deleted invite */
582     tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
583     if (tmp && channel->invite_list) {
584       char *start, *end, *n;
585       
586       if (!strncmp(channel->invite_list, tmp, 
587                    strlen(channel->invite_list) - 1)) {
588         silc_free(channel->invite_list);
589         channel->invite_list = NULL;
590       } else {
591         start = strstr(channel->invite_list, tmp);
592         if (start && strlen(start) >= tmp_len) {
593           end = start + tmp_len;
594           n = silc_calloc(strlen(channel->invite_list) - tmp_len, sizeof(*n));
595           strncat(n, channel->invite_list, start - channel->invite_list);
596           strncat(n, end + 1, ((channel->invite_list + 
597                                 strlen(channel->invite_list)) - end) - 1);
598           silc_free(channel->invite_list);
599           channel->invite_list = n;
600         }
601       }
602     }
603
604     break;
605
606   case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
607     /*
608      * Distribute to the local clients on the channel and change the
609      * channel ID.
610      */
611
612     SILC_LOG_DEBUG(("CHANNEL CHANGE"));
613
614     if (sock->type != SILC_SOCKET_TYPE_ROUTER)
615       break;
616
617     /* Get the old Channel ID */
618     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
619     if (!tmp)
620       goto out;
621     channel_id = silc_id_payload_parse_id(tmp, tmp_len);
622     if (!channel_id)
623       goto out;
624
625     /* Get the channel entry */
626     channel = silc_idlist_find_channel_by_id(server->global_list, 
627                                              channel_id, NULL);
628     if (!channel) {
629       channel = silc_idlist_find_channel_by_id(server->local_list, 
630                                                channel_id, NULL);
631       if (!channel) {
632         silc_free(channel_id);
633         goto out;
634       }
635     }
636
637     /* Send the notify to the channel */
638     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
639                                        FALSE, packet->buffer->data, 
640                                        packet->buffer->len, FALSE);
641
642     /* Get the new Channel ID */
643     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
644     if (!tmp)
645       goto out;
646     channel_id2 = silc_id_payload_parse_id(tmp, tmp_len);
647     if (!channel_id2)
648       goto out;
649
650     SILC_LOG_DEBUG(("Old Channel ID id(%s)", 
651                     silc_id_render(channel_id, SILC_ID_CHANNEL)));
652     SILC_LOG_DEBUG(("New Channel ID id(%s)", 
653                     silc_id_render(channel_id2, SILC_ID_CHANNEL)));
654
655     /* Replace the Channel ID */
656     if (!silc_idlist_replace_channel_id(server->global_list, channel_id,
657                                         channel_id2))
658       if (!silc_idlist_replace_channel_id(server->local_list, channel_id,
659                                           channel_id2)) {
660         silc_free(channel_id2);
661         channel_id2 = NULL;
662       }
663
664     if (channel_id2) {
665       SilcBuffer users = NULL;
666       
667       /* Re-announce our clients on the channel as the ID has changed now */
668       silc_server_announce_get_channel_users(server, channel, &users);
669       if (users) {
670         silc_buffer_push(users, users->data - users->head);
671         silc_server_packet_send(server, sock,
672                                 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
673                                 users->data, users->len, FALSE);
674         silc_buffer_free(users);
675       }
676     }
677
678     silc_free(channel_id);
679
680     break;
681
682   case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
683     SILC_LOG_DEBUG(("SERVER SIGNOFF notify (not-impl XXX)"));
684     break;
685
686   case SILC_NOTIFY_TYPE_KICKED:
687     /* 
688      * Distribute the notify to local clients on the channel
689      */
690     
691     SILC_LOG_DEBUG(("KICKED notify"));
692       
693     channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
694                                 packet->dst_id_type);
695     if (!channel_id)
696       goto out;
697
698     /* Get channel entry */
699     channel = silc_idlist_find_channel_by_id(server->global_list, 
700                                              channel_id, NULL);
701     if (!channel) {
702       channel = silc_idlist_find_channel_by_id(server->local_list, 
703                                                channel_id, NULL);
704       if (!channel) {
705         silc_free(channel_id);
706         goto out;
707       }
708     }
709     silc_free(channel_id);
710
711     /* Get client ID */
712     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
713     if (!tmp)
714       goto out;
715     client_id = silc_id_payload_parse_id(tmp, tmp_len);
716     if (!client_id)
717       goto out;
718
719     /* Send to channel */
720     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
721                                        FALSE, packet->buffer->data, 
722                                        packet->buffer->len, FALSE);
723
724     /* If the the client is not in local list we check global list */
725     client = silc_idlist_find_client_by_id(server->global_list, 
726                                            client_id, NULL);
727     if (!client) {
728       client = silc_idlist_find_client_by_id(server->local_list, 
729                                              client_id, NULL);
730       if (!client) {
731         silc_free(client_id);
732         goto out;
733       }
734     }
735
736     /* Remove the client from channel */
737     silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
738
739     break;
740
741   case SILC_NOTIFY_TYPE_KILLED:
742     {
743       /* 
744        * Distribute the notify to local clients on channels
745        */
746       unsigned char *id;
747       unsigned int id_len;
748     
749       SILC_LOG_DEBUG(("KILLED notify"));
750       
751       /* Get client ID */
752       id = silc_argument_get_arg_type(args, 1, &id_len);
753       if (!id)
754         goto out;
755       client_id = silc_id_payload_parse_id(id, id_len);
756       if (!client_id)
757         goto out;
758
759       /* If the the client is not in local list we check global list */
760       client = silc_idlist_find_client_by_id(server->global_list, 
761                                              client_id, NULL);
762       if (!client) {
763         client = silc_idlist_find_client_by_id(server->local_list, 
764                                                client_id, NULL);
765         if (!client) {
766           silc_free(client_id);
767           goto out;
768         }
769       }
770       silc_free(client_id);
771
772       /* If the client is one of ours, then close the connection to the
773          client now. This removes the client from all channels as well. */
774       if (packet->dst_id_type == SILC_ID_CLIENT && client->data.registered &&
775           client->connection) {
776         sock = client->connection;
777         silc_server_free_client_data(server, NULL, client, FALSE, NULL);
778         silc_server_close_connection(server, sock);
779         break;
780       }
781
782       /* Get comment */
783       tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
784       if (tmp_len > 128)
785         tmp = NULL;
786
787       /* Send the notify to local clients on the channels except to the
788          client who is killed. */
789       silc_server_send_notify_on_channels(server, client, client,
790                                           SILC_NOTIFY_TYPE_KILLED, 
791                                           tmp ? 2 : 1,
792                                           id, id_len, 
793                                           tmp, tmp_len);
794
795       /* Remove the client from all channels */
796       silc_server_remove_from_channels(server, NULL, client, FALSE, NULL, 
797                                        FALSE);
798
799       break;
800     }
801
802   case SILC_NOTIFY_TYPE_UMODE_CHANGE:
803     /*
804      * Save the mode of the client.
805      */
806
807     SILC_LOG_DEBUG(("UMODE_CHANGE notify"));
808       
809     /* Get client ID */
810     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
811     if (!tmp)
812       goto out;
813     client_id = silc_id_payload_parse_id(tmp, tmp_len);
814     if (!client_id)
815       goto out;
816
817     /* Get client entry */
818     client = silc_idlist_find_client_by_id(server->global_list, 
819                                            client_id, NULL);
820     if (!client) {
821       client = silc_idlist_find_client_by_id(server->local_list, 
822                                              client_id, NULL);
823       if (!client) {
824         silc_free(client_id);
825         goto out;
826       }
827     }
828     silc_free(client_id);
829
830     /* Get the mode */
831     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
832     if (!tmp)
833       goto out;
834
835     /* Save the mode */
836     SILC_GET32_MSB(client->mode, tmp);
837
838     break;
839
840   case SILC_NOTIFY_TYPE_BAN:
841     /*
842      * Save the ban
843      */
844
845     SILC_LOG_DEBUG(("BAN notify"));
846     
847     /* Get Channel ID */
848     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
849     if (!tmp)
850       goto out;
851     channel_id = silc_id_payload_parse_id(tmp, tmp_len);
852     if (!channel_id)
853       goto out;
854     
855     /* Get channel entry */
856     channel = silc_idlist_find_channel_by_id(server->global_list, 
857                                              channel_id, NULL);
858     if (!channel) {
859       channel = silc_idlist_find_channel_by_id(server->local_list, 
860                                                channel_id, NULL);
861       if (!channel) {
862         silc_free(channel_id);
863         goto out;
864       }
865     }
866     silc_free(channel_id);
867
868     /* Get the new ban and add it to the ban list */
869     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
870     if (tmp) {
871       if (!channel->ban_list)
872         channel->ban_list = silc_calloc(tmp_len + 2, 
873                                         sizeof(*channel->ban_list));
874       else
875         channel->ban_list = silc_realloc(channel->ban_list, 
876                                          sizeof(*channel->ban_list) * 
877                                          (tmp_len + 
878                                           strlen(channel->ban_list) + 2));
879       strncat(channel->ban_list, tmp, tmp_len);
880       strncat(channel->ban_list, ",", 1);
881     }
882
883     /* Get the ban to be removed and remove it from the list */
884     tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
885     if (tmp && channel->ban_list) {
886       char *start, *end, *n;
887       
888       if (!strcmp(channel->ban_list, tmp)) {
889         silc_free(channel->ban_list);
890         channel->ban_list = NULL;
891       } else {
892         start = strstr(channel->ban_list, tmp);
893         if (start && strlen(start) >= tmp_len) {
894           end = start + tmp_len;
895           n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
896           strncat(n, channel->ban_list, start - channel->ban_list);
897           strncat(n, end + 1, ((channel->ban_list + 
898                                 strlen(channel->ban_list)) - end) - 1);
899           silc_free(channel->ban_list);
900           channel->ban_list = n;
901         }
902       }
903     }
904
905     break;
906
907     /* Ignore rest of the notify types for now */
908   case SILC_NOTIFY_TYPE_NONE:
909   case SILC_NOTIFY_TYPE_MOTD:
910     break;
911   default:
912     break;
913   }
914
915  out:
916   silc_notify_payload_free(payload);
917 }
918
919 void silc_server_notify_list(SilcServer server,
920                              SilcSocketConnection sock,
921                              SilcPacketContext *packet)
922 {
923   SilcPacketContext *new;
924   SilcBuffer buffer;
925   unsigned short len;
926
927   SILC_LOG_DEBUG(("Processing New Notify List"));
928
929   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
930       packet->src_id_type != SILC_ID_SERVER)
931     return;
932
933   /* Make copy of the original packet context, except for the actual
934      data buffer, which we will here now fetch from the original buffer. */
935   new = silc_packet_context_alloc();
936   new->type = SILC_PACKET_NOTIFY;
937   new->flags = packet->flags;
938   new->src_id = packet->src_id;
939   new->src_id_len = packet->src_id_len;
940   new->src_id_type = packet->src_id_type;
941   new->dst_id = packet->dst_id;
942   new->dst_id_len = packet->dst_id_len;
943   new->dst_id_type = packet->dst_id_type;
944
945   buffer = silc_buffer_alloc(1024);
946   new->buffer = buffer;
947
948   while (packet->buffer->len) {
949     SILC_GET16_MSB(len, packet->buffer->data + 2);
950     if (len > packet->buffer->len)
951       break;
952
953     if (len > buffer->truelen) {
954       silc_buffer_free(buffer);
955       buffer = silc_buffer_alloc(1024 + len);
956     }
957
958     silc_buffer_pull_tail(buffer, len);
959     silc_buffer_put(buffer, packet->buffer->data, len);
960
961     /* Process the Notify */
962     silc_server_notify(server, sock, new);
963
964     silc_buffer_push_tail(buffer, len);
965     silc_buffer_pull(packet->buffer, len);
966   }
967
968   silc_buffer_free(buffer);
969   silc_free(new);
970 }
971
972 /* Received private message. This resolves the destination of the message 
973    and sends the packet. This is used by both server and router.  If the
974    destination is our locally connected client this sends the packet to
975    the client. This may also send the message for further routing if
976    the destination is not in our server (or router). */
977
978 void silc_server_private_message(SilcServer server,
979                                  SilcSocketConnection sock,
980                                  SilcPacketContext *packet)
981 {
982   SilcSocketConnection dst_sock;
983   SilcIDListData idata;
984
985   SILC_LOG_DEBUG(("Start"));
986
987   if (packet->src_id_type != SILC_ID_CLIENT ||
988       packet->dst_id_type != SILC_ID_CLIENT)
989     return;
990
991   if (!packet->dst_id)
992     return;
993
994   /* Get the route to the client */
995   dst_sock = silc_server_get_client_route(server, packet->dst_id,
996                                           packet->dst_id_len, NULL, &idata);
997   if (!dst_sock)
998     return;
999
1000   /* Send the private message */
1001   silc_server_send_private_message(server, dst_sock, idata->send_key,
1002                                    idata->hmac, packet);
1003 }
1004
1005 /* Received private message key packet.. This packet is never for us. It is to
1006    the client in the packet's destination ID. Sending of this sort of packet
1007    equals sending private message, ie. it is sent point to point from
1008    one client to another. */
1009
1010 void silc_server_private_message_key(SilcServer server,
1011                                      SilcSocketConnection sock,
1012                                      SilcPacketContext *packet)
1013 {
1014   SilcSocketConnection dst_sock;
1015   SilcIDListData idata;
1016
1017   SILC_LOG_DEBUG(("Start"));
1018
1019   if (packet->src_id_type != SILC_ID_CLIENT ||
1020       packet->dst_id_type != SILC_ID_CLIENT)
1021     return;
1022
1023   if (!packet->dst_id)
1024     return;
1025
1026   /* Get the route to the client */
1027   dst_sock = silc_server_get_client_route(server, packet->dst_id,
1028                                           packet->dst_id_len, NULL, &idata);
1029   if (!dst_sock)
1030     return;
1031
1032   /* Relay the packet */
1033   silc_server_relay_packet(server, dst_sock, idata->send_key,
1034                            idata->hmac, packet, FALSE);
1035 }
1036
1037 /* Processes incoming command reply packet. The command reply packet may
1038    be destined to one of our clients or it may directly for us. We will 
1039    call the command reply routine after processing the packet. */
1040
1041 void silc_server_command_reply(SilcServer server,
1042                                SilcSocketConnection sock,
1043                                SilcPacketContext *packet)
1044 {
1045   SilcBuffer buffer = packet->buffer;
1046   SilcClientEntry client = NULL;
1047   SilcSocketConnection dst_sock;
1048   SilcIDListData idata;
1049   SilcClientID *id = NULL;
1050
1051   SILC_LOG_DEBUG(("Start"));
1052
1053   /* Source must be server or router */
1054   if (packet->src_id_type != SILC_ID_SERVER &&
1055       sock->type != SILC_SOCKET_TYPE_ROUTER)
1056     return;
1057
1058   if (packet->dst_id_type == SILC_ID_CHANNEL)
1059     return;
1060
1061   if (packet->dst_id_type == SILC_ID_CLIENT) {
1062     /* Destination must be one of ours */
1063     id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
1064     if (!id)
1065       return;
1066     client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
1067     if (!client) {
1068       SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
1069       silc_free(id);
1070       return;
1071     }
1072   }
1073
1074   if (packet->dst_id_type == SILC_ID_SERVER) {
1075     /* For now this must be for us */
1076     if (SILC_ID_SERVER_COMPARE(packet->dst_id, server->id_string)) {
1077       SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
1078       return;
1079     }
1080   }
1081
1082   /* Execute command reply locally for the command */
1083   silc_server_command_reply_process(server, sock, buffer);
1084
1085   if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
1086     /* Relay the packet to the client */
1087     
1088     dst_sock = (SilcSocketConnection)client->connection;
1089     silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len 
1090                      + packet->dst_id_len + packet->padlen);
1091     
1092     silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
1093     silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
1094     
1095     idata = (SilcIDListData)client;
1096     
1097     /* Encrypt packet */
1098     silc_packet_encrypt(idata->send_key, idata->hmac, dst_sock->outbuf, 
1099                         buffer->len);
1100     
1101     /* Send the packet */
1102     silc_server_packet_send_real(server, dst_sock, TRUE);
1103
1104     silc_free(id);
1105   }
1106 }
1107
1108 /* Process received channel message. The message can be originated from
1109    client or server. */
1110
1111 void silc_server_channel_message(SilcServer server,
1112                                  SilcSocketConnection sock,
1113                                  SilcPacketContext *packet)
1114 {
1115   SilcChannelEntry channel = NULL;
1116   SilcChannelClientEntry chl;
1117   SilcChannelID *id = NULL;
1118   void *sender = NULL;
1119
1120   SILC_LOG_DEBUG(("Processing channel message"));
1121
1122   /* Sanity checks */
1123   if (packet->dst_id_type != SILC_ID_CHANNEL) {
1124     SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1125     goto out;
1126   }
1127
1128   /* Find channel entry */
1129   id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
1130   if (!id)
1131     goto out;
1132   channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
1133   if (!channel) {
1134     channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
1135     if (!channel) {
1136       SILC_LOG_DEBUG(("Could not find channel"));
1137       goto out;
1138     }
1139   }
1140
1141   /* See that this client is on the channel. If the message is coming
1142      from router we won't do the check as the message is from client that
1143      we don't know about. Also, if the original sender is not client
1144      (as it can be server as well) we don't do the check. */
1145   sender = silc_id_str2id(packet->src_id, packet->src_id_len, 
1146                           packet->src_id_type);
1147   if (!sender)
1148     goto out;
1149   if (sock->type != SILC_SOCKET_TYPE_ROUTER && 
1150       packet->src_id_type == SILC_ID_CLIENT) {
1151     silc_list_start(channel->user_list);
1152     while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
1153       if (chl->client && !SILC_ID_CLIENT_COMPARE(chl->client->id, sender))
1154         break;
1155     }
1156     if (chl == SILC_LIST_END) {
1157       SILC_LOG_DEBUG(("Client not on channel"));
1158       goto out;
1159     }
1160   }
1161
1162   /* If we are router and the packet came from router and private key
1163      has not been set for the channel then we must encrypt the packet
1164      as it was decrypted with the session key shared between us and the
1165      router which sent it. This is so, because cells does not share the
1166      same channel key */
1167   if (server->server_type == SILC_ROUTER &&
1168       sock->type == SILC_SOCKET_TYPE_ROUTER &&
1169       !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
1170     SilcBuffer chp;
1171     unsigned int iv_len, i;
1172     unsigned short data_len, flags;
1173
1174     iv_len = silc_cipher_get_block_len(channel->channel_key);
1175     if (channel->iv[0] == '\0')
1176       for (i = 0; i < iv_len; i++) channel->iv[i] = 
1177                                      silc_rng_get_byte(server->rng);
1178     else
1179       silc_hash_make(server->md5hash, channel->iv, iv_len, channel->iv);
1180     
1181     /* Encode new payload. This encrypts it also. */
1182     SILC_GET16_MSB(flags, packet->buffer->data);
1183     SILC_GET16_MSB(data_len, packet->buffer->data + 2);
1184     chp = silc_channel_message_payload_encode(flags, data_len, 
1185                                               packet->buffer->data + 4,
1186                                               iv_len, channel->iv,
1187                                               channel->channel_key,
1188                                               channel->hmac);
1189     silc_buffer_put(packet->buffer, chp->data, chp->len);
1190     silc_buffer_free(chp);
1191   }
1192
1193   /* Distribute the packet to our local clients. This will send the
1194      packet for further routing as well, if needed. */
1195   silc_server_packet_relay_to_channel(server, sock, channel, sender,
1196                                       packet->src_id_type,
1197                                       packet->buffer->data,
1198                                       packet->buffer->len, FALSE);
1199
1200  out:
1201   if (sender)
1202     silc_free(sender);
1203   if (id)
1204     silc_free(id);
1205 }
1206
1207 /* Received channel key packet. We distribute the key to all of our locally
1208    connected clients on the channel. */
1209
1210 void silc_server_channel_key(SilcServer server,
1211                              SilcSocketConnection sock,
1212                              SilcPacketContext *packet)
1213 {
1214   SilcBuffer buffer = packet->buffer;
1215   SilcChannelEntry channel;
1216
1217   if (packet->src_id_type != SILC_ID_SERVER ||
1218       (server->server_type == SILC_ROUTER &&
1219        sock->type == SILC_SOCKET_TYPE_ROUTER))
1220     return;
1221
1222   /* Save the channel key */
1223   channel = silc_server_save_channel_key(server, buffer, NULL);
1224   if (!channel)
1225     return;
1226
1227   /* Distribute the key to everybody who is on the channel. If we are router
1228      we will also send it to locally connected servers. */
1229   silc_server_send_channel_key(server, sock, channel, FALSE);
1230 }
1231
1232 /* Received New Client packet and processes it.  Creates Client ID for the
1233    client. Client becomes registered after calling this functions. */
1234
1235 SilcClientEntry silc_server_new_client(SilcServer server,
1236                                        SilcSocketConnection sock,
1237                                        SilcPacketContext *packet)
1238 {
1239   SilcBuffer buffer = packet->buffer;
1240   SilcClientEntry client;
1241   SilcIDCacheEntry cache;
1242   SilcClientID *client_id;
1243   SilcBuffer reply;
1244   SilcIDListData idata;
1245   char *username = NULL, *realname = NULL, *id_string;
1246   int ret;
1247
1248   SILC_LOG_DEBUG(("Creating new client"));
1249
1250   if (sock->type != SILC_SOCKET_TYPE_CLIENT)
1251     return NULL;
1252
1253   /* Take client entry */
1254   client = (SilcClientEntry)sock->user_data;
1255   idata = (SilcIDListData)client;
1256
1257   /* Fetch the old client cache entry so that we can update it. */
1258   if (!silc_idcache_find_by_context(server->local_list->clients,
1259                                     sock->user_data, &cache)) {
1260     SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
1261     return NULL;
1262   }
1263
1264   /* Parse incoming packet */
1265   ret = silc_buffer_unformat(buffer,
1266                              SILC_STR_UI16_STRING_ALLOC(&username),
1267                              SILC_STR_UI16_STRING_ALLOC(&realname),
1268                              SILC_STR_END);
1269   if (ret == -1) {
1270     if (username)
1271       silc_free(username);
1272     if (realname)
1273       silc_free(realname);
1274     return NULL;
1275   }
1276
1277   if (!username) {
1278     silc_free(username);
1279     if (realname)
1280       silc_free(realname);
1281     silc_server_disconnect_remote(server, sock, "Server closed connection: "
1282                                   "Incomplete client information");
1283     return NULL;
1284   }
1285
1286   /* Create Client ID */
1287   silc_id_create_client_id(server->id, server->rng, server->md5hash,
1288                            username, &client_id);
1289
1290   if (strlen(username) > 128)
1291     username[127] = '\0';
1292
1293   /* Update client entry */
1294   idata->registered = TRUE;
1295   client->nickname = strdup(username);
1296   client->username = username;
1297   client->userinfo = realname ? realname : strdup(" ");
1298   client->id = client_id;
1299
1300   /* Update the cache entry */
1301   cache->id = (void *)client_id;
1302   cache->type = SILC_ID_CLIENT;
1303   cache->data = username;
1304   silc_idcache_sort_by_data(server->local_list->clients);
1305
1306   /* Notify our router about new client on the SILC network */
1307   if (!server->standalone)
1308     silc_server_send_new_id(server, (SilcSocketConnection) 
1309                             server->router->connection, 
1310                             server->server_type == SILC_ROUTER ? TRUE : FALSE,
1311                             client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
1312   
1313   /* Send the new client ID to the client. */
1314   id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
1315   reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
1316   silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
1317   silc_buffer_format(reply,
1318                      SILC_STR_UI_SHORT(SILC_ID_CLIENT),
1319                      SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
1320                      SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
1321                      SILC_STR_END);
1322   silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0, 
1323                           reply->data, reply->len, FALSE);
1324   silc_free(id_string);
1325   silc_buffer_free(reply);
1326
1327   /* Send some nice info to the client */
1328   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1329                           ("Welcome to the SILC Network %s@%s",
1330                            username, sock->hostname));
1331   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1332                           ("Your host is %s, running version %s",
1333                            server->config->server_info->server_name,
1334                            server_version));
1335   if (server->server_type == SILC_ROUTER) {
1336     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1337                             ("There are %d clients on %d servers in SILC "
1338                              "Network", server->stat.clients,
1339                              server->stat.servers + 1));
1340     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1341                             ("There are %d clients on %d server in our cell",
1342                              server->stat.cell_clients,
1343                              server->stat.cell_servers + 1));
1344     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1345                             ("I have %d clients, %d channels, %d servers and "
1346                              "%d routers",
1347                              server->stat.my_clients, 
1348                              server->stat.my_channels,
1349                              server->stat.my_servers,
1350                              server->stat.my_routers));
1351     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1352                             ("%d server operators and %d router operators "
1353                              "online",
1354                              server->stat.my_server_ops,
1355                              server->stat.my_router_ops));
1356   } else {
1357     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1358                             ("I have %d clients and %d channels formed",
1359                              server->stat.my_clients,
1360                              server->stat.my_channels));
1361     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1362                             ("%d operators online",
1363                              server->stat.my_server_ops));
1364   }
1365   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1366                           ("Your connection is secured with %s cipher, "
1367                            "key length %d bits",
1368                            idata->send_key->cipher->name,
1369                            idata->send_key->cipher->key_len));
1370   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1371                           ("Your current nickname is %s",
1372                            client->nickname));
1373
1374   /* Send motd */
1375   silc_server_send_motd(server, sock);
1376
1377   return client;
1378 }
1379
1380 /* Create new server. This processes received New Server packet and
1381    saves the received Server ID. The server is our locally connected
1382    server thus we save all the information and save it to local list. 
1383    This funtion can be used by both normal server and router server.
1384    If normal server uses this it means that its router has connected
1385    to the server. If router uses this it means that one of the cell's
1386    servers is connected to the router. */
1387
1388 SilcServerEntry silc_server_new_server(SilcServer server,
1389                                        SilcSocketConnection sock,
1390                                        SilcPacketContext *packet)
1391 {
1392   SilcBuffer buffer = packet->buffer;
1393   SilcServerEntry new_server;
1394   SilcIDCacheEntry cache;
1395   SilcServerID *server_id;
1396   SilcIDListData idata;
1397   unsigned char *server_name, *id_string;
1398   unsigned short id_len, name_len;
1399   int ret;
1400
1401   SILC_LOG_DEBUG(("Creating new server"));
1402
1403   if (sock->type != SILC_SOCKET_TYPE_SERVER &&
1404       sock->type != SILC_SOCKET_TYPE_ROUTER)
1405     return NULL;
1406
1407   /* Take server entry */
1408   new_server = (SilcServerEntry)sock->user_data;
1409   idata = (SilcIDListData)new_server;
1410
1411   /* Fetch the old server cache entry so that we can update it. */
1412   if (!silc_idcache_find_by_context(server->local_list->servers,
1413                                     sock->user_data, &cache)) {
1414     SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
1415     return NULL;
1416   }
1417
1418   /* Parse the incoming packet */
1419   ret = silc_buffer_unformat(buffer,
1420                              SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
1421                              SILC_STR_UI16_NSTRING_ALLOC(&server_name, 
1422                                                          &name_len),
1423                              SILC_STR_END);
1424   if (ret == -1) {
1425     if (id_string)
1426       silc_free(id_string);
1427     if (server_name)
1428       silc_free(server_name);
1429     return NULL;
1430   }
1431
1432   if (id_len > buffer->len) {
1433     silc_free(id_string);
1434     silc_free(server_name);
1435     return NULL;
1436   }
1437
1438   if (name_len > 256)
1439     server_name[255] = '\0';
1440
1441   /* Get Server ID */
1442   server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
1443   if (!server_id) {
1444     silc_free(id_string);
1445     silc_free(server_name);
1446     return NULL;
1447   }
1448   silc_free(id_string);
1449
1450   /* Update client entry */
1451   idata->registered = TRUE;
1452   new_server->server_name = server_name;
1453   new_server->id = server_id;
1454
1455   /* Update the cache entry */
1456   cache->id = (void *)server_id;
1457   cache->type = SILC_ID_SERVER;
1458   cache->data = server_name;
1459   cache->data_len = strlen(server_name);
1460   silc_idcache_sort_by_data(server->local_list->servers);
1461
1462   /* Distribute the information about new server in the SILC network
1463      to our router. If we are normal server we won't send anything
1464      since this connection must be our router connection. */
1465   if (server->server_type == SILC_ROUTER && !server->standalone &&
1466       server->router->connection != sock)
1467     silc_server_send_new_id(server, server->router->connection,
1468                             TRUE, new_server->id, SILC_ID_SERVER, 
1469                             SILC_ID_SERVER_LEN);
1470
1471   if (server->server_type == SILC_ROUTER)
1472     server->stat.cell_servers++;
1473
1474   return new_server;
1475 }
1476
1477 /* Processes incoming New ID packet. New ID Payload is used to distribute
1478    information about newly registered clients and servers. */
1479
1480 static void silc_server_new_id_real(SilcServer server, 
1481                                     SilcSocketConnection sock,
1482                                     SilcPacketContext *packet,
1483                                     int broadcast)
1484 {
1485   SilcBuffer buffer = packet->buffer;
1486   SilcIDList id_list;
1487   SilcServerEntry router;
1488   SilcSocketConnection router_sock;
1489   SilcIDPayload idp;
1490   SilcIdType id_type;
1491   unsigned char *hash = NULL;
1492   void *id;
1493
1494   SILC_LOG_DEBUG(("Processing new ID"));
1495
1496   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1497       server->server_type == SILC_SERVER ||
1498       packet->src_id_type != SILC_ID_SERVER)
1499     return;
1500
1501   idp = silc_id_payload_parse(buffer);
1502   if (!idp)
1503     return;
1504
1505   id_type = silc_id_payload_get_type(idp);
1506
1507   /* Normal server cannot have other normal server connections */
1508   if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
1509     goto out;
1510
1511   id = silc_id_payload_get_id(idp);
1512   if (!id)
1513     goto out;
1514
1515   /* If the sender of this packet is server and we are router we need to
1516      broadcast this packet to other routers in the network. */
1517   if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
1518       sock->type == SILC_SOCKET_TYPE_SERVER &&
1519       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1520     SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
1521     silc_server_packet_send(server, server->router->connection,
1522                             packet->type, 
1523                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1524                             buffer->data, buffer->len, FALSE);
1525   }
1526
1527   if (sock->type == SILC_SOCKET_TYPE_SERVER)
1528     id_list = server->local_list;
1529   else
1530     id_list = server->global_list;
1531
1532   router_sock = sock;
1533   router = sock->user_data;
1534
1535   switch(id_type) {
1536   case SILC_ID_CLIENT:
1537     {
1538       SilcClientEntry entry;
1539
1540       SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
1541                       silc_id_render(id, SILC_ID_CLIENT),
1542                       sock->type == SILC_SOCKET_TYPE_SERVER ?
1543                       "Server" : "Router", sock->hostname));
1544     
1545       /* As a router we keep information of all global information in our
1546          global list. Cell wide information however is kept in the local
1547          list. The client is put to global list and we will take the hash
1548          value of the Client ID and save it to the ID Cache system for fast
1549          searching in the future. */
1550       hash = silc_calloc(sizeof(((SilcClientID *)id)->hash),
1551                          sizeof(unsigned char));
1552       memcpy(hash, ((SilcClientID *)id)->hash, 
1553              sizeof(((SilcClientID *)id)->hash));
1554       entry = silc_idlist_add_client(id_list, hash, 
1555                                      sizeof(((SilcClientID *)id)->hash),
1556                                      NULL, NULL, id, router, NULL);
1557       entry->nickname = NULL;
1558       entry->data.registered = TRUE;
1559
1560       if (sock->type == SILC_SOCKET_TYPE_SERVER)
1561         server->stat.cell_clients++;
1562       server->stat.clients++;
1563     }
1564     break;
1565
1566   case SILC_ID_SERVER:
1567     SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
1568                     silc_id_render(id, SILC_ID_SERVER),
1569                     sock->type == SILC_SOCKET_TYPE_SERVER ?
1570                     "Server" : "Router", sock->hostname));
1571     
1572     /* As a router we keep information of all global information in our global
1573        list. Cell wide information however is kept in the local list. */
1574     silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
1575
1576     if (sock->type == SILC_SOCKET_TYPE_SERVER)
1577       server->stat.cell_servers++;
1578     server->stat.servers++;
1579     break;
1580
1581   case SILC_ID_CHANNEL:
1582     SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
1583     break;
1584
1585   default:
1586     break;
1587   }
1588
1589  out:
1590   silc_id_payload_free(idp);
1591 }
1592
1593
1594 /* Processes incoming New ID packet. New ID Payload is used to distribute
1595    information about newly registered clients and servers. */
1596
1597 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
1598                         SilcPacketContext *packet)
1599 {
1600   silc_server_new_id_real(server, sock, packet, TRUE);
1601 }
1602
1603 /* Receoved New Id List packet, list of New ID payloads inside one
1604    packet. Process the New ID payloads one by one. */
1605
1606 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
1607                              SilcPacketContext *packet)
1608 {
1609   SilcPacketContext *new_id;
1610   SilcBuffer idp;
1611   unsigned short id_len;
1612
1613   SILC_LOG_DEBUG(("Processing New ID List"));
1614
1615   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1616       packet->src_id_type != SILC_ID_SERVER)
1617     return;
1618
1619   /* If the sender of this packet is server and we are router we need to
1620      broadcast this packet to other routers in the network. Broadcast
1621      this list packet instead of multiple New ID packets. */
1622   if (!server->standalone && server->server_type == SILC_ROUTER &&
1623       sock->type == SILC_SOCKET_TYPE_SERVER &&
1624       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1625     SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
1626     silc_server_packet_send(server, server->router->connection,
1627                             packet->type, 
1628                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1629                             packet->buffer->data, packet->buffer->len, FALSE);
1630   }
1631
1632   /* Make copy of the original packet context, except for the actual
1633      data buffer, which we will here now fetch from the original buffer. */
1634   new_id = silc_packet_context_alloc();
1635   new_id->type = SILC_PACKET_NEW_ID;
1636   new_id->flags = packet->flags;
1637   new_id->src_id = packet->src_id;
1638   new_id->src_id_len = packet->src_id_len;
1639   new_id->src_id_type = packet->src_id_type;
1640   new_id->dst_id = packet->dst_id;
1641   new_id->dst_id_len = packet->dst_id_len;
1642   new_id->dst_id_type = packet->dst_id_type;
1643
1644   idp = silc_buffer_alloc(256);
1645   new_id->buffer = idp;
1646
1647   while (packet->buffer->len) {
1648     SILC_GET16_MSB(id_len, packet->buffer->data + 2);
1649     if ((id_len > packet->buffer->len) ||
1650         (id_len > idp->truelen))
1651       break;
1652
1653     silc_buffer_pull_tail(idp, 4 + id_len);
1654     silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
1655
1656     /* Process the New ID */
1657     silc_server_new_id_real(server, sock, new_id, FALSE);
1658
1659     silc_buffer_push_tail(idp, 4 + id_len);
1660     silc_buffer_pull(packet->buffer, 4 + id_len);
1661   }
1662
1663   silc_buffer_free(idp);
1664   silc_free(new_id);
1665 }
1666
1667 /* Received New Channel packet. Information about new channels in the 
1668    network are distributed using this packet. Save the information about
1669    the new channel. This usually comes from router but also normal server
1670    can send this to notify channels it has when it connects to us. */
1671
1672 void silc_server_new_channel(SilcServer server,
1673                              SilcSocketConnection sock,
1674                              SilcPacketContext *packet)
1675 {
1676   SilcChannelPayload payload;
1677   SilcChannelID *channel_id;
1678   char *channel_name;
1679   unsigned int name_len;
1680   unsigned char *id;
1681   unsigned int id_len;
1682   unsigned int mode;
1683
1684   SILC_LOG_DEBUG(("Processing New Channel"));
1685
1686   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1687       packet->src_id_type != SILC_ID_SERVER ||
1688       server->server_type == SILC_SERVER)
1689     return;
1690
1691   /* Parse the channel payload */
1692   payload = silc_channel_payload_parse(packet->buffer);
1693   if (!payload)
1694     return;
1695     
1696   /* Get the channel ID */
1697   channel_id = silc_channel_get_id_parse(payload);
1698   if (!channel_id) {
1699     silc_channel_payload_free(payload);
1700     return;
1701   }
1702
1703   channel_name = silc_channel_get_name(payload, &name_len);
1704   if (name_len > 256)
1705     channel_name[255] = '\0';
1706
1707   id = silc_channel_get_id(payload, &id_len);
1708
1709   if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
1710     /* Add the server to global list as it is coming from router. It 
1711        cannot be our own channel as it is coming from router. */
1712
1713     SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
1714                     silc_id_render(channel_id, SILC_ID_CHANNEL), 
1715                     sock->hostname));
1716     
1717     silc_idlist_add_channel(server->global_list, strdup(channel_name), 
1718                             0, channel_id, server->router->connection, 
1719                             NULL, NULL);
1720
1721     server->stat.channels++;
1722   } else {
1723     /* The channel is coming from our server, thus it is in our cell
1724        we will add it to our local list. */
1725     SilcChannelEntry channel;
1726     SilcBuffer chk;
1727
1728     SILC_LOG_DEBUG(("New channel id(%s) from [Server] %s",
1729                     silc_id_render(channel_id, SILC_ID_CHANNEL), 
1730                     sock->hostname));
1731     
1732     /* Check that we don't already have this channel */
1733     channel = silc_idlist_find_channel_by_name(server->local_list, 
1734                                                channel_name, NULL);
1735     if (!channel)
1736       channel = silc_idlist_find_channel_by_name(server->global_list, 
1737                                                  channel_name, NULL);
1738
1739     /* If the channel does not exist, then create it. We create the channel
1740        with the channel ID provided by the server. This creates a new
1741        key to the channel as well that we will send to the server. */
1742     if (!channel) {
1743       channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
1744                                                        channel_name,
1745                                                        channel_id, FALSE);
1746       if (!channel) {
1747         silc_channel_payload_free(payload);
1748         silc_free(channel_id);
1749         return;
1750       }
1751
1752       /* Send the new channel key to the server */
1753       chk = silc_channel_key_payload_encode(id_len, id,
1754                                             strlen(channel->channel_key->
1755                                                    cipher->name),
1756                                             channel->channel_key->cipher->name,
1757                                             channel->key_len / 8, 
1758                                             channel->key);
1759       silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
1760                               chk->data, chk->len, FALSE);
1761       silc_buffer_free(chk);
1762
1763     } else {
1764       /* The channel exist by that name, check whether the ID's match.
1765          If they don't then we'll force the server to use the ID we have.
1766          We also create a new key for the channel. */
1767       SilcBuffer users = NULL;
1768
1769       if (SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
1770         /* They don't match, send CHANNEL_CHANGE notify to the server to
1771            force the ID change. */
1772         SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
1773         silc_server_send_notify_channel_change(server, sock, FALSE, 
1774                                                channel_id,
1775                                                channel->id, 
1776                                                SILC_ID_CHANNEL_LEN);
1777       }
1778
1779       /* If the mode is different from what we have then enforce the
1780          mode change. */
1781       mode = silc_channel_get_mode(payload);
1782       if (channel->mode != mode) {
1783         SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
1784         silc_server_send_notify_cmode(server, sock, FALSE, channel,
1785                                       channel->mode, server->id,
1786                                       SILC_ID_SERVER, SILC_ID_SERVER_LEN,
1787                                       channel->cipher, channel->hmac_name);
1788       }
1789
1790       /* Create new key for the channel and send it to the server and
1791          everybody else possibly on the channel. */
1792
1793       if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
1794         silc_server_create_channel_key(server, channel, 0);
1795         
1796         /* Send to the channel */
1797         silc_server_send_channel_key(server, sock, channel, FALSE);
1798         id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
1799         id_len = SILC_ID_CHANNEL_LEN;
1800         
1801         /* Send to the server */
1802         chk = silc_channel_key_payload_encode(id_len, id,
1803                                               strlen(channel->channel_key->
1804                                                      cipher->name),
1805                                               channel->channel_key->
1806                                               cipher->name,
1807                                               channel->key_len / 8, 
1808                                               channel->key);
1809         silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
1810                                 chk->data, chk->len, FALSE);
1811         silc_buffer_free(chk);
1812         silc_free(id);
1813       }
1814
1815       silc_free(channel_id);
1816
1817       /* Since the channel is coming from server and we also know about it
1818          then send the JOIN notify to the server so that it see's our
1819          users on the channel "joining" the channel. */
1820       silc_server_announce_get_channel_users(server, channel, &users);
1821       if (users) {
1822         silc_buffer_push(users, users->data - users->head);
1823         silc_server_packet_send(server, sock,
1824                                 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1825                                 users->data, users->len, FALSE);
1826         silc_buffer_free(users);
1827       }
1828     }
1829   }
1830
1831   silc_channel_payload_free(payload);
1832 }
1833
1834 /* Received New Channel List packet, list of New Channel List payloads inside
1835    one packet. Process the New Channel payloads one by one. */
1836
1837 void silc_server_new_channel_list(SilcServer server,
1838                                   SilcSocketConnection sock,
1839                                   SilcPacketContext *packet)
1840 {
1841   SilcPacketContext *new;
1842   SilcBuffer buffer;
1843   unsigned short len1, len2;
1844
1845   SILC_LOG_DEBUG(("Processing New Channel List"));
1846
1847   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1848       packet->src_id_type != SILC_ID_SERVER ||
1849       server->server_type == SILC_SERVER)
1850     return;
1851
1852   /* If the sender of this packet is server and we are router we need to
1853      broadcast this packet to other routers in the network. Broadcast
1854      this list packet instead of multiple New Channel packets. */
1855   if (!server->standalone && server->server_type == SILC_ROUTER &&
1856       sock->type == SILC_SOCKET_TYPE_SERVER &&
1857       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1858     SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
1859     silc_server_packet_send(server, server->router->connection,
1860                             packet->type, 
1861                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1862                             packet->buffer->data, packet->buffer->len, FALSE);
1863   }
1864
1865   /* Make copy of the original packet context, except for the actual
1866      data buffer, which we will here now fetch from the original buffer. */
1867   new = silc_packet_context_alloc();
1868   new->type = SILC_PACKET_NEW_CHANNEL;
1869   new->flags = packet->flags;
1870   new->src_id = packet->src_id;
1871   new->src_id_len = packet->src_id_len;
1872   new->src_id_type = packet->src_id_type;
1873   new->dst_id = packet->dst_id;
1874   new->dst_id_len = packet->dst_id_len;
1875   new->dst_id_type = packet->dst_id_type;
1876
1877   buffer = silc_buffer_alloc(512);
1878   new->buffer = buffer;
1879
1880   while (packet->buffer->len) {
1881     SILC_GET16_MSB(len1, packet->buffer->data);
1882     if ((len1 > packet->buffer->len) ||
1883         (len1 > buffer->truelen))
1884       break;
1885
1886     SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
1887     if ((len2 > packet->buffer->len) ||
1888         (len2 > buffer->truelen))
1889       break;
1890
1891     silc_buffer_pull_tail(buffer, 8 + len1 + len2);
1892     silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
1893
1894     /* Process the New Channel */
1895     silc_server_new_channel(server, sock, new);
1896
1897     silc_buffer_push_tail(buffer, 8 + len1 + len2);
1898     silc_buffer_pull(packet->buffer, 8 + len1 + len2);
1899   }
1900
1901   silc_buffer_free(buffer);
1902   silc_free(new);
1903 }
1904
1905 /* Received key agreement packet. This packet is never for us. It is to
1906    the client in the packet's destination ID. Sending of this sort of packet
1907    equals sending private message, ie. it is sent point to point from
1908    one client to another. */
1909
1910 void silc_server_key_agreement(SilcServer server,
1911                                SilcSocketConnection sock,
1912                                SilcPacketContext *packet)
1913 {
1914   SilcSocketConnection dst_sock;
1915   SilcIDListData idata;
1916
1917   SILC_LOG_DEBUG(("Start"));
1918
1919   if (packet->src_id_type != SILC_ID_CLIENT ||
1920       packet->dst_id_type != SILC_ID_CLIENT)
1921     return;
1922
1923   if (!packet->dst_id)
1924     return;
1925
1926   /* Get the route to the client */
1927   dst_sock = silc_server_get_client_route(server, packet->dst_id,
1928                                           packet->dst_id_len, NULL, &idata);
1929   if (!dst_sock)
1930     return;
1931
1932   /* Relay the packet */
1933   silc_server_relay_packet(server, dst_sock, idata->send_key,
1934                            idata->hmac, packet, FALSE);
1935 }
1936
1937 /* Received connection auth request packet that is used during connection
1938    phase to resolve the mandatory authentication method.  This packet can
1939    actually be received at anytime but usually it is used only during
1940    the connection authentication phase. Now, protocol says that this packet
1941    can come from client or server, however, we support only this coming
1942    from client and expect that server's always knows what authentication
1943    method to use. */
1944
1945 void silc_server_connection_auth_request(SilcServer server,
1946                                          SilcSocketConnection sock,
1947                                          SilcPacketContext *packet)
1948 {
1949   SilcServerConfigSectionClientConnection *client = NULL;
1950   unsigned short conn_type;
1951   int ret;
1952   SilcAuthMethod auth_meth;
1953
1954   SILC_LOG_DEBUG(("Start"));
1955
1956   if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT)
1957     return;
1958
1959   /* Parse the payload */
1960   ret = silc_buffer_unformat(packet->buffer,
1961                              SILC_STR_UI_SHORT(&conn_type),
1962                              SILC_STR_UI_SHORT(NULL),
1963                              SILC_STR_END);
1964   if (ret == -1)
1965     return;
1966
1967   if (conn_type != SILC_SOCKET_TYPE_CLIENT)
1968     return;
1969
1970   /* Get the authentication method for the client */
1971   auth_meth = SILC_AUTH_NONE;
1972   client = silc_server_config_find_client_conn(server->config,
1973                                                sock->ip,
1974                                                sock->port);
1975   if (!client)
1976     client = silc_server_config_find_client_conn(server->config,
1977                                                  sock->hostname,
1978                                                  sock->port);
1979   if (client)
1980     auth_meth = client->auth_meth;
1981           
1982   /* Send it back to the client */
1983   silc_server_send_connection_auth_request(server, sock,
1984                                            conn_type,
1985                                            auth_meth);
1986 }