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;
47 SilcHashTableList htl;
53 SILC_LOG_DEBUG(("Start"));
55 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
56 packet->src_id_type != SILC_ID_SERVER)
62 /* If the packet is destined directly to a client then relay the packet
63 before processing it. */
64 if (packet->dst_id_type == SILC_ID_CLIENT) {
66 SilcSocketConnection dst_sock;
68 /* Get the route to the client */
69 dst_sock = silc_server_get_client_route(server, packet->dst_id,
70 packet->dst_id_len, NULL,
73 /* Relay the packet */
74 silc_server_relay_packet(server, dst_sock, idata->send_key,
75 idata->hmac_send, idata->psn_send++,
79 /* Parse the Notify Payload */
80 payload = silc_notify_payload_parse(packet->buffer->data,
85 /* If we are router and this packet is not already broadcast packet
86 we will broadcast it. The sending socket really cannot be router or
87 the router is buggy. If this packet is coming from router then it must
88 have the broadcast flag set already and we won't do anything. */
89 if (server->server_type == SILC_ROUTER &&
90 sock->type == SILC_SOCKET_TYPE_SERVER &&
91 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
92 SILC_LOG_DEBUG(("Broadcasting received Notify packet"));
93 if (packet->dst_id_type == SILC_ID_CHANNEL) {
94 /* Packet is destined to channel */
95 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
100 if (!server->standalone)
101 silc_server_packet_send_dest(server, server->router->connection,
102 packet->type, packet->flags |
103 SILC_PACKET_FLAG_BROADCAST,
104 channel_id, SILC_ID_CHANNEL,
105 packet->buffer->data,
106 packet->buffer->len, FALSE);
107 silc_server_backup_send_dest(server, (SilcServerEntry)sock->user_data,
108 packet->type, packet->flags,
109 channel_id, SILC_ID_CHANNEL,
110 packet->buffer->data, packet->buffer->len,
113 /* Packet is destined to client or server */
114 if (!server->standalone)
115 silc_server_packet_send(server, server->router->connection,
117 packet->flags | SILC_PACKET_FLAG_BROADCAST,
118 packet->buffer->data, packet->buffer->len,
120 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
121 packet->type, packet->flags,
122 packet->buffer->data, packet->buffer->len,
127 type = silc_notify_get_type(payload);
128 args = silc_notify_get_args(payload);
133 case SILC_NOTIFY_TYPE_JOIN:
135 * Distribute the notify to local clients on the channel
137 SILC_LOG_DEBUG(("JOIN notify"));
140 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
143 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
147 /* Get channel entry */
148 channel = silc_idlist_find_channel_by_id(server->global_list,
151 channel = silc_idlist_find_channel_by_id(server->local_list,
154 silc_free(channel_id);
158 silc_free(channel_id);
161 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
164 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
168 /* If the the client is not in local list we check global list (ie. the
169 channel will be global channel) and if it does not exist then create
170 entry for the client. */
171 client = silc_idlist_find_client_by_id(server->global_list,
172 client_id, server->server_type,
175 client = silc_idlist_find_client_by_id(server->local_list,
176 client_id, server->server_type,
179 /* If router did not find the client the it is bogus */
180 if (server->server_type != SILC_SERVER)
184 silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
185 silc_id_dup(client_id, SILC_ID_CLIENT),
186 sock->user_data, NULL, 0);
188 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
189 silc_free(client_id);
193 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
197 /* Do not process the notify if the client is not registered */
198 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
201 /* Do not add client to channel if it is there already */
202 if (silc_server_client_on_channel(client, channel, NULL)) {
203 SILC_LOG_DEBUG(("Client already on channel"));
207 /* Send to channel */
208 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
209 FALSE, packet->buffer->data,
210 packet->buffer->len, FALSE);
212 if (server->server_type != SILC_ROUTER &&
213 sock->type == SILC_SOCKET_TYPE_ROUTER)
214 /* The channel is global now */
215 channel->global_users = TRUE;
217 SILC_LOG_DEBUG(("Joining to channel %s", channel->channel_name));
219 /* JOIN the global client to the channel (local clients (if router
220 created the channel) is joined in the pending JOIN command). */
221 chl = silc_calloc(1, sizeof(*chl));
222 chl->client = client;
223 chl->channel = channel;
225 /* If this is the first one on the channel then it is the founder of
227 if (!silc_hash_table_count(channel->user_list))
228 chl->mode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
230 silc_hash_table_add(channel->user_list, client, chl);
231 silc_hash_table_add(client->channels, channel, chl);
232 silc_free(client_id);
233 channel->user_count++;
234 channel->disabled = FALSE;
236 /* Update statistics */
237 if (server->server_type == SILC_ROUTER) {
238 if (sock->type != SILC_SOCKET_TYPE_ROUTER)
239 server->stat.cell_chanclients++;
240 server->stat.chanclients++;
245 case SILC_NOTIFY_TYPE_LEAVE:
247 * Distribute the notify to local clients on the channel
249 SILC_LOG_DEBUG(("LEAVE notify"));
252 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
253 packet->dst_id_type);
258 /* Get channel entry */
259 channel = silc_idlist_find_channel_by_id(server->global_list,
262 channel = silc_idlist_find_channel_by_id(server->local_list,
265 silc_free(channel_id);
271 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
273 silc_free(channel_id);
276 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
278 silc_free(channel_id);
282 /* Get client entry */
283 client = silc_idlist_find_client_by_id(server->global_list,
284 client_id, TRUE, NULL);
286 client = silc_idlist_find_client_by_id(server->local_list,
287 client_id, TRUE, NULL);
289 silc_free(client_id);
290 silc_free(channel_id);
294 silc_free(client_id);
296 /* Check if on channel */
297 if (!silc_server_client_on_channel(client, channel, NULL))
300 /* Send the leave notify to channel */
301 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
302 FALSE, packet->buffer->data,
303 packet->buffer->len, FALSE);
305 /* Remove the user from channel */
306 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
309 case SILC_NOTIFY_TYPE_SIGNOFF:
311 * Distribute the notify to local clients on the channel
313 SILC_LOG_DEBUG(("SIGNOFF notify"));
316 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
319 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
323 /* Get client entry */
324 client = silc_idlist_find_client_by_id(server->global_list,
325 client_id, TRUE, &cache);
327 client = silc_idlist_find_client_by_id(server->local_list,
328 client_id, TRUE, &cache);
330 silc_free(client_id);
334 silc_free(client_id);
336 /* Get signoff message */
337 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
341 /* Update statistics */
342 server->stat.clients--;
343 if (server->stat.cell_clients)
344 server->stat.cell_clients--;
345 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
346 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
348 /* Remove the client from all channels. */
349 silc_server_remove_from_channels(server, NULL, client, TRUE, tmp, FALSE);
351 /* Check if anyone is watching this nickname */
352 if (server->server_type == SILC_ROUTER)
353 silc_server_check_watcher_list(server, client, NULL,
354 SILC_NOTIFY_TYPE_SIGNOFF);
356 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
357 cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
360 case SILC_NOTIFY_TYPE_TOPIC_SET:
362 * Distribute the notify to local clients on the channel
365 SILC_LOG_DEBUG(("TOPIC SET notify"));
368 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
371 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
375 /* Get client entry */
376 client = silc_idlist_find_client_by_id(server->global_list,
377 client_id, TRUE, &cache);
379 client = silc_idlist_find_client_by_id(server->local_list,
380 client_id, TRUE, &cache);
382 silc_free(client_id);
386 silc_free(client_id);
389 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
391 silc_free(channel_id);
396 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
397 packet->dst_id_type);
402 /* Get channel entry */
403 channel = silc_idlist_find_channel_by_id(server->global_list,
406 channel = silc_idlist_find_channel_by_id(server->local_list,
409 silc_free(channel_id);
414 if (channel->topic && !strcmp(channel->topic, tmp))
417 /* Get user's channel entry and check that topic set is allowed. */
418 if (!silc_server_client_on_channel(client, channel, &chl))
420 if (channel->mode & SILC_CHANNEL_MODE_TOPIC &&
421 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
422 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
423 SILC_LOG_DEBUG(("Topic change is not allowed"));
427 /* Change the topic */
428 silc_free(channel->topic);
429 channel->topic = strdup(tmp);
431 /* Send the same notify to the channel */
432 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
433 FALSE, packet->buffer->data,
434 packet->buffer->len, FALSE);
435 silc_free(channel_id);
438 case SILC_NOTIFY_TYPE_NICK_CHANGE:
441 * Distribute the notify to local clients on the channel
443 unsigned char *id, *id2;
445 SilcUInt32 nickname_len;
447 SILC_LOG_DEBUG(("NICK CHANGE notify"));
449 /* Get old client ID */
450 id = silc_argument_get_arg_type(args, 1, &tmp_len);
453 client_id = silc_id_payload_parse_id(id, tmp_len, NULL);
457 /* Get new client ID */
458 id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
461 client_id2 = silc_id_payload_parse_id(id2, tmp_len, NULL);
465 SILC_LOG_DEBUG(("Old Client ID id(%s)",
466 silc_id_render(client_id, SILC_ID_CLIENT)));
467 SILC_LOG_DEBUG(("New Client ID id(%s)",
468 silc_id_render(client_id2, SILC_ID_CLIENT)));
470 /* From protocol version 1.1 we also get the new nickname */
471 nickname = silc_argument_get_arg_type(args, 3, &nickname_len);;
473 /* Replace the Client ID */
474 client = silc_idlist_replace_client_id(server,
475 server->global_list, client_id,
476 client_id2, nickname);
478 client = silc_idlist_replace_client_id(server,
479 server->local_list, client_id,
480 client_id2, nickname);
483 /* Send the NICK_CHANGE notify type to local clients on the channels
484 this client is joined to. */
485 silc_server_send_notify_on_channels(server, client, client,
486 SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
487 id, tmp_len, id2, tmp_len,
492 silc_free(client_id);
494 silc_free(client_id2);
498 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
500 * Distribute the notify to local clients on the channel
503 SILC_LOG_DEBUG(("CMODE CHANGE notify"));
506 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
509 client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
513 /* Get client entry */
514 if (id_type == SILC_ID_CLIENT) {
515 client = silc_idlist_find_client_by_id(server->global_list,
516 client_id, TRUE, &cache);
518 client = silc_idlist_find_client_by_id(server->local_list,
519 client_id, TRUE, &cache);
521 silc_free(client_id);
525 silc_free(client_id);
529 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
530 packet->dst_id_type);
535 /* Get channel entry */
536 channel = silc_idlist_find_channel_by_id(server->global_list,
539 channel = silc_idlist_find_channel_by_id(server->local_list,
542 silc_free(channel_id);
546 silc_free(channel_id);
549 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
552 SILC_GET32_MSB(mode, tmp);
554 /* Check if mode changed */
555 if (channel->mode == mode)
558 /* Get user's channel entry and check that mode change is allowed */
560 if (!silc_server_client_on_channel(client, channel, &chl))
562 if (!silc_server_check_cmode_rights(server, channel, chl, mode)) {
563 SILC_LOG_DEBUG(("CMODE change is not allowed"));
567 if (server->server_type == SILC_ROUTER &&
568 channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH &&
569 !(mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
570 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
571 silc_server_send_notify_cmode(server, sock, FALSE, channel,
572 channel->mode, server->id,
577 channel->founder_key);
582 /* Send the same notify to the channel */
583 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
584 FALSE, packet->buffer->data,
585 packet->buffer->len, FALSE);
587 /* If the channel had private keys set and the mode was removed then
588 we must re-generate and re-distribute a new channel key */
589 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY &&
590 !(mode & SILC_CHANNEL_MODE_PRIVKEY)) {
591 /* Re-generate channel key */
592 if (!silc_server_create_channel_key(server, channel, 0))
595 /* Send the channel key. This sends it to our local clients and if
596 we are normal server to our router as well. */
597 silc_server_send_channel_key(server, NULL, channel,
598 server->server_type == SILC_ROUTER ?
599 FALSE : !server->standalone);
603 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
605 unsigned char hash[32];
608 silc_hmac_free(channel->hmac);
609 if (!silc_hmac_alloc(tmp, NULL, &channel->hmac))
612 /* Set the HMAC key out of current channel key. The client must do
614 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key,
615 channel->key_len / 8, hash);
616 silc_hmac_set_key(channel->hmac, hash,
617 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
618 memset(hash, 0, sizeof(hash));
621 /* Get the passphrase */
622 tmp = silc_argument_get_arg_type(args, 5, &tmp_len);
624 silc_free(channel->passphrase);
625 channel->passphrase = silc_memdup(tmp, tmp_len);
628 /* Get founder public key */
629 tmp = silc_argument_get_arg_type(args, 6, &tmp_len);
630 if (tmp && mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
631 if (channel->founder_key)
632 silc_pkcs_public_key_free(channel->founder_key);
633 channel->founder_key = NULL;
634 silc_pkcs_public_key_decode(tmp, tmp_len, &channel->founder_key);
636 if (!channel->founder_key ||
637 (client && client->data.public_key &&
638 server->server_type == SILC_ROUTER &&
639 !silc_pkcs_public_key_compare(channel->founder_key,
640 client->data.public_key))) {
641 /* A really buggy server isn't checking public keys correctly.
642 It's not possible that the mode setter and founder wouldn't
643 have same public key. */
644 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
646 mode &= ~SILC_CHANNEL_MODE_FOUNDER_AUTH;
647 silc_server_send_notify_cmode(server, sock, FALSE, channel,
648 mode, server->id, SILC_ID_SERVER,
651 channel->passphrase, NULL);
652 if (channel->founder_key)
653 silc_pkcs_public_key_free(channel->founder_key);
654 channel->founder_key = NULL;
655 } else if (client && !client->data.public_key) {
656 client->data.public_key =
657 silc_pkcs_public_key_copy(channel->founder_key);
661 if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH && !channel->founder_key &&
662 server->server_type == SILC_ROUTER) {
663 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
664 mode &= ~SILC_CHANNEL_MODE_FOUNDER_AUTH;
665 silc_server_send_notify_cmode(server, sock, FALSE, channel,
666 mode, server->id, SILC_ID_SERVER,
669 channel->passphrase, NULL);
673 channel->mode = mode;
675 if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) &&
676 channel->founder_key) {
677 silc_pkcs_public_key_free(channel->founder_key);
678 channel->founder_key = NULL;
683 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
686 * Distribute the notify to local clients on the channel
688 SilcChannelClientEntry chl2 = NULL;
689 bool notify_sent = FALSE;
691 SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
694 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
697 client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
701 /* Get client entry */
702 if (id_type == SILC_ID_CLIENT) {
703 client = silc_idlist_find_client_by_id(server->global_list,
704 client_id, TRUE, &cache);
706 client = silc_idlist_find_client_by_id(server->local_list,
707 client_id, TRUE, &cache);
709 silc_free(client_id);
713 silc_free(client_id);
717 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
718 packet->dst_id_type);
723 /* Get channel entry */
724 channel = silc_idlist_find_channel_by_id(server->global_list,
727 channel = silc_idlist_find_channel_by_id(server->local_list,
730 silc_free(channel_id);
736 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
738 silc_free(channel_id);
742 SILC_GET32_MSB(mode, tmp);
744 /* Get target client */
745 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
748 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
752 /* Get client entry */
753 client2 = silc_idlist_find_client_by_id(server->global_list,
754 client_id, TRUE, NULL);
756 client2 = silc_idlist_find_client_by_id(server->local_list,
757 client_id, TRUE, NULL);
759 silc_free(client_id);
763 silc_free(client_id);
766 /* Check that sender is on channel */
767 if (!silc_server_client_on_channel(client, channel, &chl))
770 if (client != client2 && server->server_type == SILC_ROUTER) {
771 /* Sender must be operator */
772 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
773 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
774 SILC_LOG_DEBUG(("CUMODE change is not allowed"));
778 if (!silc_server_client_on_channel(client2, channel, &chl))
781 /* If target is founder mode change is not allowed. */
782 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
783 SILC_LOG_DEBUG(("CUMODE change is not allowed"));
789 /* Get target channel entry */
790 if (!silc_server_client_on_channel(client2, channel, &chl))
793 if (mode & SILC_CHANNEL_UMODE_CHANFO &&
794 !(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) && !client &&
795 server->server_type == SILC_ROUTER) {
796 /* Get the founder of the channel and if found then this client
797 cannot be the founder since there already is one. */
798 silc_hash_table_list(channel->user_list, &htl);
799 while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
800 if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
801 mode &= ~SILC_CHANNEL_UMODE_CHANFO;
802 silc_server_force_cumode_change(server, sock, channel, chl, mode);
806 silc_hash_table_list_reset(&htl);
807 if (!(mode & SILC_CHANNEL_UMODE_CHANFO))
811 if (client && mode & SILC_CHANNEL_UMODE_CHANFO &&
812 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO) &&
813 server->server_type == SILC_ROUTER) {
814 /* Check whether this client is allowed to be channel founder on
816 SilcPublicKey founder_key = NULL;
818 /* If channel doesn't have founder auth mode then it's impossible
819 that someone would be getting founder rights with CUMODE command.
820 In that case there already either is founder or there isn't
821 founder at all on the channel. */
822 if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
823 /* Force the mode to not have founder mode */
824 mode &= ~SILC_CHANNEL_UMODE_CHANFO;
825 silc_server_force_cumode_change(server, sock, channel, chl, mode);
830 /* Get the founder of the channel and if found then this client
831 cannot be the founder since there already is one. */
832 silc_hash_table_list(channel->user_list, &htl);
833 while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
834 if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
835 mode &= ~SILC_CHANNEL_UMODE_CHANFO;
836 silc_server_force_cumode_change(server, sock, channel, chl, mode);
840 silc_hash_table_list_reset(&htl);
841 if (!(mode & SILC_CHANNEL_UMODE_CHANFO))
844 /* Founder not found of the channel. Since the founder auth mode
845 is set on the channel now check whether this is the client that
846 originally set the mode. */
848 /* Get public key that must be present in notify */
849 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
850 if (!tmp || !silc_pkcs_public_key_decode(tmp, tmp_len,
852 mode &= ~SILC_CHANNEL_UMODE_CHANFO;
853 silc_server_force_cumode_change(server, sock, channel, chl, mode);
858 /* Now match the public key we have cached and public key sent.
860 if (client->data.public_key &&
861 !silc_pkcs_public_key_compare(channel->founder_key,
862 client->data.public_key)) {
863 mode &= ~SILC_CHANNEL_UMODE_CHANFO;
864 silc_server_force_cumode_change(server, sock, channel, chl, mode);
868 if (!silc_pkcs_public_key_compare(channel->founder_key,
870 mode &= ~SILC_CHANNEL_UMODE_CHANFO;
871 silc_server_force_cumode_change(server, sock, channel, chl, mode);
877 silc_pkcs_public_key_free(founder_key);
880 SILC_LOG_DEBUG(("Changing the channel user mode"));
882 /* Change the mode */
885 /* Send the same notify to the channel */
887 silc_server_packet_send_to_channel(server, sock, channel,
889 FALSE, packet->buffer->data,
890 packet->buffer->len, FALSE);
892 silc_free(channel_id);
896 case SILC_NOTIFY_TYPE_INVITE:
898 if (packet->dst_id_type == SILC_ID_CLIENT)
901 SILC_LOG_DEBUG(("INVITE notify"));
904 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
907 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
911 /* Get channel entry */
912 channel = silc_idlist_find_channel_by_id(server->global_list,
915 channel = silc_idlist_find_channel_by_id(server->local_list,
918 silc_free(channel_id);
922 silc_free(channel_id);
925 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
928 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
932 /* Get client entry */
933 client = silc_idlist_find_client_by_id(server->global_list,
934 client_id, TRUE, &cache);
936 client = silc_idlist_find_client_by_id(server->local_list,
937 client_id, TRUE, &cache);
939 silc_free(client_id);
943 silc_free(client_id);
945 /* Get user's channel entry and check that inviting is allowed. */
946 if (!silc_server_client_on_channel(client, channel, &chl))
948 if (channel->mode & SILC_CHANNEL_MODE_INVITE &&
949 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
950 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
951 SILC_LOG_DEBUG(("Inviting is not allowed"));
955 /* Get the added invite */
956 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
958 if (!channel->invite_list)
959 channel->invite_list = silc_calloc(tmp_len + 2,
960 sizeof(*channel->invite_list));
962 channel->invite_list = silc_realloc(channel->invite_list,
963 sizeof(*channel->invite_list) *
965 strlen(channel->invite_list) +
967 if (tmp[tmp_len - 1] == ',')
968 tmp[tmp_len - 1] = '\0';
970 strncat(channel->invite_list, tmp, tmp_len);
971 strncat(channel->invite_list, ",", 1);
974 /* Get the deleted invite */
975 tmp = silc_argument_get_arg_type(args, 5, &tmp_len);
976 if (tmp && channel->invite_list) {
977 char *start, *end, *n;
979 if (!strncmp(channel->invite_list, tmp,
980 strlen(channel->invite_list) - 1)) {
981 silc_free(channel->invite_list);
982 channel->invite_list = NULL;
984 start = strstr(channel->invite_list, tmp);
985 if (start && strlen(start) >= tmp_len) {
986 end = start + tmp_len;
987 n = silc_calloc(strlen(channel->invite_list) - tmp_len, sizeof(*n));
988 strncat(n, channel->invite_list, start - channel->invite_list);
989 strncat(n, end + 1, ((channel->invite_list +
990 strlen(channel->invite_list)) - end) - 1);
991 silc_free(channel->invite_list);
992 channel->invite_list = n;
999 case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
1001 * Distribute to the local clients on the channel and change the
1005 SILC_LOG_DEBUG(("CHANNEL CHANGE"));
1007 if (sock->type != SILC_SOCKET_TYPE_ROUTER)
1010 /* Get the old Channel ID */
1011 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1014 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1018 /* Get the channel entry */
1019 channel = silc_idlist_find_channel_by_id(server->local_list,
1022 channel = silc_idlist_find_channel_by_id(server->global_list,
1025 silc_free(channel_id);
1030 /* Send the notify to the channel */
1031 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
1032 FALSE, packet->buffer->data,
1033 packet->buffer->len, FALSE);
1035 /* Get the new Channel ID */
1036 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1039 channel_id2 = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1043 SILC_LOG_DEBUG(("Old Channel ID id(%s)",
1044 silc_id_render(channel_id, SILC_ID_CHANNEL)));
1045 SILC_LOG_DEBUG(("New Channel ID id(%s)",
1046 silc_id_render(channel_id2, SILC_ID_CHANNEL)));
1048 /* Replace the Channel ID */
1049 if (!silc_idlist_replace_channel_id(server->local_list, channel_id,
1051 if (!silc_idlist_replace_channel_id(server->global_list, channel_id,
1053 silc_free(channel_id2);
1058 SilcBuffer modes = NULL, users = NULL, users_modes = NULL;
1060 /* Re-announce this channel which ID was changed. */
1061 silc_server_send_new_channel(server, sock, FALSE, channel->channel_name,
1063 silc_id_get_len(channel->id,
1067 /* Re-announce our clients on the channel as the ID has changed now */
1068 silc_server_announce_get_channel_users(server, channel, &modes, &users,
1071 silc_buffer_push(modes, modes->data - modes->head);
1072 silc_server_packet_send_dest(server, sock,
1073 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1074 channel->id, SILC_ID_CHANNEL,
1075 modes->data, modes->len, FALSE);
1076 silc_buffer_free(modes);
1079 silc_buffer_push(users, users->data - users->head);
1080 silc_server_packet_send(server, sock,
1081 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1082 users->data, users->len, FALSE);
1083 silc_buffer_free(users);
1086 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
1087 silc_server_packet_send_dest(server, sock,
1088 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1089 channel->id, SILC_ID_CHANNEL,
1091 users_modes->len, FALSE);
1092 silc_buffer_free(users_modes);
1095 /* Re-announce channel's topic */
1096 if (channel->topic) {
1097 silc_server_send_notify_topic_set(server, sock,
1098 server->server_type == SILC_ROUTER ?
1099 TRUE : FALSE, channel,
1100 channel->id, SILC_ID_CHANNEL,
1105 silc_free(channel_id);
1109 case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
1111 * Remove the server entry and all clients that this server owns.
1114 SILC_LOG_DEBUG(("SERVER SIGNOFF notify"));
1117 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1120 server_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1124 /* Get server entry */
1125 server_entry = silc_idlist_find_server_by_id(server->global_list,
1126 server_id, TRUE, NULL);
1128 if (!server_entry) {
1129 server_entry = silc_idlist_find_server_by_id(server->local_list,
1130 server_id, TRUE, NULL);
1132 if (!server_entry) {
1133 /* If we are normal server then we might not have the server. Check
1134 whether router was kind enough to send the list of all clients
1135 that actually was to be removed. Remove them if the list is
1137 if (server->server_type != SILC_ROUTER &&
1138 silc_argument_get_arg_num(args) > 1) {
1141 for (i = 1; i < silc_argument_get_arg_num(args); i++) {
1143 tmp = silc_argument_get_arg_type(args, i + 1, &tmp_len);
1146 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1150 /* Get client entry */
1151 client = silc_idlist_find_client_by_id(server->global_list,
1152 client_id, TRUE, &cache);
1155 client = silc_idlist_find_client_by_id(server->local_list,
1156 client_id, TRUE, &cache);
1159 silc_free(client_id);
1163 silc_free(client_id);
1165 /* Update statistics */
1166 server->stat.clients--;
1167 if (server->stat.cell_clients)
1168 server->stat.cell_clients--;
1169 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
1170 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
1172 /* Remove the client from all channels. */
1173 silc_server_remove_from_channels(server, NULL, client,
1176 /* Check if anyone is watching this nickname */
1177 if (server->server_type == SILC_ROUTER)
1178 silc_server_check_watcher_list(server, client, NULL,
1179 SILC_NOTIFY_TYPE_SERVER_SIGNOFF);
1181 /* Remove this client from watcher list if it is */
1183 silc_server_del_from_watcher_list(server, client);
1185 /* Remove the client */
1186 silc_idlist_del_client(local ? server->local_list :
1187 server->global_list, client);
1191 silc_free(server_id);
1195 silc_free(server_id);
1197 /* Free all client entries that this server owns as they will
1198 become invalid now as well. */
1199 silc_server_remove_clients_by_server(server, server_entry, TRUE);
1201 /* Remove the server entry */
1202 silc_idlist_del_server(local ? server->local_list :
1203 server->global_list, server_entry);
1205 /* Update statistics */
1206 if (server->server_type == SILC_ROUTER)
1207 server->stat.servers--;
1211 case SILC_NOTIFY_TYPE_KICKED:
1213 * Distribute the notify to local clients on the channel
1216 SILC_LOG_DEBUG(("KICKED notify"));
1219 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
1220 packet->dst_id_type);
1225 /* Get channel entry */
1226 channel = silc_idlist_find_channel_by_id(server->global_list,
1229 channel = silc_idlist_find_channel_by_id(server->local_list,
1232 silc_free(channel_id);
1236 silc_free(channel_id);
1239 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1242 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1246 /* If the the client is not in local list we check global list */
1247 client = silc_idlist_find_client_by_id(server->global_list,
1248 client_id, TRUE, NULL);
1250 client = silc_idlist_find_client_by_id(server->local_list,
1251 client_id, TRUE, NULL);
1253 silc_free(client_id);
1257 silc_free(client_id);
1259 /* If target is founder they cannot be kicked */
1260 if (!silc_server_client_on_channel(client, channel, &chl))
1262 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO)
1265 /* From protocol version 1.1 we get the kicker's ID as well. */
1266 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1268 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1272 /* If the the client is not in local list we check global list */
1273 client2 = silc_idlist_find_client_by_id(server->global_list,
1274 client_id, TRUE, NULL);
1276 client2 = silc_idlist_find_client_by_id(server->local_list,
1277 client_id, TRUE, NULL);
1279 silc_free(client_id);
1283 silc_free(client_id);
1285 /* Kicker must be operator on channel */
1286 if (!silc_server_client_on_channel(client2, channel, &chl))
1288 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
1289 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1290 SILC_LOG_DEBUG(("Kicking is not allowed"));
1295 /* Send to channel */
1296 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
1297 FALSE, packet->buffer->data,
1298 packet->buffer->len, FALSE);
1300 /* Remove the client from channel */
1301 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
1305 case SILC_NOTIFY_TYPE_KILLED:
1308 * Distribute the notify to local clients on channels
1310 unsigned char *id, *comment;
1311 SilcUInt32 id_len, comment_len;
1313 SILC_LOG_DEBUG(("KILLED notify"));
1316 id = silc_argument_get_arg_type(args, 1, &id_len);
1319 client_id = silc_id_payload_parse_id(id, id_len, NULL);
1323 /* If the the client is not in local list we check global list */
1324 client = silc_idlist_find_client_by_id(server->global_list,
1325 client_id, TRUE, NULL);
1327 client = silc_idlist_find_client_by_id(server->local_list,
1328 client_id, TRUE, NULL);
1330 silc_free(client_id);
1334 silc_free(client_id);
1336 /* If the client is one of ours, then close the connection to the
1337 client now. This removes the client from all channels as well. */
1338 if (packet->dst_id_type == SILC_ID_CLIENT && client->connection) {
1339 sock = client->connection;
1340 silc_server_free_client_data(server, NULL, client, FALSE, NULL);
1341 silc_server_close_connection(server, sock);
1346 comment = silc_argument_get_arg_type(args, 2, &comment_len);
1347 if (comment_len > 128)
1350 /* From protocol version 1.1 we get the killer's ID as well. */
1351 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1353 client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
1357 if (id_type == SILC_ID_CLIENT) {
1358 /* If the the client is not in local list we check global list */
1359 client2 = silc_idlist_find_client_by_id(server->global_list,
1360 client_id, TRUE, NULL);
1362 client2 = silc_idlist_find_client_by_id(server->local_list,
1363 client_id, TRUE, NULL);
1365 silc_free(client_id);
1369 silc_free(client_id);
1371 /* Killer must be router operator */
1372 if (!(client2->mode & SILC_UMODE_ROUTER_OPERATOR)) {
1373 SILC_LOG_DEBUG(("Killing is not allowed"));
1379 /* Send the notify to local clients on the channels except to the
1380 client who is killed. */
1381 silc_server_send_notify_on_channels(server, client, client,
1382 SILC_NOTIFY_TYPE_KILLED, 3,
1383 id, id_len, comment, comment_len,
1386 /* Remove the client from all channels */
1387 silc_server_remove_from_channels(server, NULL, client, FALSE, NULL,
1390 /* Check if anyone is watching this nickname */
1391 if (server->server_type == SILC_ROUTER)
1392 silc_server_check_watcher_list(server, client, NULL,
1393 SILC_NOTIFY_TYPE_KILLED);
1398 case SILC_NOTIFY_TYPE_UMODE_CHANGE:
1400 * Save the mode of the client.
1403 SILC_LOG_DEBUG(("UMODE_CHANGE notify"));
1406 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1409 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1413 /* Get client entry */
1414 client = silc_idlist_find_client_by_id(server->global_list,
1415 client_id, TRUE, NULL);
1417 client = silc_idlist_find_client_by_id(server->local_list,
1418 client_id, TRUE, NULL);
1420 silc_free(client_id);
1424 silc_free(client_id);
1427 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1430 SILC_GET32_MSB(mode, tmp);
1432 /* Check that mode changing is allowed. */
1433 if (!silc_server_check_umode_rights(server, client, mode)) {
1434 SILC_LOG_DEBUG(("UMODE change is not allowed"));
1438 /* Remove internal resumed flag if client is marked detached now */
1439 if (mode & SILC_UMODE_DETACHED)
1440 client->data.status &= ~SILC_IDLIST_STATUS_RESUMED;
1442 /* Update statistics */
1443 if (server->server_type == SILC_ROUTER) {
1444 if (mode & SILC_UMODE_GONE) {
1445 if (!client->mode & SILC_UMODE_GONE)
1446 server->stat.aways++;
1448 if (client->mode & SILC_UMODE_GONE)
1449 server->stat.aways--;
1451 if (mode & SILC_UMODE_DETACHED) {
1452 if (!client->mode & SILC_UMODE_DETACHED)
1453 server->stat.detached++;
1455 if (client->mode & SILC_UMODE_DETACHED)
1456 server->stat.detached--;
1460 /* Change the mode */
1461 client->mode = mode;
1463 /* Check if anyone is watching this nickname */
1464 if (server->server_type == SILC_ROUTER)
1465 silc_server_check_watcher_list(server, client, NULL,
1466 SILC_NOTIFY_TYPE_UMODE_CHANGE);
1470 case SILC_NOTIFY_TYPE_BAN:
1475 SILC_LOG_DEBUG(("BAN notify"));
1477 /* Get Channel ID */
1478 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1481 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1485 /* Get channel entry */
1486 channel = silc_idlist_find_channel_by_id(server->global_list,
1489 channel = silc_idlist_find_channel_by_id(server->local_list,
1492 silc_free(channel_id);
1496 silc_free(channel_id);
1498 /* Get the new ban and add it to the ban list */
1499 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1501 if (!channel->ban_list)
1502 channel->ban_list = silc_calloc(tmp_len + 2,
1503 sizeof(*channel->ban_list));
1505 channel->ban_list = silc_realloc(channel->ban_list,
1506 sizeof(*channel->ban_list) *
1508 strlen(channel->ban_list) + 2));
1509 strncat(channel->ban_list, tmp, tmp_len);
1510 strncat(channel->ban_list, ",", 1);
1513 /* Get the ban to be removed and remove it from the list */
1514 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1515 if (tmp && channel->ban_list) {
1516 char *start, *end, *n;
1518 if (!strncmp(channel->ban_list, tmp, strlen(channel->ban_list) - 1)) {
1519 silc_free(channel->ban_list);
1520 channel->ban_list = NULL;
1522 start = strstr(channel->ban_list, tmp);
1523 if (start && strlen(start) >= tmp_len) {
1524 end = start + tmp_len;
1525 n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
1526 strncat(n, channel->ban_list, start - channel->ban_list);
1527 strncat(n, end + 1, ((channel->ban_list +
1528 strlen(channel->ban_list)) - end) - 1);
1529 silc_free(channel->ban_list);
1530 channel->ban_list = n;
1536 case SILC_NOTIFY_TYPE_ERROR:
1543 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1544 if (!tmp && tmp_len != 1)
1546 error = (SilcStatus)tmp[0];
1548 SILC_LOG_DEBUG(("ERROR notify (%d)", error));
1550 if (error == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID &&
1551 sock->type == SILC_SOCKET_TYPE_ROUTER) {
1552 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1554 SILC_LOG_DEBUG(("Received invalid client ID notification, deleting "
1555 "the entry from cache"));
1556 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1559 client = silc_idlist_find_client_by_id(server->global_list,
1560 client_id, FALSE, NULL);
1562 silc_server_remove_from_channels(server, NULL, client, TRUE,
1564 silc_idlist_del_client(server->global_list, client);
1566 silc_free(client_id);
1572 /* Ignore rest of the notify types for now */
1573 case SILC_NOTIFY_TYPE_NONE:
1574 case SILC_NOTIFY_TYPE_MOTD:
1581 silc_notify_payload_free(payload);
1584 void silc_server_notify_list(SilcServer server,
1585 SilcSocketConnection sock,
1586 SilcPacketContext *packet)
1588 SilcPacketContext *new;
1592 SILC_LOG_DEBUG(("Processing Notify List"));
1594 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1595 packet->src_id_type != SILC_ID_SERVER)
1598 /* Make copy of the original packet context, except for the actual
1599 data buffer, which we will here now fetch from the original buffer. */
1600 new = silc_packet_context_alloc();
1601 new->type = SILC_PACKET_NOTIFY;
1602 new->flags = packet->flags;
1603 new->src_id = packet->src_id;
1604 new->src_id_len = packet->src_id_len;
1605 new->src_id_type = packet->src_id_type;
1606 new->dst_id = packet->dst_id;
1607 new->dst_id_len = packet->dst_id_len;
1608 new->dst_id_type = packet->dst_id_type;
1610 buffer = silc_buffer_alloc(1024);
1611 new->buffer = buffer;
1613 while (packet->buffer->len) {
1614 SILC_GET16_MSB(len, packet->buffer->data + 2);
1615 if (len > packet->buffer->len)
1618 if (len > buffer->truelen) {
1619 silc_buffer_free(buffer);
1620 buffer = silc_buffer_alloc(1024 + len);
1623 silc_buffer_pull_tail(buffer, len);
1624 silc_buffer_put(buffer, packet->buffer->data, len);
1626 /* Process the Notify */
1627 silc_server_notify(server, sock, new);
1629 silc_buffer_push_tail(buffer, len);
1630 silc_buffer_pull(packet->buffer, len);
1633 silc_buffer_free(buffer);
1637 /* Received private message. This resolves the destination of the message
1638 and sends the packet. This is used by both server and router. If the
1639 destination is our locally connected client this sends the packet to
1640 the client. This may also send the message for further routing if
1641 the destination is not in our server (or router). */
1643 void silc_server_private_message(SilcServer server,
1644 SilcSocketConnection sock,
1645 SilcPacketContext *packet)
1647 SilcSocketConnection dst_sock;
1648 SilcIDListData idata;
1649 SilcClientEntry client;
1651 SILC_LOG_DEBUG(("Start"));
1653 if (packet->src_id_type != SILC_ID_CLIENT ||
1654 packet->dst_id_type != SILC_ID_CLIENT || !packet->dst_id)
1657 /* Get the route to the client */
1658 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1659 packet->dst_id_len, NULL,
1663 unsigned char error;
1665 if (client && client->mode & SILC_UMODE_DETACHED) {
1666 SILC_LOG_DEBUG(("Client is detached, discarding packet"));
1670 /* Send SILC_NOTIFY_TYPE_ERROR to indicate that such destination ID
1671 does not exist or is invalid. */
1672 idp = silc_id_payload_encode_data(packet->dst_id,
1674 packet->dst_id_type);
1678 error = SILC_STATUS_ERR_NO_SUCH_CLIENT_ID;
1679 if (packet->src_id_type == SILC_ID_CLIENT) {
1680 SilcClientID *client_id = silc_id_str2id(packet->src_id,
1682 packet->src_id_type);
1683 silc_server_send_notify_dest(server, sock, FALSE,
1684 client_id, SILC_ID_CLIENT,
1685 SILC_NOTIFY_TYPE_ERROR, 2,
1687 idp->data, idp->len);
1688 silc_free(client_id);
1690 silc_server_send_notify(server, sock, FALSE,
1691 SILC_NOTIFY_TYPE_ERROR, 2,
1693 idp->data, idp->len);
1696 silc_buffer_free(idp);
1700 /* Check whether destination client wishes to receive private messages */
1701 if (client && !(packet->flags & SILC_PACKET_FLAG_PRIVMSG_KEY) &&
1702 client->mode & SILC_UMODE_BLOCK_PRIVMSG) {
1703 SILC_LOG_DEBUG(("Client blocks private messages, discarding packet"));
1707 /* Send the private message */
1708 silc_server_send_private_message(server, dst_sock, idata->send_key,
1709 idata->hmac_send, idata->psn_send++,
1713 /* Received private message key packet.. This packet is never for us. It is to
1714 the client in the packet's destination ID. Sending of this sort of packet
1715 equals sending private message, ie. it is sent point to point from
1716 one client to another. */
1718 void silc_server_private_message_key(SilcServer server,
1719 SilcSocketConnection sock,
1720 SilcPacketContext *packet)
1722 SilcSocketConnection dst_sock;
1723 SilcIDListData idata;
1725 SILC_LOG_DEBUG(("Start"));
1727 if (packet->src_id_type != SILC_ID_CLIENT ||
1728 packet->dst_id_type != SILC_ID_CLIENT)
1731 if (!packet->dst_id)
1734 /* Get the route to the client */
1735 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1736 packet->dst_id_len, NULL,
1741 /* Relay the packet */
1742 silc_server_relay_packet(server, dst_sock, idata->send_key,
1743 idata->hmac_send, idata->psn_send++, packet, FALSE);
1746 /* Processes incoming command reply packet. The command reply packet may
1747 be destined to one of our clients or it may directly for us. We will
1748 call the command reply routine after processing the packet. */
1750 void silc_server_command_reply(SilcServer server,
1751 SilcSocketConnection sock,
1752 SilcPacketContext *packet)
1754 SilcBuffer buffer = packet->buffer;
1755 SilcClientEntry client = NULL;
1756 SilcSocketConnection dst_sock;
1757 SilcIDListData idata;
1758 SilcClientID *id = NULL;
1760 SILC_LOG_DEBUG(("Start"));
1762 /* Source must be server or router */
1763 if (packet->src_id_type != SILC_ID_SERVER &&
1764 sock->type != SILC_SOCKET_TYPE_ROUTER)
1767 if (packet->dst_id_type == SILC_ID_CHANNEL)
1770 if (packet->dst_id_type == SILC_ID_CLIENT) {
1771 /* Destination must be one of ours */
1772 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
1775 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
1777 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
1783 if (packet->dst_id_type == SILC_ID_SERVER) {
1784 /* For now this must be for us */
1785 if (memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
1786 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
1791 /* Execute command reply locally for the command */
1792 silc_server_command_reply_process(server, sock, buffer);
1794 if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
1795 /* Relay the packet to the client */
1796 const SilcBufferStruct p;
1798 dst_sock = (SilcSocketConnection)client->connection;
1799 idata = (SilcIDListData)client;
1801 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
1802 + packet->dst_id_len + packet->padlen);
1803 if (!silc_packet_send_prepare(dst_sock, 0, 0, buffer->len,
1804 idata->hmac_send, (const SilcBuffer)&p)) {
1805 SILC_LOG_ERROR(("Cannot send packet"));
1808 silc_buffer_put((SilcBuffer)&p, buffer->data, buffer->len);
1810 /* Encrypt packet */
1811 silc_packet_encrypt(idata->send_key, idata->hmac_send, idata->psn_send++,
1812 (SilcBuffer)&p, buffer->len);
1814 /* Send the packet */
1815 silc_server_packet_send_real(server, dst_sock, TRUE);
1821 /* Process received channel message. The message can be originated from
1822 client or server. */
1824 void silc_server_channel_message(SilcServer server,
1825 SilcSocketConnection sock,
1826 SilcPacketContext *packet)
1828 SilcChannelEntry channel = NULL;
1829 SilcChannelID *id = NULL;
1830 void *sender_id = NULL;
1831 SilcClientEntry sender_entry = NULL;
1832 SilcChannelClientEntry chl;
1835 SILC_LOG_DEBUG(("Processing channel message"));
1838 if (packet->dst_id_type != SILC_ID_CHANNEL) {
1839 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1843 /* Find channel entry */
1844 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
1847 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
1849 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
1852 unsigned char error;
1854 /* Send SILC_NOTIFY_TYPE_ERROR to indicate that such destination ID
1855 does not exist or is invalid. */
1856 idp = silc_id_payload_encode_data(packet->dst_id,
1858 packet->dst_id_type);
1862 error = SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID;
1863 if (packet->src_id_type == SILC_ID_CLIENT) {
1864 SilcClientID *client_id = silc_id_str2id(packet->src_id,
1866 packet->src_id_type);
1867 silc_server_send_notify_dest(server, sock, FALSE,
1868 client_id, SILC_ID_CLIENT,
1869 SILC_NOTIFY_TYPE_ERROR, 2,
1870 &error, 1, idp->data, idp->len);
1871 silc_free(client_id);
1873 silc_server_send_notify(server, sock, FALSE,
1874 SILC_NOTIFY_TYPE_ERROR, 2,
1875 &error, 1, idp->data, idp->len);
1878 silc_buffer_free(idp);
1883 /* See that this client is on the channel. If the original sender is
1884 not client (as it can be server as well) we don't do the check. */
1885 sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1886 packet->src_id_type);
1889 if (packet->src_id_type == SILC_ID_CLIENT) {
1890 sender_entry = silc_idlist_find_client_by_id(server->local_list,
1891 sender_id, TRUE, NULL);
1892 if (!sender_entry) {
1894 sender_entry = silc_idlist_find_client_by_id(server->global_list,
1895 sender_id, TRUE, NULL);
1897 if (!sender_entry || !silc_server_client_on_channel(sender_entry,
1899 SILC_LOG_DEBUG(("Client not on channel"));
1903 /* If channel is moderated check that client is allowed to send
1905 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS &&
1906 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
1907 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1908 SILC_LOG_DEBUG(("Channel is silenced from normal users"));
1911 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS &&
1912 chl->mode & SILC_CHANNEL_UMODE_CHANOP &&
1913 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1914 SILC_LOG_DEBUG(("Channel is silenced from operators"));
1917 if (chl->mode & SILC_CHANNEL_UMODE_QUIET) {
1918 SILC_LOG_DEBUG(("Sender is quieted on the channel"));
1922 /* If the packet is coming from router, but the client entry is local
1923 entry to us then some router is rerouting this to us and it is not
1924 allowed. When the client is local to us it means that we've routed
1925 this packet to network, and now someone is routing it back to us. */
1926 if (server->server_type == SILC_ROUTER &&
1927 sock->type == SILC_SOCKET_TYPE_ROUTER && local) {
1928 SILC_LOG_DEBUG(("Channel message rerouted to the sender, drop it"));
1933 /* Distribute the packet to our local clients. This will send the
1934 packet for further routing as well, if needed. */
1935 silc_server_packet_relay_to_channel(server, sock, channel, sender_id,
1936 packet->src_id_type, sender_entry,
1937 packet->buffer->data,
1938 packet->buffer->len, FALSE);
1941 silc_free(sender_id);
1945 /* Received channel key packet. We distribute the key to all of our locally
1946 connected clients on the channel. */
1948 void silc_server_channel_key(SilcServer server,
1949 SilcSocketConnection sock,
1950 SilcPacketContext *packet)
1952 SilcBuffer buffer = packet->buffer;
1953 SilcChannelEntry channel;
1955 if (packet->src_id_type != SILC_ID_SERVER ||
1956 (server->server_type == SILC_ROUTER &&
1957 sock->type == SILC_SOCKET_TYPE_ROUTER))
1960 /* Save the channel key */
1961 channel = silc_server_save_channel_key(server, buffer, NULL);
1965 /* Distribute the key to everybody who is on the channel. If we are router
1966 we will also send it to locally connected servers. */
1967 silc_server_send_channel_key(server, sock, channel, FALSE);
1969 if (server->server_type != SILC_BACKUP_ROUTER) {
1970 /* Distribute to local cell backup routers. */
1971 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
1972 SILC_PACKET_CHANNEL_KEY, 0,
1973 buffer->data, buffer->len, FALSE, TRUE);
1977 /* Received New Client packet and processes it. Creates Client ID for the
1978 client. Client becomes registered after calling this functions. */
1980 SilcClientEntry silc_server_new_client(SilcServer server,
1981 SilcSocketConnection sock,
1982 SilcPacketContext *packet)
1984 SilcBuffer buffer = packet->buffer;
1985 SilcClientEntry client;
1986 SilcClientID *client_id;
1987 SilcIDListData idata;
1988 char *username = NULL, *realname = NULL;
1989 SilcUInt16 username_len;
1992 char *hostname, *nickname;
1995 SILC_LOG_DEBUG(("Creating new client"));
1997 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
2000 /* Take client entry */
2001 client = (SilcClientEntry)sock->user_data;
2002 idata = (SilcIDListData)client;
2004 /* Remove the old cache entry. */
2005 if (!silc_idcache_del_by_context(server->local_list->clients, client)) {
2006 SILC_LOG_INFO(("Unauthenticated client attempted to register to network"));
2007 silc_server_disconnect_remote(server, sock,
2008 SILC_STATUS_ERR_NOT_AUTHENTICATED, NULL);
2009 if (sock->user_data)
2010 silc_server_free_sock_user_data(server, sock, NULL);
2014 /* Parse incoming packet */
2015 ret = silc_buffer_unformat(buffer,
2016 SILC_STR_UI16_NSTRING_ALLOC(&username,
2018 SILC_STR_UI16_STRING_ALLOC(&realname),
2021 silc_free(username);
2022 silc_free(realname);
2023 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2024 "connection", sock->hostname, sock->ip));
2025 silc_server_disconnect_remote(server, sock,
2026 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2028 if (sock->user_data)
2029 silc_server_free_sock_user_data(server, sock, NULL);
2034 silc_free(username);
2035 silc_free(realname);
2036 SILC_LOG_ERROR(("Client %s (%s) did not send its username, closing "
2037 "connection", sock->hostname, sock->ip));
2038 silc_server_disconnect_remote(server, sock,
2039 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2041 if (sock->user_data)
2042 silc_server_free_sock_user_data(server, sock, NULL);
2046 if (username_len > 128)
2047 username[128] = '\0';
2049 /* Check for bad characters for nickname, and modify the nickname if
2050 it includes those. */
2051 if (silc_server_name_bad_chars(username, username_len)) {
2052 nickname = silc_server_name_modify_bad(username, username_len);
2054 nickname = strdup(username);
2057 /* Make sanity checks for the hostname of the client. If the hostname
2058 is provided in the `username' check that it is the same than the
2059 resolved hostname, or if not resolved the hostname that appears in
2060 the client's public key. If the hostname is not present then put
2061 it from the resolved name or from the public key. */
2062 if (strchr(username, '@')) {
2063 SilcPublicKeyIdentifier pident;
2064 int tlen = strcspn(username, "@");
2065 char *phostname = NULL;
2067 hostname = silc_memdup(username + tlen + 1, strlen(username) - tlen - 1);
2069 if (strcmp(sock->hostname, sock->ip) &&
2070 strcmp(sock->hostname, hostname)) {
2071 silc_free(username);
2072 silc_free(hostname);
2073 silc_free(realname);
2074 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2075 "connection", sock->hostname, sock->ip));
2076 silc_server_disconnect_remote(server, sock,
2077 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2079 if (sock->user_data)
2080 silc_server_free_sock_user_data(server, sock, NULL);
2084 pident = silc_pkcs_decode_identifier(client->data.public_key->identifier);
2086 phostname = strdup(pident->host);
2087 silc_pkcs_free_identifier(pident);
2090 if (!strcmp(sock->hostname, sock->ip) &&
2091 phostname && strcmp(phostname, hostname)) {
2092 silc_free(username);
2093 silc_free(hostname);
2094 silc_free(phostname);
2095 silc_free(realname);
2096 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2097 "connection", sock->hostname, sock->ip));
2098 silc_server_disconnect_remote(server, sock,
2099 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2101 if (sock->user_data)
2102 silc_server_free_sock_user_data(server, sock, NULL);
2106 silc_free(phostname);
2108 /* The hostname is not present, add it. */
2110 /* XXX For now we cannot take the host name from the public key since
2111 they are not trusted or we cannot verify them as trusted. Just take
2112 what the resolved name or address is. */
2114 if (strcmp(sock->hostname, sock->ip)) {
2116 newusername = silc_calloc(strlen(username) +
2117 strlen(sock->hostname) + 2,
2118 sizeof(*newusername));
2119 strncat(newusername, username, strlen(username));
2120 strncat(newusername, "@", 1);
2121 strncat(newusername, sock->hostname, strlen(sock->hostname));
2122 silc_free(username);
2123 username = newusername;
2126 SilcPublicKeyIdentifier pident =
2127 silc_pkcs_decode_identifier(client->data.public_key->identifier);
2130 newusername = silc_calloc(strlen(username) +
2131 strlen(pident->host) + 2,
2132 sizeof(*newusername));
2133 strncat(newusername, username, strlen(username));
2134 strncat(newusername, "@", 1);
2135 strncat(newusername, pident->host, strlen(pident->host));
2136 silc_free(username);
2137 username = newusername;
2138 silc_pkcs_free_identifier(pident);
2144 /* Create Client ID */
2145 while (!silc_id_create_client_id(server, server->id, server->rng,
2146 server->md5hash, nickname, &client_id)) {
2149 silc_server_disconnect_remote(server, sock,
2150 SILC_STATUS_ERR_BAD_NICKNAME, NULL);
2151 if (sock->user_data)
2152 silc_server_free_sock_user_data(server, sock, NULL);
2155 snprintf(&nickname[strlen(nickname) - 1], 1, "%d", nickfail);
2158 /* Update client entry */
2159 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
2160 client->nickname = nickname;
2161 client->username = username;
2162 client->userinfo = realname ? realname : strdup(" ");
2163 client->id = client_id;
2164 id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
2166 /* Add the client again to the ID cache */
2167 silc_idcache_add(server->local_list->clients, client->nickname,
2168 client_id, client, 0, NULL);
2170 /* Notify our router about new client on the SILC network */
2171 if (!server->standalone)
2172 silc_server_send_new_id(server, (SilcSocketConnection)
2173 server->router->connection,
2174 server->server_type == SILC_ROUTER ? TRUE : FALSE,
2175 client->id, SILC_ID_CLIENT, id_len);
2177 /* Distribute to backup routers */
2178 if (server->server_type == SILC_ROUTER) {
2179 SilcBuffer idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
2180 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_ID, 0,
2181 idp->data, idp->len, FALSE, TRUE);
2182 silc_buffer_free(idp);
2185 /* Send the new client ID to the client. */
2186 silc_server_send_new_id(server, sock, FALSE, client->id, SILC_ID_CLIENT,
2187 silc_id_get_len(client->id, SILC_ID_CLIENT));
2189 /* Send some nice info to the client */
2190 silc_server_send_connect_notifys(server, sock, client);
2192 /* Check if anyone is watching this nickname */
2193 if (server->server_type == SILC_ROUTER)
2194 silc_server_check_watcher_list(server, client, NULL, 0);
2199 /* Create new server. This processes received New Server packet and
2200 saves the received Server ID. The server is our locally connected
2201 server thus we save all the information and save it to local list.
2202 This funtion can be used by both normal server and router server.
2203 If normal server uses this it means that its router has connected
2204 to the server. If router uses this it means that one of the cell's
2205 servers is connected to the router. */
2207 SilcServerEntry silc_server_new_server(SilcServer server,
2208 SilcSocketConnection sock,
2209 SilcPacketContext *packet)
2211 SilcBuffer buffer = packet->buffer;
2212 SilcServerEntry new_server, server_entry;
2213 SilcServerID *server_id;
2214 SilcIDListData idata;
2215 unsigned char *server_name, *id_string;
2216 SilcUInt16 id_len, name_len;
2220 SILC_LOG_DEBUG(("Creating new server"));
2222 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
2223 sock->type != SILC_SOCKET_TYPE_ROUTER)
2226 /* Take server entry */
2227 new_server = (SilcServerEntry)sock->user_data;
2228 idata = (SilcIDListData)new_server;
2230 /* Remove the old cache entry */
2231 if (!silc_idcache_del_by_context(server->local_list->servers, new_server)) {
2232 if (!silc_idcache_del_by_context(server->global_list->servers,
2234 SILC_LOG_INFO(("Unauthenticated %s attempted to register to "
2235 "network", (sock->type == SILC_SOCKET_TYPE_SERVER ?
2236 "server" : "router")));
2237 silc_server_disconnect_remote(server, sock,
2238 SILC_STATUS_ERR_NOT_AUTHENTICATED, NULL);
2239 if (sock->user_data)
2240 silc_server_free_sock_user_data(server, sock, NULL);
2246 /* Parse the incoming packet */
2247 ret = silc_buffer_unformat(buffer,
2248 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
2249 SILC_STR_UI16_NSTRING_ALLOC(&server_name,
2253 silc_free(id_string);
2254 silc_free(server_name);
2255 silc_server_disconnect_remote(server, sock,
2256 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2258 if (sock->user_data)
2259 silc_server_free_sock_user_data(server, sock, NULL);
2263 if (id_len > buffer->len) {
2264 silc_free(id_string);
2265 silc_free(server_name);
2266 silc_server_disconnect_remote(server, sock,
2267 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2269 if (sock->user_data)
2270 silc_server_free_sock_user_data(server, sock, NULL);
2275 server_name[255] = '\0';
2278 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
2280 silc_free(id_string);
2281 silc_free(server_name);
2282 silc_server_disconnect_remote(server, sock,
2283 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2285 if (sock->user_data)
2286 silc_server_free_sock_user_data(server, sock, NULL);
2289 silc_free(id_string);
2291 /* Check for valid server ID */
2292 if (!silc_id_is_valid_server_id(server, server_id, sock)) {
2293 SILC_LOG_INFO(("Invalid server ID sent by %s (%s)",
2294 sock->ip, sock->hostname));
2295 silc_server_disconnect_remote(server, sock,
2296 SILC_STATUS_ERR_BAD_SERVER_ID, NULL);
2297 if (sock->user_data)
2298 silc_server_free_sock_user_data(server, sock, NULL);
2299 silc_free(server_name);
2303 /* Check that we do not have this ID already */
2304 server_entry = silc_idlist_find_server_by_id(server->local_list,
2305 server_id, TRUE, NULL);
2307 silc_idcache_del_by_context(server->local_list->servers, server_entry);
2309 server_entry = silc_idlist_find_server_by_id(server->global_list,
2310 server_id, TRUE, NULL);
2312 silc_idcache_del_by_context(server->global_list->servers, server_entry);
2315 /* Update server entry */
2316 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
2317 new_server->server_name = server_name;
2318 new_server->id = server_id;
2320 SILC_LOG_DEBUG(("New server id(%s)",
2321 silc_id_render(server_id, SILC_ID_SERVER)));
2323 /* Add again the entry to the ID cache. */
2324 silc_idcache_add(local ? server->local_list->servers :
2325 server->global_list->servers, server_name, server_id,
2326 new_server, 0, NULL);
2328 /* Distribute the information about new server in the SILC network
2329 to our router. If we are normal server we won't send anything
2330 since this connection must be our router connection. */
2331 if (server->server_type == SILC_ROUTER && !server->standalone &&
2332 server->router->connection != sock)
2333 silc_server_send_new_id(server, server->router->connection,
2334 TRUE, new_server->id, SILC_ID_SERVER,
2335 silc_id_get_len(server_id, SILC_ID_SERVER));
2337 if (server->server_type == SILC_ROUTER) {
2338 /* Distribute to backup routers */
2339 SilcBuffer idp = silc_id_payload_encode(new_server->id, SILC_ID_SERVER);
2340 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_ID, 0,
2341 idp->data, idp->len, FALSE, TRUE);
2342 silc_buffer_free(idp);
2345 server->stat.cell_servers++;
2348 /* Check whether this router connection has been replaced by an
2349 backup router. If it has been then we'll disable the server and will
2350 ignore everything it will send until the backup router resuming
2351 protocol has been completed. */
2352 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
2353 silc_server_backup_replaced_get(server, server_id, NULL)) {
2354 /* Send packet to the server indicating that it cannot use this
2355 connection as it has been replaced by backup router. */
2356 SilcBuffer packet = silc_buffer_alloc(2);
2357 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
2358 silc_buffer_format(packet,
2359 SILC_STR_UI_CHAR(SILC_SERVER_BACKUP_REPLACED),
2360 SILC_STR_UI_CHAR(0),
2362 silc_server_packet_send(server, sock,
2363 SILC_PACKET_RESUME_ROUTER, 0,
2364 packet->data, packet->len, TRUE);
2365 silc_buffer_free(packet);
2367 /* Mark the router disabled. The data sent earlier will go but nothing
2368 after this does not go to this connection. */
2369 idata->status |= SILC_IDLIST_STATUS_DISABLED;
2371 /* If it is router announce our stuff to it. */
2372 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
2373 server->server_type == SILC_ROUTER) {
2374 silc_server_announce_servers(server, FALSE, 0, sock);
2375 silc_server_announce_clients(server, 0, sock);
2376 silc_server_announce_channels(server, 0, sock);
2383 /* Processes incoming New ID packet. New ID Payload is used to distribute
2384 information about newly registered clients and servers. */
2386 static void silc_server_new_id_real(SilcServer server,
2387 SilcSocketConnection sock,
2388 SilcPacketContext *packet,
2391 SilcBuffer buffer = packet->buffer;
2393 SilcServerEntry router, server_entry;
2394 SilcSocketConnection router_sock;
2399 SILC_LOG_DEBUG(("Processing new ID"));
2401 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2402 server->server_type == SILC_SERVER ||
2403 packet->src_id_type != SILC_ID_SERVER)
2406 idp = silc_id_payload_parse(buffer->data, buffer->len);
2410 id_type = silc_id_payload_get_type(idp);
2412 /* Normal server cannot have other normal server connections */
2413 server_entry = (SilcServerEntry)sock->user_data;
2414 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER &&
2415 server_entry->server_type == SILC_SERVER)
2418 id = silc_id_payload_get_id(idp);
2422 /* If the packet is coming from server then use the sender as the
2423 origin of the the packet. If it came from router then check the real
2424 sender of the packet and use that as the origin. */
2425 if (sock->type == SILC_SOCKET_TYPE_SERVER) {
2426 id_list = server->local_list;
2428 router = sock->user_data;
2430 /* If the sender is backup router and ID is server (and we are not
2431 backup router) then switch the entry to global list. */
2432 if (server_entry->server_type == SILC_BACKUP_ROUTER &&
2433 id_type == SILC_ID_SERVER &&
2434 server->id_entry->server_type != SILC_BACKUP_ROUTER) {
2435 id_list = server->global_list;
2436 router_sock = server->router ? server->router->connection : sock;
2439 void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2440 packet->src_id_type);
2441 router = silc_idlist_find_server_by_id(server->global_list,
2442 sender_id, TRUE, NULL);
2444 router = silc_idlist_find_server_by_id(server->local_list,
2445 sender_id, TRUE, NULL);
2446 silc_free(sender_id);
2448 id_list = server->global_list;
2455 case SILC_ID_CLIENT:
2457 SilcClientEntry entry;
2459 /* Check that we do not have this client already */
2460 entry = silc_idlist_find_client_by_id(server->global_list,
2461 id, server->server_type,
2464 entry = silc_idlist_find_client_by_id(server->local_list,
2465 id, server->server_type,
2468 SILC_LOG_DEBUG(("Ignoring client that we already have"));
2472 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
2473 silc_id_render(id, SILC_ID_CLIENT),
2474 sock->type == SILC_SOCKET_TYPE_SERVER ?
2475 "Server" : "Router", sock->hostname));
2477 /* As a router we keep information of all global information in our
2478 global list. Cell wide information however is kept in the local
2480 entry = silc_idlist_add_client(id_list, NULL, NULL, NULL,
2481 id, router, NULL, 0);
2483 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
2485 /* Inform the sender that the ID is not usable */
2486 silc_server_send_notify_signoff(server, sock, FALSE, id, NULL);
2489 entry->nickname = NULL;
2490 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2492 if (sock->type == SILC_SOCKET_TYPE_SERVER)
2493 server->stat.cell_clients++;
2494 server->stat.clients++;
2496 /* Check if anyone is watching this nickname */
2497 if (server->server_type == SILC_ROUTER && id_list == server->local_list)
2498 silc_server_check_watcher_list(server, entry, NULL, 0);
2502 case SILC_ID_SERVER:
2504 SilcServerEntry entry;
2506 /* If the ID is mine, ignore it. */
2507 if (SILC_ID_SERVER_COMPARE(id, server->id)) {
2508 SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
2512 /* If the ID is the sender's ID, ignore it (we have it already) */
2513 if (SILC_ID_SERVER_COMPARE(id, router->id)) {
2514 SILC_LOG_DEBUG(("Ignoring sender's own ID"));
2518 /* Check that we do not have this server already */
2519 entry = silc_idlist_find_server_by_id(server->global_list,
2520 id, server->server_type,
2523 entry = silc_idlist_find_server_by_id(server->local_list,
2524 id, server->server_type,
2527 SILC_LOG_DEBUG(("Ignoring server that we already have"));
2531 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
2532 silc_id_render(id, SILC_ID_SERVER),
2533 sock->type == SILC_SOCKET_TYPE_SERVER ?
2534 "Server" : "Router", sock->hostname));
2536 /* As a router we keep information of all global information in our
2537 global list. Cell wide information however is kept in the local
2539 entry = silc_idlist_add_server(id_list, NULL, 0, id, router,
2542 SILC_LOG_ERROR(("Could not add new server to the ID Cache"));
2545 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2547 if (sock->type == SILC_SOCKET_TYPE_SERVER)
2548 server->stat.cell_servers++;
2549 server->stat.servers++;
2553 case SILC_ID_CHANNEL:
2554 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
2563 /* If the sender of this packet is server and we are router we need to
2564 broadcast this packet to other routers in the network. */
2565 if (broadcast && server->server_type == SILC_ROUTER &&
2566 sock->type == SILC_SOCKET_TYPE_SERVER &&
2567 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2568 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
2569 if (!server->standalone)
2570 silc_server_packet_send(server, server->router->connection,
2572 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2573 buffer->data, buffer->len, FALSE);
2574 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
2575 packet->type, packet->flags,
2576 packet->buffer->data, packet->buffer->len,
2581 silc_id_payload_free(idp);
2585 /* Processes incoming New ID packet. New ID Payload is used to distribute
2586 information about newly registered clients and servers. */
2588 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
2589 SilcPacketContext *packet)
2591 silc_server_new_id_real(server, sock, packet, TRUE);
2594 /* Receoved New Id List packet, list of New ID payloads inside one
2595 packet. Process the New ID payloads one by one. */
2597 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
2598 SilcPacketContext *packet)
2600 SilcPacketContext *new_id;
2604 SILC_LOG_DEBUG(("Processing New ID List"));
2606 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2607 packet->src_id_type != SILC_ID_SERVER)
2610 /* If the sender of this packet is server and we are router we need to
2611 broadcast this packet to other routers in the network. Broadcast
2612 this list packet instead of multiple New ID packets. */
2613 if (server->server_type == SILC_ROUTER &&
2614 sock->type == SILC_SOCKET_TYPE_SERVER &&
2615 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2616 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
2617 if (!server->standalone)
2618 silc_server_packet_send(server, server->router->connection,
2620 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2621 packet->buffer->data,
2622 packet->buffer->len, FALSE);
2623 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
2624 packet->type, packet->flags,
2625 packet->buffer->data, packet->buffer->len,
2629 /* Make copy of the original packet context, except for the actual
2630 data buffer, which we will here now fetch from the original buffer. */
2631 new_id = silc_packet_context_alloc();
2632 new_id->type = SILC_PACKET_NEW_ID;
2633 new_id->flags = packet->flags;
2634 new_id->src_id = packet->src_id;
2635 new_id->src_id_len = packet->src_id_len;
2636 new_id->src_id_type = packet->src_id_type;
2637 new_id->dst_id = packet->dst_id;
2638 new_id->dst_id_len = packet->dst_id_len;
2639 new_id->dst_id_type = packet->dst_id_type;
2641 idp = silc_buffer_alloc(256);
2642 new_id->buffer = idp;
2644 while (packet->buffer->len) {
2645 SILC_GET16_MSB(id_len, packet->buffer->data + 2);
2646 if ((id_len > packet->buffer->len) ||
2647 (id_len > idp->truelen))
2650 silc_buffer_pull_tail(idp, 4 + id_len);
2651 silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
2653 /* Process the New ID */
2654 silc_server_new_id_real(server, sock, new_id, FALSE);
2656 silc_buffer_push_tail(idp, 4 + id_len);
2657 silc_buffer_pull(packet->buffer, 4 + id_len);
2660 silc_buffer_free(idp);
2664 /* Received New Channel packet. Information about new channels in the
2665 network are distributed using this packet. Save the information about
2666 the new channel. This usually comes from router but also normal server
2667 can send this to notify channels it has when it connects to us. */
2669 void silc_server_new_channel(SilcServer server,
2670 SilcSocketConnection sock,
2671 SilcPacketContext *packet)
2673 SilcChannelPayload payload;
2674 SilcChannelID *channel_id;
2676 SilcUInt32 name_len;
2680 SilcServerEntry server_entry;
2681 SilcChannelEntry channel;
2683 SILC_LOG_DEBUG(("Processing New Channel"));
2685 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2686 packet->src_id_type != SILC_ID_SERVER ||
2687 server->server_type == SILC_SERVER)
2690 /* Parse the channel payload */
2691 payload = silc_channel_payload_parse(packet->buffer->data,
2692 packet->buffer->len);
2696 /* Get the channel ID */
2697 channel_id = silc_channel_get_id_parse(payload);
2699 silc_channel_payload_free(payload);
2703 channel_name = silc_channel_get_name(payload, &name_len);
2705 channel_name[255] = '\0';
2707 id = silc_channel_get_id(payload, &id_len);
2709 server_entry = (SilcServerEntry)sock->user_data;
2711 if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
2712 /* Add the channel to global list as it is coming from router. It
2713 cannot be our own channel as it is coming from router. */
2715 /* Check that we don't already have this channel */
2716 channel = silc_idlist_find_channel_by_name(server->local_list,
2717 channel_name, NULL);
2719 channel = silc_idlist_find_channel_by_name(server->global_list,
2720 channel_name, NULL);
2722 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
2723 silc_id_render(channel_id, SILC_ID_CHANNEL),
2727 silc_idlist_add_channel(server->global_list, strdup(channel_name),
2728 0, channel_id, sock->user_data, NULL, NULL, 0);
2731 channel->disabled = TRUE;
2733 server->stat.channels++;
2734 if (server->server_type == SILC_ROUTER)
2735 channel->users_resolved = TRUE;
2738 /* The channel is coming from our server, thus it is in our cell
2739 we will add it to our local list. */
2742 SILC_LOG_DEBUG(("Channel id(%s) from [Server] %s",
2743 silc_id_render(channel_id, SILC_ID_CHANNEL),
2746 /* Check that we don't already have this channel */
2747 channel = silc_idlist_find_channel_by_name(server->local_list,
2748 channel_name, NULL);
2750 channel = silc_idlist_find_channel_by_name(server->global_list,
2751 channel_name, NULL);
2753 /* If the channel does not exist, then create it. This creates a new
2754 key to the channel as well that we will send to the server. */
2756 /* The protocol says that the Channel ID's IP address must be based
2757 on the router's IP address. Check whether the ID is based in our
2758 IP and if it is not then create a new ID and enforce the server
2759 to switch the ID. */
2760 if (server_entry->server_type != SILC_BACKUP_ROUTER &&
2761 !SILC_ID_COMPARE(channel_id, server->id, server->id->ip.data_len)) {
2763 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2765 if (silc_id_create_channel_id(server, server->id, server->rng, &tmp)) {
2766 silc_server_send_notify_channel_change(server, sock, FALSE,
2768 silc_free(channel_id);
2773 /* Create the channel with the provided Channel ID */
2774 channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
2778 silc_channel_payload_free(payload);
2779 silc_free(channel_id);
2782 channel->disabled = TRUE;
2784 /* Send the new channel key to the server */
2785 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2786 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
2787 chk = silc_channel_key_payload_encode(id_len, id,
2788 strlen(channel->channel_key->
2790 channel->channel_key->cipher->name,
2791 channel->key_len / 8,
2793 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
2794 chk->data, chk->len, FALSE);
2795 silc_buffer_free(chk);
2797 /* The channel exist by that name, check whether the ID's match.
2798 If they don't then we'll force the server to use the ID we have.
2799 We also create a new key for the channel. */
2800 SilcBuffer modes = NULL, users = NULL, users_modes = NULL;
2802 if (!SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
2803 /* They don't match, send CHANNEL_CHANGE notify to the server to
2804 force the ID change. */
2805 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2806 silc_server_send_notify_channel_change(server, sock, FALSE,
2807 channel_id, channel->id);
2810 /* If the mode is different from what we have then enforce the
2812 mode = silc_channel_get_mode(payload);
2813 if (channel->mode != mode) {
2814 SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
2815 silc_server_send_notify_cmode(server, sock, FALSE, channel,
2816 channel->mode, server->id,
2817 SILC_ID_SERVER, channel->cipher,
2819 channel->passphrase,
2820 channel->founder_key);
2823 /* Create new key for the channel and send it to the server and
2824 everybody else possibly on the channel. */
2825 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
2826 if (!silc_server_create_channel_key(server, channel, 0))
2829 /* Send to the channel */
2830 silc_server_send_channel_key(server, sock, channel, FALSE);
2831 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2832 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
2834 /* Send to the server */
2835 chk = silc_channel_key_payload_encode(id_len, id,
2836 strlen(channel->channel_key->
2838 channel->channel_key->
2840 channel->key_len / 8,
2842 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
2843 chk->data, chk->len, FALSE);
2844 silc_buffer_free(chk);
2848 silc_free(channel_id);
2850 /* Update statistics */
2851 server->stat.channels++;
2852 server->stat.cell_channels++;
2854 /* Since the channel is coming from server and we also know about it
2855 then send the JOIN notify to the server so that it see's our
2856 users on the channel "joining" the channel. */
2857 silc_server_announce_get_channel_users(server, channel, &modes, &users,
2860 silc_buffer_push(modes, modes->data - modes->head);
2861 silc_server_packet_send_dest(server, sock,
2862 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2863 channel->id, SILC_ID_CHANNEL,
2864 modes->data, modes->len, FALSE);
2865 silc_buffer_free(modes);
2868 silc_buffer_push(users, users->data - users->head);
2869 silc_server_packet_send(server, sock,
2870 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2871 users->data, users->len, FALSE);
2872 silc_buffer_free(users);
2875 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
2876 silc_server_packet_send_dest(server, sock,
2877 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2878 channel->id, SILC_ID_CHANNEL,
2880 users_modes->len, FALSE);
2881 silc_buffer_free(users_modes);
2886 silc_channel_payload_free(payload);
2889 /* Received New Channel List packet, list of New Channel List payloads inside
2890 one packet. Process the New Channel payloads one by one. */
2892 void silc_server_new_channel_list(SilcServer server,
2893 SilcSocketConnection sock,
2894 SilcPacketContext *packet)
2896 SilcPacketContext *new;
2898 SilcUInt16 len1, len2;
2900 SILC_LOG_DEBUG(("Processing New Channel List"));
2902 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2903 packet->src_id_type != SILC_ID_SERVER ||
2904 server->server_type == SILC_SERVER)
2907 /* If the sender of this packet is server and we are router we need to
2908 broadcast this packet to other routers in the network. Broadcast
2909 this list packet instead of multiple New Channel packets. */
2910 if (server->server_type == SILC_ROUTER &&
2911 sock->type == SILC_SOCKET_TYPE_SERVER &&
2912 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2913 SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
2914 if (!server->standalone)
2915 silc_server_packet_send(server, server->router->connection,
2917 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2918 packet->buffer->data,
2919 packet->buffer->len, FALSE);
2920 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
2921 packet->type, packet->flags,
2922 packet->buffer->data, packet->buffer->len,
2926 /* Make copy of the original packet context, except for the actual
2927 data buffer, which we will here now fetch from the original buffer. */
2928 new = silc_packet_context_alloc();
2929 new->type = SILC_PACKET_NEW_CHANNEL;
2930 new->flags = packet->flags;
2931 new->src_id = packet->src_id;
2932 new->src_id_len = packet->src_id_len;
2933 new->src_id_type = packet->src_id_type;
2934 new->dst_id = packet->dst_id;
2935 new->dst_id_len = packet->dst_id_len;
2936 new->dst_id_type = packet->dst_id_type;
2938 buffer = silc_buffer_alloc(512);
2939 new->buffer = buffer;
2941 while (packet->buffer->len) {
2942 SILC_GET16_MSB(len1, packet->buffer->data);
2943 if ((len1 > packet->buffer->len) ||
2944 (len1 > buffer->truelen))
2947 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
2948 if ((len2 > packet->buffer->len) ||
2949 (len2 > buffer->truelen))
2952 silc_buffer_pull_tail(buffer, 8 + len1 + len2);
2953 silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
2955 /* Process the New Channel */
2956 silc_server_new_channel(server, sock, new);
2958 silc_buffer_push_tail(buffer, 8 + len1 + len2);
2959 silc_buffer_pull(packet->buffer, 8 + len1 + len2);
2962 silc_buffer_free(buffer);
2966 /* Received key agreement packet. This packet is never for us. It is to
2967 the client in the packet's destination ID. Sending of this sort of packet
2968 equals sending private message, ie. it is sent point to point from
2969 one client to another. */
2971 void silc_server_key_agreement(SilcServer server,
2972 SilcSocketConnection sock,
2973 SilcPacketContext *packet)
2975 SilcSocketConnection dst_sock;
2976 SilcIDListData idata;
2978 SILC_LOG_DEBUG(("Start"));
2980 if (packet->src_id_type != SILC_ID_CLIENT ||
2981 packet->dst_id_type != SILC_ID_CLIENT)
2984 if (!packet->dst_id)
2987 /* Get the route to the client */
2988 dst_sock = silc_server_get_client_route(server, packet->dst_id,
2989 packet->dst_id_len, NULL,
2994 /* Relay the packet */
2995 silc_server_relay_packet(server, dst_sock, idata->send_key,
2996 idata->hmac_send, idata->psn_send++,
3000 /* Received connection auth request packet that is used during connection
3001 phase to resolve the mandatory authentication method. This packet can
3002 actually be received at anytime but usually it is used only during
3003 the connection authentication phase. Now, protocol says that this packet
3004 can come from client or server, however, we support only this coming
3005 from client and expect that server always knows what authentication
3008 void silc_server_connection_auth_request(SilcServer server,
3009 SilcSocketConnection sock,
3010 SilcPacketContext *packet)
3012 SilcServerConfigClient *client = NULL;
3013 SilcUInt16 conn_type;
3015 SilcAuthMethod auth_meth = SILC_AUTH_NONE;
3017 SILC_LOG_DEBUG(("Start"));
3019 if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT)
3022 /* Parse the payload */
3023 ret = silc_buffer_unformat(packet->buffer,
3024 SILC_STR_UI_SHORT(&conn_type),
3025 SILC_STR_UI_SHORT(NULL),
3030 if (conn_type != SILC_SOCKET_TYPE_CLIENT)
3033 /* Get the authentication method for the client */
3034 auth_meth = SILC_AUTH_NONE;
3035 client = silc_server_config_find_client(server, sock->ip);
3037 client = silc_server_config_find_client(server, sock->hostname);
3039 if (client->passphrase) {
3040 if (client->publickeys && !server->config->prefer_passphrase_auth)
3041 auth_meth = SILC_AUTH_PUBLIC_KEY;
3043 auth_meth = SILC_AUTH_PASSWORD;
3044 } else if (client->publickeys)
3045 auth_meth = SILC_AUTH_PUBLIC_KEY;
3048 /* Send it back to the client */
3049 silc_server_send_connection_auth_request(server, sock, conn_type, auth_meth);
3052 /* Received REKEY packet. The sender of the packet wants to regenerate
3053 its session keys. This starts the REKEY protocol. */
3055 void silc_server_rekey(SilcServer server,
3056 SilcSocketConnection sock,
3057 SilcPacketContext *packet)
3059 SilcProtocol protocol;
3060 SilcServerRekeyInternalContext *proto_ctx;
3061 SilcIDListData idata = (SilcIDListData)sock->user_data;
3063 SILC_LOG_DEBUG(("Start"));
3065 /* Allocate internal protocol context. This is sent as context
3067 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
3068 proto_ctx->server = (void *)server;
3069 proto_ctx->sock = sock;
3070 proto_ctx->responder = TRUE;
3071 proto_ctx->pfs = idata->rekey->pfs;
3073 /* Perform rekey protocol. Will call the final callback after the
3074 protocol is over. */
3075 silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
3076 &protocol, proto_ctx, silc_server_rekey_final);
3077 sock->protocol = protocol;
3079 if (proto_ctx->pfs == FALSE)
3080 /* Run the protocol */
3081 silc_protocol_execute(protocol, server->schedule, 0, 0);
3084 /* Received file transger packet. This packet is never for us. It is to
3085 the client in the packet's destination ID. Sending of this sort of packet
3086 equals sending private message, ie. it is sent point to point from
3087 one client to another. */
3089 void silc_server_ftp(SilcServer server,
3090 SilcSocketConnection sock,
3091 SilcPacketContext *packet)
3093 SilcSocketConnection dst_sock;
3094 SilcIDListData idata;
3096 SILC_LOG_DEBUG(("Start"));
3098 if (packet->src_id_type != SILC_ID_CLIENT ||
3099 packet->dst_id_type != SILC_ID_CLIENT)
3102 if (!packet->dst_id)
3105 /* Get the route to the client */
3106 dst_sock = silc_server_get_client_route(server, packet->dst_id,
3107 packet->dst_id_len, NULL,
3112 /* Relay the packet */
3113 silc_server_relay_packet(server, dst_sock, idata->send_key,
3114 idata->hmac_send, idata->psn_send++,
3120 SilcSocketConnection sock;
3121 SilcPacketContext *packet;
3123 } *SilcServerResumeResolve;
3125 SILC_SERVER_CMD_FUNC(resume_resolve)
3127 SilcServerResumeResolve r = (SilcServerResumeResolve)context;
3128 SilcServer server = r->server;
3129 SilcSocketConnection sock = r->sock;
3130 SilcServerCommandReplyContext reply = context2;
3131 SilcClientEntry client;
3133 SILC_LOG_DEBUG(("Start"));
3135 if (!reply || !silc_command_get_status(reply->payload, NULL, NULL)) {
3136 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3137 "closing connection", sock->hostname, sock->ip));
3138 silc_server_disconnect_remote(server, sock,
3139 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3140 "Resuming not possible");
3144 if (reply && silc_command_get(reply->payload) == SILC_COMMAND_WHOIS) {
3145 /* Get entry to the client, and resolve it if we don't have it. */
3146 client = silc_idlist_find_client_by_id(server->local_list,
3147 r->data, TRUE, NULL);
3149 client = silc_idlist_find_client_by_id(server->global_list,
3150 r->data, TRUE, NULL);
3152 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3153 "closing connection", sock->hostname, sock->ip));
3154 silc_server_disconnect_remote(server, sock,
3155 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3156 "Resuming not possible");
3161 if (!(client->mode & SILC_UMODE_DETACHED)) {
3162 SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, "
3163 "closing connection", sock->hostname, sock->ip));
3164 silc_server_disconnect_remote(server, sock,
3165 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3166 "Resuming not possible");
3171 /* Reprocess the packet */
3172 silc_server_resume_client(server, sock, r->packet);
3175 silc_socket_free(r->sock);
3176 silc_packet_context_free(r->packet);
3181 /* Received client resuming packet. This is used to resume detached
3182 client session. It can be sent by the client who wishes to resume
3183 but this is also sent by servers and routers to notify other routers
3184 that the client is not detached anymore. */
3186 void silc_server_resume_client(SilcServer server,
3187 SilcSocketConnection sock,
3188 SilcPacketContext *packet)
3190 SilcBuffer buffer = packet->buffer, buf;
3191 SilcIDListData idata;
3192 SilcClientEntry detached_client;
3193 SilcClientID *client_id = NULL;
3194 unsigned char *id_string, *auth = NULL;
3195 SilcUInt16 id_len, auth_len = 0;
3196 int ret, nickfail = 0;
3197 bool resolved, local, nick_change = FALSE, resolve = FALSE;
3198 SilcChannelEntry channel;
3199 SilcHashTableList htl;
3200 SilcChannelClientEntry chl;
3201 SilcServerResumeResolve r;
3203 SILC_LOG_DEBUG(("Start"));
3205 ret = silc_buffer_unformat(buffer,
3206 SILC_STR_UI16_NSTRING(&id_string, &id_len),
3209 client_id = silc_id_str2id(id_string, id_len, SILC_ID_CLIENT);
3211 if (sock->type == SILC_SOCKET_TYPE_CLIENT) {
3212 /* Client send this and is attempting to resume to old client session */
3213 SilcClientEntry client;
3217 silc_buffer_pull(buffer, 2 + id_len);
3218 auth = buffer->data;
3219 auth_len = buffer->len;
3220 silc_buffer_push(buffer, 2 + id_len);
3223 if (!client_id || auth_len < 128) {
3224 SILC_LOG_ERROR(("Client %s (%s) sent incomplete resume information, "
3225 "closing connection", sock->hostname, sock->ip));
3226 silc_server_disconnect_remote(server, sock,
3227 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3228 "Resuming not possible");
3232 /* Take client entry of this connection */
3233 client = (SilcClientEntry)sock->user_data;
3234 idata = (SilcIDListData)client;
3236 /* Get entry to the client, and resolve it if we don't have it. */
3237 detached_client = silc_server_get_client_resolve(server, client_id, FALSE,
3239 if (!detached_client) {
3241 /* The client info is being resolved. Reprocess this packet after
3242 receiving the reply to the query. */
3243 SILC_LOG_DEBUG(("Resolving client"));
3244 r = silc_calloc(1, sizeof(*r));
3248 r->sock = silc_socket_dup(sock);
3249 r->packet = silc_packet_context_dup(packet);
3250 r->data = silc_id_dup(client_id, SILC_ID_CLIENT);
3251 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
3253 silc_server_command_resume_resolve, r);
3255 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3256 "closing connection", sock->hostname, sock->ip));
3257 silc_server_disconnect_remote(server, sock,
3258 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3259 "Resuming not possible");
3264 if (!(detached_client->mode & SILC_UMODE_DETACHED))
3266 if (!silc_hash_table_count(detached_client->channels) &&
3267 detached_client->router)
3269 if (!detached_client->nickname)
3273 if (server->server_type == SILC_SERVER && !server->standalone) {
3274 /* The client info is being resolved. Reprocess this packet after
3275 receiving the reply to the query. */
3276 SILC_LOG_DEBUG(("Resolving client info"));
3277 silc_server_get_client_resolve(server, client_id, TRUE, NULL);
3278 r = silc_calloc(1, sizeof(*r));
3282 r->sock = silc_socket_dup(sock);
3283 r->packet = silc_packet_context_dup(packet);
3284 r->data = silc_id_dup(client_id, SILC_ID_CLIENT);
3285 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
3287 silc_server_command_resume_resolve, r);
3290 if (server->server_type == SILC_SERVER) {
3291 SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, "
3292 "closing connection", sock->hostname, sock->ip));
3293 silc_server_disconnect_remote(server, sock,
3294 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3295 "Resuming not possible");
3300 /* Check that we have the public key of the client, if not then we must
3301 resolve it first. */
3302 if (!detached_client->data.public_key) {
3303 if (server->server_type == SILC_SERVER && server->standalone) {
3304 silc_server_disconnect_remote(server, sock,
3305 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3306 "Resuming not possible");
3308 /* We must retrieve the detached client's public key by sending
3309 GETKEY command. Reprocess this packet after receiving the key */
3310 SilcBuffer idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
3311 SilcSocketConnection dest_sock =
3312 silc_server_get_client_route(server, NULL, 0, client_id, NULL, NULL);
3314 SILC_LOG_DEBUG(("Resolving client public key"));
3316 silc_server_send_command(server, dest_sock ? dest_sock :
3317 server->router->connection,
3318 SILC_COMMAND_GETKEY, ++server->cmd_ident,
3319 1, 1, idp->data, idp->len);
3321 r = silc_calloc(1, sizeof(*r));
3326 r->sock = silc_socket_dup(sock);
3327 r->packet = silc_packet_context_dup(packet);
3328 silc_server_command_pending(server, SILC_COMMAND_GETKEY,
3330 silc_server_command_resume_resolve, r);
3332 silc_buffer_free(idp);
3335 } else if (!silc_pkcs_public_key_compare(detached_client->data.public_key,
3336 idata->public_key)) {
3337 /* We require that the connection and resuming authentication data
3338 must be using same key pair. */
3339 silc_server_disconnect_remote(server, sock,
3340 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3341 "Resuming not possible");
3345 /* Verify the authentication payload. This has to be successful in
3346 order to allow the resuming */
3348 !silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
3349 detached_client->data.public_key, 0,
3350 idata->hash, detached_client->id,
3352 SILC_LOG_ERROR(("Client %s (%s) resume authentication failed, "
3353 "closing connection", sock->hostname, sock->ip));
3354 silc_server_disconnect_remote(server, sock,
3355 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3356 "Resuming not possible");
3360 /* Now resume the client to the network */
3362 silc_schedule_task_del_by_context(server->schedule, detached_client);
3363 sock->user_data = detached_client;
3364 detached_client->connection = sock;
3366 /* Take new keys and stuff into use in the old entry */
3367 silc_idlist_del_data(detached_client);
3368 silc_idlist_add_data(detached_client, idata);
3369 detached_client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
3370 detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
3371 detached_client->mode &= ~SILC_UMODE_DETACHED;
3373 /* Send the RESUME_CLIENT packet to our primary router so that others
3374 know this client isn't detached anymore. */
3375 buf = silc_buffer_alloc_size(2 + id_len);
3376 silc_buffer_format(buf,
3377 SILC_STR_UI_SHORT(id_len),
3378 SILC_STR_UI_XNSTRING(id_string, id_len),
3381 /* Send to primary router */
3382 if (!server->standalone)
3383 silc_server_packet_send(server, server->router->connection,
3384 SILC_PACKET_RESUME_CLIENT, 0,
3385 buf->data, buf->len, TRUE);
3387 /* As router we must deliver this packet directly to the original
3388 server whom this client was earlier. */
3389 if (server->server_type == SILC_ROUTER && detached_client->router &&
3390 detached_client->router->server_type != SILC_ROUTER)
3391 silc_server_packet_send(server, detached_client->router->connection,
3392 SILC_PACKET_RESUME_CLIENT, 0,
3393 buf->data, buf->len, TRUE);
3394 silc_buffer_free(buf);
3396 detached_client->router = NULL;
3398 /* Delete this client entry since we're resuming to old one. */
3399 server->stat.my_clients--;
3400 server->stat.clients--;
3401 if (server->stat.cell_clients)
3402 server->stat.cell_clients--;
3403 silc_server_del_from_watcher_list(server, client);
3404 silc_idlist_del_client(server->local_list, client);
3405 client = detached_client;
3407 /* If the ID is not based in our ID then change it */
3408 if (!SILC_ID_COMPARE(client->id, server->id, server->id->ip.data_len)) {
3409 while (!silc_id_create_client_id(server, server->id, server->rng,
3410 server->md5hash, client->nickname,
3414 silc_server_disconnect_remote(server, sock,
3415 SILC_STATUS_ERR_BAD_NICKNAME, NULL);
3418 snprintf(&client->nickname[strlen(client->nickname) - 1], 1,
3425 /* Notify about Client ID change, nickname doesn't actually change. */
3426 if (!server->standalone)
3427 silc_server_send_notify_nick_change(server, server->router->connection,
3428 FALSE, client->id, client_id,
3432 /* Resolve users on those channels that client has joined but we
3433 haven't resolved user list yet. */
3434 if (server->server_type == SILC_SERVER && !server->standalone) {
3435 silc_hash_table_list(client->channels, &htl);
3436 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
3437 channel = chl->channel;
3438 SILC_LOG_DEBUG(("Resolving users for %s channel",
3439 channel->channel_name));
3440 if (channel->disabled || !channel->users_resolved) {
3441 silc_server_send_command(server, server->router->connection,
3442 SILC_COMMAND_USERS, ++server->cmd_ident,
3443 1, 2, channel->channel_name,
3444 strlen(channel->channel_name));
3447 silc_hash_table_list_reset(&htl);
3450 /* Send the new client ID to the client. After this client may start
3451 receiving other packets, and may start sending packets too. */
3452 silc_server_send_new_id(server, sock, FALSE, client_id, SILC_ID_CLIENT,
3453 silc_id_get_len(client_id, SILC_ID_CLIENT));
3456 /* Send NICK change notify to channels as well. */
3457 SilcBuffer oidp, nidp;
3458 oidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3459 nidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
3460 silc_server_send_notify_on_channels(server, NULL, client,
3461 SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
3462 oidp->data, oidp->len,
3463 nidp->data, nidp->len,
3465 strlen(client->nickname));
3466 silc_buffer_free(oidp);
3467 silc_buffer_free(nidp);
3470 /* Add the client again to the ID cache to get it to correct list */
3471 if (!silc_idcache_del_by_context(server->local_list->clients, client))
3472 silc_idcache_del_by_context(server->global_list->clients, client);
3473 silc_free(client->id);
3474 client->id = client_id;
3476 silc_idcache_add(server->local_list->clients, client->nickname,
3477 client->id, client, 0, NULL);
3479 /* Send some nice info to the client */
3480 silc_server_send_connect_notifys(server, sock, client);
3482 /* Send all channel keys of channels the client has joined */
3483 silc_hash_table_list(client->channels, &htl);
3484 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
3485 bool created = FALSE;
3486 channel = chl->channel;
3488 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY)
3491 /* If we don't have channel key, then create one */
3492 if (!channel->channel_key) {
3493 if (!silc_server_create_channel_key(server, channel, 0))
3498 id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3500 silc_channel_key_payload_encode(silc_id_get_len(channel->id,
3503 strlen(channel->channel_key->
3505 channel->channel_key->cipher->name,
3506 channel->key_len / 8, channel->key);
3507 silc_free(id_string);
3509 /* Send the key packet to client */
3510 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
3511 keyp->data, keyp->len, FALSE);
3513 if (created && server->server_type == SILC_SERVER &&
3514 !server->standalone)
3515 silc_server_packet_send(server, server->router->connection,
3516 SILC_PACKET_CHANNEL_KEY, 0,
3517 keyp->data, keyp->len, FALSE);
3519 silc_buffer_free(keyp);
3521 silc_hash_table_list_reset(&htl);
3523 } else if (sock->type != SILC_SOCKET_TYPE_CLIENT) {
3524 /* Server or router sent this to us to notify that that a client has
3526 SilcServerEntry server_entry;
3527 SilcServerID *server_id;
3532 /* Get entry to the client, and resolve it if we don't have it. */
3533 detached_client = silc_idlist_find_client_by_id(server->local_list,
3534 client_id, TRUE, NULL);
3535 if (!detached_client) {
3536 detached_client = silc_idlist_find_client_by_id(server->global_list,
3537 client_id, TRUE, NULL);
3538 if (!detached_client)
3542 /* Check that the client has not been resumed already because it is
3543 protocol error to attempt to resume more than once. The client
3544 will be killed if this protocol error occurs. */
3545 if (detached_client->data.status & SILC_IDLIST_STATUS_RESUMED &&
3546 !(detached_client->mode & SILC_UMODE_DETACHED)) {
3547 /* The client is clearly attempting to resume more than once and
3548 perhaps playing around by resuming from several different places
3549 at the same time. */
3550 silc_server_kill_client(server, detached_client, NULL,
3551 server->id, SILC_ID_SERVER);
3555 /* Check whether client is detached at all */
3556 if (!(detached_client->mode & SILC_UMODE_DETACHED))
3559 /* Client is detached, and now it is resumed. Remove the detached
3560 mode and mark that it is resumed. */
3561 detached_client->mode &= ~SILC_UMODE_DETACHED;
3562 detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
3564 /* Get the new owner of the resumed client */
3565 server_id = silc_id_str2id(packet->src_id, packet->src_id_len,
3566 packet->src_id_type);
3570 /* Get server entry */
3571 server_entry = silc_idlist_find_server_by_id(server->global_list,
3572 server_id, TRUE, NULL);
3574 if (!server_entry) {
3575 server_entry = silc_idlist_find_server_by_id(server->local_list,
3576 server_id, TRUE, NULL);
3578 if (!server_entry) {
3579 silc_free(server_id);
3584 if (server->server_type == SILC_ROUTER &&
3585 sock->type == SILC_SOCKET_TYPE_ROUTER &&
3586 server_entry->server_type == SILC_ROUTER)
3589 SILC_LOG_DEBUG(("Resuming detached client"));
3591 /* Change the client to correct list. */
3592 if (!silc_idcache_del_by_context(server->local_list->clients,
3594 silc_idcache_del_by_context(server->global_list->clients,
3596 silc_idcache_add(local && server->server_type == SILC_ROUTER ?
3597 server->local_list->clients :
3598 server->global_list->clients,
3599 detached_client->nickname,
3600 detached_client->id, detached_client, FALSE, NULL);
3602 /* Change the owner of the client if needed */
3603 if (detached_client->router != server_entry)
3604 detached_client->router = server_entry;
3606 /* Update channel information regarding global clients on channel. */
3607 if (server->server_type == SILC_SERVER) {
3608 silc_hash_table_list(detached_client->channels, &htl);
3609 while (silc_hash_table_get(&htl, NULL, (void **)&chl))
3610 chl->channel->global_users =
3611 silc_server_channel_has_global(chl->channel);
3612 silc_hash_table_list_reset(&htl);
3615 silc_schedule_task_del_by_context(server->schedule, detached_client);
3617 /* If the sender of this packet is server and we are router we need to
3618 broadcast this packet to other routers in the network. */
3619 if (server->server_type == SILC_ROUTER &&
3620 sock->type == SILC_SOCKET_TYPE_SERVER &&
3621 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
3622 SILC_LOG_DEBUG(("Broadcasting received Resume Client packet"));
3623 if (!server->standalone)
3624 silc_server_packet_send(server, server->router->connection,
3626 packet->flags | SILC_PACKET_FLAG_BROADCAST,
3627 buffer->data, buffer->len, FALSE);
3628 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
3629 packet->type, packet->flags,
3630 packet->buffer->data, packet->buffer->len,
3634 silc_free(server_id);
3637 silc_free(client_id);