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 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
138 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
142 /* Get channel entry */
143 channel = silc_idlist_find_channel_by_id(server->global_list,
146 channel = silc_idlist_find_channel_by_id(server->local_list,
149 SILC_LOG_DEBUG(("Notify for unknown channel"));
150 silc_free(channel_id);
154 silc_free(channel_id);
157 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
160 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
164 /* If the the client is not in local list we check global list (ie. the
165 channel will be global channel) and if it does not exist then create
166 entry for the client. */
167 client = silc_idlist_find_client_by_id(server->global_list,
168 client_id, server->server_type,
171 client = silc_idlist_find_client_by_id(server->local_list,
172 client_id, server->server_type,
175 /* If router did not find the client the it is bogus */
176 if (server->server_type != SILC_SERVER) {
177 silc_free(client_id);
182 silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
183 silc_id_dup(client_id, SILC_ID_CLIENT),
184 sock->user_data, NULL, 0);
186 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
187 silc_free(client_id);
191 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
194 silc_free(client_id);
196 /* Do not process the notify if the client is not registered */
197 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
200 /* Do not add client to channel if it is there already */
201 if (silc_server_client_on_channel(client, channel, NULL)) {
202 SILC_LOG_DEBUG(("Client already on channel %s",
203 channel->channel_name));
207 /* Send to channel */
208 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
209 FALSE, packet->buffer->data,
210 packet->buffer->len, FALSE);
212 if (server->server_type != SILC_ROUTER &&
213 sock->type == SILC_SOCKET_TYPE_ROUTER)
214 /* The channel is global now */
215 channel->global_users = TRUE;
217 SILC_LOG_DEBUG(("Joining to channel %s", channel->channel_name));
219 /* JOIN the global client to the channel (local clients (if router
220 created the channel) is joined in the pending JOIN command). */
221 chl = silc_calloc(1, sizeof(*chl));
222 chl->client = client;
223 chl->channel = channel;
225 if (server->server_type != SILC_ROUTER ||
226 sock->type == SILC_SOCKET_TYPE_ROUTER) {
227 /* If this is the first one on the channel then it is the founder of
228 the channel. This is done on normal server and on router if this
229 notify is coming from router */
230 if (!silc_hash_table_count(channel->user_list)) {
231 SILC_LOG_DEBUG(("Client %s is founder on channel",
232 silc_id_render(chl->client->id, SILC_ID_CLIENT)));
233 chl->mode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
237 silc_hash_table_add(channel->user_list, client, chl);
238 silc_hash_table_add(client->channels, channel, chl);
239 channel->user_count++;
240 channel->disabled = FALSE;
242 /* Make sure we don't expire clients that are on channel */
246 /* Update statistics */
247 if (server->server_type == SILC_ROUTER) {
248 if (sock->type != SILC_SOCKET_TYPE_ROUTER)
249 server->stat.cell_chanclients++;
250 server->stat.chanclients++;
255 case SILC_NOTIFY_TYPE_LEAVE:
257 * Distribute the notify to local clients on the channel
259 SILC_LOG_DEBUG(("LEAVE notify"));
262 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
263 packet->dst_id_type);
268 /* Get channel entry */
269 channel = silc_idlist_find_channel_by_id(server->global_list,
272 channel = silc_idlist_find_channel_by_id(server->local_list,
275 SILC_LOG_DEBUG(("Notify for unknown channel"));
276 silc_free(channel_id);
282 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
284 silc_free(channel_id);
287 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
289 silc_free(channel_id);
293 /* Get client entry */
294 client = silc_idlist_find_client_by_id(server->global_list,
295 client_id, TRUE, NULL);
297 client = silc_idlist_find_client_by_id(server->local_list,
298 client_id, TRUE, NULL);
300 silc_free(client_id);
301 silc_free(channel_id);
305 silc_free(client_id);
307 /* Check if on channel */
308 if (!silc_server_client_on_channel(client, channel, NULL))
311 /* Send the leave notify to channel */
312 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
313 FALSE, packet->buffer->data,
314 packet->buffer->len, FALSE);
316 /* Remove the user from channel */
317 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
320 case SILC_NOTIFY_TYPE_SIGNOFF:
322 * Distribute the notify to local clients on the channel
324 SILC_LOG_DEBUG(("SIGNOFF notify"));
327 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
330 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
334 /* Get client entry */
335 client = silc_idlist_find_client_by_id(server->global_list,
336 client_id, TRUE, &cache);
338 client = silc_idlist_find_client_by_id(server->local_list,
339 client_id, TRUE, &cache);
341 silc_free(client_id);
345 silc_free(client_id);
347 /* Get signoff message */
348 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
352 /* Update statistics */
353 server->stat.clients--;
354 if (server->stat.cell_clients)
355 server->stat.cell_clients--;
356 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
357 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
358 silc_schedule_task_del_by_context(server->schedule, client);
360 /* Remove the client from all channels. */
361 silc_server_remove_from_channels(server, NULL, client, TRUE, tmp, FALSE);
363 /* Check if anyone is watching this nickname */
364 if (server->server_type == SILC_ROUTER)
365 silc_server_check_watcher_list(server, client, NULL,
366 SILC_NOTIFY_TYPE_SIGNOFF);
368 /* Remove this client from watcher list if it is */
369 silc_server_del_from_watcher_list(server, client);
371 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
372 cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
375 case SILC_NOTIFY_TYPE_TOPIC_SET:
377 * Distribute the notify to local clients on the channel
380 SILC_LOG_DEBUG(("TOPIC SET notify"));
383 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
386 client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
390 /* Get client entry */
391 if (id_type == SILC_ID_CLIENT) {
392 client = silc_idlist_find_client_by_id(server->global_list,
393 client_id, TRUE, &cache);
395 client = silc_idlist_find_client_by_id(server->local_list,
396 client_id, TRUE, &cache);
398 silc_free(client_id);
402 silc_free(client_id);
406 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
408 silc_free(channel_id);
413 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
414 packet->dst_id_type);
419 /* Get channel entry */
420 channel = silc_idlist_find_channel_by_id(server->global_list,
423 channel = silc_idlist_find_channel_by_id(server->local_list,
426 SILC_LOG_DEBUG(("Notify for unknown channel"));
427 silc_free(channel_id);
431 silc_free(channel_id);
433 if (channel->topic && !strcmp(channel->topic, tmp)) {
434 SILC_LOG_DEBUG(("Topic is already set and same"));
439 /* Get user's channel entry and check that topic set is allowed. */
440 if (!silc_server_client_on_channel(client, channel, &chl))
442 if (channel->mode & SILC_CHANNEL_MODE_TOPIC &&
443 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
444 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
445 SILC_LOG_DEBUG(("Topic change is not allowed"));
450 /* Change the topic */
451 silc_free(channel->topic);
452 channel->topic = strdup(tmp);
454 /* Send the same notify to the channel */
455 silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
456 FALSE, packet->buffer->data,
457 packet->buffer->len, FALSE);
460 case SILC_NOTIFY_TYPE_NICK_CHANGE:
463 * Distribute the notify to local clients on the channel
465 unsigned char *id, *id2;
467 SilcUInt32 nickname_len;
469 SILC_LOG_DEBUG(("NICK CHANGE notify"));
471 /* Get old client ID */
472 id = silc_argument_get_arg_type(args, 1, &tmp_len);
475 client_id = silc_id_payload_parse_id(id, tmp_len, NULL);
479 /* Get new client ID */
480 id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
483 client_id2 = silc_id_payload_parse_id(id2, tmp_len, NULL);
485 silc_free(client_id);
489 SILC_LOG_DEBUG(("Old Client ID id(%s)",
490 silc_id_render(client_id, SILC_ID_CLIENT)));
491 SILC_LOG_DEBUG(("New Client ID id(%s)",
492 silc_id_render(client_id2, SILC_ID_CLIENT)));
494 /* From protocol version 1.1 we also get the new nickname */
495 nickname = silc_argument_get_arg_type(args, 3, &nickname_len);;
497 /* Replace the Client ID */
498 client = silc_idlist_replace_client_id(server,
499 server->global_list, client_id,
500 client_id2, nickname);
502 client = silc_idlist_replace_client_id(server,
503 server->local_list, client_id,
504 client_id2, nickname);
507 /* Send the NICK_CHANGE notify type to local clients on the channels
508 this client is joined to. */
509 silc_server_send_notify_on_channels(server, client, client,
510 SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
511 id, tmp_len, id2, tmp_len,
516 silc_free(client_id);
518 silc_free(client_id2);
522 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
524 * Distribute the notify to local clients on the channel
527 SILC_LOG_DEBUG(("CMODE CHANGE notify"));
530 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
533 client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
537 /* Get client entry */
538 if (id_type == SILC_ID_CLIENT) {
539 client = silc_idlist_find_client_by_id(server->global_list,
540 client_id, TRUE, &cache);
542 client = silc_idlist_find_client_by_id(server->local_list,
543 client_id, TRUE, &cache);
545 silc_free(client_id);
549 silc_free(client_id);
553 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
554 packet->dst_id_type);
559 /* Get channel entry */
560 channel = silc_idlist_find_channel_by_id(server->global_list,
563 channel = silc_idlist_find_channel_by_id(server->local_list,
566 SILC_LOG_DEBUG(("Notify for unknown channel"));
567 silc_free(channel_id);
571 silc_free(channel_id);
574 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
577 SILC_GET32_MSB(mode, tmp);
579 /* Check if mode changed */
580 if (channel->mode == mode) {
581 SILC_LOG_DEBUG(("Mode is changed already"));
583 /* If this mode change has founder mode then we'll enforce the
584 change so that the server gets the real founder public key */
585 if (server->server_type != SILC_SERVER &&
586 sock != SILC_PRIMARY_ROUTE(server) &&
587 mode & SILC_CHANNEL_MODE_FOUNDER_AUTH && channel->founder_key) {
588 SILC_LOG_DEBUG(("Sending founder public key to server"));
589 silc_server_send_notify_cmode(server, sock, FALSE, channel,
590 channel->mode, server->id,
591 SILC_ID_SERVER, channel->cipher,
594 channel->founder_key);
597 /* If we received same mode from our primary check whether founder
598 mode and key in the notify is set. We update the founder key
599 here since we may have wrong one */
600 if (server->server_type == SILC_SERVER &&
601 sock == SILC_PRIMARY_ROUTE(server) &&
602 mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
603 SILC_LOG_DEBUG(("Founder public key received from router"));
604 tmp = silc_argument_get_arg_type(args, 6, &tmp_len);
608 if (channel->founder_key)
609 silc_pkcs_public_key_free(channel->founder_key);
610 channel->founder_key = NULL;
611 silc_pkcs_public_key_decode(tmp, tmp_len, &channel->founder_key);
617 /* Get user's channel entry and check that mode change is allowed */
619 if (!silc_server_client_on_channel(client, channel, &chl))
621 if (!silc_server_check_cmode_rights(server, channel, chl, mode)) {
622 SILC_LOG_DEBUG(("CMODE change is not allowed"));
623 silc_server_send_notify_cmode(server, sock, FALSE, channel,
624 channel->mode, server->id,
625 SILC_ID_SERVER, channel->cipher,
628 channel->founder_key);
632 /* Assure that server is not removing founder mode from us */
633 if (server->server_type == SILC_ROUTER &&
634 sock != SILC_PRIMARY_ROUTE(server) &&
635 channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH &&
636 !(mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
637 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
638 silc_server_send_notify_cmode(server, sock, FALSE, channel,
639 channel->mode, server->id,
640 SILC_ID_SERVER, channel->cipher,
643 channel->founder_key);
647 /* If server is adding founder mode, check whether there is founder
648 on channel already and is not from this server */
649 if (server->server_type == SILC_ROUTER &&
650 sock != SILC_PRIMARY_ROUTE(server) &&
651 mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
652 silc_hash_table_list(channel->user_list, &htl);
653 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
654 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO &&
655 chl->client->router != sock->user_data) {
656 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
657 silc_server_send_notify_cmode(server, sock, FALSE, channel,
658 channel->mode, server->id,
659 SILC_ID_SERVER, channel->cipher,
662 channel->founder_key);
663 silc_hash_table_list_reset(&htl);
666 silc_hash_table_list_reset(&htl);
670 /* If the channel had private keys set and the mode was removed then
671 we must re-generate and re-distribute a new channel key */
672 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY &&
673 !(mode & SILC_CHANNEL_MODE_PRIVKEY)) {
674 /* Re-generate channel key */
675 if (!silc_server_create_channel_key(server, channel, 0))
678 /* Send the channel key. This sends it to our local clients and if
679 we are normal server to our router as well. */
680 silc_server_send_channel_key(server, NULL, channel,
681 server->server_type == SILC_ROUTER ?
682 FALSE : !server->standalone);
686 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
688 unsigned char hash[32];
691 silc_hmac_free(channel->hmac);
692 if (!silc_hmac_alloc(tmp, NULL, &channel->hmac))
695 /* Set the HMAC key out of current channel key. The client must do
697 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key,
698 channel->key_len / 8, hash);
699 silc_hmac_set_key(channel->hmac, hash,
700 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
701 memset(hash, 0, sizeof(hash));
704 /* Get the passphrase */
705 tmp = silc_argument_get_arg_type(args, 5, &tmp_len);
707 silc_free(channel->passphrase);
708 channel->passphrase = silc_memdup(tmp, tmp_len);
711 /* Get founder public key */
712 tmp = silc_argument_get_arg_type(args, 6, &tmp_len);
713 if (tmp && mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
714 if (channel->founder_key)
715 silc_pkcs_public_key_free(channel->founder_key);
716 channel->founder_key = NULL;
717 silc_pkcs_public_key_decode(tmp, tmp_len, &channel->founder_key);
719 if (!channel->founder_key ||
720 (client && client->data.public_key &&
721 server->server_type == SILC_ROUTER &&
722 !silc_pkcs_public_key_compare(channel->founder_key,
723 client->data.public_key))) {
724 /* A really buggy server isn't checking public keys correctly.
725 It's not possible that the mode setter and founder wouldn't
726 have same public key. */
727 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
729 mode &= ~SILC_CHANNEL_MODE_FOUNDER_AUTH;
730 silc_server_send_notify_cmode(server, sock, FALSE, channel,
731 mode, server->id, SILC_ID_SERVER,
734 channel->passphrase, NULL);
735 if (channel->founder_key)
736 silc_pkcs_public_key_free(channel->founder_key);
737 channel->founder_key = NULL;
738 } else if (client && !client->data.public_key) {
739 client->data.public_key =
740 silc_pkcs_public_key_copy(channel->founder_key);
744 if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH && !channel->founder_key &&
745 server->server_type == SILC_ROUTER) {
746 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
747 mode &= ~SILC_CHANNEL_MODE_FOUNDER_AUTH;
748 silc_server_send_notify_cmode(server, sock, FALSE, channel,
749 mode, server->id, SILC_ID_SERVER,
752 channel->passphrase, NULL);
755 /* Send the same notify to the channel */
756 silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
757 FALSE, packet->buffer->data,
758 packet->buffer->len, FALSE);
761 channel->mode = mode;
763 if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) &&
764 channel->founder_key) {
765 silc_pkcs_public_key_free(channel->founder_key);
766 channel->founder_key = NULL;
771 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
774 * Distribute the notify to local clients on the channel
776 SilcChannelClientEntry chl2 = NULL;
777 bool notify_sent = FALSE;
779 SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
782 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
785 client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
789 /* Get client entry */
790 if (id_type == SILC_ID_CLIENT) {
791 client = silc_idlist_find_client_by_id(server->global_list,
792 client_id, TRUE, &cache);
794 client = silc_idlist_find_client_by_id(server->local_list,
795 client_id, TRUE, &cache);
797 silc_free(client_id);
801 silc_free(client_id);
805 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
806 packet->dst_id_type);
811 /* Get channel entry */
812 channel = silc_idlist_find_channel_by_id(server->global_list,
815 channel = silc_idlist_find_channel_by_id(server->local_list,
818 SILC_LOG_DEBUG(("Notify for unknown channel"));
819 silc_free(channel_id);
825 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
827 silc_free(channel_id);
831 SILC_GET32_MSB(mode, tmp);
833 /* Get target client */
834 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
837 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
841 /* Get client entry */
842 client2 = silc_idlist_find_client_by_id(server->global_list,
843 client_id, TRUE, NULL);
845 client2 = silc_idlist_find_client_by_id(server->local_list,
846 client_id, TRUE, NULL);
848 silc_free(client_id);
852 silc_free(client_id);
855 /* Check that sender is on channel */
856 if (!silc_server_client_on_channel(client, channel, &chl))
859 if (client != client2 && server->server_type == SILC_ROUTER) {
860 /* Sender must be operator */
861 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
862 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
863 SILC_LOG_DEBUG(("CUMODE change is not allowed"));
867 if (!silc_server_client_on_channel(client2, channel, &chl))
870 /* If target is founder mode change is not allowed. */
871 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
872 SILC_LOG_DEBUG(("CUMODE change is not allowed"));
878 /* Get target channel user entry */
879 if (!silc_server_client_on_channel(client2, channel, &chl))
882 if (server->server_type == SILC_SERVER && chl->mode == mode) {
883 SILC_LOG_DEBUG(("Mode is changed already"));
887 if (mode & SILC_CHANNEL_UMODE_CHANFO &&
888 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO) &&
889 server->server_type == SILC_ROUTER &&
890 sock != SILC_PRIMARY_ROUTE(server)) {
891 SilcPublicKey founder_key = NULL;
893 /* If channel doesn't have founder auth mode then it's impossible
894 that someone would be getting founder rights with CUMODE command.
895 In that case there already either is founder or there isn't
896 founder at all on the channel. */
897 if (client && !(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
898 /* Force the mode to not have founder mode */
899 chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
900 silc_server_force_cumode_change(server, sock, channel, chl, mode);
905 /* Get the founder of the channel and if found then this client
906 cannot be the founder since there already is one. */
907 silc_hash_table_list(channel->user_list, &htl);
908 while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
909 if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
910 /* If the founder on the channel is not the one whom has set
911 the founder mode, then it's possible that this CUMODE_CHANGE
912 is correct. Due to netsplits it's possible that this
913 situation happens. */
914 if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) ||
915 (channel->founder_key && chl2->client->data.public_key &&
916 silc_pkcs_public_key_compare(
917 channel->founder_key,
918 chl2->client->data.public_key))) {
919 chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
920 silc_server_force_cumode_change(server, sock, channel,
926 silc_hash_table_list_reset(&htl);
927 if (!(mode & SILC_CHANNEL_UMODE_CHANFO))
930 /* Founder not found of the channel. Since the founder auth mode
931 is set on the channel now check whether this is the client that
932 originally set the mode. */
934 if (channel->founder_key) {
935 /* Get public key that must be present in notify */
936 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
937 if (!tmp || !silc_pkcs_public_key_decode(tmp, tmp_len,
939 chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
940 silc_server_force_cumode_change(server, sock, channel, chl, mode);
945 /* Now match the public key we have cached and public key sent.
947 if (client && client->data.public_key &&
948 !silc_pkcs_public_key_compare(channel->founder_key,
949 client->data.public_key)) {
950 chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
951 silc_server_force_cumode_change(server, sock, channel, chl, mode);
955 if (!silc_pkcs_public_key_compare(channel->founder_key,
957 chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
958 silc_server_force_cumode_change(server, sock, channel, chl, mode);
964 /* There cannot be anyone else as founder on the channel now. This
965 client is definitely the founder due to this authentication */
966 silc_hash_table_list(channel->user_list, &htl);
967 while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
968 if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
969 chl2->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
970 silc_server_force_cumode_change(server, NULL, channel, chl2,
974 silc_hash_table_list_reset(&htl);
977 silc_pkcs_public_key_free(founder_key);
980 if (server->server_type != SILC_SERVER && chl->mode == mode) {
981 SILC_LOG_DEBUG(("Mode is changed already"));
985 SILC_LOG_DEBUG(("Changing %s channel user mode",
986 chl->client->nickname ? chl->client->nickname :
987 (unsigned char *)""));
989 /* Change the mode */
992 /* Send the same notify to the channel */
994 silc_server_packet_send_to_channel(server, NULL, channel,
996 FALSE, packet->buffer->data,
997 packet->buffer->len, FALSE);
999 silc_free(channel_id);
1003 case SILC_NOTIFY_TYPE_INVITE:
1005 if (packet->dst_id_type == SILC_ID_CLIENT)
1008 SILC_LOG_DEBUG(("INVITE notify"));
1010 /* Get Channel ID */
1011 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1014 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1018 /* Get channel entry */
1019 channel = silc_idlist_find_channel_by_id(server->global_list,
1022 channel = silc_idlist_find_channel_by_id(server->local_list,
1025 SILC_LOG_DEBUG(("Notify for unknown channel"));
1026 silc_free(channel_id);
1030 silc_free(channel_id);
1033 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1036 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1040 /* Get client entry */
1041 client = silc_idlist_find_client_by_id(server->global_list,
1042 client_id, TRUE, &cache);
1044 client = silc_idlist_find_client_by_id(server->local_list,
1045 client_id, TRUE, &cache);
1047 silc_free(client_id);
1051 silc_free(client_id);
1053 /* Get user's channel entry and check that inviting is allowed. */
1054 if (!silc_server_client_on_channel(client, channel, &chl))
1056 if (channel->mode & SILC_CHANNEL_MODE_INVITE &&
1057 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
1058 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1059 SILC_LOG_DEBUG(("Inviting is not allowed"));
1063 /* Get the added invite */
1064 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
1066 if (!channel->invite_list)
1067 channel->invite_list = silc_calloc(tmp_len + 2,
1068 sizeof(*channel->invite_list));
1070 channel->invite_list = silc_realloc(channel->invite_list,
1071 sizeof(*channel->invite_list) *
1073 strlen(channel->invite_list) +
1075 if (tmp[tmp_len - 1] == ',')
1076 tmp[tmp_len - 1] = '\0';
1078 strncat(channel->invite_list, tmp, tmp_len);
1079 strncat(channel->invite_list, ",", 1);
1082 /* Get the deleted invite */
1083 tmp = silc_argument_get_arg_type(args, 5, &tmp_len);
1084 if (tmp && channel->invite_list) {
1085 char *start, *end, *n;
1087 if (!strncmp(channel->invite_list, tmp,
1088 strlen(channel->invite_list) - 1)) {
1089 silc_free(channel->invite_list);
1090 channel->invite_list = NULL;
1092 start = strstr(channel->invite_list, tmp);
1093 if (start && strlen(start) >= tmp_len) {
1094 end = start + tmp_len;
1095 n = silc_calloc(strlen(channel->invite_list) - tmp_len, sizeof(*n));
1096 strncat(n, channel->invite_list, start - channel->invite_list);
1097 strncat(n, end + 1, ((channel->invite_list +
1098 strlen(channel->invite_list)) - end) - 1);
1099 silc_free(channel->invite_list);
1100 channel->invite_list = n;
1107 case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
1109 * Distribute to the local clients on the channel and change the
1113 SILC_LOG_DEBUG(("CHANNEL CHANGE"));
1115 if (sock->type != SILC_SOCKET_TYPE_ROUTER)
1118 /* Get the old Channel ID */
1119 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1122 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1126 /* Get the channel entry */
1127 channel = silc_idlist_find_channel_by_id(server->local_list,
1130 channel = silc_idlist_find_channel_by_id(server->global_list,
1133 SILC_LOG_DEBUG(("Notify for unknown channel"));
1134 silc_free(channel_id);
1139 /* Send the notify to the channel */
1140 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
1141 FALSE, packet->buffer->data,
1142 packet->buffer->len, FALSE);
1144 /* Get the new Channel ID */
1145 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1148 channel_id2 = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1152 SILC_LOG_DEBUG(("Old Channel ID id(%s)",
1153 silc_id_render(channel_id, SILC_ID_CHANNEL)));
1154 SILC_LOG_DEBUG(("New Channel ID id(%s)",
1155 silc_id_render(channel_id2, SILC_ID_CHANNEL)));
1157 /* Replace the Channel ID */
1158 if (!silc_idlist_replace_channel_id(server->local_list, channel_id,
1160 if (!silc_idlist_replace_channel_id(server->global_list, channel_id,
1162 silc_free(channel_id2);
1167 SilcBuffer modes = NULL, users = NULL, users_modes = NULL;
1169 /* Re-announce this channel which ID was changed. */
1170 silc_server_send_new_channel(server, sock, FALSE, channel->channel_name,
1172 silc_id_get_len(channel->id,
1176 /* Re-announce our clients on the channel as the ID has changed now */
1177 silc_server_announce_get_channel_users(server, channel, &modes, &users,
1180 silc_buffer_push(users, users->data - users->head);
1181 silc_server_packet_send(server, sock,
1182 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1183 users->data, users->len, FALSE);
1184 silc_buffer_free(users);
1187 silc_buffer_push(modes, modes->data - modes->head);
1188 silc_server_packet_send_dest(server, sock,
1189 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1190 channel->id, SILC_ID_CHANNEL,
1191 modes->data, modes->len, FALSE);
1192 silc_buffer_free(modes);
1195 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
1196 silc_server_packet_send_dest(server, sock,
1197 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1198 channel->id, SILC_ID_CHANNEL,
1200 users_modes->len, FALSE);
1201 silc_buffer_free(users_modes);
1204 /* Re-announce channel's topic */
1205 if (channel->topic) {
1206 silc_server_send_notify_topic_set(server, sock,
1207 server->server_type == SILC_ROUTER ?
1208 TRUE : FALSE, channel,
1209 server->id, SILC_ID_SERVER,
1214 silc_free(channel_id);
1218 case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
1220 * Remove the server entry and all clients that this server owns.
1223 SILC_LOG_DEBUG(("SERVER SIGNOFF notify"));
1226 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1229 server_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1233 /* If the ID is mine, this notify is not allowed. */
1234 if (SILC_ID_SERVER_COMPARE(server_id, server->id)) {
1235 SILC_LOG_DEBUG(("Ignoring my own ID for SERVER_SIGNOFF"));
1239 /* Get server entry */
1240 server_entry = silc_idlist_find_server_by_id(server->global_list,
1241 server_id, TRUE, NULL);
1243 if (!server_entry) {
1244 server_entry = silc_idlist_find_server_by_id(server->local_list,
1245 server_id, TRUE, NULL);
1247 if (!server_entry) {
1248 /* If we are normal server then we might not have the server. Check
1249 whether router was kind enough to send the list of all clients
1250 that actually was to be removed. Remove them if the list is
1252 if (server->server_type != SILC_ROUTER &&
1253 silc_argument_get_arg_num(args) > 1) {
1256 for (i = 1; i < silc_argument_get_arg_num(args); i++) {
1258 tmp = silc_argument_get_arg_type(args, i + 1, &tmp_len);
1261 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1265 /* Get client entry */
1266 client = silc_idlist_find_client_by_id(server->global_list,
1267 client_id, TRUE, &cache);
1270 client = silc_idlist_find_client_by_id(server->local_list,
1271 client_id, TRUE, &cache);
1274 silc_free(client_id);
1278 silc_free(client_id);
1280 /* Update statistics */
1281 server->stat.clients--;
1282 if (server->stat.cell_clients)
1283 server->stat.cell_clients--;
1284 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
1285 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
1287 /* Remove the client from all channels. */
1288 silc_server_remove_from_channels(server, NULL, client,
1291 /* Check if anyone is watching this nickname */
1292 if (server->server_type == SILC_ROUTER)
1293 silc_server_check_watcher_list(server, client, NULL,
1294 SILC_NOTIFY_TYPE_SERVER_SIGNOFF);
1296 /* Remove this client from watcher list if it is */
1298 silc_server_del_from_watcher_list(server, client);
1300 /* Remove the client */
1301 silc_idlist_del_data(client);
1302 silc_idlist_del_client(local ? server->local_list :
1303 server->global_list, client);
1307 silc_free(server_id);
1311 silc_free(server_id);
1313 /* Sending SERVER_SIGNOFF is not right way to signoff local connection */
1314 if (SILC_IS_LOCAL(server_entry))
1317 /* Remove all servers that are originated from this server, and
1318 remove the clients of those servers too. */
1319 silc_server_remove_servers_by_server(server, server_entry, TRUE);
1321 /* Remove the clients that this server owns as they will become
1323 silc_server_remove_clients_by_server(server, server_entry->router,
1324 server_entry, TRUE);
1325 silc_server_backup_del(server, server_entry);
1327 /* Remove the server entry */
1328 silc_idlist_del_server(local ? server->local_list :
1329 server->global_list, server_entry);
1331 /* Update statistics */
1332 if (server->server_type == SILC_ROUTER)
1333 server->stat.servers--;
1337 case SILC_NOTIFY_TYPE_KICKED:
1339 * Distribute the notify to local clients on the channel
1342 SILC_LOG_DEBUG(("KICKED notify"));
1345 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
1346 packet->dst_id_type);
1351 /* Get channel entry */
1352 channel = silc_idlist_find_channel_by_id(server->global_list,
1355 channel = silc_idlist_find_channel_by_id(server->local_list,
1358 SILC_LOG_DEBUG(("Notify for unknown channel"));
1359 silc_free(channel_id);
1363 silc_free(channel_id);
1366 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1369 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1373 /* If the the client is not in local list we check global list */
1374 client = silc_idlist_find_client_by_id(server->global_list,
1375 client_id, TRUE, NULL);
1377 client = silc_idlist_find_client_by_id(server->local_list,
1378 client_id, TRUE, NULL);
1380 silc_free(client_id);
1384 silc_free(client_id);
1386 /* If target is founder they cannot be kicked */
1387 if (!silc_server_client_on_channel(client, channel, &chl))
1389 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO)
1392 /* From protocol version 1.1 we get the kicker's ID as well. */
1393 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1395 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1399 /* If the the client is not in local list we check global list */
1400 client2 = silc_idlist_find_client_by_id(server->global_list,
1401 client_id, TRUE, NULL);
1403 client2 = silc_idlist_find_client_by_id(server->local_list,
1404 client_id, TRUE, NULL);
1406 silc_free(client_id);
1410 silc_free(client_id);
1412 /* Kicker must be operator on channel */
1413 if (!silc_server_client_on_channel(client2, channel, &chl))
1415 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
1416 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1417 SILC_LOG_DEBUG(("Kicking is not allowed"));
1422 /* Send to channel */
1423 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
1424 FALSE, packet->buffer->data,
1425 packet->buffer->len, FALSE);
1427 /* Remove the client from channel */
1428 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
1432 case SILC_NOTIFY_TYPE_KILLED:
1435 * Distribute the notify to local clients on channels
1437 unsigned char *id, *comment;
1438 SilcUInt32 id_len, comment_len;
1440 SILC_LOG_DEBUG(("KILLED notify"));
1443 id = silc_argument_get_arg_type(args, 1, &id_len);
1446 client_id = silc_id_payload_parse_id(id, id_len, NULL);
1450 /* If the the client is not in local list we check global list */
1451 client = silc_idlist_find_client_by_id(server->global_list,
1452 client_id, TRUE, &cache);
1454 client = silc_idlist_find_client_by_id(server->local_list,
1455 client_id, TRUE, &cache);
1457 silc_free(client_id);
1461 silc_free(client_id);
1463 /* If the client is one of ours, then close the connection to the
1464 client now. This removes the client from all channels as well. */
1465 if (packet->dst_id_type == SILC_ID_CLIENT && client->connection) {
1466 sock = client->connection;
1467 silc_server_free_client_data(server, NULL, client, FALSE, NULL);
1468 silc_server_close_connection(server, sock);
1473 comment = silc_argument_get_arg_type(args, 2, &comment_len);
1474 if (comment_len > 128)
1477 /* From protocol version 1.1 we get the killer's ID as well. */
1478 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1480 client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
1484 if (id_type == SILC_ID_CLIENT) {
1485 /* If the the client is not in local list we check global list */
1486 client2 = silc_idlist_find_client_by_id(server->global_list,
1487 client_id, TRUE, NULL);
1489 client2 = silc_idlist_find_client_by_id(server->local_list,
1490 client_id, TRUE, NULL);
1492 silc_free(client_id);
1496 silc_free(client_id);
1498 /* Killer must be router operator */
1499 if (server->server_type != SILC_SERVER &&
1500 !(client2->mode & SILC_UMODE_ROUTER_OPERATOR)) {
1501 SILC_LOG_DEBUG(("Killing is not allowed"));
1507 /* Send the notify to local clients on the channels except to the
1508 client who is killed. */
1509 silc_server_send_notify_on_channels(server, client, client,
1510 SILC_NOTIFY_TYPE_KILLED, 3,
1511 id, id_len, comment, comment_len,
1514 /* Remove the client from all channels */
1515 silc_server_remove_from_channels(server, NULL, client, FALSE, NULL,
1518 /* Check if anyone is watching this nickname */
1519 silc_server_check_watcher_list(server, client, NULL,
1520 SILC_NOTIFY_TYPE_KILLED);
1522 /* Update statistics */
1523 server->stat.clients--;
1524 if (server->stat.cell_clients)
1525 server->stat.cell_clients--;
1526 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
1527 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
1529 if (SILC_IS_LOCAL(client)) {
1530 server->stat.my_clients--;
1531 silc_schedule_task_del_by_context(server->schedule, client);
1532 silc_idlist_del_data(client);
1536 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
1537 cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
1541 case SILC_NOTIFY_TYPE_UMODE_CHANGE:
1543 * Save the mode of the client.
1546 SILC_LOG_DEBUG(("UMODE_CHANGE notify"));
1549 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1552 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1556 /* Get client entry */
1557 client = silc_idlist_find_client_by_id(server->global_list,
1558 client_id, TRUE, NULL);
1560 client = silc_idlist_find_client_by_id(server->local_list,
1561 client_id, TRUE, NULL);
1563 silc_free(client_id);
1567 silc_free(client_id);
1570 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1573 SILC_GET32_MSB(mode, tmp);
1575 /* Remove internal resumed flag if client is marked detached now */
1576 if (mode & SILC_UMODE_DETACHED)
1577 client->data.status &= ~SILC_IDLIST_STATUS_RESUMED;
1579 /* Update statistics */
1580 if (server->server_type == SILC_ROUTER) {
1581 if (mode & SILC_UMODE_GONE) {
1582 if (!(client->mode & SILC_UMODE_GONE))
1583 server->stat.aways++;
1585 if (client->mode & SILC_UMODE_GONE)
1586 server->stat.aways--;
1588 if (mode & SILC_UMODE_DETACHED) {
1589 if (!(client->mode & SILC_UMODE_DETACHED))
1590 server->stat.detached++;
1592 if (client->mode & SILC_UMODE_DETACHED)
1593 server->stat.detached--;
1596 SILC_UMODE_STATS_UPDATE(server, SILC_UMODE_SERVER_OPERATOR);
1597 SILC_UMODE_STATS_UPDATE(router, SILC_UMODE_ROUTER_OPERATOR);
1599 /* Change the mode */
1600 client->mode = mode;
1602 /* Check if anyone is watching this nickname */
1603 if (server->server_type == SILC_ROUTER)
1604 silc_server_check_watcher_list(server, client, NULL,
1605 SILC_NOTIFY_TYPE_UMODE_CHANGE);
1609 case SILC_NOTIFY_TYPE_BAN:
1614 SILC_LOG_DEBUG(("BAN notify"));
1616 /* Get Channel ID */
1617 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1620 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1624 /* Get channel entry */
1625 channel = silc_idlist_find_channel_by_id(server->global_list,
1628 channel = silc_idlist_find_channel_by_id(server->local_list,
1631 SILC_LOG_DEBUG(("Notify for unknown channel"));
1632 silc_free(channel_id);
1636 silc_free(channel_id);
1638 /* Get the new ban and add it to the ban list */
1639 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1641 if (!channel->ban_list)
1642 channel->ban_list = silc_calloc(tmp_len + 2,
1643 sizeof(*channel->ban_list));
1645 channel->ban_list = silc_realloc(channel->ban_list,
1646 sizeof(*channel->ban_list) *
1648 strlen(channel->ban_list) + 2));
1649 strncat(channel->ban_list, tmp, tmp_len);
1650 strncat(channel->ban_list, ",", 1);
1653 /* Get the ban to be removed and remove it from the list */
1654 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1655 if (tmp && channel->ban_list) {
1656 char *start, *end, *n;
1658 if (!strncmp(channel->ban_list, tmp, strlen(channel->ban_list) - 1)) {
1659 silc_free(channel->ban_list);
1660 channel->ban_list = NULL;
1662 start = strstr(channel->ban_list, tmp);
1663 if (start && strlen(start) >= tmp_len) {
1664 end = start + tmp_len;
1665 n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
1666 strncat(n, channel->ban_list, start - channel->ban_list);
1667 strncat(n, end + 1, ((channel->ban_list +
1668 strlen(channel->ban_list)) - end) - 1);
1669 silc_free(channel->ban_list);
1670 channel->ban_list = n;
1676 case SILC_NOTIFY_TYPE_ERROR:
1683 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1684 if (!tmp && tmp_len != 1)
1686 error = (SilcStatus)tmp[0];
1688 SILC_LOG_DEBUG(("ERROR notify (%d)", error));
1690 if (error == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID &&
1691 sock->type == SILC_SOCKET_TYPE_ROUTER) {
1692 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1694 SILC_LOG_DEBUG(("Received invalid client ID notification, deleting "
1695 "the entry from cache"));
1696 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1699 client = silc_idlist_find_client_by_id(server->global_list,
1700 client_id, FALSE, NULL);
1702 silc_server_remove_from_channels(server, NULL, client, TRUE,
1704 silc_idlist_del_data(client);
1705 silc_idlist_del_client(server->global_list, client);
1707 silc_free(client_id);
1713 /* Ignore rest of the notify types for now */
1714 case SILC_NOTIFY_TYPE_NONE:
1715 case SILC_NOTIFY_TYPE_MOTD:
1722 silc_notify_payload_free(payload);
1725 void silc_server_notify_list(SilcServer server,
1726 SilcSocketConnection sock,
1727 SilcPacketContext *packet)
1729 SilcPacketContext *new;
1733 SILC_LOG_DEBUG(("Processing Notify List"));
1735 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1736 packet->src_id_type != SILC_ID_SERVER)
1739 /* Make copy of the original packet context, except for the actual
1740 data buffer, which we will here now fetch from the original buffer. */
1741 new = silc_packet_context_alloc();
1742 new->type = SILC_PACKET_NOTIFY;
1743 new->flags = packet->flags;
1744 new->src_id = packet->src_id;
1745 new->src_id_len = packet->src_id_len;
1746 new->src_id_type = packet->src_id_type;
1747 new->dst_id = packet->dst_id;
1748 new->dst_id_len = packet->dst_id_len;
1749 new->dst_id_type = packet->dst_id_type;
1751 buffer = silc_buffer_alloc(1024);
1752 new->buffer = buffer;
1754 while (packet->buffer->len) {
1755 SILC_GET16_MSB(len, packet->buffer->data + 2);
1756 if (len > packet->buffer->len)
1759 if (len > buffer->truelen) {
1760 silc_buffer_free(buffer);
1761 buffer = silc_buffer_alloc(1024 + len);
1764 silc_buffer_pull_tail(buffer, len);
1765 silc_buffer_put(buffer, packet->buffer->data, len);
1767 /* Process the Notify */
1768 silc_server_notify(server, sock, new);
1770 silc_buffer_push_tail(buffer, len);
1771 silc_buffer_pull(packet->buffer, len);
1774 silc_buffer_free(buffer);
1778 /* Received private message. This resolves the destination of the message
1779 and sends the packet. This is used by both server and router. If the
1780 destination is our locally connected client this sends the packet to
1781 the client. This may also send the message for further routing if
1782 the destination is not in our server (or router). */
1784 void silc_server_private_message(SilcServer server,
1785 SilcSocketConnection sock,
1786 SilcPacketContext *packet)
1788 SilcSocketConnection dst_sock;
1789 SilcIDListData idata;
1790 SilcClientEntry client;
1792 SILC_LOG_DEBUG(("Start"));
1794 if (packet->src_id_type != SILC_ID_CLIENT ||
1795 packet->dst_id_type != SILC_ID_CLIENT || !packet->dst_id)
1798 /* Get the route to the client */
1799 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1800 packet->dst_id_len, NULL,
1804 unsigned char error;
1806 if (client && client->mode & SILC_UMODE_DETACHED) {
1807 SILC_LOG_DEBUG(("Client is detached, discarding packet"));
1811 /* Send SILC_NOTIFY_TYPE_ERROR to indicate that such destination ID
1812 does not exist or is invalid. */
1813 idp = silc_id_payload_encode_data(packet->dst_id,
1815 packet->dst_id_type);
1819 error = SILC_STATUS_ERR_NO_SUCH_CLIENT_ID;
1820 if (packet->src_id_type == SILC_ID_CLIENT) {
1821 SilcClientID *client_id = silc_id_str2id(packet->src_id,
1823 packet->src_id_type);
1824 silc_server_send_notify_dest(server, sock, FALSE,
1825 client_id, SILC_ID_CLIENT,
1826 SILC_NOTIFY_TYPE_ERROR, 2,
1828 idp->data, idp->len);
1829 silc_free(client_id);
1831 silc_server_send_notify(server, sock, FALSE,
1832 SILC_NOTIFY_TYPE_ERROR, 2,
1834 idp->data, idp->len);
1837 silc_buffer_free(idp);
1841 /* Check whether destination client wishes to receive private messages */
1842 if (client && !(packet->flags & SILC_PACKET_FLAG_PRIVMSG_KEY) &&
1843 client->mode & SILC_UMODE_BLOCK_PRIVMSG) {
1844 SILC_LOG_DEBUG(("Client blocks private messages, discarding packet"));
1848 /* Send the private message */
1849 silc_server_send_private_message(server, dst_sock, idata->send_key,
1850 idata->hmac_send, idata->psn_send++,
1854 /* Received private message key packet.. This packet is never for us. It is to
1855 the client in the packet's destination ID. Sending of this sort of packet
1856 equals sending private message, ie. it is sent point to point from
1857 one client to another. */
1859 void silc_server_private_message_key(SilcServer server,
1860 SilcSocketConnection sock,
1861 SilcPacketContext *packet)
1863 SilcSocketConnection dst_sock;
1864 SilcIDListData idata;
1866 SILC_LOG_DEBUG(("Start"));
1868 if (packet->src_id_type != SILC_ID_CLIENT ||
1869 packet->dst_id_type != SILC_ID_CLIENT)
1872 if (!packet->dst_id)
1875 /* Get the route to the client */
1876 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1877 packet->dst_id_len, NULL,
1882 /* Relay the packet */
1883 silc_server_relay_packet(server, dst_sock, idata->send_key,
1884 idata->hmac_send, idata->psn_send++, packet, FALSE);
1887 /* Processes incoming command reply packet. The command reply packet may
1888 be destined to one of our clients or it may directly for us. We will
1889 call the command reply routine after processing the packet. */
1891 void silc_server_command_reply(SilcServer server,
1892 SilcSocketConnection sock,
1893 SilcPacketContext *packet)
1895 SilcBuffer buffer = packet->buffer;
1896 SilcClientEntry client = NULL;
1897 SilcSocketConnection dst_sock;
1898 SilcIDListData idata;
1899 SilcClientID *id = NULL;
1901 SILC_LOG_DEBUG(("Start"));
1903 if (packet->dst_id_type == SILC_ID_CHANNEL)
1906 if (packet->dst_id_type == SILC_ID_CLIENT) {
1907 /* Destination must be one of ours */
1908 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
1911 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
1913 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
1919 if (packet->dst_id_type == SILC_ID_SERVER) {
1920 /* For now this must be for us */
1921 if (memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
1922 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
1927 /* Execute command reply locally for the command */
1928 silc_server_command_reply_process(server, sock, buffer);
1930 if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
1931 /* Relay the packet to the client */
1932 const SilcBufferStruct p;
1934 dst_sock = (SilcSocketConnection)client->connection;
1935 idata = (SilcIDListData)client;
1937 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
1938 + packet->dst_id_len + packet->padlen);
1939 if (!silc_packet_send_prepare(dst_sock, 0, 0, buffer->len,
1940 idata->hmac_send, (const SilcBuffer)&p)) {
1941 SILC_LOG_ERROR(("Cannot send packet"));
1944 silc_buffer_put((SilcBuffer)&p, buffer->data, buffer->len);
1946 /* Encrypt packet */
1947 silc_packet_encrypt(idata->send_key, idata->hmac_send, idata->psn_send++,
1948 (SilcBuffer)&p, buffer->len);
1950 /* Send the packet */
1951 silc_server_packet_send_real(server, dst_sock, TRUE);
1957 /* Process received channel message. The message can be originated from
1958 client or server. */
1960 void silc_server_channel_message(SilcServer server,
1961 SilcSocketConnection sock,
1962 SilcPacketContext *packet)
1964 SilcChannelEntry channel = NULL;
1965 SilcChannelID *id = NULL;
1966 void *sender_id = NULL;
1967 SilcClientEntry sender_entry = NULL;
1968 SilcChannelClientEntry chl;
1971 SILC_LOG_DEBUG(("Processing channel message"));
1974 if (packet->dst_id_type != SILC_ID_CHANNEL) {
1975 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1979 /* Find channel entry */
1980 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
1983 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
1985 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
1988 unsigned char error;
1990 /* Send SILC_NOTIFY_TYPE_ERROR to indicate that such destination ID
1991 does not exist or is invalid. */
1992 idp = silc_id_payload_encode_data(packet->dst_id,
1994 packet->dst_id_type);
1998 error = SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID;
1999 if (packet->src_id_type == SILC_ID_CLIENT) {
2000 SilcClientID *client_id = silc_id_str2id(packet->src_id,
2002 packet->src_id_type);
2003 silc_server_send_notify_dest(server, sock, FALSE,
2004 client_id, SILC_ID_CLIENT,
2005 SILC_NOTIFY_TYPE_ERROR, 2,
2006 &error, 1, idp->data, idp->len);
2007 silc_free(client_id);
2009 silc_server_send_notify(server, sock, FALSE,
2010 SILC_NOTIFY_TYPE_ERROR, 2,
2011 &error, 1, idp->data, idp->len);
2014 silc_buffer_free(idp);
2019 /* See that this client is on the channel. If the original sender is
2020 not client (as it can be server as well) we don't do the check. */
2021 sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2022 packet->src_id_type);
2025 if (packet->src_id_type == SILC_ID_CLIENT) {
2026 sender_entry = silc_idlist_find_client_by_id(server->local_list,
2027 sender_id, TRUE, NULL);
2028 if (!sender_entry) {
2030 sender_entry = silc_idlist_find_client_by_id(server->global_list,
2031 sender_id, TRUE, NULL);
2033 if (!sender_entry || !silc_server_client_on_channel(sender_entry,
2035 SILC_LOG_DEBUG(("Client not on channel"));
2039 /* If channel is moderated check that client is allowed to send
2041 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS &&
2042 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
2043 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
2044 SILC_LOG_DEBUG(("Channel is silenced from normal users"));
2047 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS &&
2048 chl->mode & SILC_CHANNEL_UMODE_CHANOP &&
2049 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
2050 SILC_LOG_DEBUG(("Channel is silenced from operators"));
2053 if (chl->mode & SILC_CHANNEL_UMODE_QUIET) {
2054 SILC_LOG_DEBUG(("Sender is quieted on the channel"));
2058 /* If the packet is coming from router, but the client entry is local
2059 entry to us then some router is rerouting this to us and it is not
2060 allowed. When the client is local to us it means that we've routed
2061 this packet to network, and now someone is routing it back to us. */
2062 if (server->server_type == SILC_ROUTER &&
2063 sock->type == SILC_SOCKET_TYPE_ROUTER && local) {
2064 SILC_LOG_DEBUG(("Channel message rerouted to the sender, drop it"));
2069 /* Distribute the packet to our local clients. This will send the
2070 packet for further routing as well, if needed. */
2071 silc_server_packet_relay_to_channel(server, sock, channel, sender_id,
2072 packet->src_id_type, sender_entry,
2073 packet->buffer->data,
2074 packet->buffer->len, FALSE);
2077 silc_free(sender_id);
2081 /* Received channel key packet. We distribute the key to all of our locally
2082 connected clients on the channel. */
2084 void silc_server_channel_key(SilcServer server,
2085 SilcSocketConnection sock,
2086 SilcPacketContext *packet)
2088 SilcBuffer buffer = packet->buffer;
2089 SilcChannelEntry channel;
2091 if (packet->src_id_type != SILC_ID_SERVER ||
2092 (server->server_type == SILC_ROUTER &&
2093 sock->type == SILC_SOCKET_TYPE_ROUTER))
2096 /* Save the channel key */
2097 channel = silc_server_save_channel_key(server, buffer, NULL);
2101 /* Distribute the key to everybody who is on the channel. If we are router
2102 we will also send it to locally connected servers. */
2103 silc_server_send_channel_key(server, sock, channel, FALSE);
2105 if (server->server_type != SILC_BACKUP_ROUTER) {
2106 /* Distribute to local cell backup routers. */
2107 silc_server_backup_send(server, sock->user_data,
2108 SILC_PACKET_CHANNEL_KEY, 0,
2109 buffer->data, buffer->len, FALSE, TRUE);
2113 /* Received New Client packet and processes it. Creates Client ID for the
2114 client. Client becomes registered after calling this functions. */
2116 SilcClientEntry silc_server_new_client(SilcServer server,
2117 SilcSocketConnection sock,
2118 SilcPacketContext *packet)
2120 SilcBuffer buffer = packet->buffer;
2121 SilcClientEntry client;
2122 SilcClientID *client_id;
2123 SilcIDListData idata;
2124 char *username = NULL, *realname = NULL;
2125 SilcUInt16 username_len;
2128 char *hostname, *nickname;
2131 SILC_LOG_DEBUG(("Creating new client"));
2133 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
2136 /* Take client entry */
2137 client = (SilcClientEntry)sock->user_data;
2138 idata = (SilcIDListData)client;
2140 /* Remove the old cache entry. */
2141 if (!silc_idcache_del_by_context(server->local_list->clients, client)) {
2142 SILC_LOG_INFO(("Unauthenticated client attempted to register to network"));
2143 silc_server_disconnect_remote(server, sock,
2144 SILC_STATUS_ERR_NOT_AUTHENTICATED, NULL);
2145 if (sock->user_data)
2146 silc_server_free_sock_user_data(server, sock, NULL);
2150 /* Parse incoming packet */
2151 ret = silc_buffer_unformat(buffer,
2152 SILC_STR_UI16_NSTRING_ALLOC(&username,
2154 SILC_STR_UI16_STRING_ALLOC(&realname),
2157 silc_free(username);
2158 silc_free(realname);
2159 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2160 "connection", sock->hostname, sock->ip));
2161 silc_server_disconnect_remote(server, sock,
2162 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2164 if (sock->user_data)
2165 silc_server_free_sock_user_data(server, sock, NULL);
2170 silc_free(username);
2171 silc_free(realname);
2172 SILC_LOG_ERROR(("Client %s (%s) did not send its username, closing "
2173 "connection", sock->hostname, sock->ip));
2174 silc_server_disconnect_remote(server, sock,
2175 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2177 if (sock->user_data)
2178 silc_server_free_sock_user_data(server, sock, NULL);
2182 if (username_len > 128)
2183 username[128] = '\0';
2185 /* Check for bad characters for nickname, and modify the nickname if
2186 it includes those. */
2187 if (silc_server_name_bad_chars(username, username_len)) {
2188 nickname = silc_server_name_modify_bad(username, username_len);
2190 nickname = strdup(username);
2193 /* Make sanity checks for the hostname of the client. If the hostname
2194 is provided in the `username' check that it is the same than the
2195 resolved hostname, or if not resolved the hostname that appears in
2196 the client's public key. If the hostname is not present then put
2197 it from the resolved name or from the public key. */
2198 if (strchr(username, '@')) {
2199 SilcPublicKeyIdentifier pident;
2200 int tlen = strcspn(username, "@");
2201 char *phostname = NULL;
2203 hostname = silc_memdup(username + tlen + 1, strlen(username) - tlen - 1);
2205 if (strcmp(sock->hostname, sock->ip) &&
2206 strcmp(sock->hostname, hostname)) {
2207 silc_free(username);
2208 silc_free(hostname);
2209 silc_free(realname);
2210 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2211 "connection", sock->hostname, sock->ip));
2212 silc_server_disconnect_remote(server, sock,
2213 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2215 if (sock->user_data)
2216 silc_server_free_sock_user_data(server, sock, NULL);
2220 pident = silc_pkcs_decode_identifier(client->data.public_key->identifier);
2222 phostname = strdup(pident->host);
2223 silc_pkcs_free_identifier(pident);
2226 if (!strcmp(sock->hostname, sock->ip) &&
2227 phostname && strcmp(phostname, hostname)) {
2228 silc_free(username);
2229 silc_free(hostname);
2230 silc_free(phostname);
2231 silc_free(realname);
2232 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2233 "connection", sock->hostname, sock->ip));
2234 silc_server_disconnect_remote(server, sock,
2235 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2237 if (sock->user_data)
2238 silc_server_free_sock_user_data(server, sock, NULL);
2242 silc_free(phostname);
2244 /* The hostname is not present, add it. */
2246 /* XXX For now we cannot take the host name from the public key since
2247 they are not trusted or we cannot verify them as trusted. Just take
2248 what the resolved name or address is. */
2250 if (strcmp(sock->hostname, sock->ip)) {
2252 newusername = silc_calloc(strlen(username) +
2253 strlen(sock->hostname) + 2,
2254 sizeof(*newusername));
2255 strncat(newusername, username, strlen(username));
2256 strncat(newusername, "@", 1);
2257 strncat(newusername, sock->hostname, strlen(sock->hostname));
2258 silc_free(username);
2259 username = newusername;
2262 SilcPublicKeyIdentifier pident =
2263 silc_pkcs_decode_identifier(client->data.public_key->identifier);
2266 newusername = silc_calloc(strlen(username) +
2267 strlen(pident->host) + 2,
2268 sizeof(*newusername));
2269 strncat(newusername, username, strlen(username));
2270 strncat(newusername, "@", 1);
2271 strncat(newusername, pident->host, strlen(pident->host));
2272 silc_free(username);
2273 username = newusername;
2274 silc_pkcs_free_identifier(pident);
2280 /* Create Client ID */
2281 while (!silc_id_create_client_id(server, server->id, server->rng,
2282 server->md5hash, nickname, &client_id)) {
2285 silc_server_disconnect_remote(server, sock,
2286 SILC_STATUS_ERR_BAD_NICKNAME, NULL);
2287 if (sock->user_data)
2288 silc_server_free_sock_user_data(server, sock, NULL);
2291 snprintf(&nickname[strlen(nickname) - 1], 1, "%d", nickfail);
2294 /* If client marked as anonymous, scramble the username and hostname */
2295 if (client->mode & SILC_UMODE_ANONYMOUS) {
2298 if (strlen(username) >= 2) {
2299 username[0] = silc_rng_get_byte_fast(server->rng);
2300 username[1] = silc_rng_get_byte_fast(server->rng);
2303 scramble = silc_hash_babbleprint(server->sha1hash, username,
2307 memcpy(&scramble[16], ".silc", 5);
2308 scramble[21] = '\0';
2309 silc_free(username);
2310 username = scramble;
2313 /* Update client entry */
2314 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
2315 client->nickname = nickname;
2316 client->username = username;
2317 client->userinfo = realname ? realname : strdup(" ");
2318 client->id = client_id;
2319 id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
2321 /* Add the client again to the ID cache */
2322 silc_idcache_add(server->local_list->clients, client->nickname,
2323 client_id, client, 0, NULL);
2325 /* Notify our router about new client on the SILC network */
2326 silc_server_send_new_id(server, SILC_PRIMARY_ROUTE(server),
2327 SILC_BROADCAST(server), client->id,
2328 SILC_ID_CLIENT, id_len);
2330 /* Distribute to backup routers */
2331 if (server->server_type == SILC_ROUTER) {
2332 SilcBuffer idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
2333 silc_server_backup_send(server, sock->user_data, SILC_PACKET_NEW_ID, 0,
2334 idp->data, idp->len, FALSE, TRUE);
2335 silc_buffer_free(idp);
2338 /* Send the new client ID to the client. */
2339 silc_server_send_new_id(server, sock, FALSE, client->id, SILC_ID_CLIENT,
2340 silc_id_get_len(client->id, SILC_ID_CLIENT));
2342 /* Send some nice info to the client */
2343 silc_server_send_connect_notifys(server, sock, client);
2345 /* Check if anyone is watching this nickname */
2346 if (server->server_type == SILC_ROUTER)
2347 silc_server_check_watcher_list(server, client, NULL, 0);
2352 /* Create new server. This processes received New Server packet and
2353 saves the received Server ID. The server is our locally connected
2354 server thus we save all the information and save it to local list.
2355 This funtion can be used by both normal server and router server.
2356 If normal server uses this it means that its router has connected
2357 to the server. If router uses this it means that one of the cell's
2358 servers is connected to the router. */
2360 SilcServerEntry silc_server_new_server(SilcServer server,
2361 SilcSocketConnection sock,
2362 SilcPacketContext *packet)
2364 SilcBuffer buffer = packet->buffer;
2365 SilcServerEntry new_server, server_entry;
2366 SilcServerID *server_id;
2367 SilcIDListData idata;
2368 unsigned char *server_name, *id_string;
2369 SilcUInt16 id_len, name_len;
2373 SILC_LOG_DEBUG(("Creating new server"));
2375 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
2376 sock->type != SILC_SOCKET_TYPE_ROUTER)
2379 /* Take server entry */
2380 new_server = (SilcServerEntry)sock->user_data;
2381 idata = (SilcIDListData)new_server;
2383 /* Remove the old cache entry */
2384 if (!silc_idcache_del_by_context(server->local_list->servers, new_server)) {
2385 if (!silc_idcache_del_by_context(server->global_list->servers,
2387 SILC_LOG_INFO(("Unauthenticated %s attempted to register to "
2388 "network", (sock->type == SILC_SOCKET_TYPE_SERVER ?
2389 "server" : "router")));
2390 silc_server_disconnect_remote(server, sock,
2391 SILC_STATUS_ERR_NOT_AUTHENTICATED, NULL);
2392 if (sock->user_data)
2393 silc_server_free_sock_user_data(server, sock, NULL);
2399 /* Parse the incoming packet */
2400 ret = silc_buffer_unformat(buffer,
2401 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
2402 SILC_STR_UI16_NSTRING_ALLOC(&server_name,
2406 silc_free(id_string);
2407 silc_free(server_name);
2408 silc_server_disconnect_remote(server, sock,
2409 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2411 if (sock->user_data)
2412 silc_server_free_sock_user_data(server, sock, NULL);
2416 if (id_len > buffer->len) {
2417 silc_free(id_string);
2418 silc_free(server_name);
2419 silc_server_disconnect_remote(server, sock,
2420 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2422 if (sock->user_data)
2423 silc_server_free_sock_user_data(server, sock, NULL);
2428 server_name[255] = '\0';
2431 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
2433 silc_free(id_string);
2434 silc_free(server_name);
2435 silc_server_disconnect_remote(server, sock,
2436 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2438 if (sock->user_data)
2439 silc_server_free_sock_user_data(server, sock, NULL);
2442 silc_free(id_string);
2444 /* Check for valid server ID */
2445 if (!silc_id_is_valid_server_id(server, server_id, sock)) {
2446 SILC_LOG_INFO(("Invalid server ID sent by %s (%s)",
2447 sock->ip, sock->hostname));
2448 silc_server_disconnect_remote(server, sock,
2449 SILC_STATUS_ERR_BAD_SERVER_ID, NULL);
2450 if (sock->user_data)
2451 silc_server_free_sock_user_data(server, sock, NULL);
2452 silc_free(server_name);
2456 /* Check that we do not have this ID already */
2457 server_entry = silc_idlist_find_server_by_id(server->local_list,
2458 server_id, TRUE, NULL);
2460 silc_idcache_del_by_context(server->local_list->servers, server_entry);
2462 server_entry = silc_idlist_find_server_by_id(server->global_list,
2463 server_id, TRUE, NULL);
2465 silc_idcache_del_by_context(server->global_list->servers, server_entry);
2468 /* Update server entry */
2469 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
2470 new_server->server_name = server_name;
2471 new_server->id = server_id;
2473 SILC_LOG_DEBUG(("New server id(%s)",
2474 silc_id_render(server_id, SILC_ID_SERVER)));
2476 /* Add again the entry to the ID cache. */
2477 silc_idcache_add(local ? server->local_list->servers :
2478 server->global_list->servers, server_name, server_id,
2479 new_server, 0, NULL);
2481 /* Distribute the information about new server in the SILC network
2482 to our router. If we are normal server we won't send anything
2483 since this connection must be our router connection. */
2484 if (server->server_type == SILC_ROUTER && !server->standalone &&
2485 SILC_PRIMARY_ROUTE(server) != sock)
2486 silc_server_send_new_id(server, SILC_PRIMARY_ROUTE(server),
2487 TRUE, new_server->id, SILC_ID_SERVER,
2488 silc_id_get_len(server_id, SILC_ID_SERVER));
2490 if (server->server_type == SILC_ROUTER) {
2491 /* Distribute to backup routers */
2492 SilcBuffer idp = silc_id_payload_encode(new_server->id, SILC_ID_SERVER);
2493 silc_server_backup_send(server, sock->user_data, SILC_PACKET_NEW_ID, 0,
2494 idp->data, idp->len, FALSE, TRUE);
2495 silc_buffer_free(idp);
2498 server->stat.cell_servers++;
2501 /* Check whether this router connection has been replaced by an
2502 backup router. If it has been then we'll disable the server and will
2503 ignore everything it will send until the backup router resuming
2504 protocol has been completed. */
2505 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
2506 silc_server_backup_replaced_get(server, server_id, NULL)) {
2507 /* Send packet to the server indicating that it cannot use this
2508 connection as it has been replaced by backup router. */
2509 SilcBuffer packet = silc_buffer_alloc(2);
2510 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
2511 silc_buffer_format(packet,
2512 SILC_STR_UI_CHAR(SILC_SERVER_BACKUP_REPLACED),
2513 SILC_STR_UI_CHAR(0),
2515 silc_server_packet_send(server, sock,
2516 SILC_PACKET_RESUME_ROUTER, 0,
2517 packet->data, packet->len, TRUE);
2518 silc_buffer_free(packet);
2520 /* Mark the router disabled. The data sent earlier will go but nothing
2521 after this does not go to this connection. */
2522 idata->status |= SILC_IDLIST_STATUS_DISABLED;
2524 /* If it is router announce our stuff to it. */
2525 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
2526 server->server_type == SILC_ROUTER) {
2527 silc_server_announce_servers(server, FALSE, 0, sock);
2528 silc_server_announce_clients(server, 0, sock);
2529 silc_server_announce_channels(server, 0, sock);
2532 /* Announce our information to backup router */
2533 if (new_server->server_type == SILC_BACKUP_ROUTER &&
2534 sock->type == SILC_SOCKET_TYPE_SERVER &&
2535 server->server_type == SILC_ROUTER) {
2536 silc_server_announce_servers(server, TRUE, 0, sock);
2537 silc_server_announce_clients(server, 0, sock);
2538 silc_server_announce_channels(server, 0, sock);
2541 /* If backup router, mark it as one of ours. This server is considered
2542 to be backup router after this setting. */
2543 if (new_server->server_type == SILC_BACKUP_ROUTER) {
2544 SilcServerConfigRouter *backup;
2545 backup = silc_server_config_find_backup_conn(server, sock->ip);
2547 backup = silc_server_config_find_backup_conn(server, sock->hostname);
2549 /* Add as our backup router */
2550 silc_server_backup_add(server, new_server, backup->backup_replace_ip,
2551 backup->backup_replace_port,
2552 backup->backup_local);
2556 /* By default the servers connected to backup router are disabled
2557 until backup router has become the primary */
2558 if (server->server_type == SILC_BACKUP_ROUTER &&
2559 sock->type == SILC_SOCKET_TYPE_SERVER)
2560 idata->status |= SILC_IDLIST_STATUS_DISABLED;
2566 /* Processes incoming New ID packet. New ID Payload is used to distribute
2567 information about newly registered clients and servers. */
2569 static void silc_server_new_id_real(SilcServer server,
2570 SilcSocketConnection sock,
2571 SilcPacketContext *packet,
2574 SilcBuffer buffer = packet->buffer;
2576 SilcServerEntry router, server_entry;
2577 SilcSocketConnection router_sock;
2582 SILC_LOG_DEBUG(("Processing new ID"));
2584 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2585 server->server_type == SILC_SERVER ||
2586 packet->src_id_type != SILC_ID_SERVER)
2589 idp = silc_id_payload_parse(buffer->data, buffer->len);
2593 id_type = silc_id_payload_get_type(idp);
2595 /* Normal server cannot have other normal server connections */
2596 server_entry = (SilcServerEntry)sock->user_data;
2597 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER &&
2598 server_entry->server_type == SILC_SERVER)
2601 id = silc_id_payload_get_id(idp);
2605 /* If the packet is coming from server then use the sender as the
2606 origin of the the packet. If it came from router then check the real
2607 sender of the packet and use that as the origin. */
2608 if (sock->type == SILC_SOCKET_TYPE_SERVER) {
2609 id_list = server->local_list;
2611 router = sock->user_data;
2613 /* If the sender is backup router and ID is server (and we are not
2614 backup router) then switch the entry to global list. */
2615 if (server_entry->server_type == SILC_BACKUP_ROUTER &&
2616 id_type == SILC_ID_SERVER &&
2617 server->id_entry->server_type != SILC_BACKUP_ROUTER) {
2618 id_list = server->global_list;
2619 router_sock = server->router ? SILC_PRIMARY_ROUTE(server) : sock;
2622 void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2623 packet->src_id_type);
2624 router = silc_idlist_find_server_by_id(server->global_list,
2625 sender_id, TRUE, NULL);
2627 router = silc_idlist_find_server_by_id(server->local_list,
2628 sender_id, TRUE, NULL);
2629 silc_free(sender_id);
2631 id_list = server->global_list;
2638 case SILC_ID_CLIENT:
2640 SilcClientEntry entry;
2642 /* Check that we do not have this client already */
2643 entry = silc_idlist_find_client_by_id(server->global_list,
2644 id, server->server_type,
2647 entry = silc_idlist_find_client_by_id(server->local_list,
2648 id, server->server_type,
2651 SILC_LOG_DEBUG(("Ignoring client that we already have"));
2655 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
2656 silc_id_render(id, SILC_ID_CLIENT),
2657 sock->type == SILC_SOCKET_TYPE_SERVER ?
2658 "Server" : "Router", sock->hostname));
2660 /* As a router we keep information of all global information in our
2661 global list. Cell wide information however is kept in the local
2663 entry = silc_idlist_add_client(id_list, NULL, NULL, NULL,
2664 id, router, NULL, 0);
2666 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
2668 /* Inform the sender that the ID is not usable */
2669 silc_server_send_notify_signoff(server, sock, FALSE, id, NULL);
2672 entry->nickname = NULL;
2673 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2675 if (sock->type == SILC_SOCKET_TYPE_SERVER)
2676 server->stat.cell_clients++;
2677 server->stat.clients++;
2679 /* Check if anyone is watching this nickname */
2680 if (server->server_type == SILC_ROUTER && id_list == server->local_list)
2681 silc_server_check_watcher_list(server, entry, NULL, 0);
2685 case SILC_ID_SERVER:
2687 SilcServerEntry entry;
2689 /* If the ID is mine, ignore it. */
2690 if (SILC_ID_SERVER_COMPARE(id, server->id)) {
2691 SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
2695 /* If the ID is the sender's ID, ignore it (we have it already) */
2696 if (SILC_ID_SERVER_COMPARE(id, router->id)) {
2697 SILC_LOG_DEBUG(("Ignoring sender's own ID"));
2701 /* Check that we do not have this server already */
2702 entry = silc_idlist_find_server_by_id(server->global_list,
2703 id, server->server_type,
2706 entry = silc_idlist_find_server_by_id(server->local_list,
2707 id, server->server_type,
2710 SILC_LOG_DEBUG(("Ignoring server that we already have"));
2714 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
2715 silc_id_render(id, SILC_ID_SERVER),
2716 sock->type == SILC_SOCKET_TYPE_SERVER ?
2717 "Server" : "Router", sock->hostname));
2719 /* As a router we keep information of all global information in our
2720 global list. Cell wide information however is kept in the local
2722 entry = silc_idlist_add_server(id_list, NULL, 0, id, router,
2725 SILC_LOG_ERROR(("Could not add new server to the ID Cache"));
2728 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2730 if (sock->type == SILC_SOCKET_TYPE_SERVER)
2731 server->stat.cell_servers++;
2732 server->stat.servers++;
2736 case SILC_ID_CHANNEL:
2737 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
2746 /* If the sender of this packet is server and we are router we need to
2747 broadcast this packet to other routers in the network. */
2748 if (broadcast && server->server_type == SILC_ROUTER &&
2749 sock->type == SILC_SOCKET_TYPE_SERVER &&
2750 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2751 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
2752 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
2754 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2755 buffer->data, buffer->len, FALSE);
2756 silc_server_backup_send(server, sock->user_data,
2757 packet->type, packet->flags,
2758 packet->buffer->data, packet->buffer->len,
2763 silc_id_payload_free(idp);
2767 /* Processes incoming New ID packet. New ID Payload is used to distribute
2768 information about newly registered clients and servers. */
2770 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
2771 SilcPacketContext *packet)
2773 silc_server_new_id_real(server, sock, packet, TRUE);
2776 /* Receoved New Id List packet, list of New ID payloads inside one
2777 packet. Process the New ID payloads one by one. */
2779 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
2780 SilcPacketContext *packet)
2782 SilcPacketContext *new_id;
2786 SILC_LOG_DEBUG(("Processing New ID List"));
2788 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2789 packet->src_id_type != SILC_ID_SERVER)
2792 /* If the sender of this packet is server and we are router we need to
2793 broadcast this packet to other routers in the network. Broadcast
2794 this list packet instead of multiple New ID packets. */
2795 if (server->server_type == SILC_ROUTER &&
2796 sock->type == SILC_SOCKET_TYPE_SERVER &&
2797 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2798 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
2799 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
2801 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2802 packet->buffer->data,
2803 packet->buffer->len, FALSE);
2804 silc_server_backup_send(server, sock->user_data,
2805 packet->type, packet->flags,
2806 packet->buffer->data, packet->buffer->len,
2810 /* Make copy of the original packet context, except for the actual
2811 data buffer, which we will here now fetch from the original buffer. */
2812 new_id = silc_packet_context_alloc();
2813 new_id->type = SILC_PACKET_NEW_ID;
2814 new_id->flags = packet->flags & (~SILC_PACKET_FLAG_LIST);
2815 new_id->src_id = packet->src_id;
2816 new_id->src_id_len = packet->src_id_len;
2817 new_id->src_id_type = packet->src_id_type;
2818 new_id->dst_id = packet->dst_id;
2819 new_id->dst_id_len = packet->dst_id_len;
2820 new_id->dst_id_type = packet->dst_id_type;
2822 idp = silc_buffer_alloc(256);
2823 new_id->buffer = idp;
2825 while (packet->buffer->len) {
2826 SILC_GET16_MSB(id_len, packet->buffer->data + 2);
2827 if ((id_len > packet->buffer->len) ||
2828 (id_len > idp->truelen))
2831 silc_buffer_pull_tail(idp, 4 + id_len);
2832 silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
2834 /* Process the New ID */
2835 silc_server_new_id_real(server, sock, new_id, FALSE);
2837 silc_buffer_push_tail(idp, 4 + id_len);
2838 silc_buffer_pull(packet->buffer, 4 + id_len);
2841 silc_buffer_free(idp);
2845 /* Received New Channel packet. Information about new channels in the
2846 network are distributed using this packet. Save the information about
2847 the new channel. This usually comes from router but also normal server
2848 can send this to notify channels it has when it connects to us. */
2850 void silc_server_new_channel(SilcServer server,
2851 SilcSocketConnection sock,
2852 SilcPacketContext *packet)
2854 SilcChannelPayload payload;
2855 SilcChannelID *channel_id;
2857 SilcUInt32 name_len;
2860 SilcServerEntry server_entry;
2861 SilcChannelEntry channel;
2863 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2864 packet->src_id_type != SILC_ID_SERVER ||
2865 server->server_type == SILC_SERVER)
2868 /* Parse the channel payload */
2869 payload = silc_channel_payload_parse(packet->buffer->data,
2870 packet->buffer->len);
2874 /* Get the channel ID */
2875 channel_id = silc_channel_get_id_parse(payload);
2877 silc_channel_payload_free(payload);
2881 channel_name = silc_channel_get_name(payload, &name_len);
2883 channel_name[255] = '\0';
2885 id = silc_channel_get_id(payload, &id_len);
2887 server_entry = (SilcServerEntry)sock->user_data;
2889 if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
2890 /* Add the channel to global list as it is coming from router. It
2891 cannot be our own channel as it is coming from router. */
2893 /* Check that we don't already have this channel */
2894 channel = silc_idlist_find_channel_by_name(server->local_list,
2895 channel_name, NULL);
2897 channel = silc_idlist_find_channel_by_name(server->global_list,
2898 channel_name, NULL);
2900 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
2901 silc_id_render(channel_id, SILC_ID_CHANNEL),
2905 silc_idlist_add_channel(server->global_list, strdup(channel_name),
2906 0, channel_id, sock->user_data, NULL, NULL, 0);
2909 channel->disabled = TRUE; /* Disabled until someone JOINs */
2911 server->stat.channels++;
2912 if (server->server_type == SILC_ROUTER)
2913 channel->users_resolved = TRUE;
2916 /* The channel is coming from our server, thus it is in our cell
2917 we will add it to our local list. */
2920 SILC_LOG_DEBUG(("Channel id(%s) from [Server] %s",
2921 silc_id_render(channel_id, SILC_ID_CHANNEL),
2924 /* Check that we don't already have this channel */
2925 channel = silc_idlist_find_channel_by_name(server->local_list,
2926 channel_name, NULL);
2928 channel = silc_idlist_find_channel_by_name(server->global_list,
2929 channel_name, NULL);
2931 /* If the channel does not exist, then create it. This creates a new
2932 key to the channel as well that we will send to the server. */
2934 SILC_LOG_DEBUG(("Channel is new to us"));
2936 /* The protocol says that the Channel ID's IP address must be based
2937 on the router's IP address. Check whether the ID is based in our
2938 IP and if it is not then create a new ID and enforce the server
2939 to switch the ID. */
2940 if (server_entry->server_type != SILC_BACKUP_ROUTER &&
2941 !SILC_ID_COMPARE(channel_id, server->id, server->id->ip.data_len)) {
2943 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2944 if (silc_id_create_channel_id(server, server->id, server->rng, &tmp)) {
2945 silc_server_send_notify_channel_change(server, sock, FALSE,
2947 silc_free(channel_id);
2951 /* Wait that server re-announces this channel */
2955 /* Create the channel with the provided Channel ID */
2956 channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
2960 silc_channel_payload_free(payload);
2961 silc_free(channel_id);
2964 channel->disabled = TRUE; /* Disabled until someone JOINs */
2966 #if 0 /* We assume that CMODE_CHANGE notify is sent to us after this. */
2968 /* XXX Dunno if this is supposed to be set in any server type. If set
2969 here the CMODE_CHANGE that may follow sets mode that we already
2970 have, and we may loose data from the CMODE_CHANGE notify. */
2971 if (server_entry->server_type != SILC_BACKUP_ROUTER)
2972 channel->mode = silc_channel_get_mode(payload);
2975 /* Send the new channel key to the server */
2976 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2977 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
2978 chk = silc_channel_key_payload_encode(id_len, id,
2979 strlen(channel->channel_key->
2981 channel->channel_key->cipher->name,
2982 channel->key_len / 8,
2984 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
2985 chk->data, chk->len, FALSE);
2986 silc_buffer_free(chk);
2988 /* The channel exist by that name, check whether the ID's match.
2989 If they don't then we'll force the server to use the ID we have.
2990 We also create a new key for the channel. */
2991 SilcBuffer modes = NULL, users = NULL, users_modes = NULL;
2993 SILC_LOG_DEBUG(("Channel already exists"));
2995 if (!SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
2996 /* They don't match, send CHANNEL_CHANGE notify to the server to
2997 force the ID change. */
2998 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2999 silc_server_send_notify_channel_change(server, sock, FALSE,
3000 channel_id, channel->id);
3002 /* Wait that server re-announces this channel */
3006 #if 0 /* We will announce our CMODE anyway for this channel, so no need
3007 to check it (implicit enforce). */
3009 /* If the mode is different from what we have then enforce the
3011 mode = silc_channel_get_mode(payload);
3012 if (channel->mode != mode) {
3013 SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
3014 silc_server_send_notify_cmode(server, sock, FALSE, channel,
3015 channel->mode, server->id,
3016 SILC_ID_SERVER, channel->cipher,
3018 channel->passphrase,
3019 channel->founder_key);
3023 /* Create new key for the channel and send it to the server and
3024 everybody else possibly on the channel. */
3025 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3027 if (silc_hash_table_count(channel->user_list)) {
3028 if (!silc_server_create_channel_key(server, channel, 0))
3031 /* Send to the channel */
3032 silc_server_send_channel_key(server, sock, channel, FALSE);
3035 /* Send to the server */
3036 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3037 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
3038 chk = silc_channel_key_payload_encode(id_len, id,
3039 strlen(channel->channel_key->
3041 channel->channel_key->
3043 channel->key_len / 8,
3045 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
3046 chk->data, chk->len, FALSE);
3047 silc_buffer_free(chk);
3051 silc_free(channel_id);
3053 /* Update statistics */
3054 server->stat.channels++;
3055 server->stat.cell_channels++;
3057 /* Since the channel is coming from server and we also know about it
3058 then send the JOIN notify to the server so that it see's our
3059 users on the channel "joining" the channel. */
3060 silc_server_announce_get_channel_users(server, channel, &modes, &users,
3063 silc_buffer_push(users, users->data - users->head);
3064 silc_server_packet_send(server, sock,
3065 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3066 users->data, users->len, FALSE);
3067 silc_buffer_free(users);
3070 silc_buffer_push(modes, modes->data - modes->head);
3071 silc_server_packet_send_dest(server, sock,
3072 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3073 channel->id, SILC_ID_CHANNEL,
3074 modes->data, modes->len, FALSE);
3075 silc_buffer_free(modes);
3078 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
3079 silc_server_packet_send_dest(server, sock,
3080 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3081 channel->id, SILC_ID_CHANNEL,
3083 users_modes->len, FALSE);
3084 silc_buffer_free(users_modes);
3086 if (channel->topic) {
3087 silc_server_send_notify_topic_set(server, sock,
3088 server->server_type == SILC_ROUTER ?
3089 TRUE : FALSE, channel,
3090 server->id, SILC_ID_SERVER,
3096 /* If the sender of this packet is server and we are router we need to
3097 broadcast this packet to other routers in the network. Broadcast
3098 this list packet instead of multiple New Channel packets. */
3099 if (server->server_type == SILC_ROUTER &&
3100 sock->type == SILC_SOCKET_TYPE_SERVER &&
3101 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
3102 SILC_LOG_DEBUG(("Broadcasting received New Channel packet"));
3103 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
3105 packet->flags | SILC_PACKET_FLAG_BROADCAST,
3106 packet->buffer->data,
3107 packet->buffer->len, FALSE);
3108 silc_server_backup_send(server, sock->user_data,
3109 packet->type, packet->flags,
3110 packet->buffer->data, packet->buffer->len,
3114 silc_channel_payload_free(payload);
3117 /* Received New Channel List packet, list of New Channel List payloads inside
3118 one packet. Process the New Channel payloads one by one. */
3120 void silc_server_new_channel_list(SilcServer server,
3121 SilcSocketConnection sock,
3122 SilcPacketContext *packet)
3124 SilcPacketContext *new;
3126 SilcUInt16 len1, len2;
3128 SILC_LOG_DEBUG(("Processing New Channel List"));
3130 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
3131 packet->src_id_type != SILC_ID_SERVER ||
3132 server->server_type == SILC_SERVER)
3135 /* Make copy of the original packet context, except for the actual
3136 data buffer, which we will here now fetch from the original buffer. */
3137 new = silc_packet_context_alloc();
3138 new->type = SILC_PACKET_NEW_CHANNEL;
3139 new->flags = packet->flags & (~SILC_PACKET_FLAG_LIST);
3140 new->src_id = packet->src_id;
3141 new->src_id_len = packet->src_id_len;
3142 new->src_id_type = packet->src_id_type;
3143 new->dst_id = packet->dst_id;
3144 new->dst_id_len = packet->dst_id_len;
3145 new->dst_id_type = packet->dst_id_type;
3147 buffer = silc_buffer_alloc(512);
3148 new->buffer = buffer;
3150 while (packet->buffer->len) {
3151 SILC_GET16_MSB(len1, packet->buffer->data);
3152 if ((len1 > packet->buffer->len) ||
3153 (len1 > buffer->truelen))
3156 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
3157 if ((len2 > packet->buffer->len) ||
3158 (len2 > buffer->truelen))
3161 silc_buffer_pull_tail(buffer, 8 + len1 + len2);
3162 silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
3164 /* Process the New Channel */
3165 silc_server_new_channel(server, sock, new);
3167 silc_buffer_push_tail(buffer, 8 + len1 + len2);
3168 silc_buffer_pull(packet->buffer, 8 + len1 + len2);
3171 silc_buffer_free(buffer);
3175 /* Received key agreement packet. This packet is never for us. It is to
3176 the client in the packet's destination ID. Sending of this sort of packet
3177 equals sending private message, ie. it is sent point to point from
3178 one client to another. */
3180 void silc_server_key_agreement(SilcServer server,
3181 SilcSocketConnection sock,
3182 SilcPacketContext *packet)
3184 SilcSocketConnection dst_sock;
3185 SilcIDListData idata;
3187 SILC_LOG_DEBUG(("Start"));
3189 if (packet->src_id_type != SILC_ID_CLIENT ||
3190 packet->dst_id_type != SILC_ID_CLIENT)
3193 if (!packet->dst_id)
3196 /* Get the route to the client */
3197 dst_sock = silc_server_get_client_route(server, packet->dst_id,
3198 packet->dst_id_len, NULL,
3203 /* Relay the packet */
3204 silc_server_relay_packet(server, dst_sock, idata->send_key,
3205 idata->hmac_send, idata->psn_send++,
3209 /* Received connection auth request packet that is used during connection
3210 phase to resolve the mandatory authentication method. This packet can
3211 actually be received at anytime but usually it is used only during
3212 the connection authentication phase. Now, protocol says that this packet
3213 can come from client or server, however, we support only this coming
3214 from client and expect that server always knows what authentication
3217 void silc_server_connection_auth_request(SilcServer server,
3218 SilcSocketConnection sock,
3219 SilcPacketContext *packet)
3221 SilcServerConfigClient *client = NULL;
3222 SilcUInt16 conn_type;
3224 SilcAuthMethod auth_meth = SILC_AUTH_NONE;
3226 if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT) {
3227 SILC_LOG_DEBUG(("Request not from client"));
3231 /* Parse the payload */
3232 ret = silc_buffer_unformat(packet->buffer,
3233 SILC_STR_UI_SHORT(&conn_type),
3234 SILC_STR_UI_SHORT(NULL),
3239 if (conn_type != SILC_SOCKET_TYPE_CLIENT)
3242 /* Get the authentication method for the client */
3243 auth_meth = SILC_AUTH_NONE;
3244 client = silc_server_config_find_client(server, sock->ip);
3246 client = silc_server_config_find_client(server, sock->hostname);
3248 if (client->passphrase) {
3249 if (client->publickeys && !server->config->prefer_passphrase_auth)
3250 auth_meth = SILC_AUTH_PUBLIC_KEY;
3252 auth_meth = SILC_AUTH_PASSWORD;
3253 } else if (client->publickeys)
3254 auth_meth = SILC_AUTH_PUBLIC_KEY;
3257 SILC_LOG_DEBUG(("Authentication method is [%s]",
3258 (auth_meth == SILC_AUTH_NONE ? "None" :
3259 auth_meth == SILC_AUTH_PASSWORD ? "Passphrase" :
3260 "Digital signatures")));
3262 /* Send it back to the client */
3263 silc_server_send_connection_auth_request(server, sock, conn_type, auth_meth);
3266 /* Received REKEY packet. The sender of the packet wants to regenerate
3267 its session keys. This starts the REKEY protocol. */
3269 void silc_server_rekey(SilcServer server,
3270 SilcSocketConnection sock,
3271 SilcPacketContext *packet)
3273 SilcProtocol protocol;
3274 SilcServerRekeyInternalContext *proto_ctx;
3275 SilcIDListData idata = (SilcIDListData)sock->user_data;
3277 SILC_LOG_DEBUG(("Start"));
3279 /* Allocate internal protocol context. This is sent as context
3281 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
3282 proto_ctx->server = (void *)server;
3283 proto_ctx->sock = sock;
3284 proto_ctx->responder = TRUE;
3285 proto_ctx->pfs = idata->rekey->pfs;
3287 /* Perform rekey protocol. Will call the final callback after the
3288 protocol is over. */
3289 silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
3290 &protocol, proto_ctx, silc_server_rekey_final);
3291 sock->protocol = protocol;
3293 if (proto_ctx->pfs == FALSE)
3294 /* Run the protocol */
3295 silc_protocol_execute(protocol, server->schedule, 0, 0);
3298 /* Received file transger packet. This packet is never for us. It is to
3299 the client in the packet's destination ID. Sending of this sort of packet
3300 equals sending private message, ie. it is sent point to point from
3301 one client to another. */
3303 void silc_server_ftp(SilcServer server,
3304 SilcSocketConnection sock,
3305 SilcPacketContext *packet)
3307 SilcSocketConnection dst_sock;
3308 SilcIDListData idata;
3310 SILC_LOG_DEBUG(("Start"));
3312 if (packet->src_id_type != SILC_ID_CLIENT ||
3313 packet->dst_id_type != SILC_ID_CLIENT)
3316 if (!packet->dst_id)
3319 /* Get the route to the client */
3320 dst_sock = silc_server_get_client_route(server, packet->dst_id,
3321 packet->dst_id_len, NULL,
3326 /* Relay the packet */
3327 silc_server_relay_packet(server, dst_sock, idata->send_key,
3328 idata->hmac_send, idata->psn_send++,
3334 SilcSocketConnection sock;
3335 SilcPacketContext *packet;
3337 } *SilcServerResumeResolve;
3339 SILC_SERVER_CMD_FUNC(resume_resolve)
3341 SilcServerResumeResolve r = (SilcServerResumeResolve)context;
3342 SilcServer server = r->server;
3343 SilcSocketConnection sock = r->sock;
3344 SilcServerCommandReplyContext reply = context2;
3345 SilcClientEntry client;
3347 SILC_LOG_DEBUG(("Start"));
3349 if (!reply || !silc_command_get_status(reply->payload, NULL, NULL)) {
3350 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3351 "closing connection", sock->hostname, sock->ip));
3352 silc_server_disconnect_remote(server, sock,
3353 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3354 "Resuming not possible");
3355 if (sock->user_data)
3356 silc_server_free_sock_user_data(server, sock, NULL);
3360 if (reply && silc_command_get(reply->payload) == SILC_COMMAND_WHOIS) {
3361 /* Get entry to the client, and resolve it if we don't have it. */
3362 client = silc_idlist_find_client_by_id(server->local_list,
3363 r->data, TRUE, NULL);
3365 client = silc_idlist_find_client_by_id(server->global_list,
3366 r->data, TRUE, NULL);
3368 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3369 "closing connection", sock->hostname, sock->ip));
3370 silc_server_disconnect_remote(server, sock,
3371 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3372 "Resuming not possible");
3373 if (sock->user_data)
3374 silc_server_free_sock_user_data(server, sock, NULL);
3379 if (!(client->mode & SILC_UMODE_DETACHED)) {
3380 SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, "
3381 "closing connection", sock->hostname, sock->ip));
3382 silc_server_disconnect_remote(server, sock,
3383 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3384 "Resuming not possible");
3385 if (sock->user_data)
3386 silc_server_free_sock_user_data(server, sock, NULL);
3390 client->data.status |= SILC_IDLIST_STATUS_RESUME_RES;
3393 /* Reprocess the packet */
3394 silc_server_resume_client(server, sock, r->packet);
3397 silc_socket_free(r->sock);
3398 silc_packet_context_free(r->packet);
3403 /* Received client resuming packet. This is used to resume detached
3404 client session. It can be sent by the client who wishes to resume
3405 but this is also sent by servers and routers to notify other routers
3406 that the client is not detached anymore. */
3408 void silc_server_resume_client(SilcServer server,
3409 SilcSocketConnection sock,
3410 SilcPacketContext *packet)
3412 SilcBuffer buffer = packet->buffer, buf;
3413 SilcIDListData idata;
3414 SilcIDCacheEntry id_cache = NULL;
3415 SilcClientEntry detached_client;
3416 SilcClientID *client_id = NULL;
3417 unsigned char *id_string, *auth = NULL;
3418 SilcUInt16 id_len, auth_len = 0;
3419 int ret, nickfail = 0;
3420 bool resolved, local, nick_change = FALSE, resolve = FALSE;
3421 SilcChannelEntry channel;
3422 SilcHashTableList htl;
3423 SilcChannelClientEntry chl;
3424 SilcServerResumeResolve r;
3426 ret = silc_buffer_unformat(buffer,
3427 SILC_STR_UI16_NSTRING(&id_string, &id_len),
3430 client_id = silc_id_str2id(id_string, id_len, SILC_ID_CLIENT);
3432 if (sock->type == SILC_SOCKET_TYPE_CLIENT) {
3433 /* Client send this and is attempting to resume to old client session */
3434 SilcClientEntry client;
3438 silc_buffer_pull(buffer, 2 + id_len);
3439 auth = buffer->data;
3440 auth_len = buffer->len;
3441 silc_buffer_push(buffer, 2 + id_len);
3444 if (!client_id || auth_len < 128) {
3445 SILC_LOG_ERROR(("Client %s (%s) sent incomplete resume information, "
3446 "closing connection", sock->hostname, sock->ip));
3447 silc_server_disconnect_remote(server, sock,
3448 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3449 "Resuming not possible");
3450 if (sock->user_data)
3451 silc_server_free_sock_user_data(server, sock, NULL);
3452 silc_free(client_id);
3456 /* Take client entry of this connection */
3457 client = (SilcClientEntry)sock->user_data;
3458 idata = (SilcIDListData)client;
3460 /* Get entry to the client, and resolve it if we don't have it. */
3461 detached_client = silc_server_query_client(server, client_id, FALSE,
3463 if (!detached_client) {
3465 /* The client info is being resolved. Reprocess this packet after
3466 receiving the reply to the query. */
3467 SILC_LOG_DEBUG(("Resolving client"));
3468 r = silc_calloc(1, sizeof(*r));
3472 r->sock = silc_socket_dup(sock);
3473 r->packet = silc_packet_context_dup(packet);
3474 r->data = client_id;
3475 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
3477 silc_server_command_resume_resolve, r);
3479 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3480 "closing connection", sock->hostname, sock->ip));
3481 silc_server_disconnect_remote(server, sock,
3482 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3483 "Resuming not possible");
3484 if (sock->user_data)
3485 silc_server_free_sock_user_data(server, sock, NULL);
3486 silc_free(client_id);
3491 if (!(detached_client->mode & SILC_UMODE_DETACHED))
3493 if (!silc_hash_table_count(detached_client->channels) &&
3494 detached_client->router)
3496 if (!detached_client->nickname)
3498 if (detached_client->data.status & SILC_IDLIST_STATUS_RESUME_RES)
3502 if (server->server_type == SILC_SERVER && !server->standalone) {
3503 /* The client info is being resolved. Reprocess this packet after
3504 receiving the reply to the query. */
3505 SILC_LOG_DEBUG(("Resolving client info"));
3506 silc_server_query_client(server, client_id, TRUE, NULL);
3507 r = silc_calloc(1, sizeof(*r));
3511 r->sock = silc_socket_dup(sock);
3512 r->packet = silc_packet_context_dup(packet);
3513 r->data = client_id;
3514 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
3516 silc_server_command_resume_resolve, r);
3519 if (server->server_type == SILC_SERVER) {
3520 SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, "
3521 "closing connection", sock->hostname, sock->ip));
3522 silc_server_disconnect_remote(server, sock,
3523 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3524 "Resuming not possible");
3525 if (sock->user_data)
3526 silc_server_free_sock_user_data(server, sock, NULL);
3527 silc_free(client_id);
3532 /* Check that we have the public key of the client, if not then we must
3533 resolve it first. */
3534 if (!detached_client->data.public_key) {
3535 if (server->server_type == SILC_SERVER && server->standalone) {
3536 SILC_LOG_ERROR(("Detached client's public key not present, "
3537 "closing connection"));
3538 silc_server_disconnect_remote(server, sock,
3539 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3540 "Resuming not possible");
3541 if (sock->user_data)
3542 silc_server_free_sock_user_data(server, sock, NULL);
3543 silc_free(client_id);
3545 /* We must retrieve the detached client's public key by sending
3546 GETKEY command. Reprocess this packet after receiving the key */
3547 SilcBuffer idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
3548 SilcSocketConnection dest_sock =
3549 silc_server_get_client_route(server, NULL, 0, client_id, NULL, NULL);
3551 SILC_LOG_DEBUG(("Resolving client public key"));
3553 silc_server_send_command(server, dest_sock ? dest_sock :
3554 SILC_PRIMARY_ROUTE(server),
3555 SILC_COMMAND_GETKEY, ++server->cmd_ident,
3556 1, 1, idp->data, idp->len);
3558 r = silc_calloc(1, sizeof(*r));
3560 silc_free(client_id);
3565 r->sock = silc_socket_dup(sock);
3566 r->packet = silc_packet_context_dup(packet);
3567 silc_server_command_pending(server, SILC_COMMAND_GETKEY,
3569 silc_server_command_resume_resolve, r);
3571 silc_buffer_free(idp);
3573 silc_free(client_id);
3575 } else if (!silc_pkcs_public_key_compare(detached_client->data.public_key,
3576 idata->public_key)) {
3577 /* We require that the connection and resuming authentication data
3578 must be using same key pair. */
3579 SILC_LOG_ERROR(("Resuming attempted with wrong public key, "
3580 "closing connection"));
3581 silc_server_disconnect_remote(server, sock,
3582 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3583 "Resuming not possible");
3584 if (sock->user_data)
3585 silc_server_free_sock_user_data(server, sock, NULL);
3586 silc_free(client_id);
3590 /* Verify the authentication payload. This has to be successful in
3591 order to allow the resuming */
3593 !silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
3594 detached_client->data.public_key, 0,
3595 idata->hash, detached_client->id,
3597 SILC_LOG_ERROR(("Client %s (%s) resume authentication failed, "
3598 "closing connection", sock->hostname, sock->ip));
3599 silc_server_disconnect_remote(server, sock,
3600 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3601 "Resuming not possible");
3602 if (sock->user_data)
3603 silc_server_free_sock_user_data(server, sock, NULL);
3604 silc_free(client_id);
3608 /* Now resume the client to the network */
3610 silc_schedule_task_del_by_context(server->schedule, detached_client);
3611 sock->user_data = detached_client;
3612 detached_client->connection = sock;
3614 /* Take new keys and stuff into use in the old entry */
3615 silc_idlist_del_data(detached_client);
3616 silc_idlist_add_data(detached_client, idata);
3617 detached_client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
3618 detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
3619 detached_client->data.status &= ~SILC_IDLIST_STATUS_RESUME_RES;
3620 detached_client->mode &= ~SILC_UMODE_DETACHED;
3621 server->stat.my_detached--;
3623 /* Send the RESUME_CLIENT packet to our primary router so that others
3624 know this client isn't detached anymore. */
3625 buf = silc_buffer_alloc_size(2 + id_len);
3626 silc_buffer_format(buf,
3627 SILC_STR_UI_SHORT(id_len),
3628 SILC_STR_UI_XNSTRING(id_string, id_len),
3631 /* Send to primary router */
3632 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
3633 SILC_PACKET_RESUME_CLIENT, 0,
3634 buf->data, buf->len, TRUE);
3636 /* As router we must deliver this packet directly to the original
3637 server whom this client was earlier. */
3638 if (server->server_type == SILC_ROUTER && detached_client->router &&
3639 detached_client->router->server_type != SILC_ROUTER)
3640 silc_server_packet_send(server, detached_client->router->connection,
3641 SILC_PACKET_RESUME_CLIENT, 0,
3642 buf->data, buf->len, TRUE);
3643 silc_buffer_free(buf);
3645 detached_client->router = NULL;
3647 /* Delete this client entry since we're resuming to old one. */
3648 server->stat.my_clients--;
3649 server->stat.clients--;
3650 if (server->stat.cell_clients)
3651 server->stat.cell_clients--;
3652 silc_server_remove_from_channels(server, NULL, client, FALSE, NULL, FALSE);
3653 silc_server_del_from_watcher_list(server, client);
3654 if (!silc_idlist_del_client(server->local_list, client))
3655 silc_idlist_del_client(server->global_list, client);
3656 client = detached_client;
3658 /* If the ID is not based in our ID then change it */
3659 if (!SILC_ID_COMPARE(client->id, server->id, server->id->ip.data_len)) {
3660 silc_free(client_id);
3661 while (!silc_id_create_client_id(server, server->id, server->rng,
3662 server->md5hash, client->nickname,
3666 silc_server_disconnect_remote(server, sock,
3667 SILC_STATUS_ERR_BAD_NICKNAME, NULL);
3668 if (sock->user_data)
3669 silc_server_free_sock_user_data(server, sock, NULL);
3672 snprintf(&client->nickname[strlen(client->nickname) - 1], 1,
3679 /* Notify about Client ID change, nickname doesn't actually change. */
3680 silc_server_send_notify_nick_change(server, SILC_PRIMARY_ROUTE(server),
3681 SILC_BROADCAST(server),
3682 client->id, client_id,
3686 /* Resolve users on those channels that client has joined but we
3687 haven't resolved user list yet. */
3688 if (server->server_type == SILC_SERVER && !server->standalone) {
3689 silc_hash_table_list(client->channels, &htl);
3690 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
3691 channel = chl->channel;
3692 SILC_LOG_DEBUG(("Resolving users for %s channel",
3693 channel->channel_name));
3694 if (channel->disabled || !channel->users_resolved) {
3695 silc_server_send_command(server, SILC_PRIMARY_ROUTE(server),
3696 SILC_COMMAND_USERS, ++server->cmd_ident,
3697 1, 2, channel->channel_name,
3698 strlen(channel->channel_name));
3701 silc_hash_table_list_reset(&htl);
3704 /* Send the new client ID to the client. After this client may start
3705 receiving other packets, and may start sending packets too. */
3706 silc_server_send_new_id(server, sock, FALSE, client_id, SILC_ID_CLIENT,
3707 silc_id_get_len(client_id, SILC_ID_CLIENT));
3710 /* Send NICK change notify to channels as well. */
3711 SilcBuffer oidp, nidp;
3712 oidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3713 nidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
3714 silc_server_send_notify_on_channels(server, NULL, client,
3715 SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
3716 oidp->data, oidp->len,
3717 nidp->data, nidp->len,
3719 strlen(client->nickname));
3720 silc_buffer_free(oidp);
3721 silc_buffer_free(nidp);
3724 /* Add the client again to the ID cache to get it to correct list */
3725 if (!silc_idcache_del_by_context(server->local_list->clients, client))
3726 silc_idcache_del_by_context(server->global_list->clients, client);
3727 silc_free(client->id);
3728 client->id = client_id;
3730 silc_idcache_add(server->local_list->clients, client->nickname,
3731 client->id, client, 0, NULL);
3733 /* Send some nice info to the client */
3734 silc_server_send_connect_notifys(server, sock, client);
3736 /* Send all channel keys of channels the client has joined */
3737 silc_hash_table_list(client->channels, &htl);
3738 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
3739 bool created = FALSE;
3740 channel = chl->channel;
3742 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY)
3745 /* If we don't have channel key, then create one */
3746 if (!channel->channel_key) {
3747 if (!silc_server_create_channel_key(server, channel, 0))
3752 id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3754 silc_channel_key_payload_encode(silc_id_get_len(channel->id,
3757 strlen(channel->channel_key->
3759 channel->channel_key->cipher->name,
3760 channel->key_len / 8, channel->key);
3761 silc_free(id_string);
3763 /* Send the key packet to client */
3764 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
3765 keyp->data, keyp->len, FALSE);
3767 if (created && server->server_type == SILC_SERVER)
3768 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
3769 SILC_PACKET_CHANNEL_KEY, 0,
3770 keyp->data, keyp->len, FALSE);
3772 silc_buffer_free(keyp);
3774 silc_hash_table_list_reset(&htl);
3776 } else if (sock->type != SILC_SOCKET_TYPE_CLIENT) {
3777 /* Server or router sent this to us to notify that that a client has
3779 SilcServerEntry server_entry;
3780 SilcServerID *server_id;
3783 SILC_LOG_DEBUG(("Malformed resuming packet"));
3787 /* Get entry to the client, and resolve it if we don't have it. */
3788 detached_client = silc_idlist_find_client_by_id(server->local_list,
3791 if (!detached_client) {
3792 detached_client = silc_idlist_find_client_by_id(server->global_list,
3795 if (!detached_client) {
3796 SILC_LOG_DEBUG(("Resuming client is unknown"));
3797 silc_free(client_id);
3802 /* Check that the client has not been resumed already because it is
3803 protocol error to attempt to resume more than once. The client
3804 will be killed if this protocol error occurs. */
3805 if (detached_client->data.status & SILC_IDLIST_STATUS_RESUMED &&
3806 !(detached_client->mode & SILC_UMODE_DETACHED)) {
3807 /* The client is clearly attempting to resume more than once and
3808 perhaps playing around by resuming from several different places
3809 at the same time. */
3810 SILC_LOG_DEBUG(("Attempting to re-resume client, killing both"));
3811 silc_server_kill_client(server, detached_client, NULL,
3812 server->id, SILC_ID_SERVER);
3813 silc_free(client_id);
3817 /* Check whether client is detached at all */
3818 if (!(detached_client->mode & SILC_UMODE_DETACHED)) {
3819 SILC_LOG_DEBUG(("Client is not detached"));
3820 silc_free(client_id);
3824 SILC_LOG_DEBUG(("Resuming detached client"));
3826 /* If the sender of this packet is server and we are router we need to
3827 broadcast this packet to other routers in the network. */
3828 if (server->server_type == SILC_ROUTER &&
3829 sock->type == SILC_SOCKET_TYPE_SERVER &&
3830 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
3831 SILC_LOG_DEBUG(("Broadcasting received Resume Client packet"));
3832 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
3834 packet->flags | SILC_PACKET_FLAG_BROADCAST,
3835 buffer->data, buffer->len, FALSE);
3836 silc_server_backup_send(server, sock->user_data,
3837 packet->type, packet->flags,
3838 packet->buffer->data, packet->buffer->len,
3842 /* Client is detached, and now it is resumed. Remove the detached
3843 mode and mark that it is resumed. */
3844 detached_client->mode &= ~SILC_UMODE_DETACHED;
3845 detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
3846 detached_client->data.status &= ~SILC_IDLIST_STATUS_LOCAL;
3847 id_cache->expire = 0;
3849 /* Update channel information regarding global clients on channel. */
3850 if (server->server_type == SILC_SERVER) {
3851 silc_hash_table_list(detached_client->channels, &htl);
3852 while (silc_hash_table_get(&htl, NULL, (void **)&chl))
3853 chl->channel->global_users =
3854 silc_server_channel_has_global(chl->channel);
3855 silc_hash_table_list_reset(&htl);
3858 silc_schedule_task_del_by_context(server->schedule, detached_client);
3860 /* Get the new owner of the resumed client */
3861 server_id = silc_id_str2id(packet->src_id, packet->src_id_len,
3862 packet->src_id_type);
3864 silc_free(client_id);
3868 /* Get server entry */
3869 server_entry = silc_idlist_find_server_by_id(server->global_list,
3870 server_id, TRUE, NULL);
3872 if (!server_entry) {
3873 server_entry = silc_idlist_find_server_by_id(server->local_list,
3874 server_id, TRUE, NULL);
3876 if (!server_entry) {
3877 silc_free(server_id);
3878 silc_free(client_id);
3883 if (server->server_type == SILC_ROUTER &&
3884 sock->type == SILC_SOCKET_TYPE_ROUTER &&
3885 server_entry->server_type == SILC_ROUTER)
3888 /* Change the client to correct list. */
3889 if (!silc_idcache_del_by_context(server->local_list->clients,
3891 silc_idcache_del_by_context(server->global_list->clients,
3893 silc_idcache_add(local && server->server_type == SILC_ROUTER ?
3894 server->local_list->clients :
3895 server->global_list->clients,
3896 detached_client->nickname,
3897 detached_client->id, detached_client, FALSE, NULL);
3899 /* Change the owner of the client */
3900 detached_client->router = server_entry;
3902 silc_free(server_id);
3905 silc_free(client_id);