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 case SILC_NOTIFY_TYPE_ERROR:
1377 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1378 if (!tmp && tmp_len != 1)
1380 error = (SilcStatus)tmp[0];
1382 SILC_LOG_DEBUG(("ERROR notify (%d)", error));
1384 if (error == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID &&
1385 sock->type == SILC_SOCKET_TYPE_ROUTER) {
1386 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1388 SILC_LOG_DEBUG(("Received invalid client ID notification, deleting "
1389 "the entry from cache"));
1390 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1393 client = silc_idlist_find_client_by_id(server->global_list,
1394 client_id, FALSE, NULL);
1396 silc_server_remove_from_channels(server, NULL, client, TRUE,
1398 silc_idlist_del_client(server->global_list, client);
1400 silc_free(client_id);
1406 /* Ignore rest of the notify types for now */
1407 case SILC_NOTIFY_TYPE_NONE:
1408 case SILC_NOTIFY_TYPE_MOTD:
1415 silc_notify_payload_free(payload);
1418 void silc_server_notify_list(SilcServer server,
1419 SilcSocketConnection sock,
1420 SilcPacketContext *packet)
1422 SilcPacketContext *new;
1426 SILC_LOG_DEBUG(("Processing Notify List"));
1428 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1429 packet->src_id_type != SILC_ID_SERVER)
1432 /* Make copy of the original packet context, except for the actual
1433 data buffer, which we will here now fetch from the original buffer. */
1434 new = silc_packet_context_alloc();
1435 new->type = SILC_PACKET_NOTIFY;
1436 new->flags = packet->flags;
1437 new->src_id = packet->src_id;
1438 new->src_id_len = packet->src_id_len;
1439 new->src_id_type = packet->src_id_type;
1440 new->dst_id = packet->dst_id;
1441 new->dst_id_len = packet->dst_id_len;
1442 new->dst_id_type = packet->dst_id_type;
1444 buffer = silc_buffer_alloc(1024);
1445 new->buffer = buffer;
1447 while (packet->buffer->len) {
1448 SILC_GET16_MSB(len, packet->buffer->data + 2);
1449 if (len > packet->buffer->len)
1452 if (len > buffer->truelen) {
1453 silc_buffer_free(buffer);
1454 buffer = silc_buffer_alloc(1024 + len);
1457 silc_buffer_pull_tail(buffer, len);
1458 silc_buffer_put(buffer, packet->buffer->data, len);
1460 /* Process the Notify */
1461 silc_server_notify(server, sock, new);
1463 silc_buffer_push_tail(buffer, len);
1464 silc_buffer_pull(packet->buffer, len);
1467 silc_buffer_free(buffer);
1471 /* Received private message. This resolves the destination of the message
1472 and sends the packet. This is used by both server and router. If the
1473 destination is our locally connected client this sends the packet to
1474 the client. This may also send the message for further routing if
1475 the destination is not in our server (or router). */
1477 void silc_server_private_message(SilcServer server,
1478 SilcSocketConnection sock,
1479 SilcPacketContext *packet)
1481 SilcSocketConnection dst_sock;
1482 SilcIDListData idata;
1483 SilcClientEntry client;
1485 SILC_LOG_DEBUG(("Start"));
1487 if (packet->src_id_type != SILC_ID_CLIENT ||
1488 packet->dst_id_type != SILC_ID_CLIENT || !packet->dst_id)
1491 /* Get the route to the client */
1492 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1493 packet->dst_id_len, NULL,
1497 unsigned char error;
1499 if (client && client->mode & SILC_UMODE_DETACHED) {
1500 SILC_LOG_DEBUG(("Client is detached, discarding packet"));
1504 /* Send SILC_NOTIFY_TYPE_ERROR to indicate that such destination ID
1505 does not exist or is invalid. */
1506 idp = silc_id_payload_encode_data(packet->dst_id,
1508 packet->dst_id_type);
1512 error = SILC_STATUS_ERR_NO_SUCH_CLIENT_ID;
1513 if (packet->src_id_type == SILC_ID_CLIENT) {
1514 SilcClientID *client_id = silc_id_str2id(packet->src_id,
1516 packet->src_id_type);
1517 silc_server_send_notify_dest(server, sock, FALSE,
1518 client_id, SILC_ID_CLIENT,
1519 SILC_NOTIFY_TYPE_ERROR, 2,
1521 idp->data, idp->len);
1522 silc_free(client_id);
1524 silc_server_send_notify(server, sock, FALSE,
1525 SILC_NOTIFY_TYPE_ERROR, 2,
1527 idp->data, idp->len);
1530 silc_buffer_free(idp);
1534 /* Check whether destination client wishes to receive private messages */
1535 if (client && !(packet->flags & SILC_PACKET_FLAG_PRIVMSG_KEY) &&
1536 client->mode & SILC_UMODE_BLOCK_PRIVMSG) {
1537 SILC_LOG_DEBUG(("Client blocks private messages, discarding packet"));
1541 /* Send the private message */
1542 silc_server_send_private_message(server, dst_sock, idata->send_key,
1543 idata->hmac_send, idata->psn_send++,
1547 /* Received private message key packet.. This packet is never for us. It is to
1548 the client in the packet's destination ID. Sending of this sort of packet
1549 equals sending private message, ie. it is sent point to point from
1550 one client to another. */
1552 void silc_server_private_message_key(SilcServer server,
1553 SilcSocketConnection sock,
1554 SilcPacketContext *packet)
1556 SilcSocketConnection dst_sock;
1557 SilcIDListData idata;
1559 SILC_LOG_DEBUG(("Start"));
1561 if (packet->src_id_type != SILC_ID_CLIENT ||
1562 packet->dst_id_type != SILC_ID_CLIENT)
1565 if (!packet->dst_id)
1568 /* Get the route to the client */
1569 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1570 packet->dst_id_len, NULL,
1575 /* Relay the packet */
1576 silc_server_relay_packet(server, dst_sock, idata->send_key,
1577 idata->hmac_send, idata->psn_send++, packet, FALSE);
1580 /* Processes incoming command reply packet. The command reply packet may
1581 be destined to one of our clients or it may directly for us. We will
1582 call the command reply routine after processing the packet. */
1584 void silc_server_command_reply(SilcServer server,
1585 SilcSocketConnection sock,
1586 SilcPacketContext *packet)
1588 SilcBuffer buffer = packet->buffer;
1589 SilcClientEntry client = NULL;
1590 SilcSocketConnection dst_sock;
1591 SilcIDListData idata;
1592 SilcClientID *id = NULL;
1594 SILC_LOG_DEBUG(("Start"));
1596 /* Source must be server or router */
1597 if (packet->src_id_type != SILC_ID_SERVER &&
1598 sock->type != SILC_SOCKET_TYPE_ROUTER)
1601 if (packet->dst_id_type == SILC_ID_CHANNEL)
1604 if (packet->dst_id_type == SILC_ID_CLIENT) {
1605 /* Destination must be one of ours */
1606 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
1609 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
1611 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
1617 if (packet->dst_id_type == SILC_ID_SERVER) {
1618 /* For now this must be for us */
1619 if (memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
1620 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
1625 /* Execute command reply locally for the command */
1626 silc_server_command_reply_process(server, sock, buffer);
1628 if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
1629 /* Relay the packet to the client */
1630 const SilcBufferStruct p;
1632 dst_sock = (SilcSocketConnection)client->connection;
1633 idata = (SilcIDListData)client;
1635 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
1636 + packet->dst_id_len + packet->padlen);
1637 if (!silc_packet_send_prepare(dst_sock, 0, 0, buffer->len,
1638 idata->hmac_send, (const SilcBuffer)&p)) {
1639 SILC_LOG_ERROR(("Cannot send packet"));
1642 silc_buffer_put((SilcBuffer)&p, buffer->data, buffer->len);
1644 /* Encrypt packet */
1645 silc_packet_encrypt(idata->send_key, idata->hmac_send, idata->psn_send++,
1646 (SilcBuffer)&p, buffer->len);
1648 /* Send the packet */
1649 silc_server_packet_send_real(server, dst_sock, TRUE);
1655 /* Process received channel message. The message can be originated from
1656 client or server. */
1658 void silc_server_channel_message(SilcServer server,
1659 SilcSocketConnection sock,
1660 SilcPacketContext *packet)
1662 SilcChannelEntry channel = NULL;
1663 SilcChannelID *id = NULL;
1664 void *sender_id = NULL;
1665 SilcClientEntry sender_entry = NULL;
1666 SilcChannelClientEntry chl;
1669 SILC_LOG_DEBUG(("Processing channel message"));
1672 if (packet->dst_id_type != SILC_ID_CHANNEL) {
1673 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1677 /* Find channel entry */
1678 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
1681 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
1683 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
1685 SILC_LOG_DEBUG(("Could not find channel"));
1690 /* See that this client is on the channel. If the original sender is
1691 not client (as it can be server as well) we don't do the check. */
1692 sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1693 packet->src_id_type);
1696 if (packet->src_id_type == SILC_ID_CLIENT) {
1697 sender_entry = silc_idlist_find_client_by_id(server->local_list,
1698 sender_id, TRUE, NULL);
1699 if (!sender_entry) {
1701 sender_entry = silc_idlist_find_client_by_id(server->global_list,
1702 sender_id, TRUE, NULL);
1704 if (!sender_entry || !silc_server_client_on_channel(sender_entry,
1706 SILC_LOG_DEBUG(("Client not on channel"));
1710 /* If channel is moderated check that client is allowed to send
1712 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS && !chl->mode) {
1713 SILC_LOG_DEBUG(("Channel is silenced from normal users"));
1716 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS &&
1717 chl->mode & SILC_CHANNEL_UMODE_CHANOP &&
1718 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1719 SILC_LOG_DEBUG(("Channel is silenced from operators"));
1723 /* If the packet is coming from router, but the client entry is local
1724 entry to us then some router is rerouting this to us and it is not
1725 allowed. When the client is local to us it means that we've routed
1726 this packet to network, and now someone is routing it back to us. */
1727 if (server->server_type == SILC_ROUTER &&
1728 sock->type == SILC_SOCKET_TYPE_ROUTER && local) {
1729 SILC_LOG_DEBUG(("Channel message rerouted to the sender, drop it"));
1734 /* Distribute the packet to our local clients. This will send the
1735 packet for further routing as well, if needed. */
1736 silc_server_packet_relay_to_channel(server, sock, channel, sender_id,
1737 packet->src_id_type, sender_entry,
1738 packet->buffer->data,
1739 packet->buffer->len, FALSE);
1742 silc_free(sender_id);
1746 /* Received channel key packet. We distribute the key to all of our locally
1747 connected clients on the channel. */
1749 void silc_server_channel_key(SilcServer server,
1750 SilcSocketConnection sock,
1751 SilcPacketContext *packet)
1753 SilcBuffer buffer = packet->buffer;
1754 SilcChannelEntry channel;
1756 if (packet->src_id_type != SILC_ID_SERVER ||
1757 (server->server_type == SILC_ROUTER &&
1758 sock->type == SILC_SOCKET_TYPE_ROUTER))
1761 /* Save the channel key */
1762 channel = silc_server_save_channel_key(server, buffer, NULL);
1766 /* Distribute the key to everybody who is on the channel. If we are router
1767 we will also send it to locally connected servers. */
1768 silc_server_send_channel_key(server, sock, channel, FALSE);
1770 if (server->server_type != SILC_BACKUP_ROUTER) {
1771 /* Distribute to local cell backup routers. */
1772 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
1773 SILC_PACKET_CHANNEL_KEY, 0,
1774 buffer->data, buffer->len, FALSE, TRUE);
1778 /* Received New Client packet and processes it. Creates Client ID for the
1779 client. Client becomes registered after calling this functions. */
1781 SilcClientEntry silc_server_new_client(SilcServer server,
1782 SilcSocketConnection sock,
1783 SilcPacketContext *packet)
1785 SilcBuffer buffer = packet->buffer;
1786 SilcClientEntry client;
1787 SilcClientID *client_id;
1788 SilcIDListData idata;
1789 char *username = NULL, *realname = NULL;
1790 SilcUInt16 username_len;
1793 char *hostname, *nickname;
1796 SILC_LOG_DEBUG(("Creating new client"));
1798 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
1801 /* Take client entry */
1802 client = (SilcClientEntry)sock->user_data;
1803 idata = (SilcIDListData)client;
1805 /* Remove the old cache entry. */
1806 if (!silc_idcache_del_by_context(server->local_list->clients, client)) {
1807 SILC_LOG_INFO(("Unauthenticated client attempted to register to network"));
1808 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1809 "You have not been authenticated");
1813 /* Parse incoming packet */
1814 ret = silc_buffer_unformat(buffer,
1815 SILC_STR_UI16_NSTRING_ALLOC(&username,
1817 SILC_STR_UI16_STRING_ALLOC(&realname),
1820 silc_free(username);
1821 silc_free(realname);
1822 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
1823 "connection", sock->hostname, sock->ip));
1824 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1825 "Incomplete client information");
1830 silc_free(username);
1831 silc_free(realname);
1832 SILC_LOG_ERROR(("Client %s (%s) did not send its username, closing "
1833 "connection", sock->hostname, sock->ip));
1834 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1835 "Incomplete client information");
1839 if (username_len > 128)
1840 username[128] = '\0';
1842 /* Check for bad characters for nickname, and modify the nickname if
1843 it includes those. */
1844 if (silc_server_name_bad_chars(username, username_len)) {
1845 nickname = silc_server_name_modify_bad(username, username_len);
1847 nickname = strdup(username);
1850 /* Make sanity checks for the hostname of the client. If the hostname
1851 is provided in the `username' check that it is the same than the
1852 resolved hostname, or if not resolved the hostname that appears in
1853 the client's public key. If the hostname is not present then put
1854 it from the resolved name or from the public key. */
1855 if (strchr(username, '@')) {
1856 SilcPublicKeyIdentifier pident;
1857 int tlen = strcspn(username, "@");
1858 char *phostname = NULL;
1860 hostname = silc_memdup(username + tlen + 1, strlen(username) - tlen - 1);
1862 if (strcmp(sock->hostname, sock->ip) &&
1863 strcmp(sock->hostname, hostname)) {
1864 silc_free(username);
1865 silc_free(hostname);
1866 silc_free(realname);
1867 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
1868 "connection", sock->hostname, sock->ip));
1869 silc_server_disconnect_remote(server, sock,
1870 "Server closed connection: "
1871 "Incomplete client information");
1875 pident = silc_pkcs_decode_identifier(client->data.public_key->identifier);
1877 phostname = strdup(pident->host);
1878 silc_pkcs_free_identifier(pident);
1881 if (!strcmp(sock->hostname, sock->ip) &&
1882 phostname && strcmp(phostname, hostname)) {
1883 silc_free(username);
1884 silc_free(hostname);
1885 silc_free(phostname);
1886 silc_free(realname);
1887 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
1888 "connection", sock->hostname, sock->ip));
1889 silc_server_disconnect_remote(server, sock,
1890 "Server closed connection: "
1891 "Incomplete client information");
1895 silc_free(phostname);
1897 /* The hostname is not present, add it. */
1899 /* XXX For now we cannot take the host name from the public key since
1900 they are not trusted or we cannot verify them as trusted. Just take
1901 what the resolved name or address is. */
1903 if (strcmp(sock->hostname, sock->ip)) {
1905 newusername = silc_calloc(strlen(username) +
1906 strlen(sock->hostname) + 2,
1907 sizeof(*newusername));
1908 strncat(newusername, username, strlen(username));
1909 strncat(newusername, "@", 1);
1910 strncat(newusername, sock->hostname, strlen(sock->hostname));
1911 silc_free(username);
1912 username = newusername;
1915 SilcPublicKeyIdentifier pident =
1916 silc_pkcs_decode_identifier(client->data.public_key->identifier);
1919 newusername = silc_calloc(strlen(username) +
1920 strlen(pident->host) + 2,
1921 sizeof(*newusername));
1922 strncat(newusername, username, strlen(username));
1923 strncat(newusername, "@", 1);
1924 strncat(newusername, pident->host, strlen(pident->host));
1925 silc_free(username);
1926 username = newusername;
1927 silc_pkcs_free_identifier(pident);
1933 /* Create Client ID */
1934 while (!silc_id_create_client_id(server, server->id, server->rng,
1935 server->md5hash, nickname, &client_id)) {
1938 silc_server_disconnect_remote(server, sock,
1939 "Server closed connection: Bad nickname");
1942 snprintf(&nickname[strlen(nickname) - 1], 1, "%d", nickfail);
1945 /* Update client entry */
1946 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
1947 client->nickname = nickname;
1948 client->username = username;
1949 client->userinfo = realname ? realname : strdup(" ");
1950 client->id = client_id;
1951 id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
1953 /* Add the client again to the ID cache */
1954 silc_idcache_add(server->local_list->clients, client->nickname,
1955 client_id, client, 0, NULL);
1957 /* Notify our router about new client on the SILC network */
1958 if (!server->standalone)
1959 silc_server_send_new_id(server, (SilcSocketConnection)
1960 server->router->connection,
1961 server->server_type == SILC_ROUTER ? TRUE : FALSE,
1962 client->id, SILC_ID_CLIENT, id_len);
1964 /* Send the new client ID to the client. */
1965 silc_server_send_new_id(server, sock, FALSE, client->id, SILC_ID_CLIENT,
1966 silc_id_get_len(client->id, SILC_ID_CLIENT));
1968 /* Send some nice info to the client */
1969 silc_server_send_connect_notifys(server, sock, client);
1974 /* Create new server. This processes received New Server packet and
1975 saves the received Server ID. The server is our locally connected
1976 server thus we save all the information and save it to local list.
1977 This funtion can be used by both normal server and router server.
1978 If normal server uses this it means that its router has connected
1979 to the server. If router uses this it means that one of the cell's
1980 servers is connected to the router. */
1982 SilcServerEntry silc_server_new_server(SilcServer server,
1983 SilcSocketConnection sock,
1984 SilcPacketContext *packet)
1986 SilcBuffer buffer = packet->buffer;
1987 SilcServerEntry new_server, server_entry;
1988 SilcServerID *server_id;
1989 SilcIDListData idata;
1990 unsigned char *server_name, *id_string;
1991 SilcUInt16 id_len, name_len;
1995 SILC_LOG_DEBUG(("Creating new server"));
1997 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
1998 sock->type != SILC_SOCKET_TYPE_ROUTER)
2001 /* Take server entry */
2002 new_server = (SilcServerEntry)sock->user_data;
2003 idata = (SilcIDListData)new_server;
2005 /* Remove the old cache entry */
2006 if (!silc_idcache_del_by_context(server->local_list->servers, new_server)) {
2007 if (!silc_idcache_del_by_context(server->global_list->servers,
2009 SILC_LOG_INFO(("Unauthenticated %s attempted to register to "
2010 "network", (sock->type == SILC_SOCKET_TYPE_SERVER ?
2011 "server" : "router")));
2012 silc_server_disconnect_remote(server, sock, "Server closed connection: "
2013 "You have not been authenticated");
2019 /* Parse the incoming packet */
2020 ret = silc_buffer_unformat(buffer,
2021 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
2022 SILC_STR_UI16_NSTRING_ALLOC(&server_name,
2027 silc_free(id_string);
2029 silc_free(server_name);
2033 if (id_len > buffer->len) {
2034 silc_free(id_string);
2035 silc_free(server_name);
2040 server_name[255] = '\0';
2043 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
2045 silc_free(id_string);
2046 silc_free(server_name);
2049 silc_free(id_string);
2051 /* Check for valid server ID */
2052 if (!silc_id_is_valid_server_id(server, server_id, sock)) {
2053 SILC_LOG_INFO(("Invalid server ID sent by %s (%s)",
2054 sock->ip, sock->hostname));
2055 silc_server_disconnect_remote(server, sock, "Server closed connection: "
2056 "Your Server ID is not valid");
2057 silc_free(server_name);
2061 /* Check that we do not have this ID already */
2062 server_entry = silc_idlist_find_server_by_id(server->local_list,
2063 server_id, TRUE, NULL);
2065 silc_idcache_del_by_context(server->local_list->servers, server_entry);
2067 server_entry = silc_idlist_find_server_by_id(server->global_list,
2068 server_id, TRUE, NULL);
2070 silc_idcache_del_by_context(server->global_list->servers, server_entry);
2073 /* Update server entry */
2074 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
2075 new_server->server_name = server_name;
2076 new_server->id = server_id;
2078 SILC_LOG_DEBUG(("New server id(%s)",
2079 silc_id_render(server_id, SILC_ID_SERVER)));
2081 /* Add again the entry to the ID cache. */
2082 silc_idcache_add(local ? server->local_list->servers :
2083 server->global_list->servers, server_name, server_id,
2084 new_server, 0, NULL);
2086 /* Distribute the information about new server in the SILC network
2087 to our router. If we are normal server we won't send anything
2088 since this connection must be our router connection. */
2089 if (server->server_type == SILC_ROUTER && !server->standalone &&
2090 server->router->connection != sock)
2091 silc_server_send_new_id(server, server->router->connection,
2092 TRUE, new_server->id, SILC_ID_SERVER,
2093 silc_id_get_len(server_id, SILC_ID_SERVER));
2095 if (server->server_type == SILC_ROUTER)
2096 server->stat.cell_servers++;
2098 /* Check whether this router connection has been replaced by an
2099 backup router. If it has been then we'll disable the server and will
2100 ignore everything it will send until the backup router resuming
2101 protocol has been completed. */
2102 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
2103 silc_server_backup_replaced_get(server, server_id, NULL)) {
2104 /* Send packet to the server indicating that it cannot use this
2105 connection as it has been replaced by backup router. */
2106 SilcBuffer packet = silc_buffer_alloc(2);
2107 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
2108 silc_buffer_format(packet,
2109 SILC_STR_UI_CHAR(SILC_SERVER_BACKUP_REPLACED),
2110 SILC_STR_UI_CHAR(0),
2112 silc_server_packet_send(server, sock,
2113 SILC_PACKET_RESUME_ROUTER, 0,
2114 packet->data, packet->len, TRUE);
2115 silc_buffer_free(packet);
2117 /* Mark the router disabled. The data sent earlier will go but nothing
2118 after this does not go to this connection. */
2119 idata->status |= SILC_IDLIST_STATUS_DISABLED;
2121 /* If it is router announce our stuff to it. */
2122 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
2123 server->server_type == SILC_ROUTER) {
2124 silc_server_announce_servers(server, FALSE, 0, sock);
2125 silc_server_announce_clients(server, 0, sock);
2126 silc_server_announce_channels(server, 0, sock);
2133 /* Processes incoming New ID packet. New ID Payload is used to distribute
2134 information about newly registered clients and servers. */
2136 static void silc_server_new_id_real(SilcServer server,
2137 SilcSocketConnection sock,
2138 SilcPacketContext *packet,
2141 SilcBuffer buffer = packet->buffer;
2143 SilcServerEntry router, server_entry;
2144 SilcSocketConnection router_sock;
2149 SILC_LOG_DEBUG(("Processing new ID"));
2151 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2152 server->server_type == SILC_SERVER ||
2153 packet->src_id_type != SILC_ID_SERVER)
2156 idp = silc_id_payload_parse(buffer->data, buffer->len);
2160 id_type = silc_id_payload_get_type(idp);
2162 /* Normal server cannot have other normal server connections */
2163 server_entry = (SilcServerEntry)sock->user_data;
2164 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER &&
2165 server_entry->server_type == SILC_SERVER)
2168 id = silc_id_payload_get_id(idp);
2172 /* If the packet is coming from server then use the sender as the
2173 origin of the the packet. If it came from router then check the real
2174 sender of the packet and use that as the origin. */
2175 if (sock->type == SILC_SOCKET_TYPE_SERVER) {
2176 id_list = server->local_list;
2178 router = sock->user_data;
2180 /* If the sender is backup router and ID is server (and we are not
2181 backup router) then switch the entry to global list. */
2182 if (server_entry->server_type == SILC_BACKUP_ROUTER &&
2183 id_type == SILC_ID_SERVER &&
2184 server->id_entry->server_type != SILC_BACKUP_ROUTER) {
2185 id_list = server->global_list;
2186 router_sock = server->router ? server->router->connection : sock;
2189 void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2190 packet->src_id_type);
2191 router = silc_idlist_find_server_by_id(server->global_list,
2192 sender_id, TRUE, NULL);
2194 router = silc_idlist_find_server_by_id(server->local_list,
2195 sender_id, TRUE, NULL);
2196 silc_free(sender_id);
2198 id_list = server->global_list;
2205 case SILC_ID_CLIENT:
2207 SilcClientEntry entry;
2209 /* Check that we do not have this client already */
2210 entry = silc_idlist_find_client_by_id(server->global_list,
2211 id, server->server_type,
2214 entry = silc_idlist_find_client_by_id(server->local_list,
2215 id, server->server_type,
2218 SILC_LOG_DEBUG(("Ignoring client that we already have"));
2222 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
2223 silc_id_render(id, SILC_ID_CLIENT),
2224 sock->type == SILC_SOCKET_TYPE_SERVER ?
2225 "Server" : "Router", sock->hostname));
2227 /* As a router we keep information of all global information in our
2228 global list. Cell wide information however is kept in the local
2230 entry = silc_idlist_add_client(id_list, NULL, NULL, NULL,
2231 id, router, NULL, 0);
2233 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
2235 /* Inform the sender that the ID is not usable */
2236 silc_server_send_notify_signoff(server, sock, FALSE, id, NULL);
2239 entry->nickname = NULL;
2240 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2242 if (sock->type == SILC_SOCKET_TYPE_SERVER)
2243 server->stat.cell_clients++;
2244 server->stat.clients++;
2248 case SILC_ID_SERVER:
2250 SilcServerEntry entry;
2252 /* If the ID is mine, ignore it. */
2253 if (SILC_ID_SERVER_COMPARE(id, server->id)) {
2254 SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
2258 /* If the ID is the sender's ID, ignore it (we have it already) */
2259 if (SILC_ID_SERVER_COMPARE(id, router->id)) {
2260 SILC_LOG_DEBUG(("Ignoring sender's own ID"));
2264 /* Check that we do not have this server already */
2265 entry = silc_idlist_find_server_by_id(server->global_list,
2266 id, server->server_type,
2269 entry = silc_idlist_find_server_by_id(server->local_list,
2270 id, server->server_type,
2273 SILC_LOG_DEBUG(("Ignoring server that we already have"));
2277 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
2278 silc_id_render(id, SILC_ID_SERVER),
2279 sock->type == SILC_SOCKET_TYPE_SERVER ?
2280 "Server" : "Router", sock->hostname));
2282 /* As a router we keep information of all global information in our
2283 global list. Cell wide information however is kept in the local
2285 entry = silc_idlist_add_server(id_list, NULL, 0, id, router,
2288 SILC_LOG_ERROR(("Could not add new server to the ID Cache"));
2291 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2293 if (sock->type == SILC_SOCKET_TYPE_SERVER)
2294 server->stat.cell_servers++;
2295 server->stat.servers++;
2299 case SILC_ID_CHANNEL:
2300 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
2309 /* If the sender of this packet is server and we are router we need to
2310 broadcast this packet to other routers in the network. */
2311 if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
2312 sock->type == SILC_SOCKET_TYPE_SERVER &&
2313 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2314 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
2315 silc_server_packet_send(server, server->router->connection,
2317 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2318 buffer->data, buffer->len, FALSE);
2319 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
2320 packet->type, packet->flags,
2321 packet->buffer->data, packet->buffer->len,
2326 silc_id_payload_free(idp);
2330 /* Processes incoming New ID packet. New ID Payload is used to distribute
2331 information about newly registered clients and servers. */
2333 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
2334 SilcPacketContext *packet)
2336 silc_server_new_id_real(server, sock, packet, TRUE);
2339 /* Receoved New Id List packet, list of New ID payloads inside one
2340 packet. Process the New ID payloads one by one. */
2342 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
2343 SilcPacketContext *packet)
2345 SilcPacketContext *new_id;
2349 SILC_LOG_DEBUG(("Processing New ID List"));
2351 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2352 packet->src_id_type != SILC_ID_SERVER)
2355 /* If the sender of this packet is server and we are router we need to
2356 broadcast this packet to other routers in the network. Broadcast
2357 this list packet instead of multiple New ID packets. */
2358 if (!server->standalone && server->server_type == SILC_ROUTER &&
2359 sock->type == SILC_SOCKET_TYPE_SERVER &&
2360 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2361 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
2362 silc_server_packet_send(server, server->router->connection,
2364 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2365 packet->buffer->data, packet->buffer->len, FALSE);
2366 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
2367 packet->type, packet->flags,
2368 packet->buffer->data, packet->buffer->len,
2372 /* Make copy of the original packet context, except for the actual
2373 data buffer, which we will here now fetch from the original buffer. */
2374 new_id = silc_packet_context_alloc();
2375 new_id->type = SILC_PACKET_NEW_ID;
2376 new_id->flags = packet->flags;
2377 new_id->src_id = packet->src_id;
2378 new_id->src_id_len = packet->src_id_len;
2379 new_id->src_id_type = packet->src_id_type;
2380 new_id->dst_id = packet->dst_id;
2381 new_id->dst_id_len = packet->dst_id_len;
2382 new_id->dst_id_type = packet->dst_id_type;
2384 idp = silc_buffer_alloc(256);
2385 new_id->buffer = idp;
2387 while (packet->buffer->len) {
2388 SILC_GET16_MSB(id_len, packet->buffer->data + 2);
2389 if ((id_len > packet->buffer->len) ||
2390 (id_len > idp->truelen))
2393 silc_buffer_pull_tail(idp, 4 + id_len);
2394 silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
2396 /* Process the New ID */
2397 silc_server_new_id_real(server, sock, new_id, FALSE);
2399 silc_buffer_push_tail(idp, 4 + id_len);
2400 silc_buffer_pull(packet->buffer, 4 + id_len);
2403 silc_buffer_free(idp);
2407 /* Received New Channel packet. Information about new channels in the
2408 network are distributed using this packet. Save the information about
2409 the new channel. This usually comes from router but also normal server
2410 can send this to notify channels it has when it connects to us. */
2412 void silc_server_new_channel(SilcServer server,
2413 SilcSocketConnection sock,
2414 SilcPacketContext *packet)
2416 SilcChannelPayload payload;
2417 SilcChannelID *channel_id;
2419 SilcUInt32 name_len;
2423 SilcServerEntry server_entry;
2424 SilcChannelEntry channel;
2426 SILC_LOG_DEBUG(("Processing New Channel"));
2428 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2429 packet->src_id_type != SILC_ID_SERVER ||
2430 server->server_type == SILC_SERVER)
2433 /* Parse the channel payload */
2434 payload = silc_channel_payload_parse(packet->buffer->data,
2435 packet->buffer->len);
2439 /* Get the channel ID */
2440 channel_id = silc_channel_get_id_parse(payload);
2442 silc_channel_payload_free(payload);
2446 channel_name = silc_channel_get_name(payload, &name_len);
2448 channel_name[255] = '\0';
2450 id = silc_channel_get_id(payload, &id_len);
2452 server_entry = (SilcServerEntry)sock->user_data;
2454 if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
2455 /* Add the channel to global list as it is coming from router. It
2456 cannot be our own channel as it is coming from router. */
2458 /* Check that we don't already have this channel */
2459 channel = silc_idlist_find_channel_by_name(server->local_list,
2460 channel_name, NULL);
2462 channel = silc_idlist_find_channel_by_name(server->global_list,
2463 channel_name, NULL);
2465 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
2466 silc_id_render(channel_id, SILC_ID_CHANNEL),
2470 silc_idlist_add_channel(server->global_list, strdup(channel_name),
2471 0, channel_id, sock->user_data, NULL, NULL, 0);
2475 server->stat.channels++;
2476 if (server->server_type == SILC_ROUTER)
2477 channel->users_resolved = TRUE;
2480 /* The channel is coming from our server, thus it is in our cell
2481 we will add it to our local list. */
2484 SILC_LOG_DEBUG(("Channel id(%s) from [Server] %s",
2485 silc_id_render(channel_id, SILC_ID_CHANNEL),
2488 /* Check that we don't already have this channel */
2489 channel = silc_idlist_find_channel_by_name(server->local_list,
2490 channel_name, NULL);
2492 channel = silc_idlist_find_channel_by_name(server->global_list,
2493 channel_name, NULL);
2495 /* If the channel does not exist, then create it. This creates a new
2496 key to the channel as well that we will send to the server. */
2498 /* The protocol says that the Channel ID's IP address must be based
2499 on the router's IP address. Check whether the ID is based in our
2500 IP and if it is not then create a new ID and enforce the server
2501 to switch the ID. */
2502 if (server_entry->server_type != SILC_BACKUP_ROUTER &&
2503 !SILC_ID_COMPARE(channel_id, server->id, server->id->ip.data_len)) {
2505 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2507 if (silc_id_create_channel_id(server, server->id, server->rng, &tmp)) {
2508 silc_server_send_notify_channel_change(server, sock, FALSE,
2510 silc_free(channel_id);
2515 /* Create the channel with the provided Channel ID */
2516 channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
2520 silc_channel_payload_free(payload);
2521 silc_free(channel_id);
2525 /* Get the mode and set it to the channel */
2526 channel->mode = silc_channel_get_mode(payload);
2528 /* Send the new channel key to the server */
2529 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2530 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
2531 chk = silc_channel_key_payload_encode(id_len, id,
2532 strlen(channel->channel_key->
2534 channel->channel_key->cipher->name,
2535 channel->key_len / 8,
2537 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
2538 chk->data, chk->len, FALSE);
2539 silc_buffer_free(chk);
2542 /* The channel exist by that name, check whether the ID's match.
2543 If they don't then we'll force the server to use the ID we have.
2544 We also create a new key for the channel. */
2545 SilcBuffer users = NULL, users_modes = NULL;
2547 if (!SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
2548 /* They don't match, send CHANNEL_CHANGE notify to the server to
2549 force the ID change. */
2550 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2551 silc_server_send_notify_channel_change(server, sock, FALSE,
2552 channel_id, channel->id);
2555 /* If the mode is different from what we have then enforce the
2557 mode = silc_channel_get_mode(payload);
2558 if (channel->mode != mode) {
2559 SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
2560 silc_server_send_notify_cmode(server, sock, FALSE, channel,
2561 channel->mode, server->id,
2563 channel->cipher, channel->hmac_name,
2564 channel->passphrase);
2567 /* Create new key for the channel and send it to the server and
2568 everybody else possibly on the channel. */
2570 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
2571 if (!silc_server_create_channel_key(server, channel, 0))
2574 /* Send to the channel */
2575 silc_server_send_channel_key(server, sock, channel, FALSE);
2576 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2577 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
2579 /* Send to the server */
2580 chk = silc_channel_key_payload_encode(id_len, id,
2581 strlen(channel->channel_key->
2583 channel->channel_key->
2585 channel->key_len / 8,
2587 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
2588 chk->data, chk->len, FALSE);
2589 silc_buffer_free(chk);
2593 silc_free(channel_id);
2595 /* Since the channel is coming from server and we also know about it
2596 then send the JOIN notify to the server so that it see's our
2597 users on the channel "joining" the channel. */
2598 silc_server_announce_get_channel_users(server, channel, &users,
2601 silc_buffer_push(users, users->data - users->head);
2602 silc_server_packet_send(server, sock,
2603 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2604 users->data, users->len, FALSE);
2605 silc_buffer_free(users);
2608 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
2609 silc_server_packet_send_dest(server, sock,
2610 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2611 channel->id, SILC_ID_CHANNEL,
2613 users_modes->len, FALSE);
2614 silc_buffer_free(users_modes);
2619 silc_channel_payload_free(payload);
2622 /* Received New Channel List packet, list of New Channel List payloads inside
2623 one packet. Process the New Channel payloads one by one. */
2625 void silc_server_new_channel_list(SilcServer server,
2626 SilcSocketConnection sock,
2627 SilcPacketContext *packet)
2629 SilcPacketContext *new;
2631 SilcUInt16 len1, len2;
2633 SILC_LOG_DEBUG(("Processing New Channel List"));
2635 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2636 packet->src_id_type != SILC_ID_SERVER ||
2637 server->server_type == SILC_SERVER)
2640 /* If the sender of this packet is server and we are router we need to
2641 broadcast this packet to other routers in the network. Broadcast
2642 this list packet instead of multiple New Channel packets. */
2643 if (!server->standalone && server->server_type == SILC_ROUTER &&
2644 sock->type == SILC_SOCKET_TYPE_SERVER &&
2645 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2646 SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
2647 silc_server_packet_send(server, server->router->connection,
2649 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2650 packet->buffer->data, packet->buffer->len, FALSE);
2651 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
2652 packet->type, packet->flags,
2653 packet->buffer->data, packet->buffer->len,
2657 /* Make copy of the original packet context, except for the actual
2658 data buffer, which we will here now fetch from the original buffer. */
2659 new = silc_packet_context_alloc();
2660 new->type = SILC_PACKET_NEW_CHANNEL;
2661 new->flags = packet->flags;
2662 new->src_id = packet->src_id;
2663 new->src_id_len = packet->src_id_len;
2664 new->src_id_type = packet->src_id_type;
2665 new->dst_id = packet->dst_id;
2666 new->dst_id_len = packet->dst_id_len;
2667 new->dst_id_type = packet->dst_id_type;
2669 buffer = silc_buffer_alloc(512);
2670 new->buffer = buffer;
2672 while (packet->buffer->len) {
2673 SILC_GET16_MSB(len1, packet->buffer->data);
2674 if ((len1 > packet->buffer->len) ||
2675 (len1 > buffer->truelen))
2678 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
2679 if ((len2 > packet->buffer->len) ||
2680 (len2 > buffer->truelen))
2683 silc_buffer_pull_tail(buffer, 8 + len1 + len2);
2684 silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
2686 /* Process the New Channel */
2687 silc_server_new_channel(server, sock, new);
2689 silc_buffer_push_tail(buffer, 8 + len1 + len2);
2690 silc_buffer_pull(packet->buffer, 8 + len1 + len2);
2693 silc_buffer_free(buffer);
2697 /* Received key agreement packet. This packet is never for us. It is to
2698 the client in the packet's destination ID. Sending of this sort of packet
2699 equals sending private message, ie. it is sent point to point from
2700 one client to another. */
2702 void silc_server_key_agreement(SilcServer server,
2703 SilcSocketConnection sock,
2704 SilcPacketContext *packet)
2706 SilcSocketConnection dst_sock;
2707 SilcIDListData idata;
2709 SILC_LOG_DEBUG(("Start"));
2711 if (packet->src_id_type != SILC_ID_CLIENT ||
2712 packet->dst_id_type != SILC_ID_CLIENT)
2715 if (!packet->dst_id)
2718 /* Get the route to the client */
2719 dst_sock = silc_server_get_client_route(server, packet->dst_id,
2720 packet->dst_id_len, NULL,
2725 /* Relay the packet */
2726 silc_server_relay_packet(server, dst_sock, idata->send_key,
2727 idata->hmac_send, idata->psn_send++,
2731 /* Received connection auth request packet that is used during connection
2732 phase to resolve the mandatory authentication method. This packet can
2733 actually be received at anytime but usually it is used only during
2734 the connection authentication phase. Now, protocol says that this packet
2735 can come from client or server, however, we support only this coming
2736 from client and expect that server always knows what authentication
2739 void silc_server_connection_auth_request(SilcServer server,
2740 SilcSocketConnection sock,
2741 SilcPacketContext *packet)
2743 SilcServerConfigClient *client = NULL;
2744 SilcUInt16 conn_type;
2746 SilcAuthMethod auth_meth = SILC_AUTH_NONE;
2748 SILC_LOG_DEBUG(("Start"));
2750 if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT)
2753 /* Parse the payload */
2754 ret = silc_buffer_unformat(packet->buffer,
2755 SILC_STR_UI_SHORT(&conn_type),
2756 SILC_STR_UI_SHORT(NULL),
2761 if (conn_type != SILC_SOCKET_TYPE_CLIENT)
2764 /* Get the authentication method for the client */
2765 auth_meth = SILC_AUTH_NONE;
2766 client = silc_server_config_find_client(server, sock->ip);
2768 client = silc_server_config_find_client(server, sock->hostname);
2770 if (client->passphrase) {
2771 if (client->publickeys && !server->config->prefer_passphrase_auth)
2772 auth_meth = SILC_AUTH_PUBLIC_KEY;
2774 auth_meth = SILC_AUTH_PASSWORD;
2775 } else if (client->publickeys)
2776 auth_meth = SILC_AUTH_PUBLIC_KEY;
2779 /* Send it back to the client */
2780 silc_server_send_connection_auth_request(server, sock, conn_type, auth_meth);
2783 /* Received REKEY packet. The sender of the packet wants to regenerate
2784 its session keys. This starts the REKEY protocol. */
2786 void silc_server_rekey(SilcServer server,
2787 SilcSocketConnection sock,
2788 SilcPacketContext *packet)
2790 SilcProtocol protocol;
2791 SilcServerRekeyInternalContext *proto_ctx;
2792 SilcIDListData idata = (SilcIDListData)sock->user_data;
2794 SILC_LOG_DEBUG(("Start"));
2796 /* Allocate internal protocol context. This is sent as context
2798 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
2799 proto_ctx->server = (void *)server;
2800 proto_ctx->sock = sock;
2801 proto_ctx->responder = TRUE;
2802 proto_ctx->pfs = idata->rekey->pfs;
2804 /* Perform rekey protocol. Will call the final callback after the
2805 protocol is over. */
2806 silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
2807 &protocol, proto_ctx, silc_server_rekey_final);
2808 sock->protocol = protocol;
2810 if (proto_ctx->pfs == FALSE)
2811 /* Run the protocol */
2812 silc_protocol_execute(protocol, server->schedule, 0, 0);
2815 /* Received file transger packet. This packet is never for us. It is to
2816 the client in the packet's destination ID. Sending of this sort of packet
2817 equals sending private message, ie. it is sent point to point from
2818 one client to another. */
2820 void silc_server_ftp(SilcServer server,
2821 SilcSocketConnection sock,
2822 SilcPacketContext *packet)
2824 SilcSocketConnection dst_sock;
2825 SilcIDListData idata;
2827 SILC_LOG_DEBUG(("Start"));
2829 if (packet->src_id_type != SILC_ID_CLIENT ||
2830 packet->dst_id_type != SILC_ID_CLIENT)
2833 if (!packet->dst_id)
2836 /* Get the route to the client */
2837 dst_sock = silc_server_get_client_route(server, packet->dst_id,
2838 packet->dst_id_len, NULL,
2843 /* Relay the packet */
2844 silc_server_relay_packet(server, dst_sock, idata->send_key,
2845 idata->hmac_send, idata->psn_send++,
2851 SilcSocketConnection sock;
2852 SilcPacketContext *packet;
2854 } *SilcServerResumeResolve;
2856 SILC_SERVER_CMD_FUNC(resume_resolve)
2858 SilcServerResumeResolve r = (SilcServerResumeResolve)context;
2859 SilcServer server = r->server;
2860 SilcSocketConnection sock = r->sock;
2861 SilcServerCommandReplyContext reply = context2;
2862 SilcClientEntry client;
2864 SILC_LOG_DEBUG(("Start"));
2866 if (!reply || !silc_command_get_status(reply->payload, NULL, NULL)) {
2867 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
2868 "closing connection", sock->hostname, sock->ip));
2869 silc_server_disconnect_remote(server, sock,
2870 "Server closed connection: "
2871 "Incomplete resume information");
2875 if (reply && silc_command_get(reply->payload) == SILC_COMMAND_WHOIS) {
2876 /* Get entry to the client, and resolve it if we don't have it. */
2877 client = silc_idlist_find_client_by_id(server->local_list,
2878 r->data, TRUE, NULL);
2880 client = silc_idlist_find_client_by_id(server->global_list,
2881 r->data, TRUE, NULL);
2883 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
2884 "closing connection", sock->hostname, sock->ip));
2885 silc_server_disconnect_remote(server, sock,
2886 "Server closed connection: "
2887 "Incomplete resume information");
2892 if (!(client->mode & SILC_UMODE_DETACHED)) {
2893 SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, "
2894 "closing connection", sock->hostname, sock->ip));
2895 silc_server_disconnect_remote(server, sock,
2896 "Server closed connection: "
2897 "Incomplete resume information");
2902 /* Reprocess the packet */
2903 silc_server_resume_client(server, sock, r->packet);
2906 silc_socket_free(r->sock);
2907 silc_packet_context_free(r->packet);
2912 /* Received client resuming packet. This is used to resume detached
2913 client session. It can be sent by the client who wishes to resume
2914 but this is also sent by servers and routers to notify other routers
2915 that the client is not detached anymore. */
2917 void silc_server_resume_client(SilcServer server,
2918 SilcSocketConnection sock,
2919 SilcPacketContext *packet)
2921 SilcBuffer buffer = packet->buffer, buf;
2922 SilcIDListData idata;
2923 SilcClientEntry detached_client;
2924 SilcClientID *client_id = NULL;
2925 unsigned char *id_string, *auth = NULL;
2926 SilcUInt16 id_len, auth_len = 0;
2927 int ret, nickfail = 0;
2928 bool resolved, local, nick_change = FALSE;
2929 SilcChannelEntry channel;
2930 SilcHashTableList htl;
2931 SilcChannelClientEntry chl;
2932 SilcServerResumeResolve r;
2934 SILC_LOG_DEBUG(("Start"));
2936 ret = silc_buffer_unformat(buffer,
2937 SILC_STR_UI16_NSTRING(&id_string, &id_len),
2940 client_id = silc_id_str2id(id_string, id_len, SILC_ID_CLIENT);
2942 if (sock->type == SILC_SOCKET_TYPE_CLIENT) {
2943 /* Client send this and is attempting to resume to old client session */
2944 SilcClientEntry client;
2948 silc_buffer_pull(buffer, 2 + id_len);
2949 auth = buffer->data;
2950 auth_len = buffer->len;
2951 silc_buffer_push(buffer, 2 + id_len);
2954 if (!client_id || auth_len < 128) {
2955 SILC_LOG_ERROR(("Client %s (%s) sent incomplete resume information, "
2956 "closing connection", sock->hostname, sock->ip));
2957 silc_server_disconnect_remote(server, sock, "Server closed connection: "
2958 "Incomplete resume information");
2962 /* Take client entry of this connection */
2963 client = (SilcClientEntry)sock->user_data;
2964 idata = (SilcIDListData)client;
2966 /* Get entry to the client, and resolve it if we don't have it. */
2967 detached_client = silc_server_get_client_resolve(server, client_id, FALSE,
2969 if (!detached_client) {
2971 /* The client info is being resolved. Reprocess this packet after
2972 receiving the reply to the query. */
2973 SILC_LOG_DEBUG(("Resolving client"));
2974 r = silc_calloc(1, sizeof(*r));
2978 r->sock = silc_socket_dup(sock);
2979 r->packet = silc_packet_context_dup(packet);
2980 r->data = silc_id_dup(client_id, SILC_ID_CLIENT);
2981 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
2983 silc_server_command_resume_resolve, r);
2985 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
2986 "closing connection", sock->hostname, sock->ip));
2987 silc_server_disconnect_remote(server, sock,
2988 "Server closed connection: "
2989 "Incomplete resume information");
2994 /* Check that the client is detached, and that we have other info too */
2995 if (!(detached_client->mode & SILC_UMODE_DETACHED) ||
2996 !silc_hash_table_count(detached_client->channels) ||
2997 !detached_client->nickname) {
2998 if (server->server_type == SILC_SERVER && !server->standalone) {
2999 /* The client info is being resolved. Reprocess this packet after
3000 receiving the reply to the query. */
3001 SILC_LOG_DEBUG(("Resolving client info"));
3002 silc_server_get_client_resolve(server, client_id, TRUE, NULL);
3003 r = silc_calloc(1, sizeof(*r));
3007 r->sock = silc_socket_dup(sock);
3008 r->packet = silc_packet_context_dup(packet);
3009 r->data = silc_id_dup(client_id, SILC_ID_CLIENT);
3010 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
3012 silc_server_command_resume_resolve, r);
3015 if (server->server_type == SILC_SERVER) {
3016 SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, "
3017 "closing connection", sock->hostname, sock->ip));
3018 silc_server_disconnect_remote(server, sock,
3019 "Server closed connection: "
3020 "Incomplete resume information");
3025 /* Check that we have the public key of the client, if not then we must
3026 resolve it first. */
3027 if (!detached_client->data.public_key) {
3028 if (server->standalone) {
3029 silc_server_disconnect_remote(server, sock,
3030 "Server closed connection: "
3031 "Incomplete resume information");
3033 /* We must retrieve the detached client's public key by sending
3034 GETKEY command. Reprocess this packet after receiving the key */
3035 SilcBuffer idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
3036 SilcSocketConnection dest_sock =
3037 silc_server_get_client_route(server, NULL, 0, client_id, NULL, NULL);
3039 SILC_LOG_DEBUG(("Resolving client public key"));
3041 silc_server_send_command(server, dest_sock ? dest_sock :
3042 server->router->connection,
3043 SILC_COMMAND_GETKEY, ++server->cmd_ident,
3044 1, 1, idp->data, idp->len);
3046 r = silc_calloc(1, sizeof(*r));
3051 r->sock = silc_socket_dup(sock);
3052 r->packet = silc_packet_context_dup(packet);
3053 silc_server_command_pending(server, SILC_COMMAND_GETKEY,
3055 silc_server_command_resume_resolve, r);
3057 silc_buffer_free(idp);
3060 } else if (!silc_pkcs_public_key_compare(detached_client->data.public_key,
3061 idata->public_key)) {
3062 /* We require that the connection and resuming authentication data
3063 must be using same key pair. */
3064 silc_server_disconnect_remote(server, sock,
3065 "Server closed connection: "
3066 "Incomplete resume information");
3070 /* Verify the authentication payload. This has to be successful in
3071 order to allow the resuming */
3072 if (!silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
3073 detached_client->data.public_key, 0,
3074 idata->hash, detached_client->id,
3076 SILC_LOG_ERROR(("Client %s (%s) resume authentication failed, "
3077 "closing connection", sock->hostname, sock->ip));
3078 silc_server_disconnect_remote(server, sock, "Server closed connection: "
3079 "Incomplete resume information");
3083 /* Now resume the client to the network */
3085 silc_schedule_task_del_by_context(server->schedule, detached_client);
3086 sock->user_data = detached_client;
3087 detached_client->connection = sock;
3089 /* Take new keys and stuff into use in the old entry */
3090 silc_idlist_del_data(detached_client);
3091 silc_idlist_add_data(detached_client, idata);
3092 detached_client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
3093 detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
3094 detached_client->mode &= ~SILC_UMODE_DETACHED;
3096 /* Send the RESUME_CLIENT packet to our primary router so that others
3097 know this client isn't detached anymore. */
3098 buf = silc_buffer_alloc_size(2 + id_len);
3099 silc_buffer_format(buf,
3100 SILC_STR_UI_SHORT(id_len),
3101 SILC_STR_UI_XNSTRING(id_string, id_len),
3104 /* Send to primary router */
3105 if (!server->standalone)
3106 silc_server_packet_send(server, server->router->connection,
3107 SILC_PACKET_RESUME_CLIENT, 0,
3108 buf->data, buf->len, TRUE);
3110 /* As router we must deliver this packet directly to the original
3111 server whom this client was earlier. */
3112 if (server->server_type == SILC_ROUTER && detached_client->router &&
3113 detached_client->router->server_type != SILC_ROUTER)
3114 silc_server_packet_send(server, detached_client->router->connection,
3115 SILC_PACKET_RESUME_CLIENT, 0,
3116 buf->data, buf->len, TRUE);
3117 silc_buffer_free(buf);
3119 detached_client->router = NULL;
3121 /* Delete this client entry since we're resuming to old one. */
3122 server->stat.my_clients--;
3123 server->stat.clients--;
3124 if (server->stat.cell_clients)
3125 server->stat.cell_clients--;
3126 silc_idlist_del_client(server->local_list, client);
3127 client = detached_client;
3129 /* If the ID is not based in our ID then change it */
3130 if (!SILC_ID_COMPARE(client->id, server->id, server->id->ip.data_len)) {
3131 while (!silc_id_create_client_id(server, server->id, server->rng,
3132 server->md5hash, client->nickname,
3136 silc_server_disconnect_remote(server, sock,
3137 "Server closed connection: "
3141 snprintf(&client->nickname[strlen(client->nickname) - 1], 1,
3148 /* Notify about Client ID change, nickname doesn't actually change. */
3149 if (!server->standalone)
3150 silc_server_send_notify_nick_change(server, server->router->connection,
3151 FALSE, client->id, client_id,
3155 /* Resolve users on those channels that client has joined but we
3156 haven't resolved user list yet. */
3157 if (server->server_type == SILC_SERVER && !server->standalone) {
3158 silc_hash_table_list(client->channels, &htl);
3159 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
3160 channel = chl->channel;
3161 SILC_LOG_DEBUG(("Resolving users for %s channel",
3162 channel->channel_name));
3163 if (channel->disabled || !channel->users_resolved) {
3164 silc_server_send_command(server, server->router->connection,
3165 SILC_COMMAND_USERS, ++server->cmd_ident,
3166 1, 2, channel->channel_name,
3167 strlen(channel->channel_name));
3170 silc_hash_table_list_reset(&htl);
3173 /* Send the new client ID to the client. After this client may start
3174 receiving other packets, and may start sending packets too. */
3175 silc_server_send_new_id(server, sock, FALSE, client_id, SILC_ID_CLIENT,
3176 silc_id_get_len(client_id, SILC_ID_CLIENT));
3179 /* Send NICK change notify to channels as well. */
3180 SilcBuffer oidp, nidp;
3181 oidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3182 nidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
3183 silc_server_send_notify_on_channels(server, NULL, client,
3184 SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
3185 oidp->data, oidp->len,
3186 nidp->data, nidp->len,
3188 strlen(client->nickname));
3189 silc_buffer_free(oidp);
3190 silc_buffer_free(nidp);
3193 /* Add the client again to the ID cache to get it to correct list */
3194 if (!silc_idcache_del_by_context(server->local_list->clients, client))
3195 silc_idcache_del_by_context(server->global_list->clients, client);
3196 silc_free(client->id);
3197 client->id = client_id;
3199 silc_idcache_add(server->local_list->clients, client->nickname,
3200 client->id, client, 0, NULL);
3202 /* Send some nice info to the client */
3203 silc_server_send_connect_notifys(server, sock, client);
3205 /* Send all channel keys of channels the client has joined */
3206 silc_hash_table_list(client->channels, &htl);
3207 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
3208 bool created = FALSE;
3209 channel = chl->channel;
3211 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY)
3214 /* If we don't have channel key, then create one */
3215 if (!channel->channel_key) {
3216 if (!silc_server_create_channel_key(server, channel, 0))
3221 id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3223 silc_channel_key_payload_encode(silc_id_get_len(channel->id,
3226 strlen(channel->channel_key->
3228 channel->channel_key->cipher->name,
3229 channel->key_len / 8, channel->key);
3230 silc_free(id_string);
3232 /* Send the key packet to client */
3233 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
3234 keyp->data, keyp->len, FALSE);
3236 if (created && server->server_type == SILC_SERVER &&
3237 !server->standalone)
3238 silc_server_packet_send(server, server->router->connection,
3239 SILC_PACKET_CHANNEL_KEY, 0,
3240 keyp->data, keyp->len, FALSE);
3242 silc_buffer_free(keyp);
3244 silc_hash_table_list_reset(&htl);
3246 } else if (sock->type != SILC_SOCKET_TYPE_CLIENT) {
3247 /* Server or router sent this to us to notify that that a client has
3249 SilcServerEntry server_entry;
3250 SilcServerID *server_id;
3255 /* Get entry to the client, and resolve it if we don't have it. */
3256 detached_client = silc_idlist_find_client_by_id(server->local_list,
3257 client_id, TRUE, NULL);
3258 if (!detached_client) {
3259 detached_client = silc_idlist_find_client_by_id(server->global_list,
3260 client_id, TRUE, NULL);
3261 if (!detached_client)
3265 /* Check that the client has not been resumed already because it is
3266 protocol error to attempt to resume more than once. The client
3267 will be killed if this protocol error occurs. */
3268 if (detached_client->data.status & SILC_IDLIST_STATUS_RESUMED &&
3269 !(detached_client->mode & SILC_UMODE_DETACHED)) {
3270 /* The client is clearly attempting to resume more than once and
3271 perhaps playing around by resuming from several different places
3272 at the same time. */
3273 silc_server_kill_client(server, detached_client, NULL,
3274 server->id, SILC_ID_SERVER);
3278 /* Check whether client is detached at all */
3279 if (!(detached_client->mode & SILC_UMODE_DETACHED))
3282 /* Client is detached, and now it is resumed. Remove the detached
3283 mode and mark that it is resumed. */
3284 detached_client->mode &= ~SILC_UMODE_DETACHED;
3285 detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
3287 /* Get the new owner of the resumed client */
3288 server_id = silc_id_str2id(packet->src_id, packet->src_id_len,
3289 packet->src_id_type);
3293 /* Get server entry */
3294 server_entry = silc_idlist_find_server_by_id(server->global_list,
3295 server_id, TRUE, NULL);
3297 if (!server_entry) {
3298 server_entry = silc_idlist_find_server_by_id(server->local_list,
3299 server_id, TRUE, NULL);
3301 if (!server_entry) {
3302 silc_free(server_id);
3307 if (server->server_type == SILC_ROUTER &&
3308 sock->type == SILC_SOCKET_TYPE_ROUTER &&
3309 server_entry->server_type == SILC_ROUTER)
3312 SILC_LOG_DEBUG(("Resuming detached client"));
3314 /* Change the client to correct list. */
3315 if (!silc_idcache_del_by_context(server->local_list->clients,
3317 silc_idcache_del_by_context(server->global_list->clients,
3319 silc_idcache_add(local && server->server_type == SILC_ROUTER ?
3320 server->local_list->clients :
3321 server->global_list->clients,
3322 detached_client->nickname,
3323 detached_client->id, detached_client, FALSE, NULL);
3325 /* Change the owner of the client if needed */
3326 if (detached_client->router != server_entry)
3327 detached_client->router = server_entry;
3329 /* Update channel information regarding global clients on channel. */
3330 if (server->server_type == SILC_SERVER) {
3331 silc_hash_table_list(detached_client->channels, &htl);
3332 while (silc_hash_table_get(&htl, NULL, (void **)&chl))
3333 chl->channel->global_users =
3334 silc_server_channel_has_global(chl->channel);
3335 silc_hash_table_list_reset(&htl);
3338 silc_schedule_task_del_by_context(server->schedule, detached_client);
3340 /* If the sender of this packet is server and we are router we need to
3341 broadcast this packet to other routers in the network. */
3342 if (!server->standalone && server->server_type == SILC_ROUTER &&
3343 sock->type == SILC_SOCKET_TYPE_SERVER &&
3344 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
3345 SILC_LOG_DEBUG(("Broadcasting received Resume Client packet"));
3346 silc_server_packet_send(server, server->router->connection,
3348 packet->flags | SILC_PACKET_FLAG_BROADCAST,
3349 buffer->data, buffer->len, FALSE);
3350 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
3351 packet->type, packet->flags,
3352 packet->buffer->data, packet->buffer->len,
3356 silc_free(server_id);
3359 silc_free(client_id);