5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2002 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
21 * Server packet routines to handle received packets.
25 #include "serverincludes.h"
26 #include "server_internal.h"
28 /* Received notify packet. Server can receive notify packets from router.
29 Server then relays the notify messages to clients if needed. */
31 void silc_server_notify(SilcServer server,
32 SilcSocketConnection sock,
33 SilcPacketContext *packet)
35 SilcNotifyPayload payload;
37 SilcArgumentPayload args;
38 SilcChannelID *channel_id = NULL, *channel_id2;
39 SilcClientID *client_id, *client_id2;
40 SilcServerID *server_id;
42 SilcChannelEntry channel = NULL;
43 SilcClientEntry client = NULL, client2 = NULL;
44 SilcServerEntry server_entry = NULL;
45 SilcChannelClientEntry chl;
46 SilcIDCacheEntry cache = NULL;
47 SilcHashTableList htl;
53 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
54 packet->src_id_type != SILC_ID_SERVER || !packet->dst_id) {
55 SILC_LOG_DEBUG(("Bad notify packet received"));
59 /* If the packet is destined directly to a client then relay the packet
60 before processing it. */
61 if (packet->dst_id_type == SILC_ID_CLIENT) {
63 SilcSocketConnection dst_sock;
65 /* Get the route to the client */
66 dst_sock = silc_server_get_client_route(server, packet->dst_id,
67 packet->dst_id_len, NULL,
70 /* Relay the packet */
71 silc_server_relay_packet(server, dst_sock, idata->send_key,
72 idata->hmac_send, idata->psn_send++,
76 /* Parse the Notify Payload */
77 payload = silc_notify_payload_parse(packet->buffer->data,
82 /* If we are router and this packet is not already broadcast packet
83 we will broadcast it. The sending socket really cannot be router or
84 the router is buggy. If this packet is coming from router then it must
85 have the broadcast flag set already and we won't do anything. */
86 if (server->server_type == SILC_ROUTER &&
87 sock->type == SILC_SOCKET_TYPE_SERVER &&
88 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
89 SILC_LOG_DEBUG(("Broadcasting received Notify packet"));
90 if (packet->dst_id_type == SILC_ID_CHANNEL) {
91 /* Packet is destined to channel */
92 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
97 silc_server_packet_send_dest(server, SILC_PRIMARY_ROUTE(server),
98 packet->type, packet->flags |
99 SILC_PACKET_FLAG_BROADCAST,
100 channel_id, SILC_ID_CHANNEL,
101 packet->buffer->data,
102 packet->buffer->len, FALSE);
103 silc_server_backup_send_dest(server, sock->user_data,
104 packet->type, packet->flags,
105 channel_id, SILC_ID_CHANNEL,
106 packet->buffer->data, packet->buffer->len,
109 /* Packet is destined to client or server */
110 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
112 packet->flags | SILC_PACKET_FLAG_BROADCAST,
113 packet->buffer->data, packet->buffer->len,
115 silc_server_backup_send(server, sock->user_data,
116 packet->type, packet->flags,
117 packet->buffer->data, packet->buffer->len,
122 type = silc_notify_get_type(payload);
123 args = silc_notify_get_args(payload);
128 case SILC_NOTIFY_TYPE_JOIN:
130 * Distribute the notify to local clients on the channel
132 SILC_LOG_DEBUG(("JOIN notify"));
135 silc_free(channel_id);
138 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
141 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
145 /* Get channel entry */
146 channel = silc_idlist_find_channel_by_id(server->global_list,
149 channel = silc_idlist_find_channel_by_id(server->local_list,
152 SILC_LOG_DEBUG(("Notify for unknown channel"));
153 silc_free(channel_id);
157 silc_free(channel_id);
160 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
163 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
167 /* If the the client is not in local list we check global list (ie. the
168 channel will be global channel) and if it does not exist then create
169 entry for the client. */
170 client = silc_idlist_find_client_by_id(server->global_list,
171 client_id, server->server_type,
174 client = silc_idlist_find_client_by_id(server->local_list,
175 client_id, server->server_type,
178 /* If router did not find the client the it is bogus */
179 if (server->server_type != SILC_SERVER) {
180 silc_free(client_id);
185 silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
186 silc_id_dup(client_id, SILC_ID_CLIENT),
187 sock->user_data, NULL, 0);
189 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
190 silc_free(client_id);
194 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
197 silc_free(client_id);
199 /* Do not process the notify if the client is not registered */
200 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
203 /* Do not add client to channel if it is there already */
204 if (silc_server_client_on_channel(client, channel, NULL)) {
205 SILC_LOG_DEBUG(("Client already on channel %s",
206 channel->channel_name));
210 /* Send to channel */
211 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
212 FALSE, packet->buffer->data,
213 packet->buffer->len, FALSE);
215 if (server->server_type != SILC_ROUTER &&
216 sock->type == SILC_SOCKET_TYPE_ROUTER)
217 /* The channel is global now */
218 channel->global_users = TRUE;
220 SILC_LOG_DEBUG(("Joining to channel %s", channel->channel_name));
222 /* JOIN the global client to the channel (local clients (if router
223 created the channel) is joined in the pending JOIN command). */
224 chl = silc_calloc(1, sizeof(*chl));
225 chl->client = client;
226 chl->channel = channel;
228 if (server->server_type != SILC_ROUTER ||
229 sock->type == SILC_SOCKET_TYPE_ROUTER) {
230 /* If this is the first one on the channel then it is the founder of
231 the channel. This is done on normal server and on router if this
232 notify is coming from router */
233 if (!silc_hash_table_count(channel->user_list)) {
234 SILC_LOG_DEBUG(("Client %s is founder on channel",
235 silc_id_render(chl->client->id, SILC_ID_CLIENT)));
236 chl->mode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
240 silc_hash_table_add(channel->user_list, client, chl);
241 silc_hash_table_add(client->channels, channel, chl);
242 channel->user_count++;
243 channel->disabled = FALSE;
245 /* Make sure we don't expire clients that are on channel */
249 /* Update statistics */
250 if (server->server_type == SILC_ROUTER) {
251 if (sock->type != SILC_SOCKET_TYPE_ROUTER)
252 server->stat.cell_chanclients++;
253 server->stat.chanclients++;
258 case SILC_NOTIFY_TYPE_LEAVE:
260 * Distribute the notify to local clients on the channel
262 SILC_LOG_DEBUG(("LEAVE notify"));
265 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
266 packet->dst_id_type);
271 /* Get channel entry */
272 channel = silc_idlist_find_channel_by_id(server->global_list,
275 channel = silc_idlist_find_channel_by_id(server->local_list,
278 SILC_LOG_DEBUG(("Notify for unknown channel"));
279 silc_free(channel_id);
285 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
287 silc_free(channel_id);
290 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
292 silc_free(channel_id);
296 /* Get client entry */
297 client = silc_idlist_find_client_by_id(server->global_list,
298 client_id, TRUE, NULL);
300 client = silc_idlist_find_client_by_id(server->local_list,
301 client_id, TRUE, NULL);
303 silc_free(client_id);
304 silc_free(channel_id);
308 silc_free(client_id);
309 silc_free(channel_id);
311 /* Check if on channel */
312 if (!silc_server_client_on_channel(client, channel, NULL))
315 /* Send the leave notify to channel */
316 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
317 FALSE, packet->buffer->data,
318 packet->buffer->len, FALSE);
320 /* Remove the user from channel */
321 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
324 case SILC_NOTIFY_TYPE_SIGNOFF:
326 * Distribute the notify to local clients on the channel
328 SILC_LOG_DEBUG(("SIGNOFF notify"));
331 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
334 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
338 /* Get client entry */
339 client = silc_idlist_find_client_by_id(server->global_list,
340 client_id, TRUE, &cache);
342 client = silc_idlist_find_client_by_id(server->local_list,
343 client_id, TRUE, &cache);
345 silc_free(client_id);
349 silc_free(client_id);
351 /* Get signoff message */
352 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
356 /* Update statistics */
357 server->stat.clients--;
358 if (server->stat.cell_clients)
359 server->stat.cell_clients--;
360 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
361 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
362 silc_schedule_task_del_by_context(server->schedule, client);
364 /* Remove the client from all channels. */
365 silc_server_remove_from_channels(server, NULL, client, TRUE,
368 /* Check if anyone is watching this nickname */
369 if (server->server_type == SILC_ROUTER)
370 silc_server_check_watcher_list(server, client, NULL,
371 SILC_NOTIFY_TYPE_SIGNOFF);
373 /* Remove this client from watcher list if it is */
374 silc_server_del_from_watcher_list(server, client);
376 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
377 cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
380 case SILC_NOTIFY_TYPE_TOPIC_SET:
382 * Distribute the notify to local clients on the channel
385 SILC_LOG_DEBUG(("TOPIC SET notify"));
388 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
391 client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
395 /* Get client entry */
396 if (id_type == SILC_ID_CLIENT) {
397 client = silc_idlist_find_client_by_id(server->global_list,
398 client_id, TRUE, &cache);
400 client = silc_idlist_find_client_by_id(server->local_list,
401 client_id, TRUE, &cache);
403 silc_free(client_id);
407 silc_free(client_id);
411 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
413 silc_free(channel_id);
418 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
419 packet->dst_id_type);
424 /* Get channel entry */
425 channel = silc_idlist_find_channel_by_id(server->global_list,
428 channel = silc_idlist_find_channel_by_id(server->local_list,
431 SILC_LOG_DEBUG(("Notify for unknown channel"));
432 silc_free(channel_id);
436 silc_free(channel_id);
438 if (channel->topic && !strcmp(channel->topic, tmp)) {
439 SILC_LOG_DEBUG(("Topic is already set and same"));
444 /* Get user's channel entry and check that topic set is allowed. */
445 if (!silc_server_client_on_channel(client, channel, &chl))
447 if (channel->mode & SILC_CHANNEL_MODE_TOPIC &&
448 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
449 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
450 SILC_LOG_DEBUG(("Topic change is not allowed"));
455 /* Change the topic */
456 silc_free(channel->topic);
457 channel->topic = strdup(tmp);
459 /* Send the same notify to the channel */
460 silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
461 FALSE, packet->buffer->data,
462 packet->buffer->len, FALSE);
465 case SILC_NOTIFY_TYPE_NICK_CHANGE:
468 * Distribute the notify to local clients on the channel
470 unsigned char *id, *id2;
472 SilcUInt32 nickname_len;
474 SILC_LOG_DEBUG(("NICK CHANGE notify"));
476 /* Get old client ID */
477 id = silc_argument_get_arg_type(args, 1, &tmp_len);
480 client_id = silc_id_payload_parse_id(id, tmp_len, NULL);
484 /* Get new client ID */
485 id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
488 client_id2 = silc_id_payload_parse_id(id2, tmp_len, NULL);
490 silc_free(client_id);
494 SILC_LOG_DEBUG(("Old Client ID id(%s)",
495 silc_id_render(client_id, SILC_ID_CLIENT)));
496 SILC_LOG_DEBUG(("New Client ID id(%s)",
497 silc_id_render(client_id2, SILC_ID_CLIENT)));
499 /* From protocol version 1.1 we also get the new nickname */
500 nickname = silc_argument_get_arg_type(args, 3, &nickname_len);;
502 /* Replace the Client ID */
503 client = silc_idlist_replace_client_id(server,
504 server->global_list, client_id,
505 client_id2, nickname);
507 client = silc_idlist_replace_client_id(server,
508 server->local_list, client_id,
509 client_id2, nickname);
512 /* Send the NICK_CHANGE notify type to local clients on the channels
513 this client is joined to. */
514 silc_server_send_notify_on_channels(server, client, client,
515 SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
516 id, tmp_len, id2, tmp_len,
521 silc_free(client_id);
523 silc_free(client_id2);
527 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
529 * Distribute the notify to local clients on the channel
532 SILC_LOG_DEBUG(("CMODE CHANGE notify"));
535 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
538 client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
542 /* Get client entry */
543 if (id_type == SILC_ID_CLIENT) {
544 client = silc_idlist_find_client_by_id(server->global_list,
545 client_id, TRUE, &cache);
547 client = silc_idlist_find_client_by_id(server->local_list,
548 client_id, TRUE, &cache);
550 silc_free(client_id);
555 silc_free(client_id);
558 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
559 packet->dst_id_type);
564 /* Get channel entry */
565 channel = silc_idlist_find_channel_by_id(server->global_list,
568 channel = silc_idlist_find_channel_by_id(server->local_list,
571 SILC_LOG_DEBUG(("Notify for unknown channel"));
572 silc_free(channel_id);
576 silc_free(channel_id);
579 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
582 SILC_GET32_MSB(mode, tmp);
584 /* Check if mode changed */
585 if (channel->mode == mode) {
586 SILC_LOG_DEBUG(("Mode is changed already"));
588 /* If this mode change has founder mode then we'll enforce the
589 change so that the server gets the real founder public key */
590 if (server->server_type != SILC_SERVER &&
591 sock != SILC_PRIMARY_ROUTE(server) &&
592 mode & SILC_CHANNEL_MODE_FOUNDER_AUTH && channel->founder_key) {
593 SILC_LOG_DEBUG(("Sending founder public key to server"));
594 silc_server_send_notify_cmode(server, sock, FALSE, channel,
595 channel->mode, server->id,
596 SILC_ID_SERVER, channel->cipher,
599 channel->founder_key);
602 /* If we received same mode from our primary check whether founder
603 mode and key in the notify is set. We update the founder key
604 here since we may have wrong one */
605 if (server->server_type == SILC_SERVER &&
606 sock == SILC_PRIMARY_ROUTE(server) &&
607 mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
608 SILC_LOG_DEBUG(("Founder public key received from router"));
609 tmp = silc_argument_get_arg_type(args, 6, &tmp_len);
613 if (channel->founder_key)
614 silc_pkcs_public_key_free(channel->founder_key);
615 channel->founder_key = NULL;
616 silc_pkcs_public_key_payload_decode(tmp, tmp_len,
617 &channel->founder_key);
623 /* Get user's channel entry and check that mode change is allowed */
625 if (!silc_server_client_on_channel(client, channel, &chl))
627 if (!silc_server_check_cmode_rights(server, channel, chl, mode)) {
628 SILC_LOG_DEBUG(("CMODE change is not allowed"));
629 silc_server_send_notify_cmode(server, sock, FALSE, channel,
630 channel->mode, server->id,
631 SILC_ID_SERVER, channel->cipher,
634 channel->founder_key);
638 /* Assure that server is not removing founder mode from us */
639 if (server->server_type == SILC_ROUTER &&
640 sock != SILC_PRIMARY_ROUTE(server) &&
641 channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH &&
642 !(mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
643 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
644 silc_server_send_notify_cmode(server, sock, FALSE, channel,
645 channel->mode, server->id,
646 SILC_ID_SERVER, channel->cipher,
649 channel->founder_key);
653 /* If server is adding founder mode, check whether there is founder
654 on channel already and is not from this server */
655 if (server->server_type == SILC_ROUTER &&
656 sock != SILC_PRIMARY_ROUTE(server) &&
657 mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
658 silc_hash_table_list(channel->user_list, &htl);
659 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
660 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO &&
661 chl->client->router != sock->user_data) {
662 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
663 silc_server_send_notify_cmode(server, sock, FALSE, channel,
664 channel->mode, server->id,
665 SILC_ID_SERVER, channel->cipher,
668 channel->founder_key);
669 silc_hash_table_list_reset(&htl);
672 silc_hash_table_list_reset(&htl);
676 /* If the channel had private keys set and the mode was removed then
677 we must re-generate and re-distribute a new channel key */
678 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY &&
679 !(mode & SILC_CHANNEL_MODE_PRIVKEY)) {
680 /* Re-generate channel key */
681 if (!silc_server_create_channel_key(server, channel, 0))
684 /* Send the channel key. This sends it to our local clients and if
685 we are normal server to our router as well. */
686 silc_server_send_channel_key(server, NULL, channel,
687 server->server_type == SILC_ROUTER ?
688 FALSE : !server->standalone);
692 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
694 unsigned char hash[32];
697 silc_hmac_free(channel->hmac);
698 if (!silc_hmac_alloc(tmp, NULL, &channel->hmac))
701 /* Set the HMAC key out of current channel key. The client must do
703 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key,
704 channel->key_len / 8, hash);
705 silc_hmac_set_key(channel->hmac, hash,
706 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
707 memset(hash, 0, sizeof(hash));
710 /* Get the passphrase */
711 tmp = silc_argument_get_arg_type(args, 5, &tmp_len);
713 silc_free(channel->passphrase);
714 channel->passphrase = silc_memdup(tmp, tmp_len);
717 /* Get founder public key */
718 tmp = silc_argument_get_arg_type(args, 6, &tmp_len);
719 if (tmp && mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
720 if (channel->founder_key)
721 silc_pkcs_public_key_free(channel->founder_key);
722 channel->founder_key = NULL;
723 silc_pkcs_public_key_payload_decode(tmp, tmp_len, &channel->founder_key);
725 if (!channel->founder_key ||
726 (client && client->data.public_key &&
727 server->server_type == SILC_ROUTER &&
728 !silc_pkcs_public_key_compare(channel->founder_key,
729 client->data.public_key))) {
730 /* A really buggy server isn't checking public keys correctly.
731 It's not possible that the mode setter and founder wouldn't
732 have same public key. */
733 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
735 mode &= ~SILC_CHANNEL_MODE_FOUNDER_AUTH;
736 silc_server_send_notify_cmode(server, sock, FALSE, channel,
737 mode, server->id, SILC_ID_SERVER,
740 channel->passphrase, NULL);
741 if (channel->founder_key)
742 silc_pkcs_public_key_free(channel->founder_key);
743 channel->founder_key = NULL;
744 } else if (client && !client->data.public_key) {
745 client->data.public_key =
746 silc_pkcs_public_key_copy(channel->founder_key);
750 if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH && !channel->founder_key &&
751 server->server_type == SILC_ROUTER) {
752 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
753 mode &= ~SILC_CHANNEL_MODE_FOUNDER_AUTH;
754 silc_server_send_notify_cmode(server, sock, FALSE, channel,
755 mode, server->id, SILC_ID_SERVER,
758 channel->passphrase, NULL);
761 /* Send the same notify to the channel */
762 silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
763 FALSE, packet->buffer->data,
764 packet->buffer->len, FALSE);
767 channel->mode = mode;
769 if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) &&
770 channel->founder_key) {
771 silc_pkcs_public_key_free(channel->founder_key);
772 channel->founder_key = NULL;
777 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
780 * Distribute the notify to local clients on the channel
782 SilcChannelClientEntry chl2 = NULL;
783 bool notify_sent = FALSE;
785 SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
788 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
791 client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
795 /* Get client entry */
796 if (id_type == SILC_ID_CLIENT) {
797 client = silc_idlist_find_client_by_id(server->global_list,
798 client_id, TRUE, &cache);
800 client = silc_idlist_find_client_by_id(server->local_list,
801 client_id, TRUE, &cache);
803 silc_free(client_id);
808 silc_free(client_id);
811 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
812 packet->dst_id_type);
817 /* Get channel entry */
818 channel = silc_idlist_find_channel_by_id(server->global_list,
821 channel = silc_idlist_find_channel_by_id(server->local_list,
824 SILC_LOG_DEBUG(("Notify for unknown channel"));
825 silc_free(channel_id);
831 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
833 silc_free(channel_id);
837 SILC_GET32_MSB(mode, tmp);
839 /* Get target client */
840 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
843 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
847 /* Get client entry */
848 client2 = silc_idlist_find_client_by_id(server->global_list,
849 client_id, TRUE, NULL);
851 client2 = silc_idlist_find_client_by_id(server->local_list,
852 client_id, TRUE, NULL);
854 silc_free(client_id);
858 silc_free(client_id);
861 /* Check that sender is on channel */
862 if (!silc_server_client_on_channel(client, channel, &chl))
865 if (client != client2 && server->server_type == SILC_ROUTER) {
866 /* Sender must be operator */
867 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
868 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
869 SILC_LOG_DEBUG(("CUMODE change is not allowed"));
873 if (!silc_server_client_on_channel(client2, channel, &chl))
876 /* If target is founder mode change is not allowed. */
877 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
878 SILC_LOG_DEBUG(("CUMODE change is not allowed"));
884 /* Get target channel user entry */
885 if (!silc_server_client_on_channel(client2, channel, &chl))
888 if (server->server_type == SILC_SERVER && chl->mode == mode) {
889 SILC_LOG_DEBUG(("Mode is changed already"));
893 if (mode & SILC_CHANNEL_UMODE_CHANFO &&
894 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO) &&
895 server->server_type == SILC_ROUTER &&
896 sock != SILC_PRIMARY_ROUTE(server)) {
897 SilcPublicKey founder_key = NULL;
899 /* If channel doesn't have founder auth mode then it's impossible
900 that someone would be getting founder rights with CUMODE command.
901 In that case there already either is founder or there isn't
902 founder at all on the channel. */
903 if (client && !(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
904 /* Force the mode to not have founder mode */
905 chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
906 silc_server_force_cumode_change(server, sock, channel, chl, mode);
911 /* Get the founder of the channel and if found then this client
912 cannot be the founder since there already is one. */
913 silc_hash_table_list(channel->user_list, &htl);
914 while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
915 if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
916 /* If the founder on the channel is not the one whom has set
917 the founder mode, then it's possible that this CUMODE_CHANGE
918 is correct. Due to netsplits it's possible that this
919 situation happens. */
920 if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) ||
921 (channel->founder_key && chl2->client->data.public_key &&
922 silc_pkcs_public_key_compare(
923 channel->founder_key,
924 chl2->client->data.public_key))) {
925 chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
926 silc_server_force_cumode_change(server, sock, channel,
932 silc_hash_table_list_reset(&htl);
933 if (!(mode & SILC_CHANNEL_UMODE_CHANFO))
936 /* Founder not found of the channel. Since the founder auth mode
937 is set on the channel now check whether this is the client that
938 originally set the mode. */
940 if (channel->founder_key) {
941 /* Get public key that must be present in notify */
942 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
943 if (!tmp || !silc_pkcs_public_key_payload_decode(tmp, tmp_len,
945 chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
946 silc_server_force_cumode_change(server, sock, channel, chl, mode);
951 /* Now match the public key we have cached and public key sent.
953 #if 0 /* The key may be other than the client's in 1.2 */
954 if (client && client->data.public_key &&
955 !silc_pkcs_public_key_compare(channel->founder_key,
956 client->data.public_key)) {
957 chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
958 silc_server_force_cumode_change(server, sock, channel, chl, mode);
963 if (!silc_pkcs_public_key_compare(channel->founder_key,
965 chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
966 silc_server_force_cumode_change(server, sock, channel, chl, mode);
972 /* There cannot be anyone else as founder on the channel now. This
973 client is definitely the founder due to this authentication */
974 silc_hash_table_list(channel->user_list, &htl);
975 while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
976 if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
977 chl2->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
978 silc_server_force_cumode_change(server, NULL, channel, chl2,
982 silc_hash_table_list_reset(&htl);
985 silc_pkcs_public_key_free(founder_key);
988 if (server->server_type != SILC_SERVER && chl->mode == mode) {
989 SILC_LOG_DEBUG(("Mode is changed already"));
993 SILC_LOG_DEBUG(("Changing %s channel user mode",
994 chl->client->nickname ? chl->client->nickname :
995 (unsigned char *)""));
997 /* Change the mode */
1000 /* Send the same notify to the channel */
1002 silc_server_packet_send_to_channel(server, NULL, channel,
1004 FALSE, packet->buffer->data,
1005 packet->buffer->len, FALSE);
1007 silc_free(channel_id);
1011 case SILC_NOTIFY_TYPE_INVITE:
1013 if (packet->dst_id_type == SILC_ID_CLIENT)
1016 SILC_LOG_DEBUG(("INVITE notify"));
1018 /* Get Channel ID */
1019 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1022 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1026 /* Get channel entry */
1027 channel = silc_idlist_find_channel_by_id(server->global_list,
1030 channel = silc_idlist_find_channel_by_id(server->local_list,
1033 SILC_LOG_DEBUG(("Notify for unknown channel"));
1034 silc_free(channel_id);
1038 silc_free(channel_id);
1041 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1044 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1048 /* Get client entry */
1049 client = silc_idlist_find_client_by_id(server->global_list,
1050 client_id, TRUE, &cache);
1052 client = silc_idlist_find_client_by_id(server->local_list,
1053 client_id, TRUE, &cache);
1055 silc_free(client_id);
1059 silc_free(client_id);
1061 /* Get user's channel entry and check that inviting is allowed. */
1062 if (!silc_server_client_on_channel(client, channel, &chl))
1064 if (channel->mode & SILC_CHANNEL_MODE_INVITE &&
1065 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
1066 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1067 SILC_LOG_DEBUG(("Inviting is not allowed"));
1071 /* Get the invite action */
1072 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
1073 if (tmp && tmp_len == 1) {
1074 SilcUInt8 action = (SilcUInt8)tmp[0];
1075 SilcUInt16 iargc = 0;
1076 SilcArgumentPayload iargs;
1078 /* Get invite list */
1079 tmp = silc_argument_get_arg_type(args, 5, &tmp_len);
1080 if (!tmp || tmp_len < 2)
1083 /* Parse the arguments to see they are constructed correctly */
1084 SILC_GET16_MSB(iargc, tmp);
1085 iargs = silc_argument_payload_parse(tmp + 2, tmp_len - 2, iargc);
1089 if (action == 0 && !channel->invite_list)
1090 channel->invite_list =
1091 silc_hash_table_alloc(0, silc_hash_ptr,
1093 silc_server_inviteban_destruct, channel, TRUE);
1095 /* Proces the invite action */
1096 silc_server_inviteban_process(server, channel->invite_list, action,
1098 silc_argument_payload_free(iargs);
1103 case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
1105 * Distribute to the local clients on the channel and change the
1109 SILC_LOG_DEBUG(("CHANNEL CHANGE"));
1111 if (sock->type != SILC_SOCKET_TYPE_ROUTER)
1114 /* Get the old Channel ID */
1115 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1118 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1122 /* Get the channel entry */
1123 channel = silc_idlist_find_channel_by_id(server->local_list,
1126 channel = silc_idlist_find_channel_by_id(server->global_list,
1129 SILC_LOG_DEBUG(("Notify for unknown channel"));
1130 silc_free(channel_id);
1135 /* Send the notify to the channel */
1136 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
1137 FALSE, packet->buffer->data,
1138 packet->buffer->len, FALSE);
1140 /* Get the new Channel ID */
1141 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1144 channel_id2 = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1148 SILC_LOG_DEBUG(("Old Channel ID id(%s)",
1149 silc_id_render(channel_id, SILC_ID_CHANNEL)));
1150 SILC_LOG_DEBUG(("New Channel ID id(%s)",
1151 silc_id_render(channel_id2, SILC_ID_CHANNEL)));
1153 /* Replace the Channel ID */
1154 if (!silc_idlist_replace_channel_id(server->local_list, channel_id,
1156 if (!silc_idlist_replace_channel_id(server->global_list, channel_id,
1158 silc_free(channel_id2);
1163 SilcBuffer modes = NULL, users = NULL, users_modes = NULL;
1165 /* Re-announce this channel which ID was changed. */
1166 silc_server_send_new_channel(server, sock, FALSE, channel->channel_name,
1168 silc_id_get_len(channel->id,
1172 /* Re-announce our clients on the channel as the ID has changed now */
1173 silc_server_announce_get_channel_users(server, channel, &modes, &users,
1176 silc_buffer_push(users, users->data - users->head);
1177 silc_server_packet_send(server, sock,
1178 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1179 users->data, users->len, FALSE);
1180 silc_buffer_free(users);
1183 silc_buffer_push(modes, modes->data - modes->head);
1184 silc_server_packet_send_dest(server, sock,
1185 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1186 channel->id, SILC_ID_CHANNEL,
1187 modes->data, modes->len, FALSE);
1188 silc_buffer_free(modes);
1191 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
1192 silc_server_packet_send_dest(server, sock,
1193 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1194 channel->id, SILC_ID_CHANNEL,
1196 users_modes->len, FALSE);
1197 silc_buffer_free(users_modes);
1200 /* Re-announce channel's topic */
1201 if (channel->topic) {
1202 silc_server_send_notify_topic_set(server, sock,
1203 server->server_type == SILC_ROUTER ?
1204 TRUE : FALSE, channel,
1205 server->id, SILC_ID_SERVER,
1210 silc_free(channel_id);
1214 case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
1216 * Remove the server entry and all clients that this server owns.
1219 SILC_LOG_DEBUG(("SERVER SIGNOFF notify"));
1222 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1225 server_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1229 /* If the ID is mine, this notify is not allowed. */
1230 if (SILC_ID_SERVER_COMPARE(server_id, server->id)) {
1231 SILC_LOG_DEBUG(("Ignoring my own ID for SERVER_SIGNOFF"));
1235 /* Get server entry */
1236 server_entry = silc_idlist_find_server_by_id(server->global_list,
1237 server_id, TRUE, NULL);
1239 if (!server_entry) {
1240 server_entry = silc_idlist_find_server_by_id(server->local_list,
1241 server_id, TRUE, NULL);
1243 if (!server_entry) {
1244 /* If we are normal server then we might not have the server. Check
1245 whether router was kind enough to send the list of all clients
1246 that actually was to be removed. Remove them if the list is
1248 if (server->server_type != SILC_ROUTER &&
1249 silc_argument_get_arg_num(args) > 1) {
1252 for (i = 1; i < silc_argument_get_arg_num(args); i++) {
1254 tmp = silc_argument_get_arg_type(args, i + 1, &tmp_len);
1257 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1261 /* Get client entry */
1262 client = silc_idlist_find_client_by_id(server->global_list,
1263 client_id, TRUE, &cache);
1266 client = silc_idlist_find_client_by_id(server->local_list,
1267 client_id, TRUE, &cache);
1270 silc_free(client_id);
1274 silc_free(client_id);
1276 /* Update statistics */
1277 server->stat.clients--;
1278 if (server->stat.cell_clients)
1279 server->stat.cell_clients--;
1280 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
1281 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
1283 /* Remove the client from all channels. */
1284 silc_server_remove_from_channels(server, NULL, client,
1285 TRUE, NULL, FALSE, FALSE);
1287 /* Check if anyone is watching this nickname */
1288 if (server->server_type == SILC_ROUTER)
1289 silc_server_check_watcher_list(server, client, NULL,
1290 SILC_NOTIFY_TYPE_SERVER_SIGNOFF);
1292 /* Remove this client from watcher list if it is */
1294 silc_server_del_from_watcher_list(server, client);
1296 /* Remove the client */
1297 silc_idlist_del_data(client);
1298 silc_idlist_del_client(local ? server->local_list :
1299 server->global_list, client);
1303 silc_free(server_id);
1307 silc_free(server_id);
1309 /* For local entrys SERVER_SIGNOFF is processed only on backup router.
1310 It is possible that router sends server signoff for a server. If
1311 backup router has it as local connection it will be closed. */
1312 if (SILC_IS_LOCAL(server_entry)) {
1313 if (server->server_type == SILC_BACKUP_ROUTER) {
1314 sock = server_entry->connection;
1315 SILC_LOG_DEBUG(("Closing connection %s after SERVER_SIGNOFF",
1317 SILC_SET_DISCONNECTING(sock);
1318 if (sock->user_data)
1319 silc_server_free_sock_user_data(server, sock, NULL);
1320 silc_server_close_connection(server, sock);
1326 /* Remove all servers that are originated from this server, and
1327 remove the clients of those servers too. */
1328 silc_server_remove_servers_by_server(server, server_entry, TRUE);
1330 /* Remove the clients that this server owns as they will become
1332 silc_server_remove_clients_by_server(server, server_entry->router,
1333 server_entry, TRUE);
1334 silc_server_backup_del(server, server_entry);
1336 /* Remove the server entry */
1337 silc_idlist_del_server(local ? server->local_list :
1338 server->global_list, server_entry);
1340 /* Update statistics */
1341 if (server->server_type == SILC_ROUTER)
1342 server->stat.servers--;
1346 case SILC_NOTIFY_TYPE_KICKED:
1348 * Distribute the notify to local clients on the channel
1351 SILC_LOG_DEBUG(("KICKED notify"));
1354 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
1355 packet->dst_id_type);
1360 /* Get channel entry */
1361 channel = silc_idlist_find_channel_by_id(server->global_list,
1364 channel = silc_idlist_find_channel_by_id(server->local_list,
1367 SILC_LOG_DEBUG(("Notify for unknown channel"));
1368 silc_free(channel_id);
1372 silc_free(channel_id);
1375 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1378 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1382 /* If the the client is not in local list we check global list */
1383 client = silc_idlist_find_client_by_id(server->global_list,
1384 client_id, TRUE, NULL);
1386 client = silc_idlist_find_client_by_id(server->local_list,
1387 client_id, TRUE, NULL);
1389 silc_free(client_id);
1393 silc_free(client_id);
1395 /* If target is founder they cannot be kicked */
1396 if (!silc_server_client_on_channel(client, channel, &chl))
1398 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO)
1401 /* Get the kicker's Client ID */
1402 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1405 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1409 /* If the the client is not in local list we check global list */
1410 client2 = silc_idlist_find_client_by_id(server->global_list,
1411 client_id, TRUE, NULL);
1413 client2 = silc_idlist_find_client_by_id(server->local_list,
1414 client_id, TRUE, NULL);
1416 silc_free(client_id);
1420 silc_free(client_id);
1422 /* Kicker must be operator on channel */
1423 if (!silc_server_client_on_channel(client2, channel, &chl))
1425 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
1426 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1427 SILC_LOG_DEBUG(("Kicking is not allowed"));
1431 /* Send to channel */
1432 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
1433 FALSE, packet->buffer->data,
1434 packet->buffer->len, FALSE);
1436 /* Remove the client from channel's invite list */
1437 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
1439 SilcArgumentPayload iargs;
1440 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1441 ab = silc_argument_payload_encode_one(NULL, tmp, tmp_len, 3);
1442 iargs = silc_argument_payload_parse(ab->data, ab->len, 1);
1443 silc_server_inviteban_process(server, channel->invite_list, 1, iargs);
1444 silc_buffer_free(ab);
1445 silc_argument_payload_free(iargs);
1448 /* Remove the client from channel */
1449 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
1453 case SILC_NOTIFY_TYPE_KILLED:
1456 * Distribute the notify to local clients on channels
1458 unsigned char *id, *comment;
1459 SilcUInt32 id_len, comment_len;
1461 SILC_LOG_DEBUG(("KILLED notify"));
1464 id = silc_argument_get_arg_type(args, 1, &id_len);
1467 client_id = silc_id_payload_parse_id(id, id_len, NULL);
1471 /* If the the client is not in local list we check global list */
1472 client = silc_idlist_find_client_by_id(server->global_list,
1473 client_id, TRUE, &cache);
1475 client = silc_idlist_find_client_by_id(server->local_list,
1476 client_id, TRUE, &cache);
1478 silc_free(client_id);
1482 silc_free(client_id);
1484 /* If the client is one of ours, then close the connection to the
1485 client now. This removes the client from all channels as well. */
1486 if (packet->dst_id_type == SILC_ID_CLIENT && client->connection) {
1487 sock = client->connection;
1488 silc_server_free_client_data(server, NULL, client, FALSE, NULL);
1489 silc_server_close_connection(server, sock);
1494 comment = silc_argument_get_arg_type(args, 2, &comment_len);
1495 if (comment_len > 128)
1498 /* Get the killer's Client ID */
1499 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1502 client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
1506 if (id_type == SILC_ID_CLIENT) {
1507 /* If the the client is not in local list we check global list */
1508 client2 = silc_idlist_find_client_by_id(server->global_list,
1509 client_id, TRUE, NULL);
1511 client2 = silc_idlist_find_client_by_id(server->local_list,
1512 client_id, TRUE, NULL);
1514 silc_free(client_id);
1518 silc_free(client_id);
1520 /* Killer must be router operator */
1521 if (server->server_type != SILC_SERVER &&
1522 !(client2->mode & SILC_UMODE_ROUTER_OPERATOR)) {
1523 SILC_LOG_DEBUG(("Killing is not allowed"));
1528 /* Send the notify to local clients on the channels except to the
1529 client who is killed. */
1530 silc_server_send_notify_on_channels(server, client, client,
1531 SILC_NOTIFY_TYPE_KILLED, 3,
1532 id, id_len, comment, comment_len,
1535 /* Remove the client from all channels */
1536 silc_server_remove_from_channels(server, NULL, client, FALSE, NULL,
1539 /* Check if anyone is watching this nickname */
1540 silc_server_check_watcher_list(server, client, NULL,
1541 SILC_NOTIFY_TYPE_KILLED);
1543 /* Update statistics */
1544 server->stat.clients--;
1545 if (server->stat.cell_clients)
1546 server->stat.cell_clients--;
1547 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
1548 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
1550 if (SILC_IS_LOCAL(client)) {
1551 server->stat.my_clients--;
1552 silc_schedule_task_del_by_context(server->schedule, client);
1553 silc_idlist_del_data(client);
1557 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
1558 cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
1562 case SILC_NOTIFY_TYPE_UMODE_CHANGE:
1564 * Save the mode of the client.
1567 SILC_LOG_DEBUG(("UMODE_CHANGE notify"));
1570 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1573 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1577 /* Get client entry */
1578 client = silc_idlist_find_client_by_id(server->global_list,
1579 client_id, TRUE, NULL);
1581 client = silc_idlist_find_client_by_id(server->local_list,
1582 client_id, TRUE, NULL);
1584 silc_free(client_id);
1588 silc_free(client_id);
1591 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1594 SILC_GET32_MSB(mode, tmp);
1596 /* Remove internal resumed flag if client is marked detached now */
1597 if (mode & SILC_UMODE_DETACHED)
1598 client->data.status &= ~SILC_IDLIST_STATUS_RESUMED;
1600 /* Update statistics */
1601 if (server->server_type == SILC_ROUTER) {
1602 if (mode & SILC_UMODE_GONE) {
1603 if (!(client->mode & SILC_UMODE_GONE))
1604 server->stat.aways++;
1606 if (client->mode & SILC_UMODE_GONE)
1607 server->stat.aways--;
1609 if (mode & SILC_UMODE_DETACHED) {
1610 if (!(client->mode & SILC_UMODE_DETACHED))
1611 server->stat.detached++;
1613 if (client->mode & SILC_UMODE_DETACHED)
1614 server->stat.detached--;
1617 SILC_UMODE_STATS_UPDATE(server, SILC_UMODE_SERVER_OPERATOR);
1618 SILC_UMODE_STATS_UPDATE(router, SILC_UMODE_ROUTER_OPERATOR);
1620 /* Change the mode */
1621 client->mode = mode;
1623 /* Check if anyone is watching this nickname */
1624 if (server->server_type == SILC_ROUTER)
1625 silc_server_check_watcher_list(server, client, NULL,
1626 SILC_NOTIFY_TYPE_UMODE_CHANGE);
1630 case SILC_NOTIFY_TYPE_BAN:
1635 SILC_LOG_DEBUG(("BAN notify"));
1637 /* Get Channel ID */
1638 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1641 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1645 /* Get channel entry */
1646 channel = silc_idlist_find_channel_by_id(server->global_list,
1649 channel = silc_idlist_find_channel_by_id(server->local_list,
1652 SILC_LOG_DEBUG(("Notify for unknown channel"));
1653 silc_free(channel_id);
1657 silc_free(channel_id);
1659 /* Get the ban action */
1660 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1661 if (tmp && tmp_len == 1) {
1662 SilcUInt8 action = (SilcUInt8)tmp[0];
1663 SilcUInt16 iargc = 0;
1664 SilcArgumentPayload iargs;
1667 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1668 if (!tmp || tmp_len < 2)
1671 /* Parse the arguments to see they are constructed correctly */
1672 SILC_GET16_MSB(iargc, tmp);
1673 iargs = silc_argument_payload_parse(tmp + 2, tmp_len - 2, iargc);
1677 if (action == 0 && !channel->ban_list)
1679 silc_hash_table_alloc(0, silc_hash_ptr,
1681 silc_server_inviteban_destruct, channel, TRUE);
1683 /* Proces the ban action */
1684 silc_server_inviteban_process(server, channel->ban_list, action,
1686 silc_argument_payload_free(iargs);
1690 case SILC_NOTIFY_TYPE_ERROR:
1697 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1698 if (!tmp && tmp_len != 1)
1700 error = (SilcStatus)tmp[0];
1702 SILC_LOG_DEBUG(("ERROR notify (%d)", error));
1704 if (error == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID &&
1705 sock->type == SILC_SOCKET_TYPE_ROUTER) {
1706 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1708 SILC_LOG_DEBUG(("Received invalid client ID notification, deleting "
1709 "the entry from cache"));
1710 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1713 client = silc_idlist_find_client_by_id(server->global_list,
1714 client_id, FALSE, NULL);
1716 silc_server_remove_from_channels(server, NULL, client, TRUE,
1718 silc_idlist_del_data(client);
1719 silc_idlist_del_client(server->global_list, client);
1721 silc_free(client_id);
1727 /* Ignore rest of the notify types for now */
1728 case SILC_NOTIFY_TYPE_NONE:
1729 case SILC_NOTIFY_TYPE_MOTD:
1736 silc_notify_payload_free(payload);
1739 void silc_server_notify_list(SilcServer server,
1740 SilcSocketConnection sock,
1741 SilcPacketContext *packet)
1743 SilcPacketContext *new;
1747 SILC_LOG_DEBUG(("Processing Notify List"));
1749 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1750 packet->src_id_type != SILC_ID_SERVER)
1753 /* Make copy of the original packet context, except for the actual
1754 data buffer, which we will here now fetch from the original buffer. */
1755 new = silc_packet_context_alloc();
1756 new->type = SILC_PACKET_NOTIFY;
1757 new->flags = packet->flags;
1758 new->src_id = packet->src_id;
1759 new->src_id_len = packet->src_id_len;
1760 new->src_id_type = packet->src_id_type;
1761 new->dst_id = packet->dst_id;
1762 new->dst_id_len = packet->dst_id_len;
1763 new->dst_id_type = packet->dst_id_type;
1765 buffer = silc_buffer_alloc(1024);
1766 new->buffer = buffer;
1768 while (packet->buffer->len) {
1769 SILC_GET16_MSB(len, packet->buffer->data + 2);
1770 if (len > packet->buffer->len)
1773 if (len > buffer->truelen) {
1774 silc_buffer_free(buffer);
1775 buffer = silc_buffer_alloc(1024 + len);
1778 silc_buffer_pull_tail(buffer, len);
1779 silc_buffer_put(buffer, packet->buffer->data, len);
1781 /* Process the Notify */
1782 silc_server_notify(server, sock, new);
1784 silc_buffer_push_tail(buffer, len);
1785 silc_buffer_pull(packet->buffer, len);
1788 silc_buffer_free(buffer);
1792 /* Received private message. This resolves the destination of the message
1793 and sends the packet. This is used by both server and router. If the
1794 destination is our locally connected client this sends the packet to
1795 the client. This may also send the message for further routing if
1796 the destination is not in our server (or router). */
1798 void silc_server_private_message(SilcServer server,
1799 SilcSocketConnection sock,
1800 SilcPacketContext *packet)
1802 SilcSocketConnection dst_sock;
1803 SilcIDListData idata;
1804 SilcClientEntry client;
1806 SILC_LOG_DEBUG(("Start"));
1808 if (packet->src_id_type != SILC_ID_CLIENT ||
1809 packet->dst_id_type != SILC_ID_CLIENT || !packet->dst_id)
1812 /* Get the route to the client */
1813 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1814 packet->dst_id_len, NULL,
1818 unsigned char error;
1820 if (client && client->mode & SILC_UMODE_DETACHED) {
1821 SILC_LOG_DEBUG(("Client is detached, discarding packet"));
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_CLIENT_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,
1842 idp->data, idp->len);
1843 silc_free(client_id);
1845 silc_server_send_notify(server, sock, FALSE,
1846 SILC_NOTIFY_TYPE_ERROR, 2,
1848 idp->data, idp->len);
1851 silc_buffer_free(idp);
1855 /* Check whether destination client wishes to receive private messages */
1856 if (client && !(packet->flags & SILC_PACKET_FLAG_PRIVMSG_KEY) &&
1857 client->mode & SILC_UMODE_BLOCK_PRIVMSG) {
1858 SILC_LOG_DEBUG(("Client blocks private messages, discarding packet"));
1862 /* Send the private message */
1863 silc_server_send_private_message(server, dst_sock, idata->send_key,
1864 idata->hmac_send, idata->psn_send++,
1868 /* Received private message key packet.. This packet is never for us. It is to
1869 the client in the packet's destination ID. Sending of this sort of packet
1870 equals sending private message, ie. it is sent point to point from
1871 one client to another. */
1873 void silc_server_private_message_key(SilcServer server,
1874 SilcSocketConnection sock,
1875 SilcPacketContext *packet)
1877 SilcSocketConnection dst_sock;
1878 SilcIDListData idata;
1880 SILC_LOG_DEBUG(("Start"));
1882 if (packet->src_id_type != SILC_ID_CLIENT ||
1883 packet->dst_id_type != SILC_ID_CLIENT)
1886 if (!packet->dst_id)
1889 /* Get the route to the client */
1890 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1891 packet->dst_id_len, NULL,
1896 /* Relay the packet */
1897 silc_server_relay_packet(server, dst_sock, idata->send_key,
1898 idata->hmac_send, idata->psn_send++, packet, FALSE);
1901 /* Processes incoming command reply packet. The command reply packet may
1902 be destined to one of our clients or it may directly for us. We will
1903 call the command reply routine after processing the packet. */
1905 void silc_server_command_reply(SilcServer server,
1906 SilcSocketConnection sock,
1907 SilcPacketContext *packet)
1909 SilcBuffer buffer = packet->buffer;
1910 SilcClientEntry client = NULL;
1911 SilcSocketConnection dst_sock;
1912 SilcIDListData idata;
1913 SilcClientID *id = NULL;
1915 SILC_LOG_DEBUG(("Start"));
1917 if (packet->dst_id_type == SILC_ID_CHANNEL)
1920 if (packet->dst_id_type == SILC_ID_CLIENT) {
1921 /* Destination must be one of ours */
1922 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
1925 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
1927 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
1933 if (packet->dst_id_type == SILC_ID_SERVER) {
1934 /* For now this must be for us */
1935 if (memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
1936 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
1941 /* Execute command reply locally for the command */
1942 silc_server_command_reply_process(server, sock, buffer);
1944 if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
1945 /* Relay the packet to the client */
1946 const SilcBufferStruct p;
1948 dst_sock = (SilcSocketConnection)client->connection;
1949 idata = (SilcIDListData)client;
1951 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
1952 + packet->dst_id_len + packet->padlen);
1953 if (!silc_packet_send_prepare(dst_sock, 0, 0, buffer->len,
1954 idata->hmac_send, (const SilcBuffer)&p)) {
1955 SILC_LOG_ERROR(("Cannot send packet"));
1958 silc_buffer_put((SilcBuffer)&p, buffer->data, buffer->len);
1960 /* Encrypt packet */
1961 silc_packet_encrypt(idata->send_key, idata->hmac_send, idata->psn_send++,
1962 (SilcBuffer)&p, buffer->len);
1964 /* Send the packet */
1965 silc_server_packet_send_real(server, dst_sock, TRUE);
1971 /* Process received channel message. The message can be originated from
1972 client or server. */
1974 void silc_server_channel_message(SilcServer server,
1975 SilcSocketConnection sock,
1976 SilcPacketContext *packet)
1978 SilcChannelEntry channel = NULL;
1979 SilcChannelID *id = NULL;
1980 void *sender_id = NULL;
1981 SilcClientEntry sender_entry = NULL;
1982 SilcChannelClientEntry chl;
1985 SILC_LOG_DEBUG(("Processing channel message"));
1988 if (packet->dst_id_type != SILC_ID_CHANNEL) {
1989 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1993 /* Find channel entry */
1994 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
1997 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
1999 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
2002 unsigned char error;
2004 /* Send SILC_NOTIFY_TYPE_ERROR to indicate that such destination ID
2005 does not exist or is invalid. */
2006 idp = silc_id_payload_encode_data(packet->dst_id,
2008 packet->dst_id_type);
2012 error = SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID;
2013 if (packet->src_id_type == SILC_ID_CLIENT) {
2014 SilcClientID *client_id = silc_id_str2id(packet->src_id,
2016 packet->src_id_type);
2017 silc_server_send_notify_dest(server, sock, FALSE,
2018 client_id, SILC_ID_CLIENT,
2019 SILC_NOTIFY_TYPE_ERROR, 2,
2020 &error, 1, idp->data, idp->len);
2021 silc_free(client_id);
2023 silc_server_send_notify(server, sock, FALSE,
2024 SILC_NOTIFY_TYPE_ERROR, 2,
2025 &error, 1, idp->data, idp->len);
2028 silc_buffer_free(idp);
2033 /* See that this client is on the channel. If the original sender is
2034 not client (as it can be server as well) we don't do the check. */
2035 sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2036 packet->src_id_type);
2039 if (packet->src_id_type == SILC_ID_CLIENT) {
2040 sender_entry = silc_idlist_find_client_by_id(server->local_list,
2041 sender_id, TRUE, NULL);
2042 if (!sender_entry) {
2044 sender_entry = silc_idlist_find_client_by_id(server->global_list,
2045 sender_id, TRUE, NULL);
2047 if (!sender_entry || !silc_server_client_on_channel(sender_entry,
2049 SILC_LOG_DEBUG(("Client not on channel"));
2053 /* If channel is moderated check that client is allowed to send
2055 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS &&
2056 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
2057 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
2058 SILC_LOG_DEBUG(("Channel is silenced from normal users"));
2061 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS &&
2062 chl->mode & SILC_CHANNEL_UMODE_CHANOP &&
2063 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
2064 SILC_LOG_DEBUG(("Channel is silenced from operators"));
2067 if (chl->mode & SILC_CHANNEL_UMODE_QUIET) {
2068 SILC_LOG_DEBUG(("Sender is quieted on the channel"));
2072 /* If the packet is coming from router, but the client entry is local
2073 entry to us then some router is rerouting this to us and it is not
2074 allowed. When the client is local to us it means that we've routed
2075 this packet to network, and now someone is routing it back to us. */
2076 if (server->server_type == SILC_ROUTER &&
2077 sock->type == SILC_SOCKET_TYPE_ROUTER && local) {
2078 SILC_LOG_DEBUG(("Channel message rerouted to the sender, drop it"));
2083 /* Distribute the packet to our local clients. This will send the
2084 packet for further routing as well, if needed. */
2085 silc_server_packet_relay_to_channel(server, sock, channel, sender_id,
2086 packet->src_id_type, sender_entry,
2087 packet->buffer->data,
2088 packet->buffer->len, FALSE);
2091 silc_free(sender_id);
2095 /* Received channel key packet. We distribute the key to all of our locally
2096 connected clients on the channel. */
2098 void silc_server_channel_key(SilcServer server,
2099 SilcSocketConnection sock,
2100 SilcPacketContext *packet)
2102 SilcBuffer buffer = packet->buffer;
2103 SilcChannelEntry channel;
2105 if (packet->src_id_type != SILC_ID_SERVER ||
2106 (server->server_type == SILC_ROUTER && !server->backup_router &&
2107 sock->type == SILC_SOCKET_TYPE_ROUTER))
2110 /* Save the channel key */
2111 channel = silc_server_save_channel_key(server, buffer, NULL);
2113 SILC_LOG_ERROR(("Bad channel key from %s (%s)",
2114 sock->hostname, sock->ip));
2118 /* Distribute the key to everybody who is on the channel. If we are router
2119 we will also send it to locally connected servers. */
2120 silc_server_send_channel_key(server, sock, channel, FALSE);
2122 if (server->server_type != SILC_BACKUP_ROUTER) {
2123 /* Distribute to local cell backup routers. */
2124 silc_server_backup_send(server, sock->user_data,
2125 SILC_PACKET_CHANNEL_KEY, 0,
2126 buffer->data, buffer->len, FALSE, TRUE);
2130 /* Received New Client packet and processes it. Creates Client ID for the
2131 client. Client becomes registered after calling this functions. */
2133 SilcClientEntry silc_server_new_client(SilcServer server,
2134 SilcSocketConnection sock,
2135 SilcPacketContext *packet)
2137 SilcBuffer buffer = packet->buffer;
2138 SilcClientEntry client;
2139 SilcClientID *client_id;
2140 SilcIDListData idata;
2141 char *username = NULL, *realname = NULL;
2142 SilcUInt16 username_len;
2145 char *hostname, *nickname;
2148 SILC_LOG_DEBUG(("Creating new client"));
2150 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
2153 /* Take client entry */
2154 client = (SilcClientEntry)sock->user_data;
2155 idata = (SilcIDListData)client;
2157 /* Remove the old cache entry. */
2158 if (!silc_idcache_del_by_context(server->local_list->clients, client)) {
2159 SILC_LOG_INFO(("Unauthenticated client attempted to register to network"));
2160 silc_server_disconnect_remote(server, sock,
2161 SILC_STATUS_ERR_NOT_AUTHENTICATED, NULL);
2162 if (sock->user_data)
2163 silc_server_free_sock_user_data(server, sock, NULL);
2167 /* Parse incoming packet */
2168 ret = silc_buffer_unformat(buffer,
2169 SILC_STR_UI16_NSTRING_ALLOC(&username,
2171 SILC_STR_UI16_STRING_ALLOC(&realname),
2174 silc_free(username);
2175 silc_free(realname);
2176 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2177 "connection", sock->hostname, sock->ip));
2178 silc_server_disconnect_remote(server, sock,
2179 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2181 if (sock->user_data)
2182 silc_server_free_sock_user_data(server, sock, NULL);
2187 silc_free(username);
2188 silc_free(realname);
2189 SILC_LOG_ERROR(("Client %s (%s) did not send its username, closing "
2190 "connection", sock->hostname, sock->ip));
2191 silc_server_disconnect_remote(server, sock,
2192 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2194 if (sock->user_data)
2195 silc_server_free_sock_user_data(server, sock, NULL);
2199 if (username_len > 128)
2200 username[128] = '\0';
2202 /* Check for bad characters for nickname, and modify the nickname if
2203 it includes those. */
2204 if (silc_server_name_bad_chars(username, username_len)) {
2205 nickname = silc_server_name_modify_bad(username, username_len);
2207 nickname = strdup(username);
2210 /* Make sanity checks for the hostname of the client. If the hostname
2211 is provided in the `username' check that it is the same than the
2212 resolved hostname, or if not resolved the hostname that appears in
2213 the client's public key. If the hostname is not present then put
2214 it from the resolved name or from the public key. */
2215 if (strchr(username, '@')) {
2216 SilcPublicKeyIdentifier pident;
2217 int tlen = strcspn(username, "@");
2218 char *phostname = NULL;
2220 hostname = silc_memdup(username + tlen + 1, strlen(username) - tlen - 1);
2222 if (strcmp(sock->hostname, sock->ip) &&
2223 strcmp(sock->hostname, hostname)) {
2224 silc_free(username);
2225 silc_free(hostname);
2226 silc_free(realname);
2227 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2228 "connection", sock->hostname, sock->ip));
2229 silc_server_disconnect_remote(server, sock,
2230 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2232 if (sock->user_data)
2233 silc_server_free_sock_user_data(server, sock, NULL);
2237 pident = silc_pkcs_decode_identifier(client->data.public_key->identifier);
2239 phostname = strdup(pident->host);
2240 silc_pkcs_free_identifier(pident);
2243 if (!strcmp(sock->hostname, sock->ip) &&
2244 phostname && strcmp(phostname, hostname)) {
2245 silc_free(username);
2246 silc_free(hostname);
2247 silc_free(phostname);
2248 silc_free(realname);
2249 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2250 "connection", sock->hostname, sock->ip));
2251 silc_server_disconnect_remote(server, sock,
2252 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2254 if (sock->user_data)
2255 silc_server_free_sock_user_data(server, sock, NULL);
2259 silc_free(phostname);
2261 /* The hostname is not present, add it. */
2263 /* XXX For now we cannot take the host name from the public key since
2264 they are not trusted or we cannot verify them as trusted. Just take
2265 what the resolved name or address is. */
2267 if (strcmp(sock->hostname, sock->ip)) {
2269 newusername = silc_calloc(strlen(username) +
2270 strlen(sock->hostname) + 2,
2271 sizeof(*newusername));
2272 strncat(newusername, username, strlen(username));
2273 strncat(newusername, "@", 1);
2274 strncat(newusername, sock->hostname, strlen(sock->hostname));
2275 silc_free(username);
2276 username = newusername;
2279 SilcPublicKeyIdentifier pident =
2280 silc_pkcs_decode_identifier(client->data.public_key->identifier);
2283 newusername = silc_calloc(strlen(username) +
2284 strlen(pident->host) + 2,
2285 sizeof(*newusername));
2286 strncat(newusername, username, strlen(username));
2287 strncat(newusername, "@", 1);
2288 strncat(newusername, pident->host, strlen(pident->host));
2289 silc_free(username);
2290 username = newusername;
2291 silc_pkcs_free_identifier(pident);
2297 /* Create Client ID */
2298 while (!silc_id_create_client_id(server, server->id, server->rng,
2299 server->md5hash, nickname, &client_id)) {
2302 silc_server_disconnect_remote(server, sock,
2303 SILC_STATUS_ERR_BAD_NICKNAME, NULL);
2304 if (sock->user_data)
2305 silc_server_free_sock_user_data(server, sock, NULL);
2308 snprintf(&nickname[strlen(nickname) - 1], 1, "%d", nickfail);
2311 /* If client marked as anonymous, scramble the username and hostname */
2312 if (client->mode & SILC_UMODE_ANONYMOUS) {
2315 if (strlen(username) >= 2) {
2316 username[0] = silc_rng_get_byte_fast(server->rng);
2317 username[1] = silc_rng_get_byte_fast(server->rng);
2320 scramble = silc_hash_babbleprint(server->sha1hash, username,
2324 memcpy(&scramble[16], ".silc", 5);
2325 scramble[21] = '\0';
2326 silc_free(username);
2327 username = scramble;
2330 /* Update client entry */
2331 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
2332 client->nickname = nickname;
2333 client->username = username;
2334 client->userinfo = realname ? realname : strdup(username);
2335 client->id = client_id;
2336 id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
2338 /* Add the client again to the ID cache */
2339 silc_idcache_add(server->local_list->clients, client->nickname,
2340 client_id, client, 0, NULL);
2342 /* Notify our router about new client on the SILC network */
2343 silc_server_send_new_id(server, SILC_PRIMARY_ROUTE(server),
2344 SILC_BROADCAST(server), client->id,
2345 SILC_ID_CLIENT, id_len);
2347 /* Distribute to backup routers */
2348 if (server->server_type == SILC_ROUTER) {
2349 SilcBuffer idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
2350 silc_server_backup_send(server, sock->user_data, SILC_PACKET_NEW_ID, 0,
2351 idp->data, idp->len, FALSE, TRUE);
2352 silc_buffer_free(idp);
2355 /* Send the new client ID to the client. */
2356 silc_server_send_new_id(server, sock, FALSE, client->id, SILC_ID_CLIENT,
2357 silc_id_get_len(client->id, SILC_ID_CLIENT));
2359 /* Send some nice info to the client */
2360 silc_server_send_connect_notifys(server, sock, client);
2362 /* Check if anyone is watching this nickname */
2363 if (server->server_type == SILC_ROUTER)
2364 silc_server_check_watcher_list(server, client, NULL, 0);
2369 /* Create new server. This processes received New Server packet and
2370 saves the received Server ID. The server is our locally connected
2371 server thus we save all the information and save it to local list.
2372 This funtion can be used by both normal server and router server.
2373 If normal server uses this it means that its router has connected
2374 to the server. If router uses this it means that one of the cell's
2375 servers is connected to the router. */
2377 SilcServerEntry silc_server_new_server(SilcServer server,
2378 SilcSocketConnection sock,
2379 SilcPacketContext *packet)
2381 SilcBuffer buffer = packet->buffer;
2382 SilcServerEntry new_server, server_entry;
2383 SilcServerID *server_id;
2384 SilcIDListData idata;
2385 unsigned char *server_name, *id_string;
2386 SilcUInt16 id_len, name_len;
2390 SILC_LOG_DEBUG(("Creating new server"));
2392 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
2393 sock->type != SILC_SOCKET_TYPE_ROUTER)
2396 /* Take server entry */
2397 new_server = (SilcServerEntry)sock->user_data;
2398 idata = (SilcIDListData)new_server;
2400 /* Remove the old cache entry */
2401 if (!silc_idcache_del_by_context(server->local_list->servers, new_server)) {
2402 if (!silc_idcache_del_by_context(server->global_list->servers,
2404 SILC_LOG_INFO(("Unauthenticated %s attempted to register to "
2405 "network", (sock->type == SILC_SOCKET_TYPE_SERVER ?
2406 "server" : "router")));
2407 silc_server_disconnect_remote(server, sock,
2408 SILC_STATUS_ERR_NOT_AUTHENTICATED, NULL);
2409 if (sock->user_data)
2410 silc_server_free_sock_user_data(server, sock, NULL);
2416 /* Parse the incoming packet */
2417 ret = silc_buffer_unformat(buffer,
2418 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
2419 SILC_STR_UI16_NSTRING_ALLOC(&server_name,
2423 silc_free(id_string);
2424 silc_free(server_name);
2425 silc_server_disconnect_remote(server, sock,
2426 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2428 if (sock->user_data)
2429 silc_server_free_sock_user_data(server, sock, NULL);
2433 if (id_len > buffer->len) {
2434 silc_free(id_string);
2435 silc_free(server_name);
2436 silc_server_disconnect_remote(server, sock,
2437 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2439 if (sock->user_data)
2440 silc_server_free_sock_user_data(server, sock, NULL);
2445 server_name[255] = '\0';
2448 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
2450 silc_free(id_string);
2451 silc_free(server_name);
2452 silc_server_disconnect_remote(server, sock,
2453 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2455 if (sock->user_data)
2456 silc_server_free_sock_user_data(server, sock, NULL);
2459 silc_free(id_string);
2461 /* Check for valid server ID */
2462 if (!silc_id_is_valid_server_id(server, server_id, sock)) {
2463 SILC_LOG_INFO(("Invalid server ID sent by %s (%s)",
2464 sock->ip, sock->hostname));
2465 silc_server_disconnect_remote(server, sock,
2466 SILC_STATUS_ERR_BAD_SERVER_ID, NULL);
2467 if (sock->user_data)
2468 silc_server_free_sock_user_data(server, sock, NULL);
2469 silc_free(server_name);
2473 /* Check that we do not have this ID already */
2474 server_entry = silc_idlist_find_server_by_id(server->local_list,
2475 server_id, TRUE, NULL);
2477 silc_idcache_del_by_context(server->local_list->servers, server_entry);
2479 server_entry = silc_idlist_find_server_by_id(server->global_list,
2480 server_id, TRUE, NULL);
2482 silc_idcache_del_by_context(server->global_list->servers, server_entry);
2485 /* Update server entry */
2486 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
2487 new_server->server_name = server_name;
2488 new_server->id = server_id;
2490 SILC_LOG_DEBUG(("New server id(%s)",
2491 silc_id_render(server_id, SILC_ID_SERVER)));
2493 /* Add again the entry to the ID cache. */
2494 silc_idcache_add(local ? server->local_list->servers :
2495 server->global_list->servers, server_name, server_id,
2496 new_server, 0, NULL);
2498 /* Distribute the information about new server in the SILC network
2499 to our router. If we are normal server we won't send anything
2500 since this connection must be our router connection. */
2501 if (server->server_type == SILC_ROUTER && !server->standalone &&
2502 SILC_PRIMARY_ROUTE(server) != sock)
2503 silc_server_send_new_id(server, SILC_PRIMARY_ROUTE(server),
2504 TRUE, new_server->id, SILC_ID_SERVER,
2505 silc_id_get_len(server_id, SILC_ID_SERVER));
2507 if (server->server_type == SILC_ROUTER) {
2508 /* Distribute to backup routers */
2509 SilcBuffer idp = silc_id_payload_encode(new_server->id, SILC_ID_SERVER);
2510 silc_server_backup_send(server, sock->user_data, SILC_PACKET_NEW_ID, 0,
2511 idp->data, idp->len, FALSE, TRUE);
2512 silc_buffer_free(idp);
2515 server->stat.cell_servers++;
2518 /* Check whether this router connection has been replaced by an
2519 backup router. If it has been then we'll disable the server and will
2520 ignore everything it will send until the backup router resuming
2521 protocol has been completed. */
2522 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
2523 silc_server_backup_replaced_get(server, server_id, NULL)) {
2524 /* Send packet to the server indicating that it cannot use this
2525 connection as it has been replaced by backup router. */
2526 SilcBuffer packet = silc_buffer_alloc(2);
2527 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
2528 silc_buffer_format(packet,
2529 SILC_STR_UI_CHAR(SILC_SERVER_BACKUP_REPLACED),
2530 SILC_STR_UI_CHAR(0),
2532 silc_server_packet_send(server, sock,
2533 SILC_PACKET_RESUME_ROUTER, 0,
2534 packet->data, packet->len, TRUE);
2535 silc_buffer_free(packet);
2537 /* Mark the router disabled. The data sent earlier will go but nothing
2538 after this does not go to this connection. */
2539 idata->status |= SILC_IDLIST_STATUS_DISABLED;
2541 /* If it is router announce our stuff to it. */
2542 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
2543 server->server_type == SILC_ROUTER) {
2544 silc_server_announce_servers(server, FALSE, 0, sock);
2545 silc_server_announce_clients(server, 0, sock);
2546 silc_server_announce_channels(server, 0, sock);
2549 /* Announce our information to backup router */
2550 if (new_server->server_type == SILC_BACKUP_ROUTER &&
2551 sock->type == SILC_SOCKET_TYPE_SERVER &&
2552 server->server_type == SILC_ROUTER) {
2553 silc_server_announce_servers(server, TRUE, 0, sock);
2554 silc_server_announce_clients(server, 0, sock);
2555 silc_server_announce_channels(server, 0, sock);
2558 /* If backup router, mark it as one of ours. This server is considered
2559 to be backup router after this setting. */
2560 if (new_server->server_type == SILC_BACKUP_ROUTER) {
2561 SilcServerConfigRouter *backup;
2562 backup = silc_server_config_find_backup_conn(server, sock->ip);
2564 backup = silc_server_config_find_backup_conn(server, sock->hostname);
2566 /* Add as our backup router */
2567 silc_server_backup_add(server, new_server, backup->backup_replace_ip,
2568 backup->backup_replace_port,
2569 backup->backup_local);
2573 /* By default the servers connected to backup router are disabled
2574 until backup router has become the primary */
2575 if (server->server_type == SILC_BACKUP_ROUTER &&
2576 sock->type == SILC_SOCKET_TYPE_SERVER)
2577 idata->status |= SILC_IDLIST_STATUS_DISABLED;
2583 /* Processes incoming New ID packet. New ID Payload is used to distribute
2584 information about newly registered clients and servers. */
2586 static void silc_server_new_id_real(SilcServer server,
2587 SilcSocketConnection sock,
2588 SilcPacketContext *packet,
2591 SilcBuffer buffer = packet->buffer;
2593 SilcServerEntry router, server_entry;
2594 SilcSocketConnection router_sock;
2599 SILC_LOG_DEBUG(("Processing new ID"));
2601 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2602 server->server_type == SILC_SERVER ||
2603 packet->src_id_type != SILC_ID_SERVER)
2606 idp = silc_id_payload_parse(buffer->data, buffer->len);
2610 id_type = silc_id_payload_get_type(idp);
2612 /* Normal server cannot have other normal server connections */
2613 server_entry = (SilcServerEntry)sock->user_data;
2614 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER &&
2615 server_entry->server_type == SILC_SERVER)
2618 id = silc_id_payload_get_id(idp);
2622 /* If the packet is coming from server then use the sender as the
2623 origin of the the packet. If it came from router then check the real
2624 sender of the packet and use that as the origin. */
2625 if (sock->type == SILC_SOCKET_TYPE_SERVER) {
2626 id_list = server->local_list;
2628 router = sock->user_data;
2630 /* If the sender is backup router and ID is server (and we are not
2631 backup router) then switch the entry to global list. */
2632 if (server_entry->server_type == SILC_BACKUP_ROUTER &&
2633 id_type == SILC_ID_SERVER &&
2634 server->id_entry->server_type != SILC_BACKUP_ROUTER) {
2635 id_list = server->global_list;
2636 router_sock = server->router ? SILC_PRIMARY_ROUTE(server) : sock;
2639 void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2640 packet->src_id_type);
2641 router = silc_idlist_find_server_by_id(server->global_list,
2642 sender_id, TRUE, NULL);
2644 router = silc_idlist_find_server_by_id(server->local_list,
2645 sender_id, TRUE, NULL);
2646 silc_free(sender_id);
2648 id_list = server->global_list;
2655 case SILC_ID_CLIENT:
2657 SilcClientEntry entry;
2659 /* Check that we do not have this client already */
2660 entry = silc_idlist_find_client_by_id(server->global_list,
2661 id, server->server_type,
2664 entry = silc_idlist_find_client_by_id(server->local_list,
2665 id, server->server_type,
2668 SILC_LOG_DEBUG(("Ignoring client that we already have"));
2672 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
2673 silc_id_render(id, SILC_ID_CLIENT),
2674 sock->type == SILC_SOCKET_TYPE_SERVER ?
2675 "Server" : "Router", sock->hostname));
2677 /* As a router we keep information of all global information in our
2678 global list. Cell wide information however is kept in the local
2680 entry = silc_idlist_add_client(id_list, NULL, NULL, NULL,
2681 id, router, NULL, 0);
2683 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
2685 /* Inform the sender that the ID is not usable */
2686 silc_server_send_notify_signoff(server, sock, FALSE, id, NULL);
2689 entry->nickname = NULL;
2690 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2692 if (sock->type == SILC_SOCKET_TYPE_SERVER)
2693 server->stat.cell_clients++;
2694 server->stat.clients++;
2696 /* Check if anyone is watching this nickname */
2697 if (server->server_type == SILC_ROUTER && id_list == server->local_list)
2698 silc_server_check_watcher_list(server, entry, NULL, 0);
2702 case SILC_ID_SERVER:
2704 SilcServerEntry entry;
2706 /* If the ID is mine, ignore it. */
2707 if (SILC_ID_SERVER_COMPARE(id, server->id)) {
2708 SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
2712 /* If the ID is the sender's ID, ignore it (we have it already) */
2713 if (SILC_ID_SERVER_COMPARE(id, router->id)) {
2714 SILC_LOG_DEBUG(("Ignoring sender's own ID"));
2718 /* Check that we do not have this server already */
2719 entry = silc_idlist_find_server_by_id(server->global_list,
2720 id, server->server_type,
2723 entry = silc_idlist_find_server_by_id(server->local_list,
2724 id, server->server_type,
2727 SILC_LOG_DEBUG(("Ignoring server that we already have"));
2731 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
2732 silc_id_render(id, SILC_ID_SERVER),
2733 sock->type == SILC_SOCKET_TYPE_SERVER ?
2734 "Server" : "Router", sock->hostname));
2736 /* As a router we keep information of all global information in our
2737 global list. Cell wide information however is kept in the local
2739 entry = silc_idlist_add_server(id_list, NULL, 0, id, router,
2742 SILC_LOG_ERROR(("Could not add new server to the ID Cache"));
2745 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2747 if (sock->type == SILC_SOCKET_TYPE_SERVER)
2748 server->stat.cell_servers++;
2749 server->stat.servers++;
2753 case SILC_ID_CHANNEL:
2754 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
2763 /* If the sender of this packet is server and we are router we need to
2764 broadcast this packet to other routers in the network. */
2765 if (broadcast && server->server_type == SILC_ROUTER &&
2766 sock->type == SILC_SOCKET_TYPE_SERVER &&
2767 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2768 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
2769 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
2771 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2772 buffer->data, buffer->len, FALSE);
2773 silc_server_backup_send(server, sock->user_data,
2774 packet->type, packet->flags,
2775 packet->buffer->data, packet->buffer->len,
2780 silc_id_payload_free(idp);
2784 /* Processes incoming New ID packet. New ID Payload is used to distribute
2785 information about newly registered clients and servers. */
2787 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
2788 SilcPacketContext *packet)
2790 silc_server_new_id_real(server, sock, packet, TRUE);
2793 /* Receoved New Id List packet, list of New ID payloads inside one
2794 packet. Process the New ID payloads one by one. */
2796 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
2797 SilcPacketContext *packet)
2799 SilcPacketContext *new_id;
2803 SILC_LOG_DEBUG(("Processing New ID List"));
2805 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2806 packet->src_id_type != SILC_ID_SERVER)
2809 /* If the sender of this packet is server and we are router we need to
2810 broadcast this packet to other routers in the network. Broadcast
2811 this list packet instead of multiple New ID packets. */
2812 if (server->server_type == SILC_ROUTER &&
2813 sock->type == SILC_SOCKET_TYPE_SERVER &&
2814 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2815 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
2816 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
2818 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2819 packet->buffer->data,
2820 packet->buffer->len, FALSE);
2821 silc_server_backup_send(server, sock->user_data,
2822 packet->type, packet->flags,
2823 packet->buffer->data, packet->buffer->len,
2827 /* Make copy of the original packet context, except for the actual
2828 data buffer, which we will here now fetch from the original buffer. */
2829 new_id = silc_packet_context_alloc();
2830 new_id->type = SILC_PACKET_NEW_ID;
2831 new_id->flags = packet->flags & (~SILC_PACKET_FLAG_LIST);
2832 new_id->src_id = packet->src_id;
2833 new_id->src_id_len = packet->src_id_len;
2834 new_id->src_id_type = packet->src_id_type;
2835 new_id->dst_id = packet->dst_id;
2836 new_id->dst_id_len = packet->dst_id_len;
2837 new_id->dst_id_type = packet->dst_id_type;
2839 idp = silc_buffer_alloc(256);
2840 new_id->buffer = idp;
2842 while (packet->buffer->len) {
2843 SILC_GET16_MSB(id_len, packet->buffer->data + 2);
2844 if ((id_len > packet->buffer->len) ||
2845 (id_len > idp->truelen))
2848 silc_buffer_pull_tail(idp, 4 + id_len);
2849 silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
2851 /* Process the New ID */
2852 silc_server_new_id_real(server, sock, new_id, FALSE);
2854 silc_buffer_push_tail(idp, 4 + id_len);
2855 silc_buffer_pull(packet->buffer, 4 + id_len);
2858 silc_buffer_free(idp);
2862 /* Received New Channel packet. Information about new channels in the
2863 network are distributed using this packet. Save the information about
2864 the new channel. This usually comes from router but also normal server
2865 can send this to notify channels it has when it connects to us. */
2867 void silc_server_new_channel(SilcServer server,
2868 SilcSocketConnection sock,
2869 SilcPacketContext *packet)
2871 SilcChannelPayload payload;
2872 SilcChannelID *channel_id;
2874 SilcUInt32 name_len;
2876 SilcUInt32 id_len, cipher_len;
2877 SilcServerEntry server_entry;
2878 SilcChannelEntry channel;
2881 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2882 packet->src_id_type != SILC_ID_SERVER ||
2883 server->server_type == SILC_SERVER)
2886 /* Parse the channel payload */
2887 payload = silc_channel_payload_parse(packet->buffer->data,
2888 packet->buffer->len);
2892 /* Get the channel ID */
2893 channel_id = silc_channel_get_id_parse(payload);
2895 silc_channel_payload_free(payload);
2899 channel_name = silc_channel_get_name(payload, &name_len);
2901 channel_name[255] = '\0';
2903 id = silc_channel_get_id(payload, &id_len);
2905 server_entry = (SilcServerEntry)sock->user_data;
2907 if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
2908 /* Add the channel to global list as it is coming from router. It
2909 cannot be our own channel as it is coming from router. */
2911 /* Check that we don't already have this channel */
2912 channel = silc_idlist_find_channel_by_name(server->local_list,
2913 channel_name, NULL);
2915 channel = silc_idlist_find_channel_by_name(server->global_list,
2916 channel_name, NULL);
2918 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
2919 silc_id_render(channel_id, SILC_ID_CHANNEL),
2923 silc_idlist_add_channel(server->global_list, strdup(channel_name),
2924 0, channel_id, sock->user_data, NULL, NULL, 0);
2926 silc_channel_payload_free(payload);
2927 silc_free(channel_id);
2930 channel->disabled = TRUE; /* Disabled until someone JOINs */
2932 server->stat.channels++;
2933 if (server->server_type == SILC_ROUTER)
2934 channel->users_resolved = TRUE;
2937 /* The channel is coming from our server, thus it is in our cell
2938 we will add it to our local list. */
2941 SILC_LOG_DEBUG(("Channel id(%s) from [Server] %s",
2942 silc_id_render(channel_id, SILC_ID_CHANNEL),
2945 /* Check that we don't already have this channel */
2946 channel = silc_idlist_find_channel_by_name(server->local_list,
2947 channel_name, NULL);
2949 channel = silc_idlist_find_channel_by_name(server->global_list,
2950 channel_name, NULL);
2952 /* If the channel does not exist, then create it. This creates a new
2953 key to the channel as well that we will send to the server. */
2955 SILC_LOG_DEBUG(("Channel is new to us"));
2957 /* The protocol says that the Channel ID's IP address must be based
2958 on the router's IP address. Check whether the ID is based in our
2959 IP and if it is not then create a new ID and enforce the server
2960 to switch the ID. */
2961 if (server_entry->server_type != SILC_BACKUP_ROUTER &&
2962 !SILC_ID_COMPARE(channel_id, server->id, server->id->ip.data_len)) {
2964 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2965 if (silc_id_create_channel_id(server, server->id, server->rng, &tmp)) {
2966 silc_server_send_notify_channel_change(server, sock, FALSE,
2968 silc_channel_payload_free(payload);
2969 silc_free(channel_id);
2973 /* Wait that server re-announces this channel */
2977 /* Create the channel with the provided Channel ID */
2978 channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
2982 silc_channel_payload_free(payload);
2983 silc_free(channel_id);
2986 channel->disabled = TRUE; /* Disabled until someone JOINs */
2988 #if 0 /* We assume that CMODE_CHANGE notify is sent to us after this. */
2990 /* XXX Dunno if this is supposed to be set in any server type. If set
2991 here the CMODE_CHANGE that may follow sets mode that we already
2992 have, and we may loose data from the CMODE_CHANGE notify. */
2993 if (server_entry->server_type != SILC_BACKUP_ROUTER)
2994 channel->mode = silc_channel_get_mode(payload);
2997 /* Send the new channel key to the server */
2998 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2999 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
3000 cipher = silc_cipher_get_name(channel->channel_key);
3001 cipher_len = strlen(cipher);
3002 chk = silc_channel_key_payload_encode(id_len, id,
3004 channel->key_len / 8,
3006 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
3007 chk->data, chk->len, FALSE);
3008 silc_buffer_free(chk);
3011 /* The channel exist by that name, check whether the ID's match.
3012 If they don't then we'll force the server to use the ID we have.
3013 We also create a new key for the channel. */
3014 SilcBuffer modes = NULL, users = NULL, users_modes = NULL;
3016 SILC_LOG_DEBUG(("Channel already exists"));
3018 if (!SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
3019 /* They don't match, send CHANNEL_CHANGE notify to the server to
3020 force the ID change. */
3021 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
3022 silc_server_send_notify_channel_change(server, sock, FALSE,
3023 channel_id, channel->id);
3024 silc_channel_payload_free(payload);
3025 silc_free(channel_id);
3027 /* Wait that server re-announces this channel */
3031 #if 0 /* We will announce our CMODE anyway for this channel, so no need
3032 to check it (implicit enforce). */
3034 /* If the mode is different from what we have then enforce the
3036 mode = silc_channel_get_mode(payload);
3037 if (channel->mode != mode) {
3038 SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
3039 silc_server_send_notify_cmode(server, sock, FALSE, channel,
3040 channel->mode, server->id,
3041 SILC_ID_SERVER, channel->cipher,
3043 channel->passphrase,
3044 channel->founder_key);
3048 /* Create new key for the channel and send it to the server and
3049 everybody else possibly on the channel. */
3050 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3052 if (silc_hash_table_count(channel->user_list)) {
3053 if (!silc_server_create_channel_key(server, channel, 0)) {
3054 silc_channel_payload_free(payload);
3055 silc_free(channel_id);
3059 /* Send to the channel */
3060 silc_server_send_channel_key(server, sock, channel, FALSE);
3063 /* Send to the server */
3064 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3065 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
3066 cipher = silc_cipher_get_name(channel->channel_key);
3067 cipher_len = strlen(cipher);
3068 chk = silc_channel_key_payload_encode(id_len, id,
3070 channel->key_len / 8,
3072 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
3073 chk->data, chk->len, FALSE);
3074 silc_buffer_free(chk);
3078 silc_free(channel_id);
3080 /* Since the channel is coming from server and we also know about it
3081 then send the JOIN notify to the server so that it see's our
3082 users on the channel "joining" the channel. */
3083 silc_server_announce_get_channel_users(server, channel, &modes, &users,
3086 silc_buffer_push(users, users->data - users->head);
3087 silc_server_packet_send(server, sock,
3088 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3089 users->data, users->len, FALSE);
3090 silc_buffer_free(users);
3093 silc_buffer_push(modes, modes->data - modes->head);
3094 silc_server_packet_send_dest(server, sock,
3095 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3096 channel->id, SILC_ID_CHANNEL,
3097 modes->data, modes->len, FALSE);
3098 silc_buffer_free(modes);
3101 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
3102 silc_server_packet_send_dest(server, sock,
3103 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3104 channel->id, SILC_ID_CHANNEL,
3106 users_modes->len, FALSE);
3107 silc_buffer_free(users_modes);
3109 if (channel->topic) {
3110 silc_server_send_notify_topic_set(server, sock,
3111 server->server_type == SILC_ROUTER ?
3112 TRUE : FALSE, channel,
3113 server->id, SILC_ID_SERVER,
3119 /* If the sender of this packet is server and we are router we need to
3120 broadcast this packet to other routers in the network. Broadcast
3121 this list packet instead of multiple New Channel packets. */
3122 if (server->server_type == SILC_ROUTER &&
3123 sock->type == SILC_SOCKET_TYPE_SERVER &&
3124 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
3125 SILC_LOG_DEBUG(("Broadcasting received New Channel packet"));
3126 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
3128 packet->flags | SILC_PACKET_FLAG_BROADCAST,
3129 packet->buffer->data,
3130 packet->buffer->len, FALSE);
3131 silc_server_backup_send(server, sock->user_data,
3132 packet->type, packet->flags,
3133 packet->buffer->data, packet->buffer->len,
3137 silc_channel_payload_free(payload);
3140 /* Received New Channel List packet, list of New Channel List payloads inside
3141 one packet. Process the New Channel payloads one by one. */
3143 void silc_server_new_channel_list(SilcServer server,
3144 SilcSocketConnection sock,
3145 SilcPacketContext *packet)
3147 SilcPacketContext *new;
3149 SilcUInt16 len1, len2;
3151 SILC_LOG_DEBUG(("Processing New Channel List"));
3153 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
3154 packet->src_id_type != SILC_ID_SERVER ||
3155 server->server_type == SILC_SERVER)
3158 /* Make copy of the original packet context, except for the actual
3159 data buffer, which we will here now fetch from the original buffer. */
3160 new = silc_packet_context_alloc();
3161 new->type = SILC_PACKET_NEW_CHANNEL;
3162 new->flags = packet->flags & (~SILC_PACKET_FLAG_LIST);
3163 new->src_id = packet->src_id;
3164 new->src_id_len = packet->src_id_len;
3165 new->src_id_type = packet->src_id_type;
3166 new->dst_id = packet->dst_id;
3167 new->dst_id_len = packet->dst_id_len;
3168 new->dst_id_type = packet->dst_id_type;
3170 buffer = silc_buffer_alloc(512);
3171 new->buffer = buffer;
3173 while (packet->buffer->len) {
3174 SILC_GET16_MSB(len1, packet->buffer->data);
3175 if ((len1 > packet->buffer->len) ||
3176 (len1 > buffer->truelen))
3179 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
3180 if ((len2 > packet->buffer->len) ||
3181 (len2 > buffer->truelen))
3184 silc_buffer_pull_tail(buffer, 8 + len1 + len2);
3185 silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
3187 /* Process the New Channel */
3188 silc_server_new_channel(server, sock, new);
3190 silc_buffer_push_tail(buffer, 8 + len1 + len2);
3191 silc_buffer_pull(packet->buffer, 8 + len1 + len2);
3194 silc_buffer_free(buffer);
3198 /* Received key agreement packet. This packet is never for us. It is to
3199 the client in the packet's destination ID. Sending of this sort of packet
3200 equals sending private message, ie. it is sent point to point from
3201 one client to another. */
3203 void silc_server_key_agreement(SilcServer server,
3204 SilcSocketConnection sock,
3205 SilcPacketContext *packet)
3207 SilcSocketConnection dst_sock;
3208 SilcIDListData idata;
3210 SILC_LOG_DEBUG(("Start"));
3212 if (packet->src_id_type != SILC_ID_CLIENT ||
3213 packet->dst_id_type != SILC_ID_CLIENT)
3216 if (!packet->dst_id)
3219 /* Get the route to the client */
3220 dst_sock = silc_server_get_client_route(server, packet->dst_id,
3221 packet->dst_id_len, NULL,
3226 /* Relay the packet */
3227 silc_server_relay_packet(server, dst_sock, idata->send_key,
3228 idata->hmac_send, idata->psn_send++,
3232 /* Received connection auth request packet that is used during connection
3233 phase to resolve the mandatory authentication method. This packet can
3234 actually be received at anytime but usually it is used only during
3235 the connection authentication phase. Now, protocol says that this packet
3236 can come from client or server, however, we support only this coming
3237 from client and expect that server always knows what authentication
3240 void silc_server_connection_auth_request(SilcServer server,
3241 SilcSocketConnection sock,
3242 SilcPacketContext *packet)
3244 SilcServerConfigClient *client = NULL;
3245 SilcUInt16 conn_type;
3247 SilcAuthMethod auth_meth = SILC_AUTH_NONE;
3249 if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT) {
3250 SILC_LOG_DEBUG(("Request not from client"));
3254 /* Parse the payload */
3255 ret = silc_buffer_unformat(packet->buffer,
3256 SILC_STR_UI_SHORT(&conn_type),
3257 SILC_STR_UI_SHORT(NULL),
3262 if (conn_type != SILC_SOCKET_TYPE_CLIENT)
3265 /* Get the authentication method for the client */
3266 auth_meth = SILC_AUTH_NONE;
3267 client = silc_server_config_find_client(server, sock->ip);
3269 client = silc_server_config_find_client(server, sock->hostname);
3271 if (client->passphrase) {
3272 if (client->publickeys && !server->config->prefer_passphrase_auth)
3273 auth_meth = SILC_AUTH_PUBLIC_KEY;
3275 auth_meth = SILC_AUTH_PASSWORD;
3276 } else if (client->publickeys)
3277 auth_meth = SILC_AUTH_PUBLIC_KEY;
3280 SILC_LOG_DEBUG(("Authentication method is [%s]",
3281 (auth_meth == SILC_AUTH_NONE ? "None" :
3282 auth_meth == SILC_AUTH_PASSWORD ? "Passphrase" :
3283 "Digital signatures")));
3285 /* Send it back to the client */
3286 silc_server_send_connection_auth_request(server, sock, conn_type, auth_meth);
3289 /* Received REKEY packet. The sender of the packet wants to regenerate
3290 its session keys. This starts the REKEY protocol. */
3292 void silc_server_rekey(SilcServer server,
3293 SilcSocketConnection sock,
3294 SilcPacketContext *packet)
3296 SilcProtocol protocol;
3297 SilcServerRekeyInternalContext *proto_ctx;
3298 SilcIDListData idata = (SilcIDListData)sock->user_data;
3300 SILC_LOG_DEBUG(("Start"));
3302 /* Allocate internal protocol context. This is sent as context
3304 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
3305 proto_ctx->server = (void *)server;
3306 proto_ctx->sock = sock;
3307 proto_ctx->responder = TRUE;
3308 proto_ctx->pfs = idata->rekey->pfs;
3310 /* Perform rekey protocol. Will call the final callback after the
3311 protocol is over. */
3312 silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
3313 &protocol, proto_ctx, silc_server_rekey_final);
3314 sock->protocol = protocol;
3316 if (proto_ctx->pfs == FALSE)
3317 /* Run the protocol */
3318 silc_protocol_execute(protocol, server->schedule, 0, 0);
3321 /* Received file transger packet. This packet is never for us. It is to
3322 the client in the packet's destination ID. Sending of this sort of packet
3323 equals sending private message, ie. it is sent point to point from
3324 one client to another. */
3326 void silc_server_ftp(SilcServer server,
3327 SilcSocketConnection sock,
3328 SilcPacketContext *packet)
3330 SilcSocketConnection dst_sock;
3331 SilcIDListData idata;
3333 SILC_LOG_DEBUG(("Start"));
3335 if (packet->src_id_type != SILC_ID_CLIENT ||
3336 packet->dst_id_type != SILC_ID_CLIENT)
3339 if (!packet->dst_id)
3342 /* Get the route to the client */
3343 dst_sock = silc_server_get_client_route(server, packet->dst_id,
3344 packet->dst_id_len, NULL,
3349 /* Relay the packet */
3350 silc_server_relay_packet(server, dst_sock, idata->send_key,
3351 idata->hmac_send, idata->psn_send++,
3357 SilcSocketConnection sock;
3358 SilcPacketContext *packet;
3360 } *SilcServerResumeResolve;
3362 SILC_SERVER_CMD_FUNC(resume_resolve)
3364 SilcServerResumeResolve r = (SilcServerResumeResolve)context;
3365 SilcServer server = r->server;
3366 SilcSocketConnection sock = r->sock;
3367 SilcServerCommandReplyContext reply = context2;
3368 SilcClientEntry client;
3370 SILC_LOG_DEBUG(("Start"));
3372 if (!reply || !silc_command_get_status(reply->payload, NULL, NULL)) {
3373 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3374 "closing connection", sock->hostname, sock->ip));
3375 silc_server_disconnect_remote(server, sock,
3376 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3377 "Resuming not possible");
3378 if (sock->user_data)
3379 silc_server_free_sock_user_data(server, sock, NULL);
3383 if (reply && silc_command_get(reply->payload) == SILC_COMMAND_WHOIS) {
3384 /* Get entry to the client, and resolve it if we don't have it. */
3385 client = silc_idlist_find_client_by_id(server->local_list,
3386 r->data, TRUE, NULL);
3388 client = silc_idlist_find_client_by_id(server->global_list,
3389 r->data, TRUE, NULL);
3391 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3392 "closing connection", sock->hostname, sock->ip));
3393 silc_server_disconnect_remote(server, sock,
3394 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3395 "Resuming not possible");
3396 if (sock->user_data)
3397 silc_server_free_sock_user_data(server, sock, NULL);
3402 if (!(client->mode & SILC_UMODE_DETACHED)) {
3403 SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, "
3404 "closing connection", sock->hostname, sock->ip));
3405 silc_server_disconnect_remote(server, sock,
3406 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3407 "Resuming not possible");
3408 if (sock->user_data)
3409 silc_server_free_sock_user_data(server, sock, NULL);
3413 client->data.status |= SILC_IDLIST_STATUS_RESUME_RES;
3416 /* Reprocess the packet */
3417 silc_server_resume_client(server, sock, r->packet);
3420 silc_socket_free(r->sock);
3421 silc_packet_context_free(r->packet);
3426 /* Received client resuming packet. This is used to resume detached
3427 client session. It can be sent by the client who wishes to resume
3428 but this is also sent by servers and routers to notify other routers
3429 that the client is not detached anymore. */
3431 void silc_server_resume_client(SilcServer server,
3432 SilcSocketConnection sock,
3433 SilcPacketContext *packet)
3435 SilcBuffer buffer = packet->buffer, buf;
3436 SilcIDListData idata;
3437 SilcIDCacheEntry id_cache = NULL;
3438 SilcClientEntry detached_client;
3439 SilcClientID *client_id = NULL;
3440 unsigned char *id_string, *auth = NULL;
3441 SilcUInt16 id_len, auth_len = 0;
3442 int ret, nickfail = 0;
3443 bool resolved, local, nick_change = FALSE, resolve = FALSE;
3444 SilcChannelEntry channel;
3445 SilcHashTableList htl;
3446 SilcChannelClientEntry chl;
3447 SilcServerResumeResolve r;
3450 ret = silc_buffer_unformat(buffer,
3451 SILC_STR_UI16_NSTRING(&id_string, &id_len),
3454 client_id = silc_id_str2id(id_string, id_len, SILC_ID_CLIENT);
3456 if (sock->type == SILC_SOCKET_TYPE_CLIENT) {
3457 /* Client send this and is attempting to resume to old client session */
3458 SilcClientEntry client;
3462 silc_buffer_pull(buffer, 2 + id_len);
3463 auth = buffer->data;
3464 auth_len = buffer->len;
3465 silc_buffer_push(buffer, 2 + id_len);
3468 if (!client_id || auth_len < 128) {
3469 SILC_LOG_ERROR(("Client %s (%s) sent incomplete resume information, "
3470 "closing connection", sock->hostname, sock->ip));
3471 silc_server_disconnect_remote(server, sock,
3472 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3473 "Resuming not possible");
3474 if (sock->user_data)
3475 silc_server_free_sock_user_data(server, sock, NULL);
3476 silc_free(client_id);
3480 /* Take client entry of this connection */
3481 client = (SilcClientEntry)sock->user_data;
3482 idata = (SilcIDListData)client;
3484 /* Get entry to the client, and resolve it if we don't have it. */
3485 detached_client = silc_server_query_client(server, client_id, FALSE,
3487 if (!detached_client) {
3489 /* The client info is being resolved. Reprocess this packet after
3490 receiving the reply to the query. */
3491 SILC_LOG_DEBUG(("Resolving client"));
3492 r = silc_calloc(1, sizeof(*r));
3496 r->sock = silc_socket_dup(sock);
3497 r->packet = silc_packet_context_dup(packet);
3498 r->data = client_id;
3499 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
3501 silc_server_command_resume_resolve, r);
3503 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3504 "closing connection", sock->hostname, sock->ip));
3505 silc_server_disconnect_remote(server, sock,
3506 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3507 "Resuming not possible");
3508 if (sock->user_data)
3509 silc_server_free_sock_user_data(server, sock, NULL);
3510 silc_free(client_id);
3515 if (!(detached_client->mode & SILC_UMODE_DETACHED))
3517 if (!silc_hash_table_count(detached_client->channels) &&
3518 detached_client->router)
3520 if (!detached_client->nickname)
3522 if (detached_client->data.status & SILC_IDLIST_STATUS_RESUME_RES)
3526 if (server->server_type == SILC_SERVER && !server->standalone) {
3527 /* The client info is being resolved. Reprocess this packet after
3528 receiving the reply to the query. */
3529 SILC_LOG_DEBUG(("Resolving client info"));
3530 silc_server_query_client(server, client_id, TRUE, NULL);
3531 r = silc_calloc(1, sizeof(*r));
3535 r->sock = silc_socket_dup(sock);
3536 r->packet = silc_packet_context_dup(packet);
3537 r->data = client_id;
3538 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
3540 silc_server_command_resume_resolve, r);
3543 if (server->server_type == SILC_SERVER) {
3544 SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, "
3545 "closing connection", sock->hostname, sock->ip));
3546 silc_server_disconnect_remote(server, sock,
3547 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3548 "Resuming not possible");
3549 if (sock->user_data)
3550 silc_server_free_sock_user_data(server, sock, NULL);
3551 silc_free(client_id);
3556 /* Check that we have the public key of the client, if not then we must
3557 resolve it first. */
3558 if (!detached_client->data.public_key) {
3559 if (server->server_type == SILC_SERVER && server->standalone) {
3560 SILC_LOG_ERROR(("Detached client's public key not present, "
3561 "closing connection"));
3562 silc_server_disconnect_remote(server, sock,
3563 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3564 "Resuming not possible");
3565 if (sock->user_data)
3566 silc_server_free_sock_user_data(server, sock, NULL);
3567 silc_free(client_id);
3569 /* We must retrieve the detached client's public key by sending
3570 GETKEY command. Reprocess this packet after receiving the key */
3571 SilcBuffer idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
3572 SilcSocketConnection dest_sock =
3573 silc_server_get_client_route(server, NULL, 0, client_id, NULL, NULL);
3575 SILC_LOG_DEBUG(("Resolving client public key"));
3577 silc_server_send_command(server, dest_sock ? dest_sock :
3578 SILC_PRIMARY_ROUTE(server),
3579 SILC_COMMAND_GETKEY, ++server->cmd_ident,
3580 1, 1, idp->data, idp->len);
3582 r = silc_calloc(1, sizeof(*r));
3584 silc_free(client_id);
3589 r->sock = silc_socket_dup(sock);
3590 r->packet = silc_packet_context_dup(packet);
3591 silc_server_command_pending(server, SILC_COMMAND_GETKEY,
3593 silc_server_command_resume_resolve, r);
3595 silc_buffer_free(idp);
3597 silc_free(client_id);
3599 } else if (!silc_pkcs_public_key_compare(detached_client->data.public_key,
3600 idata->public_key)) {
3601 /* We require that the connection and resuming authentication data
3602 must be using same key pair. */
3603 SILC_LOG_ERROR(("Resuming attempted with wrong public key, "
3604 "closing connection"));
3605 silc_server_disconnect_remote(server, sock,
3606 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3607 "Resuming not possible");
3608 if (sock->user_data)
3609 silc_server_free_sock_user_data(server, sock, NULL);
3610 silc_free(client_id);
3614 /* Verify the authentication payload. This has to be successful in
3615 order to allow the resuming */
3617 !silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
3618 detached_client->data.public_key, 0,
3619 idata->hash, detached_client->id,
3621 SILC_LOG_ERROR(("Client %s (%s) resume authentication failed, "
3622 "closing connection", sock->hostname, sock->ip));
3623 silc_server_disconnect_remote(server, sock,
3624 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3625 "Resuming not possible");
3626 if (sock->user_data)
3627 silc_server_free_sock_user_data(server, sock, NULL);
3628 silc_free(client_id);
3632 /* Now resume the client to the network */
3634 silc_schedule_task_del_by_context(server->schedule, detached_client);
3635 sock->user_data = detached_client;
3636 detached_client->connection = sock;
3638 /* Take new keys and stuff into use in the old entry */
3639 silc_idlist_del_data(detached_client);
3640 silc_idlist_add_data(detached_client, idata);
3641 detached_client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
3642 detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
3643 detached_client->data.status |= SILC_IDLIST_STATUS_LOCAL;
3644 detached_client->data.status &= ~SILC_IDLIST_STATUS_RESUME_RES;
3645 detached_client->mode &= ~SILC_UMODE_DETACHED;
3646 server->stat.my_detached--;
3648 /* Send the RESUME_CLIENT packet to our primary router so that others
3649 know this client isn't detached anymore. */
3650 buf = silc_buffer_alloc_size(2 + id_len);
3651 silc_buffer_format(buf,
3652 SILC_STR_UI_SHORT(id_len),
3653 SILC_STR_UI_XNSTRING(id_string, id_len),
3656 /* Send to primary router */
3657 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
3658 SILC_PACKET_RESUME_CLIENT, 0,
3659 buf->data, buf->len, TRUE);
3660 silc_server_backup_send(server, detached_client->router,
3661 SILC_PACKET_RESUME_CLIENT, 0,
3662 buf->data, buf->len, TRUE, TRUE);
3664 /* As router we must deliver this packet directly to the original
3665 server whom this client was earlier. */
3666 if (server->server_type == SILC_ROUTER && detached_client->router &&
3667 detached_client->router->server_type != SILC_ROUTER)
3668 silc_server_packet_send(server, detached_client->router->connection,
3669 SILC_PACKET_RESUME_CLIENT, 0,
3670 buf->data, buf->len, TRUE);
3671 silc_buffer_free(buf);
3673 detached_client->router = NULL;
3675 /* Delete this client entry since we're resuming to old one. */
3676 server->stat.my_clients--;
3677 server->stat.clients--;
3678 if (server->stat.cell_clients)
3679 server->stat.cell_clients--;
3680 silc_server_remove_from_channels(server, NULL, client, FALSE,
3681 NULL, FALSE, FALSE);
3682 silc_server_del_from_watcher_list(server, client);
3683 if (!silc_idlist_del_client(server->local_list, client))
3684 silc_idlist_del_client(server->global_list, client);
3685 client = detached_client;
3686 silc_free(client->servername);
3687 client->servername = strdup(server->server_name);
3689 /* If the ID is not based in our ID then change it */
3690 if (!SILC_ID_COMPARE(client->id, server->id, server->id->ip.data_len)) {
3691 silc_free(client_id);
3692 while (!silc_id_create_client_id(server, server->id, server->rng,
3693 server->md5hash, client->nickname,
3697 silc_server_disconnect_remote(server, sock,
3698 SILC_STATUS_ERR_BAD_NICKNAME, NULL);
3699 if (sock->user_data)
3700 silc_server_free_sock_user_data(server, sock, NULL);
3703 snprintf(&client->nickname[strlen(client->nickname) - 1], 1,
3710 /* Notify about Client ID change, nickname doesn't actually change. */
3711 silc_server_send_notify_nick_change(server, SILC_PRIMARY_ROUTE(server),
3712 SILC_BROADCAST(server),
3713 client->id, client_id,
3717 /* Resolve users on those channels that client has joined but we
3718 haven't resolved user list yet. */
3719 if (server->server_type == SILC_SERVER && !server->standalone) {
3720 silc_hash_table_list(client->channels, &htl);
3721 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
3722 channel = chl->channel;
3723 SILC_LOG_DEBUG(("Resolving users for %s channel",
3724 channel->channel_name));
3725 if (channel->disabled || !channel->users_resolved) {
3726 silc_server_send_command(server, SILC_PRIMARY_ROUTE(server),
3727 SILC_COMMAND_USERS, ++server->cmd_ident,
3728 1, 2, channel->channel_name,
3729 strlen(channel->channel_name));
3732 silc_hash_table_list_reset(&htl);
3735 /* Send the new client ID to the client. After this client may start
3736 receiving other packets, and may start sending packets too. */
3737 silc_server_send_new_id(server, sock, FALSE, client_id, SILC_ID_CLIENT,
3738 silc_id_get_len(client_id, SILC_ID_CLIENT));
3741 /* Send NICK change notify to channels as well. */
3742 SilcBuffer oidp, nidp;
3743 oidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3744 nidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
3745 silc_server_send_notify_on_channels(server, NULL, client,
3746 SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
3747 oidp->data, oidp->len,
3748 nidp->data, nidp->len,
3750 strlen(client->nickname));
3751 silc_buffer_free(oidp);
3752 silc_buffer_free(nidp);
3755 /* Add the client again to the ID cache to get it to correct list */
3756 if (!silc_idcache_del_by_context(server->local_list->clients, client))
3757 silc_idcache_del_by_context(server->global_list->clients, client);
3758 silc_free(client->id);
3759 client->id = client_id;
3761 silc_idcache_add(server->local_list->clients, client->nickname,
3762 client->id, client, 0, NULL);
3764 /* Send some nice info to the client */
3765 silc_server_send_connect_notifys(server, sock, client);
3767 /* Send all channel keys of channels the client has joined */
3768 silc_hash_table_list(client->channels, &htl);
3769 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
3770 bool created = FALSE;
3771 channel = chl->channel;
3773 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY)
3776 /* If we don't have channel key, then create one */
3777 if (!channel->channel_key) {
3778 if (!silc_server_create_channel_key(server, channel, 0))
3783 id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3784 cipher = silc_cipher_get_name(channel->channel_key);
3786 silc_channel_key_payload_encode(silc_id_get_len(channel->id,
3789 strlen(cipher), cipher,
3790 channel->key_len / 8, channel->key);
3791 silc_free(id_string);
3793 /* Send the channel key to the client */
3794 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
3795 keyp->data, keyp->len, FALSE);
3797 /* Distribute the channel key to channel */
3799 silc_server_send_channel_key(server, NULL, channel,
3800 server->server_type == SILC_ROUTER ?
3801 FALSE : !server->standalone);
3802 silc_server_backup_send(server, NULL, SILC_PACKET_CHANNEL_KEY, 0,
3803 keyp->data, keyp->len, FALSE, TRUE);
3806 silc_buffer_free(keyp);
3808 silc_hash_table_list_reset(&htl);
3810 } else if (sock->type != SILC_SOCKET_TYPE_CLIENT) {
3811 /* Server or router sent this to us to notify that that a client has
3813 SilcServerEntry server_entry;
3814 SilcServerID *server_id;
3817 SILC_LOG_DEBUG(("Malformed resuming packet"));
3821 /* Get entry to the client, and resolve it if we don't have it. */
3822 detached_client = silc_idlist_find_client_by_id(server->local_list,
3825 if (!detached_client) {
3826 detached_client = silc_idlist_find_client_by_id(server->global_list,
3829 if (!detached_client) {
3830 SILC_LOG_DEBUG(("Resuming client is unknown"));
3831 silc_free(client_id);
3836 /* Check that the client has not been resumed already because it is
3837 protocol error to attempt to resume more than once. The client
3838 will be killed if this protocol error occurs. */
3839 if (detached_client->data.status & SILC_IDLIST_STATUS_RESUMED &&
3840 !(detached_client->mode & SILC_UMODE_DETACHED)) {
3841 /* The client is clearly attempting to resume more than once and
3842 perhaps playing around by resuming from several different places
3843 at the same time. */
3844 SILC_LOG_DEBUG(("Attempting to re-resume client, killing both"));
3845 silc_server_kill_client(server, detached_client, NULL,
3846 server->id, SILC_ID_SERVER);
3847 silc_free(client_id);
3851 /* Check whether client is detached at all */
3852 if (!(detached_client->mode & SILC_UMODE_DETACHED)) {
3853 SILC_LOG_DEBUG(("Client is not detached"));
3854 silc_free(client_id);
3858 SILC_LOG_DEBUG(("Resuming detached client"));
3860 /* If the sender of this packet is server and we are router we need to
3861 broadcast this packet to other routers in the network. */
3862 if (server->server_type == SILC_ROUTER &&
3863 sock->type == SILC_SOCKET_TYPE_SERVER &&
3864 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
3865 SILC_LOG_DEBUG(("Broadcasting received Resume Client packet"));
3866 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
3868 packet->flags | SILC_PACKET_FLAG_BROADCAST,
3869 buffer->data, buffer->len, FALSE);
3870 silc_server_backup_send(server, sock->user_data,
3871 packet->type, packet->flags,
3872 packet->buffer->data, packet->buffer->len,
3876 /* Client is detached, and now it is resumed. Remove the detached
3877 mode and mark that it is resumed. */
3878 silc_idlist_del_data(detached_client);
3879 detached_client->mode &= ~SILC_UMODE_DETACHED;
3880 detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
3881 detached_client->data.status &= ~SILC_IDLIST_STATUS_LOCAL;
3882 id_cache->expire = 0;
3884 silc_schedule_task_del_by_context(server->schedule, detached_client);
3886 /* Get the new owner of the resumed client */
3887 server_id = silc_id_str2id(packet->src_id, packet->src_id_len,
3888 packet->src_id_type);
3890 silc_free(client_id);
3894 /* Get server entry */
3895 server_entry = silc_idlist_find_server_by_id(server->global_list,
3896 server_id, TRUE, NULL);
3898 if (!server_entry) {
3899 server_entry = silc_idlist_find_server_by_id(server->local_list,
3900 server_id, TRUE, NULL);
3902 if (!server_entry) {
3903 silc_free(server_id);
3904 silc_free(client_id);
3909 if (server->server_type == SILC_ROUTER &&
3910 sock->type == SILC_SOCKET_TYPE_ROUTER &&
3911 server_entry->server_type == SILC_ROUTER)
3914 /* Change the client to correct list. */
3915 if (!silc_idcache_del_by_context(server->local_list->clients,
3917 silc_idcache_del_by_context(server->global_list->clients,
3919 silc_idcache_add(local && server->server_type == SILC_ROUTER ?
3920 server->local_list->clients :
3921 server->global_list->clients,
3922 detached_client->nickname,
3923 detached_client->id, detached_client, FALSE, NULL);
3925 /* Change the owner of the client */
3926 detached_client->router = server_entry;
3928 /* Update channel information regarding global clients on channel. */
3929 if (server->server_type != SILC_ROUTER) {
3930 silc_hash_table_list(detached_client->channels, &htl);
3931 while (silc_hash_table_get(&htl, NULL, (void **)&chl))
3932 chl->channel->global_users =
3933 silc_server_channel_has_global(chl->channel);
3934 silc_hash_table_list_reset(&htl);
3937 silc_free(server_id);
3940 silc_free(client_id);