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->standalone && 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 silc_server_packet_send_dest(server, server->router->connection,
102 packet->flags | SILC_PACKET_FLAG_BROADCAST,
103 channel_id, SILC_ID_CHANNEL,
104 packet->buffer->data, packet->buffer->len,
106 silc_server_backup_send_dest(server, (SilcServerEntry)sock->user_data,
107 packet->type, packet->flags,
108 channel_id, SILC_ID_CHANNEL,
109 packet->buffer->data, packet->buffer->len,
112 /* Packet is destined to client or server */
113 silc_server_packet_send(server, server->router->connection,
115 packet->flags | SILC_PACKET_FLAG_BROADCAST,
116 packet->buffer->data, packet->buffer->len,
118 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
119 packet->type, packet->flags,
120 packet->buffer->data, packet->buffer->len,
125 type = silc_notify_get_type(payload);
126 args = silc_notify_get_args(payload);
131 case SILC_NOTIFY_TYPE_JOIN:
133 * Distribute the notify to local clients on the channel
135 SILC_LOG_DEBUG(("JOIN notify"));
138 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
141 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
145 /* Get channel entry */
146 channel = silc_idlist_find_channel_by_id(server->global_list,
149 channel = silc_idlist_find_channel_by_id(server->local_list,
152 silc_free(channel_id);
156 silc_free(channel_id);
159 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
162 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
166 /* If the the client is not in local list we check global list (ie. the
167 channel will be global channel) and if it does not exist then create
168 entry for the client. */
169 client = silc_idlist_find_client_by_id(server->global_list,
170 client_id, server->server_type,
173 client = silc_idlist_find_client_by_id(server->local_list,
174 client_id, server->server_type,
177 /* If router did not find the client the it is bogus */
178 if (server->server_type != SILC_SERVER)
182 silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
183 silc_id_dup(client_id, SILC_ID_CLIENT),
184 sock->user_data, NULL, 0);
186 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
187 silc_free(client_id);
191 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
195 /* Do not process the notify if the client is not registered */
196 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
199 /* Do not add client to channel if it is there already */
200 if (silc_server_client_on_channel(client, channel, NULL)) {
201 SILC_LOG_DEBUG(("Client already on channel"));
205 /* Send to channel */
206 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
207 FALSE, packet->buffer->data,
208 packet->buffer->len, FALSE);
210 if (server->server_type != SILC_ROUTER &&
211 sock->type == SILC_SOCKET_TYPE_ROUTER)
212 /* The channel is global now */
213 channel->global_users = TRUE;
215 SILC_LOG_DEBUG(("Joining to channel %s", channel->channel_name));
217 /* JOIN the global client to the channel (local clients (if router
218 created the channel) is joined in the pending JOIN command). */
219 chl = silc_calloc(1, sizeof(*chl));
220 chl->client = client;
221 chl->channel = channel;
223 /* If this is the first one on the channel then it is the founder of
225 if (!silc_hash_table_count(channel->user_list))
226 chl->mode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
228 silc_hash_table_add(channel->user_list, client, chl);
229 silc_hash_table_add(client->channels, channel, chl);
230 silc_free(client_id);
231 channel->user_count++;
232 channel->disabled = FALSE;
236 case SILC_NOTIFY_TYPE_LEAVE:
238 * Distribute the notify to local clients on the channel
240 SILC_LOG_DEBUG(("LEAVE notify"));
243 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
244 packet->dst_id_type);
249 /* Get channel entry */
250 channel = silc_idlist_find_channel_by_id(server->global_list,
253 channel = silc_idlist_find_channel_by_id(server->local_list,
256 silc_free(channel_id);
262 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
264 silc_free(channel_id);
267 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
269 silc_free(channel_id);
273 /* Get client entry */
274 client = silc_idlist_find_client_by_id(server->global_list,
275 client_id, TRUE, NULL);
277 client = silc_idlist_find_client_by_id(server->local_list,
278 client_id, TRUE, NULL);
280 silc_free(client_id);
281 silc_free(channel_id);
285 silc_free(client_id);
287 /* Check if on channel */
288 if (!silc_server_client_on_channel(client, channel, NULL))
291 /* Send the leave notify to channel */
292 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
293 FALSE, packet->buffer->data,
294 packet->buffer->len, FALSE);
296 /* Remove the user from channel */
297 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
300 case SILC_NOTIFY_TYPE_SIGNOFF:
302 * Distribute the notify to local clients on the channel
304 SILC_LOG_DEBUG(("SIGNOFF notify"));
307 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
310 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
314 /* Get client entry */
315 client = silc_idlist_find_client_by_id(server->global_list,
316 client_id, TRUE, &cache);
318 client = silc_idlist_find_client_by_id(server->local_list,
319 client_id, TRUE, &cache);
321 silc_free(client_id);
325 silc_free(client_id);
327 /* Get signoff message */
328 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
332 /* Update statistics */
333 server->stat.clients--;
334 if (server->stat.cell_clients)
335 server->stat.cell_clients--;
336 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
337 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
339 /* Remove the client from all channels. */
340 silc_server_remove_from_channels(server, NULL, client, TRUE, tmp, FALSE);
342 /* Check if anyone is watching this nickname */
343 if (server->server_type == SILC_ROUTER)
344 silc_server_check_watcher_list(server, client, NULL,
345 SILC_NOTIFY_TYPE_SIGNOFF);
347 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
348 cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
351 case SILC_NOTIFY_TYPE_TOPIC_SET:
353 * Distribute the notify to local clients on the channel
356 SILC_LOG_DEBUG(("TOPIC SET notify"));
359 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
362 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
366 /* Get client entry */
367 client = silc_idlist_find_client_by_id(server->global_list,
368 client_id, TRUE, &cache);
370 client = silc_idlist_find_client_by_id(server->local_list,
371 client_id, TRUE, &cache);
373 silc_free(client_id);
377 silc_free(client_id);
380 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
382 silc_free(channel_id);
387 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
388 packet->dst_id_type);
393 /* Get channel entry */
394 channel = silc_idlist_find_channel_by_id(server->global_list,
397 channel = silc_idlist_find_channel_by_id(server->local_list,
400 silc_free(channel_id);
405 if (channel->topic && !strcmp(channel->topic, tmp))
408 /* Get user's channel entry and check that topic set is allowed. */
409 if (!silc_server_client_on_channel(client, channel, &chl))
411 if (channel->mode & SILC_CHANNEL_MODE_TOPIC &&
412 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
413 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
414 SILC_LOG_DEBUG(("Topic change is not allowed"));
418 /* Change the topic */
419 silc_free(channel->topic);
420 channel->topic = strdup(tmp);
422 /* Send the same notify to the channel */
423 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
424 FALSE, packet->buffer->data,
425 packet->buffer->len, FALSE);
426 silc_free(channel_id);
429 case SILC_NOTIFY_TYPE_NICK_CHANGE:
432 * Distribute the notify to local clients on the channel
434 unsigned char *id, *id2;
436 SilcUInt32 nickname_len;
438 SILC_LOG_DEBUG(("NICK CHANGE notify"));
440 /* Get old client ID */
441 id = silc_argument_get_arg_type(args, 1, &tmp_len);
444 client_id = silc_id_payload_parse_id(id, tmp_len, NULL);
448 /* Get new client ID */
449 id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
452 client_id2 = silc_id_payload_parse_id(id2, tmp_len, NULL);
456 SILC_LOG_DEBUG(("Old Client ID id(%s)",
457 silc_id_render(client_id, SILC_ID_CLIENT)));
458 SILC_LOG_DEBUG(("New Client ID id(%s)",
459 silc_id_render(client_id2, SILC_ID_CLIENT)));
461 /* From protocol version 1.1 we also get the new nickname */
462 nickname = silc_argument_get_arg_type(args, 3, &nickname_len);;
464 /* Replace the Client ID */
465 client = silc_idlist_replace_client_id(server,
466 server->global_list, client_id,
467 client_id2, nickname);
469 client = silc_idlist_replace_client_id(server,
470 server->local_list, client_id,
471 client_id2, nickname);
474 /* Send the NICK_CHANGE notify type to local clients on the channels
475 this client is joined to. */
476 silc_server_send_notify_on_channels(server, client, client,
477 SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
478 id, tmp_len, id2, tmp_len,
483 silc_free(client_id);
485 silc_free(client_id2);
489 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
491 * Distribute the notify to local clients on the channel
494 SILC_LOG_DEBUG(("CMODE CHANGE notify"));
497 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
500 client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
504 /* Get client entry */
505 if (id_type == SILC_ID_CLIENT) {
506 client = silc_idlist_find_client_by_id(server->global_list,
507 client_id, TRUE, &cache);
509 client = silc_idlist_find_client_by_id(server->local_list,
510 client_id, TRUE, &cache);
512 silc_free(client_id);
516 silc_free(client_id);
520 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
521 packet->dst_id_type);
526 /* Get channel entry */
527 channel = silc_idlist_find_channel_by_id(server->global_list,
530 channel = silc_idlist_find_channel_by_id(server->local_list,
533 silc_free(channel_id);
537 silc_free(channel_id);
540 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
543 SILC_GET32_MSB(mode, tmp);
545 /* Check if mode changed */
546 if (channel->mode == mode)
549 /* Get user's channel entry and check that mode change is allowed */
551 if (!silc_server_client_on_channel(client, channel, &chl))
553 if (!silc_server_check_cmode_rights(server, channel, chl, mode)) {
554 SILC_LOG_DEBUG(("CMODE change is not allowed"));
558 if (server->server_type == SILC_ROUTER &&
559 channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH &&
560 !(mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
561 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
562 silc_server_send_notify_cmode(server, sock, FALSE, channel,
563 channel->mode, server->id,
568 channel->founder_key);
573 /* Send the same notify to the channel */
574 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
575 FALSE, packet->buffer->data,
576 packet->buffer->len, FALSE);
578 /* If the channel had private keys set and the mode was removed then
579 we must re-generate and re-distribute a new channel key */
580 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY &&
581 !(mode & SILC_CHANNEL_MODE_PRIVKEY)) {
582 /* Re-generate channel key */
583 if (!silc_server_create_channel_key(server, channel, 0))
586 /* Send the channel key. This sends it to our local clients and if
587 we are normal server to our router as well. */
588 silc_server_send_channel_key(server, NULL, channel,
589 server->server_type == SILC_ROUTER ?
590 FALSE : !server->standalone);
594 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
596 unsigned char hash[32];
599 silc_hmac_free(channel->hmac);
600 if (!silc_hmac_alloc(tmp, NULL, &channel->hmac))
603 /* Set the HMAC key out of current channel key. The client must do
605 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key,
606 channel->key_len / 8, hash);
607 silc_hmac_set_key(channel->hmac, hash,
608 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
609 memset(hash, 0, sizeof(hash));
612 /* Get the passphrase */
613 tmp = silc_argument_get_arg_type(args, 5, &tmp_len);
615 silc_free(channel->passphrase);
616 channel->passphrase = silc_memdup(tmp, tmp_len);
619 /* Get founder public key */
620 tmp = silc_argument_get_arg_type(args, 6, &tmp_len);
621 if (tmp && mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
622 if (channel->founder_key)
623 silc_pkcs_public_key_free(channel->founder_key);
624 channel->founder_key = NULL;
625 silc_pkcs_public_key_decode(tmp, tmp_len, &channel->founder_key);
627 if (!channel->founder_key ||
628 (client && client->data.public_key &&
629 server->server_type == SILC_ROUTER &&
630 !silc_pkcs_public_key_compare(channel->founder_key,
631 client->data.public_key))) {
632 /* A really buggy server isn't checking public keys correctly.
633 It's not possible that the mode setter and founder wouldn't
634 have same public key. */
635 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
637 mode &= ~SILC_CHANNEL_MODE_FOUNDER_AUTH;
638 silc_server_send_notify_cmode(server, sock, FALSE, channel,
639 mode, server->id, SILC_ID_SERVER,
642 channel->passphrase, NULL);
643 if (channel->founder_key)
644 silc_pkcs_public_key_free(channel->founder_key);
645 channel->founder_key = NULL;
646 } else if (client && !client->data.public_key) {
647 client->data.public_key =
648 silc_pkcs_public_key_copy(channel->founder_key);
652 if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH && !channel->founder_key &&
653 server->server_type == SILC_ROUTER) {
654 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
655 mode &= ~SILC_CHANNEL_MODE_FOUNDER_AUTH;
656 silc_server_send_notify_cmode(server, sock, FALSE, channel,
657 mode, server->id, SILC_ID_SERVER,
660 channel->passphrase, NULL);
664 channel->mode = mode;
666 if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) &&
667 channel->founder_key) {
668 silc_pkcs_public_key_free(channel->founder_key);
669 channel->founder_key = NULL;
674 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
677 * Distribute the notify to local clients on the channel
679 SilcChannelClientEntry chl2 = NULL;
680 bool notify_sent = FALSE;
682 SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
685 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
688 client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
692 /* Get client entry */
693 if (id_type == SILC_ID_CLIENT) {
694 client = silc_idlist_find_client_by_id(server->global_list,
695 client_id, TRUE, &cache);
697 client = silc_idlist_find_client_by_id(server->local_list,
698 client_id, TRUE, &cache);
700 silc_free(client_id);
704 silc_free(client_id);
708 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
709 packet->dst_id_type);
714 /* Get channel entry */
715 channel = silc_idlist_find_channel_by_id(server->global_list,
718 channel = silc_idlist_find_channel_by_id(server->local_list,
721 silc_free(channel_id);
727 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
729 silc_free(channel_id);
733 SILC_GET32_MSB(mode, tmp);
735 /* Get target client */
736 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
739 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
743 /* Get client entry */
744 client2 = silc_idlist_find_client_by_id(server->global_list,
745 client_id, TRUE, NULL);
747 client2 = silc_idlist_find_client_by_id(server->local_list,
748 client_id, TRUE, NULL);
750 silc_free(client_id);
754 silc_free(client_id);
757 /* Check that sender is on channel */
758 if (!silc_server_client_on_channel(client, channel, &chl))
761 if (client != client2 && server->server_type == SILC_ROUTER) {
762 /* Sender must be operator */
763 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
764 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
765 SILC_LOG_DEBUG(("CUMODE change is not allowed"));
769 if (!silc_server_client_on_channel(client2, channel, &chl))
772 /* If target is founder mode change is not allowed. */
773 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
774 SILC_LOG_DEBUG(("CUMODE change is not allowed"));
780 /* Get target channel entry */
781 if (!silc_server_client_on_channel(client2, channel, &chl))
784 if (mode & SILC_CHANNEL_UMODE_CHANFO &&
785 !(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) && !client &&
786 server->server_type == SILC_ROUTER) {
787 /* Get the founder of the channel and if found then this client
788 cannot be the founder since there already is one. */
789 silc_hash_table_list(channel->user_list, &htl);
790 while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
791 if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
792 mode &= ~SILC_CHANNEL_UMODE_CHANFO;
793 silc_server_force_cumode_change(server, sock, channel, chl, mode);
797 silc_hash_table_list_reset(&htl);
798 if (!(mode & SILC_CHANNEL_UMODE_CHANFO))
802 if (client && mode & SILC_CHANNEL_UMODE_CHANFO &&
803 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO) &&
804 server->server_type == SILC_ROUTER) {
805 /* Check whether this client is allowed to be channel founder on
807 SilcPublicKey founder_key = NULL;
809 /* If channel doesn't have founder auth mode then it's impossible
810 that someone would be getting founder rights with CUMODE command.
811 In that case there already either is founder or there isn't
812 founder at all on the channel. */
813 if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
814 /* Force the mode to not have founder mode */
815 mode &= ~SILC_CHANNEL_UMODE_CHANFO;
816 silc_server_force_cumode_change(server, sock, channel, chl, mode);
821 /* Get the founder of the channel and if found then this client
822 cannot be the founder since there already is one. */
823 silc_hash_table_list(channel->user_list, &htl);
824 while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
825 if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
826 mode &= ~SILC_CHANNEL_UMODE_CHANFO;
827 silc_server_force_cumode_change(server, sock, channel, chl, mode);
831 silc_hash_table_list_reset(&htl);
832 if (!(mode & SILC_CHANNEL_UMODE_CHANFO))
835 /* Founder not found of the channel. Since the founder auth mode
836 is set on the channel now check whether this is the client that
837 originally set the mode. */
839 /* Get public key that must be present in notify */
840 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
841 if (!tmp || !silc_pkcs_public_key_decode(tmp, tmp_len,
843 mode &= ~SILC_CHANNEL_UMODE_CHANFO;
844 silc_server_force_cumode_change(server, sock, channel, chl, mode);
849 /* Now match the public key we have cached and public key sent.
851 if (client->data.public_key &&
852 !silc_pkcs_public_key_compare(channel->founder_key,
853 client->data.public_key)) {
854 mode &= ~SILC_CHANNEL_UMODE_CHANFO;
855 silc_server_force_cumode_change(server, sock, channel, chl, mode);
859 if (!silc_pkcs_public_key_compare(channel->founder_key,
861 mode &= ~SILC_CHANNEL_UMODE_CHANFO;
862 silc_server_force_cumode_change(server, sock, channel, chl, mode);
868 silc_pkcs_public_key_free(founder_key);
871 SILC_LOG_DEBUG(("Changing the channel user mode"));
873 /* Change the mode */
876 /* Send the same notify to the channel */
878 silc_server_packet_send_to_channel(server, sock, channel,
880 FALSE, packet->buffer->data,
881 packet->buffer->len, FALSE);
883 silc_free(channel_id);
887 case SILC_NOTIFY_TYPE_INVITE:
889 if (packet->dst_id_type == SILC_ID_CLIENT)
892 SILC_LOG_DEBUG(("INVITE notify"));
895 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
898 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
902 /* Get channel entry */
903 channel = silc_idlist_find_channel_by_id(server->global_list,
906 channel = silc_idlist_find_channel_by_id(server->local_list,
909 silc_free(channel_id);
913 silc_free(channel_id);
916 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
919 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
923 /* Get client entry */
924 client = silc_idlist_find_client_by_id(server->global_list,
925 client_id, TRUE, &cache);
927 client = silc_idlist_find_client_by_id(server->local_list,
928 client_id, TRUE, &cache);
930 silc_free(client_id);
934 silc_free(client_id);
936 /* Get user's channel entry and check that inviting is allowed. */
937 if (!silc_server_client_on_channel(client, channel, &chl))
939 if (channel->mode & SILC_CHANNEL_MODE_INVITE &&
940 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
941 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
942 SILC_LOG_DEBUG(("Inviting is not allowed"));
946 /* Get the added invite */
947 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
949 if (!channel->invite_list)
950 channel->invite_list = silc_calloc(tmp_len + 2,
951 sizeof(*channel->invite_list));
953 channel->invite_list = silc_realloc(channel->invite_list,
954 sizeof(*channel->invite_list) *
956 strlen(channel->invite_list) +
958 if (tmp[tmp_len - 1] == ',')
959 tmp[tmp_len - 1] = '\0';
961 strncat(channel->invite_list, tmp, tmp_len);
962 strncat(channel->invite_list, ",", 1);
965 /* Get the deleted invite */
966 tmp = silc_argument_get_arg_type(args, 5, &tmp_len);
967 if (tmp && channel->invite_list) {
968 char *start, *end, *n;
970 if (!strncmp(channel->invite_list, tmp,
971 strlen(channel->invite_list) - 1)) {
972 silc_free(channel->invite_list);
973 channel->invite_list = NULL;
975 start = strstr(channel->invite_list, tmp);
976 if (start && strlen(start) >= tmp_len) {
977 end = start + tmp_len;
978 n = silc_calloc(strlen(channel->invite_list) - tmp_len, sizeof(*n));
979 strncat(n, channel->invite_list, start - channel->invite_list);
980 strncat(n, end + 1, ((channel->invite_list +
981 strlen(channel->invite_list)) - end) - 1);
982 silc_free(channel->invite_list);
983 channel->invite_list = n;
990 case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
992 * Distribute to the local clients on the channel and change the
996 SILC_LOG_DEBUG(("CHANNEL CHANGE"));
998 if (sock->type != SILC_SOCKET_TYPE_ROUTER)
1001 /* Get the old Channel ID */
1002 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1005 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1009 /* Get the channel entry */
1010 channel = silc_idlist_find_channel_by_id(server->local_list,
1013 channel = silc_idlist_find_channel_by_id(server->global_list,
1016 silc_free(channel_id);
1021 /* Send the notify to the channel */
1022 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
1023 FALSE, packet->buffer->data,
1024 packet->buffer->len, FALSE);
1026 /* Get the new Channel ID */
1027 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1030 channel_id2 = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1034 SILC_LOG_DEBUG(("Old Channel ID id(%s)",
1035 silc_id_render(channel_id, SILC_ID_CHANNEL)));
1036 SILC_LOG_DEBUG(("New Channel ID id(%s)",
1037 silc_id_render(channel_id2, SILC_ID_CHANNEL)));
1039 /* Replace the Channel ID */
1040 if (!silc_idlist_replace_channel_id(server->local_list, channel_id,
1042 if (!silc_idlist_replace_channel_id(server->global_list, channel_id,
1044 silc_free(channel_id2);
1049 SilcBuffer modes = NULL, users = NULL, users_modes = NULL;
1051 /* Re-announce this channel which ID was changed. */
1052 silc_server_send_new_channel(server, sock, FALSE, channel->channel_name,
1054 silc_id_get_len(channel->id,
1058 /* Re-announce our clients on the channel as the ID has changed now */
1059 silc_server_announce_get_channel_users(server, channel, &modes, &users,
1062 silc_buffer_push(modes, modes->data - modes->head);
1063 silc_server_packet_send_dest(server, sock,
1064 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1065 channel->id, SILC_ID_CHANNEL,
1066 modes->data, modes->len, FALSE);
1067 silc_buffer_free(modes);
1070 silc_buffer_push(users, users->data - users->head);
1071 silc_server_packet_send(server, sock,
1072 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1073 users->data, users->len, FALSE);
1074 silc_buffer_free(users);
1077 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
1078 silc_server_packet_send_dest(server, sock,
1079 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1080 channel->id, SILC_ID_CHANNEL,
1082 users_modes->len, FALSE);
1083 silc_buffer_free(users_modes);
1086 /* Re-announce channel's topic */
1087 if (channel->topic) {
1088 silc_server_send_notify_topic_set(server, sock,
1089 server->server_type == SILC_ROUTER ?
1090 TRUE : FALSE, channel,
1091 channel->id, SILC_ID_CHANNEL,
1096 silc_free(channel_id);
1100 case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
1102 * Remove the server entry and all clients that this server owns.
1105 SILC_LOG_DEBUG(("SERVER SIGNOFF notify"));
1108 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1111 server_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1115 /* Get server entry */
1116 server_entry = silc_idlist_find_server_by_id(server->global_list,
1117 server_id, TRUE, NULL);
1119 if (!server_entry) {
1120 server_entry = silc_idlist_find_server_by_id(server->local_list,
1121 server_id, TRUE, NULL);
1123 if (!server_entry) {
1124 /* If we are normal server then we might not have the server. Check
1125 whether router was kind enough to send the list of all clients
1126 that actually was to be removed. Remove them if the list is
1128 if (server->server_type != SILC_ROUTER &&
1129 silc_argument_get_arg_num(args) > 1) {
1132 for (i = 1; i < silc_argument_get_arg_num(args); i++) {
1134 tmp = silc_argument_get_arg_type(args, i + 1, &tmp_len);
1137 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1141 /* Get client entry */
1142 client = silc_idlist_find_client_by_id(server->global_list,
1143 client_id, TRUE, &cache);
1146 client = silc_idlist_find_client_by_id(server->local_list,
1147 client_id, TRUE, &cache);
1150 silc_free(client_id);
1154 silc_free(client_id);
1156 /* Update statistics */
1157 server->stat.clients--;
1158 if (server->stat.cell_clients)
1159 server->stat.cell_clients--;
1160 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
1161 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
1163 /* Remove the client from all channels. */
1164 silc_server_remove_from_channels(server, NULL, client,
1167 /* Check if anyone is watching this nickname */
1168 if (server->server_type == SILC_ROUTER)
1169 silc_server_check_watcher_list(server, client, NULL,
1170 SILC_NOTIFY_TYPE_SERVER_SIGNOFF);
1172 /* Remove this client from watcher list if it is */
1174 silc_server_del_from_watcher_list(server, client);
1176 /* Remove the client */
1177 silc_idlist_del_client(local ? server->local_list :
1178 server->global_list, client);
1182 silc_free(server_id);
1186 silc_free(server_id);
1188 /* Free all client entries that this server owns as they will
1189 become invalid now as well. */
1190 silc_server_remove_clients_by_server(server, server_entry, TRUE);
1192 /* Remove the server entry */
1193 silc_idlist_del_server(local ? server->local_list :
1194 server->global_list, server_entry);
1196 /* XXX update statistics */
1200 case SILC_NOTIFY_TYPE_KICKED:
1202 * Distribute the notify to local clients on the channel
1205 SILC_LOG_DEBUG(("KICKED notify"));
1208 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
1209 packet->dst_id_type);
1214 /* Get channel entry */
1215 channel = silc_idlist_find_channel_by_id(server->global_list,
1218 channel = silc_idlist_find_channel_by_id(server->local_list,
1221 silc_free(channel_id);
1225 silc_free(channel_id);
1228 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1231 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1235 /* If the the client is not in local list we check global list */
1236 client = silc_idlist_find_client_by_id(server->global_list,
1237 client_id, TRUE, NULL);
1239 client = silc_idlist_find_client_by_id(server->local_list,
1240 client_id, TRUE, NULL);
1242 silc_free(client_id);
1246 silc_free(client_id);
1248 /* If target is founder they cannot be kicked */
1249 if (!silc_server_client_on_channel(client, channel, &chl))
1251 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO)
1254 /* From protocol version 1.1 we get the kicker's ID as well. */
1255 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1257 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1261 /* If the the client is not in local list we check global list */
1262 client2 = silc_idlist_find_client_by_id(server->global_list,
1263 client_id, TRUE, NULL);
1265 client2 = silc_idlist_find_client_by_id(server->local_list,
1266 client_id, TRUE, NULL);
1268 silc_free(client_id);
1272 silc_free(client_id);
1274 /* Kicker must be operator on channel */
1275 if (!silc_server_client_on_channel(client2, channel, &chl))
1277 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
1278 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1279 SILC_LOG_DEBUG(("Kicking is not allowed"));
1284 /* Send to channel */
1285 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
1286 FALSE, packet->buffer->data,
1287 packet->buffer->len, FALSE);
1289 /* Remove the client from channel */
1290 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
1294 case SILC_NOTIFY_TYPE_KILLED:
1297 * Distribute the notify to local clients on channels
1299 unsigned char *id, *comment;
1300 SilcUInt32 id_len, comment_len;
1302 SILC_LOG_DEBUG(("KILLED notify"));
1305 id = silc_argument_get_arg_type(args, 1, &id_len);
1308 client_id = silc_id_payload_parse_id(id, id_len, NULL);
1312 /* If the the client is not in local list we check global list */
1313 client = silc_idlist_find_client_by_id(server->global_list,
1314 client_id, TRUE, NULL);
1316 client = silc_idlist_find_client_by_id(server->local_list,
1317 client_id, TRUE, NULL);
1319 silc_free(client_id);
1323 silc_free(client_id);
1325 /* If the client is one of ours, then close the connection to the
1326 client now. This removes the client from all channels as well. */
1327 if (packet->dst_id_type == SILC_ID_CLIENT && client->connection) {
1328 sock = client->connection;
1329 silc_server_free_client_data(server, NULL, client, FALSE, NULL);
1330 silc_server_close_connection(server, sock);
1335 comment = silc_argument_get_arg_type(args, 2, &comment_len);
1336 if (comment_len > 128)
1339 /* From protocol version 1.1 we get the killer's ID as well. */
1340 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1342 client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
1346 if (id_type == SILC_ID_CLIENT) {
1347 /* If the the client is not in local list we check global list */
1348 client2 = silc_idlist_find_client_by_id(server->global_list,
1349 client_id, TRUE, NULL);
1351 client2 = silc_idlist_find_client_by_id(server->local_list,
1352 client_id, TRUE, NULL);
1354 silc_free(client_id);
1358 silc_free(client_id);
1360 /* Killer must be router operator */
1361 if (!(client2->mode & SILC_UMODE_ROUTER_OPERATOR)) {
1362 SILC_LOG_DEBUG(("Killing is not allowed"));
1368 /* Send the notify to local clients on the channels except to the
1369 client who is killed. */
1370 silc_server_send_notify_on_channels(server, client, client,
1371 SILC_NOTIFY_TYPE_KILLED, 3,
1372 id, id_len, comment, comment_len,
1375 /* Remove the client from all channels */
1376 silc_server_remove_from_channels(server, NULL, client, FALSE, NULL,
1379 /* Check if anyone is watching this nickname */
1380 if (server->server_type == SILC_ROUTER)
1381 silc_server_check_watcher_list(server, client, NULL,
1382 SILC_NOTIFY_TYPE_KILLED);
1387 case SILC_NOTIFY_TYPE_UMODE_CHANGE:
1389 * Save the mode of the client.
1392 SILC_LOG_DEBUG(("UMODE_CHANGE notify"));
1395 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1398 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1402 /* Get client entry */
1403 client = silc_idlist_find_client_by_id(server->global_list,
1404 client_id, TRUE, NULL);
1406 client = silc_idlist_find_client_by_id(server->local_list,
1407 client_id, TRUE, NULL);
1409 silc_free(client_id);
1413 silc_free(client_id);
1416 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1419 SILC_GET32_MSB(mode, tmp);
1421 /* Check that mode changing is allowed. */
1422 if (!silc_server_check_umode_rights(server, client, mode)) {
1423 SILC_LOG_DEBUG(("UMODE change is not allowed"));
1427 /* Remove internal resumed flag if client is marked detached now */
1428 if (mode & SILC_UMODE_DETACHED)
1429 client->data.status &= ~SILC_IDLIST_STATUS_RESUMED;
1431 /* Change the mode */
1432 client->mode = mode;
1434 /* Check if anyone is watching this nickname */
1435 if (server->server_type == SILC_ROUTER)
1436 silc_server_check_watcher_list(server, client, NULL,
1437 SILC_NOTIFY_TYPE_UMODE_CHANGE);
1441 case SILC_NOTIFY_TYPE_BAN:
1446 SILC_LOG_DEBUG(("BAN notify"));
1448 /* Get Channel ID */
1449 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1452 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1456 /* Get channel entry */
1457 channel = silc_idlist_find_channel_by_id(server->global_list,
1460 channel = silc_idlist_find_channel_by_id(server->local_list,
1463 silc_free(channel_id);
1467 silc_free(channel_id);
1469 /* Get the new ban and add it to the ban list */
1470 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1472 if (!channel->ban_list)
1473 channel->ban_list = silc_calloc(tmp_len + 2,
1474 sizeof(*channel->ban_list));
1476 channel->ban_list = silc_realloc(channel->ban_list,
1477 sizeof(*channel->ban_list) *
1479 strlen(channel->ban_list) + 2));
1480 strncat(channel->ban_list, tmp, tmp_len);
1481 strncat(channel->ban_list, ",", 1);
1484 /* Get the ban to be removed and remove it from the list */
1485 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1486 if (tmp && channel->ban_list) {
1487 char *start, *end, *n;
1489 if (!strncmp(channel->ban_list, tmp, strlen(channel->ban_list) - 1)) {
1490 silc_free(channel->ban_list);
1491 channel->ban_list = NULL;
1493 start = strstr(channel->ban_list, tmp);
1494 if (start && strlen(start) >= tmp_len) {
1495 end = start + tmp_len;
1496 n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
1497 strncat(n, channel->ban_list, start - channel->ban_list);
1498 strncat(n, end + 1, ((channel->ban_list +
1499 strlen(channel->ban_list)) - end) - 1);
1500 silc_free(channel->ban_list);
1501 channel->ban_list = n;
1507 case SILC_NOTIFY_TYPE_ERROR:
1514 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1515 if (!tmp && tmp_len != 1)
1517 error = (SilcStatus)tmp[0];
1519 SILC_LOG_DEBUG(("ERROR notify (%d)", error));
1521 if (error == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID &&
1522 sock->type == SILC_SOCKET_TYPE_ROUTER) {
1523 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1525 SILC_LOG_DEBUG(("Received invalid client ID notification, deleting "
1526 "the entry from cache"));
1527 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1530 client = silc_idlist_find_client_by_id(server->global_list,
1531 client_id, FALSE, NULL);
1533 silc_server_remove_from_channels(server, NULL, client, TRUE,
1535 silc_idlist_del_client(server->global_list, client);
1537 silc_free(client_id);
1543 /* Ignore rest of the notify types for now */
1544 case SILC_NOTIFY_TYPE_NONE:
1545 case SILC_NOTIFY_TYPE_MOTD:
1552 silc_notify_payload_free(payload);
1555 void silc_server_notify_list(SilcServer server,
1556 SilcSocketConnection sock,
1557 SilcPacketContext *packet)
1559 SilcPacketContext *new;
1563 SILC_LOG_DEBUG(("Processing Notify List"));
1565 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1566 packet->src_id_type != SILC_ID_SERVER)
1569 /* Make copy of the original packet context, except for the actual
1570 data buffer, which we will here now fetch from the original buffer. */
1571 new = silc_packet_context_alloc();
1572 new->type = SILC_PACKET_NOTIFY;
1573 new->flags = packet->flags;
1574 new->src_id = packet->src_id;
1575 new->src_id_len = packet->src_id_len;
1576 new->src_id_type = packet->src_id_type;
1577 new->dst_id = packet->dst_id;
1578 new->dst_id_len = packet->dst_id_len;
1579 new->dst_id_type = packet->dst_id_type;
1581 buffer = silc_buffer_alloc(1024);
1582 new->buffer = buffer;
1584 while (packet->buffer->len) {
1585 SILC_GET16_MSB(len, packet->buffer->data + 2);
1586 if (len > packet->buffer->len)
1589 if (len > buffer->truelen) {
1590 silc_buffer_free(buffer);
1591 buffer = silc_buffer_alloc(1024 + len);
1594 silc_buffer_pull_tail(buffer, len);
1595 silc_buffer_put(buffer, packet->buffer->data, len);
1597 /* Process the Notify */
1598 silc_server_notify(server, sock, new);
1600 silc_buffer_push_tail(buffer, len);
1601 silc_buffer_pull(packet->buffer, len);
1604 silc_buffer_free(buffer);
1608 /* Received private message. This resolves the destination of the message
1609 and sends the packet. This is used by both server and router. If the
1610 destination is our locally connected client this sends the packet to
1611 the client. This may also send the message for further routing if
1612 the destination is not in our server (or router). */
1614 void silc_server_private_message(SilcServer server,
1615 SilcSocketConnection sock,
1616 SilcPacketContext *packet)
1618 SilcSocketConnection dst_sock;
1619 SilcIDListData idata;
1620 SilcClientEntry client;
1622 SILC_LOG_DEBUG(("Start"));
1624 if (packet->src_id_type != SILC_ID_CLIENT ||
1625 packet->dst_id_type != SILC_ID_CLIENT || !packet->dst_id)
1628 /* Get the route to the client */
1629 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1630 packet->dst_id_len, NULL,
1634 unsigned char error;
1636 if (client && client->mode & SILC_UMODE_DETACHED) {
1637 SILC_LOG_DEBUG(("Client is detached, discarding packet"));
1641 /* Send SILC_NOTIFY_TYPE_ERROR to indicate that such destination ID
1642 does not exist or is invalid. */
1643 idp = silc_id_payload_encode_data(packet->dst_id,
1645 packet->dst_id_type);
1649 error = SILC_STATUS_ERR_NO_SUCH_CLIENT_ID;
1650 if (packet->src_id_type == SILC_ID_CLIENT) {
1651 SilcClientID *client_id = silc_id_str2id(packet->src_id,
1653 packet->src_id_type);
1654 silc_server_send_notify_dest(server, sock, FALSE,
1655 client_id, SILC_ID_CLIENT,
1656 SILC_NOTIFY_TYPE_ERROR, 2,
1658 idp->data, idp->len);
1659 silc_free(client_id);
1661 silc_server_send_notify(server, sock, FALSE,
1662 SILC_NOTIFY_TYPE_ERROR, 2,
1664 idp->data, idp->len);
1667 silc_buffer_free(idp);
1671 /* Check whether destination client wishes to receive private messages */
1672 if (client && !(packet->flags & SILC_PACKET_FLAG_PRIVMSG_KEY) &&
1673 client->mode & SILC_UMODE_BLOCK_PRIVMSG) {
1674 SILC_LOG_DEBUG(("Client blocks private messages, discarding packet"));
1678 /* Send the private message */
1679 silc_server_send_private_message(server, dst_sock, idata->send_key,
1680 idata->hmac_send, idata->psn_send++,
1684 /* Received private message key packet.. This packet is never for us. It is to
1685 the client in the packet's destination ID. Sending of this sort of packet
1686 equals sending private message, ie. it is sent point to point from
1687 one client to another. */
1689 void silc_server_private_message_key(SilcServer server,
1690 SilcSocketConnection sock,
1691 SilcPacketContext *packet)
1693 SilcSocketConnection dst_sock;
1694 SilcIDListData idata;
1696 SILC_LOG_DEBUG(("Start"));
1698 if (packet->src_id_type != SILC_ID_CLIENT ||
1699 packet->dst_id_type != SILC_ID_CLIENT)
1702 if (!packet->dst_id)
1705 /* Get the route to the client */
1706 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1707 packet->dst_id_len, NULL,
1712 /* Relay the packet */
1713 silc_server_relay_packet(server, dst_sock, idata->send_key,
1714 idata->hmac_send, idata->psn_send++, packet, FALSE);
1717 /* Processes incoming command reply packet. The command reply packet may
1718 be destined to one of our clients or it may directly for us. We will
1719 call the command reply routine after processing the packet. */
1721 void silc_server_command_reply(SilcServer server,
1722 SilcSocketConnection sock,
1723 SilcPacketContext *packet)
1725 SilcBuffer buffer = packet->buffer;
1726 SilcClientEntry client = NULL;
1727 SilcSocketConnection dst_sock;
1728 SilcIDListData idata;
1729 SilcClientID *id = NULL;
1731 SILC_LOG_DEBUG(("Start"));
1733 /* Source must be server or router */
1734 if (packet->src_id_type != SILC_ID_SERVER &&
1735 sock->type != SILC_SOCKET_TYPE_ROUTER)
1738 if (packet->dst_id_type == SILC_ID_CHANNEL)
1741 if (packet->dst_id_type == SILC_ID_CLIENT) {
1742 /* Destination must be one of ours */
1743 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
1746 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
1748 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
1754 if (packet->dst_id_type == SILC_ID_SERVER) {
1755 /* For now this must be for us */
1756 if (memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
1757 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
1762 /* Execute command reply locally for the command */
1763 silc_server_command_reply_process(server, sock, buffer);
1765 if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
1766 /* Relay the packet to the client */
1767 const SilcBufferStruct p;
1769 dst_sock = (SilcSocketConnection)client->connection;
1770 idata = (SilcIDListData)client;
1772 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
1773 + packet->dst_id_len + packet->padlen);
1774 if (!silc_packet_send_prepare(dst_sock, 0, 0, buffer->len,
1775 idata->hmac_send, (const SilcBuffer)&p)) {
1776 SILC_LOG_ERROR(("Cannot send packet"));
1779 silc_buffer_put((SilcBuffer)&p, buffer->data, buffer->len);
1781 /* Encrypt packet */
1782 silc_packet_encrypt(idata->send_key, idata->hmac_send, idata->psn_send++,
1783 (SilcBuffer)&p, buffer->len);
1785 /* Send the packet */
1786 silc_server_packet_send_real(server, dst_sock, TRUE);
1792 /* Process received channel message. The message can be originated from
1793 client or server. */
1795 void silc_server_channel_message(SilcServer server,
1796 SilcSocketConnection sock,
1797 SilcPacketContext *packet)
1799 SilcChannelEntry channel = NULL;
1800 SilcChannelID *id = NULL;
1801 void *sender_id = NULL;
1802 SilcClientEntry sender_entry = NULL;
1803 SilcChannelClientEntry chl;
1806 SILC_LOG_DEBUG(("Processing channel message"));
1809 if (packet->dst_id_type != SILC_ID_CHANNEL) {
1810 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1814 /* Find channel entry */
1815 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
1818 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
1820 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
1823 unsigned char error;
1825 /* Send SILC_NOTIFY_TYPE_ERROR to indicate that such destination ID
1826 does not exist or is invalid. */
1827 idp = silc_id_payload_encode_data(packet->dst_id,
1829 packet->dst_id_type);
1833 error = SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID;
1834 if (packet->src_id_type == SILC_ID_CLIENT) {
1835 SilcClientID *client_id = silc_id_str2id(packet->src_id,
1837 packet->src_id_type);
1838 silc_server_send_notify_dest(server, sock, FALSE,
1839 client_id, SILC_ID_CLIENT,
1840 SILC_NOTIFY_TYPE_ERROR, 2,
1841 &error, 1, idp->data, idp->len);
1842 silc_free(client_id);
1844 silc_server_send_notify(server, sock, FALSE,
1845 SILC_NOTIFY_TYPE_ERROR, 2,
1846 &error, 1, idp->data, idp->len);
1849 silc_buffer_free(idp);
1854 /* See that this client is on the channel. If the original sender is
1855 not client (as it can be server as well) we don't do the check. */
1856 sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1857 packet->src_id_type);
1860 if (packet->src_id_type == SILC_ID_CLIENT) {
1861 sender_entry = silc_idlist_find_client_by_id(server->local_list,
1862 sender_id, TRUE, NULL);
1863 if (!sender_entry) {
1865 sender_entry = silc_idlist_find_client_by_id(server->global_list,
1866 sender_id, TRUE, NULL);
1868 if (!sender_entry || !silc_server_client_on_channel(sender_entry,
1870 SILC_LOG_DEBUG(("Client not on channel"));
1874 /* If channel is moderated check that client is allowed to send
1876 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS &&
1877 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
1878 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1879 SILC_LOG_DEBUG(("Channel is silenced from normal users"));
1882 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS &&
1883 chl->mode & SILC_CHANNEL_UMODE_CHANOP &&
1884 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1885 SILC_LOG_DEBUG(("Channel is silenced from operators"));
1889 /* If the packet is coming from router, but the client entry is local
1890 entry to us then some router is rerouting this to us and it is not
1891 allowed. When the client is local to us it means that we've routed
1892 this packet to network, and now someone is routing it back to us. */
1893 if (server->server_type == SILC_ROUTER &&
1894 sock->type == SILC_SOCKET_TYPE_ROUTER && local) {
1895 SILC_LOG_DEBUG(("Channel message rerouted to the sender, drop it"));
1900 /* Distribute the packet to our local clients. This will send the
1901 packet for further routing as well, if needed. */
1902 silc_server_packet_relay_to_channel(server, sock, channel, sender_id,
1903 packet->src_id_type, sender_entry,
1904 packet->buffer->data,
1905 packet->buffer->len, FALSE);
1908 silc_free(sender_id);
1912 /* Received channel key packet. We distribute the key to all of our locally
1913 connected clients on the channel. */
1915 void silc_server_channel_key(SilcServer server,
1916 SilcSocketConnection sock,
1917 SilcPacketContext *packet)
1919 SilcBuffer buffer = packet->buffer;
1920 SilcChannelEntry channel;
1922 if (packet->src_id_type != SILC_ID_SERVER ||
1923 (server->server_type == SILC_ROUTER &&
1924 sock->type == SILC_SOCKET_TYPE_ROUTER))
1927 /* Save the channel key */
1928 channel = silc_server_save_channel_key(server, buffer, NULL);
1932 /* Distribute the key to everybody who is on the channel. If we are router
1933 we will also send it to locally connected servers. */
1934 silc_server_send_channel_key(server, sock, channel, FALSE);
1936 if (server->server_type != SILC_BACKUP_ROUTER) {
1937 /* Distribute to local cell backup routers. */
1938 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
1939 SILC_PACKET_CHANNEL_KEY, 0,
1940 buffer->data, buffer->len, FALSE, TRUE);
1944 /* Received New Client packet and processes it. Creates Client ID for the
1945 client. Client becomes registered after calling this functions. */
1947 SilcClientEntry silc_server_new_client(SilcServer server,
1948 SilcSocketConnection sock,
1949 SilcPacketContext *packet)
1951 SilcBuffer buffer = packet->buffer;
1952 SilcClientEntry client;
1953 SilcClientID *client_id;
1954 SilcIDListData idata;
1955 char *username = NULL, *realname = NULL;
1956 SilcUInt16 username_len;
1959 char *hostname, *nickname;
1962 SILC_LOG_DEBUG(("Creating new client"));
1964 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
1967 /* Take client entry */
1968 client = (SilcClientEntry)sock->user_data;
1969 idata = (SilcIDListData)client;
1971 /* Remove the old cache entry. */
1972 if (!silc_idcache_del_by_context(server->local_list->clients, client)) {
1973 SILC_LOG_INFO(("Unauthenticated client attempted to register to network"));
1974 silc_server_disconnect_remote(server, sock,
1975 SILC_STATUS_ERR_NOT_AUTHENTICATED, NULL);
1976 if (sock->user_data)
1977 silc_server_free_sock_user_data(server, sock, NULL);
1981 /* Parse incoming packet */
1982 ret = silc_buffer_unformat(buffer,
1983 SILC_STR_UI16_NSTRING_ALLOC(&username,
1985 SILC_STR_UI16_STRING_ALLOC(&realname),
1988 silc_free(username);
1989 silc_free(realname);
1990 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
1991 "connection", sock->hostname, sock->ip));
1992 silc_server_disconnect_remote(server, sock,
1993 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
1995 if (sock->user_data)
1996 silc_server_free_sock_user_data(server, sock, NULL);
2001 silc_free(username);
2002 silc_free(realname);
2003 SILC_LOG_ERROR(("Client %s (%s) did not send its username, closing "
2004 "connection", sock->hostname, sock->ip));
2005 silc_server_disconnect_remote(server, sock,
2006 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2008 if (sock->user_data)
2009 silc_server_free_sock_user_data(server, sock, NULL);
2013 if (username_len > 128)
2014 username[128] = '\0';
2016 /* Check for bad characters for nickname, and modify the nickname if
2017 it includes those. */
2018 if (silc_server_name_bad_chars(username, username_len)) {
2019 nickname = silc_server_name_modify_bad(username, username_len);
2021 nickname = strdup(username);
2024 /* Make sanity checks for the hostname of the client. If the hostname
2025 is provided in the `username' check that it is the same than the
2026 resolved hostname, or if not resolved the hostname that appears in
2027 the client's public key. If the hostname is not present then put
2028 it from the resolved name or from the public key. */
2029 if (strchr(username, '@')) {
2030 SilcPublicKeyIdentifier pident;
2031 int tlen = strcspn(username, "@");
2032 char *phostname = NULL;
2034 hostname = silc_memdup(username + tlen + 1, strlen(username) - tlen - 1);
2036 if (strcmp(sock->hostname, sock->ip) &&
2037 strcmp(sock->hostname, hostname)) {
2038 silc_free(username);
2039 silc_free(hostname);
2040 silc_free(realname);
2041 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2042 "connection", sock->hostname, sock->ip));
2043 silc_server_disconnect_remote(server, sock,
2044 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2046 if (sock->user_data)
2047 silc_server_free_sock_user_data(server, sock, NULL);
2051 pident = silc_pkcs_decode_identifier(client->data.public_key->identifier);
2053 phostname = strdup(pident->host);
2054 silc_pkcs_free_identifier(pident);
2057 if (!strcmp(sock->hostname, sock->ip) &&
2058 phostname && strcmp(phostname, hostname)) {
2059 silc_free(username);
2060 silc_free(hostname);
2061 silc_free(phostname);
2062 silc_free(realname);
2063 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2064 "connection", sock->hostname, sock->ip));
2065 silc_server_disconnect_remote(server, sock,
2066 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2068 if (sock->user_data)
2069 silc_server_free_sock_user_data(server, sock, NULL);
2073 silc_free(phostname);
2075 /* The hostname is not present, add it. */
2077 /* XXX For now we cannot take the host name from the public key since
2078 they are not trusted or we cannot verify them as trusted. Just take
2079 what the resolved name or address is. */
2081 if (strcmp(sock->hostname, sock->ip)) {
2083 newusername = silc_calloc(strlen(username) +
2084 strlen(sock->hostname) + 2,
2085 sizeof(*newusername));
2086 strncat(newusername, username, strlen(username));
2087 strncat(newusername, "@", 1);
2088 strncat(newusername, sock->hostname, strlen(sock->hostname));
2089 silc_free(username);
2090 username = newusername;
2093 SilcPublicKeyIdentifier pident =
2094 silc_pkcs_decode_identifier(client->data.public_key->identifier);
2097 newusername = silc_calloc(strlen(username) +
2098 strlen(pident->host) + 2,
2099 sizeof(*newusername));
2100 strncat(newusername, username, strlen(username));
2101 strncat(newusername, "@", 1);
2102 strncat(newusername, pident->host, strlen(pident->host));
2103 silc_free(username);
2104 username = newusername;
2105 silc_pkcs_free_identifier(pident);
2111 /* Create Client ID */
2112 while (!silc_id_create_client_id(server, server->id, server->rng,
2113 server->md5hash, nickname, &client_id)) {
2116 silc_server_disconnect_remote(server, sock,
2117 SILC_STATUS_ERR_BAD_NICKNAME, NULL);
2118 if (sock->user_data)
2119 silc_server_free_sock_user_data(server, sock, NULL);
2122 snprintf(&nickname[strlen(nickname) - 1], 1, "%d", nickfail);
2125 /* Update client entry */
2126 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
2127 client->nickname = nickname;
2128 client->username = username;
2129 client->userinfo = realname ? realname : strdup(" ");
2130 client->id = client_id;
2131 id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
2133 /* Add the client again to the ID cache */
2134 silc_idcache_add(server->local_list->clients, client->nickname,
2135 client_id, client, 0, NULL);
2137 /* Notify our router about new client on the SILC network */
2138 if (!server->standalone)
2139 silc_server_send_new_id(server, (SilcSocketConnection)
2140 server->router->connection,
2141 server->server_type == SILC_ROUTER ? TRUE : FALSE,
2142 client->id, SILC_ID_CLIENT, id_len);
2144 /* Send the new client ID to the client. */
2145 silc_server_send_new_id(server, sock, FALSE, client->id, SILC_ID_CLIENT,
2146 silc_id_get_len(client->id, SILC_ID_CLIENT));
2148 /* Send some nice info to the client */
2149 silc_server_send_connect_notifys(server, sock, client);
2151 /* Check if anyone is watching this nickname */
2152 if (server->server_type == SILC_ROUTER)
2153 silc_server_check_watcher_list(server, client, NULL, 0);
2158 /* Create new server. This processes received New Server packet and
2159 saves the received Server ID. The server is our locally connected
2160 server thus we save all the information and save it to local list.
2161 This funtion can be used by both normal server and router server.
2162 If normal server uses this it means that its router has connected
2163 to the server. If router uses this it means that one of the cell's
2164 servers is connected to the router. */
2166 SilcServerEntry silc_server_new_server(SilcServer server,
2167 SilcSocketConnection sock,
2168 SilcPacketContext *packet)
2170 SilcBuffer buffer = packet->buffer;
2171 SilcServerEntry new_server, server_entry;
2172 SilcServerID *server_id;
2173 SilcIDListData idata;
2174 unsigned char *server_name, *id_string;
2175 SilcUInt16 id_len, name_len;
2179 SILC_LOG_DEBUG(("Creating new server"));
2181 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
2182 sock->type != SILC_SOCKET_TYPE_ROUTER)
2185 /* Take server entry */
2186 new_server = (SilcServerEntry)sock->user_data;
2187 idata = (SilcIDListData)new_server;
2189 /* Remove the old cache entry */
2190 if (!silc_idcache_del_by_context(server->local_list->servers, new_server)) {
2191 if (!silc_idcache_del_by_context(server->global_list->servers,
2193 SILC_LOG_INFO(("Unauthenticated %s attempted to register to "
2194 "network", (sock->type == SILC_SOCKET_TYPE_SERVER ?
2195 "server" : "router")));
2196 silc_server_disconnect_remote(server, sock,
2197 SILC_STATUS_ERR_NOT_AUTHENTICATED, NULL);
2198 if (sock->user_data)
2199 silc_server_free_sock_user_data(server, sock, NULL);
2205 /* Parse the incoming packet */
2206 ret = silc_buffer_unformat(buffer,
2207 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
2208 SILC_STR_UI16_NSTRING_ALLOC(&server_name,
2212 silc_free(id_string);
2213 silc_free(server_name);
2214 silc_server_disconnect_remote(server, sock,
2215 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2217 if (sock->user_data)
2218 silc_server_free_sock_user_data(server, sock, NULL);
2222 if (id_len > buffer->len) {
2223 silc_free(id_string);
2224 silc_free(server_name);
2225 silc_server_disconnect_remote(server, sock,
2226 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2228 if (sock->user_data)
2229 silc_server_free_sock_user_data(server, sock, NULL);
2234 server_name[255] = '\0';
2237 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
2239 silc_free(id_string);
2240 silc_free(server_name);
2241 silc_server_disconnect_remote(server, sock,
2242 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2244 if (sock->user_data)
2245 silc_server_free_sock_user_data(server, sock, NULL);
2248 silc_free(id_string);
2250 /* Check for valid server ID */
2251 if (!silc_id_is_valid_server_id(server, server_id, sock)) {
2252 SILC_LOG_INFO(("Invalid server ID sent by %s (%s)",
2253 sock->ip, sock->hostname));
2254 silc_server_disconnect_remote(server, sock,
2255 SILC_STATUS_ERR_BAD_SERVER_ID, NULL);
2256 if (sock->user_data)
2257 silc_server_free_sock_user_data(server, sock, NULL);
2258 silc_free(server_name);
2262 /* Check that we do not have this ID already */
2263 server_entry = silc_idlist_find_server_by_id(server->local_list,
2264 server_id, TRUE, NULL);
2266 silc_idcache_del_by_context(server->local_list->servers, server_entry);
2268 server_entry = silc_idlist_find_server_by_id(server->global_list,
2269 server_id, TRUE, NULL);
2271 silc_idcache_del_by_context(server->global_list->servers, server_entry);
2274 /* Update server entry */
2275 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
2276 new_server->server_name = server_name;
2277 new_server->id = server_id;
2279 SILC_LOG_DEBUG(("New server id(%s)",
2280 silc_id_render(server_id, SILC_ID_SERVER)));
2282 /* Add again the entry to the ID cache. */
2283 silc_idcache_add(local ? server->local_list->servers :
2284 server->global_list->servers, server_name, server_id,
2285 new_server, 0, NULL);
2287 /* Distribute the information about new server in the SILC network
2288 to our router. If we are normal server we won't send anything
2289 since this connection must be our router connection. */
2290 if (server->server_type == SILC_ROUTER && !server->standalone &&
2291 server->router->connection != sock)
2292 silc_server_send_new_id(server, server->router->connection,
2293 TRUE, new_server->id, SILC_ID_SERVER,
2294 silc_id_get_len(server_id, SILC_ID_SERVER));
2296 if (server->server_type == SILC_ROUTER)
2297 server->stat.cell_servers++;
2299 /* Check whether this router connection has been replaced by an
2300 backup router. If it has been then we'll disable the server and will
2301 ignore everything it will send until the backup router resuming
2302 protocol has been completed. */
2303 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
2304 silc_server_backup_replaced_get(server, server_id, NULL)) {
2305 /* Send packet to the server indicating that it cannot use this
2306 connection as it has been replaced by backup router. */
2307 SilcBuffer packet = silc_buffer_alloc(2);
2308 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
2309 silc_buffer_format(packet,
2310 SILC_STR_UI_CHAR(SILC_SERVER_BACKUP_REPLACED),
2311 SILC_STR_UI_CHAR(0),
2313 silc_server_packet_send(server, sock,
2314 SILC_PACKET_RESUME_ROUTER, 0,
2315 packet->data, packet->len, TRUE);
2316 silc_buffer_free(packet);
2318 /* Mark the router disabled. The data sent earlier will go but nothing
2319 after this does not go to this connection. */
2320 idata->status |= SILC_IDLIST_STATUS_DISABLED;
2322 /* If it is router announce our stuff to it. */
2323 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
2324 server->server_type == SILC_ROUTER) {
2325 silc_server_announce_servers(server, FALSE, 0, sock);
2326 silc_server_announce_clients(server, 0, sock);
2327 silc_server_announce_channels(server, 0, sock);
2334 /* Processes incoming New ID packet. New ID Payload is used to distribute
2335 information about newly registered clients and servers. */
2337 static void silc_server_new_id_real(SilcServer server,
2338 SilcSocketConnection sock,
2339 SilcPacketContext *packet,
2342 SilcBuffer buffer = packet->buffer;
2344 SilcServerEntry router, server_entry;
2345 SilcSocketConnection router_sock;
2350 SILC_LOG_DEBUG(("Processing new ID"));
2352 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2353 server->server_type == SILC_SERVER ||
2354 packet->src_id_type != SILC_ID_SERVER)
2357 idp = silc_id_payload_parse(buffer->data, buffer->len);
2361 id_type = silc_id_payload_get_type(idp);
2363 /* Normal server cannot have other normal server connections */
2364 server_entry = (SilcServerEntry)sock->user_data;
2365 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER &&
2366 server_entry->server_type == SILC_SERVER)
2369 id = silc_id_payload_get_id(idp);
2373 /* If the packet is coming from server then use the sender as the
2374 origin of the the packet. If it came from router then check the real
2375 sender of the packet and use that as the origin. */
2376 if (sock->type == SILC_SOCKET_TYPE_SERVER) {
2377 id_list = server->local_list;
2379 router = sock->user_data;
2381 /* If the sender is backup router and ID is server (and we are not
2382 backup router) then switch the entry to global list. */
2383 if (server_entry->server_type == SILC_BACKUP_ROUTER &&
2384 id_type == SILC_ID_SERVER &&
2385 server->id_entry->server_type != SILC_BACKUP_ROUTER) {
2386 id_list = server->global_list;
2387 router_sock = server->router ? server->router->connection : sock;
2390 void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2391 packet->src_id_type);
2392 router = silc_idlist_find_server_by_id(server->global_list,
2393 sender_id, TRUE, NULL);
2395 router = silc_idlist_find_server_by_id(server->local_list,
2396 sender_id, TRUE, NULL);
2397 silc_free(sender_id);
2399 id_list = server->global_list;
2406 case SILC_ID_CLIENT:
2408 SilcClientEntry entry;
2410 /* Check that we do not have this client already */
2411 entry = silc_idlist_find_client_by_id(server->global_list,
2412 id, server->server_type,
2415 entry = silc_idlist_find_client_by_id(server->local_list,
2416 id, server->server_type,
2419 SILC_LOG_DEBUG(("Ignoring client that we already have"));
2423 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
2424 silc_id_render(id, SILC_ID_CLIENT),
2425 sock->type == SILC_SOCKET_TYPE_SERVER ?
2426 "Server" : "Router", sock->hostname));
2428 /* As a router we keep information of all global information in our
2429 global list. Cell wide information however is kept in the local
2431 entry = silc_idlist_add_client(id_list, NULL, NULL, NULL,
2432 id, router, NULL, 0);
2434 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
2436 /* Inform the sender that the ID is not usable */
2437 silc_server_send_notify_signoff(server, sock, FALSE, id, NULL);
2440 entry->nickname = NULL;
2441 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2443 if (sock->type == SILC_SOCKET_TYPE_SERVER)
2444 server->stat.cell_clients++;
2445 server->stat.clients++;
2447 /* Check if anyone is watching this nickname */
2448 if (server->server_type == SILC_ROUTER && id_list == server->local_list)
2449 silc_server_check_watcher_list(server, entry, NULL, 0);
2453 case SILC_ID_SERVER:
2455 SilcServerEntry entry;
2457 /* If the ID is mine, ignore it. */
2458 if (SILC_ID_SERVER_COMPARE(id, server->id)) {
2459 SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
2463 /* If the ID is the sender's ID, ignore it (we have it already) */
2464 if (SILC_ID_SERVER_COMPARE(id, router->id)) {
2465 SILC_LOG_DEBUG(("Ignoring sender's own ID"));
2469 /* Check that we do not have this server already */
2470 entry = silc_idlist_find_server_by_id(server->global_list,
2471 id, server->server_type,
2474 entry = silc_idlist_find_server_by_id(server->local_list,
2475 id, server->server_type,
2478 SILC_LOG_DEBUG(("Ignoring server that we already have"));
2482 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
2483 silc_id_render(id, SILC_ID_SERVER),
2484 sock->type == SILC_SOCKET_TYPE_SERVER ?
2485 "Server" : "Router", sock->hostname));
2487 /* As a router we keep information of all global information in our
2488 global list. Cell wide information however is kept in the local
2490 entry = silc_idlist_add_server(id_list, NULL, 0, id, router,
2493 SILC_LOG_ERROR(("Could not add new server to the ID Cache"));
2496 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2498 if (sock->type == SILC_SOCKET_TYPE_SERVER)
2499 server->stat.cell_servers++;
2500 server->stat.servers++;
2504 case SILC_ID_CHANNEL:
2505 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
2514 /* If the sender of this packet is server and we are router we need to
2515 broadcast this packet to other routers in the network. */
2516 if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
2517 sock->type == SILC_SOCKET_TYPE_SERVER &&
2518 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2519 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
2520 silc_server_packet_send(server, server->router->connection,
2522 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2523 buffer->data, buffer->len, FALSE);
2524 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
2525 packet->type, packet->flags,
2526 packet->buffer->data, packet->buffer->len,
2531 silc_id_payload_free(idp);
2535 /* Processes incoming New ID packet. New ID Payload is used to distribute
2536 information about newly registered clients and servers. */
2538 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
2539 SilcPacketContext *packet)
2541 silc_server_new_id_real(server, sock, packet, TRUE);
2544 /* Receoved New Id List packet, list of New ID payloads inside one
2545 packet. Process the New ID payloads one by one. */
2547 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
2548 SilcPacketContext *packet)
2550 SilcPacketContext *new_id;
2554 SILC_LOG_DEBUG(("Processing New ID List"));
2556 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2557 packet->src_id_type != SILC_ID_SERVER)
2560 /* If the sender of this packet is server and we are router we need to
2561 broadcast this packet to other routers in the network. Broadcast
2562 this list packet instead of multiple New ID packets. */
2563 if (!server->standalone && server->server_type == SILC_ROUTER &&
2564 sock->type == SILC_SOCKET_TYPE_SERVER &&
2565 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2566 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
2567 silc_server_packet_send(server, server->router->connection,
2569 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2570 packet->buffer->data, packet->buffer->len, FALSE);
2571 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
2572 packet->type, packet->flags,
2573 packet->buffer->data, packet->buffer->len,
2577 /* Make copy of the original packet context, except for the actual
2578 data buffer, which we will here now fetch from the original buffer. */
2579 new_id = silc_packet_context_alloc();
2580 new_id->type = SILC_PACKET_NEW_ID;
2581 new_id->flags = packet->flags;
2582 new_id->src_id = packet->src_id;
2583 new_id->src_id_len = packet->src_id_len;
2584 new_id->src_id_type = packet->src_id_type;
2585 new_id->dst_id = packet->dst_id;
2586 new_id->dst_id_len = packet->dst_id_len;
2587 new_id->dst_id_type = packet->dst_id_type;
2589 idp = silc_buffer_alloc(256);
2590 new_id->buffer = idp;
2592 while (packet->buffer->len) {
2593 SILC_GET16_MSB(id_len, packet->buffer->data + 2);
2594 if ((id_len > packet->buffer->len) ||
2595 (id_len > idp->truelen))
2598 silc_buffer_pull_tail(idp, 4 + id_len);
2599 silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
2601 /* Process the New ID */
2602 silc_server_new_id_real(server, sock, new_id, FALSE);
2604 silc_buffer_push_tail(idp, 4 + id_len);
2605 silc_buffer_pull(packet->buffer, 4 + id_len);
2608 silc_buffer_free(idp);
2612 /* Received New Channel packet. Information about new channels in the
2613 network are distributed using this packet. Save the information about
2614 the new channel. This usually comes from router but also normal server
2615 can send this to notify channels it has when it connects to us. */
2617 void silc_server_new_channel(SilcServer server,
2618 SilcSocketConnection sock,
2619 SilcPacketContext *packet)
2621 SilcChannelPayload payload;
2622 SilcChannelID *channel_id;
2624 SilcUInt32 name_len;
2628 SilcServerEntry server_entry;
2629 SilcChannelEntry channel;
2631 SILC_LOG_DEBUG(("Processing New Channel"));
2633 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2634 packet->src_id_type != SILC_ID_SERVER ||
2635 server->server_type == SILC_SERVER)
2638 /* Parse the channel payload */
2639 payload = silc_channel_payload_parse(packet->buffer->data,
2640 packet->buffer->len);
2644 /* Get the channel ID */
2645 channel_id = silc_channel_get_id_parse(payload);
2647 silc_channel_payload_free(payload);
2651 channel_name = silc_channel_get_name(payload, &name_len);
2653 channel_name[255] = '\0';
2655 id = silc_channel_get_id(payload, &id_len);
2657 server_entry = (SilcServerEntry)sock->user_data;
2659 if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
2660 /* Add the channel to global list as it is coming from router. It
2661 cannot be our own channel as it is coming from router. */
2663 /* Check that we don't already have this channel */
2664 channel = silc_idlist_find_channel_by_name(server->local_list,
2665 channel_name, NULL);
2667 channel = silc_idlist_find_channel_by_name(server->global_list,
2668 channel_name, NULL);
2670 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
2671 silc_id_render(channel_id, SILC_ID_CHANNEL),
2675 silc_idlist_add_channel(server->global_list, strdup(channel_name),
2676 0, channel_id, sock->user_data, NULL, NULL, 0);
2679 channel->disabled = TRUE;
2681 server->stat.channels++;
2682 if (server->server_type == SILC_ROUTER)
2683 channel->users_resolved = TRUE;
2686 /* The channel is coming from our server, thus it is in our cell
2687 we will add it to our local list. */
2690 SILC_LOG_DEBUG(("Channel id(%s) from [Server] %s",
2691 silc_id_render(channel_id, SILC_ID_CHANNEL),
2694 /* Check that we don't already have this channel */
2695 channel = silc_idlist_find_channel_by_name(server->local_list,
2696 channel_name, NULL);
2698 channel = silc_idlist_find_channel_by_name(server->global_list,
2699 channel_name, NULL);
2701 /* If the channel does not exist, then create it. This creates a new
2702 key to the channel as well that we will send to the server. */
2704 /* The protocol says that the Channel ID's IP address must be based
2705 on the router's IP address. Check whether the ID is based in our
2706 IP and if it is not then create a new ID and enforce the server
2707 to switch the ID. */
2708 if (server_entry->server_type != SILC_BACKUP_ROUTER &&
2709 !SILC_ID_COMPARE(channel_id, server->id, server->id->ip.data_len)) {
2711 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2713 if (silc_id_create_channel_id(server, server->id, server->rng, &tmp)) {
2714 silc_server_send_notify_channel_change(server, sock, FALSE,
2716 silc_free(channel_id);
2721 /* Create the channel with the provided Channel ID */
2722 channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
2726 silc_channel_payload_free(payload);
2727 silc_free(channel_id);
2730 channel->disabled = TRUE;
2733 /* CMODE change notify is expected */
2734 /* Get the mode and set it to the channel */
2735 channel->mode = silc_channel_get_mode(payload);
2738 /* Send the new channel key to the server */
2739 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2740 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
2741 chk = silc_channel_key_payload_encode(id_len, id,
2742 strlen(channel->channel_key->
2744 channel->channel_key->cipher->name,
2745 channel->key_len / 8,
2747 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
2748 chk->data, chk->len, FALSE);
2749 silc_buffer_free(chk);
2752 /* The channel exist by that name, check whether the ID's match.
2753 If they don't then we'll force the server to use the ID we have.
2754 We also create a new key for the channel. */
2755 SilcBuffer modes = NULL, users = NULL, users_modes = NULL;
2757 if (!SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
2758 /* They don't match, send CHANNEL_CHANGE notify to the server to
2759 force the ID change. */
2760 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2761 silc_server_send_notify_channel_change(server, sock, FALSE,
2762 channel_id, channel->id);
2765 /* If the mode is different from what we have then enforce the
2767 mode = silc_channel_get_mode(payload);
2768 if (channel->mode != mode) {
2769 SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
2770 silc_server_send_notify_cmode(server, sock, FALSE, channel,
2771 channel->mode, server->id,
2772 SILC_ID_SERVER, channel->cipher,
2774 channel->passphrase,
2775 channel->founder_key);
2778 /* Create new key for the channel and send it to the server and
2779 everybody else possibly on the channel. */
2780 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
2781 if (!silc_server_create_channel_key(server, channel, 0))
2784 /* Send to the channel */
2785 silc_server_send_channel_key(server, sock, channel, FALSE);
2786 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2787 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
2789 /* Send to the server */
2790 chk = silc_channel_key_payload_encode(id_len, id,
2791 strlen(channel->channel_key->
2793 channel->channel_key->
2795 channel->key_len / 8,
2797 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
2798 chk->data, chk->len, FALSE);
2799 silc_buffer_free(chk);
2803 silc_free(channel_id);
2805 /* Since the channel is coming from server and we also know about it
2806 then send the JOIN notify to the server so that it see's our
2807 users on the channel "joining" the channel. */
2808 silc_server_announce_get_channel_users(server, channel, &modes, &users,
2811 silc_buffer_push(modes, modes->data - modes->head);
2812 silc_server_packet_send_dest(server, sock,
2813 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2814 channel->id, SILC_ID_CHANNEL,
2815 modes->data, modes->len, FALSE);
2816 silc_buffer_free(modes);
2819 silc_buffer_push(users, users->data - users->head);
2820 silc_server_packet_send(server, sock,
2821 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2822 users->data, users->len, FALSE);
2823 silc_buffer_free(users);
2826 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
2827 silc_server_packet_send_dest(server, sock,
2828 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2829 channel->id, SILC_ID_CHANNEL,
2831 users_modes->len, FALSE);
2832 silc_buffer_free(users_modes);
2837 silc_channel_payload_free(payload);
2840 /* Received New Channel List packet, list of New Channel List payloads inside
2841 one packet. Process the New Channel payloads one by one. */
2843 void silc_server_new_channel_list(SilcServer server,
2844 SilcSocketConnection sock,
2845 SilcPacketContext *packet)
2847 SilcPacketContext *new;
2849 SilcUInt16 len1, len2;
2851 SILC_LOG_DEBUG(("Processing New Channel List"));
2853 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2854 packet->src_id_type != SILC_ID_SERVER ||
2855 server->server_type == SILC_SERVER)
2858 /* If the sender of this packet is server and we are router we need to
2859 broadcast this packet to other routers in the network. Broadcast
2860 this list packet instead of multiple New Channel packets. */
2861 if (!server->standalone && server->server_type == SILC_ROUTER &&
2862 sock->type == SILC_SOCKET_TYPE_SERVER &&
2863 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2864 SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
2865 silc_server_packet_send(server, server->router->connection,
2867 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2868 packet->buffer->data, packet->buffer->len, FALSE);
2869 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
2870 packet->type, packet->flags,
2871 packet->buffer->data, packet->buffer->len,
2875 /* Make copy of the original packet context, except for the actual
2876 data buffer, which we will here now fetch from the original buffer. */
2877 new = silc_packet_context_alloc();
2878 new->type = SILC_PACKET_NEW_CHANNEL;
2879 new->flags = packet->flags;
2880 new->src_id = packet->src_id;
2881 new->src_id_len = packet->src_id_len;
2882 new->src_id_type = packet->src_id_type;
2883 new->dst_id = packet->dst_id;
2884 new->dst_id_len = packet->dst_id_len;
2885 new->dst_id_type = packet->dst_id_type;
2887 buffer = silc_buffer_alloc(512);
2888 new->buffer = buffer;
2890 while (packet->buffer->len) {
2891 SILC_GET16_MSB(len1, packet->buffer->data);
2892 if ((len1 > packet->buffer->len) ||
2893 (len1 > buffer->truelen))
2896 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
2897 if ((len2 > packet->buffer->len) ||
2898 (len2 > buffer->truelen))
2901 silc_buffer_pull_tail(buffer, 8 + len1 + len2);
2902 silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
2904 /* Process the New Channel */
2905 silc_server_new_channel(server, sock, new);
2907 silc_buffer_push_tail(buffer, 8 + len1 + len2);
2908 silc_buffer_pull(packet->buffer, 8 + len1 + len2);
2911 silc_buffer_free(buffer);
2915 /* Received key agreement packet. This packet is never for us. It is to
2916 the client in the packet's destination ID. Sending of this sort of packet
2917 equals sending private message, ie. it is sent point to point from
2918 one client to another. */
2920 void silc_server_key_agreement(SilcServer server,
2921 SilcSocketConnection sock,
2922 SilcPacketContext *packet)
2924 SilcSocketConnection dst_sock;
2925 SilcIDListData idata;
2927 SILC_LOG_DEBUG(("Start"));
2929 if (packet->src_id_type != SILC_ID_CLIENT ||
2930 packet->dst_id_type != SILC_ID_CLIENT)
2933 if (!packet->dst_id)
2936 /* Get the route to the client */
2937 dst_sock = silc_server_get_client_route(server, packet->dst_id,
2938 packet->dst_id_len, NULL,
2943 /* Relay the packet */
2944 silc_server_relay_packet(server, dst_sock, idata->send_key,
2945 idata->hmac_send, idata->psn_send++,
2949 /* Received connection auth request packet that is used during connection
2950 phase to resolve the mandatory authentication method. This packet can
2951 actually be received at anytime but usually it is used only during
2952 the connection authentication phase. Now, protocol says that this packet
2953 can come from client or server, however, we support only this coming
2954 from client and expect that server always knows what authentication
2957 void silc_server_connection_auth_request(SilcServer server,
2958 SilcSocketConnection sock,
2959 SilcPacketContext *packet)
2961 SilcServerConfigClient *client = NULL;
2962 SilcUInt16 conn_type;
2964 SilcAuthMethod auth_meth = SILC_AUTH_NONE;
2966 SILC_LOG_DEBUG(("Start"));
2968 if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT)
2971 /* Parse the payload */
2972 ret = silc_buffer_unformat(packet->buffer,
2973 SILC_STR_UI_SHORT(&conn_type),
2974 SILC_STR_UI_SHORT(NULL),
2979 if (conn_type != SILC_SOCKET_TYPE_CLIENT)
2982 /* Get the authentication method for the client */
2983 auth_meth = SILC_AUTH_NONE;
2984 client = silc_server_config_find_client(server, sock->ip);
2986 client = silc_server_config_find_client(server, sock->hostname);
2988 if (client->passphrase) {
2989 if (client->publickeys && !server->config->prefer_passphrase_auth)
2990 auth_meth = SILC_AUTH_PUBLIC_KEY;
2992 auth_meth = SILC_AUTH_PASSWORD;
2993 } else if (client->publickeys)
2994 auth_meth = SILC_AUTH_PUBLIC_KEY;
2997 /* Send it back to the client */
2998 silc_server_send_connection_auth_request(server, sock, conn_type, auth_meth);
3001 /* Received REKEY packet. The sender of the packet wants to regenerate
3002 its session keys. This starts the REKEY protocol. */
3004 void silc_server_rekey(SilcServer server,
3005 SilcSocketConnection sock,
3006 SilcPacketContext *packet)
3008 SilcProtocol protocol;
3009 SilcServerRekeyInternalContext *proto_ctx;
3010 SilcIDListData idata = (SilcIDListData)sock->user_data;
3012 SILC_LOG_DEBUG(("Start"));
3014 /* Allocate internal protocol context. This is sent as context
3016 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
3017 proto_ctx->server = (void *)server;
3018 proto_ctx->sock = sock;
3019 proto_ctx->responder = TRUE;
3020 proto_ctx->pfs = idata->rekey->pfs;
3022 /* Perform rekey protocol. Will call the final callback after the
3023 protocol is over. */
3024 silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
3025 &protocol, proto_ctx, silc_server_rekey_final);
3026 sock->protocol = protocol;
3028 if (proto_ctx->pfs == FALSE)
3029 /* Run the protocol */
3030 silc_protocol_execute(protocol, server->schedule, 0, 0);
3033 /* Received file transger packet. This packet is never for us. It is to
3034 the client in the packet's destination ID. Sending of this sort of packet
3035 equals sending private message, ie. it is sent point to point from
3036 one client to another. */
3038 void silc_server_ftp(SilcServer server,
3039 SilcSocketConnection sock,
3040 SilcPacketContext *packet)
3042 SilcSocketConnection dst_sock;
3043 SilcIDListData idata;
3045 SILC_LOG_DEBUG(("Start"));
3047 if (packet->src_id_type != SILC_ID_CLIENT ||
3048 packet->dst_id_type != SILC_ID_CLIENT)
3051 if (!packet->dst_id)
3054 /* Get the route to the client */
3055 dst_sock = silc_server_get_client_route(server, packet->dst_id,
3056 packet->dst_id_len, NULL,
3061 /* Relay the packet */
3062 silc_server_relay_packet(server, dst_sock, idata->send_key,
3063 idata->hmac_send, idata->psn_send++,
3069 SilcSocketConnection sock;
3070 SilcPacketContext *packet;
3072 } *SilcServerResumeResolve;
3074 SILC_SERVER_CMD_FUNC(resume_resolve)
3076 SilcServerResumeResolve r = (SilcServerResumeResolve)context;
3077 SilcServer server = r->server;
3078 SilcSocketConnection sock = r->sock;
3079 SilcServerCommandReplyContext reply = context2;
3080 SilcClientEntry client;
3082 SILC_LOG_DEBUG(("Start"));
3084 if (!reply || !silc_command_get_status(reply->payload, NULL, NULL)) {
3085 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3086 "closing connection", sock->hostname, sock->ip));
3087 silc_server_disconnect_remote(server, sock,
3088 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3089 "Resuming not possible");
3093 if (reply && silc_command_get(reply->payload) == SILC_COMMAND_WHOIS) {
3094 /* Get entry to the client, and resolve it if we don't have it. */
3095 client = silc_idlist_find_client_by_id(server->local_list,
3096 r->data, TRUE, NULL);
3098 client = silc_idlist_find_client_by_id(server->global_list,
3099 r->data, TRUE, NULL);
3101 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3102 "closing connection", sock->hostname, sock->ip));
3103 silc_server_disconnect_remote(server, sock,
3104 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3105 "Resuming not possible");
3110 if (!(client->mode & SILC_UMODE_DETACHED)) {
3111 SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, "
3112 "closing connection", sock->hostname, sock->ip));
3113 silc_server_disconnect_remote(server, sock,
3114 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3115 "Resuming not possible");
3120 /* Reprocess the packet */
3121 silc_server_resume_client(server, sock, r->packet);
3124 silc_socket_free(r->sock);
3125 silc_packet_context_free(r->packet);
3130 /* Received client resuming packet. This is used to resume detached
3131 client session. It can be sent by the client who wishes to resume
3132 but this is also sent by servers and routers to notify other routers
3133 that the client is not detached anymore. */
3135 void silc_server_resume_client(SilcServer server,
3136 SilcSocketConnection sock,
3137 SilcPacketContext *packet)
3139 SilcBuffer buffer = packet->buffer, buf;
3140 SilcIDListData idata;
3141 SilcClientEntry detached_client;
3142 SilcClientID *client_id = NULL;
3143 unsigned char *id_string, *auth = NULL;
3144 SilcUInt16 id_len, auth_len = 0;
3145 int ret, nickfail = 0;
3146 bool resolved, local, nick_change = FALSE, resolve = FALSE;
3147 SilcChannelEntry channel;
3148 SilcHashTableList htl;
3149 SilcChannelClientEntry chl;
3150 SilcServerResumeResolve r;
3152 SILC_LOG_DEBUG(("Start"));
3154 ret = silc_buffer_unformat(buffer,
3155 SILC_STR_UI16_NSTRING(&id_string, &id_len),
3158 client_id = silc_id_str2id(id_string, id_len, SILC_ID_CLIENT);
3160 if (sock->type == SILC_SOCKET_TYPE_CLIENT) {
3161 /* Client send this and is attempting to resume to old client session */
3162 SilcClientEntry client;
3166 silc_buffer_pull(buffer, 2 + id_len);
3167 auth = buffer->data;
3168 auth_len = buffer->len;
3169 silc_buffer_push(buffer, 2 + id_len);
3172 if (!client_id || auth_len < 128) {
3173 SILC_LOG_ERROR(("Client %s (%s) sent incomplete resume information, "
3174 "closing connection", sock->hostname, sock->ip));
3175 silc_server_disconnect_remote(server, sock,
3176 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3177 "Resuming not possible");
3181 /* Take client entry of this connection */
3182 client = (SilcClientEntry)sock->user_data;
3183 idata = (SilcIDListData)client;
3185 /* Get entry to the client, and resolve it if we don't have it. */
3186 detached_client = silc_server_get_client_resolve(server, client_id, FALSE,
3188 if (!detached_client) {
3190 /* The client info is being resolved. Reprocess this packet after
3191 receiving the reply to the query. */
3192 SILC_LOG_DEBUG(("Resolving client"));
3193 r = silc_calloc(1, sizeof(*r));
3197 r->sock = silc_socket_dup(sock);
3198 r->packet = silc_packet_context_dup(packet);
3199 r->data = silc_id_dup(client_id, SILC_ID_CLIENT);
3200 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
3202 silc_server_command_resume_resolve, r);
3204 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3205 "closing connection", sock->hostname, sock->ip));
3206 silc_server_disconnect_remote(server, sock,
3207 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3208 "Resuming not possible");
3213 if (!(detached_client->mode & SILC_UMODE_DETACHED))
3215 if (!silc_hash_table_count(detached_client->channels) &&
3216 detached_client->router)
3218 if (!detached_client->nickname)
3222 if (server->server_type == SILC_SERVER && !server->standalone) {
3223 /* The client info is being resolved. Reprocess this packet after
3224 receiving the reply to the query. */
3225 SILC_LOG_DEBUG(("Resolving client info"));
3226 silc_server_get_client_resolve(server, client_id, TRUE, NULL);
3227 r = silc_calloc(1, sizeof(*r));
3231 r->sock = silc_socket_dup(sock);
3232 r->packet = silc_packet_context_dup(packet);
3233 r->data = silc_id_dup(client_id, SILC_ID_CLIENT);
3234 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
3236 silc_server_command_resume_resolve, r);
3239 if (server->server_type == SILC_SERVER) {
3240 SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, "
3241 "closing connection", sock->hostname, sock->ip));
3242 silc_server_disconnect_remote(server, sock,
3243 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3244 "Resuming not possible");
3249 /* Check that we have the public key of the client, if not then we must
3250 resolve it first. */
3251 if (!detached_client->data.public_key) {
3252 if (server->server_type == SILC_SERVER && server->standalone) {
3253 silc_server_disconnect_remote(server, sock,
3254 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3255 "Resuming not possible");
3257 /* We must retrieve the detached client's public key by sending
3258 GETKEY command. Reprocess this packet after receiving the key */
3259 SilcBuffer idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
3260 SilcSocketConnection dest_sock =
3261 silc_server_get_client_route(server, NULL, 0, client_id, NULL, NULL);
3263 SILC_LOG_DEBUG(("Resolving client public key"));
3265 silc_server_send_command(server, dest_sock ? dest_sock :
3266 server->router->connection,
3267 SILC_COMMAND_GETKEY, ++server->cmd_ident,
3268 1, 1, idp->data, idp->len);
3270 r = silc_calloc(1, sizeof(*r));
3275 r->sock = silc_socket_dup(sock);
3276 r->packet = silc_packet_context_dup(packet);
3277 silc_server_command_pending(server, SILC_COMMAND_GETKEY,
3279 silc_server_command_resume_resolve, r);
3281 silc_buffer_free(idp);
3284 } else if (!silc_pkcs_public_key_compare(detached_client->data.public_key,
3285 idata->public_key)) {
3286 /* We require that the connection and resuming authentication data
3287 must be using same key pair. */
3288 silc_server_disconnect_remote(server, sock,
3289 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3290 "Resuming not possible");
3294 /* Verify the authentication payload. This has to be successful in
3295 order to allow the resuming */
3297 !silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
3298 detached_client->data.public_key, 0,
3299 idata->hash, detached_client->id,
3301 SILC_LOG_ERROR(("Client %s (%s) resume authentication failed, "
3302 "closing connection", sock->hostname, sock->ip));
3303 silc_server_disconnect_remote(server, sock,
3304 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3305 "Resuming not possible");
3309 /* Now resume the client to the network */
3311 silc_schedule_task_del_by_context(server->schedule, detached_client);
3312 sock->user_data = detached_client;
3313 detached_client->connection = sock;
3315 /* Take new keys and stuff into use in the old entry */
3316 silc_idlist_del_data(detached_client);
3317 silc_idlist_add_data(detached_client, idata);
3318 detached_client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
3319 detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
3320 detached_client->mode &= ~SILC_UMODE_DETACHED;
3322 /* Send the RESUME_CLIENT packet to our primary router so that others
3323 know this client isn't detached anymore. */
3324 buf = silc_buffer_alloc_size(2 + id_len);
3325 silc_buffer_format(buf,
3326 SILC_STR_UI_SHORT(id_len),
3327 SILC_STR_UI_XNSTRING(id_string, id_len),
3330 /* Send to primary router */
3331 if (!server->standalone)
3332 silc_server_packet_send(server, server->router->connection,
3333 SILC_PACKET_RESUME_CLIENT, 0,
3334 buf->data, buf->len, TRUE);
3336 /* As router we must deliver this packet directly to the original
3337 server whom this client was earlier. */
3338 if (server->server_type == SILC_ROUTER && detached_client->router &&
3339 detached_client->router->server_type != SILC_ROUTER)
3340 silc_server_packet_send(server, detached_client->router->connection,
3341 SILC_PACKET_RESUME_CLIENT, 0,
3342 buf->data, buf->len, TRUE);
3343 silc_buffer_free(buf);
3345 detached_client->router = NULL;
3347 /* Delete this client entry since we're resuming to old one. */
3348 server->stat.my_clients--;
3349 server->stat.clients--;
3350 if (server->stat.cell_clients)
3351 server->stat.cell_clients--;
3352 silc_server_del_from_watcher_list(server, client);
3353 silc_idlist_del_client(server->local_list, client);
3354 client = detached_client;
3356 /* If the ID is not based in our ID then change it */
3357 if (!SILC_ID_COMPARE(client->id, server->id, server->id->ip.data_len)) {
3358 while (!silc_id_create_client_id(server, server->id, server->rng,
3359 server->md5hash, client->nickname,
3363 silc_server_disconnect_remote(server, sock,
3364 SILC_STATUS_ERR_BAD_NICKNAME, NULL);
3367 snprintf(&client->nickname[strlen(client->nickname) - 1], 1,
3374 /* Notify about Client ID change, nickname doesn't actually change. */
3375 if (!server->standalone)
3376 silc_server_send_notify_nick_change(server, server->router->connection,
3377 FALSE, client->id, client_id,
3381 /* Resolve users on those channels that client has joined but we
3382 haven't resolved user list yet. */
3383 if (server->server_type == SILC_SERVER && !server->standalone) {
3384 silc_hash_table_list(client->channels, &htl);
3385 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
3386 channel = chl->channel;
3387 SILC_LOG_DEBUG(("Resolving users for %s channel",
3388 channel->channel_name));
3389 if (channel->disabled || !channel->users_resolved) {
3390 silc_server_send_command(server, server->router->connection,
3391 SILC_COMMAND_USERS, ++server->cmd_ident,
3392 1, 2, channel->channel_name,
3393 strlen(channel->channel_name));
3396 silc_hash_table_list_reset(&htl);
3399 /* Send the new client ID to the client. After this client may start
3400 receiving other packets, and may start sending packets too. */
3401 silc_server_send_new_id(server, sock, FALSE, client_id, SILC_ID_CLIENT,
3402 silc_id_get_len(client_id, SILC_ID_CLIENT));
3405 /* Send NICK change notify to channels as well. */
3406 SilcBuffer oidp, nidp;
3407 oidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3408 nidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
3409 silc_server_send_notify_on_channels(server, NULL, client,
3410 SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
3411 oidp->data, oidp->len,
3412 nidp->data, nidp->len,
3414 strlen(client->nickname));
3415 silc_buffer_free(oidp);
3416 silc_buffer_free(nidp);
3419 /* Add the client again to the ID cache to get it to correct list */
3420 if (!silc_idcache_del_by_context(server->local_list->clients, client))
3421 silc_idcache_del_by_context(server->global_list->clients, client);
3422 silc_free(client->id);
3423 client->id = client_id;
3425 silc_idcache_add(server->local_list->clients, client->nickname,
3426 client->id, client, 0, NULL);
3428 /* Send some nice info to the client */
3429 silc_server_send_connect_notifys(server, sock, client);
3431 /* Send all channel keys of channels the client has joined */
3432 silc_hash_table_list(client->channels, &htl);
3433 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
3434 bool created = FALSE;
3435 channel = chl->channel;
3437 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY)
3440 /* If we don't have channel key, then create one */
3441 if (!channel->channel_key) {
3442 if (!silc_server_create_channel_key(server, channel, 0))
3447 id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3449 silc_channel_key_payload_encode(silc_id_get_len(channel->id,
3452 strlen(channel->channel_key->
3454 channel->channel_key->cipher->name,
3455 channel->key_len / 8, channel->key);
3456 silc_free(id_string);
3458 /* Send the key packet to client */
3459 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
3460 keyp->data, keyp->len, FALSE);
3462 if (created && server->server_type == SILC_SERVER &&
3463 !server->standalone)
3464 silc_server_packet_send(server, server->router->connection,
3465 SILC_PACKET_CHANNEL_KEY, 0,
3466 keyp->data, keyp->len, FALSE);
3468 silc_buffer_free(keyp);
3470 silc_hash_table_list_reset(&htl);
3472 } else if (sock->type != SILC_SOCKET_TYPE_CLIENT) {
3473 /* Server or router sent this to us to notify that that a client has
3475 SilcServerEntry server_entry;
3476 SilcServerID *server_id;
3481 /* Get entry to the client, and resolve it if we don't have it. */
3482 detached_client = silc_idlist_find_client_by_id(server->local_list,
3483 client_id, TRUE, NULL);
3484 if (!detached_client) {
3485 detached_client = silc_idlist_find_client_by_id(server->global_list,
3486 client_id, TRUE, NULL);
3487 if (!detached_client)
3491 /* Check that the client has not been resumed already because it is
3492 protocol error to attempt to resume more than once. The client
3493 will be killed if this protocol error occurs. */
3494 if (detached_client->data.status & SILC_IDLIST_STATUS_RESUMED &&
3495 !(detached_client->mode & SILC_UMODE_DETACHED)) {
3496 /* The client is clearly attempting to resume more than once and
3497 perhaps playing around by resuming from several different places
3498 at the same time. */
3499 silc_server_kill_client(server, detached_client, NULL,
3500 server->id, SILC_ID_SERVER);
3504 /* Check whether client is detached at all */
3505 if (!(detached_client->mode & SILC_UMODE_DETACHED))
3508 /* Client is detached, and now it is resumed. Remove the detached
3509 mode and mark that it is resumed. */
3510 detached_client->mode &= ~SILC_UMODE_DETACHED;
3511 detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
3513 /* Get the new owner of the resumed client */
3514 server_id = silc_id_str2id(packet->src_id, packet->src_id_len,
3515 packet->src_id_type);
3519 /* Get server entry */
3520 server_entry = silc_idlist_find_server_by_id(server->global_list,
3521 server_id, TRUE, NULL);
3523 if (!server_entry) {
3524 server_entry = silc_idlist_find_server_by_id(server->local_list,
3525 server_id, TRUE, NULL);
3527 if (!server_entry) {
3528 silc_free(server_id);
3533 if (server->server_type == SILC_ROUTER &&
3534 sock->type == SILC_SOCKET_TYPE_ROUTER &&
3535 server_entry->server_type == SILC_ROUTER)
3538 SILC_LOG_DEBUG(("Resuming detached client"));
3540 /* Change the client to correct list. */
3541 if (!silc_idcache_del_by_context(server->local_list->clients,
3543 silc_idcache_del_by_context(server->global_list->clients,
3545 silc_idcache_add(local && server->server_type == SILC_ROUTER ?
3546 server->local_list->clients :
3547 server->global_list->clients,
3548 detached_client->nickname,
3549 detached_client->id, detached_client, FALSE, NULL);
3551 /* Change the owner of the client if needed */
3552 if (detached_client->router != server_entry)
3553 detached_client->router = server_entry;
3555 /* Update channel information regarding global clients on channel. */
3556 if (server->server_type == SILC_SERVER) {
3557 silc_hash_table_list(detached_client->channels, &htl);
3558 while (silc_hash_table_get(&htl, NULL, (void **)&chl))
3559 chl->channel->global_users =
3560 silc_server_channel_has_global(chl->channel);
3561 silc_hash_table_list_reset(&htl);
3564 silc_schedule_task_del_by_context(server->schedule, detached_client);
3566 /* If the sender of this packet is server and we are router we need to
3567 broadcast this packet to other routers in the network. */
3568 if (!server->standalone && server->server_type == SILC_ROUTER &&
3569 sock->type == SILC_SOCKET_TYPE_SERVER &&
3570 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
3571 SILC_LOG_DEBUG(("Broadcasting received Resume Client packet"));
3572 silc_server_packet_send(server, server->router->connection,
3574 packet->flags | SILC_PACKET_FLAG_BROADCAST,
3575 buffer->data, buffer->len, FALSE);
3576 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
3577 packet->type, packet->flags,
3578 packet->buffer->data, packet->buffer->len,
3582 silc_free(server_id);
3585 silc_free(client_id);