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