5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2002 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
21 * Server packet routines to handle received packets.
25 #include "serverincludes.h"
26 #include "server_internal.h"
28 /* Received notify packet. Server can receive notify packets from router.
29 Server then relays the notify messages to clients if needed. */
31 void silc_server_notify(SilcServer server,
32 SilcSocketConnection sock,
33 SilcPacketContext *packet)
35 SilcNotifyPayload payload;
37 SilcArgumentPayload args;
38 SilcChannelID *channel_id = NULL, *channel_id2;
39 SilcClientID *client_id, *client_id2;
40 SilcServerID *server_id;
42 SilcChannelEntry channel = NULL;
43 SilcClientEntry client = NULL, client2 = NULL;
44 SilcServerEntry server_entry = NULL;
45 SilcChannelClientEntry chl;
46 SilcIDCacheEntry cache;
47 SilcHashTableList htl;
53 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)
180 silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
181 silc_id_dup(client_id, SILC_ID_CLIENT),
182 sock->user_data, NULL, 0);
184 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
185 silc_free(client_id);
189 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
193 /* Do not process the notify if the client is not registered */
194 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
197 /* Do not add client to channel if it is there already */
198 if (silc_server_client_on_channel(client, channel, NULL)) {
199 SILC_LOG_DEBUG(("Client already on channel %s",
200 channel->channel_name));
204 /* Send to channel */
205 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
206 FALSE, packet->buffer->data,
207 packet->buffer->len, FALSE);
209 if (server->server_type != SILC_ROUTER &&
210 sock->type == SILC_SOCKET_TYPE_ROUTER)
211 /* The channel is global now */
212 channel->global_users = TRUE;
214 SILC_LOG_DEBUG(("Joining to channel %s", channel->channel_name));
216 /* JOIN the global client to the channel (local clients (if router
217 created the channel) is joined in the pending JOIN command). */
218 chl = silc_calloc(1, sizeof(*chl));
219 chl->client = client;
220 chl->channel = channel;
222 if (server->server_type != SILC_ROUTER ||
223 sock->type == SILC_SOCKET_TYPE_ROUTER) {
224 /* If this is the first one on the channel then it is the founder of
225 the channel. This is done on normal server and on router if this
226 notify is coming from router */
227 if (!silc_hash_table_count(channel->user_list)) {
228 SILC_LOG_DEBUG(("Client %s is founder on channel",
229 silc_id_render(chl->client->id, SILC_ID_CLIENT)));
230 chl->mode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
234 silc_hash_table_add(channel->user_list, client, chl);
235 silc_hash_table_add(client->channels, channel, chl);
236 silc_free(client_id);
237 channel->user_count++;
238 channel->disabled = FALSE;
240 /* Update statistics */
241 if (server->server_type == SILC_ROUTER) {
242 if (sock->type != SILC_SOCKET_TYPE_ROUTER)
243 server->stat.cell_chanclients++;
244 server->stat.chanclients++;
249 case SILC_NOTIFY_TYPE_LEAVE:
251 * Distribute the notify to local clients on the channel
253 SILC_LOG_DEBUG(("LEAVE notify"));
256 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
257 packet->dst_id_type);
262 /* Get channel entry */
263 channel = silc_idlist_find_channel_by_id(server->global_list,
266 channel = silc_idlist_find_channel_by_id(server->local_list,
269 SILC_LOG_DEBUG(("Notify for unknown channel"));
270 silc_free(channel_id);
276 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
278 silc_free(channel_id);
281 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
283 silc_free(channel_id);
287 /* Get client entry */
288 client = silc_idlist_find_client_by_id(server->global_list,
289 client_id, TRUE, NULL);
291 client = silc_idlist_find_client_by_id(server->local_list,
292 client_id, TRUE, NULL);
294 silc_free(client_id);
295 silc_free(channel_id);
299 silc_free(client_id);
301 /* Check if on channel */
302 if (!silc_server_client_on_channel(client, channel, NULL))
305 /* Send the leave notify to channel */
306 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
307 FALSE, packet->buffer->data,
308 packet->buffer->len, FALSE);
310 /* Remove the user from channel */
311 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
314 case SILC_NOTIFY_TYPE_SIGNOFF:
316 * Distribute the notify to local clients on the channel
318 SILC_LOG_DEBUG(("SIGNOFF notify"));
321 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
324 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
328 /* Get client entry */
329 client = silc_idlist_find_client_by_id(server->global_list,
330 client_id, TRUE, &cache);
332 client = silc_idlist_find_client_by_id(server->local_list,
333 client_id, TRUE, &cache);
335 silc_free(client_id);
339 silc_free(client_id);
341 /* Get signoff message */
342 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
346 /* Update statistics */
347 server->stat.clients--;
348 if (server->stat.cell_clients)
349 server->stat.cell_clients--;
350 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
351 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
352 silc_schedule_task_del_by_context(server->schedule, client);
354 /* Remove the client from all channels. */
355 silc_server_remove_from_channels(server, NULL, client, TRUE, tmp, FALSE);
357 /* Check if anyone is watching this nickname */
358 if (server->server_type == SILC_ROUTER)
359 silc_server_check_watcher_list(server, client, NULL,
360 SILC_NOTIFY_TYPE_SIGNOFF);
362 /* Remove this client from watcher list if it is */
363 silc_server_del_from_watcher_list(server, client);
365 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
366 cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
369 case SILC_NOTIFY_TYPE_TOPIC_SET:
371 * Distribute the notify to local clients on the channel
374 SILC_LOG_DEBUG(("TOPIC SET notify"));
377 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
380 client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
384 /* Get client entry */
385 if (id_type == SILC_ID_CLIENT) {
386 client = silc_idlist_find_client_by_id(server->global_list,
387 client_id, TRUE, &cache);
389 client = silc_idlist_find_client_by_id(server->local_list,
390 client_id, TRUE, &cache);
392 silc_free(client_id);
396 silc_free(client_id);
400 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
402 silc_free(channel_id);
407 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
408 packet->dst_id_type);
413 /* Get channel entry */
414 channel = silc_idlist_find_channel_by_id(server->global_list,
417 channel = silc_idlist_find_channel_by_id(server->local_list,
420 SILC_LOG_DEBUG(("Notify for unknown channel"));
421 silc_free(channel_id);
426 if (channel->topic && !strcmp(channel->topic, tmp)) {
427 SILC_LOG_DEBUG(("Topic is already set and same"));
432 /* Get user's channel entry and check that topic set is allowed. */
433 if (!silc_server_client_on_channel(client, channel, &chl))
435 if (channel->mode & SILC_CHANNEL_MODE_TOPIC &&
436 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
437 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
438 SILC_LOG_DEBUG(("Topic change is not allowed"));
443 /* Change the topic */
444 silc_free(channel->topic);
445 channel->topic = strdup(tmp);
447 /* Send the same notify to the channel */
448 silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
449 FALSE, packet->buffer->data,
450 packet->buffer->len, FALSE);
451 silc_free(channel_id);
454 case SILC_NOTIFY_TYPE_NICK_CHANGE:
457 * Distribute the notify to local clients on the channel
459 unsigned char *id, *id2;
461 SilcUInt32 nickname_len;
463 SILC_LOG_DEBUG(("NICK CHANGE notify"));
465 /* Get old client ID */
466 id = silc_argument_get_arg_type(args, 1, &tmp_len);
469 client_id = silc_id_payload_parse_id(id, tmp_len, NULL);
473 /* Get new client ID */
474 id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
477 client_id2 = silc_id_payload_parse_id(id2, tmp_len, NULL);
481 SILC_LOG_DEBUG(("Old Client ID id(%s)",
482 silc_id_render(client_id, SILC_ID_CLIENT)));
483 SILC_LOG_DEBUG(("New Client ID id(%s)",
484 silc_id_render(client_id2, SILC_ID_CLIENT)));
486 /* From protocol version 1.1 we also get the new nickname */
487 nickname = silc_argument_get_arg_type(args, 3, &nickname_len);;
489 /* Replace the Client ID */
490 client = silc_idlist_replace_client_id(server,
491 server->global_list, client_id,
492 client_id2, nickname);
494 client = silc_idlist_replace_client_id(server,
495 server->local_list, client_id,
496 client_id2, nickname);
499 /* Send the NICK_CHANGE notify type to local clients on the channels
500 this client is joined to. */
501 silc_server_send_notify_on_channels(server, client, client,
502 SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
503 id, tmp_len, id2, tmp_len,
508 silc_free(client_id);
510 silc_free(client_id2);
514 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
516 * Distribute the notify to local clients on the channel
519 SILC_LOG_DEBUG(("CMODE CHANGE notify"));
522 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
525 client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
529 /* Get client entry */
530 if (id_type == SILC_ID_CLIENT) {
531 client = silc_idlist_find_client_by_id(server->global_list,
532 client_id, TRUE, &cache);
534 client = silc_idlist_find_client_by_id(server->local_list,
535 client_id, TRUE, &cache);
537 silc_free(client_id);
541 silc_free(client_id);
545 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
546 packet->dst_id_type);
551 /* Get channel entry */
552 channel = silc_idlist_find_channel_by_id(server->global_list,
555 channel = silc_idlist_find_channel_by_id(server->local_list,
558 SILC_LOG_DEBUG(("Notify for unknown channel"));
559 silc_free(channel_id);
563 silc_free(channel_id);
566 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
569 SILC_GET32_MSB(mode, tmp);
571 /* Check if mode changed */
572 if (channel->mode == mode) {
573 SILC_LOG_DEBUG(("Mode is changed already"));
575 /* If this mode change has founder mode then we'll enforce the
576 change so that the server gets the real founder public key */
577 if (server->server_type != SILC_SERVER &&
578 sock != SILC_PRIMARY_ROUTE(server) &&
579 mode & SILC_CHANNEL_MODE_FOUNDER_AUTH && channel->founder_key) {
580 SILC_LOG_DEBUG(("Sending founder public key to server"));
581 silc_server_send_notify_cmode(server, sock, FALSE, channel,
582 channel->mode, server->id,
583 SILC_ID_SERVER, channel->cipher,
586 channel->founder_key);
589 /* If we received same mode from our primary check whether founder
590 mode and key in the notify is set. We update the founder key
591 here since we may have wrong one */
592 if (server->server_type == SILC_SERVER &&
593 sock == SILC_PRIMARY_ROUTE(server) &&
594 mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
595 SILC_LOG_DEBUG(("Founder public key received from router"));
596 tmp = silc_argument_get_arg_type(args, 6, &tmp_len);
600 if (channel->founder_key)
601 silc_pkcs_public_key_free(channel->founder_key);
602 channel->founder_key = NULL;
603 silc_pkcs_public_key_decode(tmp, tmp_len, &channel->founder_key);
609 /* Get user's channel entry and check that mode change is allowed */
611 if (!silc_server_client_on_channel(client, channel, &chl))
613 if (!silc_server_check_cmode_rights(server, channel, chl, mode)) {
614 SILC_LOG_DEBUG(("CMODE change is not allowed"));
615 silc_server_send_notify_cmode(server, sock, FALSE, channel,
616 channel->mode, server->id,
617 SILC_ID_SERVER, channel->cipher,
620 channel->founder_key);
624 /* Assure that server is not removing founder mode from us */
625 if (server->server_type == SILC_ROUTER &&
626 sock != SILC_PRIMARY_ROUTE(server) &&
627 channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH &&
628 !(mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
629 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
630 silc_server_send_notify_cmode(server, sock, FALSE, channel,
631 channel->mode, server->id,
632 SILC_ID_SERVER, channel->cipher,
635 channel->founder_key);
639 /* If server is adding founder mode, check whether there is founder
640 on channel already and is not from this server */
641 if (server->server_type == SILC_ROUTER &&
642 sock != SILC_PRIMARY_ROUTE(server) &&
643 mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
644 silc_hash_table_list(channel->user_list, &htl);
645 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
646 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO &&
647 chl->client->router != sock->user_data) {
648 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
649 silc_server_send_notify_cmode(server, sock, FALSE, channel,
650 channel->mode, server->id,
651 SILC_ID_SERVER, channel->cipher,
654 channel->founder_key);
655 silc_hash_table_list_reset(&htl);
658 silc_hash_table_list_reset(&htl);
662 /* If the channel had private keys set and the mode was removed then
663 we must re-generate and re-distribute a new channel key */
664 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY &&
665 !(mode & SILC_CHANNEL_MODE_PRIVKEY)) {
666 /* Re-generate channel key */
667 if (!silc_server_create_channel_key(server, channel, 0))
670 /* Send the channel key. This sends it to our local clients and if
671 we are normal server to our router as well. */
672 silc_server_send_channel_key(server, NULL, channel,
673 server->server_type == SILC_ROUTER ?
674 FALSE : !server->standalone);
678 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
680 unsigned char hash[32];
683 silc_hmac_free(channel->hmac);
684 if (!silc_hmac_alloc(tmp, NULL, &channel->hmac))
687 /* Set the HMAC key out of current channel key. The client must do
689 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key,
690 channel->key_len / 8, hash);
691 silc_hmac_set_key(channel->hmac, hash,
692 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
693 memset(hash, 0, sizeof(hash));
696 /* Get the passphrase */
697 tmp = silc_argument_get_arg_type(args, 5, &tmp_len);
699 silc_free(channel->passphrase);
700 channel->passphrase = silc_memdup(tmp, tmp_len);
703 /* Get founder public key */
704 tmp = silc_argument_get_arg_type(args, 6, &tmp_len);
705 if (tmp && mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
706 if (channel->founder_key)
707 silc_pkcs_public_key_free(channel->founder_key);
708 channel->founder_key = NULL;
709 silc_pkcs_public_key_decode(tmp, tmp_len, &channel->founder_key);
711 if (!channel->founder_key ||
712 (client && client->data.public_key &&
713 server->server_type == SILC_ROUTER &&
714 !silc_pkcs_public_key_compare(channel->founder_key,
715 client->data.public_key))) {
716 /* A really buggy server isn't checking public keys correctly.
717 It's not possible that the mode setter and founder wouldn't
718 have same public key. */
719 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
721 mode &= ~SILC_CHANNEL_MODE_FOUNDER_AUTH;
722 silc_server_send_notify_cmode(server, sock, FALSE, channel,
723 mode, server->id, SILC_ID_SERVER,
726 channel->passphrase, NULL);
727 if (channel->founder_key)
728 silc_pkcs_public_key_free(channel->founder_key);
729 channel->founder_key = NULL;
730 } else if (client && !client->data.public_key) {
731 client->data.public_key =
732 silc_pkcs_public_key_copy(channel->founder_key);
736 if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH && !channel->founder_key &&
737 server->server_type == SILC_ROUTER) {
738 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
739 mode &= ~SILC_CHANNEL_MODE_FOUNDER_AUTH;
740 silc_server_send_notify_cmode(server, sock, FALSE, channel,
741 mode, server->id, SILC_ID_SERVER,
744 channel->passphrase, NULL);
747 /* Send the same notify to the channel */
748 silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
749 FALSE, packet->buffer->data,
750 packet->buffer->len, FALSE);
753 channel->mode = mode;
755 if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) &&
756 channel->founder_key) {
757 silc_pkcs_public_key_free(channel->founder_key);
758 channel->founder_key = NULL;
763 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
766 * Distribute the notify to local clients on the channel
768 SilcChannelClientEntry chl2 = NULL;
769 bool notify_sent = FALSE;
771 SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
774 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
777 client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
781 /* Get client entry */
782 if (id_type == SILC_ID_CLIENT) {
783 client = silc_idlist_find_client_by_id(server->global_list,
784 client_id, TRUE, &cache);
786 client = silc_idlist_find_client_by_id(server->local_list,
787 client_id, TRUE, &cache);
789 silc_free(client_id);
793 silc_free(client_id);
797 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
798 packet->dst_id_type);
803 /* Get channel entry */
804 channel = silc_idlist_find_channel_by_id(server->global_list,
807 channel = silc_idlist_find_channel_by_id(server->local_list,
810 SILC_LOG_DEBUG(("Notify for unknown channel"));
811 silc_free(channel_id);
817 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
819 silc_free(channel_id);
823 SILC_GET32_MSB(mode, tmp);
825 /* Get target client */
826 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
829 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
833 /* Get client entry */
834 client2 = silc_idlist_find_client_by_id(server->global_list,
835 client_id, TRUE, NULL);
837 client2 = silc_idlist_find_client_by_id(server->local_list,
838 client_id, TRUE, NULL);
840 silc_free(client_id);
844 silc_free(client_id);
847 /* Check that sender is on channel */
848 if (!silc_server_client_on_channel(client, channel, &chl))
851 if (client != client2 && server->server_type == SILC_ROUTER) {
852 /* Sender must be operator */
853 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
854 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
855 SILC_LOG_DEBUG(("CUMODE change is not allowed"));
859 if (!silc_server_client_on_channel(client2, channel, &chl))
862 /* If target is founder mode change is not allowed. */
863 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
864 SILC_LOG_DEBUG(("CUMODE change is not allowed"));
870 /* Get target channel user entry */
871 if (!silc_server_client_on_channel(client2, channel, &chl))
874 if (server->server_type == SILC_SERVER && chl->mode == mode) {
875 SILC_LOG_DEBUG(("Mode is changed already"));
879 if (mode & SILC_CHANNEL_UMODE_CHANFO &&
880 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO) &&
881 server->server_type == SILC_ROUTER &&
882 sock != SILC_PRIMARY_ROUTE(server)) {
883 SilcPublicKey founder_key = NULL;
885 /* If channel doesn't have founder auth mode then it's impossible
886 that someone would be getting founder rights with CUMODE command.
887 In that case there already either is founder or there isn't
888 founder at all on the channel. */
889 if (client && !(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
890 /* Force the mode to not have founder mode */
891 chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
892 silc_server_force_cumode_change(server, sock, channel, chl, mode);
897 /* Get the founder of the channel and if found then this client
898 cannot be the founder since there already is one. */
899 silc_hash_table_list(channel->user_list, &htl);
900 while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
901 if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
902 /* If the founder on the channel is not the one whom has set
903 the founder mode, then it's possible that this CUMODE_CHANGE
904 is correct. Due to netsplits it's possible that this
905 situation happens. */
906 if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) ||
907 (channel->founder_key && chl2->client->data.public_key &&
908 silc_pkcs_public_key_compare(
909 channel->founder_key,
910 chl2->client->data.public_key))) {
911 chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
912 silc_server_force_cumode_change(server, sock, channel,
918 silc_hash_table_list_reset(&htl);
919 if (!(mode & SILC_CHANNEL_UMODE_CHANFO))
922 /* Founder not found of the channel. Since the founder auth mode
923 is set on the channel now check whether this is the client that
924 originally set the mode. */
926 if (channel->founder_key) {
927 /* Get public key that must be present in notify */
928 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
929 if (!tmp || !silc_pkcs_public_key_decode(tmp, tmp_len,
931 chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
932 silc_server_force_cumode_change(server, sock, channel, chl, mode);
937 /* Now match the public key we have cached and public key sent.
939 if (client && client->data.public_key &&
940 !silc_pkcs_public_key_compare(channel->founder_key,
941 client->data.public_key)) {
942 chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
943 silc_server_force_cumode_change(server, sock, channel, chl, mode);
947 if (!silc_pkcs_public_key_compare(channel->founder_key,
949 chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
950 silc_server_force_cumode_change(server, sock, channel, chl, mode);
956 /* There cannot be anyone else as founder on the channel now. This
957 client is definitely the founder due to this authentication */
958 silc_hash_table_list(channel->user_list, &htl);
959 while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
960 if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
961 chl2->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
962 silc_server_force_cumode_change(server, NULL, channel, chl2,
966 silc_hash_table_list_reset(&htl);
969 silc_pkcs_public_key_free(founder_key);
972 if (server->server_type != SILC_SERVER && chl->mode == mode) {
973 SILC_LOG_DEBUG(("Mode is changed already"));
977 SILC_LOG_DEBUG(("Changing %s channel user mode",
978 chl->client->nickname ? chl->client->nickname :
979 (unsigned char *)""));
981 /* Change the mode */
984 /* Send the same notify to the channel */
986 silc_server_packet_send_to_channel(server, NULL, channel,
988 FALSE, packet->buffer->data,
989 packet->buffer->len, FALSE);
991 silc_free(channel_id);
995 case SILC_NOTIFY_TYPE_INVITE:
997 if (packet->dst_id_type == SILC_ID_CLIENT)
1000 SILC_LOG_DEBUG(("INVITE notify"));
1002 /* Get Channel ID */
1003 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1006 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1010 /* Get channel entry */
1011 channel = silc_idlist_find_channel_by_id(server->global_list,
1014 channel = silc_idlist_find_channel_by_id(server->local_list,
1017 SILC_LOG_DEBUG(("Notify for unknown channel"));
1018 silc_free(channel_id);
1022 silc_free(channel_id);
1025 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1028 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1032 /* Get client entry */
1033 client = silc_idlist_find_client_by_id(server->global_list,
1034 client_id, TRUE, &cache);
1036 client = silc_idlist_find_client_by_id(server->local_list,
1037 client_id, TRUE, &cache);
1039 silc_free(client_id);
1043 silc_free(client_id);
1045 /* Get user's channel entry and check that inviting is allowed. */
1046 if (!silc_server_client_on_channel(client, channel, &chl))
1048 if (channel->mode & SILC_CHANNEL_MODE_INVITE &&
1049 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
1050 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1051 SILC_LOG_DEBUG(("Inviting is not allowed"));
1055 /* Get the added invite */
1056 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
1058 if (!channel->invite_list)
1059 channel->invite_list = silc_calloc(tmp_len + 2,
1060 sizeof(*channel->invite_list));
1062 channel->invite_list = silc_realloc(channel->invite_list,
1063 sizeof(*channel->invite_list) *
1065 strlen(channel->invite_list) +
1067 if (tmp[tmp_len - 1] == ',')
1068 tmp[tmp_len - 1] = '\0';
1070 strncat(channel->invite_list, tmp, tmp_len);
1071 strncat(channel->invite_list, ",", 1);
1074 /* Get the deleted invite */
1075 tmp = silc_argument_get_arg_type(args, 5, &tmp_len);
1076 if (tmp && channel->invite_list) {
1077 char *start, *end, *n;
1079 if (!strncmp(channel->invite_list, tmp,
1080 strlen(channel->invite_list) - 1)) {
1081 silc_free(channel->invite_list);
1082 channel->invite_list = NULL;
1084 start = strstr(channel->invite_list, tmp);
1085 if (start && strlen(start) >= tmp_len) {
1086 end = start + tmp_len;
1087 n = silc_calloc(strlen(channel->invite_list) - tmp_len, sizeof(*n));
1088 strncat(n, channel->invite_list, start - channel->invite_list);
1089 strncat(n, end + 1, ((channel->invite_list +
1090 strlen(channel->invite_list)) - end) - 1);
1091 silc_free(channel->invite_list);
1092 channel->invite_list = n;
1099 case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
1101 * Distribute to the local clients on the channel and change the
1105 SILC_LOG_DEBUG(("CHANNEL CHANGE"));
1107 if (sock->type != SILC_SOCKET_TYPE_ROUTER)
1110 /* Get the old Channel ID */
1111 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1114 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1118 /* Get the channel entry */
1119 channel = silc_idlist_find_channel_by_id(server->local_list,
1122 channel = silc_idlist_find_channel_by_id(server->global_list,
1125 SILC_LOG_DEBUG(("Notify for unknown channel"));
1126 silc_free(channel_id);
1131 /* Send the notify to the channel */
1132 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
1133 FALSE, packet->buffer->data,
1134 packet->buffer->len, FALSE);
1136 /* Get the new Channel ID */
1137 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1140 channel_id2 = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1144 SILC_LOG_DEBUG(("Old Channel ID id(%s)",
1145 silc_id_render(channel_id, SILC_ID_CHANNEL)));
1146 SILC_LOG_DEBUG(("New Channel ID id(%s)",
1147 silc_id_render(channel_id2, SILC_ID_CHANNEL)));
1149 /* Replace the Channel ID */
1150 if (!silc_idlist_replace_channel_id(server->local_list, channel_id,
1152 if (!silc_idlist_replace_channel_id(server->global_list, channel_id,
1154 silc_free(channel_id2);
1159 SilcBuffer modes = NULL, users = NULL, users_modes = NULL;
1161 /* Re-announce this channel which ID was changed. */
1162 silc_server_send_new_channel(server, sock, FALSE, channel->channel_name,
1164 silc_id_get_len(channel->id,
1168 /* Re-announce our clients on the channel as the ID has changed now */
1169 silc_server_announce_get_channel_users(server, channel, &modes, &users,
1172 silc_buffer_push(users, users->data - users->head);
1173 silc_server_packet_send(server, sock,
1174 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1175 users->data, users->len, FALSE);
1176 silc_buffer_free(users);
1179 silc_buffer_push(modes, modes->data - modes->head);
1180 silc_server_packet_send_dest(server, sock,
1181 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1182 channel->id, SILC_ID_CHANNEL,
1183 modes->data, modes->len, FALSE);
1184 silc_buffer_free(modes);
1187 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
1188 silc_server_packet_send_dest(server, sock,
1189 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1190 channel->id, SILC_ID_CHANNEL,
1192 users_modes->len, FALSE);
1193 silc_buffer_free(users_modes);
1196 /* Re-announce channel's topic */
1197 if (channel->topic) {
1198 silc_server_send_notify_topic_set(server, sock,
1199 server->server_type == SILC_ROUTER ?
1200 TRUE : FALSE, channel,
1201 server->id, SILC_ID_SERVER,
1206 silc_free(channel_id);
1210 case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
1212 * Remove the server entry and all clients that this server owns.
1215 SILC_LOG_DEBUG(("SERVER SIGNOFF notify"));
1218 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1221 server_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1225 /* Get server entry */
1226 server_entry = silc_idlist_find_server_by_id(server->global_list,
1227 server_id, TRUE, NULL);
1229 if (!server_entry) {
1230 server_entry = silc_idlist_find_server_by_id(server->local_list,
1231 server_id, TRUE, NULL);
1233 if (!server_entry) {
1234 /* If we are normal server then we might not have the server. Check
1235 whether router was kind enough to send the list of all clients
1236 that actually was to be removed. Remove them if the list is
1238 if (server->server_type != SILC_ROUTER &&
1239 silc_argument_get_arg_num(args) > 1) {
1242 for (i = 1; i < silc_argument_get_arg_num(args); i++) {
1244 tmp = silc_argument_get_arg_type(args, i + 1, &tmp_len);
1247 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1251 /* Get client entry */
1252 client = silc_idlist_find_client_by_id(server->global_list,
1253 client_id, TRUE, &cache);
1256 client = silc_idlist_find_client_by_id(server->local_list,
1257 client_id, TRUE, &cache);
1260 silc_free(client_id);
1264 silc_free(client_id);
1266 /* Update statistics */
1267 server->stat.clients--;
1268 if (server->stat.cell_clients)
1269 server->stat.cell_clients--;
1270 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
1271 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
1273 /* Remove the client from all channels. */
1274 silc_server_remove_from_channels(server, NULL, client,
1277 /* Check if anyone is watching this nickname */
1278 if (server->server_type == SILC_ROUTER)
1279 silc_server_check_watcher_list(server, client, NULL,
1280 SILC_NOTIFY_TYPE_SERVER_SIGNOFF);
1282 /* Remove this client from watcher list if it is */
1284 silc_server_del_from_watcher_list(server, client);
1286 /* Remove the client */
1287 silc_idlist_del_client(local ? server->local_list :
1288 server->global_list, client);
1292 silc_free(server_id);
1296 silc_free(server_id);
1298 /* Sending SERVER_SIGNOFF is not right way to signoff local connection */
1299 if (SILC_IS_LOCAL(server_entry))
1302 /* Remove all servers that are originated from this server, and
1303 remove the clients of those servers too. */
1304 silc_server_remove_servers_by_server(server, server_entry, TRUE);
1306 /* Remove the clients that this server owns as they will become
1308 silc_server_remove_clients_by_server(server, server_entry->router,
1309 server_entry, TRUE);
1310 silc_server_backup_del(server, server_entry);
1312 /* Remove the server entry */
1313 silc_idlist_del_server(local ? server->local_list :
1314 server->global_list, server_entry);
1316 /* Update statistics */
1317 if (server->server_type == SILC_ROUTER)
1318 server->stat.servers--;
1322 case SILC_NOTIFY_TYPE_KICKED:
1324 * Distribute the notify to local clients on the channel
1327 SILC_LOG_DEBUG(("KICKED notify"));
1330 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
1331 packet->dst_id_type);
1336 /* Get channel entry */
1337 channel = silc_idlist_find_channel_by_id(server->global_list,
1340 channel = silc_idlist_find_channel_by_id(server->local_list,
1343 SILC_LOG_DEBUG(("Notify for unknown channel"));
1344 silc_free(channel_id);
1348 silc_free(channel_id);
1351 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1354 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1358 /* If the the client is not in local list we check global list */
1359 client = silc_idlist_find_client_by_id(server->global_list,
1360 client_id, TRUE, NULL);
1362 client = silc_idlist_find_client_by_id(server->local_list,
1363 client_id, TRUE, NULL);
1365 silc_free(client_id);
1369 silc_free(client_id);
1371 /* If target is founder they cannot be kicked */
1372 if (!silc_server_client_on_channel(client, channel, &chl))
1374 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO)
1377 /* From protocol version 1.1 we get the kicker's ID as well. */
1378 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1380 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1384 /* If the the client is not in local list we check global list */
1385 client2 = silc_idlist_find_client_by_id(server->global_list,
1386 client_id, TRUE, NULL);
1388 client2 = silc_idlist_find_client_by_id(server->local_list,
1389 client_id, TRUE, NULL);
1391 silc_free(client_id);
1395 silc_free(client_id);
1397 /* Kicker must be operator on channel */
1398 if (!silc_server_client_on_channel(client2, channel, &chl))
1400 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
1401 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1402 SILC_LOG_DEBUG(("Kicking is not allowed"));
1407 /* Send to channel */
1408 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
1409 FALSE, packet->buffer->data,
1410 packet->buffer->len, FALSE);
1412 /* Remove the client from channel */
1413 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
1417 case SILC_NOTIFY_TYPE_KILLED:
1420 * Distribute the notify to local clients on channels
1422 unsigned char *id, *comment;
1423 SilcUInt32 id_len, comment_len;
1425 SILC_LOG_DEBUG(("KILLED notify"));
1428 id = silc_argument_get_arg_type(args, 1, &id_len);
1431 client_id = silc_id_payload_parse_id(id, id_len, NULL);
1435 /* If the the client is not in local list we check global list */
1436 client = silc_idlist_find_client_by_id(server->global_list,
1437 client_id, TRUE, &cache);
1439 client = silc_idlist_find_client_by_id(server->local_list,
1440 client_id, TRUE, &cache);
1442 silc_free(client_id);
1446 silc_free(client_id);
1448 /* If the client is one of ours, then close the connection to the
1449 client now. This removes the client from all channels as well. */
1450 if (packet->dst_id_type == SILC_ID_CLIENT && client->connection) {
1451 sock = client->connection;
1452 silc_server_free_client_data(server, NULL, client, FALSE, NULL);
1453 silc_server_close_connection(server, sock);
1458 comment = silc_argument_get_arg_type(args, 2, &comment_len);
1459 if (comment_len > 128)
1462 /* From protocol version 1.1 we get the killer's ID as well. */
1463 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1465 client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
1469 if (id_type == SILC_ID_CLIENT) {
1470 /* If the the client is not in local list we check global list */
1471 client2 = silc_idlist_find_client_by_id(server->global_list,
1472 client_id, TRUE, NULL);
1474 client2 = silc_idlist_find_client_by_id(server->local_list,
1475 client_id, TRUE, NULL);
1477 silc_free(client_id);
1481 silc_free(client_id);
1483 /* Killer must be router operator */
1484 if (server->server_type != SILC_SERVER &&
1485 !(client2->mode & SILC_UMODE_ROUTER_OPERATOR)) {
1486 SILC_LOG_DEBUG(("Killing is not allowed"));
1492 /* Send the notify to local clients on the channels except to the
1493 client who is killed. */
1494 silc_server_send_notify_on_channels(server, client, client,
1495 SILC_NOTIFY_TYPE_KILLED, 3,
1496 id, id_len, comment, comment_len,
1499 /* Remove the client from all channels */
1500 silc_server_remove_from_channels(server, NULL, client, FALSE, NULL,
1503 /* Check if anyone is watching this nickname */
1504 silc_server_check_watcher_list(server, client, NULL,
1505 SILC_NOTIFY_TYPE_KILLED);
1507 /* Update statistics */
1508 server->stat.clients--;
1509 if (server->stat.cell_clients)
1510 server->stat.cell_clients--;
1511 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
1512 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
1514 if (SILC_IS_LOCAL(client)) {
1515 server->stat.my_clients--;
1516 silc_schedule_task_del_by_context(server->schedule, client);
1517 silc_idlist_del_data(client);
1521 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
1522 cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
1526 case SILC_NOTIFY_TYPE_UMODE_CHANGE:
1528 * Save the mode of the client.
1531 SILC_LOG_DEBUG(("UMODE_CHANGE notify"));
1534 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1537 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1541 /* Get client entry */
1542 client = silc_idlist_find_client_by_id(server->global_list,
1543 client_id, TRUE, NULL);
1545 client = silc_idlist_find_client_by_id(server->local_list,
1546 client_id, TRUE, NULL);
1548 silc_free(client_id);
1552 silc_free(client_id);
1555 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1558 SILC_GET32_MSB(mode, tmp);
1560 /* Remove internal resumed flag if client is marked detached now */
1561 if (mode & SILC_UMODE_DETACHED)
1562 client->data.status &= ~SILC_IDLIST_STATUS_RESUMED;
1564 /* Update statistics */
1565 if (server->server_type == SILC_ROUTER) {
1566 if (mode & SILC_UMODE_GONE) {
1567 if (!(client->mode & SILC_UMODE_GONE))
1568 server->stat.aways++;
1570 if (client->mode & SILC_UMODE_GONE)
1571 server->stat.aways--;
1573 if (mode & SILC_UMODE_DETACHED) {
1574 if (!(client->mode & SILC_UMODE_DETACHED))
1575 server->stat.detached++;
1577 if (client->mode & SILC_UMODE_DETACHED)
1578 server->stat.detached--;
1582 /* Change the mode */
1583 client->mode = mode;
1585 /* Check if anyone is watching this nickname */
1586 if (server->server_type == SILC_ROUTER)
1587 silc_server_check_watcher_list(server, client, NULL,
1588 SILC_NOTIFY_TYPE_UMODE_CHANGE);
1592 case SILC_NOTIFY_TYPE_BAN:
1597 SILC_LOG_DEBUG(("BAN notify"));
1599 /* Get Channel ID */
1600 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1603 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1607 /* Get channel entry */
1608 channel = silc_idlist_find_channel_by_id(server->global_list,
1611 channel = silc_idlist_find_channel_by_id(server->local_list,
1614 SILC_LOG_DEBUG(("Notify for unknown channel"));
1615 silc_free(channel_id);
1619 silc_free(channel_id);
1621 /* Get the new ban and add it to the ban list */
1622 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1624 if (!channel->ban_list)
1625 channel->ban_list = silc_calloc(tmp_len + 2,
1626 sizeof(*channel->ban_list));
1628 channel->ban_list = silc_realloc(channel->ban_list,
1629 sizeof(*channel->ban_list) *
1631 strlen(channel->ban_list) + 2));
1632 strncat(channel->ban_list, tmp, tmp_len);
1633 strncat(channel->ban_list, ",", 1);
1636 /* Get the ban to be removed and remove it from the list */
1637 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1638 if (tmp && channel->ban_list) {
1639 char *start, *end, *n;
1641 if (!strncmp(channel->ban_list, tmp, strlen(channel->ban_list) - 1)) {
1642 silc_free(channel->ban_list);
1643 channel->ban_list = NULL;
1645 start = strstr(channel->ban_list, tmp);
1646 if (start && strlen(start) >= tmp_len) {
1647 end = start + tmp_len;
1648 n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
1649 strncat(n, channel->ban_list, start - channel->ban_list);
1650 strncat(n, end + 1, ((channel->ban_list +
1651 strlen(channel->ban_list)) - end) - 1);
1652 silc_free(channel->ban_list);
1653 channel->ban_list = n;
1659 case SILC_NOTIFY_TYPE_ERROR:
1666 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1667 if (!tmp && tmp_len != 1)
1669 error = (SilcStatus)tmp[0];
1671 SILC_LOG_DEBUG(("ERROR notify (%d)", error));
1673 if (error == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID &&
1674 sock->type == SILC_SOCKET_TYPE_ROUTER) {
1675 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1677 SILC_LOG_DEBUG(("Received invalid client ID notification, deleting "
1678 "the entry from cache"));
1679 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1682 client = silc_idlist_find_client_by_id(server->global_list,
1683 client_id, FALSE, NULL);
1685 silc_server_remove_from_channels(server, NULL, client, TRUE,
1687 silc_idlist_del_client(server->global_list, client);
1689 silc_free(client_id);
1695 /* Ignore rest of the notify types for now */
1696 case SILC_NOTIFY_TYPE_NONE:
1697 case SILC_NOTIFY_TYPE_MOTD:
1704 silc_notify_payload_free(payload);
1707 void silc_server_notify_list(SilcServer server,
1708 SilcSocketConnection sock,
1709 SilcPacketContext *packet)
1711 SilcPacketContext *new;
1715 SILC_LOG_DEBUG(("Processing Notify List"));
1717 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1718 packet->src_id_type != SILC_ID_SERVER)
1721 /* Make copy of the original packet context, except for the actual
1722 data buffer, which we will here now fetch from the original buffer. */
1723 new = silc_packet_context_alloc();
1724 new->type = SILC_PACKET_NOTIFY;
1725 new->flags = packet->flags;
1726 new->src_id = packet->src_id;
1727 new->src_id_len = packet->src_id_len;
1728 new->src_id_type = packet->src_id_type;
1729 new->dst_id = packet->dst_id;
1730 new->dst_id_len = packet->dst_id_len;
1731 new->dst_id_type = packet->dst_id_type;
1733 buffer = silc_buffer_alloc(1024);
1734 new->buffer = buffer;
1736 while (packet->buffer->len) {
1737 SILC_GET16_MSB(len, packet->buffer->data + 2);
1738 if (len > packet->buffer->len)
1741 if (len > buffer->truelen) {
1742 silc_buffer_free(buffer);
1743 buffer = silc_buffer_alloc(1024 + len);
1746 silc_buffer_pull_tail(buffer, len);
1747 silc_buffer_put(buffer, packet->buffer->data, len);
1749 /* Process the Notify */
1750 silc_server_notify(server, sock, new);
1752 silc_buffer_push_tail(buffer, len);
1753 silc_buffer_pull(packet->buffer, len);
1756 silc_buffer_free(buffer);
1760 /* Received private message. This resolves the destination of the message
1761 and sends the packet. This is used by both server and router. If the
1762 destination is our locally connected client this sends the packet to
1763 the client. This may also send the message for further routing if
1764 the destination is not in our server (or router). */
1766 void silc_server_private_message(SilcServer server,
1767 SilcSocketConnection sock,
1768 SilcPacketContext *packet)
1770 SilcSocketConnection dst_sock;
1771 SilcIDListData idata;
1772 SilcClientEntry client;
1774 SILC_LOG_DEBUG(("Start"));
1776 if (packet->src_id_type != SILC_ID_CLIENT ||
1777 packet->dst_id_type != SILC_ID_CLIENT || !packet->dst_id)
1780 /* Get the route to the client */
1781 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1782 packet->dst_id_len, NULL,
1786 unsigned char error;
1788 if (client && client->mode & SILC_UMODE_DETACHED) {
1789 SILC_LOG_DEBUG(("Client is detached, discarding packet"));
1793 /* Send SILC_NOTIFY_TYPE_ERROR to indicate that such destination ID
1794 does not exist or is invalid. */
1795 idp = silc_id_payload_encode_data(packet->dst_id,
1797 packet->dst_id_type);
1801 error = SILC_STATUS_ERR_NO_SUCH_CLIENT_ID;
1802 if (packet->src_id_type == SILC_ID_CLIENT) {
1803 SilcClientID *client_id = silc_id_str2id(packet->src_id,
1805 packet->src_id_type);
1806 silc_server_send_notify_dest(server, sock, FALSE,
1807 client_id, SILC_ID_CLIENT,
1808 SILC_NOTIFY_TYPE_ERROR, 2,
1810 idp->data, idp->len);
1811 silc_free(client_id);
1813 silc_server_send_notify(server, sock, FALSE,
1814 SILC_NOTIFY_TYPE_ERROR, 2,
1816 idp->data, idp->len);
1819 silc_buffer_free(idp);
1823 /* Check whether destination client wishes to receive private messages */
1824 if (client && !(packet->flags & SILC_PACKET_FLAG_PRIVMSG_KEY) &&
1825 client->mode & SILC_UMODE_BLOCK_PRIVMSG) {
1826 SILC_LOG_DEBUG(("Client blocks private messages, discarding packet"));
1830 /* Send the private message */
1831 silc_server_send_private_message(server, dst_sock, idata->send_key,
1832 idata->hmac_send, idata->psn_send++,
1836 /* Received private message key packet.. This packet is never for us. It is to
1837 the client in the packet's destination ID. Sending of this sort of packet
1838 equals sending private message, ie. it is sent point to point from
1839 one client to another. */
1841 void silc_server_private_message_key(SilcServer server,
1842 SilcSocketConnection sock,
1843 SilcPacketContext *packet)
1845 SilcSocketConnection dst_sock;
1846 SilcIDListData idata;
1848 SILC_LOG_DEBUG(("Start"));
1850 if (packet->src_id_type != SILC_ID_CLIENT ||
1851 packet->dst_id_type != SILC_ID_CLIENT)
1854 if (!packet->dst_id)
1857 /* Get the route to the client */
1858 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1859 packet->dst_id_len, NULL,
1864 /* Relay the packet */
1865 silc_server_relay_packet(server, dst_sock, idata->send_key,
1866 idata->hmac_send, idata->psn_send++, packet, FALSE);
1869 /* Processes incoming command reply packet. The command reply packet may
1870 be destined to one of our clients or it may directly for us. We will
1871 call the command reply routine after processing the packet. */
1873 void silc_server_command_reply(SilcServer server,
1874 SilcSocketConnection sock,
1875 SilcPacketContext *packet)
1877 SilcBuffer buffer = packet->buffer;
1878 SilcClientEntry client = NULL;
1879 SilcSocketConnection dst_sock;
1880 SilcIDListData idata;
1881 SilcClientID *id = NULL;
1883 SILC_LOG_DEBUG(("Start"));
1885 /* Source must be server or router */
1886 if (packet->src_id_type != SILC_ID_SERVER &&
1887 sock->type != SILC_SOCKET_TYPE_ROUTER)
1890 if (packet->dst_id_type == SILC_ID_CHANNEL)
1893 if (packet->dst_id_type == SILC_ID_CLIENT) {
1894 /* Destination must be one of ours */
1895 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
1898 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
1900 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
1906 if (packet->dst_id_type == SILC_ID_SERVER) {
1907 /* For now this must be for us */
1908 if (memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
1909 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
1914 /* Execute command reply locally for the command */
1915 silc_server_command_reply_process(server, sock, buffer);
1917 if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
1918 /* Relay the packet to the client */
1919 const SilcBufferStruct p;
1921 dst_sock = (SilcSocketConnection)client->connection;
1922 idata = (SilcIDListData)client;
1924 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
1925 + packet->dst_id_len + packet->padlen);
1926 if (!silc_packet_send_prepare(dst_sock, 0, 0, buffer->len,
1927 idata->hmac_send, (const SilcBuffer)&p)) {
1928 SILC_LOG_ERROR(("Cannot send packet"));
1931 silc_buffer_put((SilcBuffer)&p, buffer->data, buffer->len);
1933 /* Encrypt packet */
1934 silc_packet_encrypt(idata->send_key, idata->hmac_send, idata->psn_send++,
1935 (SilcBuffer)&p, buffer->len);
1937 /* Send the packet */
1938 silc_server_packet_send_real(server, dst_sock, TRUE);
1944 /* Process received channel message. The message can be originated from
1945 client or server. */
1947 void silc_server_channel_message(SilcServer server,
1948 SilcSocketConnection sock,
1949 SilcPacketContext *packet)
1951 SilcChannelEntry channel = NULL;
1952 SilcChannelID *id = NULL;
1953 void *sender_id = NULL;
1954 SilcClientEntry sender_entry = NULL;
1955 SilcChannelClientEntry chl;
1958 SILC_LOG_DEBUG(("Processing channel message"));
1961 if (packet->dst_id_type != SILC_ID_CHANNEL) {
1962 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1966 /* Find channel entry */
1967 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
1970 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
1972 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
1975 unsigned char error;
1977 /* Send SILC_NOTIFY_TYPE_ERROR to indicate that such destination ID
1978 does not exist or is invalid. */
1979 idp = silc_id_payload_encode_data(packet->dst_id,
1981 packet->dst_id_type);
1985 error = SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID;
1986 if (packet->src_id_type == SILC_ID_CLIENT) {
1987 SilcClientID *client_id = silc_id_str2id(packet->src_id,
1989 packet->src_id_type);
1990 silc_server_send_notify_dest(server, sock, FALSE,
1991 client_id, SILC_ID_CLIENT,
1992 SILC_NOTIFY_TYPE_ERROR, 2,
1993 &error, 1, idp->data, idp->len);
1994 silc_free(client_id);
1996 silc_server_send_notify(server, sock, FALSE,
1997 SILC_NOTIFY_TYPE_ERROR, 2,
1998 &error, 1, idp->data, idp->len);
2001 silc_buffer_free(idp);
2006 /* See that this client is on the channel. If the original sender is
2007 not client (as it can be server as well) we don't do the check. */
2008 sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2009 packet->src_id_type);
2012 if (packet->src_id_type == SILC_ID_CLIENT) {
2013 sender_entry = silc_idlist_find_client_by_id(server->local_list,
2014 sender_id, TRUE, NULL);
2015 if (!sender_entry) {
2017 sender_entry = silc_idlist_find_client_by_id(server->global_list,
2018 sender_id, TRUE, NULL);
2020 if (!sender_entry || !silc_server_client_on_channel(sender_entry,
2022 SILC_LOG_DEBUG(("Client not on channel"));
2026 /* If channel is moderated check that client is allowed to send
2028 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS &&
2029 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
2030 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
2031 SILC_LOG_DEBUG(("Channel is silenced from normal users"));
2034 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS &&
2035 chl->mode & SILC_CHANNEL_UMODE_CHANOP &&
2036 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
2037 SILC_LOG_DEBUG(("Channel is silenced from operators"));
2040 if (chl->mode & SILC_CHANNEL_UMODE_QUIET) {
2041 SILC_LOG_DEBUG(("Sender is quieted on the channel"));
2045 /* If the packet is coming from router, but the client entry is local
2046 entry to us then some router is rerouting this to us and it is not
2047 allowed. When the client is local to us it means that we've routed
2048 this packet to network, and now someone is routing it back to us. */
2049 if (server->server_type == SILC_ROUTER &&
2050 sock->type == SILC_SOCKET_TYPE_ROUTER && local) {
2051 SILC_LOG_DEBUG(("Channel message rerouted to the sender, drop it"));
2056 /* Distribute the packet to our local clients. This will send the
2057 packet for further routing as well, if needed. */
2058 silc_server_packet_relay_to_channel(server, sock, channel, sender_id,
2059 packet->src_id_type, sender_entry,
2060 packet->buffer->data,
2061 packet->buffer->len, FALSE);
2064 silc_free(sender_id);
2068 /* Received channel key packet. We distribute the key to all of our locally
2069 connected clients on the channel. */
2071 void silc_server_channel_key(SilcServer server,
2072 SilcSocketConnection sock,
2073 SilcPacketContext *packet)
2075 SilcBuffer buffer = packet->buffer;
2076 SilcChannelEntry channel;
2078 if (packet->src_id_type != SILC_ID_SERVER ||
2079 (server->server_type == SILC_ROUTER &&
2080 sock->type == SILC_SOCKET_TYPE_ROUTER))
2083 /* Save the channel key */
2084 channel = silc_server_save_channel_key(server, buffer, NULL);
2088 /* Distribute the key to everybody who is on the channel. If we are router
2089 we will also send it to locally connected servers. */
2090 silc_server_send_channel_key(server, sock, channel, FALSE);
2092 if (server->server_type != SILC_BACKUP_ROUTER) {
2093 /* Distribute to local cell backup routers. */
2094 silc_server_backup_send(server, sock->user_data,
2095 SILC_PACKET_CHANNEL_KEY, 0,
2096 buffer->data, buffer->len, FALSE, TRUE);
2100 /* Received New Client packet and processes it. Creates Client ID for the
2101 client. Client becomes registered after calling this functions. */
2103 SilcClientEntry silc_server_new_client(SilcServer server,
2104 SilcSocketConnection sock,
2105 SilcPacketContext *packet)
2107 SilcBuffer buffer = packet->buffer;
2108 SilcClientEntry client;
2109 SilcClientID *client_id;
2110 SilcIDListData idata;
2111 char *username = NULL, *realname = NULL;
2112 SilcUInt16 username_len;
2115 char *hostname, *nickname;
2118 SILC_LOG_DEBUG(("Creating new client"));
2120 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
2123 /* Take client entry */
2124 client = (SilcClientEntry)sock->user_data;
2125 idata = (SilcIDListData)client;
2127 /* Remove the old cache entry. */
2128 if (!silc_idcache_del_by_context(server->local_list->clients, client)) {
2129 SILC_LOG_INFO(("Unauthenticated client attempted to register to network"));
2130 silc_server_disconnect_remote(server, sock,
2131 SILC_STATUS_ERR_NOT_AUTHENTICATED, NULL);
2132 if (sock->user_data)
2133 silc_server_free_sock_user_data(server, sock, NULL);
2137 /* Parse incoming packet */
2138 ret = silc_buffer_unformat(buffer,
2139 SILC_STR_UI16_NSTRING_ALLOC(&username,
2141 SILC_STR_UI16_STRING_ALLOC(&realname),
2144 silc_free(username);
2145 silc_free(realname);
2146 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2147 "connection", sock->hostname, sock->ip));
2148 silc_server_disconnect_remote(server, sock,
2149 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2151 if (sock->user_data)
2152 silc_server_free_sock_user_data(server, sock, NULL);
2157 silc_free(username);
2158 silc_free(realname);
2159 SILC_LOG_ERROR(("Client %s (%s) did not send its username, 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);
2169 if (username_len > 128)
2170 username[128] = '\0';
2172 /* Check for bad characters for nickname, and modify the nickname if
2173 it includes those. */
2174 if (silc_server_name_bad_chars(username, username_len)) {
2175 nickname = silc_server_name_modify_bad(username, username_len);
2177 nickname = strdup(username);
2180 /* Make sanity checks for the hostname of the client. If the hostname
2181 is provided in the `username' check that it is the same than the
2182 resolved hostname, or if not resolved the hostname that appears in
2183 the client's public key. If the hostname is not present then put
2184 it from the resolved name or from the public key. */
2185 if (strchr(username, '@')) {
2186 SilcPublicKeyIdentifier pident;
2187 int tlen = strcspn(username, "@");
2188 char *phostname = NULL;
2190 hostname = silc_memdup(username + tlen + 1, strlen(username) - tlen - 1);
2192 if (strcmp(sock->hostname, sock->ip) &&
2193 strcmp(sock->hostname, hostname)) {
2194 silc_free(username);
2195 silc_free(hostname);
2196 silc_free(realname);
2197 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2198 "connection", sock->hostname, sock->ip));
2199 silc_server_disconnect_remote(server, sock,
2200 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2202 if (sock->user_data)
2203 silc_server_free_sock_user_data(server, sock, NULL);
2207 pident = silc_pkcs_decode_identifier(client->data.public_key->identifier);
2209 phostname = strdup(pident->host);
2210 silc_pkcs_free_identifier(pident);
2213 if (!strcmp(sock->hostname, sock->ip) &&
2214 phostname && strcmp(phostname, hostname)) {
2215 silc_free(username);
2216 silc_free(hostname);
2217 silc_free(phostname);
2218 silc_free(realname);
2219 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2220 "connection", sock->hostname, sock->ip));
2221 silc_server_disconnect_remote(server, sock,
2222 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2224 if (sock->user_data)
2225 silc_server_free_sock_user_data(server, sock, NULL);
2229 silc_free(phostname);
2231 /* The hostname is not present, add it. */
2233 /* XXX For now we cannot take the host name from the public key since
2234 they are not trusted or we cannot verify them as trusted. Just take
2235 what the resolved name or address is. */
2237 if (strcmp(sock->hostname, sock->ip)) {
2239 newusername = silc_calloc(strlen(username) +
2240 strlen(sock->hostname) + 2,
2241 sizeof(*newusername));
2242 strncat(newusername, username, strlen(username));
2243 strncat(newusername, "@", 1);
2244 strncat(newusername, sock->hostname, strlen(sock->hostname));
2245 silc_free(username);
2246 username = newusername;
2249 SilcPublicKeyIdentifier pident =
2250 silc_pkcs_decode_identifier(client->data.public_key->identifier);
2253 newusername = silc_calloc(strlen(username) +
2254 strlen(pident->host) + 2,
2255 sizeof(*newusername));
2256 strncat(newusername, username, strlen(username));
2257 strncat(newusername, "@", 1);
2258 strncat(newusername, pident->host, strlen(pident->host));
2259 silc_free(username);
2260 username = newusername;
2261 silc_pkcs_free_identifier(pident);
2267 /* Create Client ID */
2268 while (!silc_id_create_client_id(server, server->id, server->rng,
2269 server->md5hash, nickname, &client_id)) {
2272 silc_server_disconnect_remote(server, sock,
2273 SILC_STATUS_ERR_BAD_NICKNAME, NULL);
2274 if (sock->user_data)
2275 silc_server_free_sock_user_data(server, sock, NULL);
2278 snprintf(&nickname[strlen(nickname) - 1], 1, "%d", nickfail);
2281 /* Update client entry */
2282 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
2283 client->nickname = nickname;
2284 client->username = username;
2285 client->userinfo = realname ? realname : strdup(" ");
2286 client->id = client_id;
2287 id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
2289 /* Add the client again to the ID cache */
2290 silc_idcache_add(server->local_list->clients, client->nickname,
2291 client_id, client, 0, NULL);
2293 /* Notify our router about new client on the SILC network */
2294 silc_server_send_new_id(server, SILC_PRIMARY_ROUTE(server),
2295 SILC_BROADCAST(server), client->id,
2296 SILC_ID_CLIENT, id_len);
2298 /* Distribute to backup routers */
2299 if (server->server_type == SILC_ROUTER) {
2300 SilcBuffer idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
2301 silc_server_backup_send(server, sock->user_data, SILC_PACKET_NEW_ID, 0,
2302 idp->data, idp->len, FALSE, TRUE);
2303 silc_buffer_free(idp);
2306 /* Send the new client ID to the client. */
2307 silc_server_send_new_id(server, sock, FALSE, client->id, SILC_ID_CLIENT,
2308 silc_id_get_len(client->id, SILC_ID_CLIENT));
2310 /* Send some nice info to the client */
2311 silc_server_send_connect_notifys(server, sock, client);
2313 /* Check if anyone is watching this nickname */
2314 if (server->server_type == SILC_ROUTER)
2315 silc_server_check_watcher_list(server, client, NULL, 0);
2320 /* Create new server. This processes received New Server packet and
2321 saves the received Server ID. The server is our locally connected
2322 server thus we save all the information and save it to local list.
2323 This funtion can be used by both normal server and router server.
2324 If normal server uses this it means that its router has connected
2325 to the server. If router uses this it means that one of the cell's
2326 servers is connected to the router. */
2328 SilcServerEntry silc_server_new_server(SilcServer server,
2329 SilcSocketConnection sock,
2330 SilcPacketContext *packet)
2332 SilcBuffer buffer = packet->buffer;
2333 SilcServerEntry new_server, server_entry;
2334 SilcServerID *server_id;
2335 SilcIDListData idata;
2336 unsigned char *server_name, *id_string;
2337 SilcUInt16 id_len, name_len;
2341 SILC_LOG_DEBUG(("Creating new server"));
2343 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
2344 sock->type != SILC_SOCKET_TYPE_ROUTER)
2347 /* Take server entry */
2348 new_server = (SilcServerEntry)sock->user_data;
2349 idata = (SilcIDListData)new_server;
2351 /* Remove the old cache entry */
2352 if (!silc_idcache_del_by_context(server->local_list->servers, new_server)) {
2353 if (!silc_idcache_del_by_context(server->global_list->servers,
2355 SILC_LOG_INFO(("Unauthenticated %s attempted to register to "
2356 "network", (sock->type == SILC_SOCKET_TYPE_SERVER ?
2357 "server" : "router")));
2358 silc_server_disconnect_remote(server, sock,
2359 SILC_STATUS_ERR_NOT_AUTHENTICATED, NULL);
2360 if (sock->user_data)
2361 silc_server_free_sock_user_data(server, sock, NULL);
2367 /* Parse the incoming packet */
2368 ret = silc_buffer_unformat(buffer,
2369 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
2370 SILC_STR_UI16_NSTRING_ALLOC(&server_name,
2374 silc_free(id_string);
2375 silc_free(server_name);
2376 silc_server_disconnect_remote(server, sock,
2377 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2379 if (sock->user_data)
2380 silc_server_free_sock_user_data(server, sock, NULL);
2384 if (id_len > buffer->len) {
2385 silc_free(id_string);
2386 silc_free(server_name);
2387 silc_server_disconnect_remote(server, sock,
2388 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2390 if (sock->user_data)
2391 silc_server_free_sock_user_data(server, sock, NULL);
2396 server_name[255] = '\0';
2399 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
2401 silc_free(id_string);
2402 silc_free(server_name);
2403 silc_server_disconnect_remote(server, sock,
2404 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2406 if (sock->user_data)
2407 silc_server_free_sock_user_data(server, sock, NULL);
2410 silc_free(id_string);
2412 /* Check for valid server ID */
2413 if (!silc_id_is_valid_server_id(server, server_id, sock)) {
2414 SILC_LOG_INFO(("Invalid server ID sent by %s (%s)",
2415 sock->ip, sock->hostname));
2416 silc_server_disconnect_remote(server, sock,
2417 SILC_STATUS_ERR_BAD_SERVER_ID, NULL);
2418 if (sock->user_data)
2419 silc_server_free_sock_user_data(server, sock, NULL);
2420 silc_free(server_name);
2424 /* Check that we do not have this ID already */
2425 server_entry = silc_idlist_find_server_by_id(server->local_list,
2426 server_id, TRUE, NULL);
2428 silc_idcache_del_by_context(server->local_list->servers, server_entry);
2430 server_entry = silc_idlist_find_server_by_id(server->global_list,
2431 server_id, TRUE, NULL);
2433 silc_idcache_del_by_context(server->global_list->servers, server_entry);
2436 /* Update server entry */
2437 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
2438 new_server->server_name = server_name;
2439 new_server->id = server_id;
2441 SILC_LOG_DEBUG(("New server id(%s)",
2442 silc_id_render(server_id, SILC_ID_SERVER)));
2444 /* Add again the entry to the ID cache. */
2445 silc_idcache_add(local ? server->local_list->servers :
2446 server->global_list->servers, server_name, server_id,
2447 new_server, 0, NULL);
2449 /* Distribute the information about new server in the SILC network
2450 to our router. If we are normal server we won't send anything
2451 since this connection must be our router connection. */
2452 if (server->server_type == SILC_ROUTER && !server->standalone &&
2453 SILC_PRIMARY_ROUTE(server) != sock)
2454 silc_server_send_new_id(server, SILC_PRIMARY_ROUTE(server),
2455 TRUE, new_server->id, SILC_ID_SERVER,
2456 silc_id_get_len(server_id, SILC_ID_SERVER));
2458 if (server->server_type == SILC_ROUTER) {
2459 /* Distribute to backup routers */
2460 SilcBuffer idp = silc_id_payload_encode(new_server->id, SILC_ID_SERVER);
2461 silc_server_backup_send(server, sock->user_data, SILC_PACKET_NEW_ID, 0,
2462 idp->data, idp->len, FALSE, TRUE);
2463 silc_buffer_free(idp);
2466 server->stat.cell_servers++;
2469 /* Check whether this router connection has been replaced by an
2470 backup router. If it has been then we'll disable the server and will
2471 ignore everything it will send until the backup router resuming
2472 protocol has been completed. */
2473 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
2474 silc_server_backup_replaced_get(server, server_id, NULL)) {
2475 /* Send packet to the server indicating that it cannot use this
2476 connection as it has been replaced by backup router. */
2477 SilcBuffer packet = silc_buffer_alloc(2);
2478 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
2479 silc_buffer_format(packet,
2480 SILC_STR_UI_CHAR(SILC_SERVER_BACKUP_REPLACED),
2481 SILC_STR_UI_CHAR(0),
2483 silc_server_packet_send(server, sock,
2484 SILC_PACKET_RESUME_ROUTER, 0,
2485 packet->data, packet->len, TRUE);
2486 silc_buffer_free(packet);
2488 /* Mark the router disabled. The data sent earlier will go but nothing
2489 after this does not go to this connection. */
2490 idata->status |= SILC_IDLIST_STATUS_DISABLED;
2492 /* If it is router announce our stuff to it. */
2493 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
2494 server->server_type == SILC_ROUTER) {
2495 silc_server_announce_servers(server, FALSE, 0, sock);
2496 silc_server_announce_clients(server, 0, sock);
2497 silc_server_announce_channels(server, 0, sock);
2500 /* Announce our information to backup router */
2501 if (new_server->server_type == SILC_BACKUP_ROUTER &&
2502 sock->type == SILC_SOCKET_TYPE_SERVER &&
2503 server->server_type == SILC_ROUTER) {
2504 silc_server_announce_servers(server, TRUE, 0, sock);
2505 silc_server_announce_clients(server, 0, sock);
2506 silc_server_announce_channels(server, 0, sock);
2509 /* If backup router, mark it as one of ours. This server is considered
2510 to be backup router after this setting. */
2511 if (new_server->server_type == SILC_BACKUP_ROUTER) {
2512 SilcServerConfigRouter *backup;
2513 backup = silc_server_config_find_backup_conn(server, sock->ip);
2515 backup = silc_server_config_find_backup_conn(server, sock->hostname);
2517 /* Add as our backup router */
2518 silc_server_backup_add(server, new_server, backup->backup_replace_ip,
2519 backup->backup_replace_port,
2520 backup->backup_local);
2524 /* By default the servers connected to backup router are disabled
2525 until backup router has become the primary */
2526 if (server->server_type == SILC_BACKUP_ROUTER &&
2527 sock->type == SILC_SOCKET_TYPE_SERVER)
2528 idata->status |= SILC_IDLIST_STATUS_DISABLED;
2534 /* Processes incoming New ID packet. New ID Payload is used to distribute
2535 information about newly registered clients and servers. */
2537 static void silc_server_new_id_real(SilcServer server,
2538 SilcSocketConnection sock,
2539 SilcPacketContext *packet,
2542 SilcBuffer buffer = packet->buffer;
2544 SilcServerEntry router, server_entry;
2545 SilcSocketConnection router_sock;
2550 SILC_LOG_DEBUG(("Processing new ID"));
2552 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2553 server->server_type == SILC_SERVER ||
2554 packet->src_id_type != SILC_ID_SERVER)
2557 idp = silc_id_payload_parse(buffer->data, buffer->len);
2561 id_type = silc_id_payload_get_type(idp);
2563 /* Normal server cannot have other normal server connections */
2564 server_entry = (SilcServerEntry)sock->user_data;
2565 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER &&
2566 server_entry->server_type == SILC_SERVER)
2569 id = silc_id_payload_get_id(idp);
2573 /* If the packet is coming from server then use the sender as the
2574 origin of the the packet. If it came from router then check the real
2575 sender of the packet and use that as the origin. */
2576 if (sock->type == SILC_SOCKET_TYPE_SERVER) {
2577 id_list = server->local_list;
2579 router = sock->user_data;
2581 /* If the sender is backup router and ID is server (and we are not
2582 backup router) then switch the entry to global list. */
2583 if (server_entry->server_type == SILC_BACKUP_ROUTER &&
2584 id_type == SILC_ID_SERVER &&
2585 server->id_entry->server_type != SILC_BACKUP_ROUTER) {
2586 id_list = server->global_list;
2587 router_sock = server->router ? SILC_PRIMARY_ROUTE(server) : sock;
2590 void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2591 packet->src_id_type);
2592 router = silc_idlist_find_server_by_id(server->global_list,
2593 sender_id, TRUE, NULL);
2595 router = silc_idlist_find_server_by_id(server->local_list,
2596 sender_id, TRUE, NULL);
2597 silc_free(sender_id);
2599 id_list = server->global_list;
2606 case SILC_ID_CLIENT:
2608 SilcClientEntry entry;
2610 /* Check that we do not have this client already */
2611 entry = silc_idlist_find_client_by_id(server->global_list,
2612 id, server->server_type,
2615 entry = silc_idlist_find_client_by_id(server->local_list,
2616 id, server->server_type,
2619 SILC_LOG_DEBUG(("Ignoring client that we already have"));
2623 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
2624 silc_id_render(id, SILC_ID_CLIENT),
2625 sock->type == SILC_SOCKET_TYPE_SERVER ?
2626 "Server" : "Router", sock->hostname));
2628 /* As a router we keep information of all global information in our
2629 global list. Cell wide information however is kept in the local
2631 entry = silc_idlist_add_client(id_list, NULL, NULL, NULL,
2632 id, router, NULL, 0);
2634 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
2636 /* Inform the sender that the ID is not usable */
2637 silc_server_send_notify_signoff(server, sock, FALSE, id, NULL);
2640 entry->nickname = NULL;
2641 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2643 if (sock->type == SILC_SOCKET_TYPE_SERVER)
2644 server->stat.cell_clients++;
2645 server->stat.clients++;
2647 /* Check if anyone is watching this nickname */
2648 if (server->server_type == SILC_ROUTER && id_list == server->local_list)
2649 silc_server_check_watcher_list(server, entry, NULL, 0);
2653 case SILC_ID_SERVER:
2655 SilcServerEntry entry;
2657 /* If the ID is mine, ignore it. */
2658 if (SILC_ID_SERVER_COMPARE(id, server->id)) {
2659 SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
2663 /* If the ID is the sender's ID, ignore it (we have it already) */
2664 if (SILC_ID_SERVER_COMPARE(id, router->id)) {
2665 SILC_LOG_DEBUG(("Ignoring sender's own ID"));
2669 /* Check that we do not have this server already */
2670 entry = silc_idlist_find_server_by_id(server->global_list,
2671 id, server->server_type,
2674 entry = silc_idlist_find_server_by_id(server->local_list,
2675 id, server->server_type,
2678 SILC_LOG_DEBUG(("Ignoring server that we already have"));
2682 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
2683 silc_id_render(id, SILC_ID_SERVER),
2684 sock->type == SILC_SOCKET_TYPE_SERVER ?
2685 "Server" : "Router", sock->hostname));
2687 /* As a router we keep information of all global information in our
2688 global list. Cell wide information however is kept in the local
2690 entry = silc_idlist_add_server(id_list, NULL, 0, id, router,
2693 SILC_LOG_ERROR(("Could not add new server to the ID Cache"));
2696 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2698 if (sock->type == SILC_SOCKET_TYPE_SERVER)
2699 server->stat.cell_servers++;
2700 server->stat.servers++;
2704 case SILC_ID_CHANNEL:
2705 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
2714 /* If the sender of this packet is server and we are router we need to
2715 broadcast this packet to other routers in the network. */
2716 if (broadcast && server->server_type == SILC_ROUTER &&
2717 sock->type == SILC_SOCKET_TYPE_SERVER &&
2718 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2719 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
2720 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
2722 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2723 buffer->data, buffer->len, FALSE);
2724 silc_server_backup_send(server, sock->user_data,
2725 packet->type, packet->flags,
2726 packet->buffer->data, packet->buffer->len,
2731 silc_id_payload_free(idp);
2735 /* Processes incoming New ID packet. New ID Payload is used to distribute
2736 information about newly registered clients and servers. */
2738 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
2739 SilcPacketContext *packet)
2741 silc_server_new_id_real(server, sock, packet, TRUE);
2744 /* Receoved New Id List packet, list of New ID payloads inside one
2745 packet. Process the New ID payloads one by one. */
2747 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
2748 SilcPacketContext *packet)
2750 SilcPacketContext *new_id;
2754 SILC_LOG_DEBUG(("Processing New ID List"));
2756 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2757 packet->src_id_type != SILC_ID_SERVER)
2760 /* If the sender of this packet is server and we are router we need to
2761 broadcast this packet to other routers in the network. Broadcast
2762 this list packet instead of multiple New ID packets. */
2763 if (server->server_type == SILC_ROUTER &&
2764 sock->type == SILC_SOCKET_TYPE_SERVER &&
2765 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2766 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
2767 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
2769 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2770 packet->buffer->data,
2771 packet->buffer->len, FALSE);
2772 silc_server_backup_send(server, sock->user_data,
2773 packet->type, packet->flags,
2774 packet->buffer->data, packet->buffer->len,
2778 /* Make copy of the original packet context, except for the actual
2779 data buffer, which we will here now fetch from the original buffer. */
2780 new_id = silc_packet_context_alloc();
2781 new_id->type = SILC_PACKET_NEW_ID;
2782 new_id->flags = packet->flags & (~SILC_PACKET_FLAG_LIST);
2783 new_id->src_id = packet->src_id;
2784 new_id->src_id_len = packet->src_id_len;
2785 new_id->src_id_type = packet->src_id_type;
2786 new_id->dst_id = packet->dst_id;
2787 new_id->dst_id_len = packet->dst_id_len;
2788 new_id->dst_id_type = packet->dst_id_type;
2790 idp = silc_buffer_alloc(256);
2791 new_id->buffer = idp;
2793 while (packet->buffer->len) {
2794 SILC_GET16_MSB(id_len, packet->buffer->data + 2);
2795 if ((id_len > packet->buffer->len) ||
2796 (id_len > idp->truelen))
2799 silc_buffer_pull_tail(idp, 4 + id_len);
2800 silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
2802 /* Process the New ID */
2803 silc_server_new_id_real(server, sock, new_id, FALSE);
2805 silc_buffer_push_tail(idp, 4 + id_len);
2806 silc_buffer_pull(packet->buffer, 4 + id_len);
2809 silc_buffer_free(idp);
2813 /* Received New Channel packet. Information about new channels in the
2814 network are distributed using this packet. Save the information about
2815 the new channel. This usually comes from router but also normal server
2816 can send this to notify channels it has when it connects to us. */
2818 void silc_server_new_channel(SilcServer server,
2819 SilcSocketConnection sock,
2820 SilcPacketContext *packet)
2822 SilcChannelPayload payload;
2823 SilcChannelID *channel_id;
2825 SilcUInt32 name_len;
2828 SilcServerEntry server_entry;
2829 SilcChannelEntry channel;
2831 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2832 packet->src_id_type != SILC_ID_SERVER ||
2833 server->server_type == SILC_SERVER)
2836 /* Parse the channel payload */
2837 payload = silc_channel_payload_parse(packet->buffer->data,
2838 packet->buffer->len);
2842 /* Get the channel ID */
2843 channel_id = silc_channel_get_id_parse(payload);
2845 silc_channel_payload_free(payload);
2849 channel_name = silc_channel_get_name(payload, &name_len);
2851 channel_name[255] = '\0';
2853 id = silc_channel_get_id(payload, &id_len);
2855 server_entry = (SilcServerEntry)sock->user_data;
2857 if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
2858 /* Add the channel to global list as it is coming from router. It
2859 cannot be our own channel as it is coming from router. */
2861 /* Check that we don't already have this channel */
2862 channel = silc_idlist_find_channel_by_name(server->local_list,
2863 channel_name, NULL);
2865 channel = silc_idlist_find_channel_by_name(server->global_list,
2866 channel_name, NULL);
2868 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
2869 silc_id_render(channel_id, SILC_ID_CHANNEL),
2873 silc_idlist_add_channel(server->global_list, strdup(channel_name),
2874 0, channel_id, sock->user_data, NULL, NULL, 0);
2877 channel->disabled = TRUE; /* Disabled until someone JOINs */
2879 server->stat.channels++;
2880 if (server->server_type == SILC_ROUTER)
2881 channel->users_resolved = TRUE;
2884 /* The channel is coming from our server, thus it is in our cell
2885 we will add it to our local list. */
2888 SILC_LOG_DEBUG(("Channel id(%s) from [Server] %s",
2889 silc_id_render(channel_id, SILC_ID_CHANNEL),
2892 /* Check that we don't already have this channel */
2893 channel = silc_idlist_find_channel_by_name(server->local_list,
2894 channel_name, NULL);
2896 channel = silc_idlist_find_channel_by_name(server->global_list,
2897 channel_name, NULL);
2899 /* If the channel does not exist, then create it. This creates a new
2900 key to the channel as well that we will send to the server. */
2902 SILC_LOG_DEBUG(("Channel is new to us"));
2904 /* The protocol says that the Channel ID's IP address must be based
2905 on the router's IP address. Check whether the ID is based in our
2906 IP and if it is not then create a new ID and enforce the server
2907 to switch the ID. */
2908 if (server_entry->server_type != SILC_BACKUP_ROUTER &&
2909 !SILC_ID_COMPARE(channel_id, server->id, server->id->ip.data_len)) {
2911 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2912 if (silc_id_create_channel_id(server, server->id, server->rng, &tmp)) {
2913 silc_server_send_notify_channel_change(server, sock, FALSE,
2915 silc_free(channel_id);
2919 /* Wait that server re-announces this channel */
2923 /* Create the channel with the provided Channel ID */
2924 channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
2928 silc_channel_payload_free(payload);
2929 silc_free(channel_id);
2932 channel->disabled = TRUE; /* Disabled until someone JOINs */
2934 #if 0 /* We assume that CMODE_CHANGE notify is sent to us after this. */
2936 /* XXX Dunno if this is supposed to be set in any server type. If set
2937 here the CMODE_CHANGE that may follow sets mode that we already
2938 have, and we may loose data from the CMODE_CHANGE notify. */
2939 if (server_entry->server_type != SILC_BACKUP_ROUTER)
2940 channel->mode = silc_channel_get_mode(payload);
2943 /* Send the new channel key to the server */
2944 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2945 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
2946 chk = silc_channel_key_payload_encode(id_len, id,
2947 strlen(channel->channel_key->
2949 channel->channel_key->cipher->name,
2950 channel->key_len / 8,
2952 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
2953 chk->data, chk->len, FALSE);
2954 silc_buffer_free(chk);
2956 /* The channel exist by that name, check whether the ID's match.
2957 If they don't then we'll force the server to use the ID we have.
2958 We also create a new key for the channel. */
2959 SilcBuffer modes = NULL, users = NULL, users_modes = NULL;
2961 SILC_LOG_DEBUG(("Channel already exists"));
2963 if (!SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
2964 /* They don't match, send CHANNEL_CHANGE notify to the server to
2965 force the ID change. */
2966 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2967 silc_server_send_notify_channel_change(server, sock, FALSE,
2968 channel_id, channel->id);
2970 /* Wait that server re-announces this channel */
2974 #if 0 /* We will announce our CMODE anyway for this channel, so no need
2975 to check it (implicit enforce). */
2977 /* If the mode is different from what we have then enforce the
2979 mode = silc_channel_get_mode(payload);
2980 if (channel->mode != mode) {
2981 SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
2982 silc_server_send_notify_cmode(server, sock, FALSE, channel,
2983 channel->mode, server->id,
2984 SILC_ID_SERVER, channel->cipher,
2986 channel->passphrase,
2987 channel->founder_key);
2991 /* Create new key for the channel and send it to the server and
2992 everybody else possibly on the channel. */
2993 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
2995 if (silc_hash_table_count(channel->user_list)) {
2996 if (!silc_server_create_channel_key(server, channel, 0))
2999 /* Send to the channel */
3000 silc_server_send_channel_key(server, sock, channel, FALSE);
3003 /* Send to the server */
3004 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3005 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
3006 chk = silc_channel_key_payload_encode(id_len, id,
3007 strlen(channel->channel_key->
3009 channel->channel_key->
3011 channel->key_len / 8,
3013 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
3014 chk->data, chk->len, FALSE);
3015 silc_buffer_free(chk);
3019 silc_free(channel_id);
3021 /* Update statistics */
3022 server->stat.channels++;
3023 server->stat.cell_channels++;
3025 /* Since the channel is coming from server and we also know about it
3026 then send the JOIN notify to the server so that it see's our
3027 users on the channel "joining" the channel. */
3028 silc_server_announce_get_channel_users(server, channel, &modes, &users,
3031 silc_buffer_push(users, users->data - users->head);
3032 silc_server_packet_send(server, sock,
3033 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3034 users->data, users->len, FALSE);
3035 silc_buffer_free(users);
3038 silc_buffer_push(modes, modes->data - modes->head);
3039 silc_server_packet_send_dest(server, sock,
3040 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3041 channel->id, SILC_ID_CHANNEL,
3042 modes->data, modes->len, FALSE);
3043 silc_buffer_free(modes);
3046 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
3047 silc_server_packet_send_dest(server, sock,
3048 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3049 channel->id, SILC_ID_CHANNEL,
3051 users_modes->len, FALSE);
3052 silc_buffer_free(users_modes);
3054 if (channel->topic) {
3055 silc_server_send_notify_topic_set(server, sock,
3056 server->server_type == SILC_ROUTER ?
3057 TRUE : FALSE, channel,
3058 server->id, SILC_ID_SERVER,
3064 /* If the sender of this packet is server and we are router we need to
3065 broadcast this packet to other routers in the network. Broadcast
3066 this list packet instead of multiple New Channel packets. */
3067 if (server->server_type == SILC_ROUTER &&
3068 sock->type == SILC_SOCKET_TYPE_SERVER &&
3069 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
3070 SILC_LOG_DEBUG(("Broadcasting received New Channel packet"));
3071 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
3073 packet->flags | SILC_PACKET_FLAG_BROADCAST,
3074 packet->buffer->data,
3075 packet->buffer->len, FALSE);
3076 silc_server_backup_send(server, sock->user_data,
3077 packet->type, packet->flags,
3078 packet->buffer->data, packet->buffer->len,
3082 silc_channel_payload_free(payload);
3085 /* Received New Channel List packet, list of New Channel List payloads inside
3086 one packet. Process the New Channel payloads one by one. */
3088 void silc_server_new_channel_list(SilcServer server,
3089 SilcSocketConnection sock,
3090 SilcPacketContext *packet)
3092 SilcPacketContext *new;
3094 SilcUInt16 len1, len2;
3096 SILC_LOG_DEBUG(("Processing New Channel List"));
3098 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
3099 packet->src_id_type != SILC_ID_SERVER ||
3100 server->server_type == SILC_SERVER)
3103 /* Make copy of the original packet context, except for the actual
3104 data buffer, which we will here now fetch from the original buffer. */
3105 new = silc_packet_context_alloc();
3106 new->type = SILC_PACKET_NEW_CHANNEL;
3107 new->flags = packet->flags & (~SILC_PACKET_FLAG_LIST);
3108 new->src_id = packet->src_id;
3109 new->src_id_len = packet->src_id_len;
3110 new->src_id_type = packet->src_id_type;
3111 new->dst_id = packet->dst_id;
3112 new->dst_id_len = packet->dst_id_len;
3113 new->dst_id_type = packet->dst_id_type;
3115 buffer = silc_buffer_alloc(512);
3116 new->buffer = buffer;
3118 while (packet->buffer->len) {
3119 SILC_GET16_MSB(len1, packet->buffer->data);
3120 if ((len1 > packet->buffer->len) ||
3121 (len1 > buffer->truelen))
3124 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
3125 if ((len2 > packet->buffer->len) ||
3126 (len2 > buffer->truelen))
3129 silc_buffer_pull_tail(buffer, 8 + len1 + len2);
3130 silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
3132 /* Process the New Channel */
3133 silc_server_new_channel(server, sock, new);
3135 silc_buffer_push_tail(buffer, 8 + len1 + len2);
3136 silc_buffer_pull(packet->buffer, 8 + len1 + len2);
3139 silc_buffer_free(buffer);
3143 /* Received key agreement packet. This packet is never for us. It is to
3144 the client in the packet's destination ID. Sending of this sort of packet
3145 equals sending private message, ie. it is sent point to point from
3146 one client to another. */
3148 void silc_server_key_agreement(SilcServer server,
3149 SilcSocketConnection sock,
3150 SilcPacketContext *packet)
3152 SilcSocketConnection dst_sock;
3153 SilcIDListData idata;
3155 SILC_LOG_DEBUG(("Start"));
3157 if (packet->src_id_type != SILC_ID_CLIENT ||
3158 packet->dst_id_type != SILC_ID_CLIENT)
3161 if (!packet->dst_id)
3164 /* Get the route to the client */
3165 dst_sock = silc_server_get_client_route(server, packet->dst_id,
3166 packet->dst_id_len, NULL,
3171 /* Relay the packet */
3172 silc_server_relay_packet(server, dst_sock, idata->send_key,
3173 idata->hmac_send, idata->psn_send++,
3177 /* Received connection auth request packet that is used during connection
3178 phase to resolve the mandatory authentication method. This packet can
3179 actually be received at anytime but usually it is used only during
3180 the connection authentication phase. Now, protocol says that this packet
3181 can come from client or server, however, we support only this coming
3182 from client and expect that server always knows what authentication
3185 void silc_server_connection_auth_request(SilcServer server,
3186 SilcSocketConnection sock,
3187 SilcPacketContext *packet)
3189 SilcServerConfigClient *client = NULL;
3190 SilcUInt16 conn_type;
3192 SilcAuthMethod auth_meth = SILC_AUTH_NONE;
3194 if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT) {
3195 SILC_LOG_DEBUG(("Request not from client"));
3199 /* Parse the payload */
3200 ret = silc_buffer_unformat(packet->buffer,
3201 SILC_STR_UI_SHORT(&conn_type),
3202 SILC_STR_UI_SHORT(NULL),
3207 if (conn_type != SILC_SOCKET_TYPE_CLIENT)
3210 /* Get the authentication method for the client */
3211 auth_meth = SILC_AUTH_NONE;
3212 client = silc_server_config_find_client(server, sock->ip);
3214 client = silc_server_config_find_client(server, sock->hostname);
3216 if (client->passphrase) {
3217 if (client->publickeys && !server->config->prefer_passphrase_auth)
3218 auth_meth = SILC_AUTH_PUBLIC_KEY;
3220 auth_meth = SILC_AUTH_PASSWORD;
3221 } else if (client->publickeys)
3222 auth_meth = SILC_AUTH_PUBLIC_KEY;
3225 SILC_LOG_DEBUG(("Authentication method is [%s]",
3226 (auth_meth == SILC_AUTH_NONE ? "None" :
3227 auth_meth == SILC_AUTH_PASSWORD ? "Passphrase" :
3228 "Digital signatures")));
3230 /* Send it back to the client */
3231 silc_server_send_connection_auth_request(server, sock, conn_type, auth_meth);
3234 /* Received REKEY packet. The sender of the packet wants to regenerate
3235 its session keys. This starts the REKEY protocol. */
3237 void silc_server_rekey(SilcServer server,
3238 SilcSocketConnection sock,
3239 SilcPacketContext *packet)
3241 SilcProtocol protocol;
3242 SilcServerRekeyInternalContext *proto_ctx;
3243 SilcIDListData idata = (SilcIDListData)sock->user_data;
3245 SILC_LOG_DEBUG(("Start"));
3247 /* Allocate internal protocol context. This is sent as context
3249 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
3250 proto_ctx->server = (void *)server;
3251 proto_ctx->sock = sock;
3252 proto_ctx->responder = TRUE;
3253 proto_ctx->pfs = idata->rekey->pfs;
3255 /* Perform rekey protocol. Will call the final callback after the
3256 protocol is over. */
3257 silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
3258 &protocol, proto_ctx, silc_server_rekey_final);
3259 sock->protocol = protocol;
3261 if (proto_ctx->pfs == FALSE)
3262 /* Run the protocol */
3263 silc_protocol_execute(protocol, server->schedule, 0, 0);
3266 /* Received file transger packet. This packet is never for us. It is to
3267 the client in the packet's destination ID. Sending of this sort of packet
3268 equals sending private message, ie. it is sent point to point from
3269 one client to another. */
3271 void silc_server_ftp(SilcServer server,
3272 SilcSocketConnection sock,
3273 SilcPacketContext *packet)
3275 SilcSocketConnection dst_sock;
3276 SilcIDListData idata;
3278 SILC_LOG_DEBUG(("Start"));
3280 if (packet->src_id_type != SILC_ID_CLIENT ||
3281 packet->dst_id_type != SILC_ID_CLIENT)
3284 if (!packet->dst_id)
3287 /* Get the route to the client */
3288 dst_sock = silc_server_get_client_route(server, packet->dst_id,
3289 packet->dst_id_len, NULL,
3294 /* Relay the packet */
3295 silc_server_relay_packet(server, dst_sock, idata->send_key,
3296 idata->hmac_send, idata->psn_send++,
3302 SilcSocketConnection sock;
3303 SilcPacketContext *packet;
3305 } *SilcServerResumeResolve;
3307 SILC_SERVER_CMD_FUNC(resume_resolve)
3309 SilcServerResumeResolve r = (SilcServerResumeResolve)context;
3310 SilcServer server = r->server;
3311 SilcSocketConnection sock = r->sock;
3312 SilcServerCommandReplyContext reply = context2;
3313 SilcClientEntry client;
3315 SILC_LOG_DEBUG(("Start"));
3317 if (!reply || !silc_command_get_status(reply->payload, NULL, NULL)) {
3318 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3319 "closing connection", sock->hostname, sock->ip));
3320 silc_server_disconnect_remote(server, sock,
3321 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3322 "Resuming not possible");
3323 if (sock->user_data)
3324 silc_server_free_sock_user_data(server, sock, NULL);
3328 if (reply && silc_command_get(reply->payload) == SILC_COMMAND_WHOIS) {
3329 /* Get entry to the client, and resolve it if we don't have it. */
3330 client = silc_idlist_find_client_by_id(server->local_list,
3331 r->data, TRUE, NULL);
3333 client = silc_idlist_find_client_by_id(server->global_list,
3334 r->data, TRUE, NULL);
3336 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3337 "closing connection", sock->hostname, sock->ip));
3338 silc_server_disconnect_remote(server, sock,
3339 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3340 "Resuming not possible");
3341 if (sock->user_data)
3342 silc_server_free_sock_user_data(server, sock, NULL);
3347 if (!(client->mode & SILC_UMODE_DETACHED)) {
3348 SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, "
3349 "closing connection", sock->hostname, sock->ip));
3350 silc_server_disconnect_remote(server, sock,
3351 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3352 "Resuming not possible");
3353 if (sock->user_data)
3354 silc_server_free_sock_user_data(server, sock, NULL);
3359 /* Reprocess the packet */
3360 silc_server_resume_client(server, sock, r->packet);
3363 silc_socket_free(r->sock);
3364 silc_packet_context_free(r->packet);
3369 /* Received client resuming packet. This is used to resume detached
3370 client session. It can be sent by the client who wishes to resume
3371 but this is also sent by servers and routers to notify other routers
3372 that the client is not detached anymore. */
3374 void silc_server_resume_client(SilcServer server,
3375 SilcSocketConnection sock,
3376 SilcPacketContext *packet)
3378 SilcBuffer buffer = packet->buffer, buf;
3379 SilcIDListData idata;
3380 SilcIDCacheEntry id_cache = NULL;
3381 SilcClientEntry detached_client;
3382 SilcClientID *client_id = NULL;
3383 unsigned char *id_string, *auth = NULL;
3384 SilcUInt16 id_len, auth_len = 0;
3385 int ret, nickfail = 0;
3386 bool resolved, local, nick_change = FALSE, resolve = FALSE;
3387 SilcChannelEntry channel;
3388 SilcHashTableList htl;
3389 SilcChannelClientEntry chl;
3390 SilcServerResumeResolve r;
3392 ret = silc_buffer_unformat(buffer,
3393 SILC_STR_UI16_NSTRING(&id_string, &id_len),
3396 client_id = silc_id_str2id(id_string, id_len, SILC_ID_CLIENT);
3398 if (sock->type == SILC_SOCKET_TYPE_CLIENT) {
3399 /* Client send this and is attempting to resume to old client session */
3400 SilcClientEntry client;
3404 silc_buffer_pull(buffer, 2 + id_len);
3405 auth = buffer->data;
3406 auth_len = buffer->len;
3407 silc_buffer_push(buffer, 2 + id_len);
3410 if (!client_id || auth_len < 128) {
3411 SILC_LOG_ERROR(("Client %s (%s) sent incomplete resume information, "
3412 "closing connection", sock->hostname, sock->ip));
3413 silc_server_disconnect_remote(server, sock,
3414 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3415 "Resuming not possible");
3416 if (sock->user_data)
3417 silc_server_free_sock_user_data(server, sock, NULL);
3418 silc_free(client_id);
3422 /* Take client entry of this connection */
3423 client = (SilcClientEntry)sock->user_data;
3424 idata = (SilcIDListData)client;
3426 /* Get entry to the client, and resolve it if we don't have it. */
3427 detached_client = silc_server_get_client_resolve(server, client_id, FALSE,
3429 if (!detached_client) {
3431 /* The client info is being resolved. Reprocess this packet after
3432 receiving the reply to the query. */
3433 SILC_LOG_DEBUG(("Resolving client"));
3434 r = silc_calloc(1, sizeof(*r));
3438 r->sock = silc_socket_dup(sock);
3439 r->packet = silc_packet_context_dup(packet);
3440 r->data = client_id;
3441 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
3443 silc_server_command_resume_resolve, r);
3445 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
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);
3457 if (!(detached_client->mode & SILC_UMODE_DETACHED))
3459 if (!silc_hash_table_count(detached_client->channels) &&
3460 detached_client->router)
3462 if (!detached_client->nickname)
3466 if (server->server_type == SILC_SERVER && !server->standalone) {
3467 /* The client info is being resolved. Reprocess this packet after
3468 receiving the reply to the query. */
3469 SILC_LOG_DEBUG(("Resolving client info"));
3470 silc_server_get_client_resolve(server, client_id, TRUE, NULL);
3471 r = silc_calloc(1, sizeof(*r));
3475 r->sock = silc_socket_dup(sock);
3476 r->packet = silc_packet_context_dup(packet);
3477 r->data = client_id;
3478 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
3480 silc_server_command_resume_resolve, r);
3483 if (server->server_type == SILC_SERVER) {
3484 SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, "
3485 "closing connection", sock->hostname, sock->ip));
3486 silc_server_disconnect_remote(server, sock,
3487 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3488 "Resuming not possible");
3489 if (sock->user_data)
3490 silc_server_free_sock_user_data(server, sock, NULL);
3491 silc_free(client_id);
3496 /* Check that we have the public key of the client, if not then we must
3497 resolve it first. */
3498 if (!detached_client->data.public_key) {
3499 if (server->server_type == SILC_SERVER && server->standalone) {
3500 SILC_LOG_ERROR(("Detached client's public key not present, "
3501 "closing connection"));
3502 silc_server_disconnect_remote(server, sock,
3503 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3504 "Resuming not possible");
3505 if (sock->user_data)
3506 silc_server_free_sock_user_data(server, sock, NULL);
3507 silc_free(client_id);
3509 /* We must retrieve the detached client's public key by sending
3510 GETKEY command. Reprocess this packet after receiving the key */
3511 SilcBuffer idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
3512 SilcSocketConnection dest_sock =
3513 silc_server_get_client_route(server, NULL, 0, client_id, NULL, NULL);
3515 SILC_LOG_DEBUG(("Resolving client public key"));
3517 silc_server_send_command(server, dest_sock ? dest_sock :
3518 SILC_PRIMARY_ROUTE(server),
3519 SILC_COMMAND_GETKEY, ++server->cmd_ident,
3520 1, 1, idp->data, idp->len);
3522 r = silc_calloc(1, sizeof(*r));
3524 silc_free(client_id);
3529 r->sock = silc_socket_dup(sock);
3530 r->packet = silc_packet_context_dup(packet);
3531 silc_server_command_pending(server, SILC_COMMAND_GETKEY,
3533 silc_server_command_resume_resolve, r);
3535 silc_buffer_free(idp);
3537 silc_free(client_id);
3539 } else if (!silc_pkcs_public_key_compare(detached_client->data.public_key,
3540 idata->public_key)) {
3541 /* We require that the connection and resuming authentication data
3542 must be using same key pair. */
3543 SILC_LOG_ERROR(("Resuming attempted with wrong public key, "
3544 "closing connection"));
3545 silc_server_disconnect_remote(server, sock,
3546 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3547 "Resuming not possible");
3548 if (sock->user_data)
3549 silc_server_free_sock_user_data(server, sock, NULL);
3550 silc_free(client_id);
3554 /* Verify the authentication payload. This has to be successful in
3555 order to allow the resuming */
3557 !silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
3558 detached_client->data.public_key, 0,
3559 idata->hash, detached_client->id,
3561 SILC_LOG_ERROR(("Client %s (%s) resume authentication failed, "
3562 "closing connection", sock->hostname, sock->ip));
3563 silc_server_disconnect_remote(server, sock,
3564 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3565 "Resuming not possible");
3566 if (sock->user_data)
3567 silc_server_free_sock_user_data(server, sock, NULL);
3568 silc_free(client_id);
3572 /* Now resume the client to the network */
3574 silc_schedule_task_del_by_context(server->schedule, detached_client);
3575 sock->user_data = detached_client;
3576 detached_client->connection = sock;
3578 /* Take new keys and stuff into use in the old entry */
3579 silc_idlist_del_data(detached_client);
3580 silc_idlist_add_data(detached_client, idata);
3581 detached_client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
3582 detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
3583 detached_client->mode &= ~SILC_UMODE_DETACHED;
3584 server->stat.my_detached--;
3586 /* Send the RESUME_CLIENT packet to our primary router so that others
3587 know this client isn't detached anymore. */
3588 buf = silc_buffer_alloc_size(2 + id_len);
3589 silc_buffer_format(buf,
3590 SILC_STR_UI_SHORT(id_len),
3591 SILC_STR_UI_XNSTRING(id_string, id_len),
3594 /* Send to primary router */
3595 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
3596 SILC_PACKET_RESUME_CLIENT, 0,
3597 buf->data, buf->len, TRUE);
3599 /* As router we must deliver this packet directly to the original
3600 server whom this client was earlier. */
3601 if (server->server_type == SILC_ROUTER && detached_client->router &&
3602 detached_client->router->server_type != SILC_ROUTER)
3603 silc_server_packet_send(server, detached_client->router->connection,
3604 SILC_PACKET_RESUME_CLIENT, 0,
3605 buf->data, buf->len, TRUE);
3606 silc_buffer_free(buf);
3608 detached_client->router = NULL;
3610 /* Delete this client entry since we're resuming to old one. */
3611 server->stat.my_clients--;
3612 server->stat.clients--;
3613 if (server->stat.cell_clients)
3614 server->stat.cell_clients--;
3615 silc_server_remove_from_channels(server, NULL, client, FALSE, NULL, FALSE);
3616 silc_server_del_from_watcher_list(server, client);
3617 if (!silc_idlist_del_client(server->local_list, client))
3618 silc_idlist_del_client(server->global_list, client);
3619 client = detached_client;
3621 /* If the ID is not based in our ID then change it */
3622 if (!SILC_ID_COMPARE(client->id, server->id, server->id->ip.data_len)) {
3623 silc_free(client_id);
3624 while (!silc_id_create_client_id(server, server->id, server->rng,
3625 server->md5hash, client->nickname,
3629 silc_server_disconnect_remote(server, sock,
3630 SILC_STATUS_ERR_BAD_NICKNAME, NULL);
3631 if (sock->user_data)
3632 silc_server_free_sock_user_data(server, sock, NULL);
3635 snprintf(&client->nickname[strlen(client->nickname) - 1], 1,
3642 /* Notify about Client ID change, nickname doesn't actually change. */
3643 silc_server_send_notify_nick_change(server, SILC_PRIMARY_ROUTE(server),
3644 SILC_BROADCAST(server),
3645 client->id, client_id,
3649 /* Resolve users on those channels that client has joined but we
3650 haven't resolved user list yet. */
3651 if (server->server_type == SILC_SERVER && !server->standalone) {
3652 silc_hash_table_list(client->channels, &htl);
3653 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
3654 channel = chl->channel;
3655 SILC_LOG_DEBUG(("Resolving users for %s channel",
3656 channel->channel_name));
3657 if (channel->disabled || !channel->users_resolved) {
3658 silc_server_send_command(server, SILC_PRIMARY_ROUTE(server),
3659 SILC_COMMAND_USERS, ++server->cmd_ident,
3660 1, 2, channel->channel_name,
3661 strlen(channel->channel_name));
3664 silc_hash_table_list_reset(&htl);
3667 /* Send the new client ID to the client. After this client may start
3668 receiving other packets, and may start sending packets too. */
3669 silc_server_send_new_id(server, sock, FALSE, client_id, SILC_ID_CLIENT,
3670 silc_id_get_len(client_id, SILC_ID_CLIENT));
3673 /* Send NICK change notify to channels as well. */
3674 SilcBuffer oidp, nidp;
3675 oidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3676 nidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
3677 silc_server_send_notify_on_channels(server, NULL, client,
3678 SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
3679 oidp->data, oidp->len,
3680 nidp->data, nidp->len,
3682 strlen(client->nickname));
3683 silc_buffer_free(oidp);
3684 silc_buffer_free(nidp);
3687 /* Add the client again to the ID cache to get it to correct list */
3688 if (!silc_idcache_del_by_context(server->local_list->clients, client))
3689 silc_idcache_del_by_context(server->global_list->clients, client);
3690 silc_free(client->id);
3691 client->id = client_id;
3693 silc_idcache_add(server->local_list->clients, client->nickname,
3694 client->id, client, 0, NULL);
3696 /* Send some nice info to the client */
3697 silc_server_send_connect_notifys(server, sock, client);
3699 /* Send all channel keys of channels the client has joined */
3700 silc_hash_table_list(client->channels, &htl);
3701 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
3702 bool created = FALSE;
3703 channel = chl->channel;
3705 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY)
3708 /* If we don't have channel key, then create one */
3709 if (!channel->channel_key) {
3710 if (!silc_server_create_channel_key(server, channel, 0))
3715 id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3717 silc_channel_key_payload_encode(silc_id_get_len(channel->id,
3720 strlen(channel->channel_key->
3722 channel->channel_key->cipher->name,
3723 channel->key_len / 8, channel->key);
3724 silc_free(id_string);
3726 /* Send the key packet to client */
3727 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
3728 keyp->data, keyp->len, FALSE);
3730 if (created && server->server_type == SILC_SERVER)
3731 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
3732 SILC_PACKET_CHANNEL_KEY, 0,
3733 keyp->data, keyp->len, FALSE);
3735 silc_buffer_free(keyp);
3737 silc_hash_table_list_reset(&htl);
3739 } else if (sock->type != SILC_SOCKET_TYPE_CLIENT) {
3740 /* Server or router sent this to us to notify that that a client has
3742 SilcServerEntry server_entry;
3743 SilcServerID *server_id;
3746 SILC_LOG_DEBUG(("Malformed resuming packet"));
3750 /* Get entry to the client, and resolve it if we don't have it. */
3751 detached_client = silc_idlist_find_client_by_id(server->local_list,
3754 if (!detached_client) {
3755 detached_client = silc_idlist_find_client_by_id(server->global_list,
3758 if (!detached_client) {
3759 SILC_LOG_DEBUG(("Resuming client is unknown"));
3760 silc_free(client_id);
3765 /* Check that the client has not been resumed already because it is
3766 protocol error to attempt to resume more than once. The client
3767 will be killed if this protocol error occurs. */
3768 if (detached_client->data.status & SILC_IDLIST_STATUS_RESUMED &&
3769 !(detached_client->mode & SILC_UMODE_DETACHED)) {
3770 /* The client is clearly attempting to resume more than once and
3771 perhaps playing around by resuming from several different places
3772 at the same time. */
3773 SILC_LOG_DEBUG(("Attempting to re-resume client, killing both"));
3774 silc_server_kill_client(server, detached_client, NULL,
3775 server->id, SILC_ID_SERVER);
3776 silc_free(client_id);
3780 /* Check whether client is detached at all */
3781 if (!(detached_client->mode & SILC_UMODE_DETACHED)) {
3782 SILC_LOG_DEBUG(("Client is not detached"));
3783 silc_free(client_id);
3787 SILC_LOG_DEBUG(("Resuming detached client"));
3789 /* If the sender of this packet is server and we are router we need to
3790 broadcast this packet to other routers in the network. */
3791 if (server->server_type == SILC_ROUTER &&
3792 sock->type == SILC_SOCKET_TYPE_SERVER &&
3793 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
3794 SILC_LOG_DEBUG(("Broadcasting received Resume Client packet"));
3795 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
3797 packet->flags | SILC_PACKET_FLAG_BROADCAST,
3798 buffer->data, buffer->len, FALSE);
3799 silc_server_backup_send(server, sock->user_data,
3800 packet->type, packet->flags,
3801 packet->buffer->data, packet->buffer->len,
3805 /* Client is detached, and now it is resumed. Remove the detached
3806 mode and mark that it is resumed. */
3807 detached_client->mode &= ~SILC_UMODE_DETACHED;
3808 detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
3809 detached_client->data.status &= ~SILC_IDLIST_STATUS_LOCAL;
3810 id_cache->expire = 0;
3812 /* Update channel information regarding global clients on channel. */
3813 if (server->server_type == SILC_SERVER) {
3814 silc_hash_table_list(detached_client->channels, &htl);
3815 while (silc_hash_table_get(&htl, NULL, (void **)&chl))
3816 chl->channel->global_users =
3817 silc_server_channel_has_global(chl->channel);
3818 silc_hash_table_list_reset(&htl);
3821 silc_schedule_task_del_by_context(server->schedule, detached_client);
3823 /* Get the new owner of the resumed client */
3824 server_id = silc_id_str2id(packet->src_id, packet->src_id_len,
3825 packet->src_id_type);
3827 silc_free(client_id);
3831 /* Get server entry */
3832 server_entry = silc_idlist_find_server_by_id(server->global_list,
3833 server_id, TRUE, NULL);
3835 if (!server_entry) {
3836 server_entry = silc_idlist_find_server_by_id(server->local_list,
3837 server_id, TRUE, NULL);
3839 if (!server_entry) {
3840 silc_free(server_id);
3841 silc_free(client_id);
3846 if (server->server_type == SILC_ROUTER &&
3847 sock->type == SILC_SOCKET_TYPE_ROUTER &&
3848 server_entry->server_type == SILC_ROUTER)
3851 /* Change the client to correct list. */
3852 if (!silc_idcache_del_by_context(server->local_list->clients,
3854 silc_idcache_del_by_context(server->global_list->clients,
3856 silc_idcache_add(local && server->server_type == SILC_ROUTER ?
3857 server->local_list->clients :
3858 server->global_list->clients,
3859 detached_client->nickname,
3860 detached_client->id, detached_client, FALSE, NULL);
3862 /* Change the owner of the client */
3863 detached_client->router = server_entry;
3865 silc_free(server_id);
3868 silc_free(client_id);