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);
1686 unsigned char error;
1688 /* Send SILC_NOTIFY_TYPE_ERROR to indicate that such destination ID
1689 does not exist or is invalid. */
1690 idp = silc_id_payload_encode_data(packet->dst_id,
1692 packet->dst_id_type);
1696 error = SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID;
1697 if (packet->src_id_type == SILC_ID_CLIENT) {
1698 SilcClientID *client_id = silc_id_str2id(packet->src_id,
1700 packet->src_id_type);
1701 silc_server_send_notify_dest(server, sock, FALSE,
1702 client_id, SILC_ID_CLIENT,
1703 SILC_NOTIFY_TYPE_ERROR, 2,
1704 &error, 1, idp->data, idp->len);
1705 silc_free(client_id);
1707 silc_server_send_notify(server, sock, FALSE,
1708 SILC_NOTIFY_TYPE_ERROR, 2,
1709 &error, 1, idp->data, idp->len);
1712 silc_buffer_free(idp);
1717 /* See that this client is on the channel. If the original sender is
1718 not client (as it can be server as well) we don't do the check. */
1719 sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1720 packet->src_id_type);
1723 if (packet->src_id_type == SILC_ID_CLIENT) {
1724 sender_entry = silc_idlist_find_client_by_id(server->local_list,
1725 sender_id, TRUE, NULL);
1726 if (!sender_entry) {
1728 sender_entry = silc_idlist_find_client_by_id(server->global_list,
1729 sender_id, TRUE, NULL);
1731 if (!sender_entry || !silc_server_client_on_channel(sender_entry,
1733 SILC_LOG_DEBUG(("Client not on channel"));
1737 /* If channel is moderated check that client is allowed to send
1739 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS && !chl->mode) {
1740 SILC_LOG_DEBUG(("Channel is silenced from normal users"));
1743 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS &&
1744 chl->mode & SILC_CHANNEL_UMODE_CHANOP &&
1745 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1746 SILC_LOG_DEBUG(("Channel is silenced from operators"));
1750 /* If the packet is coming from router, but the client entry is local
1751 entry to us then some router is rerouting this to us and it is not
1752 allowed. When the client is local to us it means that we've routed
1753 this packet to network, and now someone is routing it back to us. */
1754 if (server->server_type == SILC_ROUTER &&
1755 sock->type == SILC_SOCKET_TYPE_ROUTER && local) {
1756 SILC_LOG_DEBUG(("Channel message rerouted to the sender, drop it"));
1761 /* Distribute the packet to our local clients. This will send the
1762 packet for further routing as well, if needed. */
1763 silc_server_packet_relay_to_channel(server, sock, channel, sender_id,
1764 packet->src_id_type, sender_entry,
1765 packet->buffer->data,
1766 packet->buffer->len, FALSE);
1769 silc_free(sender_id);
1773 /* Received channel key packet. We distribute the key to all of our locally
1774 connected clients on the channel. */
1776 void silc_server_channel_key(SilcServer server,
1777 SilcSocketConnection sock,
1778 SilcPacketContext *packet)
1780 SilcBuffer buffer = packet->buffer;
1781 SilcChannelEntry channel;
1783 if (packet->src_id_type != SILC_ID_SERVER ||
1784 (server->server_type == SILC_ROUTER &&
1785 sock->type == SILC_SOCKET_TYPE_ROUTER))
1788 /* Save the channel key */
1789 channel = silc_server_save_channel_key(server, buffer, NULL);
1793 /* Distribute the key to everybody who is on the channel. If we are router
1794 we will also send it to locally connected servers. */
1795 silc_server_send_channel_key(server, sock, channel, FALSE);
1797 if (server->server_type != SILC_BACKUP_ROUTER) {
1798 /* Distribute to local cell backup routers. */
1799 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
1800 SILC_PACKET_CHANNEL_KEY, 0,
1801 buffer->data, buffer->len, FALSE, TRUE);
1805 /* Received New Client packet and processes it. Creates Client ID for the
1806 client. Client becomes registered after calling this functions. */
1808 SilcClientEntry silc_server_new_client(SilcServer server,
1809 SilcSocketConnection sock,
1810 SilcPacketContext *packet)
1812 SilcBuffer buffer = packet->buffer;
1813 SilcClientEntry client;
1814 SilcClientID *client_id;
1815 SilcIDListData idata;
1816 char *username = NULL, *realname = NULL;
1817 SilcUInt16 username_len;
1820 char *hostname, *nickname;
1823 SILC_LOG_DEBUG(("Creating new client"));
1825 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
1828 /* Take client entry */
1829 client = (SilcClientEntry)sock->user_data;
1830 idata = (SilcIDListData)client;
1832 /* Remove the old cache entry. */
1833 if (!silc_idcache_del_by_context(server->local_list->clients, client)) {
1834 SILC_LOG_INFO(("Unauthenticated client attempted to register to network"));
1835 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1836 "You have not been authenticated");
1840 /* Parse incoming packet */
1841 ret = silc_buffer_unformat(buffer,
1842 SILC_STR_UI16_NSTRING_ALLOC(&username,
1844 SILC_STR_UI16_STRING_ALLOC(&realname),
1847 silc_free(username);
1848 silc_free(realname);
1849 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
1850 "connection", sock->hostname, sock->ip));
1851 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1852 "Incomplete client information");
1857 silc_free(username);
1858 silc_free(realname);
1859 SILC_LOG_ERROR(("Client %s (%s) did not send its username, closing "
1860 "connection", sock->hostname, sock->ip));
1861 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1862 "Incomplete client information");
1866 if (username_len > 128)
1867 username[128] = '\0';
1869 /* Check for bad characters for nickname, and modify the nickname if
1870 it includes those. */
1871 if (silc_server_name_bad_chars(username, username_len)) {
1872 nickname = silc_server_name_modify_bad(username, username_len);
1874 nickname = strdup(username);
1877 /* Make sanity checks for the hostname of the client. If the hostname
1878 is provided in the `username' check that it is the same than the
1879 resolved hostname, or if not resolved the hostname that appears in
1880 the client's public key. If the hostname is not present then put
1881 it from the resolved name or from the public key. */
1882 if (strchr(username, '@')) {
1883 SilcPublicKeyIdentifier pident;
1884 int tlen = strcspn(username, "@");
1885 char *phostname = NULL;
1887 hostname = silc_memdup(username + tlen + 1, strlen(username) - tlen - 1);
1889 if (strcmp(sock->hostname, sock->ip) &&
1890 strcmp(sock->hostname, hostname)) {
1891 silc_free(username);
1892 silc_free(hostname);
1893 silc_free(realname);
1894 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
1895 "connection", sock->hostname, sock->ip));
1896 silc_server_disconnect_remote(server, sock,
1897 "Server closed connection: "
1898 "Incomplete client information");
1902 pident = silc_pkcs_decode_identifier(client->data.public_key->identifier);
1904 phostname = strdup(pident->host);
1905 silc_pkcs_free_identifier(pident);
1908 if (!strcmp(sock->hostname, sock->ip) &&
1909 phostname && strcmp(phostname, hostname)) {
1910 silc_free(username);
1911 silc_free(hostname);
1912 silc_free(phostname);
1913 silc_free(realname);
1914 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
1915 "connection", sock->hostname, sock->ip));
1916 silc_server_disconnect_remote(server, sock,
1917 "Server closed connection: "
1918 "Incomplete client information");
1922 silc_free(phostname);
1924 /* The hostname is not present, add it. */
1926 /* XXX For now we cannot take the host name from the public key since
1927 they are not trusted or we cannot verify them as trusted. Just take
1928 what the resolved name or address is. */
1930 if (strcmp(sock->hostname, sock->ip)) {
1932 newusername = silc_calloc(strlen(username) +
1933 strlen(sock->hostname) + 2,
1934 sizeof(*newusername));
1935 strncat(newusername, username, strlen(username));
1936 strncat(newusername, "@", 1);
1937 strncat(newusername, sock->hostname, strlen(sock->hostname));
1938 silc_free(username);
1939 username = newusername;
1942 SilcPublicKeyIdentifier pident =
1943 silc_pkcs_decode_identifier(client->data.public_key->identifier);
1946 newusername = silc_calloc(strlen(username) +
1947 strlen(pident->host) + 2,
1948 sizeof(*newusername));
1949 strncat(newusername, username, strlen(username));
1950 strncat(newusername, "@", 1);
1951 strncat(newusername, pident->host, strlen(pident->host));
1952 silc_free(username);
1953 username = newusername;
1954 silc_pkcs_free_identifier(pident);
1960 /* Create Client ID */
1961 while (!silc_id_create_client_id(server, server->id, server->rng,
1962 server->md5hash, nickname, &client_id)) {
1965 silc_server_disconnect_remote(server, sock,
1966 "Server closed connection: Bad nickname");
1969 snprintf(&nickname[strlen(nickname) - 1], 1, "%d", nickfail);
1972 /* Update client entry */
1973 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
1974 client->nickname = nickname;
1975 client->username = username;
1976 client->userinfo = realname ? realname : strdup(" ");
1977 client->id = client_id;
1978 id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
1980 /* Add the client again to the ID cache */
1981 silc_idcache_add(server->local_list->clients, client->nickname,
1982 client_id, client, 0, NULL);
1984 /* Notify our router about new client on the SILC network */
1985 if (!server->standalone)
1986 silc_server_send_new_id(server, (SilcSocketConnection)
1987 server->router->connection,
1988 server->server_type == SILC_ROUTER ? TRUE : FALSE,
1989 client->id, SILC_ID_CLIENT, id_len);
1991 /* Send the new client ID to the client. */
1992 silc_server_send_new_id(server, sock, FALSE, client->id, SILC_ID_CLIENT,
1993 silc_id_get_len(client->id, SILC_ID_CLIENT));
1995 /* Send some nice info to the client */
1996 silc_server_send_connect_notifys(server, sock, client);
2001 /* Create new server. This processes received New Server packet and
2002 saves the received Server ID. The server is our locally connected
2003 server thus we save all the information and save it to local list.
2004 This funtion can be used by both normal server and router server.
2005 If normal server uses this it means that its router has connected
2006 to the server. If router uses this it means that one of the cell's
2007 servers is connected to the router. */
2009 SilcServerEntry silc_server_new_server(SilcServer server,
2010 SilcSocketConnection sock,
2011 SilcPacketContext *packet)
2013 SilcBuffer buffer = packet->buffer;
2014 SilcServerEntry new_server, server_entry;
2015 SilcServerID *server_id;
2016 SilcIDListData idata;
2017 unsigned char *server_name, *id_string;
2018 SilcUInt16 id_len, name_len;
2022 SILC_LOG_DEBUG(("Creating new server"));
2024 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
2025 sock->type != SILC_SOCKET_TYPE_ROUTER)
2028 /* Take server entry */
2029 new_server = (SilcServerEntry)sock->user_data;
2030 idata = (SilcIDListData)new_server;
2032 /* Remove the old cache entry */
2033 if (!silc_idcache_del_by_context(server->local_list->servers, new_server)) {
2034 if (!silc_idcache_del_by_context(server->global_list->servers,
2036 SILC_LOG_INFO(("Unauthenticated %s attempted to register to "
2037 "network", (sock->type == SILC_SOCKET_TYPE_SERVER ?
2038 "server" : "router")));
2039 silc_server_disconnect_remote(server, sock, "Server closed connection: "
2040 "You have not been authenticated");
2046 /* Parse the incoming packet */
2047 ret = silc_buffer_unformat(buffer,
2048 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
2049 SILC_STR_UI16_NSTRING_ALLOC(&server_name,
2054 silc_free(id_string);
2056 silc_free(server_name);
2060 if (id_len > buffer->len) {
2061 silc_free(id_string);
2062 silc_free(server_name);
2067 server_name[255] = '\0';
2070 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
2072 silc_free(id_string);
2073 silc_free(server_name);
2076 silc_free(id_string);
2078 /* Check for valid server ID */
2079 if (!silc_id_is_valid_server_id(server, server_id, sock)) {
2080 SILC_LOG_INFO(("Invalid server ID sent by %s (%s)",
2081 sock->ip, sock->hostname));
2082 silc_server_disconnect_remote(server, sock, "Server closed connection: "
2083 "Your Server ID is not valid");
2084 silc_free(server_name);
2088 /* Check that we do not have this ID already */
2089 server_entry = silc_idlist_find_server_by_id(server->local_list,
2090 server_id, TRUE, NULL);
2092 silc_idcache_del_by_context(server->local_list->servers, server_entry);
2094 server_entry = silc_idlist_find_server_by_id(server->global_list,
2095 server_id, TRUE, NULL);
2097 silc_idcache_del_by_context(server->global_list->servers, server_entry);
2100 /* Update server entry */
2101 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
2102 new_server->server_name = server_name;
2103 new_server->id = server_id;
2105 SILC_LOG_DEBUG(("New server id(%s)",
2106 silc_id_render(server_id, SILC_ID_SERVER)));
2108 /* Add again the entry to the ID cache. */
2109 silc_idcache_add(local ? server->local_list->servers :
2110 server->global_list->servers, server_name, server_id,
2111 new_server, 0, NULL);
2113 /* Distribute the information about new server in the SILC network
2114 to our router. If we are normal server we won't send anything
2115 since this connection must be our router connection. */
2116 if (server->server_type == SILC_ROUTER && !server->standalone &&
2117 server->router->connection != sock)
2118 silc_server_send_new_id(server, server->router->connection,
2119 TRUE, new_server->id, SILC_ID_SERVER,
2120 silc_id_get_len(server_id, SILC_ID_SERVER));
2122 if (server->server_type == SILC_ROUTER)
2123 server->stat.cell_servers++;
2125 /* Check whether this router connection has been replaced by an
2126 backup router. If it has been then we'll disable the server and will
2127 ignore everything it will send until the backup router resuming
2128 protocol has been completed. */
2129 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
2130 silc_server_backup_replaced_get(server, server_id, NULL)) {
2131 /* Send packet to the server indicating that it cannot use this
2132 connection as it has been replaced by backup router. */
2133 SilcBuffer packet = silc_buffer_alloc(2);
2134 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
2135 silc_buffer_format(packet,
2136 SILC_STR_UI_CHAR(SILC_SERVER_BACKUP_REPLACED),
2137 SILC_STR_UI_CHAR(0),
2139 silc_server_packet_send(server, sock,
2140 SILC_PACKET_RESUME_ROUTER, 0,
2141 packet->data, packet->len, TRUE);
2142 silc_buffer_free(packet);
2144 /* Mark the router disabled. The data sent earlier will go but nothing
2145 after this does not go to this connection. */
2146 idata->status |= SILC_IDLIST_STATUS_DISABLED;
2148 /* If it is router announce our stuff to it. */
2149 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
2150 server->server_type == SILC_ROUTER) {
2151 silc_server_announce_servers(server, FALSE, 0, sock);
2152 silc_server_announce_clients(server, 0, sock);
2153 silc_server_announce_channels(server, 0, sock);
2160 /* Processes incoming New ID packet. New ID Payload is used to distribute
2161 information about newly registered clients and servers. */
2163 static void silc_server_new_id_real(SilcServer server,
2164 SilcSocketConnection sock,
2165 SilcPacketContext *packet,
2168 SilcBuffer buffer = packet->buffer;
2170 SilcServerEntry router, server_entry;
2171 SilcSocketConnection router_sock;
2176 SILC_LOG_DEBUG(("Processing new ID"));
2178 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2179 server->server_type == SILC_SERVER ||
2180 packet->src_id_type != SILC_ID_SERVER)
2183 idp = silc_id_payload_parse(buffer->data, buffer->len);
2187 id_type = silc_id_payload_get_type(idp);
2189 /* Normal server cannot have other normal server connections */
2190 server_entry = (SilcServerEntry)sock->user_data;
2191 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER &&
2192 server_entry->server_type == SILC_SERVER)
2195 id = silc_id_payload_get_id(idp);
2199 /* If the packet is coming from server then use the sender as the
2200 origin of the the packet. If it came from router then check the real
2201 sender of the packet and use that as the origin. */
2202 if (sock->type == SILC_SOCKET_TYPE_SERVER) {
2203 id_list = server->local_list;
2205 router = sock->user_data;
2207 /* If the sender is backup router and ID is server (and we are not
2208 backup router) then switch the entry to global list. */
2209 if (server_entry->server_type == SILC_BACKUP_ROUTER &&
2210 id_type == SILC_ID_SERVER &&
2211 server->id_entry->server_type != SILC_BACKUP_ROUTER) {
2212 id_list = server->global_list;
2213 router_sock = server->router ? server->router->connection : sock;
2216 void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2217 packet->src_id_type);
2218 router = silc_idlist_find_server_by_id(server->global_list,
2219 sender_id, TRUE, NULL);
2221 router = silc_idlist_find_server_by_id(server->local_list,
2222 sender_id, TRUE, NULL);
2223 silc_free(sender_id);
2225 id_list = server->global_list;
2232 case SILC_ID_CLIENT:
2234 SilcClientEntry entry;
2236 /* Check that we do not have this client already */
2237 entry = silc_idlist_find_client_by_id(server->global_list,
2238 id, server->server_type,
2241 entry = silc_idlist_find_client_by_id(server->local_list,
2242 id, server->server_type,
2245 SILC_LOG_DEBUG(("Ignoring client that we already have"));
2249 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
2250 silc_id_render(id, SILC_ID_CLIENT),
2251 sock->type == SILC_SOCKET_TYPE_SERVER ?
2252 "Server" : "Router", sock->hostname));
2254 /* As a router we keep information of all global information in our
2255 global list. Cell wide information however is kept in the local
2257 entry = silc_idlist_add_client(id_list, NULL, NULL, NULL,
2258 id, router, NULL, 0);
2260 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
2262 /* Inform the sender that the ID is not usable */
2263 silc_server_send_notify_signoff(server, sock, FALSE, id, NULL);
2266 entry->nickname = NULL;
2267 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2269 if (sock->type == SILC_SOCKET_TYPE_SERVER)
2270 server->stat.cell_clients++;
2271 server->stat.clients++;
2275 case SILC_ID_SERVER:
2277 SilcServerEntry entry;
2279 /* If the ID is mine, ignore it. */
2280 if (SILC_ID_SERVER_COMPARE(id, server->id)) {
2281 SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
2285 /* If the ID is the sender's ID, ignore it (we have it already) */
2286 if (SILC_ID_SERVER_COMPARE(id, router->id)) {
2287 SILC_LOG_DEBUG(("Ignoring sender's own ID"));
2291 /* Check that we do not have this server already */
2292 entry = silc_idlist_find_server_by_id(server->global_list,
2293 id, server->server_type,
2296 entry = silc_idlist_find_server_by_id(server->local_list,
2297 id, server->server_type,
2300 SILC_LOG_DEBUG(("Ignoring server that we already have"));
2304 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
2305 silc_id_render(id, SILC_ID_SERVER),
2306 sock->type == SILC_SOCKET_TYPE_SERVER ?
2307 "Server" : "Router", sock->hostname));
2309 /* As a router we keep information of all global information in our
2310 global list. Cell wide information however is kept in the local
2312 entry = silc_idlist_add_server(id_list, NULL, 0, id, router,
2315 SILC_LOG_ERROR(("Could not add new server to the ID Cache"));
2318 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2320 if (sock->type == SILC_SOCKET_TYPE_SERVER)
2321 server->stat.cell_servers++;
2322 server->stat.servers++;
2326 case SILC_ID_CHANNEL:
2327 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
2336 /* If the sender of this packet is server and we are router we need to
2337 broadcast this packet to other routers in the network. */
2338 if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
2339 sock->type == SILC_SOCKET_TYPE_SERVER &&
2340 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2341 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
2342 silc_server_packet_send(server, server->router->connection,
2344 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2345 buffer->data, buffer->len, FALSE);
2346 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
2347 packet->type, packet->flags,
2348 packet->buffer->data, packet->buffer->len,
2353 silc_id_payload_free(idp);
2357 /* Processes incoming New ID packet. New ID Payload is used to distribute
2358 information about newly registered clients and servers. */
2360 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
2361 SilcPacketContext *packet)
2363 silc_server_new_id_real(server, sock, packet, TRUE);
2366 /* Receoved New Id List packet, list of New ID payloads inside one
2367 packet. Process the New ID payloads one by one. */
2369 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
2370 SilcPacketContext *packet)
2372 SilcPacketContext *new_id;
2376 SILC_LOG_DEBUG(("Processing New ID List"));
2378 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2379 packet->src_id_type != SILC_ID_SERVER)
2382 /* If the sender of this packet is server and we are router we need to
2383 broadcast this packet to other routers in the network. Broadcast
2384 this list packet instead of multiple New ID packets. */
2385 if (!server->standalone && server->server_type == SILC_ROUTER &&
2386 sock->type == SILC_SOCKET_TYPE_SERVER &&
2387 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2388 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
2389 silc_server_packet_send(server, server->router->connection,
2391 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2392 packet->buffer->data, packet->buffer->len, FALSE);
2393 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
2394 packet->type, packet->flags,
2395 packet->buffer->data, packet->buffer->len,
2399 /* Make copy of the original packet context, except for the actual
2400 data buffer, which we will here now fetch from the original buffer. */
2401 new_id = silc_packet_context_alloc();
2402 new_id->type = SILC_PACKET_NEW_ID;
2403 new_id->flags = packet->flags;
2404 new_id->src_id = packet->src_id;
2405 new_id->src_id_len = packet->src_id_len;
2406 new_id->src_id_type = packet->src_id_type;
2407 new_id->dst_id = packet->dst_id;
2408 new_id->dst_id_len = packet->dst_id_len;
2409 new_id->dst_id_type = packet->dst_id_type;
2411 idp = silc_buffer_alloc(256);
2412 new_id->buffer = idp;
2414 while (packet->buffer->len) {
2415 SILC_GET16_MSB(id_len, packet->buffer->data + 2);
2416 if ((id_len > packet->buffer->len) ||
2417 (id_len > idp->truelen))
2420 silc_buffer_pull_tail(idp, 4 + id_len);
2421 silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
2423 /* Process the New ID */
2424 silc_server_new_id_real(server, sock, new_id, FALSE);
2426 silc_buffer_push_tail(idp, 4 + id_len);
2427 silc_buffer_pull(packet->buffer, 4 + id_len);
2430 silc_buffer_free(idp);
2434 /* Received New Channel packet. Information about new channels in the
2435 network are distributed using this packet. Save the information about
2436 the new channel. This usually comes from router but also normal server
2437 can send this to notify channels it has when it connects to us. */
2439 void silc_server_new_channel(SilcServer server,
2440 SilcSocketConnection sock,
2441 SilcPacketContext *packet)
2443 SilcChannelPayload payload;
2444 SilcChannelID *channel_id;
2446 SilcUInt32 name_len;
2450 SilcServerEntry server_entry;
2451 SilcChannelEntry channel;
2453 SILC_LOG_DEBUG(("Processing New Channel"));
2455 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2456 packet->src_id_type != SILC_ID_SERVER ||
2457 server->server_type == SILC_SERVER)
2460 /* Parse the channel payload */
2461 payload = silc_channel_payload_parse(packet->buffer->data,
2462 packet->buffer->len);
2466 /* Get the channel ID */
2467 channel_id = silc_channel_get_id_parse(payload);
2469 silc_channel_payload_free(payload);
2473 channel_name = silc_channel_get_name(payload, &name_len);
2475 channel_name[255] = '\0';
2477 id = silc_channel_get_id(payload, &id_len);
2479 server_entry = (SilcServerEntry)sock->user_data;
2481 if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
2482 /* Add the channel to global list as it is coming from router. It
2483 cannot be our own channel as it is coming from router. */
2485 /* Check that we don't already have this channel */
2486 channel = silc_idlist_find_channel_by_name(server->local_list,
2487 channel_name, NULL);
2489 channel = silc_idlist_find_channel_by_name(server->global_list,
2490 channel_name, NULL);
2492 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
2493 silc_id_render(channel_id, SILC_ID_CHANNEL),
2497 silc_idlist_add_channel(server->global_list, strdup(channel_name),
2498 0, channel_id, sock->user_data, NULL, NULL, 0);
2502 server->stat.channels++;
2503 if (server->server_type == SILC_ROUTER)
2504 channel->users_resolved = TRUE;
2507 /* The channel is coming from our server, thus it is in our cell
2508 we will add it to our local list. */
2511 SILC_LOG_DEBUG(("Channel id(%s) from [Server] %s",
2512 silc_id_render(channel_id, SILC_ID_CHANNEL),
2515 /* Check that we don't already have this channel */
2516 channel = silc_idlist_find_channel_by_name(server->local_list,
2517 channel_name, NULL);
2519 channel = silc_idlist_find_channel_by_name(server->global_list,
2520 channel_name, NULL);
2522 /* If the channel does not exist, then create it. This creates a new
2523 key to the channel as well that we will send to the server. */
2525 /* The protocol says that the Channel ID's IP address must be based
2526 on the router's IP address. Check whether the ID is based in our
2527 IP and if it is not then create a new ID and enforce the server
2528 to switch the ID. */
2529 if (server_entry->server_type != SILC_BACKUP_ROUTER &&
2530 !SILC_ID_COMPARE(channel_id, server->id, server->id->ip.data_len)) {
2532 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2534 if (silc_id_create_channel_id(server, server->id, server->rng, &tmp)) {
2535 silc_server_send_notify_channel_change(server, sock, FALSE,
2537 silc_free(channel_id);
2542 /* Create the channel with the provided Channel ID */
2543 channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
2547 silc_channel_payload_free(payload);
2548 silc_free(channel_id);
2552 /* Get the mode and set it to the channel */
2553 channel->mode = silc_channel_get_mode(payload);
2555 /* Send the new channel key to the server */
2556 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2557 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
2558 chk = silc_channel_key_payload_encode(id_len, id,
2559 strlen(channel->channel_key->
2561 channel->channel_key->cipher->name,
2562 channel->key_len / 8,
2564 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
2565 chk->data, chk->len, FALSE);
2566 silc_buffer_free(chk);
2569 /* The channel exist by that name, check whether the ID's match.
2570 If they don't then we'll force the server to use the ID we have.
2571 We also create a new key for the channel. */
2572 SilcBuffer users = NULL, users_modes = NULL;
2574 if (!SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
2575 /* They don't match, send CHANNEL_CHANGE notify to the server to
2576 force the ID change. */
2577 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2578 silc_server_send_notify_channel_change(server, sock, FALSE,
2579 channel_id, channel->id);
2582 /* If the mode is different from what we have then enforce the
2584 mode = silc_channel_get_mode(payload);
2585 if (channel->mode != mode) {
2586 SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
2587 silc_server_send_notify_cmode(server, sock, FALSE, channel,
2588 channel->mode, server->id,
2590 channel->cipher, channel->hmac_name,
2591 channel->passphrase);
2594 /* Create new key for the channel and send it to the server and
2595 everybody else possibly on the channel. */
2597 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
2598 if (!silc_server_create_channel_key(server, channel, 0))
2601 /* Send to the channel */
2602 silc_server_send_channel_key(server, sock, channel, FALSE);
2603 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2604 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
2606 /* Send to the server */
2607 chk = silc_channel_key_payload_encode(id_len, id,
2608 strlen(channel->channel_key->
2610 channel->channel_key->
2612 channel->key_len / 8,
2614 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
2615 chk->data, chk->len, FALSE);
2616 silc_buffer_free(chk);
2620 silc_free(channel_id);
2622 /* Since the channel is coming from server and we also know about it
2623 then send the JOIN notify to the server so that it see's our
2624 users on the channel "joining" the channel. */
2625 silc_server_announce_get_channel_users(server, channel, &users,
2628 silc_buffer_push(users, users->data - users->head);
2629 silc_server_packet_send(server, sock,
2630 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2631 users->data, users->len, FALSE);
2632 silc_buffer_free(users);
2635 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
2636 silc_server_packet_send_dest(server, sock,
2637 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2638 channel->id, SILC_ID_CHANNEL,
2640 users_modes->len, FALSE);
2641 silc_buffer_free(users_modes);
2646 silc_channel_payload_free(payload);
2649 /* Received New Channel List packet, list of New Channel List payloads inside
2650 one packet. Process the New Channel payloads one by one. */
2652 void silc_server_new_channel_list(SilcServer server,
2653 SilcSocketConnection sock,
2654 SilcPacketContext *packet)
2656 SilcPacketContext *new;
2658 SilcUInt16 len1, len2;
2660 SILC_LOG_DEBUG(("Processing New Channel List"));
2662 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2663 packet->src_id_type != SILC_ID_SERVER ||
2664 server->server_type == SILC_SERVER)
2667 /* If the sender of this packet is server and we are router we need to
2668 broadcast this packet to other routers in the network. Broadcast
2669 this list packet instead of multiple New Channel packets. */
2670 if (!server->standalone && server->server_type == SILC_ROUTER &&
2671 sock->type == SILC_SOCKET_TYPE_SERVER &&
2672 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2673 SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
2674 silc_server_packet_send(server, server->router->connection,
2676 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2677 packet->buffer->data, packet->buffer->len, FALSE);
2678 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
2679 packet->type, packet->flags,
2680 packet->buffer->data, packet->buffer->len,
2684 /* Make copy of the original packet context, except for the actual
2685 data buffer, which we will here now fetch from the original buffer. */
2686 new = silc_packet_context_alloc();
2687 new->type = SILC_PACKET_NEW_CHANNEL;
2688 new->flags = packet->flags;
2689 new->src_id = packet->src_id;
2690 new->src_id_len = packet->src_id_len;
2691 new->src_id_type = packet->src_id_type;
2692 new->dst_id = packet->dst_id;
2693 new->dst_id_len = packet->dst_id_len;
2694 new->dst_id_type = packet->dst_id_type;
2696 buffer = silc_buffer_alloc(512);
2697 new->buffer = buffer;
2699 while (packet->buffer->len) {
2700 SILC_GET16_MSB(len1, packet->buffer->data);
2701 if ((len1 > packet->buffer->len) ||
2702 (len1 > buffer->truelen))
2705 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
2706 if ((len2 > packet->buffer->len) ||
2707 (len2 > buffer->truelen))
2710 silc_buffer_pull_tail(buffer, 8 + len1 + len2);
2711 silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
2713 /* Process the New Channel */
2714 silc_server_new_channel(server, sock, new);
2716 silc_buffer_push_tail(buffer, 8 + len1 + len2);
2717 silc_buffer_pull(packet->buffer, 8 + len1 + len2);
2720 silc_buffer_free(buffer);
2724 /* Received key agreement packet. This packet is never for us. It is to
2725 the client in the packet's destination ID. Sending of this sort of packet
2726 equals sending private message, ie. it is sent point to point from
2727 one client to another. */
2729 void silc_server_key_agreement(SilcServer server,
2730 SilcSocketConnection sock,
2731 SilcPacketContext *packet)
2733 SilcSocketConnection dst_sock;
2734 SilcIDListData idata;
2736 SILC_LOG_DEBUG(("Start"));
2738 if (packet->src_id_type != SILC_ID_CLIENT ||
2739 packet->dst_id_type != SILC_ID_CLIENT)
2742 if (!packet->dst_id)
2745 /* Get the route to the client */
2746 dst_sock = silc_server_get_client_route(server, packet->dst_id,
2747 packet->dst_id_len, NULL,
2752 /* Relay the packet */
2753 silc_server_relay_packet(server, dst_sock, idata->send_key,
2754 idata->hmac_send, idata->psn_send++,
2758 /* Received connection auth request packet that is used during connection
2759 phase to resolve the mandatory authentication method. This packet can
2760 actually be received at anytime but usually it is used only during
2761 the connection authentication phase. Now, protocol says that this packet
2762 can come from client or server, however, we support only this coming
2763 from client and expect that server always knows what authentication
2766 void silc_server_connection_auth_request(SilcServer server,
2767 SilcSocketConnection sock,
2768 SilcPacketContext *packet)
2770 SilcServerConfigClient *client = NULL;
2771 SilcUInt16 conn_type;
2773 SilcAuthMethod auth_meth = SILC_AUTH_NONE;
2775 SILC_LOG_DEBUG(("Start"));
2777 if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT)
2780 /* Parse the payload */
2781 ret = silc_buffer_unformat(packet->buffer,
2782 SILC_STR_UI_SHORT(&conn_type),
2783 SILC_STR_UI_SHORT(NULL),
2788 if (conn_type != SILC_SOCKET_TYPE_CLIENT)
2791 /* Get the authentication method for the client */
2792 auth_meth = SILC_AUTH_NONE;
2793 client = silc_server_config_find_client(server, sock->ip);
2795 client = silc_server_config_find_client(server, sock->hostname);
2797 if (client->passphrase) {
2798 if (client->publickeys && !server->config->prefer_passphrase_auth)
2799 auth_meth = SILC_AUTH_PUBLIC_KEY;
2801 auth_meth = SILC_AUTH_PASSWORD;
2802 } else if (client->publickeys)
2803 auth_meth = SILC_AUTH_PUBLIC_KEY;
2806 /* Send it back to the client */
2807 silc_server_send_connection_auth_request(server, sock, conn_type, auth_meth);
2810 /* Received REKEY packet. The sender of the packet wants to regenerate
2811 its session keys. This starts the REKEY protocol. */
2813 void silc_server_rekey(SilcServer server,
2814 SilcSocketConnection sock,
2815 SilcPacketContext *packet)
2817 SilcProtocol protocol;
2818 SilcServerRekeyInternalContext *proto_ctx;
2819 SilcIDListData idata = (SilcIDListData)sock->user_data;
2821 SILC_LOG_DEBUG(("Start"));
2823 /* Allocate internal protocol context. This is sent as context
2825 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
2826 proto_ctx->server = (void *)server;
2827 proto_ctx->sock = sock;
2828 proto_ctx->responder = TRUE;
2829 proto_ctx->pfs = idata->rekey->pfs;
2831 /* Perform rekey protocol. Will call the final callback after the
2832 protocol is over. */
2833 silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
2834 &protocol, proto_ctx, silc_server_rekey_final);
2835 sock->protocol = protocol;
2837 if (proto_ctx->pfs == FALSE)
2838 /* Run the protocol */
2839 silc_protocol_execute(protocol, server->schedule, 0, 0);
2842 /* Received file transger packet. This packet is never for us. It is to
2843 the client in the packet's destination ID. Sending of this sort of packet
2844 equals sending private message, ie. it is sent point to point from
2845 one client to another. */
2847 void silc_server_ftp(SilcServer server,
2848 SilcSocketConnection sock,
2849 SilcPacketContext *packet)
2851 SilcSocketConnection dst_sock;
2852 SilcIDListData idata;
2854 SILC_LOG_DEBUG(("Start"));
2856 if (packet->src_id_type != SILC_ID_CLIENT ||
2857 packet->dst_id_type != SILC_ID_CLIENT)
2860 if (!packet->dst_id)
2863 /* Get the route to the client */
2864 dst_sock = silc_server_get_client_route(server, packet->dst_id,
2865 packet->dst_id_len, NULL,
2870 /* Relay the packet */
2871 silc_server_relay_packet(server, dst_sock, idata->send_key,
2872 idata->hmac_send, idata->psn_send++,
2878 SilcSocketConnection sock;
2879 SilcPacketContext *packet;
2881 } *SilcServerResumeResolve;
2883 SILC_SERVER_CMD_FUNC(resume_resolve)
2885 SilcServerResumeResolve r = (SilcServerResumeResolve)context;
2886 SilcServer server = r->server;
2887 SilcSocketConnection sock = r->sock;
2888 SilcServerCommandReplyContext reply = context2;
2889 SilcClientEntry client;
2891 SILC_LOG_DEBUG(("Start"));
2893 if (!reply || !silc_command_get_status(reply->payload, NULL, NULL)) {
2894 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
2895 "closing connection", sock->hostname, sock->ip));
2896 silc_server_disconnect_remote(server, sock,
2897 "Server closed connection: "
2898 "Incomplete resume information");
2902 if (reply && silc_command_get(reply->payload) == SILC_COMMAND_WHOIS) {
2903 /* Get entry to the client, and resolve it if we don't have it. */
2904 client = silc_idlist_find_client_by_id(server->local_list,
2905 r->data, TRUE, NULL);
2907 client = silc_idlist_find_client_by_id(server->global_list,
2908 r->data, TRUE, NULL);
2910 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
2911 "closing connection", sock->hostname, sock->ip));
2912 silc_server_disconnect_remote(server, sock,
2913 "Server closed connection: "
2914 "Incomplete resume information");
2919 if (!(client->mode & SILC_UMODE_DETACHED)) {
2920 SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, "
2921 "closing connection", sock->hostname, sock->ip));
2922 silc_server_disconnect_remote(server, sock,
2923 "Server closed connection: "
2924 "Incomplete resume information");
2929 /* Reprocess the packet */
2930 silc_server_resume_client(server, sock, r->packet);
2933 silc_socket_free(r->sock);
2934 silc_packet_context_free(r->packet);
2939 /* Received client resuming packet. This is used to resume detached
2940 client session. It can be sent by the client who wishes to resume
2941 but this is also sent by servers and routers to notify other routers
2942 that the client is not detached anymore. */
2944 void silc_server_resume_client(SilcServer server,
2945 SilcSocketConnection sock,
2946 SilcPacketContext *packet)
2948 SilcBuffer buffer = packet->buffer, buf;
2949 SilcIDListData idata;
2950 SilcClientEntry detached_client;
2951 SilcClientID *client_id = NULL;
2952 unsigned char *id_string, *auth = NULL;
2953 SilcUInt16 id_len, auth_len = 0;
2954 int ret, nickfail = 0;
2955 bool resolved, local, nick_change = FALSE;
2956 SilcChannelEntry channel;
2957 SilcHashTableList htl;
2958 SilcChannelClientEntry chl;
2959 SilcServerResumeResolve r;
2961 SILC_LOG_DEBUG(("Start"));
2963 ret = silc_buffer_unformat(buffer,
2964 SILC_STR_UI16_NSTRING(&id_string, &id_len),
2967 client_id = silc_id_str2id(id_string, id_len, SILC_ID_CLIENT);
2969 if (sock->type == SILC_SOCKET_TYPE_CLIENT) {
2970 /* Client send this and is attempting to resume to old client session */
2971 SilcClientEntry client;
2975 silc_buffer_pull(buffer, 2 + id_len);
2976 auth = buffer->data;
2977 auth_len = buffer->len;
2978 silc_buffer_push(buffer, 2 + id_len);
2981 if (!client_id || auth_len < 128) {
2982 SILC_LOG_ERROR(("Client %s (%s) sent incomplete resume information, "
2983 "closing connection", sock->hostname, sock->ip));
2984 silc_server_disconnect_remote(server, sock, "Server closed connection: "
2985 "Incomplete resume information");
2989 /* Take client entry of this connection */
2990 client = (SilcClientEntry)sock->user_data;
2991 idata = (SilcIDListData)client;
2993 /* Get entry to the client, and resolve it if we don't have it. */
2994 detached_client = silc_server_get_client_resolve(server, client_id, FALSE,
2996 if (!detached_client) {
2998 /* The client info is being resolved. Reprocess this packet after
2999 receiving the reply to the query. */
3000 SILC_LOG_DEBUG(("Resolving client"));
3001 r = silc_calloc(1, sizeof(*r));
3005 r->sock = silc_socket_dup(sock);
3006 r->packet = silc_packet_context_dup(packet);
3007 r->data = silc_id_dup(client_id, SILC_ID_CLIENT);
3008 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
3010 silc_server_command_resume_resolve, r);
3012 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3013 "closing connection", sock->hostname, sock->ip));
3014 silc_server_disconnect_remote(server, sock,
3015 "Server closed connection: "
3016 "Incomplete resume information");
3021 /* Check that the client is detached, and that we have other info too */
3022 if (!(detached_client->mode & SILC_UMODE_DETACHED) ||
3023 !silc_hash_table_count(detached_client->channels) ||
3024 !detached_client->nickname) {
3025 if (server->server_type == SILC_SERVER && !server->standalone) {
3026 /* The client info is being resolved. Reprocess this packet after
3027 receiving the reply to the query. */
3028 SILC_LOG_DEBUG(("Resolving client info"));
3029 silc_server_get_client_resolve(server, client_id, TRUE, NULL);
3030 r = silc_calloc(1, sizeof(*r));
3034 r->sock = silc_socket_dup(sock);
3035 r->packet = silc_packet_context_dup(packet);
3036 r->data = silc_id_dup(client_id, SILC_ID_CLIENT);
3037 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
3039 silc_server_command_resume_resolve, r);
3042 if (server->server_type == SILC_SERVER) {
3043 SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, "
3044 "closing connection", sock->hostname, sock->ip));
3045 silc_server_disconnect_remote(server, sock,
3046 "Server closed connection: "
3047 "Incomplete resume information");
3052 /* Check that we have the public key of the client, if not then we must
3053 resolve it first. */
3054 if (!detached_client->data.public_key) {
3055 if (server->standalone) {
3056 silc_server_disconnect_remote(server, sock,
3057 "Server closed connection: "
3058 "Incomplete resume information");
3060 /* We must retrieve the detached client's public key by sending
3061 GETKEY command. Reprocess this packet after receiving the key */
3062 SilcBuffer idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
3063 SilcSocketConnection dest_sock =
3064 silc_server_get_client_route(server, NULL, 0, client_id, NULL, NULL);
3066 SILC_LOG_DEBUG(("Resolving client public key"));
3068 silc_server_send_command(server, dest_sock ? dest_sock :
3069 server->router->connection,
3070 SILC_COMMAND_GETKEY, ++server->cmd_ident,
3071 1, 1, idp->data, idp->len);
3073 r = silc_calloc(1, sizeof(*r));
3078 r->sock = silc_socket_dup(sock);
3079 r->packet = silc_packet_context_dup(packet);
3080 silc_server_command_pending(server, SILC_COMMAND_GETKEY,
3082 silc_server_command_resume_resolve, r);
3084 silc_buffer_free(idp);
3087 } else if (!silc_pkcs_public_key_compare(detached_client->data.public_key,
3088 idata->public_key)) {
3089 /* We require that the connection and resuming authentication data
3090 must be using same key pair. */
3091 silc_server_disconnect_remote(server, sock,
3092 "Server closed connection: "
3093 "Incomplete resume information");
3097 /* Verify the authentication payload. This has to be successful in
3098 order to allow the resuming */
3099 if (!silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
3100 detached_client->data.public_key, 0,
3101 idata->hash, detached_client->id,
3103 SILC_LOG_ERROR(("Client %s (%s) resume authentication failed, "
3104 "closing connection", sock->hostname, sock->ip));
3105 silc_server_disconnect_remote(server, sock, "Server closed connection: "
3106 "Incomplete resume information");
3110 /* Now resume the client to the network */
3112 silc_schedule_task_del_by_context(server->schedule, detached_client);
3113 sock->user_data = detached_client;
3114 detached_client->connection = sock;
3116 /* Take new keys and stuff into use in the old entry */
3117 silc_idlist_del_data(detached_client);
3118 silc_idlist_add_data(detached_client, idata);
3119 detached_client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
3120 detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
3121 detached_client->mode &= ~SILC_UMODE_DETACHED;
3123 /* Send the RESUME_CLIENT packet to our primary router so that others
3124 know this client isn't detached anymore. */
3125 buf = silc_buffer_alloc_size(2 + id_len);
3126 silc_buffer_format(buf,
3127 SILC_STR_UI_SHORT(id_len),
3128 SILC_STR_UI_XNSTRING(id_string, id_len),
3131 /* Send to primary router */
3132 if (!server->standalone)
3133 silc_server_packet_send(server, server->router->connection,
3134 SILC_PACKET_RESUME_CLIENT, 0,
3135 buf->data, buf->len, TRUE);
3137 /* As router we must deliver this packet directly to the original
3138 server whom this client was earlier. */
3139 if (server->server_type == SILC_ROUTER && detached_client->router &&
3140 detached_client->router->server_type != SILC_ROUTER)
3141 silc_server_packet_send(server, detached_client->router->connection,
3142 SILC_PACKET_RESUME_CLIENT, 0,
3143 buf->data, buf->len, TRUE);
3144 silc_buffer_free(buf);
3146 detached_client->router = NULL;
3148 /* Delete this client entry since we're resuming to old one. */
3149 server->stat.my_clients--;
3150 server->stat.clients--;
3151 if (server->stat.cell_clients)
3152 server->stat.cell_clients--;
3153 silc_idlist_del_client(server->local_list, client);
3154 client = detached_client;
3156 /* If the ID is not based in our ID then change it */
3157 if (!SILC_ID_COMPARE(client->id, server->id, server->id->ip.data_len)) {
3158 while (!silc_id_create_client_id(server, server->id, server->rng,
3159 server->md5hash, client->nickname,
3163 silc_server_disconnect_remote(server, sock,
3164 "Server closed connection: "
3168 snprintf(&client->nickname[strlen(client->nickname) - 1], 1,
3175 /* Notify about Client ID change, nickname doesn't actually change. */
3176 if (!server->standalone)
3177 silc_server_send_notify_nick_change(server, server->router->connection,
3178 FALSE, client->id, client_id,
3182 /* Resolve users on those channels that client has joined but we
3183 haven't resolved user list yet. */
3184 if (server->server_type == SILC_SERVER && !server->standalone) {
3185 silc_hash_table_list(client->channels, &htl);
3186 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
3187 channel = chl->channel;
3188 SILC_LOG_DEBUG(("Resolving users for %s channel",
3189 channel->channel_name));
3190 if (channel->disabled || !channel->users_resolved) {
3191 silc_server_send_command(server, server->router->connection,
3192 SILC_COMMAND_USERS, ++server->cmd_ident,
3193 1, 2, channel->channel_name,
3194 strlen(channel->channel_name));
3197 silc_hash_table_list_reset(&htl);
3200 /* Send the new client ID to the client. After this client may start
3201 receiving other packets, and may start sending packets too. */
3202 silc_server_send_new_id(server, sock, FALSE, client_id, SILC_ID_CLIENT,
3203 silc_id_get_len(client_id, SILC_ID_CLIENT));
3206 /* Send NICK change notify to channels as well. */
3207 SilcBuffer oidp, nidp;
3208 oidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3209 nidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
3210 silc_server_send_notify_on_channels(server, NULL, client,
3211 SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
3212 oidp->data, oidp->len,
3213 nidp->data, nidp->len,
3215 strlen(client->nickname));
3216 silc_buffer_free(oidp);
3217 silc_buffer_free(nidp);
3220 /* Add the client again to the ID cache to get it to correct list */
3221 if (!silc_idcache_del_by_context(server->local_list->clients, client))
3222 silc_idcache_del_by_context(server->global_list->clients, client);
3223 silc_free(client->id);
3224 client->id = client_id;
3226 silc_idcache_add(server->local_list->clients, client->nickname,
3227 client->id, client, 0, NULL);
3229 /* Send some nice info to the client */
3230 silc_server_send_connect_notifys(server, sock, client);
3232 /* Send all channel keys of channels the client has joined */
3233 silc_hash_table_list(client->channels, &htl);
3234 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
3235 bool created = FALSE;
3236 channel = chl->channel;
3238 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY)
3241 /* If we don't have channel key, then create one */
3242 if (!channel->channel_key) {
3243 if (!silc_server_create_channel_key(server, channel, 0))
3248 id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3250 silc_channel_key_payload_encode(silc_id_get_len(channel->id,
3253 strlen(channel->channel_key->
3255 channel->channel_key->cipher->name,
3256 channel->key_len / 8, channel->key);
3257 silc_free(id_string);
3259 /* Send the key packet to client */
3260 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
3261 keyp->data, keyp->len, FALSE);
3263 if (created && server->server_type == SILC_SERVER &&
3264 !server->standalone)
3265 silc_server_packet_send(server, server->router->connection,
3266 SILC_PACKET_CHANNEL_KEY, 0,
3267 keyp->data, keyp->len, FALSE);
3269 silc_buffer_free(keyp);
3271 silc_hash_table_list_reset(&htl);
3273 } else if (sock->type != SILC_SOCKET_TYPE_CLIENT) {
3274 /* Server or router sent this to us to notify that that a client has
3276 SilcServerEntry server_entry;
3277 SilcServerID *server_id;
3282 /* Get entry to the client, and resolve it if we don't have it. */
3283 detached_client = silc_idlist_find_client_by_id(server->local_list,
3284 client_id, TRUE, NULL);
3285 if (!detached_client) {
3286 detached_client = silc_idlist_find_client_by_id(server->global_list,
3287 client_id, TRUE, NULL);
3288 if (!detached_client)
3292 /* Check that the client has not been resumed already because it is
3293 protocol error to attempt to resume more than once. The client
3294 will be killed if this protocol error occurs. */
3295 if (detached_client->data.status & SILC_IDLIST_STATUS_RESUMED &&
3296 !(detached_client->mode & SILC_UMODE_DETACHED)) {
3297 /* The client is clearly attempting to resume more than once and
3298 perhaps playing around by resuming from several different places
3299 at the same time. */
3300 silc_server_kill_client(server, detached_client, NULL,
3301 server->id, SILC_ID_SERVER);
3305 /* Check whether client is detached at all */
3306 if (!(detached_client->mode & SILC_UMODE_DETACHED))
3309 /* Client is detached, and now it is resumed. Remove the detached
3310 mode and mark that it is resumed. */
3311 detached_client->mode &= ~SILC_UMODE_DETACHED;
3312 detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
3314 /* Get the new owner of the resumed client */
3315 server_id = silc_id_str2id(packet->src_id, packet->src_id_len,
3316 packet->src_id_type);
3320 /* Get server entry */
3321 server_entry = silc_idlist_find_server_by_id(server->global_list,
3322 server_id, TRUE, NULL);
3324 if (!server_entry) {
3325 server_entry = silc_idlist_find_server_by_id(server->local_list,
3326 server_id, TRUE, NULL);
3328 if (!server_entry) {
3329 silc_free(server_id);
3334 if (server->server_type == SILC_ROUTER &&
3335 sock->type == SILC_SOCKET_TYPE_ROUTER &&
3336 server_entry->server_type == SILC_ROUTER)
3339 SILC_LOG_DEBUG(("Resuming detached client"));
3341 /* Change the client to correct list. */
3342 if (!silc_idcache_del_by_context(server->local_list->clients,
3344 silc_idcache_del_by_context(server->global_list->clients,
3346 silc_idcache_add(local && server->server_type == SILC_ROUTER ?
3347 server->local_list->clients :
3348 server->global_list->clients,
3349 detached_client->nickname,
3350 detached_client->id, detached_client, FALSE, NULL);
3352 /* Change the owner of the client if needed */
3353 if (detached_client->router != server_entry)
3354 detached_client->router = server_entry;
3356 /* Update channel information regarding global clients on channel. */
3357 if (server->server_type == SILC_SERVER) {
3358 silc_hash_table_list(detached_client->channels, &htl);
3359 while (silc_hash_table_get(&htl, NULL, (void **)&chl))
3360 chl->channel->global_users =
3361 silc_server_channel_has_global(chl->channel);
3362 silc_hash_table_list_reset(&htl);
3365 silc_schedule_task_del_by_context(server->schedule, detached_client);
3367 /* If the sender of this packet is server and we are router we need to
3368 broadcast this packet to other routers in the network. */
3369 if (!server->standalone && server->server_type == SILC_ROUTER &&
3370 sock->type == SILC_SOCKET_TYPE_SERVER &&
3371 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
3372 SILC_LOG_DEBUG(("Broadcasting received Resume Client packet"));
3373 silc_server_packet_send(server, server->router->connection,
3375 packet->flags | SILC_PACKET_FLAG_BROADCAST,
3376 buffer->data, buffer->len, FALSE);
3377 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
3378 packet->type, packet->flags,
3379 packet->buffer->data, packet->buffer->len,
3383 silc_free(server_id);
3386 silc_free(client_id);