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   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, packet, TRUE);
75   }
76
77   /* If we are router and this packet is not already broadcast packet
78      we will broadcast it. The sending socket really cannot be router or
79      the router is buggy. If this packet is coming from router then it must
80      have the broadcast flag set already and we won't do anything. */
81   if (!server->standalone && server->server_type == SILC_ROUTER &&
82       sock->type == SILC_SOCKET_TYPE_SERVER &&
83       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
84     SILC_LOG_DEBUG(("Broadcasting received Notify packet"));
85     silc_server_packet_send(server, server->router->connection, packet->type,
86                             packet->flags | SILC_PACKET_FLAG_BROADCAST, 
87                             packet->buffer->data, packet->buffer->len, FALSE);
88   }
89
90   payload = silc_notify_payload_parse(packet->buffer);
91   if (!payload)
92     return;
93
94   type = silc_notify_get_type(payload);
95   args = silc_notify_get_args(payload);
96   if (!args)
97     goto out;
98
99   switch(type) {
100   case SILC_NOTIFY_TYPE_JOIN:
101     /* 
102      * Distribute the notify to local clients on the channel
103      */
104     SILC_LOG_DEBUG(("JOIN notify"));
105
106     /* Get Channel ID */
107     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
108     if (!tmp)
109       goto out;
110     channel_id = silc_id_payload_parse_id(tmp, tmp_len);
111     if (!channel_id)
112       goto out;
113
114     /* Get channel entry */
115     channel = silc_idlist_find_channel_by_id(server->global_list, 
116                                              channel_id, NULL);
117     if (!channel) {
118       channel = silc_idlist_find_channel_by_id(server->local_list, 
119                                                channel_id, NULL);
120       if (!channel) {
121         silc_free(channel_id);
122         goto out;
123       }
124     }
125     silc_free(channel_id);
126
127     /* Get client ID */
128     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
129     if (!tmp)
130       goto out;
131     client_id = silc_id_payload_parse_id(tmp, tmp_len);
132     if (!client_id)
133       goto out;
134
135     /* Send to channel */
136     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
137                                        FALSE, packet->buffer->data, 
138                                        packet->buffer->len, FALSE);
139
140     /* If the the client is not in local list we check global list (ie. the
141        channel will be global channel) and if it does not exist then create
142        entry for the client. */
143     client = silc_idlist_find_client_by_id(server->global_list, 
144                                            client_id, NULL);
145     if (!client) {
146       client = silc_idlist_find_client_by_id(server->local_list, 
147                                              client_id, NULL);
148       if (!client) {
149         /* If router did not find the client the it is bogus */
150         if (server->server_type == SILC_ROUTER)
151           goto out;
152
153         client = 
154           silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
155                                  silc_id_dup(client_id, SILC_ID_CLIENT), 
156                                  sock->user_data, NULL);
157         if (!client) {
158           silc_free(client_id);
159           goto out;
160         }
161
162         client->data.registered = TRUE;
163       }
164     }
165
166     /* Do not add client to channel if it is there already */
167     if (silc_server_client_on_channel(client, channel))
168       break;
169
170     if (server->server_type == SILC_SERVER && 
171         sock->type == SILC_SOCKET_TYPE_ROUTER)
172       /* The channel is global now */
173       channel->global_users = TRUE;
174
175     /* JOIN the global client to the channel (local clients (if router 
176        created the channel) is joined in the pending JOIN command). */
177     chl = silc_calloc(1, sizeof(*chl));
178     chl->client = client;
179     chl->channel = channel;
180     silc_hash_table_add(channel->user_list, client, chl);
181     silc_hash_table_add(client->channels, channel, chl);
182     silc_free(client_id);
183
184     break;
185
186   case SILC_NOTIFY_TYPE_LEAVE:
187     /* 
188      * Distribute the notify to local clients on the channel
189      */
190     SILC_LOG_DEBUG(("LEAVE notify"));
191
192     channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
193                                 packet->dst_id_type);
194     if (!channel_id)
195       goto out;
196
197     /* Get channel entry */
198     channel = silc_idlist_find_channel_by_id(server->global_list, 
199                                              channel_id, NULL);
200     if (!channel) { 
201       channel = silc_idlist_find_channel_by_id(server->local_list, 
202                                                channel_id, NULL);
203       if (!channel) {
204         silc_free(channel_id);
205         goto out;
206       }
207     }
208
209     /* Get client ID */
210     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
211     if (!tmp) {
212       silc_free(channel_id);
213       goto out;
214     }
215     client_id = silc_id_payload_parse_id(tmp, tmp_len);
216     if (!client_id) {
217       silc_free(channel_id);
218       goto out;
219     }
220
221     /* Send to channel */
222     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
223                                        FALSE, packet->buffer->data, 
224                                        packet->buffer->len, FALSE);
225
226     /* Get client entry */
227     client = silc_idlist_find_client_by_id(server->global_list, 
228                                            client_id, NULL);
229     if (!client) {
230       client = silc_idlist_find_client_by_id(server->local_list, 
231                                              client_id, NULL);
232       if (!client) {
233         silc_free(client_id);
234         silc_free(channel_id);
235         goto out;
236       }
237     }
238     silc_free(client_id);
239
240     /* Remove the user from channel */
241     silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
242     break;
243
244   case SILC_NOTIFY_TYPE_SIGNOFF:
245     /* 
246      * Distribute the notify to local clients on the channel
247      */
248     SILC_LOG_DEBUG(("SIGNOFF notify"));
249
250     /* Get client ID */
251     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
252     if (!tmp)
253       goto out;
254     client_id = silc_id_payload_parse_id(tmp, tmp_len);
255     if (!client_id)
256       goto out;
257
258     /* Get client entry */
259     client = silc_idlist_find_client_by_id(server->global_list, 
260                                            client_id, &cache);
261     if (!client) {
262       client = silc_idlist_find_client_by_id(server->local_list, 
263                                              client_id, &cache);
264       if (!client) {
265         silc_free(client_id);
266         goto out;
267       }
268     }
269     silc_free(client_id);
270
271     /* Get signoff message */
272     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
273     if (tmp_len > 128)
274       tmp = NULL;
275
276     /* Remove the client from all channels. */
277     silc_server_remove_from_channels(server, NULL, client, TRUE, tmp, FALSE);
278
279     client->data.registered = FALSE;
280     cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
281     server->stat.clients--;
282     if (server->server_type == SILC_ROUTER)
283       server->stat.cell_clients--;
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_hash_table_list(channel->user_list, &htl);
520     while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
521       SilcChannelClientEntry chl2 = NULL;
522
523       /* If the mode is channel founder and we already find a client 
524          to have that mode on the channel we will enforce the sender
525          to change the channel founder mode away. There can be only one
526          channel founder on the channel. */
527       if (server->server_type == SILC_ROUTER &&
528           mode & SILC_CHANNEL_UMODE_CHANFO &&
529           chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
530         silc_server_send_notify_cumode(server, sock, FALSE, channel,
531                                        (mode & (~SILC_CHANNEL_UMODE_CHANFO)),
532                                        server->id, SILC_ID_SERVER, 
533                                        client->id);
534         silc_free(channel_id);
535
536         /* Change the mode back if we changed it */
537         if (chl2)
538           chl2->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
539         goto out;
540       }
541
542       if (chl->client == client) {
543         /* Change the mode */
544         chl->mode = mode;
545         if (!(mode & SILC_CHANNEL_UMODE_CHANFO))
546           break;
547
548         chl2 = chl;
549       }
550     }
551
552     /* Send the same notify to the channel */
553     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
554                                        FALSE, packet->buffer->data, 
555                                        packet->buffer->len, FALSE);
556     silc_free(channel_id);
557     break;
558
559   case SILC_NOTIFY_TYPE_INVITE:
560
561     if (packet->dst_id_type == SILC_ID_CLIENT)
562       goto out;
563
564     SILC_LOG_DEBUG(("INVITE notify"));
565
566     /* Get Channel ID */
567     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
568     if (!tmp)
569       goto out;
570     channel_id = silc_id_payload_parse_id(tmp, tmp_len);
571     if (!channel_id)
572       goto out;
573
574     /* Get channel entry */
575     channel = silc_idlist_find_channel_by_id(server->global_list, 
576                                              channel_id, NULL);
577     if (!channel) {
578       channel = silc_idlist_find_channel_by_id(server->local_list, 
579                                                channel_id, NULL);
580       if (!channel) {
581         silc_free(channel_id);
582         goto out;
583       }
584     }
585     silc_free(channel_id);
586
587     /* Get the added invite */
588     tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
589     if (tmp) {
590       if (!channel->invite_list)
591         channel->invite_list = silc_calloc(tmp_len + 2, 
592                                            sizeof(*channel->invite_list));
593       else
594         channel->invite_list = silc_realloc(channel->invite_list, 
595                                             sizeof(*channel->invite_list) * 
596                                             (tmp_len + 
597                                              strlen(channel->invite_list) + 
598                                              2));
599       if (tmp[tmp_len - 1] == ',')
600         tmp[tmp_len - 1] = '\0';
601       
602       strncat(channel->invite_list, tmp, tmp_len);
603       strncat(channel->invite_list, ",", 1);
604     }
605
606     /* Get the deleted invite */
607     tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
608     if (tmp && channel->invite_list) {
609       char *start, *end, *n;
610       
611       if (!strncmp(channel->invite_list, tmp, 
612                    strlen(channel->invite_list) - 1)) {
613         silc_free(channel->invite_list);
614         channel->invite_list = NULL;
615       } else {
616         start = strstr(channel->invite_list, tmp);
617         if (start && strlen(start) >= tmp_len) {
618           end = start + tmp_len;
619           n = silc_calloc(strlen(channel->invite_list) - tmp_len, sizeof(*n));
620           strncat(n, channel->invite_list, start - channel->invite_list);
621           strncat(n, end + 1, ((channel->invite_list + 
622                                 strlen(channel->invite_list)) - end) - 1);
623           silc_free(channel->invite_list);
624           channel->invite_list = n;
625         }
626       }
627     }
628
629     break;
630
631   case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
632     /*
633      * Distribute to the local clients on the channel and change the
634      * channel ID.
635      */
636
637     SILC_LOG_DEBUG(("CHANNEL CHANGE"));
638
639     if (sock->type != SILC_SOCKET_TYPE_ROUTER)
640       break;
641
642     /* Get the old Channel ID */
643     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
644     if (!tmp)
645       goto out;
646     channel_id = silc_id_payload_parse_id(tmp, tmp_len);
647     if (!channel_id)
648       goto out;
649
650     /* Get the channel entry */
651     channel = silc_idlist_find_channel_by_id(server->global_list, 
652                                              channel_id, NULL);
653     if (!channel) {
654       channel = silc_idlist_find_channel_by_id(server->local_list, 
655                                                channel_id, NULL);
656       if (!channel) {
657         silc_free(channel_id);
658         goto out;
659       }
660     }
661
662     /* Send the notify to the channel */
663     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
664                                        FALSE, packet->buffer->data, 
665                                        packet->buffer->len, FALSE);
666
667     /* Get the new Channel ID */
668     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
669     if (!tmp)
670       goto out;
671     channel_id2 = silc_id_payload_parse_id(tmp, tmp_len);
672     if (!channel_id2)
673       goto out;
674
675     SILC_LOG_DEBUG(("Old Channel ID id(%s)", 
676                     silc_id_render(channel_id, SILC_ID_CHANNEL)));
677     SILC_LOG_DEBUG(("New Channel ID id(%s)", 
678                     silc_id_render(channel_id2, SILC_ID_CHANNEL)));
679
680     /* Replace the Channel ID */
681     if (!silc_idlist_replace_channel_id(server->global_list, channel_id,
682                                         channel_id2))
683       if (!silc_idlist_replace_channel_id(server->local_list, channel_id,
684                                           channel_id2)) {
685         silc_free(channel_id2);
686         channel_id2 = NULL;
687       }
688
689     if (channel_id2) {
690       SilcBuffer users = NULL, users_modes = NULL;
691       
692       /* Re-announce our clients on the channel as the ID has changed now */
693       silc_server_announce_get_channel_users(server, channel, &users,
694                                              &users_modes);
695       if (users) {
696         silc_buffer_push(users, users->data - users->head);
697         silc_server_packet_send(server, sock,
698                                 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
699                                 users->data, users->len, FALSE);
700         silc_buffer_free(users);
701       }
702       if (users_modes) {
703         silc_buffer_push(users_modes, users_modes->data - users_modes->head);
704         silc_server_packet_send(server, sock,
705                                 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
706                                 users_modes->data, users_modes->len, FALSE);
707         silc_buffer_free(users_modes);
708       }
709     }
710
711     silc_free(channel_id);
712
713     break;
714
715   case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
716     /* 
717      * Remove the server entry and all clients that this server owns.
718      */
719
720     SILC_LOG_DEBUG(("SERVER SIGNOFF notify"));
721
722     /* Get Server ID */
723     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
724     if (!tmp)
725       goto out;
726     server_id = silc_id_payload_parse_id(tmp, tmp_len);
727     if (!server_id)
728       goto out;
729
730     /* Get server entry */
731     server_entry = silc_idlist_find_server_by_id(server->global_list, 
732                                                  server_id, NULL);
733     if (!server_entry) {
734       server_entry = silc_idlist_find_server_by_id(server->local_list, 
735                                                    server_id, NULL);
736       if (!server_entry) {
737         silc_free(server_id);
738         goto out;
739       }
740     }
741     silc_free(server_id);
742
743     /* Free all client entries that this server owns as they will
744        become invalid now as well. */
745     silc_server_remove_clients_by_server(server, server_entry, TRUE);
746
747     /* Remove the server entry */
748     if (!silc_idlist_del_server(server->global_list, server_entry))
749       silc_idlist_del_server(server->local_list, server_entry);
750
751     /* XXX update statistics */
752
753     break;
754
755   case SILC_NOTIFY_TYPE_KICKED:
756     /* 
757      * Distribute the notify to local clients on the channel
758      */
759     
760     SILC_LOG_DEBUG(("KICKED notify"));
761       
762     channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
763                                 packet->dst_id_type);
764     if (!channel_id)
765       goto out;
766
767     /* Get channel entry */
768     channel = silc_idlist_find_channel_by_id(server->global_list, 
769                                              channel_id, NULL);
770     if (!channel) {
771       channel = silc_idlist_find_channel_by_id(server->local_list, 
772                                                channel_id, NULL);
773       if (!channel) {
774         silc_free(channel_id);
775         goto out;
776       }
777     }
778     silc_free(channel_id);
779
780     /* Get client ID */
781     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
782     if (!tmp)
783       goto out;
784     client_id = silc_id_payload_parse_id(tmp, tmp_len);
785     if (!client_id)
786       goto out;
787
788     /* Send to channel */
789     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
790                                        FALSE, packet->buffer->data, 
791                                        packet->buffer->len, FALSE);
792
793     /* If the the client is not in local list we check global list */
794     client = silc_idlist_find_client_by_id(server->global_list, 
795                                            client_id, NULL);
796     if (!client) {
797       client = silc_idlist_find_client_by_id(server->local_list, 
798                                              client_id, NULL);
799       if (!client) {
800         silc_free(client_id);
801         goto out;
802       }
803     }
804
805     /* Remove the client from channel */
806     silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
807
808     break;
809
810   case SILC_NOTIFY_TYPE_KILLED:
811     {
812       /* 
813        * Distribute the notify to local clients on channels
814        */
815       unsigned char *id;
816       uint32 id_len;
817     
818       SILC_LOG_DEBUG(("KILLED notify"));
819       
820       /* Get client ID */
821       id = silc_argument_get_arg_type(args, 1, &id_len);
822       if (!id)
823         goto out;
824       client_id = silc_id_payload_parse_id(id, id_len);
825       if (!client_id)
826         goto out;
827
828       /* If the the client is not in local list we check global list */
829       client = silc_idlist_find_client_by_id(server->global_list, 
830                                              client_id, NULL);
831       if (!client) {
832         client = silc_idlist_find_client_by_id(server->local_list, 
833                                                client_id, NULL);
834         if (!client) {
835           silc_free(client_id);
836           goto out;
837         }
838       }
839       silc_free(client_id);
840
841       /* If the client is one of ours, then close the connection to the
842          client now. This removes the client from all channels as well. */
843       if (packet->dst_id_type == SILC_ID_CLIENT && client->data.registered &&
844           client->connection) {
845         sock = client->connection;
846         silc_server_free_client_data(server, NULL, client, FALSE, NULL);
847         silc_server_close_connection(server, sock);
848         break;
849       }
850
851       /* Get comment */
852       tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
853       if (tmp_len > 128)
854         tmp = NULL;
855
856       /* Send the notify to local clients on the channels except to the
857          client who is killed. */
858       silc_server_send_notify_on_channels(server, client, client,
859                                           SILC_NOTIFY_TYPE_KILLED, 
860                                           tmp ? 2 : 1,
861                                           id, id_len, 
862                                           tmp, tmp_len);
863
864       /* Remove the client from all channels */
865       silc_server_remove_from_channels(server, NULL, client, FALSE, NULL, 
866                                        FALSE);
867
868       break;
869     }
870
871   case SILC_NOTIFY_TYPE_UMODE_CHANGE:
872     /*
873      * Save the mode of the client.
874      */
875
876     SILC_LOG_DEBUG(("UMODE_CHANGE notify"));
877       
878     /* Get client ID */
879     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
880     if (!tmp)
881       goto out;
882     client_id = silc_id_payload_parse_id(tmp, tmp_len);
883     if (!client_id)
884       goto out;
885
886     /* Get client entry */
887     client = silc_idlist_find_client_by_id(server->global_list, 
888                                            client_id, NULL);
889     if (!client) {
890       client = silc_idlist_find_client_by_id(server->local_list, 
891                                              client_id, NULL);
892       if (!client) {
893         silc_free(client_id);
894         goto out;
895       }
896     }
897     silc_free(client_id);
898
899     /* Get the mode */
900     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
901     if (!tmp)
902       goto out;
903
904     /* Save the mode */
905     SILC_GET32_MSB(client->mode, tmp);
906
907     break;
908
909   case SILC_NOTIFY_TYPE_BAN:
910     /*
911      * Save the ban
912      */
913
914     SILC_LOG_DEBUG(("BAN notify"));
915     
916     /* Get Channel ID */
917     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
918     if (!tmp)
919       goto out;
920     channel_id = silc_id_payload_parse_id(tmp, tmp_len);
921     if (!channel_id)
922       goto out;
923     
924     /* Get channel entry */
925     channel = silc_idlist_find_channel_by_id(server->global_list, 
926                                              channel_id, NULL);
927     if (!channel) {
928       channel = silc_idlist_find_channel_by_id(server->local_list, 
929                                                channel_id, NULL);
930       if (!channel) {
931         silc_free(channel_id);
932         goto out;
933       }
934     }
935     silc_free(channel_id);
936
937     /* Get the new ban and add it to the ban list */
938     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
939     if (tmp) {
940       if (!channel->ban_list)
941         channel->ban_list = silc_calloc(tmp_len + 2, 
942                                         sizeof(*channel->ban_list));
943       else
944         channel->ban_list = silc_realloc(channel->ban_list, 
945                                          sizeof(*channel->ban_list) * 
946                                          (tmp_len + 
947                                           strlen(channel->ban_list) + 2));
948       strncat(channel->ban_list, tmp, tmp_len);
949       strncat(channel->ban_list, ",", 1);
950     }
951
952     /* Get the ban to be removed and remove it from the list */
953     tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
954     if (tmp && channel->ban_list) {
955       char *start, *end, *n;
956       
957       if (!strcmp(channel->ban_list, tmp)) {
958         silc_free(channel->ban_list);
959         channel->ban_list = NULL;
960       } else {
961         start = strstr(channel->ban_list, tmp);
962         if (start && strlen(start) >= tmp_len) {
963           end = start + tmp_len;
964           n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
965           strncat(n, channel->ban_list, start - channel->ban_list);
966           strncat(n, end + 1, ((channel->ban_list + 
967                                 strlen(channel->ban_list)) - end) - 1);
968           silc_free(channel->ban_list);
969           channel->ban_list = n;
970         }
971       }
972     }
973
974     break;
975
976     /* Ignore rest of the notify types for now */
977   case SILC_NOTIFY_TYPE_NONE:
978   case SILC_NOTIFY_TYPE_MOTD:
979     break;
980   default:
981     break;
982   }
983
984  out:
985   silc_notify_payload_free(payload);
986 }
987
988 void silc_server_notify_list(SilcServer server,
989                              SilcSocketConnection sock,
990                              SilcPacketContext *packet)
991 {
992   SilcPacketContext *new;
993   SilcBuffer buffer;
994   uint16 len;
995
996   SILC_LOG_DEBUG(("Processing Notify List"));
997
998   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
999       packet->src_id_type != SILC_ID_SERVER)
1000     return;
1001
1002   /* Make copy of the original packet context, except for the actual
1003      data buffer, which we will here now fetch from the original buffer. */
1004   new = silc_packet_context_alloc();
1005   new->type = SILC_PACKET_NOTIFY;
1006   new->flags = packet->flags;
1007   new->src_id = packet->src_id;
1008   new->src_id_len = packet->src_id_len;
1009   new->src_id_type = packet->src_id_type;
1010   new->dst_id = packet->dst_id;
1011   new->dst_id_len = packet->dst_id_len;
1012   new->dst_id_type = packet->dst_id_type;
1013
1014   buffer = silc_buffer_alloc(1024);
1015   new->buffer = buffer;
1016
1017   while (packet->buffer->len) {
1018     SILC_GET16_MSB(len, packet->buffer->data + 2);
1019     if (len > packet->buffer->len)
1020       break;
1021
1022     if (len > buffer->truelen) {
1023       silc_buffer_free(buffer);
1024       buffer = silc_buffer_alloc(1024 + len);
1025     }
1026
1027     silc_buffer_pull_tail(buffer, len);
1028     silc_buffer_put(buffer, packet->buffer->data, len);
1029
1030     /* Process the Notify */
1031     silc_server_notify(server, sock, new);
1032
1033     silc_buffer_push_tail(buffer, len);
1034     silc_buffer_pull(packet->buffer, len);
1035   }
1036
1037   silc_buffer_free(buffer);
1038   silc_free(new);
1039 }
1040
1041 /* Received private message. This resolves the destination of the message 
1042    and sends the packet. This is used by both server and router.  If the
1043    destination is our locally connected client this sends the packet to
1044    the client. This may also send the message for further routing if
1045    the destination is not in our server (or router). */
1046
1047 void silc_server_private_message(SilcServer server,
1048                                  SilcSocketConnection sock,
1049                                  SilcPacketContext *packet)
1050 {
1051   SilcSocketConnection dst_sock;
1052   SilcIDListData idata;
1053
1054   SILC_LOG_DEBUG(("Start"));
1055
1056   if (packet->src_id_type != SILC_ID_CLIENT ||
1057       packet->dst_id_type != SILC_ID_CLIENT)
1058     return;
1059
1060   if (!packet->dst_id)
1061     return;
1062
1063   /* Get the route to the client */
1064   dst_sock = silc_server_get_client_route(server, packet->dst_id,
1065                                           packet->dst_id_len, NULL, &idata);
1066   if (!dst_sock)
1067     return;
1068
1069   /* Send the private message */
1070   silc_server_send_private_message(server, dst_sock, idata->send_key,
1071                                    idata->hmac_send, packet);
1072 }
1073
1074 /* Received private message key packet.. This packet is never for us. It is to
1075    the client in the packet's destination ID. Sending of this sort of packet
1076    equals sending private message, ie. it is sent point to point from
1077    one client to another. */
1078
1079 void silc_server_private_message_key(SilcServer server,
1080                                      SilcSocketConnection sock,
1081                                      SilcPacketContext *packet)
1082 {
1083   SilcSocketConnection dst_sock;
1084   SilcIDListData idata;
1085
1086   SILC_LOG_DEBUG(("Start"));
1087
1088   if (packet->src_id_type != SILC_ID_CLIENT ||
1089       packet->dst_id_type != SILC_ID_CLIENT)
1090     return;
1091
1092   if (!packet->dst_id)
1093     return;
1094
1095   /* Get the route to the client */
1096   dst_sock = silc_server_get_client_route(server, packet->dst_id,
1097                                           packet->dst_id_len, NULL, &idata);
1098   if (!dst_sock)
1099     return;
1100
1101   /* Relay the packet */
1102   silc_server_relay_packet(server, dst_sock, idata->send_key,
1103                            idata->hmac_send, packet, FALSE);
1104 }
1105
1106 /* Processes incoming command reply packet. The command reply packet may
1107    be destined to one of our clients or it may directly for us. We will 
1108    call the command reply routine after processing the packet. */
1109
1110 void silc_server_command_reply(SilcServer server,
1111                                SilcSocketConnection sock,
1112                                SilcPacketContext *packet)
1113 {
1114   SilcBuffer buffer = packet->buffer;
1115   SilcClientEntry client = NULL;
1116   SilcSocketConnection dst_sock;
1117   SilcIDListData idata;
1118   SilcClientID *id = NULL;
1119
1120   SILC_LOG_DEBUG(("Start"));
1121
1122   /* Source must be server or router */
1123   if (packet->src_id_type != SILC_ID_SERVER &&
1124       sock->type != SILC_SOCKET_TYPE_ROUTER)
1125     return;
1126
1127   if (packet->dst_id_type == SILC_ID_CHANNEL)
1128     return;
1129
1130   if (packet->dst_id_type == SILC_ID_CLIENT) {
1131     /* Destination must be one of ours */
1132     id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
1133     if (!id)
1134       return;
1135     client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
1136     if (!client) {
1137       SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
1138       silc_free(id);
1139       return;
1140     }
1141   }
1142
1143   if (packet->dst_id_type == SILC_ID_SERVER) {
1144     /* For now this must be for us */
1145     if (memcmp(packet->dst_id, server->id_string, packet->dst_id_len)) {
1146       SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
1147       return;
1148     }
1149   }
1150
1151   /* Execute command reply locally for the command */
1152   silc_server_command_reply_process(server, sock, buffer);
1153
1154   if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
1155     /* Relay the packet to the client */
1156     
1157     dst_sock = (SilcSocketConnection)client->connection;
1158     silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len 
1159                      + packet->dst_id_len + packet->padlen);
1160     
1161     silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
1162     silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
1163     
1164     idata = (SilcIDListData)client;
1165     
1166     /* Encrypt packet */
1167     silc_packet_encrypt(idata->send_key, idata->hmac_send, dst_sock->outbuf, 
1168                         buffer->len);
1169     
1170     /* Send the packet */
1171     silc_server_packet_send_real(server, dst_sock, TRUE);
1172
1173     silc_free(id);
1174   }
1175 }
1176
1177 /* Process received channel message. The message can be originated from
1178    client or server. */
1179
1180 void silc_server_channel_message(SilcServer server,
1181                                  SilcSocketConnection sock,
1182                                  SilcPacketContext *packet)
1183 {
1184   SilcChannelEntry channel = NULL;
1185   SilcChannelID *id = NULL;
1186   void *sender = NULL;
1187   void *sender_entry = NULL;
1188
1189   SILC_LOG_DEBUG(("Processing channel message"));
1190
1191   /* Sanity checks */
1192   if (packet->dst_id_type != SILC_ID_CHANNEL) {
1193     SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1194     goto out;
1195   }
1196
1197   /* Find channel entry */
1198   id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
1199   if (!id)
1200     goto out;
1201   channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
1202   if (!channel) {
1203     channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
1204     if (!channel) {
1205       SILC_LOG_DEBUG(("Could not find channel"));
1206       goto out;
1207     }
1208   }
1209
1210   /* See that this client is on the channel. If the original sender is
1211      not client (as it can be server as well) we don't do the check. */
1212   sender = silc_id_str2id(packet->src_id, packet->src_id_len, 
1213                           packet->src_id_type);
1214   if (!sender)
1215     goto out;
1216   if (packet->src_id_type == SILC_ID_CLIENT) {
1217     sender_entry = silc_idlist_find_client_by_id(server->local_list, 
1218                                                  sender, NULL);
1219     if (!sender_entry)
1220       sender_entry = silc_idlist_find_client_by_id(server->global_list, 
1221                                                    sender, NULL);
1222     if (!sender_entry || !silc_server_client_on_channel(sender_entry, 
1223                                                         channel)) {
1224       SILC_LOG_DEBUG(("Client not on channel"));
1225       goto out;
1226     }
1227   }
1228
1229   /* Distribute the packet to our local clients. This will send the
1230      packet for further routing as well, if needed. */
1231   silc_server_packet_relay_to_channel(server, sock, channel, sender,
1232                                       packet->src_id_type, sender_entry,
1233                                       packet->buffer->data,
1234                                       packet->buffer->len, FALSE);
1235
1236  out:
1237   if (sender)
1238     silc_free(sender);
1239   if (id)
1240     silc_free(id);
1241 }
1242
1243 /* Received channel key packet. We distribute the key to all of our locally
1244    connected clients on the channel. */
1245
1246 void silc_server_channel_key(SilcServer server,
1247                              SilcSocketConnection sock,
1248                              SilcPacketContext *packet)
1249 {
1250   SilcBuffer buffer = packet->buffer;
1251   SilcChannelEntry channel;
1252
1253   if (packet->src_id_type != SILC_ID_SERVER ||
1254       (server->server_type == SILC_ROUTER &&
1255        sock->type == SILC_SOCKET_TYPE_ROUTER))
1256     return;
1257
1258   /* Save the channel key */
1259   channel = silc_server_save_channel_key(server, buffer, NULL);
1260   if (!channel)
1261     return;
1262
1263   /* Distribute the key to everybody who is on the channel. If we are router
1264      we will also send it to locally connected servers. */
1265   silc_server_send_channel_key(server, sock, channel, FALSE);
1266 }
1267
1268 /* Received New Client packet and processes it.  Creates Client ID for the
1269    client. Client becomes registered after calling this functions. */
1270
1271 SilcClientEntry silc_server_new_client(SilcServer server,
1272                                        SilcSocketConnection sock,
1273                                        SilcPacketContext *packet)
1274 {
1275   SilcBuffer buffer = packet->buffer;
1276   SilcClientEntry client;
1277   SilcClientID *client_id;
1278   SilcBuffer reply;
1279   SilcIDListData idata;
1280   char *username = NULL, *realname = NULL, *id_string;
1281   uint32 id_len;
1282   int ret;
1283   char *hostname, *nickname;
1284
1285   SILC_LOG_DEBUG(("Creating new client"));
1286
1287   if (sock->type != SILC_SOCKET_TYPE_CLIENT)
1288     return NULL;
1289
1290   /* Take client entry */
1291   client = (SilcClientEntry)sock->user_data;
1292   idata = (SilcIDListData)client;
1293
1294   /* Remove the old cache entry */
1295   if (!silc_idcache_del_by_context(server->local_list->clients, client)) {
1296     SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
1297     silc_server_disconnect_remote(server, sock, "Server closed connection: "
1298                                   "Unknown client");
1299     return NULL;
1300   }
1301
1302   /* Parse incoming packet */
1303   ret = silc_buffer_unformat(buffer,
1304                              SILC_STR_UI16_STRING_ALLOC(&username),
1305                              SILC_STR_UI16_STRING_ALLOC(&realname),
1306                              SILC_STR_END);
1307   if (ret == -1) {
1308     if (username)
1309       silc_free(username);
1310     if (realname)
1311       silc_free(realname);
1312     silc_server_disconnect_remote(server, sock, "Server closed connection: "
1313                                   "Incomplete client information");
1314     return NULL;
1315   }
1316
1317   if (!username) {
1318     silc_free(username);
1319     if (realname)
1320       silc_free(realname);
1321     silc_server_disconnect_remote(server, sock, "Server closed connection: "
1322                                   "Incomplete client information");
1323     return NULL;
1324   }
1325
1326   nickname = strdup(username);
1327
1328   /* Make sanity checks for the hostname of the client. If the hostname
1329      is provided in the `username' check that it is the same than the
1330      resolved hostname, or if not resolved the hostname that appears in
1331      the client's public key. If the hostname is not present then put
1332      it from the resolved name or from the public key. */
1333   if (strchr(username, '@')) {
1334     SilcPublicKeyIdentifier pident;
1335     int tlen = strcspn(username, "@");
1336     char *phostname = NULL;
1337
1338     hostname = silc_calloc((strlen(username) - tlen) + 1, sizeof(char));
1339     memcpy(hostname, username + tlen + 1, strlen(username) - tlen - 1);
1340
1341     if (strcmp(sock->hostname, sock->ip) && 
1342         strcmp(sock->hostname, hostname)) {
1343       silc_free(username);
1344       silc_free(hostname);
1345       if (realname)
1346         silc_free(realname);
1347       silc_server_disconnect_remote(server, sock, 
1348                                     "Server closed connection: "
1349                                     "Incomplete client information");
1350       return NULL;
1351     }
1352     
1353     pident = silc_pkcs_decode_identifier(client->data.public_key->identifier);
1354     if (pident) {
1355       phostname = strdup(pident->host);
1356       silc_pkcs_free_identifier(pident);
1357     }
1358
1359     if (!strcmp(sock->hostname, sock->ip) && 
1360         phostname && strcmp(phostname, hostname)) {
1361       silc_free(username);
1362       silc_free(hostname);
1363       if (phostname)
1364         silc_free(phostname);
1365       if (realname)
1366         silc_free(realname);
1367       silc_server_disconnect_remote(server, sock, 
1368                                     "Server closed connection: "
1369                                     "Incomplete client information");
1370       return NULL;
1371     }
1372     
1373     if (phostname)
1374       silc_free(phostname);
1375   } else {
1376     /* The hostname is not present, add it. */
1377     char *newusername;
1378     
1379     if (strcmp(sock->hostname, sock->ip)) {
1380       newusername = silc_calloc(strlen(username) + 
1381                                 strlen(sock->hostname) + 2,
1382                                 sizeof(*newusername));
1383       strncat(newusername, username, strlen(username));
1384       strncat(newusername, "@", 1);
1385       strncat(newusername, sock->hostname, strlen(sock->hostname));
1386       silc_free(username);
1387       username = newusername;
1388     } else {
1389       SilcPublicKeyIdentifier pident = 
1390         silc_pkcs_decode_identifier(client->data.public_key->identifier);
1391       
1392       if (pident) {
1393         newusername = silc_calloc(strlen(username) + 
1394                                   strlen(pident->host) + 2,
1395                                   sizeof(*newusername));
1396         strncat(newusername, username, strlen(username));
1397         strncat(newusername, "@", 1);
1398         strncat(newusername, pident->host, strlen(pident->host));
1399         silc_free(username);
1400         username = newusername;
1401         silc_pkcs_free_identifier(pident);
1402       }
1403     }
1404   }
1405
1406   /* Create Client ID */
1407   silc_id_create_client_id(server->id, server->rng, server->md5hash,
1408                            username, &client_id);
1409
1410   if (strlen(username) > 128)
1411     username[127] = '\0';
1412
1413   /* Update client entry */
1414   idata->registered = TRUE;
1415   client->nickname = nickname;
1416   client->username = username;
1417   client->userinfo = realname ? realname : strdup(" ");
1418   client->id = client_id;
1419   id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
1420
1421   /* Add the client again to the ID cache */
1422   silc_idcache_add(server->local_list->clients, client->nickname,
1423                    client_id, client, FALSE);
1424
1425   /* Notify our router about new client on the SILC network */
1426   if (!server->standalone)
1427     silc_server_send_new_id(server, (SilcSocketConnection) 
1428                             server->router->connection, 
1429                             server->server_type == SILC_ROUTER ? TRUE : FALSE,
1430                             client->id, SILC_ID_CLIENT, id_len);
1431   
1432   /* Send the new client ID to the client. */
1433   id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
1434   reply = silc_buffer_alloc(2 + 2 + id_len);
1435   silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
1436   silc_buffer_format(reply,
1437                      SILC_STR_UI_SHORT(SILC_ID_CLIENT),
1438                      SILC_STR_UI_SHORT(id_len),
1439                      SILC_STR_UI_XNSTRING(id_string, id_len),
1440                      SILC_STR_END);
1441   silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0, 
1442                           reply->data, reply->len, FALSE);
1443   silc_free(id_string);
1444   silc_buffer_free(reply);
1445
1446   /* Send some nice info to the client */
1447   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1448                           ("Welcome to the SILC Network %s",
1449                            username));
1450   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1451                           ("Your host is %s, running version %s",
1452                            server->config->server_info->server_name,
1453                            server_version));
1454   if (server->server_type == SILC_ROUTER) {
1455     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1456                             ("There are %d clients on %d servers in SILC "
1457                              "Network", server->stat.clients,
1458                              server->stat.servers + 1));
1459     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1460                             ("There are %d clients on %d server in our cell",
1461                              server->stat.cell_clients,
1462                              server->stat.cell_servers + 1));
1463     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1464                             ("I have %d clients, %d channels, %d servers and "
1465                              "%d routers",
1466                              server->stat.my_clients, 
1467                              server->stat.my_channels,
1468                              server->stat.my_servers,
1469                              server->stat.my_routers));
1470     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1471                             ("%d server operators and %d router operators "
1472                              "online",
1473                              server->stat.my_server_ops,
1474                              server->stat.my_router_ops));
1475   } else {
1476     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1477                             ("I have %d clients and %d channels formed",
1478                              server->stat.my_clients,
1479                              server->stat.my_channels));
1480     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1481                             ("%d operators online",
1482                              server->stat.my_server_ops));
1483   }
1484   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1485                           ("Your connection is secured with %s cipher, "
1486                            "key length %d bits",
1487                            idata->send_key->cipher->name,
1488                            idata->send_key->cipher->key_len));
1489   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1490                           ("Your current nickname is %s",
1491                            client->nickname));
1492
1493   /* Send motd */
1494   silc_server_send_motd(server, sock);
1495
1496   return client;
1497 }
1498
1499 /* Create new server. This processes received New Server packet and
1500    saves the received Server ID. The server is our locally connected
1501    server thus we save all the information and save it to local list. 
1502    This funtion can be used by both normal server and router server.
1503    If normal server uses this it means that its router has connected
1504    to the server. If router uses this it means that one of the cell's
1505    servers is connected to the router. */
1506
1507 SilcServerEntry silc_server_new_server(SilcServer server,
1508                                        SilcSocketConnection sock,
1509                                        SilcPacketContext *packet)
1510 {
1511   SilcBuffer buffer = packet->buffer;
1512   SilcServerEntry new_server;
1513   SilcServerID *server_id;
1514   SilcIDListData idata;
1515   unsigned char *server_name, *id_string;
1516   uint16 id_len, name_len;
1517   int ret;
1518
1519   SILC_LOG_DEBUG(("Creating new server"));
1520
1521   if (sock->type != SILC_SOCKET_TYPE_SERVER &&
1522       sock->type != SILC_SOCKET_TYPE_ROUTER)
1523     return NULL;
1524
1525   /* Take server entry */
1526   new_server = (SilcServerEntry)sock->user_data;
1527   idata = (SilcIDListData)new_server;
1528
1529   /* Remove the old cache entry */
1530   silc_idcache_del_by_context(server->local_list->servers, new_server);
1531
1532   /* Parse the incoming packet */
1533   ret = silc_buffer_unformat(buffer,
1534                              SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
1535                              SILC_STR_UI16_NSTRING_ALLOC(&server_name, 
1536                                                          &name_len),
1537                              SILC_STR_END);
1538   if (ret == -1) {
1539     if (id_string)
1540       silc_free(id_string);
1541     if (server_name)
1542       silc_free(server_name);
1543     return NULL;
1544   }
1545
1546   if (id_len > buffer->len) {
1547     silc_free(id_string);
1548     silc_free(server_name);
1549     return NULL;
1550   }
1551
1552   if (name_len > 256)
1553     server_name[255] = '\0';
1554
1555   /* Get Server ID */
1556   server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
1557   if (!server_id) {
1558     silc_free(id_string);
1559     silc_free(server_name);
1560     return NULL;
1561   }
1562   silc_free(id_string);
1563
1564   /* Update server entry */
1565   idata->registered = TRUE;
1566   new_server->server_name = server_name;
1567   new_server->id = server_id;
1568
1569   /* Add again the entry to the ID cache. */
1570   silc_idcache_add(server->local_list->servers, server_name, server_id, 
1571                    server, FALSE);
1572
1573   /* Distribute the information about new server in the SILC network
1574      to our router. If we are normal server we won't send anything
1575      since this connection must be our router connection. */
1576   if (server->server_type == SILC_ROUTER && !server->standalone &&
1577       server->router->connection != sock)
1578     silc_server_send_new_id(server, server->router->connection,
1579                             TRUE, new_server->id, SILC_ID_SERVER, 
1580                             silc_id_get_len(server_id, SILC_ID_SERVER));
1581
1582   if (server->server_type == SILC_ROUTER)
1583     server->stat.cell_servers++;
1584
1585   return new_server;
1586 }
1587
1588 /* Processes incoming New ID packet. New ID Payload is used to distribute
1589    information about newly registered clients and servers. */
1590
1591 static void silc_server_new_id_real(SilcServer server, 
1592                                     SilcSocketConnection sock,
1593                                     SilcPacketContext *packet,
1594                                     int broadcast)
1595 {
1596   SilcBuffer buffer = packet->buffer;
1597   SilcIDList id_list;
1598   SilcServerEntry router;
1599   SilcSocketConnection router_sock;
1600   SilcIDPayload idp;
1601   SilcIdType id_type;
1602   void *id;
1603
1604   SILC_LOG_DEBUG(("Processing new ID"));
1605
1606   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1607       server->server_type == SILC_SERVER ||
1608       packet->src_id_type != SILC_ID_SERVER)
1609     return;
1610
1611   idp = silc_id_payload_parse(buffer);
1612   if (!idp)
1613     return;
1614
1615   id_type = silc_id_payload_get_type(idp);
1616
1617   /* Normal server cannot have other normal server connections */
1618   if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
1619     goto out;
1620
1621   id = silc_id_payload_get_id(idp);
1622   if (!id)
1623     goto out;
1624
1625   /* If the sender of this packet is server and we are router we need to
1626      broadcast this packet to other routers in the network. */
1627   if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
1628       sock->type == SILC_SOCKET_TYPE_SERVER &&
1629       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1630     SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
1631     silc_server_packet_send(server, server->router->connection,
1632                             packet->type, 
1633                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1634                             buffer->data, buffer->len, FALSE);
1635   }
1636
1637   if (sock->type == SILC_SOCKET_TYPE_SERVER)
1638     id_list = server->local_list;
1639   else
1640     id_list = server->global_list;
1641
1642   /* If the packet is coming from server then use the sender as the
1643      origin of the the packet. If it came from router then check the real
1644      sender of the packet and use that as the origin. */
1645   if (sock->type == SILC_SOCKET_TYPE_SERVER) {
1646     router_sock = sock;
1647     router = sock->user_data;
1648   } else {
1649     void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1650                                      packet->src_id_type);
1651     router = silc_idlist_find_server_by_id(server->global_list,
1652                                            sender_id, NULL);
1653     if (!router)
1654       router = silc_idlist_find_server_by_id(server->local_list,
1655                                              sender_id, NULL);
1656     silc_free(sender_id);
1657     if (!router)
1658       goto out;
1659     router_sock = sock;
1660   }
1661
1662   switch(id_type) {
1663   case SILC_ID_CLIENT:
1664     {
1665       SilcClientEntry entry;
1666
1667       SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
1668                       silc_id_render(id, SILC_ID_CLIENT),
1669                       sock->type == SILC_SOCKET_TYPE_SERVER ?
1670                       "Server" : "Router", sock->hostname));
1671     
1672       /* As a router we keep information of all global information in our
1673          global list. Cell wide information however is kept in the local
1674          list. */
1675       entry = silc_idlist_add_client(id_list, NULL, NULL, NULL, 
1676                                      id, router, NULL);
1677       entry->nickname = NULL;
1678       entry->data.registered = TRUE;
1679
1680       if (sock->type == SILC_SOCKET_TYPE_SERVER)
1681         server->stat.cell_clients++;
1682       server->stat.clients++;
1683     }
1684     break;
1685
1686   case SILC_ID_SERVER:
1687     /* If the ID is mine, ignore it. */
1688     if (SILC_ID_SERVER_COMPARE(id, server->id)) {
1689       SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
1690       break;
1691     }
1692
1693     SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
1694                     silc_id_render(id, SILC_ID_SERVER),
1695                     sock->type == SILC_SOCKET_TYPE_SERVER ?
1696                     "Server" : "Router", sock->hostname));
1697
1698     /* As a router we keep information of all global information in our global
1699        list. Cell wide information however is kept in the local list. */
1700     silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
1701
1702     if (sock->type == SILC_SOCKET_TYPE_SERVER)
1703       server->stat.cell_servers++;
1704     server->stat.servers++;
1705     break;
1706
1707   case SILC_ID_CHANNEL:
1708     SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
1709     break;
1710
1711   default:
1712     break;
1713   }
1714
1715  out:
1716   silc_id_payload_free(idp);
1717 }
1718
1719
1720 /* Processes incoming New ID packet. New ID Payload is used to distribute
1721    information about newly registered clients and servers. */
1722
1723 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
1724                         SilcPacketContext *packet)
1725 {
1726   silc_server_new_id_real(server, sock, packet, TRUE);
1727 }
1728
1729 /* Receoved New Id List packet, list of New ID payloads inside one
1730    packet. Process the New ID payloads one by one. */
1731
1732 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
1733                              SilcPacketContext *packet)
1734 {
1735   SilcPacketContext *new_id;
1736   SilcBuffer idp;
1737   uint16 id_len;
1738
1739   SILC_LOG_DEBUG(("Processing New ID List"));
1740
1741   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1742       packet->src_id_type != SILC_ID_SERVER)
1743     return;
1744
1745   /* If the sender of this packet is server and we are router we need to
1746      broadcast this packet to other routers in the network. Broadcast
1747      this list packet instead of multiple New ID packets. */
1748   if (!server->standalone && server->server_type == SILC_ROUTER &&
1749       sock->type == SILC_SOCKET_TYPE_SERVER &&
1750       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1751     SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
1752     silc_server_packet_send(server, server->router->connection,
1753                             packet->type, 
1754                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1755                             packet->buffer->data, packet->buffer->len, FALSE);
1756   }
1757
1758   /* Make copy of the original packet context, except for the actual
1759      data buffer, which we will here now fetch from the original buffer. */
1760   new_id = silc_packet_context_alloc();
1761   new_id->type = SILC_PACKET_NEW_ID;
1762   new_id->flags = packet->flags;
1763   new_id->src_id = packet->src_id;
1764   new_id->src_id_len = packet->src_id_len;
1765   new_id->src_id_type = packet->src_id_type;
1766   new_id->dst_id = packet->dst_id;
1767   new_id->dst_id_len = packet->dst_id_len;
1768   new_id->dst_id_type = packet->dst_id_type;
1769
1770   idp = silc_buffer_alloc(256);
1771   new_id->buffer = idp;
1772
1773   while (packet->buffer->len) {
1774     SILC_GET16_MSB(id_len, packet->buffer->data + 2);
1775     if ((id_len > packet->buffer->len) ||
1776         (id_len > idp->truelen))
1777       break;
1778
1779     silc_buffer_pull_tail(idp, 4 + id_len);
1780     silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
1781
1782     /* Process the New ID */
1783     silc_server_new_id_real(server, sock, new_id, FALSE);
1784
1785     silc_buffer_push_tail(idp, 4 + id_len);
1786     silc_buffer_pull(packet->buffer, 4 + id_len);
1787   }
1788
1789   silc_buffer_free(idp);
1790   silc_free(new_id);
1791 }
1792
1793 /* Received New Channel packet. Information about new channels in the 
1794    network are distributed using this packet. Save the information about
1795    the new channel. This usually comes from router but also normal server
1796    can send this to notify channels it has when it connects to us. */
1797
1798 void silc_server_new_channel(SilcServer server,
1799                              SilcSocketConnection sock,
1800                              SilcPacketContext *packet)
1801 {
1802   SilcChannelPayload payload;
1803   SilcChannelID *channel_id;
1804   char *channel_name;
1805   uint32 name_len;
1806   unsigned char *id;
1807   uint32 id_len;
1808   uint32 mode;
1809
1810   SILC_LOG_DEBUG(("Processing New Channel"));
1811
1812   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1813       packet->src_id_type != SILC_ID_SERVER ||
1814       server->server_type == SILC_SERVER)
1815     return;
1816
1817   /* Parse the channel payload */
1818   payload = silc_channel_payload_parse(packet->buffer);
1819   if (!payload)
1820     return;
1821     
1822   /* Get the channel ID */
1823   channel_id = silc_channel_get_id_parse(payload);
1824   if (!channel_id) {
1825     silc_channel_payload_free(payload);
1826     return;
1827   }
1828
1829   channel_name = silc_channel_get_name(payload, &name_len);
1830   if (name_len > 256)
1831     channel_name[255] = '\0';
1832
1833   id = silc_channel_get_id(payload, &id_len);
1834
1835   if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
1836     /* Add the server to global list as it is coming from router. It 
1837        cannot be our own channel as it is coming from router. */
1838
1839     SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
1840                     silc_id_render(channel_id, SILC_ID_CHANNEL), 
1841                     sock->hostname));
1842     
1843     silc_idlist_add_channel(server->global_list, strdup(channel_name), 
1844                             0, channel_id, server->router->connection, 
1845                             NULL, NULL);
1846
1847     server->stat.channels++;
1848   } else {
1849     /* The channel is coming from our server, thus it is in our cell
1850        we will add it to our local list. */
1851     SilcChannelEntry channel;
1852     SilcBuffer chk;
1853
1854     SILC_LOG_DEBUG(("New channel id(%s) from [Server] %s",
1855                     silc_id_render(channel_id, SILC_ID_CHANNEL), 
1856                     sock->hostname));
1857     
1858     /* Check that we don't already have this channel */
1859     channel = silc_idlist_find_channel_by_name(server->local_list, 
1860                                                channel_name, NULL);
1861     if (!channel)
1862       channel = silc_idlist_find_channel_by_name(server->global_list, 
1863                                                  channel_name, NULL);
1864
1865     /* If the channel does not exist, then create it. We create the channel
1866        with the channel ID provided by the server. This creates a new
1867        key to the channel as well that we will send to the server. */
1868     if (!channel) {
1869       channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
1870                                                        channel_name,
1871                                                        channel_id, FALSE);
1872       if (!channel) {
1873         silc_channel_payload_free(payload);
1874         silc_free(channel_id);
1875         return;
1876       }
1877
1878       /* Send the new channel key to the server */
1879       chk = silc_channel_key_payload_encode(id_len, id,
1880                                             strlen(channel->channel_key->
1881                                                    cipher->name),
1882                                             channel->channel_key->cipher->name,
1883                                             channel->key_len / 8, 
1884                                             channel->key);
1885       silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
1886                               chk->data, chk->len, FALSE);
1887       silc_buffer_free(chk);
1888
1889     } else {
1890       /* The channel exist by that name, check whether the ID's match.
1891          If they don't then we'll force the server to use the ID we have.
1892          We also create a new key for the channel. */
1893       SilcBuffer users = NULL, users_modes = NULL;
1894
1895       if (!channel->id)
1896         channel_id = silc_id_dup(channel_id, SILC_ID_CHANNEL);
1897
1898       if (!SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
1899         /* They don't match, send CHANNEL_CHANGE notify to the server to
1900            force the ID change. */
1901         SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
1902         silc_server_send_notify_channel_change(server, sock, FALSE, 
1903                                                channel_id, channel->id);
1904       }
1905
1906       /* If the mode is different from what we have then enforce the
1907          mode change. */
1908       mode = silc_channel_get_mode(payload);
1909       if (channel->mode != mode) {
1910         SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
1911         silc_server_send_notify_cmode(server, sock, FALSE, channel,
1912                                       channel->mode, server->id,
1913                                       SILC_ID_SERVER,
1914                                       channel->cipher, channel->hmac_name);
1915       }
1916
1917       /* Create new key for the channel and send it to the server and
1918          everybody else possibly on the channel. */
1919
1920       if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
1921         silc_server_create_channel_key(server, channel, 0);
1922         
1923         /* Send to the channel */
1924         silc_server_send_channel_key(server, sock, channel, FALSE);
1925         id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
1926         id_len = SILC_ID_CHANNEL_LEN;
1927         
1928         /* Send to the server */
1929         chk = silc_channel_key_payload_encode(id_len, id,
1930                                               strlen(channel->channel_key->
1931                                                      cipher->name),
1932                                               channel->channel_key->
1933                                               cipher->name,
1934                                               channel->key_len / 8, 
1935                                               channel->key);
1936         silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
1937                                 chk->data, chk->len, FALSE);
1938         silc_buffer_free(chk);
1939         silc_free(id);
1940       }
1941
1942       silc_free(channel_id);
1943
1944       /* Since the channel is coming from server and we also know about it
1945          then send the JOIN notify to the server so that it see's our
1946          users on the channel "joining" the channel. */
1947       silc_server_announce_get_channel_users(server, channel, &users,
1948                                              &users_modes);
1949       if (users) {
1950         silc_buffer_push(users, users->data - users->head);
1951         silc_server_packet_send(server, sock,
1952                                 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1953                                 users->data, users->len, FALSE);
1954         silc_buffer_free(users);
1955       }
1956       if (users_modes) {
1957         silc_buffer_push(users_modes, users_modes->data - users_modes->head);
1958         silc_server_packet_send(server, sock,
1959                                 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1960                                 users_modes->data, users_modes->len, FALSE);
1961         silc_buffer_free(users_modes);
1962       }
1963     }
1964   }
1965
1966   silc_channel_payload_free(payload);
1967 }
1968
1969 /* Received New Channel List packet, list of New Channel List payloads inside
1970    one packet. Process the New Channel payloads one by one. */
1971
1972 void silc_server_new_channel_list(SilcServer server,
1973                                   SilcSocketConnection sock,
1974                                   SilcPacketContext *packet)
1975 {
1976   SilcPacketContext *new;
1977   SilcBuffer buffer;
1978   uint16 len1, len2;
1979
1980   SILC_LOG_DEBUG(("Processing New Channel List"));
1981
1982   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1983       packet->src_id_type != SILC_ID_SERVER ||
1984       server->server_type == SILC_SERVER)
1985     return;
1986
1987   /* If the sender of this packet is server and we are router we need to
1988      broadcast this packet to other routers in the network. Broadcast
1989      this list packet instead of multiple New Channel packets. */
1990   if (!server->standalone && server->server_type == SILC_ROUTER &&
1991       sock->type == SILC_SOCKET_TYPE_SERVER &&
1992       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1993     SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
1994     silc_server_packet_send(server, server->router->connection,
1995                             packet->type, 
1996                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1997                             packet->buffer->data, packet->buffer->len, FALSE);
1998   }
1999
2000   /* Make copy of the original packet context, except for the actual
2001      data buffer, which we will here now fetch from the original buffer. */
2002   new = silc_packet_context_alloc();
2003   new->type = SILC_PACKET_NEW_CHANNEL;
2004   new->flags = packet->flags;
2005   new->src_id = packet->src_id;
2006   new->src_id_len = packet->src_id_len;
2007   new->src_id_type = packet->src_id_type;
2008   new->dst_id = packet->dst_id;
2009   new->dst_id_len = packet->dst_id_len;
2010   new->dst_id_type = packet->dst_id_type;
2011
2012   buffer = silc_buffer_alloc(512);
2013   new->buffer = buffer;
2014
2015   while (packet->buffer->len) {
2016     SILC_GET16_MSB(len1, packet->buffer->data);
2017     if ((len1 > packet->buffer->len) ||
2018         (len1 > buffer->truelen))
2019       break;
2020
2021     SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
2022     if ((len2 > packet->buffer->len) ||
2023         (len2 > buffer->truelen))
2024       break;
2025
2026     silc_buffer_pull_tail(buffer, 8 + len1 + len2);
2027     silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
2028
2029     /* Process the New Channel */
2030     silc_server_new_channel(server, sock, new);
2031
2032     silc_buffer_push_tail(buffer, 8 + len1 + len2);
2033     silc_buffer_pull(packet->buffer, 8 + len1 + len2);
2034   }
2035
2036   silc_buffer_free(buffer);
2037   silc_free(new);
2038 }
2039
2040 /* Received key agreement packet. This packet is never for us. It is to
2041    the client in the packet's destination ID. Sending of this sort of packet
2042    equals sending private message, ie. it is sent point to point from
2043    one client to another. */
2044
2045 void silc_server_key_agreement(SilcServer server,
2046                                SilcSocketConnection sock,
2047                                SilcPacketContext *packet)
2048 {
2049   SilcSocketConnection dst_sock;
2050   SilcIDListData idata;
2051
2052   SILC_LOG_DEBUG(("Start"));
2053
2054   if (packet->src_id_type != SILC_ID_CLIENT ||
2055       packet->dst_id_type != SILC_ID_CLIENT)
2056     return;
2057
2058   if (!packet->dst_id)
2059     return;
2060
2061   /* Get the route to the client */
2062   dst_sock = silc_server_get_client_route(server, packet->dst_id,
2063                                           packet->dst_id_len, NULL, &idata);
2064   if (!dst_sock)
2065     return;
2066
2067   /* Relay the packet */
2068   silc_server_relay_packet(server, dst_sock, idata->send_key,
2069                            idata->hmac_send, packet, FALSE);
2070 }
2071
2072 /* Received connection auth request packet that is used during connection
2073    phase to resolve the mandatory authentication method.  This packet can
2074    actually be received at anytime but usually it is used only during
2075    the connection authentication phase. Now, protocol says that this packet
2076    can come from client or server, however, we support only this coming
2077    from client and expect that server's always knows what authentication
2078    method to use. */
2079
2080 void silc_server_connection_auth_request(SilcServer server,
2081                                          SilcSocketConnection sock,
2082                                          SilcPacketContext *packet)
2083 {
2084   SilcServerConfigSectionClientConnection *client = NULL;
2085   uint16 conn_type;
2086   int ret;
2087   SilcAuthMethod auth_meth;
2088
2089   SILC_LOG_DEBUG(("Start"));
2090
2091   if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT)
2092     return;
2093
2094   /* Parse the payload */
2095   ret = silc_buffer_unformat(packet->buffer,
2096                              SILC_STR_UI_SHORT(&conn_type),
2097                              SILC_STR_UI_SHORT(NULL),
2098                              SILC_STR_END);
2099   if (ret == -1)
2100     return;
2101
2102   if (conn_type != SILC_SOCKET_TYPE_CLIENT)
2103     return;
2104
2105   /* Get the authentication method for the client */
2106   auth_meth = SILC_AUTH_NONE;
2107   client = silc_server_config_find_client_conn(server->config,
2108                                                sock->ip,
2109                                                sock->port);
2110   if (!client)
2111     client = silc_server_config_find_client_conn(server->config,
2112                                                  sock->hostname,
2113                                                  sock->port);
2114   if (client)
2115     auth_meth = client->auth_meth;
2116           
2117   /* Send it back to the client */
2118   silc_server_send_connection_auth_request(server, sock,
2119                                            conn_type,
2120                                            auth_meth);
2121 }
2122
2123 /* Received REKEY packet. The sender of the packet wants to regenerate
2124    its session keys. This starts the REKEY protocol. */
2125
2126 void silc_server_rekey(SilcServer server,
2127                        SilcSocketConnection sock,
2128                        SilcPacketContext *packet)
2129 {
2130   SilcProtocol protocol;
2131   SilcServerRekeyInternalContext *proto_ctx;
2132   SilcIDListData idata = (SilcIDListData)sock->user_data;
2133
2134   SILC_LOG_DEBUG(("Start"));
2135
2136   /* Allocate internal protocol context. This is sent as context
2137      to the protocol. */
2138   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
2139   proto_ctx->server = (void *)server;
2140   proto_ctx->sock = sock;
2141   proto_ctx->responder = TRUE;
2142   proto_ctx->pfs = idata->rekey->pfs;
2143       
2144   /* Perform rekey protocol. Will call the final callback after the
2145      protocol is over. */
2146   silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY, 
2147                       &protocol, proto_ctx, silc_server_rekey_final);
2148   sock->protocol = protocol;
2149
2150   if (proto_ctx->pfs == FALSE)
2151     /* Run the protocol */
2152     silc_protocol_execute(protocol, server->timeout_queue, 0, 0);
2153 }