5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2002 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
21 * Server packet routines to handle received packets.
25 #include "serverincludes.h"
26 #include "server_internal.h"
28 /* Received notify packet. Server can receive notify packets from router.
29 Server then relays the notify messages to clients if needed. */
31 void silc_server_notify(SilcServer server,
32 SilcSocketConnection sock,
33 SilcPacketContext *packet)
35 SilcNotifyPayload payload;
37 SilcArgumentPayload args;
38 SilcChannelID *channel_id = NULL, *channel_id2;
39 SilcClientID *client_id, *client_id2;
40 SilcServerID *server_id;
42 SilcChannelEntry channel = NULL;
43 SilcClientEntry client = NULL, client2 = NULL;
44 SilcServerEntry server_entry = NULL;
45 SilcChannelClientEntry chl;
46 SilcIDCacheEntry cache;
47 SilcHashTableList htl;
53 SILC_LOG_DEBUG(("Start"));
55 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
56 packet->src_id_type != SILC_ID_SERVER)
62 /* If the packet is destined directly to a client then relay the packet
63 before processing it. */
64 if (packet->dst_id_type == SILC_ID_CLIENT) {
66 SilcSocketConnection dst_sock;
68 /* Get the route to the client */
69 dst_sock = silc_server_get_client_route(server, packet->dst_id,
70 packet->dst_id_len, NULL,
73 /* Relay the packet */
74 silc_server_relay_packet(server, dst_sock, idata->send_key,
75 idata->hmac_send, idata->psn_send++,
79 /* Parse the Notify Payload */
80 payload = silc_notify_payload_parse(packet->buffer->data,
85 /* If we are router and this packet is not already broadcast packet
86 we will broadcast it. The sending socket really cannot be router or
87 the router is buggy. If this packet is coming from router then it must
88 have the broadcast flag set already and we won't do anything. */
89 if (!server->standalone && server->server_type == SILC_ROUTER &&
90 sock->type == SILC_SOCKET_TYPE_SERVER &&
91 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
92 SILC_LOG_DEBUG(("Broadcasting received Notify packet"));
93 if (packet->dst_id_type == SILC_ID_CHANNEL) {
94 /* Packet is destined to channel */
95 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
100 silc_server_packet_send_dest(server, server->router->connection,
102 packet->flags | SILC_PACKET_FLAG_BROADCAST,
103 channel_id, SILC_ID_CHANNEL,
104 packet->buffer->data, packet->buffer->len,
106 silc_server_backup_send_dest(server, (SilcServerEntry)sock->user_data,
107 packet->type, packet->flags,
108 channel_id, SILC_ID_CHANNEL,
109 packet->buffer->data, packet->buffer->len,
112 /* Packet is destined to client or server */
113 silc_server_packet_send(server, server->router->connection,
115 packet->flags | SILC_PACKET_FLAG_BROADCAST,
116 packet->buffer->data, packet->buffer->len,
118 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
119 packet->type, packet->flags,
120 packet->buffer->data, packet->buffer->len,
125 type = silc_notify_get_type(payload);
126 args = silc_notify_get_args(payload);
131 case SILC_NOTIFY_TYPE_JOIN:
133 * Distribute the notify to local clients on the channel
135 SILC_LOG_DEBUG(("JOIN notify"));
138 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
141 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
145 /* Get channel entry */
146 channel = silc_idlist_find_channel_by_id(server->global_list,
149 channel = silc_idlist_find_channel_by_id(server->local_list,
152 silc_free(channel_id);
156 silc_free(channel_id);
159 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
162 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
166 /* If the the client is not in local list we check global list (ie. the
167 channel will be global channel) and if it does not exist then create
168 entry for the client. */
169 client = silc_idlist_find_client_by_id(server->global_list,
170 client_id, server->server_type,
173 client = silc_idlist_find_client_by_id(server->local_list,
174 client_id, server->server_type,
177 /* If router did not find the client the it is bogus */
178 if (server->server_type != SILC_SERVER)
182 silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
183 silc_id_dup(client_id, SILC_ID_CLIENT),
184 sock->user_data, NULL, 0);
186 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
187 silc_free(client_id);
191 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
195 /* Do not process the notify if the client is not registered */
196 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
199 /* Do not add client to channel if it is there already */
200 if (silc_server_client_on_channel(client, channel, NULL)) {
201 SILC_LOG_DEBUG(("Client already on channel"));
205 /* Send to channel */
206 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
207 FALSE, packet->buffer->data,
208 packet->buffer->len, FALSE);
210 if (server->server_type != SILC_ROUTER &&
211 sock->type == SILC_SOCKET_TYPE_ROUTER)
212 /* The channel is global now */
213 channel->global_users = TRUE;
215 SILC_LOG_DEBUG(("Joining to channel %s", channel->channel_name));
217 /* JOIN the global client to the channel (local clients (if router
218 created the channel) is joined in the pending JOIN command). */
219 chl = silc_calloc(1, sizeof(*chl));
220 chl->client = client;
221 chl->channel = channel;
223 /* If this is the first one on the channel then it is the founder of
225 if (!silc_hash_table_count(channel->user_list))
226 chl->mode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
228 silc_hash_table_add(channel->user_list, client, chl);
229 silc_hash_table_add(client->channels, channel, chl);
230 silc_free(client_id);
231 channel->user_count++;
235 case SILC_NOTIFY_TYPE_LEAVE:
237 * Distribute the notify to local clients on the channel
239 SILC_LOG_DEBUG(("LEAVE notify"));
242 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
243 packet->dst_id_type);
248 /* Get channel entry */
249 channel = silc_idlist_find_channel_by_id(server->global_list,
252 channel = silc_idlist_find_channel_by_id(server->local_list,
255 silc_free(channel_id);
261 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
263 silc_free(channel_id);
266 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
268 silc_free(channel_id);
272 /* Get client entry */
273 client = silc_idlist_find_client_by_id(server->global_list,
274 client_id, TRUE, NULL);
276 client = silc_idlist_find_client_by_id(server->local_list,
277 client_id, TRUE, NULL);
279 silc_free(client_id);
280 silc_free(channel_id);
284 silc_free(client_id);
286 /* Check if on channel */
287 if (!silc_server_client_on_channel(client, channel, NULL))
290 /* Send the leave notify to channel */
291 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
292 FALSE, packet->buffer->data,
293 packet->buffer->len, FALSE);
295 /* Remove the user from channel */
296 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
299 case SILC_NOTIFY_TYPE_SIGNOFF:
301 * Distribute the notify to local clients on the channel
303 SILC_LOG_DEBUG(("SIGNOFF notify"));
306 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
309 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
313 /* Get client entry */
314 client = silc_idlist_find_client_by_id(server->global_list,
315 client_id, TRUE, &cache);
317 client = silc_idlist_find_client_by_id(server->local_list,
318 client_id, TRUE, &cache);
320 silc_free(client_id);
324 silc_free(client_id);
326 /* Get signoff message */
327 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
331 /* Update statistics */
332 server->stat.clients--;
333 if (server->stat.cell_clients)
334 server->stat.cell_clients--;
335 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
336 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
338 /* Remove the client from all channels. */
339 silc_server_remove_from_channels(server, NULL, client, TRUE, tmp, FALSE);
341 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
342 cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
345 case SILC_NOTIFY_TYPE_TOPIC_SET:
347 * Distribute the notify to local clients on the channel
350 SILC_LOG_DEBUG(("TOPIC SET notify"));
353 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
356 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
360 /* Get client entry */
361 client = silc_idlist_find_client_by_id(server->global_list,
362 client_id, TRUE, &cache);
364 client = silc_idlist_find_client_by_id(server->local_list,
365 client_id, TRUE, &cache);
367 silc_free(client_id);
371 silc_free(client_id);
374 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
376 silc_free(channel_id);
381 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
382 packet->dst_id_type);
387 /* Get channel entry */
388 channel = silc_idlist_find_channel_by_id(server->global_list,
391 channel = silc_idlist_find_channel_by_id(server->local_list,
394 silc_free(channel_id);
399 if (channel->topic && !strcmp(channel->topic, tmp))
402 /* Get user's channel entry and check that topic set is allowed. */
403 if (!silc_server_client_on_channel(client, channel, &chl))
405 if (chl->mode == SILC_CHANNEL_UMODE_NONE &&
406 channel->mode & SILC_CHANNEL_MODE_TOPIC) {
407 SILC_LOG_DEBUG(("Topic change is not allowed"));
411 /* Change the topic */
412 silc_free(channel->topic);
413 channel->topic = strdup(tmp);
415 /* Send the same notify to the channel */
416 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
417 FALSE, packet->buffer->data,
418 packet->buffer->len, FALSE);
419 silc_free(channel_id);
422 case SILC_NOTIFY_TYPE_NICK_CHANGE:
425 * Distribute the notify to local clients on the channel
427 unsigned char *id, *id2;
429 SilcUInt32 nickname_len;
431 SILC_LOG_DEBUG(("NICK CHANGE notify"));
433 /* Get old client ID */
434 id = silc_argument_get_arg_type(args, 1, &tmp_len);
437 client_id = silc_id_payload_parse_id(id, tmp_len, NULL);
441 /* Get new client ID */
442 id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
445 client_id2 = silc_id_payload_parse_id(id2, tmp_len, NULL);
449 SILC_LOG_DEBUG(("Old Client ID id(%s)",
450 silc_id_render(client_id, SILC_ID_CLIENT)));
451 SILC_LOG_DEBUG(("New Client ID id(%s)",
452 silc_id_render(client_id2, SILC_ID_CLIENT)));
454 /* From protocol version 1.1 we also get the new nickname */
455 nickname = silc_argument_get_arg_type(args, 3, &nickname_len);;
457 /* Replace the Client ID */
458 client = silc_idlist_replace_client_id(server->global_list, client_id,
459 client_id2, nickname);
461 client = silc_idlist_replace_client_id(server->local_list, client_id,
462 client_id2, nickname);
465 /* Send the NICK_CHANGE notify type to local clients on the channels
466 this client is joined to. */
467 silc_server_send_notify_on_channels(server, client, client,
468 SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
469 id, tmp_len, id2, tmp_len,
474 silc_free(client_id);
476 silc_free(client_id2);
480 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
482 * Distribute the notify to local clients on the channel
485 SILC_LOG_DEBUG(("CMODE CHANGE notify"));
488 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
491 client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
495 /* Get client entry */
496 if (id_type == SILC_ID_CLIENT) {
497 client = silc_idlist_find_client_by_id(server->global_list,
498 client_id, TRUE, &cache);
500 client = silc_idlist_find_client_by_id(server->local_list,
501 client_id, TRUE, &cache);
503 silc_free(client_id);
507 silc_free(client_id);
511 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
512 packet->dst_id_type);
517 /* Get channel entry */
518 channel = silc_idlist_find_channel_by_id(server->global_list,
521 channel = silc_idlist_find_channel_by_id(server->local_list,
524 silc_free(channel_id);
528 silc_free(channel_id);
531 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
534 SILC_GET32_MSB(mode, tmp);
536 /* Check if mode changed */
537 if (channel->mode == mode)
540 /* Get user's channel entry and check that mode change is allowed */
542 if (!silc_server_client_on_channel(client, channel, &chl))
544 if (!silc_server_check_cmode_rights(server, channel, chl, mode)) {
545 SILC_LOG_DEBUG(("CMODE change is not allowed"));
550 /* Send the same notify to the channel */
551 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
552 FALSE, packet->buffer->data,
553 packet->buffer->len, FALSE);
555 /* If the channel had private keys set and the mode was removed then
556 we must re-generate and re-distribute a new channel key */
557 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY &&
558 !(mode & SILC_CHANNEL_MODE_PRIVKEY)) {
559 /* Re-generate channel key */
560 if (!silc_server_create_channel_key(server, channel, 0))
563 /* Send the channel key. This sends it to our local clients and if
564 we are normal server to our router as well. */
565 silc_server_send_channel_key(server, NULL, channel,
566 server->server_type == SILC_ROUTER ?
567 FALSE : !server->standalone);
571 channel->mode = mode;
574 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
576 unsigned char hash[32];
579 silc_hmac_free(channel->hmac);
580 if (!silc_hmac_alloc(tmp, NULL, &channel->hmac))
583 /* Set the HMAC key out of current channel key. The client must do
585 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key,
586 channel->key_len / 8,
588 silc_hmac_set_key(channel->hmac, hash,
589 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
590 memset(hash, 0, sizeof(hash));
593 /* Get the passphrase */
594 tmp = silc_argument_get_arg_type(args, 5, &tmp_len);
596 silc_free(channel->passphrase);
597 channel->passphrase = silc_memdup(tmp, tmp_len);
602 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
605 * Distribute the notify to local clients on the channel
607 SilcChannelClientEntry chl2 = NULL;
608 bool notify_sent = FALSE;
610 SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
613 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
616 client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
620 /* Get client entry */
621 if (id_type == SILC_ID_CLIENT) {
622 client = silc_idlist_find_client_by_id(server->global_list,
623 client_id, TRUE, &cache);
625 client = silc_idlist_find_client_by_id(server->local_list,
626 client_id, TRUE, &cache);
628 silc_free(client_id);
632 silc_free(client_id);
636 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
637 packet->dst_id_type);
642 /* Get channel entry */
643 channel = silc_idlist_find_channel_by_id(server->global_list,
646 channel = silc_idlist_find_channel_by_id(server->local_list,
649 silc_free(channel_id);
655 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
657 silc_free(channel_id);
661 SILC_GET32_MSB(mode, tmp);
663 /* Get target client */
664 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
667 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
671 /* Get client entry */
672 client2 = silc_idlist_find_client_by_id(server->global_list,
673 client_id, TRUE, NULL);
675 client2 = silc_idlist_find_client_by_id(server->local_list,
676 client_id, TRUE, NULL);
678 silc_free(client_id);
682 silc_free(client_id);
685 /* Check that sender is on channel */
686 if (!silc_server_client_on_channel(client, channel, &chl))
689 if (client != client2) {
690 /* Sender must be operator */
691 if (chl->mode == SILC_CHANNEL_UMODE_NONE) {
692 SILC_LOG_DEBUG(("CUMODE change is not allowed"));
696 /* Check that target is on channel */
697 if (!silc_server_client_on_channel(client2, channel, &chl))
700 /* If target is founder mode change is not allowed. */
701 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
702 SILC_LOG_DEBUG(("CUMODE change is not allowed"));
708 /* Get entry to the channel user list */
709 silc_hash_table_list(channel->user_list, &htl);
710 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
711 /* If the mode is channel founder and we already find a client
712 to have that mode on the channel we will enforce the sender
713 to change the channel founder mode away. There can be only one
714 channel founder on the channel. */
715 if (server->server_type == SILC_ROUTER &&
716 mode & SILC_CHANNEL_UMODE_CHANFO &&
717 chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
719 unsigned char cumode[4];
721 if (chl->client == client && chl->mode == mode) {
726 mode &= ~SILC_CHANNEL_UMODE_CHANFO;
727 silc_server_send_notify_cumode(server, sock, FALSE, channel, mode,
728 client2->id, SILC_ID_CLIENT,
731 idp = silc_id_payload_encode(client2->id, SILC_ID_CLIENT);
732 SILC_PUT32_MSB(mode, cumode);
733 silc_server_send_notify_to_channel(server, sock, channel, FALSE,
734 SILC_NOTIFY_TYPE_CUMODE_CHANGE,
735 3, idp->data, idp->len,
737 idp->data, idp->len);
738 silc_buffer_free(idp);
741 /* Force the mode change if we alredy set the mode */
744 silc_free(channel_id);
745 silc_hash_table_list_reset(&htl);
750 if (chl->client == client2) {
751 if (chl->mode == mode) {
756 SILC_LOG_DEBUG(("Changing the channel user mode"));
758 /* Change the mode */
760 if (!(mode & SILC_CHANNEL_UMODE_CHANFO))
766 silc_hash_table_list_reset(&htl);
768 /* Send the same notify to the channel */
770 silc_server_packet_send_to_channel(server, sock, channel,
772 FALSE, packet->buffer->data,
773 packet->buffer->len, FALSE);
775 silc_free(channel_id);
779 case SILC_NOTIFY_TYPE_INVITE:
781 if (packet->dst_id_type == SILC_ID_CLIENT)
784 SILC_LOG_DEBUG(("INVITE notify"));
787 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
790 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
794 /* Get channel entry */
795 channel = silc_idlist_find_channel_by_id(server->global_list,
798 channel = silc_idlist_find_channel_by_id(server->local_list,
801 silc_free(channel_id);
805 silc_free(channel_id);
808 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
811 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
815 /* Get client entry */
816 client = silc_idlist_find_client_by_id(server->global_list,
817 client_id, TRUE, &cache);
819 client = silc_idlist_find_client_by_id(server->local_list,
820 client_id, TRUE, &cache);
822 silc_free(client_id);
826 silc_free(client_id);
828 /* Get user's channel entry and check that inviting is allowed. */
829 if (!silc_server_client_on_channel(client, channel, &chl))
831 if (chl->mode == SILC_CHANNEL_UMODE_NONE &&
832 channel->mode & SILC_CHANNEL_MODE_INVITE) {
833 SILC_LOG_DEBUG(("Inviting is not allowed"));
837 /* Get the added invite */
838 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
840 if (!channel->invite_list)
841 channel->invite_list = silc_calloc(tmp_len + 2,
842 sizeof(*channel->invite_list));
844 channel->invite_list = silc_realloc(channel->invite_list,
845 sizeof(*channel->invite_list) *
847 strlen(channel->invite_list) +
849 if (tmp[tmp_len - 1] == ',')
850 tmp[tmp_len - 1] = '\0';
852 strncat(channel->invite_list, tmp, tmp_len);
853 strncat(channel->invite_list, ",", 1);
856 /* Get the deleted invite */
857 tmp = silc_argument_get_arg_type(args, 5, &tmp_len);
858 if (tmp && channel->invite_list) {
859 char *start, *end, *n;
861 if (!strncmp(channel->invite_list, tmp,
862 strlen(channel->invite_list) - 1)) {
863 silc_free(channel->invite_list);
864 channel->invite_list = NULL;
866 start = strstr(channel->invite_list, tmp);
867 if (start && strlen(start) >= tmp_len) {
868 end = start + tmp_len;
869 n = silc_calloc(strlen(channel->invite_list) - tmp_len, sizeof(*n));
870 strncat(n, channel->invite_list, start - channel->invite_list);
871 strncat(n, end + 1, ((channel->invite_list +
872 strlen(channel->invite_list)) - end) - 1);
873 silc_free(channel->invite_list);
874 channel->invite_list = n;
881 case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
883 * Distribute to the local clients on the channel and change the
887 SILC_LOG_DEBUG(("CHANNEL CHANGE"));
889 if (sock->type != SILC_SOCKET_TYPE_ROUTER)
892 /* Get the old Channel ID */
893 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
896 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
900 /* Get the channel entry */
901 channel = silc_idlist_find_channel_by_id(server->local_list,
904 channel = silc_idlist_find_channel_by_id(server->global_list,
907 silc_free(channel_id);
912 /* Send the notify to the channel */
913 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
914 FALSE, packet->buffer->data,
915 packet->buffer->len, FALSE);
917 /* Get the new Channel ID */
918 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
921 channel_id2 = silc_id_payload_parse_id(tmp, tmp_len, NULL);
925 SILC_LOG_DEBUG(("Old Channel ID id(%s)",
926 silc_id_render(channel_id, SILC_ID_CHANNEL)));
927 SILC_LOG_DEBUG(("New Channel ID id(%s)",
928 silc_id_render(channel_id2, SILC_ID_CHANNEL)));
930 /* Replace the Channel ID */
931 if (!silc_idlist_replace_channel_id(server->local_list, channel_id,
933 if (!silc_idlist_replace_channel_id(server->global_list, channel_id,
935 silc_free(channel_id2);
940 SilcBuffer users = NULL, users_modes = NULL;
942 /* Re-announce this channel which ID was changed. */
943 silc_server_send_new_channel(server, sock, FALSE, channel->channel_name,
945 silc_id_get_len(channel->id,
949 /* Re-announce our clients on the channel as the ID has changed now */
950 silc_server_announce_get_channel_users(server, channel, &users,
953 silc_buffer_push(users, users->data - users->head);
954 silc_server_packet_send(server, sock,
955 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
956 users->data, users->len, FALSE);
957 silc_buffer_free(users);
960 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
961 silc_server_packet_send_dest(server, sock,
962 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
963 channel->id, SILC_ID_CHANNEL,
965 users_modes->len, FALSE);
966 silc_buffer_free(users_modes);
969 /* Re-announce channel's topic */
970 if (channel->topic) {
971 silc_server_send_notify_topic_set(server, sock,
972 server->server_type == SILC_ROUTER ?
973 TRUE : FALSE, channel,
974 channel->id, SILC_ID_CHANNEL,
979 silc_free(channel_id);
983 case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
985 * Remove the server entry and all clients that this server owns.
988 SILC_LOG_DEBUG(("SERVER SIGNOFF notify"));
991 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
994 server_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
998 /* Get server entry */
999 server_entry = silc_idlist_find_server_by_id(server->global_list,
1000 server_id, TRUE, NULL);
1002 if (!server_entry) {
1003 server_entry = silc_idlist_find_server_by_id(server->local_list,
1004 server_id, TRUE, NULL);
1006 if (!server_entry) {
1007 /* If we are normal server then we might not have the server. Check
1008 whether router was kind enough to send the list of all clients
1009 that actually was to be removed. Remove them if the list is
1011 if (server->server_type != SILC_ROUTER &&
1012 silc_argument_get_arg_num(args) > 1) {
1015 for (i = 1; i < silc_argument_get_arg_num(args); i++) {
1017 tmp = silc_argument_get_arg_type(args, i + 1, &tmp_len);
1020 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1024 /* Get client entry */
1025 client = silc_idlist_find_client_by_id(server->global_list,
1026 client_id, TRUE, &cache);
1029 client = silc_idlist_find_client_by_id(server->local_list,
1030 client_id, TRUE, &cache);
1033 silc_free(client_id);
1037 silc_free(client_id);
1039 /* Update statistics */
1040 server->stat.clients--;
1041 if (server->stat.cell_clients)
1042 server->stat.cell_clients--;
1043 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
1044 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
1046 /* Remove the client from all channels. */
1047 silc_server_remove_from_channels(server, NULL, client,
1050 /* Remove the client */
1051 silc_idlist_del_client(local ? server->local_list :
1052 server->global_list, client);
1056 silc_free(server_id);
1060 silc_free(server_id);
1062 /* Free all client entries that this server owns as they will
1063 become invalid now as well. */
1064 silc_server_remove_clients_by_server(server, server_entry, TRUE);
1066 /* Remove the server entry */
1067 silc_idlist_del_server(local ? server->local_list :
1068 server->global_list, server_entry);
1070 /* XXX update statistics */
1074 case SILC_NOTIFY_TYPE_KICKED:
1076 * Distribute the notify to local clients on the channel
1079 SILC_LOG_DEBUG(("KICKED notify"));
1082 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
1083 packet->dst_id_type);
1088 /* Get channel entry */
1089 channel = silc_idlist_find_channel_by_id(server->global_list,
1092 channel = silc_idlist_find_channel_by_id(server->local_list,
1095 silc_free(channel_id);
1099 silc_free(channel_id);
1102 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1105 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1109 /* If the the client is not in local list we check global list */
1110 client = silc_idlist_find_client_by_id(server->global_list,
1111 client_id, TRUE, NULL);
1113 client = silc_idlist_find_client_by_id(server->local_list,
1114 client_id, TRUE, NULL);
1116 silc_free(client_id);
1120 silc_free(client_id);
1122 /* If target is founder they cannot be kicked */
1123 if (!silc_server_client_on_channel(client, channel, &chl))
1125 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO)
1128 /* From protocol version 1.1 we get the kicker's ID as well. */
1129 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1131 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1135 /* If the the client is not in local list we check global list */
1136 client2 = silc_idlist_find_client_by_id(server->global_list,
1137 client_id, TRUE, NULL);
1139 client2 = silc_idlist_find_client_by_id(server->local_list,
1140 client_id, TRUE, NULL);
1142 silc_free(client_id);
1146 silc_free(client_id);
1148 /* Kicker must be operator on channel */
1149 if (!silc_server_client_on_channel(client2, channel, &chl))
1151 if (chl->mode == SILC_CHANNEL_UMODE_NONE) {
1152 SILC_LOG_DEBUG(("Kicking is not allowed"));
1157 /* Send to channel */
1158 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
1159 FALSE, packet->buffer->data,
1160 packet->buffer->len, FALSE);
1162 /* Remove the client from channel */
1163 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
1167 case SILC_NOTIFY_TYPE_KILLED:
1170 * Distribute the notify to local clients on channels
1172 unsigned char *id, *comment;
1173 SilcUInt32 id_len, comment_len;
1175 SILC_LOG_DEBUG(("KILLED notify"));
1178 id = silc_argument_get_arg_type(args, 1, &id_len);
1181 client_id = silc_id_payload_parse_id(id, id_len, NULL);
1185 /* If the the client is not in local list we check global list */
1186 client = silc_idlist_find_client_by_id(server->global_list,
1187 client_id, TRUE, NULL);
1189 client = silc_idlist_find_client_by_id(server->local_list,
1190 client_id, TRUE, NULL);
1192 silc_free(client_id);
1196 silc_free(client_id);
1198 /* If the client is one of ours, then close the connection to the
1199 client now. This removes the client from all channels as well. */
1200 if (packet->dst_id_type == SILC_ID_CLIENT && client->connection) {
1201 sock = client->connection;
1202 silc_server_free_client_data(server, NULL, client, FALSE, NULL);
1203 silc_server_close_connection(server, sock);
1208 comment = silc_argument_get_arg_type(args, 2, &comment_len);
1209 if (comment_len > 128)
1212 /* From protocol version 1.1 we get the killer's ID as well. */
1213 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1215 client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
1219 if (id_type == SILC_ID_CLIENT) {
1220 /* If the the client is not in local list we check global list */
1221 client2 = silc_idlist_find_client_by_id(server->global_list,
1222 client_id, TRUE, NULL);
1224 client2 = silc_idlist_find_client_by_id(server->local_list,
1225 client_id, TRUE, NULL);
1227 silc_free(client_id);
1231 silc_free(client_id);
1233 /* Killer must be router operator */
1234 if (!(client2->mode & SILC_UMODE_ROUTER_OPERATOR)) {
1235 SILC_LOG_DEBUG(("Killing is not allowed"));
1241 /* Send the notify to local clients on the channels except to the
1242 client who is killed. */
1243 silc_server_send_notify_on_channels(server, client, client,
1244 SILC_NOTIFY_TYPE_KILLED, 3,
1245 id, id_len, comment, comment_len,
1248 /* Remove the client from all channels */
1249 silc_server_remove_from_channels(server, NULL, client, FALSE, NULL,
1255 case SILC_NOTIFY_TYPE_UMODE_CHANGE:
1257 * Save the mode of the client.
1260 SILC_LOG_DEBUG(("UMODE_CHANGE notify"));
1263 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1266 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1270 /* Get client entry */
1271 client = silc_idlist_find_client_by_id(server->global_list,
1272 client_id, TRUE, NULL);
1274 client = silc_idlist_find_client_by_id(server->local_list,
1275 client_id, TRUE, NULL);
1277 silc_free(client_id);
1281 silc_free(client_id);
1284 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1287 SILC_GET32_MSB(mode, tmp);
1289 /* Check that mode changing is allowed. */
1290 if (!silc_server_check_umode_rights(server, client, mode)) {
1291 SILC_LOG_DEBUG(("UMODE change is not allowed"));
1295 /* Remove internal resumed flag if client is marked detached now */
1296 if (mode & SILC_UMODE_DETACHED)
1297 client->data.status &= ~SILC_IDLIST_STATUS_RESUMED;
1299 /* Change the mode */
1300 client->mode = mode;
1304 case SILC_NOTIFY_TYPE_BAN:
1309 SILC_LOG_DEBUG(("BAN notify"));
1311 /* Get Channel ID */
1312 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1315 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1319 /* Get channel entry */
1320 channel = silc_idlist_find_channel_by_id(server->global_list,
1323 channel = silc_idlist_find_channel_by_id(server->local_list,
1326 silc_free(channel_id);
1330 silc_free(channel_id);
1332 /* Get the new ban and add it to the ban list */
1333 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1335 if (!channel->ban_list)
1336 channel->ban_list = silc_calloc(tmp_len + 2,
1337 sizeof(*channel->ban_list));
1339 channel->ban_list = silc_realloc(channel->ban_list,
1340 sizeof(*channel->ban_list) *
1342 strlen(channel->ban_list) + 2));
1343 strncat(channel->ban_list, tmp, tmp_len);
1344 strncat(channel->ban_list, ",", 1);
1347 /* Get the ban to be removed and remove it from the list */
1348 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1349 if (tmp && channel->ban_list) {
1350 char *start, *end, *n;
1352 if (!strncmp(channel->ban_list, tmp, strlen(channel->ban_list) - 1)) {
1353 silc_free(channel->ban_list);
1354 channel->ban_list = NULL;
1356 start = strstr(channel->ban_list, tmp);
1357 if (start && strlen(start) >= tmp_len) {
1358 end = start + tmp_len;
1359 n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
1360 strncat(n, channel->ban_list, start - channel->ban_list);
1361 strncat(n, end + 1, ((channel->ban_list +
1362 strlen(channel->ban_list)) - end) - 1);
1363 silc_free(channel->ban_list);
1364 channel->ban_list = n;
1370 /* Ignore rest of the notify types for now */
1371 case SILC_NOTIFY_TYPE_NONE:
1372 case SILC_NOTIFY_TYPE_MOTD:
1379 silc_notify_payload_free(payload);
1382 void silc_server_notify_list(SilcServer server,
1383 SilcSocketConnection sock,
1384 SilcPacketContext *packet)
1386 SilcPacketContext *new;
1390 SILC_LOG_DEBUG(("Processing Notify List"));
1392 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1393 packet->src_id_type != SILC_ID_SERVER)
1396 /* Make copy of the original packet context, except for the actual
1397 data buffer, which we will here now fetch from the original buffer. */
1398 new = silc_packet_context_alloc();
1399 new->type = SILC_PACKET_NOTIFY;
1400 new->flags = packet->flags;
1401 new->src_id = packet->src_id;
1402 new->src_id_len = packet->src_id_len;
1403 new->src_id_type = packet->src_id_type;
1404 new->dst_id = packet->dst_id;
1405 new->dst_id_len = packet->dst_id_len;
1406 new->dst_id_type = packet->dst_id_type;
1408 buffer = silc_buffer_alloc(1024);
1409 new->buffer = buffer;
1411 while (packet->buffer->len) {
1412 SILC_GET16_MSB(len, packet->buffer->data + 2);
1413 if (len > packet->buffer->len)
1416 if (len > buffer->truelen) {
1417 silc_buffer_free(buffer);
1418 buffer = silc_buffer_alloc(1024 + len);
1421 silc_buffer_pull_tail(buffer, len);
1422 silc_buffer_put(buffer, packet->buffer->data, len);
1424 /* Process the Notify */
1425 silc_server_notify(server, sock, new);
1427 silc_buffer_push_tail(buffer, len);
1428 silc_buffer_pull(packet->buffer, len);
1431 silc_buffer_free(buffer);
1435 /* Received private message. This resolves the destination of the message
1436 and sends the packet. This is used by both server and router. If the
1437 destination is our locally connected client this sends the packet to
1438 the client. This may also send the message for further routing if
1439 the destination is not in our server (or router). */
1441 void silc_server_private_message(SilcServer server,
1442 SilcSocketConnection sock,
1443 SilcPacketContext *packet)
1445 SilcSocketConnection dst_sock;
1446 SilcIDListData idata;
1447 SilcClientEntry client;
1449 SILC_LOG_DEBUG(("Start"));
1451 if (packet->src_id_type != SILC_ID_CLIENT ||
1452 packet->dst_id_type != SILC_ID_CLIENT || !packet->dst_id)
1455 /* Get the route to the client */
1456 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1457 packet->dst_id_len, NULL,
1462 if (client && client->mode & SILC_UMODE_DETACHED) {
1463 SILC_LOG_DEBUG(("Client is detached, discarding packet"));
1467 /* Send IDENTIFY command reply with error status to indicate that
1468 such destination ID does not exist or is invalid */
1469 idp = silc_id_payload_encode_data(packet->dst_id,
1471 packet->dst_id_type);
1475 if (packet->src_id_type == SILC_ID_CLIENT) {
1476 SilcClientID *client_id = silc_id_str2id(packet->src_id,
1478 packet->src_id_type);
1479 silc_server_send_dest_command_reply(server, sock,
1480 client_id, SILC_ID_CLIENT,
1481 SILC_COMMAND_IDENTIFY,
1482 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
1483 0, 0, 1, 2, idp->data, idp->len);
1484 silc_free(client_id);
1486 silc_server_send_command_reply(server, sock, SILC_COMMAND_IDENTIFY,
1487 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID, 0,
1488 0, 1, 2, idp->data, idp->len);
1491 silc_buffer_free(idp);
1495 /* Check whether destination client wishes to receive private messages */
1496 if (client && !(packet->flags & SILC_PACKET_FLAG_PRIVMSG_KEY) &&
1497 client->mode & SILC_UMODE_BLOCK_PRIVMSG) {
1498 SILC_LOG_DEBUG(("Client blocks private messages, discarding packet"));
1502 /* Send the private message */
1503 silc_server_send_private_message(server, dst_sock, idata->send_key,
1504 idata->hmac_send, idata->psn_send++,
1508 /* Received private message key packet.. This packet is never for us. It is to
1509 the client in the packet's destination ID. Sending of this sort of packet
1510 equals sending private message, ie. it is sent point to point from
1511 one client to another. */
1513 void silc_server_private_message_key(SilcServer server,
1514 SilcSocketConnection sock,
1515 SilcPacketContext *packet)
1517 SilcSocketConnection dst_sock;
1518 SilcIDListData idata;
1520 SILC_LOG_DEBUG(("Start"));
1522 if (packet->src_id_type != SILC_ID_CLIENT ||
1523 packet->dst_id_type != SILC_ID_CLIENT)
1526 if (!packet->dst_id)
1529 /* Get the route to the client */
1530 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1531 packet->dst_id_len, NULL,
1536 /* Relay the packet */
1537 silc_server_relay_packet(server, dst_sock, idata->send_key,
1538 idata->hmac_send, idata->psn_send++, packet, FALSE);
1541 /* Processes incoming command reply packet. The command reply packet may
1542 be destined to one of our clients or it may directly for us. We will
1543 call the command reply routine after processing the packet. */
1545 void silc_server_command_reply(SilcServer server,
1546 SilcSocketConnection sock,
1547 SilcPacketContext *packet)
1549 SilcBuffer buffer = packet->buffer;
1550 SilcClientEntry client = NULL;
1551 SilcSocketConnection dst_sock;
1552 SilcIDListData idata;
1553 SilcClientID *id = NULL;
1555 SILC_LOG_DEBUG(("Start"));
1557 /* Source must be server or router */
1558 if (packet->src_id_type != SILC_ID_SERVER &&
1559 sock->type != SILC_SOCKET_TYPE_ROUTER)
1562 if (packet->dst_id_type == SILC_ID_CHANNEL)
1565 if (packet->dst_id_type == SILC_ID_CLIENT) {
1566 /* Destination must be one of ours */
1567 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
1570 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
1572 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
1578 if (packet->dst_id_type == SILC_ID_SERVER) {
1579 /* For now this must be for us */
1580 if (memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
1581 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
1586 /* Execute command reply locally for the command */
1587 silc_server_command_reply_process(server, sock, buffer);
1589 if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
1590 /* Relay the packet to the client */
1591 const SilcBufferStruct p;
1593 dst_sock = (SilcSocketConnection)client->connection;
1594 idata = (SilcIDListData)client;
1596 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
1597 + packet->dst_id_len + packet->padlen);
1598 if (!silc_packet_send_prepare(dst_sock, 0, 0, buffer->len,
1599 idata->hmac_send, (const SilcBuffer)&p)) {
1600 SILC_LOG_ERROR(("Cannot send packet"));
1603 silc_buffer_put((SilcBuffer)&p, buffer->data, buffer->len);
1605 /* Encrypt packet */
1606 silc_packet_encrypt(idata->send_key, idata->hmac_send, idata->psn_send++,
1607 (SilcBuffer)&p, buffer->len);
1609 /* Send the packet */
1610 silc_server_packet_send_real(server, dst_sock, TRUE);
1616 /* Process received channel message. The message can be originated from
1617 client or server. */
1619 void silc_server_channel_message(SilcServer server,
1620 SilcSocketConnection sock,
1621 SilcPacketContext *packet)
1623 SilcChannelEntry channel = NULL;
1624 SilcChannelID *id = NULL;
1625 void *sender_id = NULL;
1626 SilcClientEntry sender_entry = NULL;
1627 SilcChannelClientEntry chl;
1630 SILC_LOG_DEBUG(("Processing channel message"));
1633 if (packet->dst_id_type != SILC_ID_CHANNEL) {
1634 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1638 /* Find channel entry */
1639 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
1642 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
1644 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
1646 SILC_LOG_DEBUG(("Could not find channel"));
1651 /* See that this client is on the channel. If the original sender is
1652 not client (as it can be server as well) we don't do the check. */
1653 sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1654 packet->src_id_type);
1657 if (packet->src_id_type == SILC_ID_CLIENT) {
1658 sender_entry = silc_idlist_find_client_by_id(server->local_list,
1659 sender_id, TRUE, NULL);
1660 if (!sender_entry) {
1662 sender_entry = silc_idlist_find_client_by_id(server->global_list,
1663 sender_id, TRUE, NULL);
1665 if (!sender_entry || !silc_server_client_on_channel(sender_entry,
1667 SILC_LOG_DEBUG(("Client not on channel"));
1671 /* If channel is moderated check that client is allowed to send
1673 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS && !chl->mode) {
1674 SILC_LOG_DEBUG(("Channel is silenced from normal users"));
1677 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS &&
1678 chl->mode & SILC_CHANNEL_UMODE_CHANOP &&
1679 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1680 SILC_LOG_DEBUG(("Channel is silenced from operators"));
1684 /* If the packet is coming from router, but the client entry is local
1685 entry to us then some router is rerouting this to us and it is not
1686 allowed. When the client is local to us it means that we've routed
1687 this packet to network, and now someone is routing it back to us. */
1688 if (server->server_type == SILC_ROUTER &&
1689 sock->type == SILC_SOCKET_TYPE_ROUTER && local) {
1690 SILC_LOG_DEBUG(("Channel message rerouted to the sender, drop it"));
1695 /* Distribute the packet to our local clients. This will send the
1696 packet for further routing as well, if needed. */
1697 silc_server_packet_relay_to_channel(server, sock, channel, sender_id,
1698 packet->src_id_type, sender_entry,
1699 packet->buffer->data,
1700 packet->buffer->len, FALSE);
1703 silc_free(sender_id);
1707 /* Received channel key packet. We distribute the key to all of our locally
1708 connected clients on the channel. */
1710 void silc_server_channel_key(SilcServer server,
1711 SilcSocketConnection sock,
1712 SilcPacketContext *packet)
1714 SilcBuffer buffer = packet->buffer;
1715 SilcChannelEntry channel;
1717 if (packet->src_id_type != SILC_ID_SERVER ||
1718 (server->server_type == SILC_ROUTER &&
1719 sock->type == SILC_SOCKET_TYPE_ROUTER))
1722 /* Save the channel key */
1723 channel = silc_server_save_channel_key(server, buffer, NULL);
1727 /* Distribute the key to everybody who is on the channel. If we are router
1728 we will also send it to locally connected servers. */
1729 silc_server_send_channel_key(server, sock, channel, FALSE);
1731 if (server->server_type != SILC_BACKUP_ROUTER) {
1732 /* Distribute to local cell backup routers. */
1733 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
1734 SILC_PACKET_CHANNEL_KEY, 0,
1735 buffer->data, buffer->len, FALSE, TRUE);
1739 /* Received New Client packet and processes it. Creates Client ID for the
1740 client. Client becomes registered after calling this functions. */
1742 SilcClientEntry silc_server_new_client(SilcServer server,
1743 SilcSocketConnection sock,
1744 SilcPacketContext *packet)
1746 SilcBuffer buffer = packet->buffer;
1747 SilcClientEntry client;
1748 SilcClientID *client_id;
1749 SilcIDListData idata;
1750 char *username = NULL, *realname = NULL;
1751 SilcUInt16 username_len;
1754 char *hostname, *nickname;
1757 SILC_LOG_DEBUG(("Creating new client"));
1759 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
1762 /* Take client entry */
1763 client = (SilcClientEntry)sock->user_data;
1764 idata = (SilcIDListData)client;
1766 /* Remove the old cache entry. */
1767 if (!silc_idcache_del_by_context(server->local_list->clients, client)) {
1768 SILC_LOG_INFO(("Unauthenticated client attempted to register to network"));
1769 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1770 "You have not been authenticated");
1774 /* Parse incoming packet */
1775 ret = silc_buffer_unformat(buffer,
1776 SILC_STR_UI16_NSTRING_ALLOC(&username,
1778 SILC_STR_UI16_STRING_ALLOC(&realname),
1781 silc_free(username);
1782 silc_free(realname);
1783 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
1784 "connection", sock->hostname, sock->ip));
1785 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1786 "Incomplete client information");
1791 silc_free(username);
1792 silc_free(realname);
1793 SILC_LOG_ERROR(("Client %s (%s) did not send its username, closing "
1794 "connection", sock->hostname, sock->ip));
1795 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1796 "Incomplete client information");
1800 if (username_len > 128)
1801 username[128] = '\0';
1803 /* Check for bad characters for nickname, and modify the nickname if
1804 it includes those. */
1805 if (silc_server_name_bad_chars(username, username_len)) {
1806 nickname = silc_server_name_modify_bad(username, username_len);
1808 nickname = strdup(username);
1811 /* Make sanity checks for the hostname of the client. If the hostname
1812 is provided in the `username' check that it is the same than the
1813 resolved hostname, or if not resolved the hostname that appears in
1814 the client's public key. If the hostname is not present then put
1815 it from the resolved name or from the public key. */
1816 if (strchr(username, '@')) {
1817 SilcPublicKeyIdentifier pident;
1818 int tlen = strcspn(username, "@");
1819 char *phostname = NULL;
1821 hostname = silc_memdup(username + tlen + 1, strlen(username) - tlen - 1);
1823 if (strcmp(sock->hostname, sock->ip) &&
1824 strcmp(sock->hostname, hostname)) {
1825 silc_free(username);
1826 silc_free(hostname);
1827 silc_free(realname);
1828 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
1829 "connection", sock->hostname, sock->ip));
1830 silc_server_disconnect_remote(server, sock,
1831 "Server closed connection: "
1832 "Incomplete client information");
1836 pident = silc_pkcs_decode_identifier(client->data.public_key->identifier);
1838 phostname = strdup(pident->host);
1839 silc_pkcs_free_identifier(pident);
1842 if (!strcmp(sock->hostname, sock->ip) &&
1843 phostname && strcmp(phostname, hostname)) {
1844 silc_free(username);
1845 silc_free(hostname);
1846 silc_free(phostname);
1847 silc_free(realname);
1848 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
1849 "connection", sock->hostname, sock->ip));
1850 silc_server_disconnect_remote(server, sock,
1851 "Server closed connection: "
1852 "Incomplete client information");
1856 silc_free(phostname);
1858 /* The hostname is not present, add it. */
1860 /* XXX For now we cannot take the host name from the public key since
1861 they are not trusted or we cannot verify them as trusted. Just take
1862 what the resolved name or address is. */
1864 if (strcmp(sock->hostname, sock->ip)) {
1866 newusername = silc_calloc(strlen(username) +
1867 strlen(sock->hostname) + 2,
1868 sizeof(*newusername));
1869 strncat(newusername, username, strlen(username));
1870 strncat(newusername, "@", 1);
1871 strncat(newusername, sock->hostname, strlen(sock->hostname));
1872 silc_free(username);
1873 username = newusername;
1876 SilcPublicKeyIdentifier pident =
1877 silc_pkcs_decode_identifier(client->data.public_key->identifier);
1880 newusername = silc_calloc(strlen(username) +
1881 strlen(pident->host) + 2,
1882 sizeof(*newusername));
1883 strncat(newusername, username, strlen(username));
1884 strncat(newusername, "@", 1);
1885 strncat(newusername, pident->host, strlen(pident->host));
1886 silc_free(username);
1887 username = newusername;
1888 silc_pkcs_free_identifier(pident);
1894 /* Create Client ID */
1895 while (!silc_id_create_client_id(server, server->id, server->rng,
1896 server->md5hash, nickname, &client_id)) {
1899 silc_server_disconnect_remote(server, sock,
1900 "Server closed connection: Bad nickname");
1903 snprintf(&nickname[strlen(nickname) - 1], 1, "%d", nickfail);
1906 /* Update client entry */
1907 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
1908 client->nickname = nickname;
1909 client->username = username;
1910 client->userinfo = realname ? realname : strdup(" ");
1911 client->id = client_id;
1912 id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
1914 /* Add the client again to the ID cache */
1915 silc_idcache_add(server->local_list->clients, client->nickname,
1916 client_id, client, 0, NULL);
1918 /* Notify our router about new client on the SILC network */
1919 if (!server->standalone)
1920 silc_server_send_new_id(server, (SilcSocketConnection)
1921 server->router->connection,
1922 server->server_type == SILC_ROUTER ? TRUE : FALSE,
1923 client->id, SILC_ID_CLIENT, id_len);
1925 /* Send the new client ID to the client. */
1926 silc_server_send_new_id(server, sock, FALSE, client->id, SILC_ID_CLIENT,
1927 silc_id_get_len(client->id, SILC_ID_CLIENT));
1929 /* Send some nice info to the client */
1930 silc_server_send_connect_notifys(server, sock, client);
1935 /* Create new server. This processes received New Server packet and
1936 saves the received Server ID. The server is our locally connected
1937 server thus we save all the information and save it to local list.
1938 This funtion can be used by both normal server and router server.
1939 If normal server uses this it means that its router has connected
1940 to the server. If router uses this it means that one of the cell's
1941 servers is connected to the router. */
1943 SilcServerEntry silc_server_new_server(SilcServer server,
1944 SilcSocketConnection sock,
1945 SilcPacketContext *packet)
1947 SilcBuffer buffer = packet->buffer;
1948 SilcServerEntry new_server, server_entry;
1949 SilcServerID *server_id;
1950 SilcIDListData idata;
1951 unsigned char *server_name, *id_string;
1952 SilcUInt16 id_len, name_len;
1956 SILC_LOG_DEBUG(("Creating new server"));
1958 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
1959 sock->type != SILC_SOCKET_TYPE_ROUTER)
1962 /* Take server entry */
1963 new_server = (SilcServerEntry)sock->user_data;
1964 idata = (SilcIDListData)new_server;
1966 /* Remove the old cache entry */
1967 if (!silc_idcache_del_by_context(server->local_list->servers, new_server)) {
1968 if (!silc_idcache_del_by_context(server->global_list->servers,
1970 SILC_LOG_INFO(("Unauthenticated %s attempted to register to "
1971 "network", (sock->type == SILC_SOCKET_TYPE_SERVER ?
1972 "server" : "router")));
1973 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1974 "You have not been authenticated");
1980 /* Parse the incoming packet */
1981 ret = silc_buffer_unformat(buffer,
1982 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
1983 SILC_STR_UI16_NSTRING_ALLOC(&server_name,
1988 silc_free(id_string);
1990 silc_free(server_name);
1994 if (id_len > buffer->len) {
1995 silc_free(id_string);
1996 silc_free(server_name);
2001 server_name[255] = '\0';
2004 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
2006 silc_free(id_string);
2007 silc_free(server_name);
2010 silc_free(id_string);
2012 /* Check for valid server ID */
2013 if (!silc_id_is_valid_server_id(server, server_id, sock)) {
2014 SILC_LOG_INFO(("Invalid server ID sent by %s (%s)",
2015 sock->ip, sock->hostname));
2016 silc_server_disconnect_remote(server, sock, "Server closed connection: "
2017 "Your Server ID is not valid");
2018 silc_free(server_name);
2022 /* Check that we do not have this ID already */
2023 server_entry = silc_idlist_find_server_by_id(server->local_list,
2024 server_id, TRUE, NULL);
2026 silc_idcache_del_by_context(server->local_list->servers, server_entry);
2028 server_entry = silc_idlist_find_server_by_id(server->global_list,
2029 server_id, TRUE, NULL);
2031 silc_idcache_del_by_context(server->global_list->servers, server_entry);
2034 /* Update server entry */
2035 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
2036 new_server->server_name = server_name;
2037 new_server->id = server_id;
2039 SILC_LOG_DEBUG(("New server id(%s)",
2040 silc_id_render(server_id, SILC_ID_SERVER)));
2042 /* Add again the entry to the ID cache. */
2043 silc_idcache_add(local ? server->local_list->servers :
2044 server->global_list->servers, server_name, server_id,
2045 new_server, 0, NULL);
2047 /* Distribute the information about new server in the SILC network
2048 to our router. If we are normal server we won't send anything
2049 since this connection must be our router connection. */
2050 if (server->server_type == SILC_ROUTER && !server->standalone &&
2051 server->router->connection != sock)
2052 silc_server_send_new_id(server, server->router->connection,
2053 TRUE, new_server->id, SILC_ID_SERVER,
2054 silc_id_get_len(server_id, SILC_ID_SERVER));
2056 if (server->server_type == SILC_ROUTER)
2057 server->stat.cell_servers++;
2059 /* Check whether this router connection has been replaced by an
2060 backup router. If it has been then we'll disable the server and will
2061 ignore everything it will send until the backup router resuming
2062 protocol has been completed. */
2063 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
2064 silc_server_backup_replaced_get(server, server_id, NULL)) {
2065 /* Send packet to the server indicating that it cannot use this
2066 connection as it has been replaced by backup router. */
2067 SilcBuffer packet = silc_buffer_alloc(2);
2068 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
2069 silc_buffer_format(packet,
2070 SILC_STR_UI_CHAR(SILC_SERVER_BACKUP_REPLACED),
2071 SILC_STR_UI_CHAR(0),
2073 silc_server_packet_send(server, sock,
2074 SILC_PACKET_RESUME_ROUTER, 0,
2075 packet->data, packet->len, TRUE);
2076 silc_buffer_free(packet);
2078 /* Mark the router disabled. The data sent earlier will go but nothing
2079 after this does not go to this connection. */
2080 idata->status |= SILC_IDLIST_STATUS_DISABLED;
2082 /* If it is router announce our stuff to it. */
2083 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
2084 server->server_type == SILC_ROUTER) {
2085 silc_server_announce_servers(server, FALSE, 0, sock);
2086 silc_server_announce_clients(server, 0, sock);
2087 silc_server_announce_channels(server, 0, sock);
2094 /* Processes incoming New ID packet. New ID Payload is used to distribute
2095 information about newly registered clients and servers. */
2097 static void silc_server_new_id_real(SilcServer server,
2098 SilcSocketConnection sock,
2099 SilcPacketContext *packet,
2102 SilcBuffer buffer = packet->buffer;
2104 SilcServerEntry router, server_entry;
2105 SilcSocketConnection router_sock;
2110 SILC_LOG_DEBUG(("Processing new ID"));
2112 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2113 server->server_type == SILC_SERVER ||
2114 packet->src_id_type != SILC_ID_SERVER)
2117 idp = silc_id_payload_parse(buffer->data, buffer->len);
2121 id_type = silc_id_payload_get_type(idp);
2123 /* Normal server cannot have other normal server connections */
2124 server_entry = (SilcServerEntry)sock->user_data;
2125 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER &&
2126 server_entry->server_type == SILC_SERVER)
2129 id = silc_id_payload_get_id(idp);
2133 /* If the packet is coming from server then use the sender as the
2134 origin of the the packet. If it came from router then check the real
2135 sender of the packet and use that as the origin. */
2136 if (sock->type == SILC_SOCKET_TYPE_SERVER) {
2137 id_list = server->local_list;
2139 router = sock->user_data;
2141 /* If the sender is backup router and ID is server (and we are not
2142 backup router) then switch the entry to global list. */
2143 if (server_entry->server_type == SILC_BACKUP_ROUTER &&
2144 id_type == SILC_ID_SERVER &&
2145 server->id_entry->server_type != SILC_BACKUP_ROUTER) {
2146 id_list = server->global_list;
2147 router_sock = server->router ? server->router->connection : sock;
2150 void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2151 packet->src_id_type);
2152 router = silc_idlist_find_server_by_id(server->global_list,
2153 sender_id, TRUE, NULL);
2155 router = silc_idlist_find_server_by_id(server->local_list,
2156 sender_id, TRUE, NULL);
2157 silc_free(sender_id);
2159 id_list = server->global_list;
2166 case SILC_ID_CLIENT:
2168 SilcClientEntry entry;
2170 /* Check that we do not have this client already */
2171 entry = silc_idlist_find_client_by_id(server->global_list,
2172 id, server->server_type,
2175 entry = silc_idlist_find_client_by_id(server->local_list,
2176 id, server->server_type,
2179 SILC_LOG_DEBUG(("Ignoring client that we already have"));
2183 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
2184 silc_id_render(id, SILC_ID_CLIENT),
2185 sock->type == SILC_SOCKET_TYPE_SERVER ?
2186 "Server" : "Router", sock->hostname));
2188 /* As a router we keep information of all global information in our
2189 global list. Cell wide information however is kept in the local
2191 entry = silc_idlist_add_client(id_list, NULL, NULL, NULL,
2192 id, router, NULL, 0);
2194 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
2196 /* Inform the sender that the ID is not usable */
2197 silc_server_send_notify_signoff(server, sock, FALSE, id, NULL);
2200 entry->nickname = NULL;
2201 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2203 if (sock->type == SILC_SOCKET_TYPE_SERVER)
2204 server->stat.cell_clients++;
2205 server->stat.clients++;
2209 case SILC_ID_SERVER:
2211 SilcServerEntry entry;
2213 /* If the ID is mine, ignore it. */
2214 if (SILC_ID_SERVER_COMPARE(id, server->id)) {
2215 SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
2219 /* If the ID is the sender's ID, ignore it (we have it already) */
2220 if (SILC_ID_SERVER_COMPARE(id, router->id)) {
2221 SILC_LOG_DEBUG(("Ignoring sender's own ID"));
2225 /* Check that we do not have this server already */
2226 entry = silc_idlist_find_server_by_id(server->global_list,
2227 id, server->server_type,
2230 entry = silc_idlist_find_server_by_id(server->local_list,
2231 id, server->server_type,
2234 SILC_LOG_DEBUG(("Ignoring server that we already have"));
2238 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
2239 silc_id_render(id, SILC_ID_SERVER),
2240 sock->type == SILC_SOCKET_TYPE_SERVER ?
2241 "Server" : "Router", sock->hostname));
2243 /* As a router we keep information of all global information in our
2244 global list. Cell wide information however is kept in the local
2246 entry = silc_idlist_add_server(id_list, NULL, 0, id, router,
2249 SILC_LOG_ERROR(("Could not add new server to the ID Cache"));
2252 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2254 if (sock->type == SILC_SOCKET_TYPE_SERVER)
2255 server->stat.cell_servers++;
2256 server->stat.servers++;
2260 case SILC_ID_CHANNEL:
2261 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
2270 /* If the sender of this packet is server and we are router we need to
2271 broadcast this packet to other routers in the network. */
2272 if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
2273 sock->type == SILC_SOCKET_TYPE_SERVER &&
2274 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2275 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
2276 silc_server_packet_send(server, server->router->connection,
2278 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2279 buffer->data, buffer->len, FALSE);
2280 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
2281 packet->type, packet->flags,
2282 packet->buffer->data, packet->buffer->len,
2287 silc_id_payload_free(idp);
2291 /* Processes incoming New ID packet. New ID Payload is used to distribute
2292 information about newly registered clients and servers. */
2294 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
2295 SilcPacketContext *packet)
2297 silc_server_new_id_real(server, sock, packet, TRUE);
2300 /* Receoved New Id List packet, list of New ID payloads inside one
2301 packet. Process the New ID payloads one by one. */
2303 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
2304 SilcPacketContext *packet)
2306 SilcPacketContext *new_id;
2310 SILC_LOG_DEBUG(("Processing New ID List"));
2312 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2313 packet->src_id_type != SILC_ID_SERVER)
2316 /* If the sender of this packet is server and we are router we need to
2317 broadcast this packet to other routers in the network. Broadcast
2318 this list packet instead of multiple New ID packets. */
2319 if (!server->standalone && server->server_type == SILC_ROUTER &&
2320 sock->type == SILC_SOCKET_TYPE_SERVER &&
2321 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2322 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
2323 silc_server_packet_send(server, server->router->connection,
2325 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2326 packet->buffer->data, packet->buffer->len, FALSE);
2327 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
2328 packet->type, packet->flags,
2329 packet->buffer->data, packet->buffer->len,
2333 /* Make copy of the original packet context, except for the actual
2334 data buffer, which we will here now fetch from the original buffer. */
2335 new_id = silc_packet_context_alloc();
2336 new_id->type = SILC_PACKET_NEW_ID;
2337 new_id->flags = packet->flags;
2338 new_id->src_id = packet->src_id;
2339 new_id->src_id_len = packet->src_id_len;
2340 new_id->src_id_type = packet->src_id_type;
2341 new_id->dst_id = packet->dst_id;
2342 new_id->dst_id_len = packet->dst_id_len;
2343 new_id->dst_id_type = packet->dst_id_type;
2345 idp = silc_buffer_alloc(256);
2346 new_id->buffer = idp;
2348 while (packet->buffer->len) {
2349 SILC_GET16_MSB(id_len, packet->buffer->data + 2);
2350 if ((id_len > packet->buffer->len) ||
2351 (id_len > idp->truelen))
2354 silc_buffer_pull_tail(idp, 4 + id_len);
2355 silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
2357 /* Process the New ID */
2358 silc_server_new_id_real(server, sock, new_id, FALSE);
2360 silc_buffer_push_tail(idp, 4 + id_len);
2361 silc_buffer_pull(packet->buffer, 4 + id_len);
2364 silc_buffer_free(idp);
2368 /* Received New Channel packet. Information about new channels in the
2369 network are distributed using this packet. Save the information about
2370 the new channel. This usually comes from router but also normal server
2371 can send this to notify channels it has when it connects to us. */
2373 void silc_server_new_channel(SilcServer server,
2374 SilcSocketConnection sock,
2375 SilcPacketContext *packet)
2377 SilcChannelPayload payload;
2378 SilcChannelID *channel_id;
2380 SilcUInt32 name_len;
2384 SilcServerEntry server_entry;
2385 SilcChannelEntry channel;
2387 SILC_LOG_DEBUG(("Processing New Channel"));
2389 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2390 packet->src_id_type != SILC_ID_SERVER ||
2391 server->server_type == SILC_SERVER)
2394 /* Parse the channel payload */
2395 payload = silc_channel_payload_parse(packet->buffer->data,
2396 packet->buffer->len);
2400 /* Get the channel ID */
2401 channel_id = silc_channel_get_id_parse(payload);
2403 silc_channel_payload_free(payload);
2407 channel_name = silc_channel_get_name(payload, &name_len);
2409 channel_name[255] = '\0';
2411 id = silc_channel_get_id(payload, &id_len);
2413 server_entry = (SilcServerEntry)sock->user_data;
2415 if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
2416 /* Add the channel to global list as it is coming from router. It
2417 cannot be our own channel as it is coming from router. */
2419 /* Check that we don't already have this channel */
2420 channel = silc_idlist_find_channel_by_name(server->local_list,
2421 channel_name, NULL);
2423 channel = silc_idlist_find_channel_by_name(server->global_list,
2424 channel_name, NULL);
2426 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
2427 silc_id_render(channel_id, SILC_ID_CHANNEL),
2431 silc_idlist_add_channel(server->global_list, strdup(channel_name),
2432 0, channel_id, sock->user_data, NULL, NULL, 0);
2436 server->stat.channels++;
2437 if (server->server_type == SILC_ROUTER)
2438 channel->users_resolved = TRUE;
2441 /* The channel is coming from our server, thus it is in our cell
2442 we will add it to our local list. */
2445 SILC_LOG_DEBUG(("Channel id(%s) from [Server] %s",
2446 silc_id_render(channel_id, SILC_ID_CHANNEL),
2449 /* Check that we don't already have this channel */
2450 channel = silc_idlist_find_channel_by_name(server->local_list,
2451 channel_name, NULL);
2453 channel = silc_idlist_find_channel_by_name(server->global_list,
2454 channel_name, NULL);
2456 /* If the channel does not exist, then create it. This creates a new
2457 key to the channel as well that we will send to the server. */
2459 /* The protocol says that the Channel ID's IP address must be based
2460 on the router's IP address. Check whether the ID is based in our
2461 IP and if it is not then create a new ID and enforce the server
2462 to switch the ID. */
2463 if (server_entry->server_type != SILC_BACKUP_ROUTER &&
2464 !SILC_ID_COMPARE(channel_id, server->id, server->id->ip.data_len)) {
2466 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2468 if (silc_id_create_channel_id(server, server->id, server->rng, &tmp)) {
2469 silc_server_send_notify_channel_change(server, sock, FALSE,
2471 silc_free(channel_id);
2476 /* Create the channel with the provided Channel ID */
2477 channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
2481 silc_channel_payload_free(payload);
2482 silc_free(channel_id);
2486 /* Get the mode and set it to the channel */
2487 channel->mode = silc_channel_get_mode(payload);
2489 /* Send the new channel key to the server */
2490 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2491 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
2492 chk = silc_channel_key_payload_encode(id_len, id,
2493 strlen(channel->channel_key->
2495 channel->channel_key->cipher->name,
2496 channel->key_len / 8,
2498 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
2499 chk->data, chk->len, FALSE);
2500 silc_buffer_free(chk);
2503 /* The channel exist by that name, check whether the ID's match.
2504 If they don't then we'll force the server to use the ID we have.
2505 We also create a new key for the channel. */
2506 SilcBuffer users = NULL, users_modes = NULL;
2508 if (!SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
2509 /* They don't match, send CHANNEL_CHANGE notify to the server to
2510 force the ID change. */
2511 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2512 silc_server_send_notify_channel_change(server, sock, FALSE,
2513 channel_id, channel->id);
2516 /* If the mode is different from what we have then enforce the
2518 mode = silc_channel_get_mode(payload);
2519 if (channel->mode != mode) {
2520 SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
2521 silc_server_send_notify_cmode(server, sock, FALSE, channel,
2522 channel->mode, server->id,
2524 channel->cipher, channel->hmac_name,
2525 channel->passphrase);
2528 /* Create new key for the channel and send it to the server and
2529 everybody else possibly on the channel. */
2531 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
2532 if (!silc_server_create_channel_key(server, channel, 0))
2535 /* Send to the channel */
2536 silc_server_send_channel_key(server, sock, channel, FALSE);
2537 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2538 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
2540 /* Send to the server */
2541 chk = silc_channel_key_payload_encode(id_len, id,
2542 strlen(channel->channel_key->
2544 channel->channel_key->
2546 channel->key_len / 8,
2548 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
2549 chk->data, chk->len, FALSE);
2550 silc_buffer_free(chk);
2554 silc_free(channel_id);
2556 /* Since the channel is coming from server and we also know about it
2557 then send the JOIN notify to the server so that it see's our
2558 users on the channel "joining" the channel. */
2559 silc_server_announce_get_channel_users(server, channel, &users,
2562 silc_buffer_push(users, users->data - users->head);
2563 silc_server_packet_send(server, sock,
2564 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2565 users->data, users->len, FALSE);
2566 silc_buffer_free(users);
2569 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
2570 silc_server_packet_send_dest(server, sock,
2571 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2572 channel->id, SILC_ID_CHANNEL,
2574 users_modes->len, FALSE);
2575 silc_buffer_free(users_modes);
2580 silc_channel_payload_free(payload);
2583 /* Received New Channel List packet, list of New Channel List payloads inside
2584 one packet. Process the New Channel payloads one by one. */
2586 void silc_server_new_channel_list(SilcServer server,
2587 SilcSocketConnection sock,
2588 SilcPacketContext *packet)
2590 SilcPacketContext *new;
2592 SilcUInt16 len1, len2;
2594 SILC_LOG_DEBUG(("Processing New Channel List"));
2596 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2597 packet->src_id_type != SILC_ID_SERVER ||
2598 server->server_type == SILC_SERVER)
2601 /* If the sender of this packet is server and we are router we need to
2602 broadcast this packet to other routers in the network. Broadcast
2603 this list packet instead of multiple New Channel packets. */
2604 if (!server->standalone && server->server_type == SILC_ROUTER &&
2605 sock->type == SILC_SOCKET_TYPE_SERVER &&
2606 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2607 SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
2608 silc_server_packet_send(server, server->router->connection,
2610 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2611 packet->buffer->data, packet->buffer->len, FALSE);
2612 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
2613 packet->type, packet->flags,
2614 packet->buffer->data, packet->buffer->len,
2618 /* Make copy of the original packet context, except for the actual
2619 data buffer, which we will here now fetch from the original buffer. */
2620 new = silc_packet_context_alloc();
2621 new->type = SILC_PACKET_NEW_CHANNEL;
2622 new->flags = packet->flags;
2623 new->src_id = packet->src_id;
2624 new->src_id_len = packet->src_id_len;
2625 new->src_id_type = packet->src_id_type;
2626 new->dst_id = packet->dst_id;
2627 new->dst_id_len = packet->dst_id_len;
2628 new->dst_id_type = packet->dst_id_type;
2630 buffer = silc_buffer_alloc(512);
2631 new->buffer = buffer;
2633 while (packet->buffer->len) {
2634 SILC_GET16_MSB(len1, packet->buffer->data);
2635 if ((len1 > packet->buffer->len) ||
2636 (len1 > buffer->truelen))
2639 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
2640 if ((len2 > packet->buffer->len) ||
2641 (len2 > buffer->truelen))
2644 silc_buffer_pull_tail(buffer, 8 + len1 + len2);
2645 silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
2647 /* Process the New Channel */
2648 silc_server_new_channel(server, sock, new);
2650 silc_buffer_push_tail(buffer, 8 + len1 + len2);
2651 silc_buffer_pull(packet->buffer, 8 + len1 + len2);
2654 silc_buffer_free(buffer);
2658 /* Received key agreement packet. This packet is never for us. It is to
2659 the client in the packet's destination ID. Sending of this sort of packet
2660 equals sending private message, ie. it is sent point to point from
2661 one client to another. */
2663 void silc_server_key_agreement(SilcServer server,
2664 SilcSocketConnection sock,
2665 SilcPacketContext *packet)
2667 SilcSocketConnection dst_sock;
2668 SilcIDListData idata;
2670 SILC_LOG_DEBUG(("Start"));
2672 if (packet->src_id_type != SILC_ID_CLIENT ||
2673 packet->dst_id_type != SILC_ID_CLIENT)
2676 if (!packet->dst_id)
2679 /* Get the route to the client */
2680 dst_sock = silc_server_get_client_route(server, packet->dst_id,
2681 packet->dst_id_len, NULL,
2686 /* Relay the packet */
2687 silc_server_relay_packet(server, dst_sock, idata->send_key,
2688 idata->hmac_send, idata->psn_send++,
2692 /* Received connection auth request packet that is used during connection
2693 phase to resolve the mandatory authentication method. This packet can
2694 actually be received at anytime but usually it is used only during
2695 the connection authentication phase. Now, protocol says that this packet
2696 can come from client or server, however, we support only this coming
2697 from client and expect that server always knows what authentication
2700 void silc_server_connection_auth_request(SilcServer server,
2701 SilcSocketConnection sock,
2702 SilcPacketContext *packet)
2704 SilcServerConfigClient *client = NULL;
2705 SilcUInt16 conn_type;
2707 SilcAuthMethod auth_meth = SILC_AUTH_NONE;
2709 SILC_LOG_DEBUG(("Start"));
2711 if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT)
2714 /* Parse the payload */
2715 ret = silc_buffer_unformat(packet->buffer,
2716 SILC_STR_UI_SHORT(&conn_type),
2717 SILC_STR_UI_SHORT(NULL),
2722 if (conn_type != SILC_SOCKET_TYPE_CLIENT)
2725 /* Get the authentication method for the client */
2726 auth_meth = SILC_AUTH_NONE;
2727 client = silc_server_config_find_client(server, sock->ip);
2729 client = silc_server_config_find_client(server, sock->hostname);
2731 if (client->passphrase) {
2732 if (client->publickeys && !server->config->prefer_passphrase_auth)
2733 auth_meth = SILC_AUTH_PUBLIC_KEY;
2735 auth_meth = SILC_AUTH_PASSWORD;
2736 } else if (client->publickeys)
2737 auth_meth = SILC_AUTH_PUBLIC_KEY;
2740 /* Send it back to the client */
2741 silc_server_send_connection_auth_request(server, sock, conn_type, auth_meth);
2744 /* Received REKEY packet. The sender of the packet wants to regenerate
2745 its session keys. This starts the REKEY protocol. */
2747 void silc_server_rekey(SilcServer server,
2748 SilcSocketConnection sock,
2749 SilcPacketContext *packet)
2751 SilcProtocol protocol;
2752 SilcServerRekeyInternalContext *proto_ctx;
2753 SilcIDListData idata = (SilcIDListData)sock->user_data;
2755 SILC_LOG_DEBUG(("Start"));
2757 /* Allocate internal protocol context. This is sent as context
2759 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
2760 proto_ctx->server = (void *)server;
2761 proto_ctx->sock = sock;
2762 proto_ctx->responder = TRUE;
2763 proto_ctx->pfs = idata->rekey->pfs;
2765 /* Perform rekey protocol. Will call the final callback after the
2766 protocol is over. */
2767 silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
2768 &protocol, proto_ctx, silc_server_rekey_final);
2769 sock->protocol = protocol;
2771 if (proto_ctx->pfs == FALSE)
2772 /* Run the protocol */
2773 silc_protocol_execute(protocol, server->schedule, 0, 0);
2776 /* Received file transger packet. This packet is never for us. It is to
2777 the client in the packet's destination ID. Sending of this sort of packet
2778 equals sending private message, ie. it is sent point to point from
2779 one client to another. */
2781 void silc_server_ftp(SilcServer server,
2782 SilcSocketConnection sock,
2783 SilcPacketContext *packet)
2785 SilcSocketConnection dst_sock;
2786 SilcIDListData idata;
2788 SILC_LOG_DEBUG(("Start"));
2790 if (packet->src_id_type != SILC_ID_CLIENT ||
2791 packet->dst_id_type != SILC_ID_CLIENT)
2794 if (!packet->dst_id)
2797 /* Get the route to the client */
2798 dst_sock = silc_server_get_client_route(server, packet->dst_id,
2799 packet->dst_id_len, NULL,
2804 /* Relay the packet */
2805 silc_server_relay_packet(server, dst_sock, idata->send_key,
2806 idata->hmac_send, idata->psn_send++,
2812 SilcSocketConnection sock;
2813 SilcPacketContext *packet;
2815 } *SilcServerResumeResolve;
2817 SILC_SERVER_CMD_FUNC(resume_resolve)
2819 SilcServerResumeResolve r = (SilcServerResumeResolve)context;
2820 SilcServer server = r->server;
2821 SilcSocketConnection sock = r->sock;
2822 SilcServerCommandReplyContext reply = context2;
2823 SilcClientEntry client;
2825 SILC_LOG_DEBUG(("Start"));
2827 if (!reply || !silc_command_get_status(reply->payload, NULL, NULL)) {
2828 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
2829 "closing connection", sock->hostname, sock->ip));
2830 silc_server_disconnect_remote(server, sock,
2831 "Server closed connection: "
2832 "Incomplete resume information");
2836 if (reply && silc_command_get(reply->payload) == SILC_COMMAND_WHOIS) {
2837 /* Get entry to the client, and resolve it if we don't have it. */
2838 client = silc_idlist_find_client_by_id(server->local_list,
2839 r->data, TRUE, NULL);
2841 client = silc_idlist_find_client_by_id(server->global_list,
2842 r->data, TRUE, NULL);
2844 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
2845 "closing connection", sock->hostname, sock->ip));
2846 silc_server_disconnect_remote(server, sock,
2847 "Server closed connection: "
2848 "Incomplete resume information");
2853 if (!(client->mode & SILC_UMODE_DETACHED)) {
2854 SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, "
2855 "closing connection", sock->hostname, sock->ip));
2856 silc_server_disconnect_remote(server, sock,
2857 "Server closed connection: "
2858 "Incomplete resume information");
2863 /* Reprocess the packet */
2864 silc_server_resume_client(server, sock, r->packet);
2867 silc_socket_free(r->sock);
2868 silc_packet_context_free(r->packet);
2873 /* Received client resuming packet. This is used to resume detached
2874 client session. It can be sent by the client who wishes to resume
2875 but this is also sent by servers and routers to notify other routers
2876 that the client is not detached anymore. */
2878 void silc_server_resume_client(SilcServer server,
2879 SilcSocketConnection sock,
2880 SilcPacketContext *packet)
2882 SilcBuffer buffer = packet->buffer, buf;
2883 SilcIDListData idata;
2884 SilcClientEntry detached_client;
2885 SilcClientID *client_id = NULL;
2886 unsigned char *id_string, *auth = NULL;
2887 SilcUInt16 id_len, auth_len = 0;
2888 int ret, nickfail = 0;
2889 bool resolved, local, nick_change = FALSE;
2890 SilcChannelEntry channel;
2891 SilcHashTableList htl;
2892 SilcChannelClientEntry chl;
2893 SilcServerResumeResolve r;
2895 SILC_LOG_DEBUG(("Start"));
2897 ret = silc_buffer_unformat(buffer,
2898 SILC_STR_UI16_NSTRING(&id_string, &id_len),
2901 client_id = silc_id_str2id(id_string, id_len, SILC_ID_CLIENT);
2903 if (sock->type == SILC_SOCKET_TYPE_CLIENT) {
2904 /* Client send this and is attempting to resume to old client session */
2905 SilcClientEntry client;
2909 silc_buffer_pull(buffer, 2 + id_len);
2910 auth = buffer->data;
2911 auth_len = buffer->len;
2912 silc_buffer_push(buffer, 2 + id_len);
2915 if (!client_id || auth_len < 128) {
2916 SILC_LOG_ERROR(("Client %s (%s) sent incomplete resume information, "
2917 "closing connection", sock->hostname, sock->ip));
2918 silc_server_disconnect_remote(server, sock, "Server closed connection: "
2919 "Incomplete resume information");
2923 /* Take client entry of this connection */
2924 client = (SilcClientEntry)sock->user_data;
2925 idata = (SilcIDListData)client;
2927 /* Get entry to the client, and resolve it if we don't have it. */
2928 detached_client = silc_server_get_client_resolve(server, client_id, FALSE,
2930 if (!detached_client) {
2932 /* The client info is being resolved. Reprocess this packet after
2933 receiving the reply to the query. */
2934 SILC_LOG_DEBUG(("Resolving client"));
2935 r = silc_calloc(1, sizeof(*r));
2939 r->sock = silc_socket_dup(sock);
2940 r->packet = silc_packet_context_dup(packet);
2941 r->data = silc_id_dup(client_id, SILC_ID_CLIENT);
2942 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
2944 silc_server_command_resume_resolve, r);
2946 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
2947 "closing connection", sock->hostname, sock->ip));
2948 silc_server_disconnect_remote(server, sock,
2949 "Server closed connection: "
2950 "Incomplete resume information");
2955 /* Check that the client is detached, and that we have other info too */
2956 if (!(detached_client->mode & SILC_UMODE_DETACHED) ||
2957 !silc_hash_table_count(detached_client->channels) ||
2958 !detached_client->nickname) {
2959 if (server->server_type == SILC_SERVER && !server->standalone) {
2960 /* The client info is being resolved. Reprocess this packet after
2961 receiving the reply to the query. */
2962 SILC_LOG_DEBUG(("Resolving client info"));
2963 silc_server_get_client_resolve(server, client_id, TRUE, NULL);
2964 r = silc_calloc(1, sizeof(*r));
2968 r->sock = silc_socket_dup(sock);
2969 r->packet = silc_packet_context_dup(packet);
2970 r->data = silc_id_dup(client_id, SILC_ID_CLIENT);
2971 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
2973 silc_server_command_resume_resolve, r);
2975 SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, "
2976 "closing connection", sock->hostname, sock->ip));
2977 silc_server_disconnect_remote(server, sock,
2978 "Server closed connection: "
2979 "Incomplete resume information");
2984 /* Check that we have the public key of the client, if not then we must
2985 resolve it first. */
2986 if (!detached_client->data.public_key) {
2987 if (server->standalone) {
2988 silc_server_disconnect_remote(server, sock,
2989 "Server closed connection: "
2990 "Incomplete resume information");
2992 /* We must retrieve the detached client's public key by sending
2993 GETKEY command. Reprocess this packet after receiving the key */
2994 SilcBuffer idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
2995 SilcSocketConnection dest_sock =
2996 silc_server_get_client_route(server, NULL, 0, client_id, NULL, NULL);
2998 SILC_LOG_DEBUG(("Resolving client public key"));
3000 silc_server_send_command(server, dest_sock ? dest_sock :
3001 server->router->connection,
3002 SILC_COMMAND_GETKEY, ++server->cmd_ident,
3003 1, 1, idp->data, idp->len);
3005 r = silc_calloc(1, sizeof(*r));
3010 r->sock = silc_socket_dup(sock);
3011 r->packet = silc_packet_context_dup(packet);
3012 silc_server_command_pending(server, SILC_COMMAND_GETKEY,
3014 silc_server_command_resume_resolve, r);
3016 silc_buffer_free(idp);
3021 /* Verify the authentication payload. This has to be successful in
3022 order to allow the resuming */
3023 if (!silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
3024 detached_client->data.public_key, 0,
3025 idata->hash, detached_client->id,
3027 SILC_LOG_ERROR(("Client %s (%s) resume authentication failed, "
3028 "closing connection", sock->hostname, sock->ip));
3029 silc_server_disconnect_remote(server, sock, "Server closed connection: "
3030 "Incomplete resume information");
3034 /* Now resume the client to the network */
3036 sock->user_data = detached_client;
3037 detached_client->connection = sock;
3039 /* Take new keys and stuff into use in the old entry */
3040 silc_idlist_del_data(detached_client);
3041 silc_idlist_add_data(detached_client, idata);
3042 detached_client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
3043 detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
3044 detached_client->mode &= ~SILC_UMODE_DETACHED;
3046 /* Send the RESUME_CLIENT packet to our primary router so that others
3047 know this client isn't detached anymore. */
3048 buf = silc_buffer_alloc_size(2 + id_len);
3049 silc_buffer_format(buf,
3050 SILC_STR_UI_SHORT(id_len),
3051 SILC_STR_UI_XNSTRING(id_string, id_len),
3054 /* Send to primary router */
3055 if (!server->standalone)
3056 silc_server_packet_send(server, server->router->connection,
3057 SILC_PACKET_RESUME_CLIENT, 0,
3058 buf->data, buf->len, TRUE);
3060 /* As router we must deliver this packet directly to the original
3061 server whom this client was earlier. */
3062 if (server->server_type == SILC_ROUTER && detached_client->router)
3063 silc_server_packet_send(server, detached_client->router->connection,
3064 SILC_PACKET_RESUME_CLIENT, 0,
3065 buf->data, buf->len, TRUE);
3066 silc_buffer_free(buf);
3068 detached_client->router = NULL;
3070 /* Delete this client entry since we're resuming to old one. */
3071 server->stat.my_clients--;
3072 server->stat.clients--;
3073 if (server->stat.cell_clients)
3074 server->stat.cell_clients--;
3075 silc_idlist_del_client(server->local_list, client);
3076 client = detached_client;
3078 /* If the ID is not based in our ID then change it */
3079 if (!SILC_ID_COMPARE(client->id, server->id, server->id->ip.data_len)) {
3080 while (!silc_id_create_client_id(server, server->id, server->rng,
3081 server->md5hash, client->nickname,
3085 silc_server_disconnect_remote(server, sock,
3086 "Server closed connection: "
3090 snprintf(&client->nickname[strlen(client->nickname) - 1], 1,
3097 /* Notify about Client ID change, nickname doesn't actually change. */
3098 if (!server->standalone)
3099 silc_server_send_notify_nick_change(server, server->router->connection,
3100 FALSE, client->id, client_id,
3104 /* Resolve users on those channels that client has joined but we
3105 haven't resolved user list yet. */
3106 if (server->server_type == SILC_SERVER && !server->standalone) {
3107 silc_hash_table_list(client->channels, &htl);
3108 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
3109 channel = chl->channel;
3110 SILC_LOG_DEBUG(("Resolving users for %s channel",
3111 channel->channel_name));
3112 if (channel->disabled || !channel->users_resolved) {
3113 silc_server_send_command(server, server->router->connection,
3114 SILC_COMMAND_USERS, ++server->cmd_ident,
3115 1, 2, channel->channel_name,
3116 strlen(channel->channel_name));
3119 silc_hash_table_list_reset(&htl);
3122 /* Send the new client ID to the client. After this client may start
3123 receiving other packets, and may start sending packets too. */
3124 silc_server_send_new_id(server, sock, FALSE, client_id, SILC_ID_CLIENT,
3125 silc_id_get_len(client_id, SILC_ID_CLIENT));
3128 /* Send NICK change notify to channels as well. */
3129 SilcBuffer oidp, nidp;
3130 oidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3131 nidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
3132 silc_server_send_notify_on_channels(server, NULL, client,
3133 SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
3134 oidp->data, oidp->len,
3135 nidp->data, nidp->len,
3137 strlen(client->nickname));
3138 silc_buffer_free(oidp);
3139 silc_buffer_free(nidp);
3142 /* Add the client again to the ID cache to get it to correct list */
3143 if (!silc_idcache_del_by_context(server->local_list->clients, client))
3144 silc_idcache_del_by_context(server->global_list->clients, client);
3145 silc_free(client->id);
3146 client->id = client_id;
3148 silc_idcache_add(server->local_list->clients, client->nickname,
3149 client->id, client, 0, NULL);
3151 /* Send some nice info to the client */
3152 silc_server_send_connect_notifys(server, sock, client);
3154 /* Send all channel keys of channels the client has joined */
3155 silc_hash_table_list(client->channels, &htl);
3156 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
3157 bool created = FALSE;
3158 channel = chl->channel;
3160 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY)
3163 /* If we don't have channel key, then create one */
3164 if (!channel->channel_key) {
3165 if (!silc_server_create_channel_key(server, channel, 0))
3170 id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3172 silc_channel_key_payload_encode(silc_id_get_len(channel->id,
3175 strlen(channel->channel_key->
3177 channel->channel_key->cipher->name,
3178 channel->key_len / 8, channel->key);
3179 silc_free(id_string);
3181 /* Send the key packet to client */
3182 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
3183 keyp->data, keyp->len, FALSE);
3185 if (created && server->server_type == SILC_SERVER &&
3186 !server->standalone)
3187 silc_server_packet_send(server, server->router->connection,
3188 SILC_PACKET_CHANNEL_KEY, 0,
3189 keyp->data, keyp->len, FALSE);
3191 silc_buffer_free(keyp);
3193 silc_hash_table_list_reset(&htl);
3195 } else if (sock->type != SILC_SOCKET_TYPE_CLIENT) {
3196 /* Server or router sent this to us to notify that that a client has
3198 SilcServerEntry server_entry;
3199 SilcServerID *server_id;
3204 /* Get entry to the client, and resolve it if we don't have it. */
3205 detached_client = silc_idlist_find_client_by_id(server->local_list,
3206 client_id, TRUE, NULL);
3207 if (!detached_client) {
3208 detached_client = silc_idlist_find_client_by_id(server->global_list,
3209 client_id, TRUE, NULL);
3210 if (!detached_client)
3214 /* Check that the client has not been resumed already because it is
3215 protocol error to attempt to resume more than once. The client
3216 will be killed if this protocol error occurs. */
3217 if (detached_client->data.status & SILC_IDLIST_STATUS_RESUMED &&
3218 !(detached_client->mode & SILC_UMODE_DETACHED)) {
3219 /* The client is clearly attempting to resume more than once and
3220 perhaps playing around by resuming from several different places
3221 at the same time. */
3222 silc_server_kill_client(server, detached_client, NULL,
3223 server->id, SILC_ID_SERVER);
3227 /* Check whether client is detached at all */
3228 if (!(detached_client->mode & SILC_UMODE_DETACHED))
3231 /* Client is detached, and now it is resumed. Remove the detached
3232 mode and mark that it is resumed. */
3233 detached_client->mode &= ~SILC_UMODE_DETACHED;
3234 detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
3236 /* Get the new owner of the resumed client */
3237 server_id = silc_id_str2id(packet->src_id, packet->src_id_len,
3238 packet->src_id_type);
3242 /* Get server entry */
3243 server_entry = silc_idlist_find_server_by_id(server->global_list,
3244 server_id, TRUE, NULL);
3246 if (!server_entry) {
3247 server_entry = silc_idlist_find_server_by_id(server->local_list,
3248 server_id, TRUE, NULL);
3250 if (!server_entry) {
3251 silc_free(server_id);
3256 SILC_LOG_DEBUG(("Resuming detached client"));
3258 /* Change the client to correct list. */
3259 if (!silc_idcache_del_by_context(server->local_list->clients,
3261 silc_idcache_del_by_context(server->global_list->clients,
3263 silc_idcache_add(local && server->server_type == SILC_ROUTER ?
3264 server->local_list->clients :
3265 server->global_list->clients,
3266 detached_client->nickname,
3267 detached_client->id, detached_client, FALSE, NULL);
3269 /* Change the owner of the client if needed */
3270 if (detached_client->router != server_entry)
3271 detached_client->router = server_entry;
3273 /* Update channel information regarding global clients on channel. */
3274 if (server->server_type == SILC_SERVER) {
3275 silc_hash_table_list(detached_client->channels, &htl);
3276 while (silc_hash_table_get(&htl, NULL, (void **)&chl))
3277 chl->channel->global_users =
3278 silc_server_channel_has_global(chl->channel);
3279 silc_hash_table_list_reset(&htl);
3282 /* If the sender of this packet is server and we are router we need to
3283 broadcast this packet to other routers in the network. */
3284 if (!server->standalone && server->server_type == SILC_ROUTER &&
3285 sock->type == SILC_SOCKET_TYPE_SERVER &&
3286 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
3287 SILC_LOG_DEBUG(("Broadcasting received Resume Client packet"));
3288 silc_server_packet_send(server, server->router->connection,
3290 packet->flags | SILC_PACKET_FLAG_BROADCAST,
3291 buffer->data, buffer->len, FALSE);
3292 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
3293 packet->type, packet->flags,
3294 packet->buffer->data, packet->buffer->len,
3298 silc_free(server_id);
3301 silc_free(client_id);