5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2002 Pekka Riikonen
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.
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.
21 * Server packet routines to handle received packets.
25 #include "serverincludes.h"
26 #include "server_internal.h"
28 /* Received notify packet. Server can receive notify packets from router.
29 Server then relays the notify messages to clients if needed. */
31 void silc_server_notify(SilcServer server,
32 SilcSocketConnection sock,
33 SilcPacketContext *packet)
35 SilcNotifyPayload payload;
37 SilcArgumentPayload args;
38 SilcChannelID *channel_id = NULL, *channel_id2;
39 SilcClientID *client_id, *client_id2;
40 SilcServerID *server_id;
42 SilcChannelEntry channel = NULL;
43 SilcClientEntry client = NULL, client2 = NULL;
44 SilcServerEntry server_entry = NULL;
45 SilcChannelClientEntry chl;
46 SilcIDCacheEntry cache = NULL;
47 SilcHashTableList htl;
53 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
54 packet->src_id_type != SILC_ID_SERVER || !packet->dst_id) {
55 SILC_LOG_DEBUG(("Bad notify packet received"));
59 /* If the packet is destined directly to a client then relay the packet
60 before processing it. */
61 if (packet->dst_id_type == SILC_ID_CLIENT) {
63 SilcSocketConnection dst_sock;
65 /* Get the route to the client */
66 dst_sock = silc_server_get_client_route(server, packet->dst_id,
67 packet->dst_id_len, NULL,
70 /* Relay the packet */
71 silc_server_relay_packet(server, dst_sock, idata->send_key,
72 idata->hmac_send, idata->psn_send++,
76 /* Parse the Notify Payload */
77 payload = silc_notify_payload_parse(packet->buffer->data,
82 /* If we are router and this packet is not already broadcast packet
83 we will broadcast it. The sending socket really cannot be router or
84 the router is buggy. If this packet is coming from router then it must
85 have the broadcast flag set already and we won't do anything. */
86 if (server->server_type == SILC_ROUTER &&
87 sock->type == SILC_SOCKET_TYPE_SERVER &&
88 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
89 SILC_LOG_DEBUG(("Broadcasting received Notify packet"));
90 if (packet->dst_id_type == SILC_ID_CHANNEL) {
91 /* Packet is destined to channel */
92 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
97 silc_server_packet_send_dest(server, SILC_PRIMARY_ROUTE(server),
98 packet->type, packet->flags |
99 SILC_PACKET_FLAG_BROADCAST,
100 channel_id, SILC_ID_CHANNEL,
101 packet->buffer->data,
102 packet->buffer->len, FALSE);
103 silc_server_backup_send_dest(server, sock->user_data,
104 packet->type, packet->flags,
105 channel_id, SILC_ID_CHANNEL,
106 packet->buffer->data, packet->buffer->len,
109 /* Packet is destined to client or server */
110 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
112 packet->flags | SILC_PACKET_FLAG_BROADCAST,
113 packet->buffer->data, packet->buffer->len,
115 silc_server_backup_send(server, sock->user_data,
116 packet->type, packet->flags,
117 packet->buffer->data, packet->buffer->len,
122 type = silc_notify_get_type(payload);
123 args = silc_notify_get_args(payload);
128 case SILC_NOTIFY_TYPE_JOIN:
130 * Distribute the notify to local clients on the channel
132 SILC_LOG_DEBUG(("JOIN notify"));
135 silc_free(channel_id);
138 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
141 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
145 /* Get channel entry */
146 channel = silc_idlist_find_channel_by_id(server->global_list,
149 channel = silc_idlist_find_channel_by_id(server->local_list,
152 SILC_LOG_DEBUG(("Notify for unknown channel"));
153 silc_free(channel_id);
157 silc_free(channel_id);
160 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
163 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
167 /* If the the client is not in local list we check global list (ie. the
168 channel will be global channel) and if it does not exist then create
169 entry for the client. */
170 client = silc_idlist_find_client_by_id(server->global_list,
171 client_id, server->server_type,
174 client = silc_idlist_find_client_by_id(server->local_list,
175 client_id, server->server_type,
178 /* If router did not find the client the it is bogus */
179 if (server->server_type != SILC_SERVER) {
180 silc_free(client_id);
185 silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
186 silc_id_dup(client_id, SILC_ID_CLIENT),
187 sock->user_data, NULL, 0);
189 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
190 silc_free(client_id);
194 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
197 silc_free(client_id);
199 /* Do not process the notify if the client is not registered */
200 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
203 /* Do not add client to channel if it is there already */
204 if (silc_server_client_on_channel(client, channel, NULL)) {
205 SILC_LOG_DEBUG(("Client already on channel %s",
206 channel->channel_name));
210 /* Send to channel */
211 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
212 FALSE, packet->buffer->data,
213 packet->buffer->len, FALSE);
215 if (server->server_type != SILC_ROUTER &&
216 sock->type == SILC_SOCKET_TYPE_ROUTER)
217 /* The channel is global now */
218 channel->global_users = TRUE;
220 SILC_LOG_DEBUG(("Joining to channel %s", channel->channel_name));
222 /* JOIN the global client to the channel (local clients (if router
223 created the channel) is joined in the pending JOIN command). */
224 chl = silc_calloc(1, sizeof(*chl));
225 chl->client = client;
226 chl->channel = channel;
228 if (server->server_type != SILC_ROUTER ||
229 sock->type == SILC_SOCKET_TYPE_ROUTER) {
230 /* If this is the first one on the channel then it is the founder of
231 the channel. This is done on normal server and on router if this
232 notify is coming from router */
233 if (!silc_hash_table_count(channel->user_list)) {
234 SILC_LOG_DEBUG(("Client %s is founder on channel",
235 silc_id_render(chl->client->id, SILC_ID_CLIENT)));
236 chl->mode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
240 silc_hash_table_add(channel->user_list, client, chl);
241 silc_hash_table_add(client->channels, channel, chl);
242 channel->user_count++;
243 channel->disabled = FALSE;
245 /* Make sure we don't expire clients that are on channel */
249 /* Update statistics */
250 if (server->server_type == SILC_ROUTER) {
251 if (sock->type != SILC_SOCKET_TYPE_ROUTER)
252 server->stat.cell_chanclients++;
253 server->stat.chanclients++;
258 case SILC_NOTIFY_TYPE_LEAVE:
260 * Distribute the notify to local clients on the channel
262 SILC_LOG_DEBUG(("LEAVE notify"));
265 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
266 packet->dst_id_type);
271 /* Get channel entry */
272 channel = silc_idlist_find_channel_by_id(server->global_list,
275 channel = silc_idlist_find_channel_by_id(server->local_list,
278 SILC_LOG_DEBUG(("Notify for unknown channel"));
279 silc_free(channel_id);
285 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
287 silc_free(channel_id);
290 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
292 silc_free(channel_id);
296 /* Get client entry */
297 client = silc_idlist_find_client_by_id(server->global_list,
298 client_id, TRUE, NULL);
300 client = silc_idlist_find_client_by_id(server->local_list,
301 client_id, TRUE, NULL);
303 silc_free(client_id);
304 silc_free(channel_id);
308 silc_free(client_id);
309 silc_free(channel_id);
311 /* Check if on channel */
312 if (!silc_server_client_on_channel(client, channel, NULL))
315 /* Send the leave notify to channel */
316 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
317 FALSE, packet->buffer->data,
318 packet->buffer->len, FALSE);
320 /* Remove the user from channel */
321 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
324 case SILC_NOTIFY_TYPE_SIGNOFF:
326 * Distribute the notify to local clients on the channel
328 SILC_LOG_DEBUG(("SIGNOFF notify"));
331 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
334 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
338 /* Get client entry */
339 client = silc_idlist_find_client_by_id(server->global_list,
340 client_id, TRUE, &cache);
342 client = silc_idlist_find_client_by_id(server->local_list,
343 client_id, TRUE, &cache);
345 silc_free(client_id);
349 silc_free(client_id);
351 /* Get signoff message */
352 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
356 /* Update statistics */
357 server->stat.clients--;
358 if (server->stat.cell_clients)
359 server->stat.cell_clients--;
360 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
361 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
362 silc_schedule_task_del_by_context(server->schedule, client);
364 /* Remove the client from all channels. */
365 silc_server_remove_from_channels(server, NULL, client, TRUE,
368 /* Check if anyone is watching this nickname */
369 if (server->server_type == SILC_ROUTER)
370 silc_server_check_watcher_list(server, client, NULL,
371 SILC_NOTIFY_TYPE_SIGNOFF);
373 /* Remove this client from watcher list if it is */
374 silc_server_del_from_watcher_list(server, client);
376 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
377 cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
380 case SILC_NOTIFY_TYPE_TOPIC_SET:
382 * Distribute the notify to local clients on the channel
385 SILC_LOG_DEBUG(("TOPIC SET notify"));
388 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
391 client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
395 /* Get client entry */
396 if (id_type == SILC_ID_CLIENT) {
397 client = silc_idlist_find_client_by_id(server->global_list,
398 client_id, TRUE, &cache);
400 client = silc_idlist_find_client_by_id(server->local_list,
401 client_id, TRUE, &cache);
403 silc_free(client_id);
407 silc_free(client_id);
411 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
413 silc_free(channel_id);
418 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
419 packet->dst_id_type);
424 /* Get channel entry */
425 channel = silc_idlist_find_channel_by_id(server->global_list,
428 channel = silc_idlist_find_channel_by_id(server->local_list,
431 SILC_LOG_DEBUG(("Notify for unknown channel"));
432 silc_free(channel_id);
436 silc_free(channel_id);
438 if (channel->topic && !strcmp(channel->topic, tmp)) {
439 SILC_LOG_DEBUG(("Topic is already set and same"));
444 /* Get user's channel entry and check that topic set is allowed. */
445 if (!silc_server_client_on_channel(client, channel, &chl))
447 if (channel->mode & SILC_CHANNEL_MODE_TOPIC &&
448 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
449 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
450 SILC_LOG_DEBUG(("Topic change is not allowed"));
455 /* Change the topic */
456 silc_free(channel->topic);
457 channel->topic = strdup(tmp);
459 /* Send the same notify to the channel */
460 silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
461 FALSE, packet->buffer->data,
462 packet->buffer->len, FALSE);
465 case SILC_NOTIFY_TYPE_NICK_CHANGE:
468 * Distribute the notify to local clients on the channel
470 unsigned char *id, *id2;
472 SilcUInt32 nickname_len;
474 SILC_LOG_DEBUG(("NICK CHANGE notify"));
476 /* Get old client ID */
477 id = silc_argument_get_arg_type(args, 1, &tmp_len);
480 client_id = silc_id_payload_parse_id(id, tmp_len, NULL);
484 /* Get new client ID */
485 id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
488 client_id2 = silc_id_payload_parse_id(id2, tmp_len, NULL);
490 silc_free(client_id);
494 SILC_LOG_DEBUG(("Old Client ID id(%s)",
495 silc_id_render(client_id, SILC_ID_CLIENT)));
496 SILC_LOG_DEBUG(("New Client ID id(%s)",
497 silc_id_render(client_id2, SILC_ID_CLIENT)));
499 /* From protocol version 1.1 we also get the new nickname */
500 nickname = silc_argument_get_arg_type(args, 3, &nickname_len);;
502 /* Replace the Client ID */
503 client = silc_idlist_replace_client_id(server,
504 server->global_list, client_id,
505 client_id2, nickname);
507 client = silc_idlist_replace_client_id(server,
508 server->local_list, client_id,
509 client_id2, nickname);
512 /* Send the NICK_CHANGE notify type to local clients on the channels
513 this client is joined to. */
514 silc_server_send_notify_on_channels(server, client, client,
515 SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
516 id, tmp_len, id2, tmp_len,
521 silc_free(client_id);
523 silc_free(client_id2);
527 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
529 * Distribute the notify to local clients on the channel
532 SILC_LOG_DEBUG(("CMODE CHANGE notify"));
535 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
538 client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
542 /* Get client entry */
543 if (id_type == SILC_ID_CLIENT) {
544 client = silc_idlist_find_client_by_id(server->global_list,
545 client_id, TRUE, &cache);
547 client = silc_idlist_find_client_by_id(server->local_list,
548 client_id, TRUE, &cache);
550 silc_free(client_id);
555 silc_free(client_id);
558 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
559 packet->dst_id_type);
564 /* Get channel entry */
565 channel = silc_idlist_find_channel_by_id(server->global_list,
568 channel = silc_idlist_find_channel_by_id(server->local_list,
571 SILC_LOG_DEBUG(("Notify for unknown channel"));
572 silc_free(channel_id);
576 silc_free(channel_id);
579 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
582 SILC_GET32_MSB(mode, tmp);
584 /* Check if mode changed */
585 if (channel->mode == mode) {
586 SILC_LOG_DEBUG(("Mode is changed already"));
588 /* If this mode change has founder mode then we'll enforce the
589 change so that the server gets the real founder public key */
590 if (server->server_type != SILC_SERVER &&
591 sock != SILC_PRIMARY_ROUTE(server) &&
592 mode & SILC_CHANNEL_MODE_FOUNDER_AUTH && channel->founder_key) {
593 SILC_LOG_DEBUG(("Sending founder public key to server"));
594 silc_server_send_notify_cmode(server, sock, FALSE, channel,
595 channel->mode, server->id,
596 SILC_ID_SERVER, channel->cipher,
599 channel->founder_key);
602 /* If we received same mode from our primary check whether founder
603 mode and key in the notify is set. We update the founder key
604 here since we may have wrong one */
605 if (server->server_type == SILC_SERVER &&
606 sock == SILC_PRIMARY_ROUTE(server) &&
607 mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
608 SILC_LOG_DEBUG(("Founder public key received from router"));
609 tmp = silc_argument_get_arg_type(args, 6, &tmp_len);
613 if (channel->founder_key)
614 silc_pkcs_public_key_free(channel->founder_key);
615 channel->founder_key = NULL;
616 silc_pkcs_public_key_payload_decode(tmp, tmp_len,
617 &channel->founder_key);
623 /* Get user's channel entry and check that mode change is allowed */
625 if (!silc_server_client_on_channel(client, channel, &chl))
627 if (!silc_server_check_cmode_rights(server, channel, chl, mode)) {
628 SILC_LOG_DEBUG(("CMODE change is not allowed"));
629 silc_server_send_notify_cmode(server, sock, FALSE, channel,
630 channel->mode, server->id,
631 SILC_ID_SERVER, channel->cipher,
634 channel->founder_key);
638 /* Assure that server is not removing founder mode from us */
639 if (server->server_type == SILC_ROUTER &&
640 sock != SILC_PRIMARY_ROUTE(server) &&
641 channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH &&
642 !(mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
643 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
644 silc_server_send_notify_cmode(server, sock, FALSE, channel,
645 channel->mode, server->id,
646 SILC_ID_SERVER, channel->cipher,
649 channel->founder_key);
653 /* If server is adding founder mode, check whether there is founder
654 on channel already and is not from this server */
655 if (server->server_type == SILC_ROUTER &&
656 sock != SILC_PRIMARY_ROUTE(server) &&
657 mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
658 silc_hash_table_list(channel->user_list, &htl);
659 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
660 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO &&
661 chl->client->router != sock->user_data) {
662 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
663 silc_server_send_notify_cmode(server, sock, FALSE, channel,
664 channel->mode, server->id,
665 SILC_ID_SERVER, channel->cipher,
668 channel->founder_key);
669 silc_hash_table_list_reset(&htl);
672 silc_hash_table_list_reset(&htl);
676 /* If the channel had private keys set and the mode was removed then
677 we must re-generate and re-distribute a new channel key */
678 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY &&
679 !(mode & SILC_CHANNEL_MODE_PRIVKEY)) {
680 /* Re-generate channel key */
681 if (!silc_server_create_channel_key(server, channel, 0))
684 /* Send the channel key. This sends it to our local clients and if
685 we are normal server to our router as well. */
686 silc_server_send_channel_key(server, NULL, channel,
687 server->server_type == SILC_ROUTER ?
688 FALSE : !server->standalone);
692 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
694 unsigned char hash[32];
697 silc_hmac_free(channel->hmac);
698 if (!silc_hmac_alloc(tmp, NULL, &channel->hmac))
701 /* Set the HMAC key out of current channel key. The client must do
703 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key,
704 channel->key_len / 8, hash);
705 silc_hmac_set_key(channel->hmac, hash,
706 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
707 memset(hash, 0, sizeof(hash));
710 /* Get the passphrase */
711 tmp = silc_argument_get_arg_type(args, 5, &tmp_len);
713 silc_free(channel->passphrase);
714 channel->passphrase = silc_memdup(tmp, tmp_len);
717 /* Get founder public key */
718 tmp = silc_argument_get_arg_type(args, 6, &tmp_len);
719 if (tmp && mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
720 if (channel->founder_key)
721 silc_pkcs_public_key_free(channel->founder_key);
722 channel->founder_key = NULL;
723 silc_pkcs_public_key_payload_decode(tmp, tmp_len, &channel->founder_key);
725 if (!channel->founder_key ||
726 (client && client->data.public_key &&
727 server->server_type == SILC_ROUTER &&
728 !silc_pkcs_public_key_compare(channel->founder_key,
729 client->data.public_key))) {
730 /* A really buggy server isn't checking public keys correctly.
731 It's not possible that the mode setter and founder wouldn't
732 have same public key. */
733 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
735 mode &= ~SILC_CHANNEL_MODE_FOUNDER_AUTH;
736 silc_server_send_notify_cmode(server, sock, FALSE, channel,
737 mode, server->id, SILC_ID_SERVER,
740 channel->passphrase, NULL);
741 if (channel->founder_key)
742 silc_pkcs_public_key_free(channel->founder_key);
743 channel->founder_key = NULL;
744 } else if (client && !client->data.public_key) {
745 client->data.public_key =
746 silc_pkcs_public_key_copy(channel->founder_key);
750 if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH && !channel->founder_key &&
751 server->server_type == SILC_ROUTER) {
752 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
753 mode &= ~SILC_CHANNEL_MODE_FOUNDER_AUTH;
754 silc_server_send_notify_cmode(server, sock, FALSE, channel,
755 mode, server->id, SILC_ID_SERVER,
758 channel->passphrase, NULL);
761 /* Send the same notify to the channel */
762 silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
763 FALSE, packet->buffer->data,
764 packet->buffer->len, FALSE);
767 channel->mode = mode;
769 if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) &&
770 channel->founder_key) {
771 silc_pkcs_public_key_free(channel->founder_key);
772 channel->founder_key = NULL;
777 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
780 * Distribute the notify to local clients on the channel
782 SilcChannelClientEntry chl2 = NULL;
783 bool notify_sent = FALSE;
785 SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
788 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
791 client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
795 /* Get client entry */
796 if (id_type == SILC_ID_CLIENT) {
797 client = silc_idlist_find_client_by_id(server->global_list,
798 client_id, TRUE, &cache);
800 client = silc_idlist_find_client_by_id(server->local_list,
801 client_id, TRUE, &cache);
803 silc_free(client_id);
808 silc_free(client_id);
811 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
812 packet->dst_id_type);
817 /* Get channel entry */
818 channel = silc_idlist_find_channel_by_id(server->global_list,
821 channel = silc_idlist_find_channel_by_id(server->local_list,
824 SILC_LOG_DEBUG(("Notify for unknown channel"));
825 silc_free(channel_id);
831 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
833 silc_free(channel_id);
837 SILC_GET32_MSB(mode, tmp);
839 /* Get target client */
840 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
843 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
847 /* Get client entry */
848 client2 = silc_idlist_find_client_by_id(server->global_list,
849 client_id, TRUE, NULL);
851 client2 = silc_idlist_find_client_by_id(server->local_list,
852 client_id, TRUE, NULL);
854 silc_free(client_id);
858 silc_free(client_id);
861 /* Check that sender is on channel */
862 if (!silc_server_client_on_channel(client, channel, &chl))
865 if (client != client2 && server->server_type == SILC_ROUTER) {
866 /* Sender must be operator */
867 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
868 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
869 SILC_LOG_DEBUG(("CUMODE change is not allowed"));
873 if (!silc_server_client_on_channel(client2, channel, &chl))
876 /* If target is founder mode change is not allowed. */
877 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
878 SILC_LOG_DEBUG(("CUMODE change is not allowed"));
884 /* Get target channel user entry */
885 if (!silc_server_client_on_channel(client2, channel, &chl))
888 if (server->server_type == SILC_SERVER && chl->mode == mode) {
889 SILC_LOG_DEBUG(("Mode is changed already"));
893 if (mode & SILC_CHANNEL_UMODE_CHANFO &&
894 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO) &&
895 server->server_type == SILC_ROUTER &&
896 sock != SILC_PRIMARY_ROUTE(server)) {
897 SilcPublicKey founder_key = NULL;
899 /* If channel doesn't have founder auth mode then it's impossible
900 that someone would be getting founder rights with CUMODE command.
901 In that case there already either is founder or there isn't
902 founder at all on the channel. */
903 if (client && !(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
904 /* Force the mode to not have founder mode */
905 chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
906 silc_server_force_cumode_change(server, sock, channel, chl, mode);
911 /* Get the founder of the channel and if found then this client
912 cannot be the founder since there already is one. */
913 silc_hash_table_list(channel->user_list, &htl);
914 while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
915 if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
916 /* If the founder on the channel is not the one whom has set
917 the founder mode, then it's possible that this CUMODE_CHANGE
918 is correct. Due to netsplits it's possible that this
919 situation happens. */
920 if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) ||
921 (channel->founder_key && chl2->client->data.public_key &&
922 silc_pkcs_public_key_compare(
923 channel->founder_key,
924 chl2->client->data.public_key))) {
925 chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
926 silc_server_force_cumode_change(server, sock, channel,
932 silc_hash_table_list_reset(&htl);
933 if (!(mode & SILC_CHANNEL_UMODE_CHANFO))
936 /* Founder not found of the channel. Since the founder auth mode
937 is set on the channel now check whether this is the client that
938 originally set the mode. */
940 if (channel->founder_key) {
941 /* Get public key that must be present in notify */
942 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
943 if (!tmp || !silc_pkcs_public_key_payload_decode(tmp, tmp_len,
945 chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
946 silc_server_force_cumode_change(server, sock, channel, chl, mode);
951 /* Now match the public key we have cached and public key sent.
953 #if 0 /* The key may be other than the client's in 1.2 */
954 if (client && client->data.public_key &&
955 !silc_pkcs_public_key_compare(channel->founder_key,
956 client->data.public_key)) {
957 chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
958 silc_server_force_cumode_change(server, sock, channel, chl, mode);
963 if (!silc_pkcs_public_key_compare(channel->founder_key,
965 chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
966 silc_server_force_cumode_change(server, sock, channel, chl, mode);
972 /* There cannot be anyone else as founder on the channel now. This
973 client is definitely the founder due to this authentication */
974 silc_hash_table_list(channel->user_list, &htl);
975 while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
976 if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
977 chl2->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
978 silc_server_force_cumode_change(server, NULL, channel, chl2,
982 silc_hash_table_list_reset(&htl);
985 silc_pkcs_public_key_free(founder_key);
988 if (server->server_type != SILC_SERVER && chl->mode == mode) {
989 SILC_LOG_DEBUG(("Mode is changed already"));
993 SILC_LOG_DEBUG(("Changing %s channel user mode",
994 chl->client->nickname ? chl->client->nickname :
995 (unsigned char *)""));
997 /* Change the mode */
1000 /* Send the same notify to the channel */
1002 silc_server_packet_send_to_channel(server, NULL, channel,
1004 FALSE, packet->buffer->data,
1005 packet->buffer->len, FALSE);
1007 silc_free(channel_id);
1011 case SILC_NOTIFY_TYPE_INVITE:
1013 if (packet->dst_id_type == SILC_ID_CLIENT)
1016 SILC_LOG_DEBUG(("INVITE notify"));
1018 /* Get Channel ID */
1019 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1022 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1026 /* Get channel entry */
1027 channel = silc_idlist_find_channel_by_id(server->global_list,
1030 channel = silc_idlist_find_channel_by_id(server->local_list,
1033 SILC_LOG_DEBUG(("Notify for unknown channel"));
1034 silc_free(channel_id);
1038 silc_free(channel_id);
1041 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1044 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1048 /* Get client entry */
1049 client = silc_idlist_find_client_by_id(server->global_list,
1050 client_id, TRUE, &cache);
1052 client = silc_idlist_find_client_by_id(server->local_list,
1053 client_id, TRUE, &cache);
1055 silc_free(client_id);
1059 silc_free(client_id);
1061 /* Get user's channel entry and check that inviting is allowed. */
1062 if (!silc_server_client_on_channel(client, channel, &chl))
1064 if (channel->mode & SILC_CHANNEL_MODE_INVITE &&
1065 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
1066 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1067 SILC_LOG_DEBUG(("Inviting is not allowed"));
1071 /* Get the invite action */
1072 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
1073 if (tmp && tmp_len == 1) {
1074 SilcUInt8 action = (SilcUInt8)tmp[0];
1075 SilcUInt16 iargc = 0;
1076 SilcArgumentPayload iargs;
1078 /* Get invite list */
1079 tmp = silc_argument_get_arg_type(args, 5, &tmp_len);
1080 if (!tmp || tmp_len < 2)
1083 /* Parse the arguments to see they are constructed correctly */
1084 SILC_GET16_MSB(iargc, tmp);
1085 iargs = silc_argument_payload_parse(tmp + 2, tmp_len - 2, iargc);
1089 if (action == 0 && !channel->invite_list)
1090 channel->invite_list =
1091 silc_hash_table_alloc(0, silc_hash_ptr,
1093 silc_server_inviteban_destruct, channel, TRUE);
1095 /* Proces the invite action */
1096 silc_server_inviteban_process(server, channel->invite_list, action,
1098 silc_argument_payload_free(iargs);
1103 case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
1105 * Distribute to the local clients on the channel and change the
1109 SILC_LOG_DEBUG(("CHANNEL CHANGE"));
1111 if (sock->type != SILC_SOCKET_TYPE_ROUTER)
1114 /* Get the old Channel ID */
1115 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1118 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1122 /* Get the channel entry */
1123 channel = silc_idlist_find_channel_by_id(server->local_list,
1126 channel = silc_idlist_find_channel_by_id(server->global_list,
1129 SILC_LOG_DEBUG(("Notify for unknown channel"));
1130 silc_free(channel_id);
1135 /* Send the notify to the channel */
1136 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
1137 FALSE, packet->buffer->data,
1138 packet->buffer->len, FALSE);
1140 /* Get the new Channel ID */
1141 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1144 channel_id2 = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1148 SILC_LOG_DEBUG(("Old Channel ID id(%s)",
1149 silc_id_render(channel_id, SILC_ID_CHANNEL)));
1150 SILC_LOG_DEBUG(("New Channel ID id(%s)",
1151 silc_id_render(channel_id2, SILC_ID_CHANNEL)));
1153 /* Replace the Channel ID */
1154 if (!silc_idlist_replace_channel_id(server->local_list, channel_id,
1156 if (!silc_idlist_replace_channel_id(server->global_list, channel_id,
1158 silc_free(channel_id2);
1163 SilcBuffer modes = NULL, users = NULL, users_modes = NULL;
1165 /* Re-announce this channel which ID was changed. */
1166 silc_server_send_new_channel(server, sock, FALSE, channel->channel_name,
1168 silc_id_get_len(channel->id,
1172 /* Re-announce our clients on the channel as the ID has changed now */
1173 silc_server_announce_get_channel_users(server, channel, &modes, &users,
1176 silc_buffer_push(users, users->data - users->head);
1177 silc_server_packet_send(server, sock,
1178 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1179 users->data, users->len, FALSE);
1180 silc_buffer_free(users);
1183 silc_buffer_push(modes, modes->data - modes->head);
1184 silc_server_packet_send_dest(server, sock,
1185 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1186 channel->id, SILC_ID_CHANNEL,
1187 modes->data, modes->len, FALSE);
1188 silc_buffer_free(modes);
1191 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
1192 silc_server_packet_send_dest(server, sock,
1193 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1194 channel->id, SILC_ID_CHANNEL,
1196 users_modes->len, FALSE);
1197 silc_buffer_free(users_modes);
1200 /* Re-announce channel's topic */
1201 if (channel->topic) {
1202 silc_server_send_notify_topic_set(server, sock,
1203 server->server_type == SILC_ROUTER ?
1204 TRUE : FALSE, channel,
1205 server->id, SILC_ID_SERVER,
1210 silc_free(channel_id);
1214 case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
1216 * Remove the server entry and all clients that this server owns.
1219 SILC_LOG_DEBUG(("SERVER SIGNOFF notify"));
1222 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1225 server_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1229 /* If the ID is mine, this notify is not allowed. */
1230 if (SILC_ID_SERVER_COMPARE(server_id, server->id)) {
1231 SILC_LOG_DEBUG(("Ignoring my own ID for SERVER_SIGNOFF"));
1235 /* Get server entry */
1236 server_entry = silc_idlist_find_server_by_id(server->global_list,
1237 server_id, TRUE, NULL);
1239 if (!server_entry) {
1240 server_entry = silc_idlist_find_server_by_id(server->local_list,
1241 server_id, TRUE, NULL);
1243 if (!server_entry) {
1244 /* If we are normal server then we might not have the server. Check
1245 whether router was kind enough to send the list of all clients
1246 that actually was to be removed. Remove them if the list is
1248 if (server->server_type != SILC_ROUTER &&
1249 silc_argument_get_arg_num(args) > 1) {
1252 for (i = 1; i < silc_argument_get_arg_num(args); i++) {
1254 tmp = silc_argument_get_arg_type(args, i + 1, &tmp_len);
1257 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1261 /* Get client entry */
1262 client = silc_idlist_find_client_by_id(server->global_list,
1263 client_id, TRUE, &cache);
1266 client = silc_idlist_find_client_by_id(server->local_list,
1267 client_id, TRUE, &cache);
1270 silc_free(client_id);
1274 silc_free(client_id);
1276 /* Update statistics */
1277 server->stat.clients--;
1278 if (server->stat.cell_clients)
1279 server->stat.cell_clients--;
1280 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
1281 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
1283 /* Remove the client from all channels. */
1284 silc_server_remove_from_channels(server, NULL, client,
1285 TRUE, NULL, FALSE, FALSE);
1287 /* Check if anyone is watching this nickname */
1288 if (server->server_type == SILC_ROUTER)
1289 silc_server_check_watcher_list(server, client, NULL,
1290 SILC_NOTIFY_TYPE_SERVER_SIGNOFF);
1292 /* Remove this client from watcher list if it is */
1294 silc_server_del_from_watcher_list(server, client);
1296 /* Remove the client */
1297 silc_idlist_del_data(client);
1298 silc_idlist_del_client(local ? server->local_list :
1299 server->global_list, client);
1303 silc_free(server_id);
1307 silc_free(server_id);
1309 /* For local entrys SERVER_SIGNOFF is processed only on backup router.
1310 It is possible that router sends server signoff for a server. If
1311 backup router has it as local connection it will be closed. */
1312 if (SILC_IS_LOCAL(server_entry) &&
1313 server->server_type == SILC_BACKUP_ROUTER) {
1314 sock = server_entry->connection;
1315 SILC_LOG_DEBUG(("Closing connection %s after SERVER_SIGNOFF",
1317 SILC_SET_DISCONNECTING(sock);
1318 if (sock->user_data)
1319 silc_server_free_sock_user_data(server, sock, NULL);
1320 silc_server_close_connection(server, sock);
1324 /* Remove all servers that are originated from this server, and
1325 remove the clients of those servers too. */
1326 silc_server_remove_servers_by_server(server, server_entry, TRUE);
1328 /* Remove the clients that this server owns as they will become
1330 silc_server_remove_clients_by_server(server, server_entry->router,
1331 server_entry, TRUE);
1332 silc_server_backup_del(server, server_entry);
1334 /* Remove the server entry */
1335 silc_idlist_del_server(local ? server->local_list :
1336 server->global_list, server_entry);
1338 /* Update statistics */
1339 if (server->server_type == SILC_ROUTER)
1340 server->stat.servers--;
1344 case SILC_NOTIFY_TYPE_KICKED:
1346 * Distribute the notify to local clients on the channel
1349 SILC_LOG_DEBUG(("KICKED notify"));
1352 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
1353 packet->dst_id_type);
1358 /* Get channel entry */
1359 channel = silc_idlist_find_channel_by_id(server->global_list,
1362 channel = silc_idlist_find_channel_by_id(server->local_list,
1365 SILC_LOG_DEBUG(("Notify for unknown channel"));
1366 silc_free(channel_id);
1370 silc_free(channel_id);
1373 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1376 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1380 /* If the the client is not in local list we check global list */
1381 client = silc_idlist_find_client_by_id(server->global_list,
1382 client_id, TRUE, NULL);
1384 client = silc_idlist_find_client_by_id(server->local_list,
1385 client_id, TRUE, NULL);
1387 silc_free(client_id);
1391 silc_free(client_id);
1393 /* If target is founder they cannot be kicked */
1394 if (!silc_server_client_on_channel(client, channel, &chl))
1396 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO)
1399 /* Get the kicker's Client ID */
1400 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1403 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1407 /* If the the client is not in local list we check global list */
1408 client2 = silc_idlist_find_client_by_id(server->global_list,
1409 client_id, TRUE, NULL);
1411 client2 = silc_idlist_find_client_by_id(server->local_list,
1412 client_id, TRUE, NULL);
1414 silc_free(client_id);
1418 silc_free(client_id);
1420 /* Kicker must be operator on channel */
1421 if (!silc_server_client_on_channel(client2, channel, &chl))
1423 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
1424 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1425 SILC_LOG_DEBUG(("Kicking is not allowed"));
1429 /* Send to channel */
1430 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
1431 FALSE, packet->buffer->data,
1432 packet->buffer->len, FALSE);
1434 /* Remove the client from channel's invite list */
1435 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
1437 SilcArgumentPayload iargs;
1438 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1439 ab = silc_argument_payload_encode_one(NULL, tmp, tmp_len, 3);
1440 iargs = silc_argument_payload_parse(ab->data, ab->len, 1);
1441 silc_server_inviteban_process(server, channel->invite_list, 1, iargs);
1442 silc_buffer_free(ab);
1443 silc_argument_payload_free(iargs);
1446 /* Remove the client from channel */
1447 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
1451 case SILC_NOTIFY_TYPE_KILLED:
1454 * Distribute the notify to local clients on channels
1456 unsigned char *id, *comment;
1457 SilcUInt32 id_len, comment_len;
1459 SILC_LOG_DEBUG(("KILLED notify"));
1462 id = silc_argument_get_arg_type(args, 1, &id_len);
1465 client_id = silc_id_payload_parse_id(id, id_len, NULL);
1469 /* If the the client is not in local list we check global list */
1470 client = silc_idlist_find_client_by_id(server->global_list,
1471 client_id, TRUE, &cache);
1473 client = silc_idlist_find_client_by_id(server->local_list,
1474 client_id, TRUE, &cache);
1476 silc_free(client_id);
1480 silc_free(client_id);
1482 /* If the client is one of ours, then close the connection to the
1483 client now. This removes the client from all channels as well. */
1484 if (packet->dst_id_type == SILC_ID_CLIENT && client->connection) {
1485 sock = client->connection;
1486 silc_server_free_client_data(server, NULL, client, FALSE, NULL);
1487 silc_server_close_connection(server, sock);
1492 comment = silc_argument_get_arg_type(args, 2, &comment_len);
1493 if (comment_len > 128)
1496 /* Get the killer's Client ID */
1497 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1500 client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
1504 if (id_type == SILC_ID_CLIENT) {
1505 /* If the the client is not in local list we check global list */
1506 client2 = silc_idlist_find_client_by_id(server->global_list,
1507 client_id, TRUE, NULL);
1509 client2 = silc_idlist_find_client_by_id(server->local_list,
1510 client_id, TRUE, NULL);
1512 silc_free(client_id);
1516 silc_free(client_id);
1518 /* Killer must be router operator */
1519 if (server->server_type != SILC_SERVER &&
1520 !(client2->mode & SILC_UMODE_ROUTER_OPERATOR)) {
1521 SILC_LOG_DEBUG(("Killing is not allowed"));
1526 /* Send the notify to local clients on the channels except to the
1527 client who is killed. */
1528 silc_server_send_notify_on_channels(server, client, client,
1529 SILC_NOTIFY_TYPE_KILLED, 3,
1530 id, id_len, comment, comment_len,
1533 /* Remove the client from all channels */
1534 silc_server_remove_from_channels(server, NULL, client, FALSE, NULL,
1537 /* Check if anyone is watching this nickname */
1538 silc_server_check_watcher_list(server, client, NULL,
1539 SILC_NOTIFY_TYPE_KILLED);
1541 /* Update statistics */
1542 server->stat.clients--;
1543 if (server->stat.cell_clients)
1544 server->stat.cell_clients--;
1545 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
1546 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
1548 if (SILC_IS_LOCAL(client)) {
1549 server->stat.my_clients--;
1550 silc_schedule_task_del_by_context(server->schedule, client);
1551 silc_idlist_del_data(client);
1555 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
1556 cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
1560 case SILC_NOTIFY_TYPE_UMODE_CHANGE:
1562 * Save the mode of the client.
1565 SILC_LOG_DEBUG(("UMODE_CHANGE notify"));
1568 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1571 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1575 /* Get client entry */
1576 client = silc_idlist_find_client_by_id(server->global_list,
1577 client_id, TRUE, NULL);
1579 client = silc_idlist_find_client_by_id(server->local_list,
1580 client_id, TRUE, NULL);
1582 silc_free(client_id);
1586 silc_free(client_id);
1589 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1592 SILC_GET32_MSB(mode, tmp);
1594 /* Remove internal resumed flag if client is marked detached now */
1595 if (mode & SILC_UMODE_DETACHED)
1596 client->data.status &= ~SILC_IDLIST_STATUS_RESUMED;
1598 /* Update statistics */
1599 if (server->server_type == SILC_ROUTER) {
1600 if (mode & SILC_UMODE_GONE) {
1601 if (!(client->mode & SILC_UMODE_GONE))
1602 server->stat.aways++;
1604 if (client->mode & SILC_UMODE_GONE)
1605 server->stat.aways--;
1607 if (mode & SILC_UMODE_DETACHED) {
1608 if (!(client->mode & SILC_UMODE_DETACHED))
1609 server->stat.detached++;
1611 if (client->mode & SILC_UMODE_DETACHED)
1612 server->stat.detached--;
1615 SILC_UMODE_STATS_UPDATE(server, SILC_UMODE_SERVER_OPERATOR);
1616 SILC_UMODE_STATS_UPDATE(router, SILC_UMODE_ROUTER_OPERATOR);
1618 /* Change the mode */
1619 client->mode = mode;
1621 /* Check if anyone is watching this nickname */
1622 if (server->server_type == SILC_ROUTER)
1623 silc_server_check_watcher_list(server, client, NULL,
1624 SILC_NOTIFY_TYPE_UMODE_CHANGE);
1628 case SILC_NOTIFY_TYPE_BAN:
1633 SILC_LOG_DEBUG(("BAN notify"));
1635 /* Get Channel ID */
1636 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1639 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1643 /* Get channel entry */
1644 channel = silc_idlist_find_channel_by_id(server->global_list,
1647 channel = silc_idlist_find_channel_by_id(server->local_list,
1650 SILC_LOG_DEBUG(("Notify for unknown channel"));
1651 silc_free(channel_id);
1655 silc_free(channel_id);
1657 /* Get the ban action */
1658 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1659 if (tmp && tmp_len == 1) {
1660 SilcUInt8 action = (SilcUInt8)tmp[0];
1661 SilcUInt16 iargc = 0;
1662 SilcArgumentPayload iargs;
1665 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1666 if (!tmp || tmp_len < 2)
1669 /* Parse the arguments to see they are constructed correctly */
1670 SILC_GET16_MSB(iargc, tmp);
1671 iargs = silc_argument_payload_parse(tmp + 2, tmp_len - 2, iargc);
1675 if (action == 0 && !channel->ban_list)
1677 silc_hash_table_alloc(0, silc_hash_ptr,
1679 silc_server_inviteban_destruct, channel, TRUE);
1681 /* Proces the ban action */
1682 silc_server_inviteban_process(server, channel->ban_list, action,
1684 silc_argument_payload_free(iargs);
1688 case SILC_NOTIFY_TYPE_ERROR:
1695 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1696 if (!tmp && tmp_len != 1)
1698 error = (SilcStatus)tmp[0];
1700 SILC_LOG_DEBUG(("ERROR notify (%d)", error));
1702 if (error == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID &&
1703 sock->type == SILC_SOCKET_TYPE_ROUTER) {
1704 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1706 SILC_LOG_DEBUG(("Received invalid client ID notification, deleting "
1707 "the entry from cache"));
1708 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1711 client = silc_idlist_find_client_by_id(server->global_list,
1712 client_id, FALSE, NULL);
1714 silc_server_remove_from_channels(server, NULL, client, TRUE,
1716 silc_idlist_del_data(client);
1717 silc_idlist_del_client(server->global_list, client);
1719 silc_free(client_id);
1725 /* Ignore rest of the notify types for now */
1726 case SILC_NOTIFY_TYPE_NONE:
1727 case SILC_NOTIFY_TYPE_MOTD:
1734 silc_notify_payload_free(payload);
1737 void silc_server_notify_list(SilcServer server,
1738 SilcSocketConnection sock,
1739 SilcPacketContext *packet)
1741 SilcPacketContext *new;
1745 SILC_LOG_DEBUG(("Processing Notify List"));
1747 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1748 packet->src_id_type != SILC_ID_SERVER)
1751 /* Make copy of the original packet context, except for the actual
1752 data buffer, which we will here now fetch from the original buffer. */
1753 new = silc_packet_context_alloc();
1754 new->type = SILC_PACKET_NOTIFY;
1755 new->flags = packet->flags;
1756 new->src_id = packet->src_id;
1757 new->src_id_len = packet->src_id_len;
1758 new->src_id_type = packet->src_id_type;
1759 new->dst_id = packet->dst_id;
1760 new->dst_id_len = packet->dst_id_len;
1761 new->dst_id_type = packet->dst_id_type;
1763 buffer = silc_buffer_alloc(1024);
1764 new->buffer = buffer;
1766 while (packet->buffer->len) {
1767 SILC_GET16_MSB(len, packet->buffer->data + 2);
1768 if (len > packet->buffer->len)
1771 if (len > buffer->truelen) {
1772 silc_buffer_free(buffer);
1773 buffer = silc_buffer_alloc(1024 + len);
1776 silc_buffer_pull_tail(buffer, len);
1777 silc_buffer_put(buffer, packet->buffer->data, len);
1779 /* Process the Notify */
1780 silc_server_notify(server, sock, new);
1782 silc_buffer_push_tail(buffer, len);
1783 silc_buffer_pull(packet->buffer, len);
1786 silc_buffer_free(buffer);
1790 /* Received private message. This resolves the destination of the message
1791 and sends the packet. This is used by both server and router. If the
1792 destination is our locally connected client this sends the packet to
1793 the client. This may also send the message for further routing if
1794 the destination is not in our server (or router). */
1796 void silc_server_private_message(SilcServer server,
1797 SilcSocketConnection sock,
1798 SilcPacketContext *packet)
1800 SilcSocketConnection dst_sock;
1801 SilcIDListData idata;
1802 SilcClientEntry client;
1804 SILC_LOG_DEBUG(("Start"));
1806 if (packet->src_id_type != SILC_ID_CLIENT ||
1807 packet->dst_id_type != SILC_ID_CLIENT || !packet->dst_id)
1810 /* Get the route to the client */
1811 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1812 packet->dst_id_len, NULL,
1816 unsigned char error;
1818 if (client && client->mode & SILC_UMODE_DETACHED) {
1819 SILC_LOG_DEBUG(("Client is detached, discarding packet"));
1823 /* Send SILC_NOTIFY_TYPE_ERROR to indicate that such destination ID
1824 does not exist or is invalid. */
1825 idp = silc_id_payload_encode_data(packet->dst_id,
1827 packet->dst_id_type);
1831 error = SILC_STATUS_ERR_NO_SUCH_CLIENT_ID;
1832 if (packet->src_id_type == SILC_ID_CLIENT) {
1833 SilcClientID *client_id = silc_id_str2id(packet->src_id,
1835 packet->src_id_type);
1836 silc_server_send_notify_dest(server, sock, FALSE,
1837 client_id, SILC_ID_CLIENT,
1838 SILC_NOTIFY_TYPE_ERROR, 2,
1840 idp->data, idp->len);
1841 silc_free(client_id);
1843 silc_server_send_notify(server, sock, FALSE,
1844 SILC_NOTIFY_TYPE_ERROR, 2,
1846 idp->data, idp->len);
1849 silc_buffer_free(idp);
1853 /* Check whether destination client wishes to receive private messages */
1854 if (client && !(packet->flags & SILC_PACKET_FLAG_PRIVMSG_KEY) &&
1855 client->mode & SILC_UMODE_BLOCK_PRIVMSG) {
1856 SILC_LOG_DEBUG(("Client blocks private messages, discarding packet"));
1860 /* Send the private message */
1861 silc_server_send_private_message(server, dst_sock, idata->send_key,
1862 idata->hmac_send, idata->psn_send++,
1866 /* Received private message key packet.. This packet is never for us. It is to
1867 the client in the packet's destination ID. Sending of this sort of packet
1868 equals sending private message, ie. it is sent point to point from
1869 one client to another. */
1871 void silc_server_private_message_key(SilcServer server,
1872 SilcSocketConnection sock,
1873 SilcPacketContext *packet)
1875 SilcSocketConnection dst_sock;
1876 SilcIDListData idata;
1878 SILC_LOG_DEBUG(("Start"));
1880 if (packet->src_id_type != SILC_ID_CLIENT ||
1881 packet->dst_id_type != SILC_ID_CLIENT)
1884 if (!packet->dst_id)
1887 /* Get the route to the client */
1888 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1889 packet->dst_id_len, NULL,
1894 /* Relay the packet */
1895 silc_server_relay_packet(server, dst_sock, idata->send_key,
1896 idata->hmac_send, idata->psn_send++, packet, FALSE);
1899 /* Processes incoming command reply packet. The command reply packet may
1900 be destined to one of our clients or it may directly for us. We will
1901 call the command reply routine after processing the packet. */
1903 void silc_server_command_reply(SilcServer server,
1904 SilcSocketConnection sock,
1905 SilcPacketContext *packet)
1907 SilcBuffer buffer = packet->buffer;
1908 SilcClientEntry client = NULL;
1909 SilcSocketConnection dst_sock;
1910 SilcIDListData idata;
1911 SilcClientID *id = NULL;
1913 SILC_LOG_DEBUG(("Start"));
1915 if (packet->dst_id_type == SILC_ID_CHANNEL)
1918 if (packet->dst_id_type == SILC_ID_CLIENT) {
1919 /* Destination must be one of ours */
1920 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
1923 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
1925 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
1931 if (packet->dst_id_type == SILC_ID_SERVER) {
1932 /* For now this must be for us */
1933 if (memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
1934 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
1939 /* Execute command reply locally for the command */
1940 silc_server_command_reply_process(server, sock, buffer);
1942 if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
1943 /* Relay the packet to the client */
1944 const SilcBufferStruct p;
1946 dst_sock = (SilcSocketConnection)client->connection;
1947 idata = (SilcIDListData)client;
1949 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
1950 + packet->dst_id_len + packet->padlen);
1951 if (!silc_packet_send_prepare(dst_sock, 0, 0, buffer->len,
1952 idata->hmac_send, (const SilcBuffer)&p)) {
1953 SILC_LOG_ERROR(("Cannot send packet"));
1956 silc_buffer_put((SilcBuffer)&p, buffer->data, buffer->len);
1958 /* Encrypt packet */
1959 silc_packet_encrypt(idata->send_key, idata->hmac_send, idata->psn_send++,
1960 (SilcBuffer)&p, buffer->len);
1962 /* Send the packet */
1963 silc_server_packet_send_real(server, dst_sock, TRUE);
1969 /* Process received channel message. The message can be originated from
1970 client or server. */
1972 void silc_server_channel_message(SilcServer server,
1973 SilcSocketConnection sock,
1974 SilcPacketContext *packet)
1976 SilcChannelEntry channel = NULL;
1977 SilcChannelID *id = NULL;
1978 void *sender_id = NULL;
1979 SilcClientEntry sender_entry = NULL;
1980 SilcChannelClientEntry chl;
1983 SILC_LOG_DEBUG(("Processing channel message"));
1986 if (packet->dst_id_type != SILC_ID_CHANNEL) {
1987 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1991 /* Find channel entry */
1992 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
1995 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
1997 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
2000 unsigned char error;
2002 /* Send SILC_NOTIFY_TYPE_ERROR to indicate that such destination ID
2003 does not exist or is invalid. */
2004 idp = silc_id_payload_encode_data(packet->dst_id,
2006 packet->dst_id_type);
2010 error = SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID;
2011 if (packet->src_id_type == SILC_ID_CLIENT) {
2012 SilcClientID *client_id = silc_id_str2id(packet->src_id,
2014 packet->src_id_type);
2015 silc_server_send_notify_dest(server, sock, FALSE,
2016 client_id, SILC_ID_CLIENT,
2017 SILC_NOTIFY_TYPE_ERROR, 2,
2018 &error, 1, idp->data, idp->len);
2019 silc_free(client_id);
2021 silc_server_send_notify(server, sock, FALSE,
2022 SILC_NOTIFY_TYPE_ERROR, 2,
2023 &error, 1, idp->data, idp->len);
2026 silc_buffer_free(idp);
2031 /* See that this client is on the channel. If the original sender is
2032 not client (as it can be server as well) we don't do the check. */
2033 sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2034 packet->src_id_type);
2037 if (packet->src_id_type == SILC_ID_CLIENT) {
2038 sender_entry = silc_idlist_find_client_by_id(server->local_list,
2039 sender_id, TRUE, NULL);
2040 if (!sender_entry) {
2042 sender_entry = silc_idlist_find_client_by_id(server->global_list,
2043 sender_id, TRUE, NULL);
2045 if (!sender_entry || !silc_server_client_on_channel(sender_entry,
2047 SILC_LOG_DEBUG(("Client not on channel"));
2051 /* If channel is moderated check that client is allowed to send
2053 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS &&
2054 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
2055 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
2056 SILC_LOG_DEBUG(("Channel is silenced from normal users"));
2059 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS &&
2060 chl->mode & SILC_CHANNEL_UMODE_CHANOP &&
2061 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
2062 SILC_LOG_DEBUG(("Channel is silenced from operators"));
2065 if (chl->mode & SILC_CHANNEL_UMODE_QUIET) {
2066 SILC_LOG_DEBUG(("Sender is quieted on the channel"));
2070 /* If the packet is coming from router, but the client entry is local
2071 entry to us then some router is rerouting this to us and it is not
2072 allowed. When the client is local to us it means that we've routed
2073 this packet to network, and now someone is routing it back to us. */
2074 if (server->server_type == SILC_ROUTER &&
2075 sock->type == SILC_SOCKET_TYPE_ROUTER && local) {
2076 SILC_LOG_DEBUG(("Channel message rerouted to the sender, drop it"));
2081 /* Distribute the packet to our local clients. This will send the
2082 packet for further routing as well, if needed. */
2083 silc_server_packet_relay_to_channel(server, sock, channel, sender_id,
2084 packet->src_id_type, sender_entry,
2085 packet->buffer->data,
2086 packet->buffer->len, FALSE);
2089 silc_free(sender_id);
2093 /* Received channel key packet. We distribute the key to all of our locally
2094 connected clients on the channel. */
2096 void silc_server_channel_key(SilcServer server,
2097 SilcSocketConnection sock,
2098 SilcPacketContext *packet)
2100 SilcBuffer buffer = packet->buffer;
2101 SilcChannelEntry channel;
2103 if (packet->src_id_type != SILC_ID_SERVER ||
2104 (server->server_type == SILC_ROUTER && !server->backup_router &&
2105 sock->type == SILC_SOCKET_TYPE_ROUTER))
2108 /* Save the channel key */
2109 channel = silc_server_save_channel_key(server, buffer, NULL);
2111 SILC_LOG_ERROR(("Bad channel key from %s (%s)",
2112 sock->hostname, sock->ip));
2116 /* Distribute the key to everybody who is on the channel. If we are router
2117 we will also send it to locally connected servers. */
2118 silc_server_send_channel_key(server, sock, channel, FALSE);
2120 if (server->server_type != SILC_BACKUP_ROUTER) {
2121 /* Distribute to local cell backup routers. */
2122 silc_server_backup_send(server, sock->user_data,
2123 SILC_PACKET_CHANNEL_KEY, 0,
2124 buffer->data, buffer->len, FALSE, TRUE);
2128 /* Received New Client packet and processes it. Creates Client ID for the
2129 client. Client becomes registered after calling this functions. */
2131 SilcClientEntry silc_server_new_client(SilcServer server,
2132 SilcSocketConnection sock,
2133 SilcPacketContext *packet)
2135 SilcBuffer buffer = packet->buffer;
2136 SilcClientEntry client;
2137 SilcClientID *client_id;
2138 SilcIDListData idata;
2139 char *username = NULL, *realname = NULL;
2140 SilcUInt16 username_len;
2143 char *hostname, *nickname;
2146 SILC_LOG_DEBUG(("Creating new client"));
2148 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
2151 /* Take client entry */
2152 client = (SilcClientEntry)sock->user_data;
2153 idata = (SilcIDListData)client;
2155 /* Remove the old cache entry. */
2156 if (!silc_idcache_del_by_context(server->local_list->clients, client)) {
2157 SILC_LOG_INFO(("Unauthenticated client attempted to register to network"));
2158 silc_server_disconnect_remote(server, sock,
2159 SILC_STATUS_ERR_NOT_AUTHENTICATED, NULL);
2160 if (sock->user_data)
2161 silc_server_free_sock_user_data(server, sock, NULL);
2165 /* Parse incoming packet */
2166 ret = silc_buffer_unformat(buffer,
2167 SILC_STR_UI16_NSTRING_ALLOC(&username,
2169 SILC_STR_UI16_STRING_ALLOC(&realname),
2172 silc_free(username);
2173 silc_free(realname);
2174 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2175 "connection", sock->hostname, sock->ip));
2176 silc_server_disconnect_remote(server, sock,
2177 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2179 if (sock->user_data)
2180 silc_server_free_sock_user_data(server, sock, NULL);
2185 silc_free(username);
2186 silc_free(realname);
2187 SILC_LOG_ERROR(("Client %s (%s) did not send its username, closing "
2188 "connection", sock->hostname, sock->ip));
2189 silc_server_disconnect_remote(server, sock,
2190 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2192 if (sock->user_data)
2193 silc_server_free_sock_user_data(server, sock, NULL);
2197 if (username_len > 128)
2198 username[128] = '\0';
2200 /* Check for bad characters for nickname, and modify the nickname if
2201 it includes those. */
2202 if (silc_server_name_bad_chars(username, username_len)) {
2203 nickname = silc_server_name_modify_bad(username, username_len);
2205 nickname = strdup(username);
2208 /* Make sanity checks for the hostname of the client. If the hostname
2209 is provided in the `username' check that it is the same than the
2210 resolved hostname, or if not resolved the hostname that appears in
2211 the client's public key. If the hostname is not present then put
2212 it from the resolved name or from the public key. */
2213 if (strchr(username, '@')) {
2214 SilcPublicKeyIdentifier pident;
2215 int tlen = strcspn(username, "@");
2216 char *phostname = NULL;
2218 hostname = silc_memdup(username + tlen + 1, strlen(username) - tlen - 1);
2220 if (strcmp(sock->hostname, sock->ip) &&
2221 strcmp(sock->hostname, hostname)) {
2222 silc_free(username);
2223 silc_free(hostname);
2224 silc_free(realname);
2225 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2226 "connection", sock->hostname, sock->ip));
2227 silc_server_disconnect_remote(server, sock,
2228 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2230 if (sock->user_data)
2231 silc_server_free_sock_user_data(server, sock, NULL);
2235 pident = silc_pkcs_decode_identifier(client->data.public_key->identifier);
2237 phostname = strdup(pident->host);
2238 silc_pkcs_free_identifier(pident);
2241 if (!strcmp(sock->hostname, sock->ip) &&
2242 phostname && strcmp(phostname, hostname)) {
2243 silc_free(username);
2244 silc_free(hostname);
2245 silc_free(phostname);
2246 silc_free(realname);
2247 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2248 "connection", sock->hostname, sock->ip));
2249 silc_server_disconnect_remote(server, sock,
2250 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2252 if (sock->user_data)
2253 silc_server_free_sock_user_data(server, sock, NULL);
2257 silc_free(phostname);
2259 /* The hostname is not present, add it. */
2261 /* XXX For now we cannot take the host name from the public key since
2262 they are not trusted or we cannot verify them as trusted. Just take
2263 what the resolved name or address is. */
2265 if (strcmp(sock->hostname, sock->ip)) {
2267 newusername = silc_calloc(strlen(username) +
2268 strlen(sock->hostname) + 2,
2269 sizeof(*newusername));
2270 strncat(newusername, username, strlen(username));
2271 strncat(newusername, "@", 1);
2272 strncat(newusername, sock->hostname, strlen(sock->hostname));
2273 silc_free(username);
2274 username = newusername;
2277 SilcPublicKeyIdentifier pident =
2278 silc_pkcs_decode_identifier(client->data.public_key->identifier);
2281 newusername = silc_calloc(strlen(username) +
2282 strlen(pident->host) + 2,
2283 sizeof(*newusername));
2284 strncat(newusername, username, strlen(username));
2285 strncat(newusername, "@", 1);
2286 strncat(newusername, pident->host, strlen(pident->host));
2287 silc_free(username);
2288 username = newusername;
2289 silc_pkcs_free_identifier(pident);
2295 /* Create Client ID */
2296 while (!silc_id_create_client_id(server, server->id, server->rng,
2297 server->md5hash, nickname, &client_id)) {
2300 silc_server_disconnect_remote(server, sock,
2301 SILC_STATUS_ERR_BAD_NICKNAME, NULL);
2302 if (sock->user_data)
2303 silc_server_free_sock_user_data(server, sock, NULL);
2306 snprintf(&nickname[strlen(nickname) - 1], 1, "%d", nickfail);
2309 /* If client marked as anonymous, scramble the username and hostname */
2310 if (client->mode & SILC_UMODE_ANONYMOUS) {
2313 if (strlen(username) >= 2) {
2314 username[0] = silc_rng_get_byte_fast(server->rng);
2315 username[1] = silc_rng_get_byte_fast(server->rng);
2318 scramble = silc_hash_babbleprint(server->sha1hash, username,
2322 memcpy(&scramble[16], ".silc", 5);
2323 scramble[21] = '\0';
2324 silc_free(username);
2325 username = scramble;
2328 /* Update client entry */
2329 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
2330 client->nickname = nickname;
2331 client->username = username;
2332 client->userinfo = realname ? realname : strdup(username);
2333 client->id = client_id;
2334 id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
2336 /* Add the client again to the ID cache */
2337 silc_idcache_add(server->local_list->clients, client->nickname,
2338 client_id, client, 0, NULL);
2340 /* Notify our router about new client on the SILC network */
2341 silc_server_send_new_id(server, SILC_PRIMARY_ROUTE(server),
2342 SILC_BROADCAST(server), client->id,
2343 SILC_ID_CLIENT, id_len);
2345 /* Distribute to backup routers */
2346 if (server->server_type == SILC_ROUTER) {
2347 SilcBuffer idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
2348 silc_server_backup_send(server, sock->user_data, SILC_PACKET_NEW_ID, 0,
2349 idp->data, idp->len, FALSE, TRUE);
2350 silc_buffer_free(idp);
2353 /* Send the new client ID to the client. */
2354 silc_server_send_new_id(server, sock, FALSE, client->id, SILC_ID_CLIENT,
2355 silc_id_get_len(client->id, SILC_ID_CLIENT));
2357 /* Send some nice info to the client */
2358 silc_server_send_connect_notifys(server, sock, client);
2360 /* Check if anyone is watching this nickname */
2361 if (server->server_type == SILC_ROUTER)
2362 silc_server_check_watcher_list(server, client, NULL, 0);
2367 /* Create new server. This processes received New Server packet and
2368 saves the received Server ID. The server is our locally connected
2369 server thus we save all the information and save it to local list.
2370 This funtion can be used by both normal server and router server.
2371 If normal server uses this it means that its router has connected
2372 to the server. If router uses this it means that one of the cell's
2373 servers is connected to the router. */
2375 SilcServerEntry silc_server_new_server(SilcServer server,
2376 SilcSocketConnection sock,
2377 SilcPacketContext *packet)
2379 SilcBuffer buffer = packet->buffer;
2380 SilcServerEntry new_server, server_entry;
2381 SilcServerID *server_id;
2382 SilcIDListData idata;
2383 unsigned char *server_name, *id_string;
2384 SilcUInt16 id_len, name_len;
2388 SILC_LOG_DEBUG(("Creating new server"));
2390 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
2391 sock->type != SILC_SOCKET_TYPE_ROUTER)
2394 /* Take server entry */
2395 new_server = (SilcServerEntry)sock->user_data;
2396 idata = (SilcIDListData)new_server;
2398 /* Remove the old cache entry */
2399 if (!silc_idcache_del_by_context(server->local_list->servers, new_server)) {
2400 if (!silc_idcache_del_by_context(server->global_list->servers,
2402 SILC_LOG_INFO(("Unauthenticated %s attempted to register to "
2403 "network", (sock->type == SILC_SOCKET_TYPE_SERVER ?
2404 "server" : "router")));
2405 silc_server_disconnect_remote(server, sock,
2406 SILC_STATUS_ERR_NOT_AUTHENTICATED, NULL);
2407 if (sock->user_data)
2408 silc_server_free_sock_user_data(server, sock, NULL);
2414 /* Parse the incoming packet */
2415 ret = silc_buffer_unformat(buffer,
2416 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
2417 SILC_STR_UI16_NSTRING_ALLOC(&server_name,
2421 silc_free(id_string);
2422 silc_free(server_name);
2423 silc_server_disconnect_remote(server, sock,
2424 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2426 if (sock->user_data)
2427 silc_server_free_sock_user_data(server, sock, NULL);
2431 if (id_len > buffer->len) {
2432 silc_free(id_string);
2433 silc_free(server_name);
2434 silc_server_disconnect_remote(server, sock,
2435 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2437 if (sock->user_data)
2438 silc_server_free_sock_user_data(server, sock, NULL);
2443 server_name[255] = '\0';
2446 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
2448 silc_free(id_string);
2449 silc_free(server_name);
2450 silc_server_disconnect_remote(server, sock,
2451 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2453 if (sock->user_data)
2454 silc_server_free_sock_user_data(server, sock, NULL);
2457 silc_free(id_string);
2459 /* Check for valid server ID */
2460 if (!silc_id_is_valid_server_id(server, server_id, sock)) {
2461 SILC_LOG_INFO(("Invalid server ID sent by %s (%s)",
2462 sock->ip, sock->hostname));
2463 silc_server_disconnect_remote(server, sock,
2464 SILC_STATUS_ERR_BAD_SERVER_ID, NULL);
2465 if (sock->user_data)
2466 silc_server_free_sock_user_data(server, sock, NULL);
2467 silc_free(server_name);
2471 /* Check that we do not have this ID already */
2472 server_entry = silc_idlist_find_server_by_id(server->local_list,
2473 server_id, TRUE, NULL);
2475 silc_idcache_del_by_context(server->local_list->servers, server_entry);
2477 server_entry = silc_idlist_find_server_by_id(server->global_list,
2478 server_id, TRUE, NULL);
2480 silc_idcache_del_by_context(server->global_list->servers, server_entry);
2483 /* Update server entry */
2484 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
2485 new_server->server_name = server_name;
2486 new_server->id = server_id;
2488 SILC_LOG_DEBUG(("New server id(%s)",
2489 silc_id_render(server_id, SILC_ID_SERVER)));
2491 /* Add again the entry to the ID cache. */
2492 silc_idcache_add(local ? server->local_list->servers :
2493 server->global_list->servers, server_name, server_id,
2494 new_server, 0, NULL);
2496 /* Distribute the information about new server in the SILC network
2497 to our router. If we are normal server we won't send anything
2498 since this connection must be our router connection. */
2499 if (server->server_type == SILC_ROUTER && !server->standalone &&
2500 SILC_PRIMARY_ROUTE(server) != sock)
2501 silc_server_send_new_id(server, SILC_PRIMARY_ROUTE(server),
2502 TRUE, new_server->id, SILC_ID_SERVER,
2503 silc_id_get_len(server_id, SILC_ID_SERVER));
2505 if (server->server_type == SILC_ROUTER) {
2506 /* Distribute to backup routers */
2507 SilcBuffer idp = silc_id_payload_encode(new_server->id, SILC_ID_SERVER);
2508 silc_server_backup_send(server, sock->user_data, SILC_PACKET_NEW_ID, 0,
2509 idp->data, idp->len, FALSE, TRUE);
2510 silc_buffer_free(idp);
2513 server->stat.cell_servers++;
2516 /* Check whether this router connection has been replaced by an
2517 backup router. If it has been then we'll disable the server and will
2518 ignore everything it will send until the backup router resuming
2519 protocol has been completed. */
2520 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
2521 silc_server_backup_replaced_get(server, server_id, NULL)) {
2522 /* Send packet to the server indicating that it cannot use this
2523 connection as it has been replaced by backup router. */
2524 SilcBuffer packet = silc_buffer_alloc(2);
2525 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
2526 silc_buffer_format(packet,
2527 SILC_STR_UI_CHAR(SILC_SERVER_BACKUP_REPLACED),
2528 SILC_STR_UI_CHAR(0),
2530 silc_server_packet_send(server, sock,
2531 SILC_PACKET_RESUME_ROUTER, 0,
2532 packet->data, packet->len, TRUE);
2533 silc_buffer_free(packet);
2535 /* Mark the router disabled. The data sent earlier will go but nothing
2536 after this does not go to this connection. */
2537 idata->status |= SILC_IDLIST_STATUS_DISABLED;
2539 /* If it is router announce our stuff to it. */
2540 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
2541 server->server_type == SILC_ROUTER) {
2542 silc_server_announce_servers(server, FALSE, 0, sock);
2543 silc_server_announce_clients(server, 0, sock);
2544 silc_server_announce_channels(server, 0, sock);
2547 /* Announce our information to backup router */
2548 if (new_server->server_type == SILC_BACKUP_ROUTER &&
2549 sock->type == SILC_SOCKET_TYPE_SERVER &&
2550 server->server_type == SILC_ROUTER) {
2551 silc_server_announce_servers(server, TRUE, 0, sock);
2552 silc_server_announce_clients(server, 0, sock);
2553 silc_server_announce_channels(server, 0, sock);
2556 /* If backup router, mark it as one of ours. This server is considered
2557 to be backup router after this setting. */
2558 if (new_server->server_type == SILC_BACKUP_ROUTER) {
2559 SilcServerConfigRouter *backup;
2560 backup = silc_server_config_find_backup_conn(server, sock->ip);
2562 backup = silc_server_config_find_backup_conn(server, sock->hostname);
2564 /* Add as our backup router */
2565 silc_server_backup_add(server, new_server, backup->backup_replace_ip,
2566 backup->backup_replace_port,
2567 backup->backup_local);
2571 /* By default the servers connected to backup router are disabled
2572 until backup router has become the primary */
2573 if (server->server_type == SILC_BACKUP_ROUTER &&
2574 sock->type == SILC_SOCKET_TYPE_SERVER)
2575 idata->status |= SILC_IDLIST_STATUS_DISABLED;
2581 /* Processes incoming New ID packet. New ID Payload is used to distribute
2582 information about newly registered clients and servers. */
2584 static void silc_server_new_id_real(SilcServer server,
2585 SilcSocketConnection sock,
2586 SilcPacketContext *packet,
2589 SilcBuffer buffer = packet->buffer;
2591 SilcServerEntry router, server_entry;
2592 SilcSocketConnection router_sock;
2597 SILC_LOG_DEBUG(("Processing new ID"));
2599 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2600 server->server_type == SILC_SERVER ||
2601 packet->src_id_type != SILC_ID_SERVER)
2604 idp = silc_id_payload_parse(buffer->data, buffer->len);
2608 id_type = silc_id_payload_get_type(idp);
2610 /* Normal server cannot have other normal server connections */
2611 server_entry = (SilcServerEntry)sock->user_data;
2612 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER &&
2613 server_entry->server_type == SILC_SERVER)
2616 id = silc_id_payload_get_id(idp);
2620 /* If the packet is coming from server then use the sender as the
2621 origin of the the packet. If it came from router then check the real
2622 sender of the packet and use that as the origin. */
2623 if (sock->type == SILC_SOCKET_TYPE_SERVER) {
2624 id_list = server->local_list;
2626 router = sock->user_data;
2628 /* If the sender is backup router and ID is server (and we are not
2629 backup router) then switch the entry to global list. */
2630 if (server_entry->server_type == SILC_BACKUP_ROUTER &&
2631 id_type == SILC_ID_SERVER &&
2632 server->id_entry->server_type != SILC_BACKUP_ROUTER) {
2633 id_list = server->global_list;
2634 router_sock = server->router ? SILC_PRIMARY_ROUTE(server) : sock;
2637 void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2638 packet->src_id_type);
2639 router = silc_idlist_find_server_by_id(server->global_list,
2640 sender_id, TRUE, NULL);
2642 router = silc_idlist_find_server_by_id(server->local_list,
2643 sender_id, TRUE, NULL);
2644 silc_free(sender_id);
2646 id_list = server->global_list;
2653 case SILC_ID_CLIENT:
2655 SilcClientEntry entry;
2657 /* Check that we do not have this client already */
2658 entry = silc_idlist_find_client_by_id(server->global_list,
2659 id, server->server_type,
2662 entry = silc_idlist_find_client_by_id(server->local_list,
2663 id, server->server_type,
2666 SILC_LOG_DEBUG(("Ignoring client that we already have"));
2670 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
2671 silc_id_render(id, SILC_ID_CLIENT),
2672 sock->type == SILC_SOCKET_TYPE_SERVER ?
2673 "Server" : "Router", sock->hostname));
2675 /* As a router we keep information of all global information in our
2676 global list. Cell wide information however is kept in the local
2678 entry = silc_idlist_add_client(id_list, NULL, NULL, NULL,
2679 id, router, NULL, 0);
2681 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
2683 /* Inform the sender that the ID is not usable */
2684 silc_server_send_notify_signoff(server, sock, FALSE, id, NULL);
2687 entry->nickname = NULL;
2688 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2690 if (sock->type == SILC_SOCKET_TYPE_SERVER)
2691 server->stat.cell_clients++;
2692 server->stat.clients++;
2694 /* Check if anyone is watching this nickname */
2695 if (server->server_type == SILC_ROUTER && id_list == server->local_list)
2696 silc_server_check_watcher_list(server, entry, NULL, 0);
2700 case SILC_ID_SERVER:
2702 SilcServerEntry entry;
2704 /* If the ID is mine, ignore it. */
2705 if (SILC_ID_SERVER_COMPARE(id, server->id)) {
2706 SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
2710 /* If the ID is the sender's ID, ignore it (we have it already) */
2711 if (SILC_ID_SERVER_COMPARE(id, router->id)) {
2712 SILC_LOG_DEBUG(("Ignoring sender's own ID"));
2716 /* Check that we do not have this server already */
2717 entry = silc_idlist_find_server_by_id(server->global_list,
2718 id, server->server_type,
2721 entry = silc_idlist_find_server_by_id(server->local_list,
2722 id, server->server_type,
2725 SILC_LOG_DEBUG(("Ignoring server that we already have"));
2729 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
2730 silc_id_render(id, SILC_ID_SERVER),
2731 sock->type == SILC_SOCKET_TYPE_SERVER ?
2732 "Server" : "Router", sock->hostname));
2734 /* As a router we keep information of all global information in our
2735 global list. Cell wide information however is kept in the local
2737 entry = silc_idlist_add_server(id_list, NULL, 0, id, router,
2740 SILC_LOG_ERROR(("Could not add new server to the ID Cache"));
2743 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2745 if (sock->type == SILC_SOCKET_TYPE_SERVER)
2746 server->stat.cell_servers++;
2747 server->stat.servers++;
2751 case SILC_ID_CHANNEL:
2752 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
2761 /* If the sender of this packet is server and we are router we need to
2762 broadcast this packet to other routers in the network. */
2763 if (broadcast && server->server_type == SILC_ROUTER &&
2764 sock->type == SILC_SOCKET_TYPE_SERVER &&
2765 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2766 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
2767 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
2769 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2770 buffer->data, buffer->len, FALSE);
2771 silc_server_backup_send(server, sock->user_data,
2772 packet->type, packet->flags,
2773 packet->buffer->data, packet->buffer->len,
2778 silc_id_payload_free(idp);
2782 /* Processes incoming New ID packet. New ID Payload is used to distribute
2783 information about newly registered clients and servers. */
2785 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
2786 SilcPacketContext *packet)
2788 silc_server_new_id_real(server, sock, packet, TRUE);
2791 /* Receoved New Id List packet, list of New ID payloads inside one
2792 packet. Process the New ID payloads one by one. */
2794 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
2795 SilcPacketContext *packet)
2797 SilcPacketContext *new_id;
2801 SILC_LOG_DEBUG(("Processing New ID List"));
2803 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2804 packet->src_id_type != SILC_ID_SERVER)
2807 /* If the sender of this packet is server and we are router we need to
2808 broadcast this packet to other routers in the network. Broadcast
2809 this list packet instead of multiple New ID packets. */
2810 if (server->server_type == SILC_ROUTER &&
2811 sock->type == SILC_SOCKET_TYPE_SERVER &&
2812 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2813 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
2814 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
2816 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2817 packet->buffer->data,
2818 packet->buffer->len, FALSE);
2819 silc_server_backup_send(server, sock->user_data,
2820 packet->type, packet->flags,
2821 packet->buffer->data, packet->buffer->len,
2825 /* Make copy of the original packet context, except for the actual
2826 data buffer, which we will here now fetch from the original buffer. */
2827 new_id = silc_packet_context_alloc();
2828 new_id->type = SILC_PACKET_NEW_ID;
2829 new_id->flags = packet->flags & (~SILC_PACKET_FLAG_LIST);
2830 new_id->src_id = packet->src_id;
2831 new_id->src_id_len = packet->src_id_len;
2832 new_id->src_id_type = packet->src_id_type;
2833 new_id->dst_id = packet->dst_id;
2834 new_id->dst_id_len = packet->dst_id_len;
2835 new_id->dst_id_type = packet->dst_id_type;
2837 idp = silc_buffer_alloc(256);
2838 new_id->buffer = idp;
2840 while (packet->buffer->len) {
2841 SILC_GET16_MSB(id_len, packet->buffer->data + 2);
2842 if ((id_len > packet->buffer->len) ||
2843 (id_len > idp->truelen))
2846 silc_buffer_pull_tail(idp, 4 + id_len);
2847 silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
2849 /* Process the New ID */
2850 silc_server_new_id_real(server, sock, new_id, FALSE);
2852 silc_buffer_push_tail(idp, 4 + id_len);
2853 silc_buffer_pull(packet->buffer, 4 + id_len);
2856 silc_buffer_free(idp);
2860 /* Received New Channel packet. Information about new channels in the
2861 network are distributed using this packet. Save the information about
2862 the new channel. This usually comes from router but also normal server
2863 can send this to notify channels it has when it connects to us. */
2865 void silc_server_new_channel(SilcServer server,
2866 SilcSocketConnection sock,
2867 SilcPacketContext *packet)
2869 SilcChannelPayload payload;
2870 SilcChannelID *channel_id;
2872 SilcUInt32 name_len;
2874 SilcUInt32 id_len, cipher_len;
2875 SilcServerEntry server_entry;
2876 SilcChannelEntry channel;
2879 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2880 packet->src_id_type != SILC_ID_SERVER ||
2881 server->server_type == SILC_SERVER)
2884 /* Parse the channel payload */
2885 payload = silc_channel_payload_parse(packet->buffer->data,
2886 packet->buffer->len);
2890 /* Get the channel ID */
2891 channel_id = silc_channel_get_id_parse(payload);
2893 silc_channel_payload_free(payload);
2897 channel_name = silc_channel_get_name(payload, &name_len);
2899 channel_name[255] = '\0';
2901 id = silc_channel_get_id(payload, &id_len);
2903 server_entry = (SilcServerEntry)sock->user_data;
2905 if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
2906 /* Add the channel to global list as it is coming from router. It
2907 cannot be our own channel as it is coming from router. */
2909 /* Check that we don't already have this channel */
2910 channel = silc_idlist_find_channel_by_name(server->local_list,
2911 channel_name, NULL);
2913 channel = silc_idlist_find_channel_by_name(server->global_list,
2914 channel_name, NULL);
2916 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
2917 silc_id_render(channel_id, SILC_ID_CHANNEL),
2921 silc_idlist_add_channel(server->global_list, strdup(channel_name),
2922 0, channel_id, sock->user_data, NULL, NULL, 0);
2924 silc_channel_payload_free(payload);
2925 silc_free(channel_id);
2928 channel->disabled = TRUE; /* Disabled until someone JOINs */
2930 server->stat.channels++;
2931 if (server->server_type == SILC_ROUTER)
2932 channel->users_resolved = TRUE;
2935 /* The channel is coming from our server, thus it is in our cell
2936 we will add it to our local list. */
2939 SILC_LOG_DEBUG(("Channel id(%s) from [Server] %s",
2940 silc_id_render(channel_id, SILC_ID_CHANNEL),
2943 /* Check that we don't already have this channel */
2944 channel = silc_idlist_find_channel_by_name(server->local_list,
2945 channel_name, NULL);
2947 channel = silc_idlist_find_channel_by_name(server->global_list,
2948 channel_name, NULL);
2950 /* If the channel does not exist, then create it. This creates a new
2951 key to the channel as well that we will send to the server. */
2953 SILC_LOG_DEBUG(("Channel is new to us"));
2955 /* The protocol says that the Channel ID's IP address must be based
2956 on the router's IP address. Check whether the ID is based in our
2957 IP and if it is not then create a new ID and enforce the server
2958 to switch the ID. */
2959 if (server_entry->server_type != SILC_BACKUP_ROUTER &&
2960 !SILC_ID_COMPARE(channel_id, server->id, server->id->ip.data_len)) {
2962 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2963 if (silc_id_create_channel_id(server, server->id, server->rng, &tmp)) {
2964 silc_server_send_notify_channel_change(server, sock, FALSE,
2966 silc_channel_payload_free(payload);
2967 silc_free(channel_id);
2971 /* Wait that server re-announces this channel */
2975 /* Create the channel with the provided Channel ID */
2976 channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
2980 silc_channel_payload_free(payload);
2981 silc_free(channel_id);
2984 channel->disabled = TRUE; /* Disabled until someone JOINs */
2986 #if 0 /* We assume that CMODE_CHANGE notify is sent to us after this. */
2988 /* XXX Dunno if this is supposed to be set in any server type. If set
2989 here the CMODE_CHANGE that may follow sets mode that we already
2990 have, and we may loose data from the CMODE_CHANGE notify. */
2991 if (server_entry->server_type != SILC_BACKUP_ROUTER)
2992 channel->mode = silc_channel_get_mode(payload);
2995 /* Send the new channel key to the server */
2996 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2997 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
2998 cipher = silc_cipher_get_name(channel->channel_key);
2999 cipher_len = strlen(cipher);
3000 chk = silc_channel_key_payload_encode(id_len, id,
3002 channel->key_len / 8,
3004 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
3005 chk->data, chk->len, FALSE);
3006 silc_buffer_free(chk);
3009 /* The channel exist by that name, check whether the ID's match.
3010 If they don't then we'll force the server to use the ID we have.
3011 We also create a new key for the channel. */
3012 SilcBuffer modes = NULL, users = NULL, users_modes = NULL;
3014 SILC_LOG_DEBUG(("Channel already exists"));
3016 if (!SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
3017 /* They don't match, send CHANNEL_CHANGE notify to the server to
3018 force the ID change. */
3019 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
3020 silc_server_send_notify_channel_change(server, sock, FALSE,
3021 channel_id, channel->id);
3022 silc_channel_payload_free(payload);
3023 silc_free(channel_id);
3025 /* Wait that server re-announces this channel */
3029 #if 0 /* We will announce our CMODE anyway for this channel, so no need
3030 to check it (implicit enforce). */
3032 /* If the mode is different from what we have then enforce the
3034 mode = silc_channel_get_mode(payload);
3035 if (channel->mode != mode) {
3036 SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
3037 silc_server_send_notify_cmode(server, sock, FALSE, channel,
3038 channel->mode, server->id,
3039 SILC_ID_SERVER, channel->cipher,
3041 channel->passphrase,
3042 channel->founder_key);
3046 /* Create new key for the channel and send it to the server and
3047 everybody else possibly on the channel. */
3048 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3050 if (silc_hash_table_count(channel->user_list)) {
3051 if (!silc_server_create_channel_key(server, channel, 0)) {
3052 silc_channel_payload_free(payload);
3053 silc_free(channel_id);
3057 /* Send to the channel */
3058 silc_server_send_channel_key(server, sock, channel, FALSE);
3061 /* Send to the server */
3062 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3063 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
3064 cipher = silc_cipher_get_name(channel->channel_key);
3065 cipher_len = strlen(cipher);
3066 chk = silc_channel_key_payload_encode(id_len, id,
3068 channel->key_len / 8,
3070 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
3071 chk->data, chk->len, FALSE);
3072 silc_buffer_free(chk);
3076 silc_free(channel_id);
3078 /* Since the channel is coming from server and we also know about it
3079 then send the JOIN notify to the server so that it see's our
3080 users on the channel "joining" the channel. */
3081 silc_server_announce_get_channel_users(server, channel, &modes, &users,
3084 silc_buffer_push(users, users->data - users->head);
3085 silc_server_packet_send(server, sock,
3086 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3087 users->data, users->len, FALSE);
3088 silc_buffer_free(users);
3091 silc_buffer_push(modes, modes->data - modes->head);
3092 silc_server_packet_send_dest(server, sock,
3093 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3094 channel->id, SILC_ID_CHANNEL,
3095 modes->data, modes->len, FALSE);
3096 silc_buffer_free(modes);
3099 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
3100 silc_server_packet_send_dest(server, sock,
3101 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3102 channel->id, SILC_ID_CHANNEL,
3104 users_modes->len, FALSE);
3105 silc_buffer_free(users_modes);
3107 if (channel->topic) {
3108 silc_server_send_notify_topic_set(server, sock,
3109 server->server_type == SILC_ROUTER ?
3110 TRUE : FALSE, channel,
3111 server->id, SILC_ID_SERVER,
3117 /* If the sender of this packet is server and we are router we need to
3118 broadcast this packet to other routers in the network. Broadcast
3119 this list packet instead of multiple New Channel packets. */
3120 if (server->server_type == SILC_ROUTER &&
3121 sock->type == SILC_SOCKET_TYPE_SERVER &&
3122 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
3123 SILC_LOG_DEBUG(("Broadcasting received New Channel packet"));
3124 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
3126 packet->flags | SILC_PACKET_FLAG_BROADCAST,
3127 packet->buffer->data,
3128 packet->buffer->len, FALSE);
3129 silc_server_backup_send(server, sock->user_data,
3130 packet->type, packet->flags,
3131 packet->buffer->data, packet->buffer->len,
3135 silc_channel_payload_free(payload);
3138 /* Received New Channel List packet, list of New Channel List payloads inside
3139 one packet. Process the New Channel payloads one by one. */
3141 void silc_server_new_channel_list(SilcServer server,
3142 SilcSocketConnection sock,
3143 SilcPacketContext *packet)
3145 SilcPacketContext *new;
3147 SilcUInt16 len1, len2;
3149 SILC_LOG_DEBUG(("Processing New Channel List"));
3151 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
3152 packet->src_id_type != SILC_ID_SERVER ||
3153 server->server_type == SILC_SERVER)
3156 /* Make copy of the original packet context, except for the actual
3157 data buffer, which we will here now fetch from the original buffer. */
3158 new = silc_packet_context_alloc();
3159 new->type = SILC_PACKET_NEW_CHANNEL;
3160 new->flags = packet->flags & (~SILC_PACKET_FLAG_LIST);
3161 new->src_id = packet->src_id;
3162 new->src_id_len = packet->src_id_len;
3163 new->src_id_type = packet->src_id_type;
3164 new->dst_id = packet->dst_id;
3165 new->dst_id_len = packet->dst_id_len;
3166 new->dst_id_type = packet->dst_id_type;
3168 buffer = silc_buffer_alloc(512);
3169 new->buffer = buffer;
3171 while (packet->buffer->len) {
3172 SILC_GET16_MSB(len1, packet->buffer->data);
3173 if ((len1 > packet->buffer->len) ||
3174 (len1 > buffer->truelen))
3177 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
3178 if ((len2 > packet->buffer->len) ||
3179 (len2 > buffer->truelen))
3182 silc_buffer_pull_tail(buffer, 8 + len1 + len2);
3183 silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
3185 /* Process the New Channel */
3186 silc_server_new_channel(server, sock, new);
3188 silc_buffer_push_tail(buffer, 8 + len1 + len2);
3189 silc_buffer_pull(packet->buffer, 8 + len1 + len2);
3192 silc_buffer_free(buffer);
3196 /* Received key agreement packet. This packet is never for us. It is to
3197 the client in the packet's destination ID. Sending of this sort of packet
3198 equals sending private message, ie. it is sent point to point from
3199 one client to another. */
3201 void silc_server_key_agreement(SilcServer server,
3202 SilcSocketConnection sock,
3203 SilcPacketContext *packet)
3205 SilcSocketConnection dst_sock;
3206 SilcIDListData idata;
3208 SILC_LOG_DEBUG(("Start"));
3210 if (packet->src_id_type != SILC_ID_CLIENT ||
3211 packet->dst_id_type != SILC_ID_CLIENT)
3214 if (!packet->dst_id)
3217 /* Get the route to the client */
3218 dst_sock = silc_server_get_client_route(server, packet->dst_id,
3219 packet->dst_id_len, NULL,
3224 /* Relay the packet */
3225 silc_server_relay_packet(server, dst_sock, idata->send_key,
3226 idata->hmac_send, idata->psn_send++,
3230 /* Received connection auth request packet that is used during connection
3231 phase to resolve the mandatory authentication method. This packet can
3232 actually be received at anytime but usually it is used only during
3233 the connection authentication phase. Now, protocol says that this packet
3234 can come from client or server, however, we support only this coming
3235 from client and expect that server always knows what authentication
3238 void silc_server_connection_auth_request(SilcServer server,
3239 SilcSocketConnection sock,
3240 SilcPacketContext *packet)
3242 SilcServerConfigClient *client = NULL;
3243 SilcUInt16 conn_type;
3245 SilcAuthMethod auth_meth = SILC_AUTH_NONE;
3247 if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT) {
3248 SILC_LOG_DEBUG(("Request not from client"));
3252 /* Parse the payload */
3253 ret = silc_buffer_unformat(packet->buffer,
3254 SILC_STR_UI_SHORT(&conn_type),
3255 SILC_STR_UI_SHORT(NULL),
3260 if (conn_type != SILC_SOCKET_TYPE_CLIENT)
3263 /* Get the authentication method for the client */
3264 auth_meth = SILC_AUTH_NONE;
3265 client = silc_server_config_find_client(server, sock->ip);
3267 client = silc_server_config_find_client(server, sock->hostname);
3269 if (client->passphrase) {
3270 if (client->publickeys && !server->config->prefer_passphrase_auth)
3271 auth_meth = SILC_AUTH_PUBLIC_KEY;
3273 auth_meth = SILC_AUTH_PASSWORD;
3274 } else if (client->publickeys)
3275 auth_meth = SILC_AUTH_PUBLIC_KEY;
3278 SILC_LOG_DEBUG(("Authentication method is [%s]",
3279 (auth_meth == SILC_AUTH_NONE ? "None" :
3280 auth_meth == SILC_AUTH_PASSWORD ? "Passphrase" :
3281 "Digital signatures")));
3283 /* Send it back to the client */
3284 silc_server_send_connection_auth_request(server, sock, conn_type, auth_meth);
3287 /* Received REKEY packet. The sender of the packet wants to regenerate
3288 its session keys. This starts the REKEY protocol. */
3290 void silc_server_rekey(SilcServer server,
3291 SilcSocketConnection sock,
3292 SilcPacketContext *packet)
3294 SilcProtocol protocol;
3295 SilcServerRekeyInternalContext *proto_ctx;
3296 SilcIDListData idata = (SilcIDListData)sock->user_data;
3298 SILC_LOG_DEBUG(("Start"));
3300 /* Allocate internal protocol context. This is sent as context
3302 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
3303 proto_ctx->server = (void *)server;
3304 proto_ctx->sock = sock;
3305 proto_ctx->responder = TRUE;
3306 proto_ctx->pfs = idata->rekey->pfs;
3308 /* Perform rekey protocol. Will call the final callback after the
3309 protocol is over. */
3310 silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
3311 &protocol, proto_ctx, silc_server_rekey_final);
3312 sock->protocol = protocol;
3314 if (proto_ctx->pfs == FALSE)
3315 /* Run the protocol */
3316 silc_protocol_execute(protocol, server->schedule, 0, 0);
3319 /* Received file transger packet. This packet is never for us. It is to
3320 the client in the packet's destination ID. Sending of this sort of packet
3321 equals sending private message, ie. it is sent point to point from
3322 one client to another. */
3324 void silc_server_ftp(SilcServer server,
3325 SilcSocketConnection sock,
3326 SilcPacketContext *packet)
3328 SilcSocketConnection dst_sock;
3329 SilcIDListData idata;
3331 SILC_LOG_DEBUG(("Start"));
3333 if (packet->src_id_type != SILC_ID_CLIENT ||
3334 packet->dst_id_type != SILC_ID_CLIENT)
3337 if (!packet->dst_id)
3340 /* Get the route to the client */
3341 dst_sock = silc_server_get_client_route(server, packet->dst_id,
3342 packet->dst_id_len, NULL,
3347 /* Relay the packet */
3348 silc_server_relay_packet(server, dst_sock, idata->send_key,
3349 idata->hmac_send, idata->psn_send++,
3355 SilcSocketConnection sock;
3356 SilcPacketContext *packet;
3358 } *SilcServerResumeResolve;
3360 SILC_SERVER_CMD_FUNC(resume_resolve)
3362 SilcServerResumeResolve r = (SilcServerResumeResolve)context;
3363 SilcServer server = r->server;
3364 SilcSocketConnection sock = r->sock;
3365 SilcServerCommandReplyContext reply = context2;
3366 SilcClientEntry client;
3368 SILC_LOG_DEBUG(("Start"));
3370 if (!reply || !silc_command_get_status(reply->payload, NULL, NULL)) {
3371 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3372 "closing connection", sock->hostname, sock->ip));
3373 silc_server_disconnect_remote(server, sock,
3374 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3375 "Resuming not possible");
3376 if (sock->user_data)
3377 silc_server_free_sock_user_data(server, sock, NULL);
3381 if (reply && silc_command_get(reply->payload) == SILC_COMMAND_WHOIS) {
3382 /* Get entry to the client, and resolve it if we don't have it. */
3383 client = silc_idlist_find_client_by_id(server->local_list,
3384 r->data, TRUE, NULL);
3386 client = silc_idlist_find_client_by_id(server->global_list,
3387 r->data, TRUE, NULL);
3389 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3390 "closing connection", sock->hostname, sock->ip));
3391 silc_server_disconnect_remote(server, sock,
3392 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3393 "Resuming not possible");
3394 if (sock->user_data)
3395 silc_server_free_sock_user_data(server, sock, NULL);
3400 if (!(client->mode & SILC_UMODE_DETACHED)) {
3401 SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, "
3402 "closing connection", sock->hostname, sock->ip));
3403 silc_server_disconnect_remote(server, sock,
3404 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3405 "Resuming not possible");
3406 if (sock->user_data)
3407 silc_server_free_sock_user_data(server, sock, NULL);
3411 client->data.status |= SILC_IDLIST_STATUS_RESUME_RES;
3414 /* Reprocess the packet */
3415 silc_server_resume_client(server, sock, r->packet);
3418 silc_socket_free(r->sock);
3419 silc_packet_context_free(r->packet);
3424 /* Received client resuming packet. This is used to resume detached
3425 client session. It can be sent by the client who wishes to resume
3426 but this is also sent by servers and routers to notify other routers
3427 that the client is not detached anymore. */
3429 void silc_server_resume_client(SilcServer server,
3430 SilcSocketConnection sock,
3431 SilcPacketContext *packet)
3433 SilcBuffer buffer = packet->buffer, buf;
3434 SilcIDListData idata;
3435 SilcIDCacheEntry id_cache = NULL;
3436 SilcClientEntry detached_client;
3437 SilcClientID *client_id = NULL;
3438 unsigned char *id_string, *auth = NULL;
3439 SilcUInt16 id_len, auth_len = 0;
3440 int ret, nickfail = 0;
3441 bool resolved, local, nick_change = FALSE, resolve = FALSE;
3442 SilcChannelEntry channel;
3443 SilcHashTableList htl;
3444 SilcChannelClientEntry chl;
3445 SilcServerResumeResolve r;
3448 ret = silc_buffer_unformat(buffer,
3449 SILC_STR_UI16_NSTRING(&id_string, &id_len),
3452 client_id = silc_id_str2id(id_string, id_len, SILC_ID_CLIENT);
3454 if (sock->type == SILC_SOCKET_TYPE_CLIENT) {
3455 /* Client send this and is attempting to resume to old client session */
3456 SilcClientEntry client;
3460 silc_buffer_pull(buffer, 2 + id_len);
3461 auth = buffer->data;
3462 auth_len = buffer->len;
3463 silc_buffer_push(buffer, 2 + id_len);
3466 if (!client_id || auth_len < 128) {
3467 SILC_LOG_ERROR(("Client %s (%s) sent incomplete resume information, "
3468 "closing connection", sock->hostname, sock->ip));
3469 silc_server_disconnect_remote(server, sock,
3470 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3471 "Resuming not possible");
3472 if (sock->user_data)
3473 silc_server_free_sock_user_data(server, sock, NULL);
3474 silc_free(client_id);
3478 /* Take client entry of this connection */
3479 client = (SilcClientEntry)sock->user_data;
3480 idata = (SilcIDListData)client;
3482 /* Get entry to the client, and resolve it if we don't have it. */
3483 detached_client = silc_server_query_client(server, client_id, FALSE,
3485 if (!detached_client) {
3487 /* The client info is being resolved. Reprocess this packet after
3488 receiving the reply to the query. */
3489 SILC_LOG_DEBUG(("Resolving client"));
3490 r = silc_calloc(1, sizeof(*r));
3494 r->sock = silc_socket_dup(sock);
3495 r->packet = silc_packet_context_dup(packet);
3496 r->data = client_id;
3497 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
3499 silc_server_command_resume_resolve, r);
3501 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3502 "closing connection", sock->hostname, sock->ip));
3503 silc_server_disconnect_remote(server, sock,
3504 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3505 "Resuming not possible");
3506 if (sock->user_data)
3507 silc_server_free_sock_user_data(server, sock, NULL);
3508 silc_free(client_id);
3513 if (!(detached_client->mode & SILC_UMODE_DETACHED))
3515 if (!silc_hash_table_count(detached_client->channels) &&
3516 detached_client->router)
3518 if (!detached_client->nickname)
3520 if (detached_client->data.status & SILC_IDLIST_STATUS_RESUME_RES)
3524 if (server->server_type == SILC_SERVER && !server->standalone) {
3525 /* The client info is being resolved. Reprocess this packet after
3526 receiving the reply to the query. */
3527 SILC_LOG_DEBUG(("Resolving client info"));
3528 silc_server_query_client(server, client_id, TRUE, NULL);
3529 r = silc_calloc(1, sizeof(*r));
3533 r->sock = silc_socket_dup(sock);
3534 r->packet = silc_packet_context_dup(packet);
3535 r->data = client_id;
3536 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
3538 silc_server_command_resume_resolve, r);
3541 if (server->server_type == SILC_SERVER) {
3542 SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, "
3543 "closing connection", sock->hostname, sock->ip));
3544 silc_server_disconnect_remote(server, sock,
3545 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3546 "Resuming not possible");
3547 if (sock->user_data)
3548 silc_server_free_sock_user_data(server, sock, NULL);
3549 silc_free(client_id);
3554 /* Check that we have the public key of the client, if not then we must
3555 resolve it first. */
3556 if (!detached_client->data.public_key) {
3557 if (server->server_type == SILC_SERVER && server->standalone) {
3558 SILC_LOG_ERROR(("Detached client's public key not present, "
3559 "closing connection"));
3560 silc_server_disconnect_remote(server, sock,
3561 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3562 "Resuming not possible");
3563 if (sock->user_data)
3564 silc_server_free_sock_user_data(server, sock, NULL);
3565 silc_free(client_id);
3567 /* We must retrieve the detached client's public key by sending
3568 GETKEY command. Reprocess this packet after receiving the key */
3569 SilcBuffer idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
3570 SilcSocketConnection dest_sock =
3571 silc_server_get_client_route(server, NULL, 0, client_id, NULL, NULL);
3573 SILC_LOG_DEBUG(("Resolving client public key"));
3575 silc_server_send_command(server, dest_sock ? dest_sock :
3576 SILC_PRIMARY_ROUTE(server),
3577 SILC_COMMAND_GETKEY, ++server->cmd_ident,
3578 1, 1, idp->data, idp->len);
3580 r = silc_calloc(1, sizeof(*r));
3582 silc_free(client_id);
3587 r->sock = silc_socket_dup(sock);
3588 r->packet = silc_packet_context_dup(packet);
3589 silc_server_command_pending(server, SILC_COMMAND_GETKEY,
3591 silc_server_command_resume_resolve, r);
3593 silc_buffer_free(idp);
3595 silc_free(client_id);
3597 } else if (!silc_pkcs_public_key_compare(detached_client->data.public_key,
3598 idata->public_key)) {
3599 /* We require that the connection and resuming authentication data
3600 must be using same key pair. */
3601 SILC_LOG_ERROR(("Resuming attempted with wrong public key, "
3602 "closing connection"));
3603 silc_server_disconnect_remote(server, sock,
3604 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3605 "Resuming not possible");
3606 if (sock->user_data)
3607 silc_server_free_sock_user_data(server, sock, NULL);
3608 silc_free(client_id);
3612 /* Verify the authentication payload. This has to be successful in
3613 order to allow the resuming */
3615 !silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
3616 detached_client->data.public_key, 0,
3617 idata->hash, detached_client->id,
3619 SILC_LOG_ERROR(("Client %s (%s) resume authentication failed, "
3620 "closing connection", sock->hostname, sock->ip));
3621 silc_server_disconnect_remote(server, sock,
3622 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3623 "Resuming not possible");
3624 if (sock->user_data)
3625 silc_server_free_sock_user_data(server, sock, NULL);
3626 silc_free(client_id);
3630 /* Now resume the client to the network */
3632 silc_schedule_task_del_by_context(server->schedule, detached_client);
3633 sock->user_data = detached_client;
3634 detached_client->connection = sock;
3636 /* Take new keys and stuff into use in the old entry */
3637 silc_idlist_del_data(detached_client);
3638 silc_idlist_add_data(detached_client, idata);
3639 detached_client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
3640 detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
3641 detached_client->data.status |= SILC_IDLIST_STATUS_LOCAL;
3642 detached_client->data.status &= ~SILC_IDLIST_STATUS_RESUME_RES;
3643 detached_client->mode &= ~SILC_UMODE_DETACHED;
3644 server->stat.my_detached--;
3646 /* Send the RESUME_CLIENT packet to our primary router so that others
3647 know this client isn't detached anymore. */
3648 buf = silc_buffer_alloc_size(2 + id_len);
3649 silc_buffer_format(buf,
3650 SILC_STR_UI_SHORT(id_len),
3651 SILC_STR_UI_XNSTRING(id_string, id_len),
3654 /* Send to primary router */
3655 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
3656 SILC_PACKET_RESUME_CLIENT, 0,
3657 buf->data, buf->len, TRUE);
3658 silc_server_backup_send(server, detached_client->router,
3659 SILC_PACKET_RESUME_CLIENT, 0,
3660 buf->data, buf->len, TRUE, TRUE);
3662 /* As router we must deliver this packet directly to the original
3663 server whom this client was earlier. */
3664 if (server->server_type == SILC_ROUTER && detached_client->router &&
3665 detached_client->router->server_type != SILC_ROUTER)
3666 silc_server_packet_send(server, detached_client->router->connection,
3667 SILC_PACKET_RESUME_CLIENT, 0,
3668 buf->data, buf->len, TRUE);
3669 silc_buffer_free(buf);
3671 detached_client->router = NULL;
3673 /* Delete this client entry since we're resuming to old one. */
3674 server->stat.my_clients--;
3675 server->stat.clients--;
3676 if (server->stat.cell_clients)
3677 server->stat.cell_clients--;
3678 silc_server_remove_from_channels(server, NULL, client, FALSE,
3679 NULL, FALSE, FALSE);
3680 silc_server_del_from_watcher_list(server, client);
3681 if (!silc_idlist_del_client(server->local_list, client))
3682 silc_idlist_del_client(server->global_list, client);
3683 client = detached_client;
3684 silc_free(client->servername);
3685 client->servername = strdup(server->server_name);
3687 /* If the ID is not based in our ID then change it */
3688 if (!SILC_ID_COMPARE(client->id, server->id, server->id->ip.data_len)) {
3689 silc_free(client_id);
3690 while (!silc_id_create_client_id(server, server->id, server->rng,
3691 server->md5hash, client->nickname,
3695 silc_server_disconnect_remote(server, sock,
3696 SILC_STATUS_ERR_BAD_NICKNAME, NULL);
3697 if (sock->user_data)
3698 silc_server_free_sock_user_data(server, sock, NULL);
3701 snprintf(&client->nickname[strlen(client->nickname) - 1], 1,
3708 /* Notify about Client ID change, nickname doesn't actually change. */
3709 silc_server_send_notify_nick_change(server, SILC_PRIMARY_ROUTE(server),
3710 SILC_BROADCAST(server),
3711 client->id, client_id,
3715 /* Resolve users on those channels that client has joined but we
3716 haven't resolved user list yet. */
3717 if (server->server_type == SILC_SERVER && !server->standalone) {
3718 silc_hash_table_list(client->channels, &htl);
3719 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
3720 channel = chl->channel;
3721 SILC_LOG_DEBUG(("Resolving users for %s channel",
3722 channel->channel_name));
3723 if (channel->disabled || !channel->users_resolved) {
3724 silc_server_send_command(server, SILC_PRIMARY_ROUTE(server),
3725 SILC_COMMAND_USERS, ++server->cmd_ident,
3726 1, 2, channel->channel_name,
3727 strlen(channel->channel_name));
3730 silc_hash_table_list_reset(&htl);
3733 /* Send the new client ID to the client. After this client may start
3734 receiving other packets, and may start sending packets too. */
3735 silc_server_send_new_id(server, sock, FALSE, client_id, SILC_ID_CLIENT,
3736 silc_id_get_len(client_id, SILC_ID_CLIENT));
3739 /* Send NICK change notify to channels as well. */
3740 SilcBuffer oidp, nidp;
3741 oidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3742 nidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
3743 silc_server_send_notify_on_channels(server, NULL, client,
3744 SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
3745 oidp->data, oidp->len,
3746 nidp->data, nidp->len,
3748 strlen(client->nickname));
3749 silc_buffer_free(oidp);
3750 silc_buffer_free(nidp);
3753 /* Add the client again to the ID cache to get it to correct list */
3754 if (!silc_idcache_del_by_context(server->local_list->clients, client))
3755 silc_idcache_del_by_context(server->global_list->clients, client);
3756 silc_free(client->id);
3757 client->id = client_id;
3759 silc_idcache_add(server->local_list->clients, client->nickname,
3760 client->id, client, 0, NULL);
3762 /* Send some nice info to the client */
3763 silc_server_send_connect_notifys(server, sock, client);
3765 /* Send all channel keys of channels the client has joined */
3766 silc_hash_table_list(client->channels, &htl);
3767 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
3768 bool created = FALSE;
3769 channel = chl->channel;
3771 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY)
3774 /* If we don't have channel key, then create one */
3775 if (!channel->channel_key) {
3776 if (!silc_server_create_channel_key(server, channel, 0))
3781 id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3782 cipher = silc_cipher_get_name(channel->channel_key);
3784 silc_channel_key_payload_encode(silc_id_get_len(channel->id,
3787 strlen(cipher), cipher,
3788 channel->key_len / 8, channel->key);
3789 silc_free(id_string);
3791 /* Send the channel key to the client */
3792 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
3793 keyp->data, keyp->len, FALSE);
3795 /* Distribute the channel key to channel */
3797 silc_server_send_channel_key(server, NULL, channel,
3798 server->server_type == SILC_ROUTER ?
3799 FALSE : !server->standalone);
3800 silc_server_backup_send(server, NULL, SILC_PACKET_CHANNEL_KEY, 0,
3801 keyp->data, keyp->len, FALSE, TRUE);
3804 silc_buffer_free(keyp);
3806 silc_hash_table_list_reset(&htl);
3808 } else if (sock->type != SILC_SOCKET_TYPE_CLIENT) {
3809 /* Server or router sent this to us to notify that that a client has
3811 SilcServerEntry server_entry;
3812 SilcServerID *server_id;
3815 SILC_LOG_DEBUG(("Malformed resuming packet"));
3819 /* Get entry to the client, and resolve it if we don't have it. */
3820 detached_client = silc_idlist_find_client_by_id(server->local_list,
3823 if (!detached_client) {
3824 detached_client = silc_idlist_find_client_by_id(server->global_list,
3827 if (!detached_client) {
3828 SILC_LOG_DEBUG(("Resuming client is unknown"));
3829 silc_free(client_id);
3834 /* Check that the client has not been resumed already because it is
3835 protocol error to attempt to resume more than once. The client
3836 will be killed if this protocol error occurs. */
3837 if (detached_client->data.status & SILC_IDLIST_STATUS_RESUMED &&
3838 !(detached_client->mode & SILC_UMODE_DETACHED)) {
3839 /* The client is clearly attempting to resume more than once and
3840 perhaps playing around by resuming from several different places
3841 at the same time. */
3842 SILC_LOG_DEBUG(("Attempting to re-resume client, killing both"));
3843 silc_server_kill_client(server, detached_client, NULL,
3844 server->id, SILC_ID_SERVER);
3845 silc_free(client_id);
3849 /* Check whether client is detached at all */
3850 if (!(detached_client->mode & SILC_UMODE_DETACHED)) {
3851 SILC_LOG_DEBUG(("Client is not detached"));
3852 silc_free(client_id);
3856 SILC_LOG_DEBUG(("Resuming detached client"));
3858 /* If the sender of this packet is server and we are router we need to
3859 broadcast this packet to other routers in the network. */
3860 if (server->server_type == SILC_ROUTER &&
3861 sock->type == SILC_SOCKET_TYPE_SERVER &&
3862 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
3863 SILC_LOG_DEBUG(("Broadcasting received Resume Client packet"));
3864 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
3866 packet->flags | SILC_PACKET_FLAG_BROADCAST,
3867 buffer->data, buffer->len, FALSE);
3868 silc_server_backup_send(server, sock->user_data,
3869 packet->type, packet->flags,
3870 packet->buffer->data, packet->buffer->len,
3874 /* Client is detached, and now it is resumed. Remove the detached
3875 mode and mark that it is resumed. */
3876 silc_idlist_del_data(detached_client);
3877 detached_client->mode &= ~SILC_UMODE_DETACHED;
3878 detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
3879 detached_client->data.status &= ~SILC_IDLIST_STATUS_LOCAL;
3880 id_cache->expire = 0;
3882 silc_schedule_task_del_by_context(server->schedule, detached_client);
3884 /* Get the new owner of the resumed client */
3885 server_id = silc_id_str2id(packet->src_id, packet->src_id_len,
3886 packet->src_id_type);
3888 silc_free(client_id);
3892 /* Get server entry */
3893 server_entry = silc_idlist_find_server_by_id(server->global_list,
3894 server_id, TRUE, NULL);
3896 if (!server_entry) {
3897 server_entry = silc_idlist_find_server_by_id(server->local_list,
3898 server_id, TRUE, NULL);
3900 if (!server_entry) {
3901 silc_free(server_id);
3902 silc_free(client_id);
3907 if (server->server_type == SILC_ROUTER &&
3908 sock->type == SILC_SOCKET_TYPE_ROUTER &&
3909 server_entry->server_type == SILC_ROUTER)
3912 /* Change the client to correct list. */
3913 if (!silc_idcache_del_by_context(server->local_list->clients,
3915 silc_idcache_del_by_context(server->global_list->clients,
3917 silc_idcache_add(local && server->server_type == SILC_ROUTER ?
3918 server->local_list->clients :
3919 server->global_list->clients,
3920 detached_client->nickname,
3921 detached_client->id, detached_client, FALSE, NULL);
3923 /* Change the owner of the client */
3924 detached_client->router = server_entry;
3926 /* Update channel information regarding global clients on channel. */
3927 if (server->server_type != SILC_ROUTER) {
3928 silc_hash_table_list(detached_client->channels, &htl);
3929 while (silc_hash_table_get(&htl, NULL, (void **)&chl))
3930 chl->channel->global_users =
3931 silc_server_channel_has_global(chl->channel);
3932 silc_hash_table_list_reset(&htl);
3935 silc_free(server_id);
3938 silc_free(client_id);