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   if (strlen(username) > 128)
1327     username[127] = '\0';
1328
1329   nickname = strdup(username);
1330
1331   /* Make sanity checks for the hostname of the client. If the hostname
1332      is provided in the `username' check that it is the same than the
1333      resolved hostname, or if not resolved the hostname that appears in
1334      the client's public key. If the hostname is not present then put
1335      it from the resolved name or from the public key. */
1336   if (strchr(username, '@')) {
1337     SilcPublicKeyIdentifier pident;
1338     int tlen = strcspn(username, "@");
1339     char *phostname = NULL;
1340
1341     hostname = silc_calloc((strlen(username) - tlen) + 1, sizeof(char));
1342     memcpy(hostname, username + tlen + 1, strlen(username) - tlen - 1);
1343
1344     if (strcmp(sock->hostname, sock->ip) && 
1345         strcmp(sock->hostname, hostname)) {
1346       silc_free(username);
1347       silc_free(hostname);
1348       if (realname)
1349         silc_free(realname);
1350       silc_server_disconnect_remote(server, sock, 
1351                                     "Server closed connection: "
1352                                     "Incomplete client information");
1353       return NULL;
1354     }
1355     
1356     pident = silc_pkcs_decode_identifier(client->data.public_key->identifier);
1357     if (pident) {
1358       phostname = strdup(pident->host);
1359       silc_pkcs_free_identifier(pident);
1360     }
1361
1362     if (!strcmp(sock->hostname, sock->ip) && 
1363         phostname && strcmp(phostname, hostname)) {
1364       silc_free(username);
1365       silc_free(hostname);
1366       if (phostname)
1367         silc_free(phostname);
1368       if (realname)
1369         silc_free(realname);
1370       silc_server_disconnect_remote(server, sock, 
1371                                     "Server closed connection: "
1372                                     "Incomplete client information");
1373       return NULL;
1374     }
1375     
1376     if (phostname)
1377       silc_free(phostname);
1378   } else {
1379     /* The hostname is not present, add it. */
1380     char *newusername;
1381     /* XXX For now we cannot take the host name from the public key since
1382        they are not trusted or we cannot verify them as trusted. Just take
1383        what the resolved name or address is. */
1384 #if 0
1385     if (strcmp(sock->hostname, sock->ip)) {
1386 #endif
1387       newusername = silc_calloc(strlen(username) + 
1388                                 strlen(sock->hostname) + 2,
1389                                 sizeof(*newusername));
1390       strncat(newusername, username, strlen(username));
1391       strncat(newusername, "@", 1);
1392       strncat(newusername, sock->hostname, strlen(sock->hostname));
1393       silc_free(username);
1394       username = newusername;
1395 #if 0
1396     } else {
1397       SilcPublicKeyIdentifier pident = 
1398         silc_pkcs_decode_identifier(client->data.public_key->identifier);
1399       
1400       if (pident) {
1401         newusername = silc_calloc(strlen(username) + 
1402                                   strlen(pident->host) + 2,
1403                                   sizeof(*newusername));
1404         strncat(newusername, username, strlen(username));
1405         strncat(newusername, "@", 1);
1406         strncat(newusername, pident->host, strlen(pident->host));
1407         silc_free(username);
1408         username = newusername;
1409         silc_pkcs_free_identifier(pident);
1410       }
1411     }
1412 #endif
1413   }
1414
1415   /* Create Client ID */
1416   silc_id_create_client_id(server->id, server->rng, server->md5hash,
1417                            username, &client_id);
1418
1419   /* Update client entry */
1420   idata->registered = TRUE;
1421   client->nickname = nickname;
1422   client->username = username;
1423   client->userinfo = realname ? realname : strdup(" ");
1424   client->id = client_id;
1425   id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
1426
1427   /* Add the client again to the ID cache */
1428   silc_idcache_add(server->local_list->clients, client->nickname,
1429                    client_id, client, FALSE);
1430
1431   /* Notify our router about new client on the SILC network */
1432   if (!server->standalone)
1433     silc_server_send_new_id(server, (SilcSocketConnection) 
1434                             server->router->connection, 
1435                             server->server_type == SILC_ROUTER ? TRUE : FALSE,
1436                             client->id, SILC_ID_CLIENT, id_len);
1437   
1438   /* Send the new client ID to the client. */
1439   id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
1440   reply = silc_buffer_alloc(2 + 2 + id_len);
1441   silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
1442   silc_buffer_format(reply,
1443                      SILC_STR_UI_SHORT(SILC_ID_CLIENT),
1444                      SILC_STR_UI_SHORT(id_len),
1445                      SILC_STR_UI_XNSTRING(id_string, id_len),
1446                      SILC_STR_END);
1447   silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0, 
1448                           reply->data, reply->len, FALSE);
1449   silc_free(id_string);
1450   silc_buffer_free(reply);
1451
1452   /* Send some nice info to the client */
1453   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1454                           ("Welcome to the SILC Network %s",
1455                            username));
1456   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1457                           ("Your host is %s, running version %s",
1458                            server->config->server_info->server_name,
1459                            server_version));
1460   if (server->server_type == SILC_ROUTER) {
1461     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1462                             ("There are %d clients on %d servers in SILC "
1463                              "Network", server->stat.clients,
1464                              server->stat.servers + 1));
1465     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1466                             ("There are %d clients on %d server in our cell",
1467                              server->stat.cell_clients,
1468                              server->stat.cell_servers + 1));
1469     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1470                             ("I have %d clients, %d channels, %d servers and "
1471                              "%d routers",
1472                              server->stat.my_clients, 
1473                              server->stat.my_channels,
1474                              server->stat.my_servers,
1475                              server->stat.my_routers));
1476     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1477                             ("%d server operators and %d router operators "
1478                              "online",
1479                              server->stat.my_server_ops,
1480                              server->stat.my_router_ops));
1481   } else {
1482     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1483                             ("I have %d clients and %d channels formed",
1484                              server->stat.my_clients,
1485                              server->stat.my_channels));
1486     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1487                             ("%d operators online",
1488                              server->stat.my_server_ops));
1489   }
1490   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1491                           ("Your connection is secured with %s cipher, "
1492                            "key length %d bits",
1493                            idata->send_key->cipher->name,
1494                            idata->send_key->cipher->key_len));
1495   SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1496                           ("Your current nickname is %s",
1497                            client->nickname));
1498
1499   /* Send motd */
1500   silc_server_send_motd(server, sock);
1501
1502   return client;
1503 }
1504
1505 /* Create new server. This processes received New Server packet and
1506    saves the received Server ID. The server is our locally connected
1507    server thus we save all the information and save it to local list. 
1508    This funtion can be used by both normal server and router server.
1509    If normal server uses this it means that its router has connected
1510    to the server. If router uses this it means that one of the cell's
1511    servers is connected to the router. */
1512
1513 SilcServerEntry silc_server_new_server(SilcServer server,
1514                                        SilcSocketConnection sock,
1515                                        SilcPacketContext *packet)
1516 {
1517   SilcBuffer buffer = packet->buffer;
1518   SilcServerEntry new_server;
1519   SilcServerID *server_id;
1520   SilcIDListData idata;
1521   unsigned char *server_name, *id_string;
1522   uint16 id_len, name_len;
1523   int ret;
1524
1525   SILC_LOG_DEBUG(("Creating new server"));
1526
1527   if (sock->type != SILC_SOCKET_TYPE_SERVER &&
1528       sock->type != SILC_SOCKET_TYPE_ROUTER)
1529     return NULL;
1530
1531   /* Take server entry */
1532   new_server = (SilcServerEntry)sock->user_data;
1533   idata = (SilcIDListData)new_server;
1534
1535   /* Remove the old cache entry */
1536   silc_idcache_del_by_context(server->local_list->servers, new_server);
1537
1538   /* Parse the incoming packet */
1539   ret = silc_buffer_unformat(buffer,
1540                              SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
1541                              SILC_STR_UI16_NSTRING_ALLOC(&server_name, 
1542                                                          &name_len),
1543                              SILC_STR_END);
1544   if (ret == -1) {
1545     if (id_string)
1546       silc_free(id_string);
1547     if (server_name)
1548       silc_free(server_name);
1549     return NULL;
1550   }
1551
1552   if (id_len > buffer->len) {
1553     silc_free(id_string);
1554     silc_free(server_name);
1555     return NULL;
1556   }
1557
1558   if (name_len > 256)
1559     server_name[255] = '\0';
1560
1561   /* Get Server ID */
1562   server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
1563   if (!server_id) {
1564     silc_free(id_string);
1565     silc_free(server_name);
1566     return NULL;
1567   }
1568   silc_free(id_string);
1569
1570   /* Update server entry */
1571   idata->registered = TRUE;
1572   new_server->server_name = server_name;
1573   new_server->id = server_id;
1574
1575   /* Add again the entry to the ID cache. */
1576   silc_idcache_add(server->local_list->servers, server_name, server_id, 
1577                    server, FALSE);
1578
1579   /* Distribute the information about new server in the SILC network
1580      to our router. If we are normal server we won't send anything
1581      since this connection must be our router connection. */
1582   if (server->server_type == SILC_ROUTER && !server->standalone &&
1583       server->router->connection != sock)
1584     silc_server_send_new_id(server, server->router->connection,
1585                             TRUE, new_server->id, SILC_ID_SERVER, 
1586                             silc_id_get_len(server_id, SILC_ID_SERVER));
1587
1588   if (server->server_type == SILC_ROUTER)
1589     server->stat.cell_servers++;
1590
1591   return new_server;
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 static void silc_server_new_id_real(SilcServer server, 
1598                                     SilcSocketConnection sock,
1599                                     SilcPacketContext *packet,
1600                                     int broadcast)
1601 {
1602   SilcBuffer buffer = packet->buffer;
1603   SilcIDList id_list;
1604   SilcServerEntry router;
1605   SilcSocketConnection router_sock;
1606   SilcIDPayload idp;
1607   SilcIdType id_type;
1608   void *id;
1609
1610   SILC_LOG_DEBUG(("Processing new ID"));
1611
1612   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1613       server->server_type == SILC_SERVER ||
1614       packet->src_id_type != SILC_ID_SERVER)
1615     return;
1616
1617   idp = silc_id_payload_parse(buffer);
1618   if (!idp)
1619     return;
1620
1621   id_type = silc_id_payload_get_type(idp);
1622
1623   /* Normal server cannot have other normal server connections */
1624   if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
1625     goto out;
1626
1627   id = silc_id_payload_get_id(idp);
1628   if (!id)
1629     goto out;
1630
1631   /* If the sender of this packet is server and we are router we need to
1632      broadcast this packet to other routers in the network. */
1633   if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
1634       sock->type == SILC_SOCKET_TYPE_SERVER &&
1635       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1636     SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
1637     silc_server_packet_send(server, server->router->connection,
1638                             packet->type, 
1639                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1640                             buffer->data, buffer->len, FALSE);
1641   }
1642
1643   if (sock->type == SILC_SOCKET_TYPE_SERVER)
1644     id_list = server->local_list;
1645   else
1646     id_list = server->global_list;
1647
1648   /* If the packet is coming from server then use the sender as the
1649      origin of the the packet. If it came from router then check the real
1650      sender of the packet and use that as the origin. */
1651   if (sock->type == SILC_SOCKET_TYPE_SERVER) {
1652     router_sock = sock;
1653     router = sock->user_data;
1654   } else {
1655     void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1656                                      packet->src_id_type);
1657     router = silc_idlist_find_server_by_id(server->global_list,
1658                                            sender_id, NULL);
1659     if (!router)
1660       router = silc_idlist_find_server_by_id(server->local_list,
1661                                              sender_id, NULL);
1662     silc_free(sender_id);
1663     if (!router)
1664       goto out;
1665     router_sock = sock;
1666   }
1667
1668   switch(id_type) {
1669   case SILC_ID_CLIENT:
1670     {
1671       SilcClientEntry entry;
1672
1673       SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
1674                       silc_id_render(id, SILC_ID_CLIENT),
1675                       sock->type == SILC_SOCKET_TYPE_SERVER ?
1676                       "Server" : "Router", sock->hostname));
1677     
1678       /* As a router we keep information of all global information in our
1679          global list. Cell wide information however is kept in the local
1680          list. */
1681       entry = silc_idlist_add_client(id_list, NULL, NULL, NULL, 
1682                                      id, router, NULL);
1683       entry->nickname = NULL;
1684       entry->data.registered = TRUE;
1685
1686       if (sock->type == SILC_SOCKET_TYPE_SERVER)
1687         server->stat.cell_clients++;
1688       server->stat.clients++;
1689     }
1690     break;
1691
1692   case SILC_ID_SERVER:
1693     /* If the ID is mine, ignore it. */
1694     if (SILC_ID_SERVER_COMPARE(id, server->id)) {
1695       SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
1696       break;
1697     }
1698
1699     SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
1700                     silc_id_render(id, SILC_ID_SERVER),
1701                     sock->type == SILC_SOCKET_TYPE_SERVER ?
1702                     "Server" : "Router", sock->hostname));
1703
1704     /* As a router we keep information of all global information in our global
1705        list. Cell wide information however is kept in the local list. */
1706     silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
1707
1708     if (sock->type == SILC_SOCKET_TYPE_SERVER)
1709       server->stat.cell_servers++;
1710     server->stat.servers++;
1711     break;
1712
1713   case SILC_ID_CHANNEL:
1714     SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
1715     break;
1716
1717   default:
1718     break;
1719   }
1720
1721  out:
1722   silc_id_payload_free(idp);
1723 }
1724
1725
1726 /* Processes incoming New ID packet. New ID Payload is used to distribute
1727    information about newly registered clients and servers. */
1728
1729 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
1730                         SilcPacketContext *packet)
1731 {
1732   silc_server_new_id_real(server, sock, packet, TRUE);
1733 }
1734
1735 /* Receoved New Id List packet, list of New ID payloads inside one
1736    packet. Process the New ID payloads one by one. */
1737
1738 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
1739                              SilcPacketContext *packet)
1740 {
1741   SilcPacketContext *new_id;
1742   SilcBuffer idp;
1743   uint16 id_len;
1744
1745   SILC_LOG_DEBUG(("Processing New ID List"));
1746
1747   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1748       packet->src_id_type != SILC_ID_SERVER)
1749     return;
1750
1751   /* If the sender of this packet is server and we are router we need to
1752      broadcast this packet to other routers in the network. Broadcast
1753      this list packet instead of multiple New ID packets. */
1754   if (!server->standalone && server->server_type == SILC_ROUTER &&
1755       sock->type == SILC_SOCKET_TYPE_SERVER &&
1756       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1757     SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
1758     silc_server_packet_send(server, server->router->connection,
1759                             packet->type, 
1760                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
1761                             packet->buffer->data, packet->buffer->len, FALSE);
1762   }
1763
1764   /* Make copy of the original packet context, except for the actual
1765      data buffer, which we will here now fetch from the original buffer. */
1766   new_id = silc_packet_context_alloc();
1767   new_id->type = SILC_PACKET_NEW_ID;
1768   new_id->flags = packet->flags;
1769   new_id->src_id = packet->src_id;
1770   new_id->src_id_len = packet->src_id_len;
1771   new_id->src_id_type = packet->src_id_type;
1772   new_id->dst_id = packet->dst_id;
1773   new_id->dst_id_len = packet->dst_id_len;
1774   new_id->dst_id_type = packet->dst_id_type;
1775
1776   idp = silc_buffer_alloc(256);
1777   new_id->buffer = idp;
1778
1779   while (packet->buffer->len) {
1780     SILC_GET16_MSB(id_len, packet->buffer->data + 2);
1781     if ((id_len > packet->buffer->len) ||
1782         (id_len > idp->truelen))
1783       break;
1784
1785     silc_buffer_pull_tail(idp, 4 + id_len);
1786     silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
1787
1788     /* Process the New ID */
1789     silc_server_new_id_real(server, sock, new_id, FALSE);
1790
1791     silc_buffer_push_tail(idp, 4 + id_len);
1792     silc_buffer_pull(packet->buffer, 4 + id_len);
1793   }
1794
1795   silc_buffer_free(idp);
1796   silc_free(new_id);
1797 }
1798
1799 /* Received New Channel packet. Information about new channels in the 
1800    network are distributed using this packet. Save the information about
1801    the new channel. This usually comes from router but also normal server
1802    can send this to notify channels it has when it connects to us. */
1803
1804 void silc_server_new_channel(SilcServer server,
1805                              SilcSocketConnection sock,
1806                              SilcPacketContext *packet)
1807 {
1808   SilcChannelPayload payload;
1809   SilcChannelID *channel_id;
1810   char *channel_name;
1811   uint32 name_len;
1812   unsigned char *id;
1813   uint32 id_len;
1814   uint32 mode;
1815
1816   SILC_LOG_DEBUG(("Processing New Channel"));
1817
1818   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1819       packet->src_id_type != SILC_ID_SERVER ||
1820       server->server_type == SILC_SERVER)
1821     return;
1822
1823   /* Parse the channel payload */
1824   payload = silc_channel_payload_parse(packet->buffer);
1825   if (!payload)
1826     return;
1827     
1828   /* Get the channel ID */
1829   channel_id = silc_channel_get_id_parse(payload);
1830   if (!channel_id) {
1831     silc_channel_payload_free(payload);
1832     return;
1833   }
1834
1835   channel_name = silc_channel_get_name(payload, &name_len);
1836   if (name_len > 256)
1837     channel_name[255] = '\0';
1838
1839   id = silc_channel_get_id(payload, &id_len);
1840
1841   if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
1842     /* Add the server to global list as it is coming from router. It 
1843        cannot be our own channel as it is coming from router. */
1844
1845     SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
1846                     silc_id_render(channel_id, SILC_ID_CHANNEL), 
1847                     sock->hostname));
1848     
1849     silc_idlist_add_channel(server->global_list, strdup(channel_name), 
1850                             0, channel_id, server->router->connection, 
1851                             NULL, NULL);
1852
1853     server->stat.channels++;
1854   } else {
1855     /* The channel is coming from our server, thus it is in our cell
1856        we will add it to our local list. */
1857     SilcChannelEntry channel;
1858     SilcBuffer chk;
1859
1860     SILC_LOG_DEBUG(("New channel id(%s) from [Server] %s",
1861                     silc_id_render(channel_id, SILC_ID_CHANNEL), 
1862                     sock->hostname));
1863     
1864     /* Check that we don't already have this channel */
1865     channel = silc_idlist_find_channel_by_name(server->local_list, 
1866                                                channel_name, NULL);
1867     if (!channel)
1868       channel = silc_idlist_find_channel_by_name(server->global_list, 
1869                                                  channel_name, NULL);
1870
1871     /* If the channel does not exist, then create it. We create the channel
1872        with the channel ID provided by the server. This creates a new
1873        key to the channel as well that we will send to the server. */
1874     if (!channel) {
1875       channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
1876                                                        channel_name,
1877                                                        channel_id, FALSE);
1878       if (!channel) {
1879         silc_channel_payload_free(payload);
1880         silc_free(channel_id);
1881         return;
1882       }
1883
1884       /* Get the mode and set it to the channel */
1885       channel->mode = silc_channel_get_mode(payload);
1886
1887       /* Send the new channel key to the server */
1888       chk = silc_channel_key_payload_encode(id_len, id,
1889                                             strlen(channel->channel_key->
1890                                                    cipher->name),
1891                                             channel->channel_key->cipher->name,
1892                                             channel->key_len / 8, 
1893                                             channel->key);
1894       silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
1895                               chk->data, chk->len, FALSE);
1896       silc_buffer_free(chk);
1897
1898     } else {
1899       /* The channel exist by that name, check whether the ID's match.
1900          If they don't then we'll force the server to use the ID we have.
1901          We also create a new key for the channel. */
1902       SilcBuffer users = NULL, users_modes = NULL;
1903
1904       if (!channel->id)
1905         channel_id = silc_id_dup(channel_id, SILC_ID_CHANNEL);
1906
1907       if (!SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
1908         /* They don't match, send CHANNEL_CHANGE notify to the server to
1909            force the ID change. */
1910         SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
1911         silc_server_send_notify_channel_change(server, sock, FALSE, 
1912                                                channel_id, channel->id);
1913       }
1914
1915       /* If the mode is different from what we have then enforce the
1916          mode change. */
1917       mode = silc_channel_get_mode(payload);
1918       if (channel->mode != mode) {
1919         SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
1920         silc_server_send_notify_cmode(server, sock, FALSE, channel,
1921                                       channel->mode, server->id,
1922                                       SILC_ID_SERVER,
1923                                       channel->cipher, channel->hmac_name);
1924       }
1925
1926       /* Create new key for the channel and send it to the server and
1927          everybody else possibly on the channel. */
1928
1929       if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
1930         silc_server_create_channel_key(server, channel, 0);
1931         
1932         /* Send to the channel */
1933         silc_server_send_channel_key(server, sock, channel, FALSE);
1934         id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
1935         id_len = SILC_ID_CHANNEL_LEN;
1936         
1937         /* Send to the server */
1938         chk = silc_channel_key_payload_encode(id_len, id,
1939                                               strlen(channel->channel_key->
1940                                                      cipher->name),
1941                                               channel->channel_key->
1942                                               cipher->name,
1943                                               channel->key_len / 8, 
1944                                               channel->key);
1945         silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
1946                                 chk->data, chk->len, FALSE);
1947         silc_buffer_free(chk);
1948         silc_free(id);
1949       }
1950
1951       silc_free(channel_id);
1952
1953       /* Since the channel is coming from server and we also know about it
1954          then send the JOIN notify to the server so that it see's our
1955          users on the channel "joining" the channel. */
1956       silc_server_announce_get_channel_users(server, channel, &users,
1957                                              &users_modes);
1958       if (users) {
1959         silc_buffer_push(users, users->data - users->head);
1960         silc_server_packet_send(server, sock,
1961                                 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1962                                 users->data, users->len, FALSE);
1963         silc_buffer_free(users);
1964       }
1965       if (users_modes) {
1966         silc_buffer_push(users_modes, users_modes->data - users_modes->head);
1967         silc_server_packet_send(server, sock,
1968                                 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1969                                 users_modes->data, users_modes->len, FALSE);
1970         silc_buffer_free(users_modes);
1971       }
1972     }
1973   }
1974
1975   silc_channel_payload_free(payload);
1976 }
1977
1978 /* Received New Channel List packet, list of New Channel List payloads inside
1979    one packet. Process the New Channel payloads one by one. */
1980
1981 void silc_server_new_channel_list(SilcServer server,
1982                                   SilcSocketConnection sock,
1983                                   SilcPacketContext *packet)
1984 {
1985   SilcPacketContext *new;
1986   SilcBuffer buffer;
1987   uint16 len1, len2;
1988
1989   SILC_LOG_DEBUG(("Processing New Channel List"));
1990
1991   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1992       packet->src_id_type != SILC_ID_SERVER ||
1993       server->server_type == SILC_SERVER)
1994     return;
1995
1996   /* If the sender of this packet is server and we are router we need to
1997      broadcast this packet to other routers in the network. Broadcast
1998      this list packet instead of multiple New Channel packets. */
1999   if (!server->standalone && server->server_type == SILC_ROUTER &&
2000       sock->type == SILC_SOCKET_TYPE_SERVER &&
2001       !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2002     SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
2003     silc_server_packet_send(server, server->router->connection,
2004                             packet->type, 
2005                             packet->flags | SILC_PACKET_FLAG_BROADCAST,
2006                             packet->buffer->data, packet->buffer->len, FALSE);
2007   }
2008
2009   /* Make copy of the original packet context, except for the actual
2010      data buffer, which we will here now fetch from the original buffer. */
2011   new = silc_packet_context_alloc();
2012   new->type = SILC_PACKET_NEW_CHANNEL;
2013   new->flags = packet->flags;
2014   new->src_id = packet->src_id;
2015   new->src_id_len = packet->src_id_len;
2016   new->src_id_type = packet->src_id_type;
2017   new->dst_id = packet->dst_id;
2018   new->dst_id_len = packet->dst_id_len;
2019   new->dst_id_type = packet->dst_id_type;
2020
2021   buffer = silc_buffer_alloc(512);
2022   new->buffer = buffer;
2023
2024   while (packet->buffer->len) {
2025     SILC_GET16_MSB(len1, packet->buffer->data);
2026     if ((len1 > packet->buffer->len) ||
2027         (len1 > buffer->truelen))
2028       break;
2029
2030     SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
2031     if ((len2 > packet->buffer->len) ||
2032         (len2 > buffer->truelen))
2033       break;
2034
2035     silc_buffer_pull_tail(buffer, 8 + len1 + len2);
2036     silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
2037
2038     /* Process the New Channel */
2039     silc_server_new_channel(server, sock, new);
2040
2041     silc_buffer_push_tail(buffer, 8 + len1 + len2);
2042     silc_buffer_pull(packet->buffer, 8 + len1 + len2);
2043   }
2044
2045   silc_buffer_free(buffer);
2046   silc_free(new);
2047 }
2048
2049 /* Received key agreement packet. This packet is never for us. It is to
2050    the client in the packet's destination ID. Sending of this sort of packet
2051    equals sending private message, ie. it is sent point to point from
2052    one client to another. */
2053
2054 void silc_server_key_agreement(SilcServer server,
2055                                SilcSocketConnection sock,
2056                                SilcPacketContext *packet)
2057 {
2058   SilcSocketConnection dst_sock;
2059   SilcIDListData idata;
2060
2061   SILC_LOG_DEBUG(("Start"));
2062
2063   if (packet->src_id_type != SILC_ID_CLIENT ||
2064       packet->dst_id_type != SILC_ID_CLIENT)
2065     return;
2066
2067   if (!packet->dst_id)
2068     return;
2069
2070   /* Get the route to the client */
2071   dst_sock = silc_server_get_client_route(server, packet->dst_id,
2072                                           packet->dst_id_len, NULL, &idata);
2073   if (!dst_sock)
2074     return;
2075
2076   /* Relay the packet */
2077   silc_server_relay_packet(server, dst_sock, idata->send_key,
2078                            idata->hmac_send, packet, FALSE);
2079 }
2080
2081 /* Received connection auth request packet that is used during connection
2082    phase to resolve the mandatory authentication method.  This packet can
2083    actually be received at anytime but usually it is used only during
2084    the connection authentication phase. Now, protocol says that this packet
2085    can come from client or server, however, we support only this coming
2086    from client and expect that server's always knows what authentication
2087    method to use. */
2088
2089 void silc_server_connection_auth_request(SilcServer server,
2090                                          SilcSocketConnection sock,
2091                                          SilcPacketContext *packet)
2092 {
2093   SilcServerConfigSectionClientConnection *client = NULL;
2094   uint16 conn_type;
2095   int ret;
2096   SilcAuthMethod auth_meth;
2097
2098   SILC_LOG_DEBUG(("Start"));
2099
2100   if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT)
2101     return;
2102
2103   /* Parse the payload */
2104   ret = silc_buffer_unformat(packet->buffer,
2105                              SILC_STR_UI_SHORT(&conn_type),
2106                              SILC_STR_UI_SHORT(NULL),
2107                              SILC_STR_END);
2108   if (ret == -1)
2109     return;
2110
2111   if (conn_type != SILC_SOCKET_TYPE_CLIENT)
2112     return;
2113
2114   /* Get the authentication method for the client */
2115   auth_meth = SILC_AUTH_NONE;
2116   client = silc_server_config_find_client_conn(server->config,
2117                                                sock->ip,
2118                                                sock->port);
2119   if (!client)
2120     client = silc_server_config_find_client_conn(server->config,
2121                                                  sock->hostname,
2122                                                  sock->port);
2123   if (client)
2124     auth_meth = client->auth_meth;
2125           
2126   /* Send it back to the client */
2127   silc_server_send_connection_auth_request(server, sock,
2128                                            conn_type,
2129                                            auth_meth);
2130 }
2131
2132 /* Received REKEY packet. The sender of the packet wants to regenerate
2133    its session keys. This starts the REKEY protocol. */
2134
2135 void silc_server_rekey(SilcServer server,
2136                        SilcSocketConnection sock,
2137                        SilcPacketContext *packet)
2138 {
2139   SilcProtocol protocol;
2140   SilcServerRekeyInternalContext *proto_ctx;
2141   SilcIDListData idata = (SilcIDListData)sock->user_data;
2142
2143   SILC_LOG_DEBUG(("Start"));
2144
2145   /* Allocate internal protocol context. This is sent as context
2146      to the protocol. */
2147   proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
2148   proto_ctx->server = (void *)server;
2149   proto_ctx->sock = sock;
2150   proto_ctx->responder = TRUE;
2151   proto_ctx->pfs = idata->rekey->pfs;
2152       
2153   /* Perform rekey protocol. Will call the final callback after the
2154      protocol is over. */
2155   silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY, 
2156                       &protocol, proto_ctx, silc_server_rekey_final);
2157   sock->protocol = protocol;
2158
2159   if (proto_ctx->pfs == FALSE)
2160     /* Run the protocol */
2161     silc_protocol_execute(protocol, server->timeout_queue, 0, 0);
2162 }