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->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 if (!server->standalone)
101 silc_server_packet_send_dest(server, server->router->connection,
102 packet->type, packet->flags |
103 SILC_PACKET_FLAG_BROADCAST,
104 channel_id, SILC_ID_CHANNEL,
105 packet->buffer->data,
106 packet->buffer->len, FALSE);
107 silc_server_backup_send_dest(server, (SilcServerEntry)sock->user_data,
108 packet->type, packet->flags,
109 channel_id, SILC_ID_CHANNEL,
110 packet->buffer->data, packet->buffer->len,
113 /* Packet is destined to client or server */
114 if (!server->standalone)
115 silc_server_packet_send(server, server->router->connection,
117 packet->flags | SILC_PACKET_FLAG_BROADCAST,
118 packet->buffer->data, packet->buffer->len,
120 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
121 packet->type, packet->flags,
122 packet->buffer->data, packet->buffer->len,
127 type = silc_notify_get_type(payload);
128 args = silc_notify_get_args(payload);
133 case SILC_NOTIFY_TYPE_JOIN:
135 * Distribute the notify to local clients on the channel
137 SILC_LOG_DEBUG(("JOIN notify"));
140 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
143 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
147 /* Get channel entry */
148 channel = silc_idlist_find_channel_by_id(server->global_list,
151 channel = silc_idlist_find_channel_by_id(server->local_list,
154 silc_free(channel_id);
158 silc_free(channel_id);
161 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
164 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
168 /* If the the client is not in local list we check global list (ie. the
169 channel will be global channel) and if it does not exist then create
170 entry for the client. */
171 client = silc_idlist_find_client_by_id(server->global_list,
172 client_id, server->server_type,
175 client = silc_idlist_find_client_by_id(server->local_list,
176 client_id, server->server_type,
179 /* If router did not find the client the it is bogus */
180 if (server->server_type != SILC_SERVER)
184 silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
185 silc_id_dup(client_id, SILC_ID_CLIENT),
186 sock->user_data, NULL, 0);
188 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
189 silc_free(client_id);
193 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
197 /* Do not process the notify if the client is not registered */
198 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
201 /* Do not add client to channel if it is there already */
202 if (silc_server_client_on_channel(client, channel, NULL)) {
203 SILC_LOG_DEBUG(("Client already on channel"));
207 /* Send to channel */
208 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
209 FALSE, packet->buffer->data,
210 packet->buffer->len, FALSE);
212 if (server->server_type != SILC_ROUTER &&
213 sock->type == SILC_SOCKET_TYPE_ROUTER)
214 /* The channel is global now */
215 channel->global_users = TRUE;
217 SILC_LOG_DEBUG(("Joining to channel %s", channel->channel_name));
219 /* JOIN the global client to the channel (local clients (if router
220 created the channel) is joined in the pending JOIN command). */
221 chl = silc_calloc(1, sizeof(*chl));
222 chl->client = client;
223 chl->channel = channel;
225 /* If this is the first one on the channel then it is the founder of
227 if (!silc_hash_table_count(channel->user_list))
228 chl->mode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
230 silc_hash_table_add(channel->user_list, client, chl);
231 silc_hash_table_add(client->channels, channel, chl);
232 silc_free(client_id);
233 channel->user_count++;
234 channel->disabled = FALSE;
236 /* Update statistics */
237 if (server->server_type == SILC_ROUTER) {
238 if (sock->type != SILC_SOCKET_TYPE_ROUTER)
239 server->stat.cell_chanclients++;
240 server->stat.chanclients++;
245 case SILC_NOTIFY_TYPE_LEAVE:
247 * Distribute the notify to local clients on the channel
249 SILC_LOG_DEBUG(("LEAVE notify"));
252 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
253 packet->dst_id_type);
258 /* Get channel entry */
259 channel = silc_idlist_find_channel_by_id(server->global_list,
262 channel = silc_idlist_find_channel_by_id(server->local_list,
265 silc_free(channel_id);
271 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
273 silc_free(channel_id);
276 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
278 silc_free(channel_id);
282 /* Get client entry */
283 client = silc_idlist_find_client_by_id(server->global_list,
284 client_id, TRUE, NULL);
286 client = silc_idlist_find_client_by_id(server->local_list,
287 client_id, TRUE, NULL);
289 silc_free(client_id);
290 silc_free(channel_id);
294 silc_free(client_id);
296 /* Check if on channel */
297 if (!silc_server_client_on_channel(client, channel, NULL))
300 /* Send the leave notify to channel */
301 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
302 FALSE, packet->buffer->data,
303 packet->buffer->len, FALSE);
305 /* Remove the user from channel */
306 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
309 case SILC_NOTIFY_TYPE_SIGNOFF:
311 * Distribute the notify to local clients on the channel
313 SILC_LOG_DEBUG(("SIGNOFF notify"));
316 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
319 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
323 /* Get client entry */
324 client = silc_idlist_find_client_by_id(server->global_list,
325 client_id, TRUE, &cache);
327 client = silc_idlist_find_client_by_id(server->local_list,
328 client_id, TRUE, &cache);
330 silc_free(client_id);
334 silc_free(client_id);
336 /* Get signoff message */
337 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
341 /* Update statistics */
342 server->stat.clients--;
343 if (server->stat.cell_clients)
344 server->stat.cell_clients--;
345 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
346 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
348 /* Remove the client from all channels. */
349 silc_server_remove_from_channels(server, NULL, client, TRUE, tmp, FALSE);
351 /* Check if anyone is watching this nickname */
352 if (server->server_type == SILC_ROUTER)
353 silc_server_check_watcher_list(server, client, NULL,
354 SILC_NOTIFY_TYPE_SIGNOFF);
356 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
357 cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
360 case SILC_NOTIFY_TYPE_TOPIC_SET:
362 * Distribute the notify to local clients on the channel
365 SILC_LOG_DEBUG(("TOPIC SET notify"));
368 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
371 client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
375 /* Get client entry */
376 if (id_type == SILC_ID_CLIENT) {
377 client = silc_idlist_find_client_by_id(server->global_list,
378 client_id, TRUE, &cache);
380 client = silc_idlist_find_client_by_id(server->local_list,
381 client_id, TRUE, &cache);
383 silc_free(client_id);
387 silc_free(client_id);
391 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
393 silc_free(channel_id);
398 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
399 packet->dst_id_type);
404 /* Get channel entry */
405 channel = silc_idlist_find_channel_by_id(server->global_list,
408 channel = silc_idlist_find_channel_by_id(server->local_list,
411 silc_free(channel_id);
416 if (channel->topic && !strcmp(channel->topic, tmp))
420 /* Get user's channel entry and check that topic set is allowed. */
421 if (!silc_server_client_on_channel(client, channel, &chl))
423 if (channel->mode & SILC_CHANNEL_MODE_TOPIC &&
424 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
425 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
426 SILC_LOG_DEBUG(("Topic change is not allowed"));
431 /* Change the topic */
432 silc_free(channel->topic);
433 channel->topic = strdup(tmp);
435 /* Send the same notify to the channel */
436 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
437 FALSE, packet->buffer->data,
438 packet->buffer->len, FALSE);
439 silc_free(channel_id);
442 case SILC_NOTIFY_TYPE_NICK_CHANGE:
445 * Distribute the notify to local clients on the channel
447 unsigned char *id, *id2;
449 SilcUInt32 nickname_len;
451 SILC_LOG_DEBUG(("NICK CHANGE notify"));
453 /* Get old client ID */
454 id = silc_argument_get_arg_type(args, 1, &tmp_len);
457 client_id = silc_id_payload_parse_id(id, tmp_len, NULL);
461 /* Get new client ID */
462 id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
465 client_id2 = silc_id_payload_parse_id(id2, tmp_len, NULL);
469 SILC_LOG_DEBUG(("Old Client ID id(%s)",
470 silc_id_render(client_id, SILC_ID_CLIENT)));
471 SILC_LOG_DEBUG(("New Client ID id(%s)",
472 silc_id_render(client_id2, SILC_ID_CLIENT)));
474 /* From protocol version 1.1 we also get the new nickname */
475 nickname = silc_argument_get_arg_type(args, 3, &nickname_len);;
477 /* Replace the Client ID */
478 client = silc_idlist_replace_client_id(server,
479 server->global_list, client_id,
480 client_id2, nickname);
482 client = silc_idlist_replace_client_id(server,
483 server->local_list, client_id,
484 client_id2, nickname);
487 /* Send the NICK_CHANGE notify type to local clients on the channels
488 this client is joined to. */
489 silc_server_send_notify_on_channels(server, client, client,
490 SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
491 id, tmp_len, id2, tmp_len,
496 silc_free(client_id);
498 silc_free(client_id2);
502 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
504 * Distribute the notify to local clients on the channel
507 SILC_LOG_DEBUG(("CMODE CHANGE notify"));
510 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
513 client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
517 /* Get client entry */
518 if (id_type == SILC_ID_CLIENT) {
519 client = silc_idlist_find_client_by_id(server->global_list,
520 client_id, TRUE, &cache);
522 client = silc_idlist_find_client_by_id(server->local_list,
523 client_id, TRUE, &cache);
525 silc_free(client_id);
529 silc_free(client_id);
533 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
534 packet->dst_id_type);
539 /* Get channel entry */
540 channel = silc_idlist_find_channel_by_id(server->global_list,
543 channel = silc_idlist_find_channel_by_id(server->local_list,
546 silc_free(channel_id);
550 silc_free(channel_id);
553 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
556 SILC_GET32_MSB(mode, tmp);
558 /* Check if mode changed */
559 if (channel->mode == mode)
562 /* Get user's channel entry and check that mode change is allowed */
564 if (!silc_server_client_on_channel(client, channel, &chl))
566 if (!silc_server_check_cmode_rights(server, channel, chl, mode)) {
567 SILC_LOG_DEBUG(("CMODE change is not allowed"));
571 if (server->server_type == SILC_ROUTER &&
572 channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH &&
573 !(mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
574 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
575 silc_server_send_notify_cmode(server, sock, FALSE, channel,
576 channel->mode, server->id,
581 channel->founder_key);
586 /* Send the same notify to the channel */
587 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
588 FALSE, packet->buffer->data,
589 packet->buffer->len, FALSE);
591 /* If the channel had private keys set and the mode was removed then
592 we must re-generate and re-distribute a new channel key */
593 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY &&
594 !(mode & SILC_CHANNEL_MODE_PRIVKEY)) {
595 /* Re-generate channel key */
596 if (!silc_server_create_channel_key(server, channel, 0))
599 /* Send the channel key. This sends it to our local clients and if
600 we are normal server to our router as well. */
601 silc_server_send_channel_key(server, NULL, channel,
602 server->server_type == SILC_ROUTER ?
603 FALSE : !server->standalone);
607 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
609 unsigned char hash[32];
612 silc_hmac_free(channel->hmac);
613 if (!silc_hmac_alloc(tmp, NULL, &channel->hmac))
616 /* Set the HMAC key out of current channel key. The client must do
618 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key,
619 channel->key_len / 8, hash);
620 silc_hmac_set_key(channel->hmac, hash,
621 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
622 memset(hash, 0, sizeof(hash));
625 /* Get the passphrase */
626 tmp = silc_argument_get_arg_type(args, 5, &tmp_len);
628 silc_free(channel->passphrase);
629 channel->passphrase = silc_memdup(tmp, tmp_len);
632 /* Get founder public key */
633 tmp = silc_argument_get_arg_type(args, 6, &tmp_len);
634 if (tmp && mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
635 if (channel->founder_key)
636 silc_pkcs_public_key_free(channel->founder_key);
637 channel->founder_key = NULL;
638 silc_pkcs_public_key_decode(tmp, tmp_len, &channel->founder_key);
640 if (!channel->founder_key ||
641 (client && client->data.public_key &&
642 server->server_type == SILC_ROUTER &&
643 !silc_pkcs_public_key_compare(channel->founder_key,
644 client->data.public_key))) {
645 /* A really buggy server isn't checking public keys correctly.
646 It's not possible that the mode setter and founder wouldn't
647 have same public key. */
648 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
650 mode &= ~SILC_CHANNEL_MODE_FOUNDER_AUTH;
651 silc_server_send_notify_cmode(server, sock, FALSE, channel,
652 mode, server->id, SILC_ID_SERVER,
655 channel->passphrase, NULL);
656 if (channel->founder_key)
657 silc_pkcs_public_key_free(channel->founder_key);
658 channel->founder_key = NULL;
659 } else if (client && !client->data.public_key) {
660 client->data.public_key =
661 silc_pkcs_public_key_copy(channel->founder_key);
665 if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH && !channel->founder_key &&
666 server->server_type == SILC_ROUTER) {
667 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
668 mode &= ~SILC_CHANNEL_MODE_FOUNDER_AUTH;
669 silc_server_send_notify_cmode(server, sock, FALSE, channel,
670 mode, server->id, SILC_ID_SERVER,
673 channel->passphrase, NULL);
677 channel->mode = mode;
679 if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) &&
680 channel->founder_key) {
681 silc_pkcs_public_key_free(channel->founder_key);
682 channel->founder_key = NULL;
687 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
690 * Distribute the notify to local clients on the channel
692 SilcChannelClientEntry chl2 = NULL;
693 bool notify_sent = FALSE;
695 SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
698 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
701 client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
705 /* Get client entry */
706 if (id_type == SILC_ID_CLIENT) {
707 client = silc_idlist_find_client_by_id(server->global_list,
708 client_id, TRUE, &cache);
710 client = silc_idlist_find_client_by_id(server->local_list,
711 client_id, TRUE, &cache);
713 silc_free(client_id);
717 silc_free(client_id);
721 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
722 packet->dst_id_type);
727 /* Get channel entry */
728 channel = silc_idlist_find_channel_by_id(server->global_list,
731 channel = silc_idlist_find_channel_by_id(server->local_list,
734 silc_free(channel_id);
740 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
742 silc_free(channel_id);
746 SILC_GET32_MSB(mode, tmp);
748 /* Get target client */
749 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
752 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
756 /* Get client entry */
757 client2 = silc_idlist_find_client_by_id(server->global_list,
758 client_id, TRUE, NULL);
760 client2 = silc_idlist_find_client_by_id(server->local_list,
761 client_id, TRUE, NULL);
763 silc_free(client_id);
767 silc_free(client_id);
770 /* Check that sender is on channel */
771 if (!silc_server_client_on_channel(client, channel, &chl))
774 if (client != client2 && server->server_type == SILC_ROUTER) {
775 /* Sender must be operator */
776 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
777 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
778 SILC_LOG_DEBUG(("CUMODE change is not allowed"));
782 if (!silc_server_client_on_channel(client2, channel, &chl))
785 /* If target is founder mode change is not allowed. */
786 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
787 SILC_LOG_DEBUG(("CUMODE change is not allowed"));
793 /* Get target channel user entry */
794 if (!silc_server_client_on_channel(client2, channel, &chl))
797 if (mode & SILC_CHANNEL_UMODE_CHANFO &&
798 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO) &&
799 server->server_type == SILC_ROUTER &&
800 sock->user_data != server->router) {
801 SilcPublicKey founder_key = NULL;
803 /* If channel doesn't have founder auth mode then it's impossible
804 that someone would be getting founder rights with CUMODE command.
805 In that case there already either is founder or there isn't
806 founder at all on the channel. */
807 if (client && !(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
808 /* Force the mode to not have founder mode */
809 mode &= ~SILC_CHANNEL_UMODE_CHANFO;
810 silc_server_force_cumode_change(server, sock, channel, chl, mode);
815 /* Get the founder of the channel and if found then this client
816 cannot be the founder since there already is one. */
817 silc_hash_table_list(channel->user_list, &htl);
818 while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
819 if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
820 mode &= ~SILC_CHANNEL_UMODE_CHANFO;
821 silc_server_force_cumode_change(server, sock, channel,
826 silc_hash_table_list_reset(&htl);
827 if (!(mode & SILC_CHANNEL_UMODE_CHANFO))
830 /* Founder not found of the channel. Since the founder auth mode
831 is set on the channel now check whether this is the client that
832 originally set the mode. */
834 /* Get public key that must be present in notify */
835 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
836 if (!tmp || !silc_pkcs_public_key_decode(tmp, tmp_len,
838 mode &= ~SILC_CHANNEL_UMODE_CHANFO;
839 silc_server_force_cumode_change(server, sock, channel, chl, mode);
844 if (channel->founder_key) {
845 /* Now match the public key we have cached and public key sent.
847 if (client && client->data.public_key &&
848 !silc_pkcs_public_key_compare(channel->founder_key,
849 client->data.public_key)) {
850 mode &= ~SILC_CHANNEL_UMODE_CHANFO;
851 silc_server_force_cumode_change(server, sock, channel, chl, mode);
855 if (!silc_pkcs_public_key_compare(channel->founder_key,
857 mode &= ~SILC_CHANNEL_UMODE_CHANFO;
858 silc_server_force_cumode_change(server, sock, channel, chl, mode);
864 /* There cannot be anyone else as founder on the channel now. This
865 client is definitely the founder due to this authentication */
866 silc_hash_table_list(channel->user_list, &htl);
867 while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
868 if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
869 chl2->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
870 silc_server_force_cumode_change(server, NULL, channel, chl2,
874 silc_hash_table_list_reset(&htl);
877 silc_pkcs_public_key_free(founder_key);
880 if (server->server_type == SILC_ROUTER && chl->mode == mode) {
881 SILC_LOG_DEBUG(("Mode is changed already"));
885 SILC_LOG_DEBUG(("Changing the channel user mode"));
887 /* Change the mode */
890 /* Send the same notify to the channel */
892 silc_server_packet_send_to_channel(server, sock, channel,
894 FALSE, packet->buffer->data,
895 packet->buffer->len, FALSE);
897 silc_free(channel_id);
901 case SILC_NOTIFY_TYPE_INVITE:
903 if (packet->dst_id_type == SILC_ID_CLIENT)
906 SILC_LOG_DEBUG(("INVITE notify"));
909 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
912 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
916 /* Get channel entry */
917 channel = silc_idlist_find_channel_by_id(server->global_list,
920 channel = silc_idlist_find_channel_by_id(server->local_list,
923 silc_free(channel_id);
927 silc_free(channel_id);
930 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
933 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
937 /* Get client entry */
938 client = silc_idlist_find_client_by_id(server->global_list,
939 client_id, TRUE, &cache);
941 client = silc_idlist_find_client_by_id(server->local_list,
942 client_id, TRUE, &cache);
944 silc_free(client_id);
948 silc_free(client_id);
950 /* Get user's channel entry and check that inviting is allowed. */
951 if (!silc_server_client_on_channel(client, channel, &chl))
953 if (channel->mode & SILC_CHANNEL_MODE_INVITE &&
954 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
955 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
956 SILC_LOG_DEBUG(("Inviting is not allowed"));
960 /* Get the added invite */
961 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
963 if (!channel->invite_list)
964 channel->invite_list = silc_calloc(tmp_len + 2,
965 sizeof(*channel->invite_list));
967 channel->invite_list = silc_realloc(channel->invite_list,
968 sizeof(*channel->invite_list) *
970 strlen(channel->invite_list) +
972 if (tmp[tmp_len - 1] == ',')
973 tmp[tmp_len - 1] = '\0';
975 strncat(channel->invite_list, tmp, tmp_len);
976 strncat(channel->invite_list, ",", 1);
979 /* Get the deleted invite */
980 tmp = silc_argument_get_arg_type(args, 5, &tmp_len);
981 if (tmp && channel->invite_list) {
982 char *start, *end, *n;
984 if (!strncmp(channel->invite_list, tmp,
985 strlen(channel->invite_list) - 1)) {
986 silc_free(channel->invite_list);
987 channel->invite_list = NULL;
989 start = strstr(channel->invite_list, tmp);
990 if (start && strlen(start) >= tmp_len) {
991 end = start + tmp_len;
992 n = silc_calloc(strlen(channel->invite_list) - tmp_len, sizeof(*n));
993 strncat(n, channel->invite_list, start - channel->invite_list);
994 strncat(n, end + 1, ((channel->invite_list +
995 strlen(channel->invite_list)) - end) - 1);
996 silc_free(channel->invite_list);
997 channel->invite_list = n;
1004 case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
1006 * Distribute to the local clients on the channel and change the
1010 SILC_LOG_DEBUG(("CHANNEL CHANGE"));
1012 if (sock->type != SILC_SOCKET_TYPE_ROUTER)
1015 /* Get the old Channel ID */
1016 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1019 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1023 /* Get the channel entry */
1024 channel = silc_idlist_find_channel_by_id(server->local_list,
1027 channel = silc_idlist_find_channel_by_id(server->global_list,
1030 silc_free(channel_id);
1035 /* Send the notify to the channel */
1036 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
1037 FALSE, packet->buffer->data,
1038 packet->buffer->len, FALSE);
1040 /* Get the new Channel ID */
1041 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1044 channel_id2 = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1048 SILC_LOG_DEBUG(("Old Channel ID id(%s)",
1049 silc_id_render(channel_id, SILC_ID_CHANNEL)));
1050 SILC_LOG_DEBUG(("New Channel ID id(%s)",
1051 silc_id_render(channel_id2, SILC_ID_CHANNEL)));
1053 /* Replace the Channel ID */
1054 if (!silc_idlist_replace_channel_id(server->local_list, channel_id,
1056 if (!silc_idlist_replace_channel_id(server->global_list, channel_id,
1058 silc_free(channel_id2);
1063 SilcBuffer modes = NULL, users = NULL, users_modes = NULL;
1065 /* Re-announce this channel which ID was changed. */
1066 silc_server_send_new_channel(server, sock, FALSE, channel->channel_name,
1068 silc_id_get_len(channel->id,
1072 /* Re-announce our clients on the channel as the ID has changed now */
1073 silc_server_announce_get_channel_users(server, channel, &modes, &users,
1076 silc_buffer_push(modes, modes->data - modes->head);
1077 silc_server_packet_send_dest(server, sock,
1078 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1079 channel->id, SILC_ID_CHANNEL,
1080 modes->data, modes->len, FALSE);
1081 silc_buffer_free(modes);
1084 silc_buffer_push(users, users->data - users->head);
1085 silc_server_packet_send(server, sock,
1086 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1087 users->data, users->len, FALSE);
1088 silc_buffer_free(users);
1091 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
1092 silc_server_packet_send_dest(server, sock,
1093 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1094 channel->id, SILC_ID_CHANNEL,
1096 users_modes->len, FALSE);
1097 silc_buffer_free(users_modes);
1100 /* Re-announce channel's topic */
1101 if (channel->topic) {
1102 silc_server_send_notify_topic_set(server, sock,
1103 server->server_type == SILC_ROUTER ?
1104 TRUE : FALSE, channel,
1105 server->id, SILC_ID_SERVER,
1110 silc_free(channel_id);
1114 case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
1116 * Remove the server entry and all clients that this server owns.
1119 SILC_LOG_DEBUG(("SERVER SIGNOFF notify"));
1122 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1125 server_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1129 /* Get server entry */
1130 server_entry = silc_idlist_find_server_by_id(server->global_list,
1131 server_id, TRUE, NULL);
1133 if (!server_entry) {
1134 server_entry = silc_idlist_find_server_by_id(server->local_list,
1135 server_id, TRUE, NULL);
1137 if (!server_entry) {
1138 /* If we are normal server then we might not have the server. Check
1139 whether router was kind enough to send the list of all clients
1140 that actually was to be removed. Remove them if the list is
1142 if (server->server_type != SILC_ROUTER &&
1143 silc_argument_get_arg_num(args) > 1) {
1146 for (i = 1; i < silc_argument_get_arg_num(args); i++) {
1148 tmp = silc_argument_get_arg_type(args, i + 1, &tmp_len);
1151 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1155 /* Get client entry */
1156 client = silc_idlist_find_client_by_id(server->global_list,
1157 client_id, TRUE, &cache);
1160 client = silc_idlist_find_client_by_id(server->local_list,
1161 client_id, TRUE, &cache);
1164 silc_free(client_id);
1168 silc_free(client_id);
1170 /* Update statistics */
1171 server->stat.clients--;
1172 if (server->stat.cell_clients)
1173 server->stat.cell_clients--;
1174 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
1175 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
1177 /* Remove the client from all channels. */
1178 silc_server_remove_from_channels(server, NULL, client,
1181 /* Check if anyone is watching this nickname */
1182 if (server->server_type == SILC_ROUTER)
1183 silc_server_check_watcher_list(server, client, NULL,
1184 SILC_NOTIFY_TYPE_SERVER_SIGNOFF);
1186 /* Remove this client from watcher list if it is */
1188 silc_server_del_from_watcher_list(server, client);
1190 /* Remove the client */
1191 silc_idlist_del_client(local ? server->local_list :
1192 server->global_list, client);
1196 silc_free(server_id);
1200 silc_free(server_id);
1202 /* Free all client entries that this server owns as they will
1203 become invalid now as well. */
1204 silc_server_remove_clients_by_server(server, server_entry, TRUE);
1206 /* Remove the server entry */
1207 silc_idlist_del_server(local ? server->local_list :
1208 server->global_list, server_entry);
1210 /* Update statistics */
1211 if (server->server_type == SILC_ROUTER)
1212 server->stat.servers--;
1216 case SILC_NOTIFY_TYPE_KICKED:
1218 * Distribute the notify to local clients on the channel
1221 SILC_LOG_DEBUG(("KICKED notify"));
1224 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
1225 packet->dst_id_type);
1230 /* Get channel entry */
1231 channel = silc_idlist_find_channel_by_id(server->global_list,
1234 channel = silc_idlist_find_channel_by_id(server->local_list,
1237 silc_free(channel_id);
1241 silc_free(channel_id);
1244 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1247 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1251 /* If the the client is not in local list we check global list */
1252 client = silc_idlist_find_client_by_id(server->global_list,
1253 client_id, TRUE, NULL);
1255 client = silc_idlist_find_client_by_id(server->local_list,
1256 client_id, TRUE, NULL);
1258 silc_free(client_id);
1262 silc_free(client_id);
1264 /* If target is founder they cannot be kicked */
1265 if (!silc_server_client_on_channel(client, channel, &chl))
1267 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO)
1270 /* From protocol version 1.1 we get the kicker's ID as well. */
1271 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1273 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1277 /* If the the client is not in local list we check global list */
1278 client2 = silc_idlist_find_client_by_id(server->global_list,
1279 client_id, TRUE, NULL);
1281 client2 = silc_idlist_find_client_by_id(server->local_list,
1282 client_id, TRUE, NULL);
1284 silc_free(client_id);
1288 silc_free(client_id);
1290 /* Kicker must be operator on channel */
1291 if (!silc_server_client_on_channel(client2, channel, &chl))
1293 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
1294 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1295 SILC_LOG_DEBUG(("Kicking is not allowed"));
1300 /* Send to channel */
1301 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
1302 FALSE, packet->buffer->data,
1303 packet->buffer->len, FALSE);
1305 /* Remove the client from channel */
1306 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
1310 case SILC_NOTIFY_TYPE_KILLED:
1313 * Distribute the notify to local clients on channels
1315 unsigned char *id, *comment;
1316 SilcUInt32 id_len, comment_len;
1318 SILC_LOG_DEBUG(("KILLED notify"));
1321 id = silc_argument_get_arg_type(args, 1, &id_len);
1324 client_id = silc_id_payload_parse_id(id, id_len, NULL);
1328 /* If the the client is not in local list we check global list */
1329 client = silc_idlist_find_client_by_id(server->global_list,
1330 client_id, TRUE, NULL);
1332 client = silc_idlist_find_client_by_id(server->local_list,
1333 client_id, TRUE, NULL);
1335 silc_free(client_id);
1339 silc_free(client_id);
1341 /* If the client is one of ours, then close the connection to the
1342 client now. This removes the client from all channels as well. */
1343 if (packet->dst_id_type == SILC_ID_CLIENT && client->connection) {
1344 sock = client->connection;
1345 silc_server_free_client_data(server, NULL, client, FALSE, NULL);
1346 silc_server_close_connection(server, sock);
1351 comment = silc_argument_get_arg_type(args, 2, &comment_len);
1352 if (comment_len > 128)
1355 /* From protocol version 1.1 we get the killer's ID as well. */
1356 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1358 client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
1362 if (id_type == SILC_ID_CLIENT) {
1363 /* If the the client is not in local list we check global list */
1364 client2 = silc_idlist_find_client_by_id(server->global_list,
1365 client_id, TRUE, NULL);
1367 client2 = silc_idlist_find_client_by_id(server->local_list,
1368 client_id, TRUE, NULL);
1370 silc_free(client_id);
1374 silc_free(client_id);
1376 /* Killer must be router operator */
1377 if (!(client2->mode & SILC_UMODE_ROUTER_OPERATOR)) {
1378 SILC_LOG_DEBUG(("Killing is not allowed"));
1384 /* Send the notify to local clients on the channels except to the
1385 client who is killed. */
1386 silc_server_send_notify_on_channels(server, client, client,
1387 SILC_NOTIFY_TYPE_KILLED, 3,
1388 id, id_len, comment, comment_len,
1391 /* Remove the client from all channels */
1392 silc_server_remove_from_channels(server, NULL, client, FALSE, NULL,
1395 /* Check if anyone is watching this nickname */
1396 if (server->server_type == SILC_ROUTER)
1397 silc_server_check_watcher_list(server, client, NULL,
1398 SILC_NOTIFY_TYPE_KILLED);
1403 case SILC_NOTIFY_TYPE_UMODE_CHANGE:
1405 * Save the mode of the client.
1408 SILC_LOG_DEBUG(("UMODE_CHANGE notify"));
1411 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1414 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1418 /* Get client entry */
1419 client = silc_idlist_find_client_by_id(server->global_list,
1420 client_id, TRUE, NULL);
1422 client = silc_idlist_find_client_by_id(server->local_list,
1423 client_id, TRUE, NULL);
1425 silc_free(client_id);
1429 silc_free(client_id);
1432 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1435 SILC_GET32_MSB(mode, tmp);
1437 /* Check that mode changing is allowed. */
1438 if (!silc_server_check_umode_rights(server, client, mode)) {
1439 SILC_LOG_DEBUG(("UMODE change is not allowed"));
1443 /* Remove internal resumed flag if client is marked detached now */
1444 if (mode & SILC_UMODE_DETACHED)
1445 client->data.status &= ~SILC_IDLIST_STATUS_RESUMED;
1447 /* Update statistics */
1448 if (server->server_type == SILC_ROUTER) {
1449 if (mode & SILC_UMODE_GONE) {
1450 if (!(client->mode & SILC_UMODE_GONE))
1451 server->stat.aways++;
1453 if (client->mode & SILC_UMODE_GONE)
1454 server->stat.aways--;
1456 if (mode & SILC_UMODE_DETACHED) {
1457 if (!(client->mode & SILC_UMODE_DETACHED))
1458 server->stat.detached++;
1460 if (client->mode & SILC_UMODE_DETACHED)
1461 server->stat.detached--;
1465 /* Change the mode */
1466 client->mode = mode;
1468 /* Check if anyone is watching this nickname */
1469 if (server->server_type == SILC_ROUTER)
1470 silc_server_check_watcher_list(server, client, NULL,
1471 SILC_NOTIFY_TYPE_UMODE_CHANGE);
1475 case SILC_NOTIFY_TYPE_BAN:
1480 SILC_LOG_DEBUG(("BAN notify"));
1482 /* Get Channel ID */
1483 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1486 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1490 /* Get channel entry */
1491 channel = silc_idlist_find_channel_by_id(server->global_list,
1494 channel = silc_idlist_find_channel_by_id(server->local_list,
1497 silc_free(channel_id);
1501 silc_free(channel_id);
1503 /* Get the new ban and add it to the ban list */
1504 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1506 if (!channel->ban_list)
1507 channel->ban_list = silc_calloc(tmp_len + 2,
1508 sizeof(*channel->ban_list));
1510 channel->ban_list = silc_realloc(channel->ban_list,
1511 sizeof(*channel->ban_list) *
1513 strlen(channel->ban_list) + 2));
1514 strncat(channel->ban_list, tmp, tmp_len);
1515 strncat(channel->ban_list, ",", 1);
1518 /* Get the ban to be removed and remove it from the list */
1519 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1520 if (tmp && channel->ban_list) {
1521 char *start, *end, *n;
1523 if (!strncmp(channel->ban_list, tmp, strlen(channel->ban_list) - 1)) {
1524 silc_free(channel->ban_list);
1525 channel->ban_list = NULL;
1527 start = strstr(channel->ban_list, tmp);
1528 if (start && strlen(start) >= tmp_len) {
1529 end = start + tmp_len;
1530 n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
1531 strncat(n, channel->ban_list, start - channel->ban_list);
1532 strncat(n, end + 1, ((channel->ban_list +
1533 strlen(channel->ban_list)) - end) - 1);
1534 silc_free(channel->ban_list);
1535 channel->ban_list = n;
1541 case SILC_NOTIFY_TYPE_ERROR:
1548 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1549 if (!tmp && tmp_len != 1)
1551 error = (SilcStatus)tmp[0];
1553 SILC_LOG_DEBUG(("ERROR notify (%d)", error));
1555 if (error == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID &&
1556 sock->type == SILC_SOCKET_TYPE_ROUTER) {
1557 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1559 SILC_LOG_DEBUG(("Received invalid client ID notification, deleting "
1560 "the entry from cache"));
1561 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1564 client = silc_idlist_find_client_by_id(server->global_list,
1565 client_id, FALSE, NULL);
1567 silc_server_remove_from_channels(server, NULL, client, TRUE,
1569 silc_idlist_del_client(server->global_list, client);
1571 silc_free(client_id);
1577 /* Ignore rest of the notify types for now */
1578 case SILC_NOTIFY_TYPE_NONE:
1579 case SILC_NOTIFY_TYPE_MOTD:
1586 silc_notify_payload_free(payload);
1589 void silc_server_notify_list(SilcServer server,
1590 SilcSocketConnection sock,
1591 SilcPacketContext *packet)
1593 SilcPacketContext *new;
1597 SILC_LOG_DEBUG(("Processing Notify List"));
1599 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1600 packet->src_id_type != SILC_ID_SERVER)
1603 /* Make copy of the original packet context, except for the actual
1604 data buffer, which we will here now fetch from the original buffer. */
1605 new = silc_packet_context_alloc();
1606 new->type = SILC_PACKET_NOTIFY;
1607 new->flags = packet->flags;
1608 new->src_id = packet->src_id;
1609 new->src_id_len = packet->src_id_len;
1610 new->src_id_type = packet->src_id_type;
1611 new->dst_id = packet->dst_id;
1612 new->dst_id_len = packet->dst_id_len;
1613 new->dst_id_type = packet->dst_id_type;
1615 buffer = silc_buffer_alloc(1024);
1616 new->buffer = buffer;
1618 while (packet->buffer->len) {
1619 SILC_GET16_MSB(len, packet->buffer->data + 2);
1620 if (len > packet->buffer->len)
1623 if (len > buffer->truelen) {
1624 silc_buffer_free(buffer);
1625 buffer = silc_buffer_alloc(1024 + len);
1628 silc_buffer_pull_tail(buffer, len);
1629 silc_buffer_put(buffer, packet->buffer->data, len);
1631 /* Process the Notify */
1632 silc_server_notify(server, sock, new);
1634 silc_buffer_push_tail(buffer, len);
1635 silc_buffer_pull(packet->buffer, len);
1638 silc_buffer_free(buffer);
1642 /* Received private message. This resolves the destination of the message
1643 and sends the packet. This is used by both server and router. If the
1644 destination is our locally connected client this sends the packet to
1645 the client. This may also send the message for further routing if
1646 the destination is not in our server (or router). */
1648 void silc_server_private_message(SilcServer server,
1649 SilcSocketConnection sock,
1650 SilcPacketContext *packet)
1652 SilcSocketConnection dst_sock;
1653 SilcIDListData idata;
1654 SilcClientEntry client;
1656 SILC_LOG_DEBUG(("Start"));
1658 if (packet->src_id_type != SILC_ID_CLIENT ||
1659 packet->dst_id_type != SILC_ID_CLIENT || !packet->dst_id)
1662 /* Get the route to the client */
1663 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1664 packet->dst_id_len, NULL,
1668 unsigned char error;
1670 if (client && client->mode & SILC_UMODE_DETACHED) {
1671 SILC_LOG_DEBUG(("Client is detached, discarding packet"));
1675 /* Send SILC_NOTIFY_TYPE_ERROR to indicate that such destination ID
1676 does not exist or is invalid. */
1677 idp = silc_id_payload_encode_data(packet->dst_id,
1679 packet->dst_id_type);
1683 error = SILC_STATUS_ERR_NO_SUCH_CLIENT_ID;
1684 if (packet->src_id_type == SILC_ID_CLIENT) {
1685 SilcClientID *client_id = silc_id_str2id(packet->src_id,
1687 packet->src_id_type);
1688 silc_server_send_notify_dest(server, sock, FALSE,
1689 client_id, SILC_ID_CLIENT,
1690 SILC_NOTIFY_TYPE_ERROR, 2,
1692 idp->data, idp->len);
1693 silc_free(client_id);
1695 silc_server_send_notify(server, sock, FALSE,
1696 SILC_NOTIFY_TYPE_ERROR, 2,
1698 idp->data, idp->len);
1701 silc_buffer_free(idp);
1705 /* Check whether destination client wishes to receive private messages */
1706 if (client && !(packet->flags & SILC_PACKET_FLAG_PRIVMSG_KEY) &&
1707 client->mode & SILC_UMODE_BLOCK_PRIVMSG) {
1708 SILC_LOG_DEBUG(("Client blocks private messages, discarding packet"));
1712 /* Send the private message */
1713 silc_server_send_private_message(server, dst_sock, idata->send_key,
1714 idata->hmac_send, idata->psn_send++,
1718 /* Received private message key packet.. This packet is never for us. It is to
1719 the client in the packet's destination ID. Sending of this sort of packet
1720 equals sending private message, ie. it is sent point to point from
1721 one client to another. */
1723 void silc_server_private_message_key(SilcServer server,
1724 SilcSocketConnection sock,
1725 SilcPacketContext *packet)
1727 SilcSocketConnection dst_sock;
1728 SilcIDListData idata;
1730 SILC_LOG_DEBUG(("Start"));
1732 if (packet->src_id_type != SILC_ID_CLIENT ||
1733 packet->dst_id_type != SILC_ID_CLIENT)
1736 if (!packet->dst_id)
1739 /* Get the route to the client */
1740 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1741 packet->dst_id_len, NULL,
1746 /* Relay the packet */
1747 silc_server_relay_packet(server, dst_sock, idata->send_key,
1748 idata->hmac_send, idata->psn_send++, packet, FALSE);
1751 /* Processes incoming command reply packet. The command reply packet may
1752 be destined to one of our clients or it may directly for us. We will
1753 call the command reply routine after processing the packet. */
1755 void silc_server_command_reply(SilcServer server,
1756 SilcSocketConnection sock,
1757 SilcPacketContext *packet)
1759 SilcBuffer buffer = packet->buffer;
1760 SilcClientEntry client = NULL;
1761 SilcSocketConnection dst_sock;
1762 SilcIDListData idata;
1763 SilcClientID *id = NULL;
1765 SILC_LOG_DEBUG(("Start"));
1767 /* Source must be server or router */
1768 if (packet->src_id_type != SILC_ID_SERVER &&
1769 sock->type != SILC_SOCKET_TYPE_ROUTER)
1772 if (packet->dst_id_type == SILC_ID_CHANNEL)
1775 if (packet->dst_id_type == SILC_ID_CLIENT) {
1776 /* Destination must be one of ours */
1777 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
1780 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
1782 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
1788 if (packet->dst_id_type == SILC_ID_SERVER) {
1789 /* For now this must be for us */
1790 if (memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
1791 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
1796 /* Execute command reply locally for the command */
1797 silc_server_command_reply_process(server, sock, buffer);
1799 if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
1800 /* Relay the packet to the client */
1801 const SilcBufferStruct p;
1803 dst_sock = (SilcSocketConnection)client->connection;
1804 idata = (SilcIDListData)client;
1806 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
1807 + packet->dst_id_len + packet->padlen);
1808 if (!silc_packet_send_prepare(dst_sock, 0, 0, buffer->len,
1809 idata->hmac_send, (const SilcBuffer)&p)) {
1810 SILC_LOG_ERROR(("Cannot send packet"));
1813 silc_buffer_put((SilcBuffer)&p, buffer->data, buffer->len);
1815 /* Encrypt packet */
1816 silc_packet_encrypt(idata->send_key, idata->hmac_send, idata->psn_send++,
1817 (SilcBuffer)&p, buffer->len);
1819 /* Send the packet */
1820 silc_server_packet_send_real(server, dst_sock, TRUE);
1826 /* Process received channel message. The message can be originated from
1827 client or server. */
1829 void silc_server_channel_message(SilcServer server,
1830 SilcSocketConnection sock,
1831 SilcPacketContext *packet)
1833 SilcChannelEntry channel = NULL;
1834 SilcChannelID *id = NULL;
1835 void *sender_id = NULL;
1836 SilcClientEntry sender_entry = NULL;
1837 SilcChannelClientEntry chl;
1840 SILC_LOG_DEBUG(("Processing channel message"));
1843 if (packet->dst_id_type != SILC_ID_CHANNEL) {
1844 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1848 /* Find channel entry */
1849 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
1852 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
1854 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
1857 unsigned char error;
1859 /* Send SILC_NOTIFY_TYPE_ERROR to indicate that such destination ID
1860 does not exist or is invalid. */
1861 idp = silc_id_payload_encode_data(packet->dst_id,
1863 packet->dst_id_type);
1867 error = SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID;
1868 if (packet->src_id_type == SILC_ID_CLIENT) {
1869 SilcClientID *client_id = silc_id_str2id(packet->src_id,
1871 packet->src_id_type);
1872 silc_server_send_notify_dest(server, sock, FALSE,
1873 client_id, SILC_ID_CLIENT,
1874 SILC_NOTIFY_TYPE_ERROR, 2,
1875 &error, 1, idp->data, idp->len);
1876 silc_free(client_id);
1878 silc_server_send_notify(server, sock, FALSE,
1879 SILC_NOTIFY_TYPE_ERROR, 2,
1880 &error, 1, idp->data, idp->len);
1883 silc_buffer_free(idp);
1888 /* See that this client is on the channel. If the original sender is
1889 not client (as it can be server as well) we don't do the check. */
1890 sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1891 packet->src_id_type);
1894 if (packet->src_id_type == SILC_ID_CLIENT) {
1895 sender_entry = silc_idlist_find_client_by_id(server->local_list,
1896 sender_id, TRUE, NULL);
1897 if (!sender_entry) {
1899 sender_entry = silc_idlist_find_client_by_id(server->global_list,
1900 sender_id, TRUE, NULL);
1902 if (!sender_entry || !silc_server_client_on_channel(sender_entry,
1904 SILC_LOG_DEBUG(("Client not on channel"));
1908 /* If channel is moderated check that client is allowed to send
1910 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS &&
1911 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
1912 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1913 SILC_LOG_DEBUG(("Channel is silenced from normal users"));
1916 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS &&
1917 chl->mode & SILC_CHANNEL_UMODE_CHANOP &&
1918 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1919 SILC_LOG_DEBUG(("Channel is silenced from operators"));
1922 if (chl->mode & SILC_CHANNEL_UMODE_QUIET) {
1923 SILC_LOG_DEBUG(("Sender is quieted on the channel"));
1927 /* If the packet is coming from router, but the client entry is local
1928 entry to us then some router is rerouting this to us and it is not
1929 allowed. When the client is local to us it means that we've routed
1930 this packet to network, and now someone is routing it back to us. */
1931 if (server->server_type == SILC_ROUTER &&
1932 sock->type == SILC_SOCKET_TYPE_ROUTER && local) {
1933 SILC_LOG_DEBUG(("Channel message rerouted to the sender, drop it"));
1938 /* Distribute the packet to our local clients. This will send the
1939 packet for further routing as well, if needed. */
1940 silc_server_packet_relay_to_channel(server, sock, channel, sender_id,
1941 packet->src_id_type, sender_entry,
1942 packet->buffer->data,
1943 packet->buffer->len, FALSE);
1946 silc_free(sender_id);
1950 /* Received channel key packet. We distribute the key to all of our locally
1951 connected clients on the channel. */
1953 void silc_server_channel_key(SilcServer server,
1954 SilcSocketConnection sock,
1955 SilcPacketContext *packet)
1957 SilcBuffer buffer = packet->buffer;
1958 SilcChannelEntry channel;
1960 if (packet->src_id_type != SILC_ID_SERVER ||
1961 (server->server_type == SILC_ROUTER &&
1962 sock->type == SILC_SOCKET_TYPE_ROUTER))
1965 /* Save the channel key */
1966 channel = silc_server_save_channel_key(server, buffer, NULL);
1970 /* Distribute the key to everybody who is on the channel. If we are router
1971 we will also send it to locally connected servers. */
1972 silc_server_send_channel_key(server, sock, channel, FALSE);
1974 if (server->server_type != SILC_BACKUP_ROUTER) {
1975 /* Distribute to local cell backup routers. */
1976 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
1977 SILC_PACKET_CHANNEL_KEY, 0,
1978 buffer->data, buffer->len, FALSE, TRUE);
1982 /* Received New Client packet and processes it. Creates Client ID for the
1983 client. Client becomes registered after calling this functions. */
1985 SilcClientEntry silc_server_new_client(SilcServer server,
1986 SilcSocketConnection sock,
1987 SilcPacketContext *packet)
1989 SilcBuffer buffer = packet->buffer;
1990 SilcClientEntry client;
1991 SilcClientID *client_id;
1992 SilcIDListData idata;
1993 char *username = NULL, *realname = NULL;
1994 SilcUInt16 username_len;
1997 char *hostname, *nickname;
2000 SILC_LOG_DEBUG(("Creating new client"));
2002 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
2005 /* Take client entry */
2006 client = (SilcClientEntry)sock->user_data;
2007 idata = (SilcIDListData)client;
2009 /* Remove the old cache entry. */
2010 if (!silc_idcache_del_by_context(server->local_list->clients, client)) {
2011 SILC_LOG_INFO(("Unauthenticated client attempted to register to network"));
2012 silc_server_disconnect_remote(server, sock,
2013 SILC_STATUS_ERR_NOT_AUTHENTICATED, NULL);
2014 if (sock->user_data)
2015 silc_server_free_sock_user_data(server, sock, NULL);
2019 /* Parse incoming packet */
2020 ret = silc_buffer_unformat(buffer,
2021 SILC_STR_UI16_NSTRING_ALLOC(&username,
2023 SILC_STR_UI16_STRING_ALLOC(&realname),
2026 silc_free(username);
2027 silc_free(realname);
2028 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2029 "connection", sock->hostname, sock->ip));
2030 silc_server_disconnect_remote(server, sock,
2031 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2033 if (sock->user_data)
2034 silc_server_free_sock_user_data(server, sock, NULL);
2039 silc_free(username);
2040 silc_free(realname);
2041 SILC_LOG_ERROR(("Client %s (%s) did not send its username, closing "
2042 "connection", sock->hostname, sock->ip));
2043 silc_server_disconnect_remote(server, sock,
2044 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2046 if (sock->user_data)
2047 silc_server_free_sock_user_data(server, sock, NULL);
2051 if (username_len > 128)
2052 username[128] = '\0';
2054 /* Check for bad characters for nickname, and modify the nickname if
2055 it includes those. */
2056 if (silc_server_name_bad_chars(username, username_len)) {
2057 nickname = silc_server_name_modify_bad(username, username_len);
2059 nickname = strdup(username);
2062 /* Make sanity checks for the hostname of the client. If the hostname
2063 is provided in the `username' check that it is the same than the
2064 resolved hostname, or if not resolved the hostname that appears in
2065 the client's public key. If the hostname is not present then put
2066 it from the resolved name or from the public key. */
2067 if (strchr(username, '@')) {
2068 SilcPublicKeyIdentifier pident;
2069 int tlen = strcspn(username, "@");
2070 char *phostname = NULL;
2072 hostname = silc_memdup(username + tlen + 1, strlen(username) - tlen - 1);
2074 if (strcmp(sock->hostname, sock->ip) &&
2075 strcmp(sock->hostname, hostname)) {
2076 silc_free(username);
2077 silc_free(hostname);
2078 silc_free(realname);
2079 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2080 "connection", sock->hostname, sock->ip));
2081 silc_server_disconnect_remote(server, sock,
2082 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2084 if (sock->user_data)
2085 silc_server_free_sock_user_data(server, sock, NULL);
2089 pident = silc_pkcs_decode_identifier(client->data.public_key->identifier);
2091 phostname = strdup(pident->host);
2092 silc_pkcs_free_identifier(pident);
2095 if (!strcmp(sock->hostname, sock->ip) &&
2096 phostname && strcmp(phostname, hostname)) {
2097 silc_free(username);
2098 silc_free(hostname);
2099 silc_free(phostname);
2100 silc_free(realname);
2101 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2102 "connection", sock->hostname, sock->ip));
2103 silc_server_disconnect_remote(server, sock,
2104 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2106 if (sock->user_data)
2107 silc_server_free_sock_user_data(server, sock, NULL);
2111 silc_free(phostname);
2113 /* The hostname is not present, add it. */
2115 /* XXX For now we cannot take the host name from the public key since
2116 they are not trusted or we cannot verify them as trusted. Just take
2117 what the resolved name or address is. */
2119 if (strcmp(sock->hostname, sock->ip)) {
2121 newusername = silc_calloc(strlen(username) +
2122 strlen(sock->hostname) + 2,
2123 sizeof(*newusername));
2124 strncat(newusername, username, strlen(username));
2125 strncat(newusername, "@", 1);
2126 strncat(newusername, sock->hostname, strlen(sock->hostname));
2127 silc_free(username);
2128 username = newusername;
2131 SilcPublicKeyIdentifier pident =
2132 silc_pkcs_decode_identifier(client->data.public_key->identifier);
2135 newusername = silc_calloc(strlen(username) +
2136 strlen(pident->host) + 2,
2137 sizeof(*newusername));
2138 strncat(newusername, username, strlen(username));
2139 strncat(newusername, "@", 1);
2140 strncat(newusername, pident->host, strlen(pident->host));
2141 silc_free(username);
2142 username = newusername;
2143 silc_pkcs_free_identifier(pident);
2149 /* Create Client ID */
2150 while (!silc_id_create_client_id(server, server->id, server->rng,
2151 server->md5hash, nickname, &client_id)) {
2154 silc_server_disconnect_remote(server, sock,
2155 SILC_STATUS_ERR_BAD_NICKNAME, NULL);
2156 if (sock->user_data)
2157 silc_server_free_sock_user_data(server, sock, NULL);
2160 snprintf(&nickname[strlen(nickname) - 1], 1, "%d", nickfail);
2163 /* Update client entry */
2164 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
2165 client->nickname = nickname;
2166 client->username = username;
2167 client->userinfo = realname ? realname : strdup(" ");
2168 client->id = client_id;
2169 id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
2171 /* Add the client again to the ID cache */
2172 silc_idcache_add(server->local_list->clients, client->nickname,
2173 client_id, client, 0, NULL);
2175 /* Notify our router about new client on the SILC network */
2176 if (!server->standalone)
2177 silc_server_send_new_id(server, (SilcSocketConnection)
2178 server->router->connection,
2179 server->server_type == SILC_ROUTER ? TRUE : FALSE,
2180 client->id, SILC_ID_CLIENT, id_len);
2182 /* Distribute to backup routers */
2183 if (server->server_type == SILC_ROUTER) {
2184 SilcBuffer idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
2185 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_ID, 0,
2186 idp->data, idp->len, FALSE, TRUE);
2187 silc_buffer_free(idp);
2190 /* Send the new client ID to the client. */
2191 silc_server_send_new_id(server, sock, FALSE, client->id, SILC_ID_CLIENT,
2192 silc_id_get_len(client->id, SILC_ID_CLIENT));
2194 /* Send some nice info to the client */
2195 silc_server_send_connect_notifys(server, sock, client);
2197 /* Check if anyone is watching this nickname */
2198 if (server->server_type == SILC_ROUTER)
2199 silc_server_check_watcher_list(server, client, NULL, 0);
2204 /* Create new server. This processes received New Server packet and
2205 saves the received Server ID. The server is our locally connected
2206 server thus we save all the information and save it to local list.
2207 This funtion can be used by both normal server and router server.
2208 If normal server uses this it means that its router has connected
2209 to the server. If router uses this it means that one of the cell's
2210 servers is connected to the router. */
2212 SilcServerEntry silc_server_new_server(SilcServer server,
2213 SilcSocketConnection sock,
2214 SilcPacketContext *packet)
2216 SilcBuffer buffer = packet->buffer;
2217 SilcServerEntry new_server, server_entry;
2218 SilcServerID *server_id;
2219 SilcIDListData idata;
2220 unsigned char *server_name, *id_string;
2221 SilcUInt16 id_len, name_len;
2225 SILC_LOG_DEBUG(("Creating new server"));
2227 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
2228 sock->type != SILC_SOCKET_TYPE_ROUTER)
2231 /* Take server entry */
2232 new_server = (SilcServerEntry)sock->user_data;
2233 idata = (SilcIDListData)new_server;
2235 /* Remove the old cache entry */
2236 if (!silc_idcache_del_by_context(server->local_list->servers, new_server)) {
2237 if (!silc_idcache_del_by_context(server->global_list->servers,
2239 SILC_LOG_INFO(("Unauthenticated %s attempted to register to "
2240 "network", (sock->type == SILC_SOCKET_TYPE_SERVER ?
2241 "server" : "router")));
2242 silc_server_disconnect_remote(server, sock,
2243 SILC_STATUS_ERR_NOT_AUTHENTICATED, NULL);
2244 if (sock->user_data)
2245 silc_server_free_sock_user_data(server, sock, NULL);
2251 /* Parse the incoming packet */
2252 ret = silc_buffer_unformat(buffer,
2253 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
2254 SILC_STR_UI16_NSTRING_ALLOC(&server_name,
2258 silc_free(id_string);
2259 silc_free(server_name);
2260 silc_server_disconnect_remote(server, sock,
2261 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2263 if (sock->user_data)
2264 silc_server_free_sock_user_data(server, sock, NULL);
2268 if (id_len > buffer->len) {
2269 silc_free(id_string);
2270 silc_free(server_name);
2271 silc_server_disconnect_remote(server, sock,
2272 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2274 if (sock->user_data)
2275 silc_server_free_sock_user_data(server, sock, NULL);
2280 server_name[255] = '\0';
2283 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
2285 silc_free(id_string);
2286 silc_free(server_name);
2287 silc_server_disconnect_remote(server, sock,
2288 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2290 if (sock->user_data)
2291 silc_server_free_sock_user_data(server, sock, NULL);
2294 silc_free(id_string);
2296 /* Check for valid server ID */
2297 if (!silc_id_is_valid_server_id(server, server_id, sock)) {
2298 SILC_LOG_INFO(("Invalid server ID sent by %s (%s)",
2299 sock->ip, sock->hostname));
2300 silc_server_disconnect_remote(server, sock,
2301 SILC_STATUS_ERR_BAD_SERVER_ID, NULL);
2302 if (sock->user_data)
2303 silc_server_free_sock_user_data(server, sock, NULL);
2304 silc_free(server_name);
2308 /* Check that we do not have this ID already */
2309 server_entry = silc_idlist_find_server_by_id(server->local_list,
2310 server_id, TRUE, NULL);
2312 silc_idcache_del_by_context(server->local_list->servers, server_entry);
2314 server_entry = silc_idlist_find_server_by_id(server->global_list,
2315 server_id, TRUE, NULL);
2317 silc_idcache_del_by_context(server->global_list->servers, server_entry);
2320 /* Update server entry */
2321 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
2322 new_server->server_name = server_name;
2323 new_server->id = server_id;
2325 SILC_LOG_DEBUG(("New server id(%s)",
2326 silc_id_render(server_id, SILC_ID_SERVER)));
2328 /* Add again the entry to the ID cache. */
2329 silc_idcache_add(local ? server->local_list->servers :
2330 server->global_list->servers, server_name, server_id,
2331 new_server, 0, NULL);
2333 /* Distribute the information about new server in the SILC network
2334 to our router. If we are normal server we won't send anything
2335 since this connection must be our router connection. */
2336 if (server->server_type == SILC_ROUTER && !server->standalone &&
2337 server->router->connection != sock)
2338 silc_server_send_new_id(server, server->router->connection,
2339 TRUE, new_server->id, SILC_ID_SERVER,
2340 silc_id_get_len(server_id, SILC_ID_SERVER));
2342 if (server->server_type == SILC_ROUTER) {
2343 /* Distribute to backup routers */
2344 SilcBuffer idp = silc_id_payload_encode(new_server->id, SILC_ID_SERVER);
2345 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_ID, 0,
2346 idp->data, idp->len, FALSE, TRUE);
2347 silc_buffer_free(idp);
2350 server->stat.cell_servers++;
2353 /* Check whether this router connection has been replaced by an
2354 backup router. If it has been then we'll disable the server and will
2355 ignore everything it will send until the backup router resuming
2356 protocol has been completed. */
2357 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
2358 silc_server_backup_replaced_get(server, server_id, NULL)) {
2359 /* Send packet to the server indicating that it cannot use this
2360 connection as it has been replaced by backup router. */
2361 SilcBuffer packet = silc_buffer_alloc(2);
2362 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
2363 silc_buffer_format(packet,
2364 SILC_STR_UI_CHAR(SILC_SERVER_BACKUP_REPLACED),
2365 SILC_STR_UI_CHAR(0),
2367 silc_server_packet_send(server, sock,
2368 SILC_PACKET_RESUME_ROUTER, 0,
2369 packet->data, packet->len, TRUE);
2370 silc_buffer_free(packet);
2372 /* Mark the router disabled. The data sent earlier will go but nothing
2373 after this does not go to this connection. */
2374 idata->status |= SILC_IDLIST_STATUS_DISABLED;
2376 /* If it is router announce our stuff to it. */
2377 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
2378 server->server_type == SILC_ROUTER) {
2379 silc_server_announce_servers(server, FALSE, 0, sock);
2380 silc_server_announce_clients(server, 0, sock);
2381 silc_server_announce_channels(server, 0, sock);
2388 /* Processes incoming New ID packet. New ID Payload is used to distribute
2389 information about newly registered clients and servers. */
2391 static void silc_server_new_id_real(SilcServer server,
2392 SilcSocketConnection sock,
2393 SilcPacketContext *packet,
2396 SilcBuffer buffer = packet->buffer;
2398 SilcServerEntry router, server_entry;
2399 SilcSocketConnection router_sock;
2404 SILC_LOG_DEBUG(("Processing new ID"));
2406 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2407 server->server_type == SILC_SERVER ||
2408 packet->src_id_type != SILC_ID_SERVER)
2411 idp = silc_id_payload_parse(buffer->data, buffer->len);
2415 id_type = silc_id_payload_get_type(idp);
2417 /* Normal server cannot have other normal server connections */
2418 server_entry = (SilcServerEntry)sock->user_data;
2419 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER &&
2420 server_entry->server_type == SILC_SERVER)
2423 id = silc_id_payload_get_id(idp);
2427 /* If the packet is coming from server then use the sender as the
2428 origin of the the packet. If it came from router then check the real
2429 sender of the packet and use that as the origin. */
2430 if (sock->type == SILC_SOCKET_TYPE_SERVER) {
2431 id_list = server->local_list;
2433 router = sock->user_data;
2435 /* If the sender is backup router and ID is server (and we are not
2436 backup router) then switch the entry to global list. */
2437 if (server_entry->server_type == SILC_BACKUP_ROUTER &&
2438 id_type == SILC_ID_SERVER &&
2439 server->id_entry->server_type != SILC_BACKUP_ROUTER) {
2440 id_list = server->global_list;
2441 router_sock = server->router ? server->router->connection : sock;
2444 void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2445 packet->src_id_type);
2446 router = silc_idlist_find_server_by_id(server->global_list,
2447 sender_id, TRUE, NULL);
2449 router = silc_idlist_find_server_by_id(server->local_list,
2450 sender_id, TRUE, NULL);
2451 silc_free(sender_id);
2453 id_list = server->global_list;
2460 case SILC_ID_CLIENT:
2462 SilcClientEntry entry;
2464 /* Check that we do not have this client already */
2465 entry = silc_idlist_find_client_by_id(server->global_list,
2466 id, server->server_type,
2469 entry = silc_idlist_find_client_by_id(server->local_list,
2470 id, server->server_type,
2473 SILC_LOG_DEBUG(("Ignoring client that we already have"));
2477 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
2478 silc_id_render(id, SILC_ID_CLIENT),
2479 sock->type == SILC_SOCKET_TYPE_SERVER ?
2480 "Server" : "Router", sock->hostname));
2482 /* As a router we keep information of all global information in our
2483 global list. Cell wide information however is kept in the local
2485 entry = silc_idlist_add_client(id_list, NULL, NULL, NULL,
2486 id, router, NULL, 0);
2488 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
2490 /* Inform the sender that the ID is not usable */
2491 silc_server_send_notify_signoff(server, sock, FALSE, id, NULL);
2494 entry->nickname = NULL;
2495 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2497 if (sock->type == SILC_SOCKET_TYPE_SERVER)
2498 server->stat.cell_clients++;
2499 server->stat.clients++;
2501 /* Check if anyone is watching this nickname */
2502 if (server->server_type == SILC_ROUTER && id_list == server->local_list)
2503 silc_server_check_watcher_list(server, entry, NULL, 0);
2507 case SILC_ID_SERVER:
2509 SilcServerEntry entry;
2511 /* If the ID is mine, ignore it. */
2512 if (SILC_ID_SERVER_COMPARE(id, server->id)) {
2513 SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
2517 /* If the ID is the sender's ID, ignore it (we have it already) */
2518 if (SILC_ID_SERVER_COMPARE(id, router->id)) {
2519 SILC_LOG_DEBUG(("Ignoring sender's own ID"));
2523 /* Check that we do not have this server already */
2524 entry = silc_idlist_find_server_by_id(server->global_list,
2525 id, server->server_type,
2528 entry = silc_idlist_find_server_by_id(server->local_list,
2529 id, server->server_type,
2532 SILC_LOG_DEBUG(("Ignoring server that we already have"));
2536 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
2537 silc_id_render(id, SILC_ID_SERVER),
2538 sock->type == SILC_SOCKET_TYPE_SERVER ?
2539 "Server" : "Router", sock->hostname));
2541 /* As a router we keep information of all global information in our
2542 global list. Cell wide information however is kept in the local
2544 entry = silc_idlist_add_server(id_list, NULL, 0, id, router,
2547 SILC_LOG_ERROR(("Could not add new server to the ID Cache"));
2550 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2552 if (sock->type == SILC_SOCKET_TYPE_SERVER)
2553 server->stat.cell_servers++;
2554 server->stat.servers++;
2558 case SILC_ID_CHANNEL:
2559 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
2568 /* If the sender of this packet is server and we are router we need to
2569 broadcast this packet to other routers in the network. */
2570 if (broadcast && server->server_type == SILC_ROUTER &&
2571 sock->type == SILC_SOCKET_TYPE_SERVER &&
2572 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2573 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
2574 if (!server->standalone)
2575 silc_server_packet_send(server, server->router->connection,
2577 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2578 buffer->data, buffer->len, FALSE);
2579 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
2580 packet->type, packet->flags,
2581 packet->buffer->data, packet->buffer->len,
2586 silc_id_payload_free(idp);
2590 /* Processes incoming New ID packet. New ID Payload is used to distribute
2591 information about newly registered clients and servers. */
2593 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
2594 SilcPacketContext *packet)
2596 silc_server_new_id_real(server, sock, packet, TRUE);
2599 /* Receoved New Id List packet, list of New ID payloads inside one
2600 packet. Process the New ID payloads one by one. */
2602 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
2603 SilcPacketContext *packet)
2605 SilcPacketContext *new_id;
2609 SILC_LOG_DEBUG(("Processing New ID List"));
2611 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2612 packet->src_id_type != SILC_ID_SERVER)
2615 /* If the sender of this packet is server and we are router we need to
2616 broadcast this packet to other routers in the network. Broadcast
2617 this list packet instead of multiple New ID packets. */
2618 if (server->server_type == SILC_ROUTER &&
2619 sock->type == SILC_SOCKET_TYPE_SERVER &&
2620 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2621 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
2622 if (!server->standalone)
2623 silc_server_packet_send(server, server->router->connection,
2625 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2626 packet->buffer->data,
2627 packet->buffer->len, FALSE);
2628 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
2629 packet->type, packet->flags,
2630 packet->buffer->data, packet->buffer->len,
2634 /* Make copy of the original packet context, except for the actual
2635 data buffer, which we will here now fetch from the original buffer. */
2636 new_id = silc_packet_context_alloc();
2637 new_id->type = SILC_PACKET_NEW_ID;
2638 new_id->flags = packet->flags;
2639 new_id->src_id = packet->src_id;
2640 new_id->src_id_len = packet->src_id_len;
2641 new_id->src_id_type = packet->src_id_type;
2642 new_id->dst_id = packet->dst_id;
2643 new_id->dst_id_len = packet->dst_id_len;
2644 new_id->dst_id_type = packet->dst_id_type;
2646 idp = silc_buffer_alloc(256);
2647 new_id->buffer = idp;
2649 while (packet->buffer->len) {
2650 SILC_GET16_MSB(id_len, packet->buffer->data + 2);
2651 if ((id_len > packet->buffer->len) ||
2652 (id_len > idp->truelen))
2655 silc_buffer_pull_tail(idp, 4 + id_len);
2656 silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
2658 /* Process the New ID */
2659 silc_server_new_id_real(server, sock, new_id, FALSE);
2661 silc_buffer_push_tail(idp, 4 + id_len);
2662 silc_buffer_pull(packet->buffer, 4 + id_len);
2665 silc_buffer_free(idp);
2669 /* Received New Channel packet. Information about new channels in the
2670 network are distributed using this packet. Save the information about
2671 the new channel. This usually comes from router but also normal server
2672 can send this to notify channels it has when it connects to us. */
2674 void silc_server_new_channel(SilcServer server,
2675 SilcSocketConnection sock,
2676 SilcPacketContext *packet)
2678 SilcChannelPayload payload;
2679 SilcChannelID *channel_id;
2681 SilcUInt32 name_len;
2684 SilcServerEntry server_entry;
2685 SilcChannelEntry channel;
2687 SILC_LOG_DEBUG(("Processing New Channel"));
2689 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2690 packet->src_id_type != SILC_ID_SERVER ||
2691 server->server_type == SILC_SERVER)
2694 /* Parse the channel payload */
2695 payload = silc_channel_payload_parse(packet->buffer->data,
2696 packet->buffer->len);
2700 /* Get the channel ID */
2701 channel_id = silc_channel_get_id_parse(payload);
2703 silc_channel_payload_free(payload);
2707 channel_name = silc_channel_get_name(payload, &name_len);
2709 channel_name[255] = '\0';
2711 id = silc_channel_get_id(payload, &id_len);
2713 server_entry = (SilcServerEntry)sock->user_data;
2715 if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
2716 /* Add the channel to global list as it is coming from router. It
2717 cannot be our own channel as it is coming from router. */
2719 /* Check that we don't already have this channel */
2720 channel = silc_idlist_find_channel_by_name(server->local_list,
2721 channel_name, NULL);
2723 channel = silc_idlist_find_channel_by_name(server->global_list,
2724 channel_name, NULL);
2726 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
2727 silc_id_render(channel_id, SILC_ID_CHANNEL),
2731 silc_idlist_add_channel(server->global_list, strdup(channel_name),
2732 0, channel_id, sock->user_data, NULL, NULL, 0);
2735 channel->disabled = TRUE;
2737 server->stat.channels++;
2738 if (server->server_type == SILC_ROUTER)
2739 channel->users_resolved = TRUE;
2742 /* The channel is coming from our server, thus it is in our cell
2743 we will add it to our local list. */
2746 SILC_LOG_DEBUG(("Channel id(%s) from [Server] %s",
2747 silc_id_render(channel_id, SILC_ID_CHANNEL),
2750 /* Check that we don't already have this channel */
2751 channel = silc_idlist_find_channel_by_name(server->local_list,
2752 channel_name, NULL);
2754 channel = silc_idlist_find_channel_by_name(server->global_list,
2755 channel_name, NULL);
2757 /* If the channel does not exist, then create it. This creates a new
2758 key to the channel as well that we will send to the server. */
2760 /* The protocol says that the Channel ID's IP address must be based
2761 on the router's IP address. Check whether the ID is based in our
2762 IP and if it is not then create a new ID and enforce the server
2763 to switch the ID. */
2764 if (server_entry->server_type != SILC_BACKUP_ROUTER &&
2765 !SILC_ID_COMPARE(channel_id, server->id, server->id->ip.data_len)) {
2767 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2769 if (silc_id_create_channel_id(server, server->id, server->rng, &tmp)) {
2770 silc_server_send_notify_channel_change(server, sock, FALSE,
2772 silc_free(channel_id);
2777 /* Create the channel with the provided Channel ID */
2778 channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
2782 silc_channel_payload_free(payload);
2783 silc_free(channel_id);
2786 channel->disabled = TRUE;
2788 /* Send the new channel key to the server */
2789 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2790 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
2791 chk = silc_channel_key_payload_encode(id_len, id,
2792 strlen(channel->channel_key->
2794 channel->channel_key->cipher->name,
2795 channel->key_len / 8,
2797 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
2798 chk->data, chk->len, FALSE);
2799 silc_buffer_free(chk);
2801 /* The channel exist by that name, check whether the ID's match.
2802 If they don't then we'll force the server to use the ID we have.
2803 We also create a new key for the channel. */
2804 SilcBuffer modes = NULL, users = NULL, users_modes = NULL;
2806 if (!SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
2807 /* They don't match, send CHANNEL_CHANGE notify to the server to
2808 force the ID change. */
2809 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2810 silc_server_send_notify_channel_change(server, sock, FALSE,
2811 channel_id, channel->id);
2813 /* Wait that server re-announces this channel */
2817 #if 0 /* Lets expect that server send CMODE_CHANGE notify anyway to
2818 (attempt) force mode change, and may very well get it. */
2820 /* If the mode is different from what we have then enforce the
2822 mode = silc_channel_get_mode(payload);
2823 if (channel->mode != mode) {
2824 SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
2825 silc_server_send_notify_cmode(server, sock, FALSE, channel,
2826 channel->mode, server->id,
2827 SILC_ID_SERVER, channel->cipher,
2829 channel->passphrase,
2830 channel->founder_key);
2834 /* Create new key for the channel and send it to the server and
2835 everybody else possibly on the channel. */
2836 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
2837 if (!silc_server_create_channel_key(server, channel, 0))
2840 /* Send to the channel */
2841 silc_server_send_channel_key(server, sock, channel, FALSE);
2842 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2843 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
2845 /* Send to the server */
2846 chk = silc_channel_key_payload_encode(id_len, id,
2847 strlen(channel->channel_key->
2849 channel->channel_key->
2851 channel->key_len / 8,
2853 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
2854 chk->data, chk->len, FALSE);
2855 silc_buffer_free(chk);
2859 silc_free(channel_id);
2861 /* Update statistics */
2862 server->stat.channels++;
2863 server->stat.cell_channels++;
2865 /* Since the channel is coming from server and we also know about it
2866 then send the JOIN notify to the server so that it see's our
2867 users on the channel "joining" the channel. */
2868 silc_server_announce_get_channel_users(server, channel, &modes, &users,
2871 silc_buffer_push(modes, modes->data - modes->head);
2872 silc_server_packet_send_dest(server, sock,
2873 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2874 channel->id, SILC_ID_CHANNEL,
2875 modes->data, modes->len, FALSE);
2876 silc_buffer_free(modes);
2879 silc_buffer_push(users, users->data - users->head);
2880 silc_server_packet_send(server, sock,
2881 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2882 users->data, users->len, FALSE);
2883 silc_buffer_free(users);
2886 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
2887 silc_server_packet_send_dest(server, sock,
2888 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2889 channel->id, SILC_ID_CHANNEL,
2891 users_modes->len, FALSE);
2892 silc_buffer_free(users_modes);
2894 if (channel->topic) {
2895 silc_server_send_notify_topic_set(server, sock,
2896 server->server_type == SILC_ROUTER ?
2897 TRUE : FALSE, channel,
2898 server->id, SILC_ID_SERVER,
2904 silc_channel_payload_free(payload);
2907 /* Received New Channel List packet, list of New Channel List payloads inside
2908 one packet. Process the New Channel payloads one by one. */
2910 void silc_server_new_channel_list(SilcServer server,
2911 SilcSocketConnection sock,
2912 SilcPacketContext *packet)
2914 SilcPacketContext *new;
2916 SilcUInt16 len1, len2;
2918 SILC_LOG_DEBUG(("Processing New Channel List"));
2920 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2921 packet->src_id_type != SILC_ID_SERVER ||
2922 server->server_type == SILC_SERVER)
2925 /* If the sender of this packet is server and we are router we need to
2926 broadcast this packet to other routers in the network. Broadcast
2927 this list packet instead of multiple New Channel packets. */
2928 if (server->server_type == SILC_ROUTER &&
2929 sock->type == SILC_SOCKET_TYPE_SERVER &&
2930 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2931 SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
2932 if (!server->standalone)
2933 silc_server_packet_send(server, server->router->connection,
2935 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2936 packet->buffer->data,
2937 packet->buffer->len, FALSE);
2938 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
2939 packet->type, packet->flags,
2940 packet->buffer->data, packet->buffer->len,
2944 /* Make copy of the original packet context, except for the actual
2945 data buffer, which we will here now fetch from the original buffer. */
2946 new = silc_packet_context_alloc();
2947 new->type = SILC_PACKET_NEW_CHANNEL;
2948 new->flags = packet->flags;
2949 new->src_id = packet->src_id;
2950 new->src_id_len = packet->src_id_len;
2951 new->src_id_type = packet->src_id_type;
2952 new->dst_id = packet->dst_id;
2953 new->dst_id_len = packet->dst_id_len;
2954 new->dst_id_type = packet->dst_id_type;
2956 buffer = silc_buffer_alloc(512);
2957 new->buffer = buffer;
2959 while (packet->buffer->len) {
2960 SILC_GET16_MSB(len1, packet->buffer->data);
2961 if ((len1 > packet->buffer->len) ||
2962 (len1 > buffer->truelen))
2965 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
2966 if ((len2 > packet->buffer->len) ||
2967 (len2 > buffer->truelen))
2970 silc_buffer_pull_tail(buffer, 8 + len1 + len2);
2971 silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
2973 /* Process the New Channel */
2974 silc_server_new_channel(server, sock, new);
2976 silc_buffer_push_tail(buffer, 8 + len1 + len2);
2977 silc_buffer_pull(packet->buffer, 8 + len1 + len2);
2980 silc_buffer_free(buffer);
2984 /* Received key agreement packet. This packet is never for us. It is to
2985 the client in the packet's destination ID. Sending of this sort of packet
2986 equals sending private message, ie. it is sent point to point from
2987 one client to another. */
2989 void silc_server_key_agreement(SilcServer server,
2990 SilcSocketConnection sock,
2991 SilcPacketContext *packet)
2993 SilcSocketConnection dst_sock;
2994 SilcIDListData idata;
2996 SILC_LOG_DEBUG(("Start"));
2998 if (packet->src_id_type != SILC_ID_CLIENT ||
2999 packet->dst_id_type != SILC_ID_CLIENT)
3002 if (!packet->dst_id)
3005 /* Get the route to the client */
3006 dst_sock = silc_server_get_client_route(server, packet->dst_id,
3007 packet->dst_id_len, NULL,
3012 /* Relay the packet */
3013 silc_server_relay_packet(server, dst_sock, idata->send_key,
3014 idata->hmac_send, idata->psn_send++,
3018 /* Received connection auth request packet that is used during connection
3019 phase to resolve the mandatory authentication method. This packet can
3020 actually be received at anytime but usually it is used only during
3021 the connection authentication phase. Now, protocol says that this packet
3022 can come from client or server, however, we support only this coming
3023 from client and expect that server always knows what authentication
3026 void silc_server_connection_auth_request(SilcServer server,
3027 SilcSocketConnection sock,
3028 SilcPacketContext *packet)
3030 SilcServerConfigClient *client = NULL;
3031 SilcUInt16 conn_type;
3033 SilcAuthMethod auth_meth = SILC_AUTH_NONE;
3035 if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT) {
3036 SILC_LOG_DEBUG(("Request not from client"));
3040 /* Parse the payload */
3041 ret = silc_buffer_unformat(packet->buffer,
3042 SILC_STR_UI_SHORT(&conn_type),
3043 SILC_STR_UI_SHORT(NULL),
3048 if (conn_type != SILC_SOCKET_TYPE_CLIENT)
3051 /* Get the authentication method for the client */
3052 auth_meth = SILC_AUTH_NONE;
3053 client = silc_server_config_find_client(server, sock->ip);
3055 client = silc_server_config_find_client(server, sock->hostname);
3057 if (client->passphrase) {
3058 if (client->publickeys && !server->config->prefer_passphrase_auth)
3059 auth_meth = SILC_AUTH_PUBLIC_KEY;
3061 auth_meth = SILC_AUTH_PASSWORD;
3062 } else if (client->publickeys)
3063 auth_meth = SILC_AUTH_PUBLIC_KEY;
3066 SILC_LOG_DEBUG(("Authentication method is [%s]",
3067 (auth_meth == SILC_AUTH_NONE ? "None" :
3068 auth_meth == SILC_AUTH_PASSWORD ? "Passphrase" :
3069 "Digital signatures")));
3071 /* Send it back to the client */
3072 silc_server_send_connection_auth_request(server, sock, conn_type, auth_meth);
3075 /* Received REKEY packet. The sender of the packet wants to regenerate
3076 its session keys. This starts the REKEY protocol. */
3078 void silc_server_rekey(SilcServer server,
3079 SilcSocketConnection sock,
3080 SilcPacketContext *packet)
3082 SilcProtocol protocol;
3083 SilcServerRekeyInternalContext *proto_ctx;
3084 SilcIDListData idata = (SilcIDListData)sock->user_data;
3086 SILC_LOG_DEBUG(("Start"));
3088 /* Allocate internal protocol context. This is sent as context
3090 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
3091 proto_ctx->server = (void *)server;
3092 proto_ctx->sock = sock;
3093 proto_ctx->responder = TRUE;
3094 proto_ctx->pfs = idata->rekey->pfs;
3096 /* Perform rekey protocol. Will call the final callback after the
3097 protocol is over. */
3098 silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
3099 &protocol, proto_ctx, silc_server_rekey_final);
3100 sock->protocol = protocol;
3102 if (proto_ctx->pfs == FALSE)
3103 /* Run the protocol */
3104 silc_protocol_execute(protocol, server->schedule, 0, 0);
3107 /* Received file transger packet. This packet is never for us. It is to
3108 the client in the packet's destination ID. Sending of this sort of packet
3109 equals sending private message, ie. it is sent point to point from
3110 one client to another. */
3112 void silc_server_ftp(SilcServer server,
3113 SilcSocketConnection sock,
3114 SilcPacketContext *packet)
3116 SilcSocketConnection dst_sock;
3117 SilcIDListData idata;
3119 SILC_LOG_DEBUG(("Start"));
3121 if (packet->src_id_type != SILC_ID_CLIENT ||
3122 packet->dst_id_type != SILC_ID_CLIENT)
3125 if (!packet->dst_id)
3128 /* Get the route to the client */
3129 dst_sock = silc_server_get_client_route(server, packet->dst_id,
3130 packet->dst_id_len, NULL,
3135 /* Relay the packet */
3136 silc_server_relay_packet(server, dst_sock, idata->send_key,
3137 idata->hmac_send, idata->psn_send++,
3143 SilcSocketConnection sock;
3144 SilcPacketContext *packet;
3146 } *SilcServerResumeResolve;
3148 SILC_SERVER_CMD_FUNC(resume_resolve)
3150 SilcServerResumeResolve r = (SilcServerResumeResolve)context;
3151 SilcServer server = r->server;
3152 SilcSocketConnection sock = r->sock;
3153 SilcServerCommandReplyContext reply = context2;
3154 SilcClientEntry client;
3156 SILC_LOG_DEBUG(("Start"));
3158 if (!reply || !silc_command_get_status(reply->payload, NULL, NULL)) {
3159 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3160 "closing connection", sock->hostname, sock->ip));
3161 silc_server_disconnect_remote(server, sock,
3162 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3163 "Resuming not possible");
3167 if (reply && silc_command_get(reply->payload) == SILC_COMMAND_WHOIS) {
3168 /* Get entry to the client, and resolve it if we don't have it. */
3169 client = silc_idlist_find_client_by_id(server->local_list,
3170 r->data, TRUE, NULL);
3172 client = silc_idlist_find_client_by_id(server->global_list,
3173 r->data, TRUE, NULL);
3175 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3176 "closing connection", sock->hostname, sock->ip));
3177 silc_server_disconnect_remote(server, sock,
3178 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3179 "Resuming not possible");
3184 if (!(client->mode & SILC_UMODE_DETACHED)) {
3185 SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, "
3186 "closing connection", sock->hostname, sock->ip));
3187 silc_server_disconnect_remote(server, sock,
3188 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3189 "Resuming not possible");
3194 /* Reprocess the packet */
3195 silc_server_resume_client(server, sock, r->packet);
3198 silc_socket_free(r->sock);
3199 silc_packet_context_free(r->packet);
3204 /* Received client resuming packet. This is used to resume detached
3205 client session. It can be sent by the client who wishes to resume
3206 but this is also sent by servers and routers to notify other routers
3207 that the client is not detached anymore. */
3209 void silc_server_resume_client(SilcServer server,
3210 SilcSocketConnection sock,
3211 SilcPacketContext *packet)
3213 SilcBuffer buffer = packet->buffer, buf;
3214 SilcIDListData idata;
3215 SilcClientEntry detached_client;
3216 SilcClientID *client_id = NULL;
3217 unsigned char *id_string, *auth = NULL;
3218 SilcUInt16 id_len, auth_len = 0;
3219 int ret, nickfail = 0;
3220 bool resolved, local, nick_change = FALSE, resolve = FALSE;
3221 SilcChannelEntry channel;
3222 SilcHashTableList htl;
3223 SilcChannelClientEntry chl;
3224 SilcServerResumeResolve r;
3226 SILC_LOG_DEBUG(("Start"));
3228 ret = silc_buffer_unformat(buffer,
3229 SILC_STR_UI16_NSTRING(&id_string, &id_len),
3232 client_id = silc_id_str2id(id_string, id_len, SILC_ID_CLIENT);
3234 if (sock->type == SILC_SOCKET_TYPE_CLIENT) {
3235 /* Client send this and is attempting to resume to old client session */
3236 SilcClientEntry client;
3240 silc_buffer_pull(buffer, 2 + id_len);
3241 auth = buffer->data;
3242 auth_len = buffer->len;
3243 silc_buffer_push(buffer, 2 + id_len);
3246 if (!client_id || auth_len < 128) {
3247 SILC_LOG_ERROR(("Client %s (%s) sent incomplete resume information, "
3248 "closing connection", sock->hostname, sock->ip));
3249 silc_server_disconnect_remote(server, sock,
3250 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3251 "Resuming not possible");
3255 /* Take client entry of this connection */
3256 client = (SilcClientEntry)sock->user_data;
3257 idata = (SilcIDListData)client;
3259 /* Get entry to the client, and resolve it if we don't have it. */
3260 detached_client = silc_server_get_client_resolve(server, client_id, FALSE,
3262 if (!detached_client) {
3264 /* The client info is being resolved. Reprocess this packet after
3265 receiving the reply to the query. */
3266 SILC_LOG_DEBUG(("Resolving client"));
3267 r = silc_calloc(1, sizeof(*r));
3271 r->sock = silc_socket_dup(sock);
3272 r->packet = silc_packet_context_dup(packet);
3273 r->data = silc_id_dup(client_id, SILC_ID_CLIENT);
3274 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
3276 silc_server_command_resume_resolve, r);
3278 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3279 "closing connection", sock->hostname, sock->ip));
3280 silc_server_disconnect_remote(server, sock,
3281 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3282 "Resuming not possible");
3287 if (!(detached_client->mode & SILC_UMODE_DETACHED))
3289 if (!silc_hash_table_count(detached_client->channels) &&
3290 detached_client->router)
3292 if (!detached_client->nickname)
3296 if (server->server_type == SILC_SERVER && !server->standalone) {
3297 /* The client info is being resolved. Reprocess this packet after
3298 receiving the reply to the query. */
3299 SILC_LOG_DEBUG(("Resolving client info"));
3300 silc_server_get_client_resolve(server, client_id, TRUE, NULL);
3301 r = silc_calloc(1, sizeof(*r));
3305 r->sock = silc_socket_dup(sock);
3306 r->packet = silc_packet_context_dup(packet);
3307 r->data = silc_id_dup(client_id, SILC_ID_CLIENT);
3308 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
3310 silc_server_command_resume_resolve, r);
3313 if (server->server_type == SILC_SERVER) {
3314 SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, "
3315 "closing connection", sock->hostname, sock->ip));
3316 silc_server_disconnect_remote(server, sock,
3317 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3318 "Resuming not possible");
3323 /* Check that we have the public key of the client, if not then we must
3324 resolve it first. */
3325 if (!detached_client->data.public_key) {
3326 if (server->server_type == SILC_SERVER && server->standalone) {
3327 silc_server_disconnect_remote(server, sock,
3328 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3329 "Resuming not possible");
3331 /* We must retrieve the detached client's public key by sending
3332 GETKEY command. Reprocess this packet after receiving the key */
3333 SilcBuffer idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
3334 SilcSocketConnection dest_sock =
3335 silc_server_get_client_route(server, NULL, 0, client_id, NULL, NULL);
3337 SILC_LOG_DEBUG(("Resolving client public key"));
3339 silc_server_send_command(server, dest_sock ? dest_sock :
3340 server->router->connection,
3341 SILC_COMMAND_GETKEY, ++server->cmd_ident,
3342 1, 1, idp->data, idp->len);
3344 r = silc_calloc(1, sizeof(*r));
3349 r->sock = silc_socket_dup(sock);
3350 r->packet = silc_packet_context_dup(packet);
3351 silc_server_command_pending(server, SILC_COMMAND_GETKEY,
3353 silc_server_command_resume_resolve, r);
3355 silc_buffer_free(idp);
3358 } else if (!silc_pkcs_public_key_compare(detached_client->data.public_key,
3359 idata->public_key)) {
3360 /* We require that the connection and resuming authentication data
3361 must be using same key pair. */
3362 silc_server_disconnect_remote(server, sock,
3363 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3364 "Resuming not possible");
3368 /* Verify the authentication payload. This has to be successful in
3369 order to allow the resuming */
3371 !silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
3372 detached_client->data.public_key, 0,
3373 idata->hash, detached_client->id,
3375 SILC_LOG_ERROR(("Client %s (%s) resume authentication failed, "
3376 "closing connection", sock->hostname, sock->ip));
3377 silc_server_disconnect_remote(server, sock,
3378 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3379 "Resuming not possible");
3383 /* Now resume the client to the network */
3385 silc_schedule_task_del_by_context(server->schedule, detached_client);
3386 sock->user_data = detached_client;
3387 detached_client->connection = sock;
3389 /* Take new keys and stuff into use in the old entry */
3390 silc_idlist_del_data(detached_client);
3391 silc_idlist_add_data(detached_client, idata);
3392 detached_client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
3393 detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
3394 detached_client->mode &= ~SILC_UMODE_DETACHED;
3395 server->stat.my_detached--;
3397 /* Send the RESUME_CLIENT packet to our primary router so that others
3398 know this client isn't detached anymore. */
3399 buf = silc_buffer_alloc_size(2 + id_len);
3400 silc_buffer_format(buf,
3401 SILC_STR_UI_SHORT(id_len),
3402 SILC_STR_UI_XNSTRING(id_string, id_len),
3405 /* Send to primary router */
3406 if (!server->standalone)
3407 silc_server_packet_send(server, server->router->connection,
3408 SILC_PACKET_RESUME_CLIENT, 0,
3409 buf->data, buf->len, TRUE);
3411 /* As router we must deliver this packet directly to the original
3412 server whom this client was earlier. */
3413 if (server->server_type == SILC_ROUTER && detached_client->router &&
3414 detached_client->router->server_type != SILC_ROUTER)
3415 silc_server_packet_send(server, detached_client->router->connection,
3416 SILC_PACKET_RESUME_CLIENT, 0,
3417 buf->data, buf->len, TRUE);
3418 silc_buffer_free(buf);
3420 detached_client->router = NULL;
3422 /* Delete this client entry since we're resuming to old one. */
3423 server->stat.my_clients--;
3424 server->stat.clients--;
3425 if (server->stat.cell_clients)
3426 server->stat.cell_clients--;
3427 silc_server_del_from_watcher_list(server, client);
3428 silc_idlist_del_client(server->local_list, client);
3429 client = detached_client;
3431 /* If the ID is not based in our ID then change it */
3432 if (!SILC_ID_COMPARE(client->id, server->id, server->id->ip.data_len)) {
3433 while (!silc_id_create_client_id(server, server->id, server->rng,
3434 server->md5hash, client->nickname,
3438 silc_server_disconnect_remote(server, sock,
3439 SILC_STATUS_ERR_BAD_NICKNAME, NULL);
3442 snprintf(&client->nickname[strlen(client->nickname) - 1], 1,
3449 /* Notify about Client ID change, nickname doesn't actually change. */
3450 if (!server->standalone)
3451 silc_server_send_notify_nick_change(server, server->router->connection,
3452 FALSE, client->id, client_id,
3456 /* Resolve users on those channels that client has joined but we
3457 haven't resolved user list yet. */
3458 if (server->server_type == SILC_SERVER && !server->standalone) {
3459 silc_hash_table_list(client->channels, &htl);
3460 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
3461 channel = chl->channel;
3462 SILC_LOG_DEBUG(("Resolving users for %s channel",
3463 channel->channel_name));
3464 if (channel->disabled || !channel->users_resolved) {
3465 silc_server_send_command(server, server->router->connection,
3466 SILC_COMMAND_USERS, ++server->cmd_ident,
3467 1, 2, channel->channel_name,
3468 strlen(channel->channel_name));
3471 silc_hash_table_list_reset(&htl);
3474 /* Send the new client ID to the client. After this client may start
3475 receiving other packets, and may start sending packets too. */
3476 silc_server_send_new_id(server, sock, FALSE, client_id, SILC_ID_CLIENT,
3477 silc_id_get_len(client_id, SILC_ID_CLIENT));
3480 /* Send NICK change notify to channels as well. */
3481 SilcBuffer oidp, nidp;
3482 oidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3483 nidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
3484 silc_server_send_notify_on_channels(server, NULL, client,
3485 SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
3486 oidp->data, oidp->len,
3487 nidp->data, nidp->len,
3489 strlen(client->nickname));
3490 silc_buffer_free(oidp);
3491 silc_buffer_free(nidp);
3494 /* Add the client again to the ID cache to get it to correct list */
3495 if (!silc_idcache_del_by_context(server->local_list->clients, client))
3496 silc_idcache_del_by_context(server->global_list->clients, client);
3497 silc_free(client->id);
3498 client->id = client_id;
3500 silc_idcache_add(server->local_list->clients, client->nickname,
3501 client->id, client, 0, NULL);
3503 /* Send some nice info to the client */
3504 silc_server_send_connect_notifys(server, sock, client);
3506 /* Send all channel keys of channels the client has joined */
3507 silc_hash_table_list(client->channels, &htl);
3508 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
3509 bool created = FALSE;
3510 channel = chl->channel;
3512 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY)
3515 /* If we don't have channel key, then create one */
3516 if (!channel->channel_key) {
3517 if (!silc_server_create_channel_key(server, channel, 0))
3522 id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3524 silc_channel_key_payload_encode(silc_id_get_len(channel->id,
3527 strlen(channel->channel_key->
3529 channel->channel_key->cipher->name,
3530 channel->key_len / 8, channel->key);
3531 silc_free(id_string);
3533 /* Send the key packet to client */
3534 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
3535 keyp->data, keyp->len, FALSE);
3537 if (created && server->server_type == SILC_SERVER &&
3538 !server->standalone)
3539 silc_server_packet_send(server, server->router->connection,
3540 SILC_PACKET_CHANNEL_KEY, 0,
3541 keyp->data, keyp->len, FALSE);
3543 silc_buffer_free(keyp);
3545 silc_hash_table_list_reset(&htl);
3547 } else if (sock->type != SILC_SOCKET_TYPE_CLIENT) {
3548 /* Server or router sent this to us to notify that that a client has
3550 SilcServerEntry server_entry;
3551 SilcServerID *server_id;
3556 /* Get entry to the client, and resolve it if we don't have it. */
3557 detached_client = silc_idlist_find_client_by_id(server->local_list,
3558 client_id, TRUE, NULL);
3559 if (!detached_client) {
3560 detached_client = silc_idlist_find_client_by_id(server->global_list,
3561 client_id, TRUE, NULL);
3562 if (!detached_client)
3566 /* Check that the client has not been resumed already because it is
3567 protocol error to attempt to resume more than once. The client
3568 will be killed if this protocol error occurs. */
3569 if (detached_client->data.status & SILC_IDLIST_STATUS_RESUMED &&
3570 !(detached_client->mode & SILC_UMODE_DETACHED)) {
3571 /* The client is clearly attempting to resume more than once and
3572 perhaps playing around by resuming from several different places
3573 at the same time. */
3574 silc_server_kill_client(server, detached_client, NULL,
3575 server->id, SILC_ID_SERVER);
3579 /* Check whether client is detached at all */
3580 if (!(detached_client->mode & SILC_UMODE_DETACHED))
3583 /* Client is detached, and now it is resumed. Remove the detached
3584 mode and mark that it is resumed. */
3585 detached_client->mode &= ~SILC_UMODE_DETACHED;
3586 detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
3588 /* Get the new owner of the resumed client */
3589 server_id = silc_id_str2id(packet->src_id, packet->src_id_len,
3590 packet->src_id_type);
3594 /* Get server entry */
3595 server_entry = silc_idlist_find_server_by_id(server->global_list,
3596 server_id, TRUE, NULL);
3598 if (!server_entry) {
3599 server_entry = silc_idlist_find_server_by_id(server->local_list,
3600 server_id, TRUE, NULL);
3602 if (!server_entry) {
3603 silc_free(server_id);
3608 if (server->server_type == SILC_ROUTER &&
3609 sock->type == SILC_SOCKET_TYPE_ROUTER &&
3610 server_entry->server_type == SILC_ROUTER)
3613 SILC_LOG_DEBUG(("Resuming detached client"));
3615 /* Change the client to correct list. */
3616 if (!silc_idcache_del_by_context(server->local_list->clients,
3618 silc_idcache_del_by_context(server->global_list->clients,
3620 silc_idcache_add(local && server->server_type == SILC_ROUTER ?
3621 server->local_list->clients :
3622 server->global_list->clients,
3623 detached_client->nickname,
3624 detached_client->id, detached_client, FALSE, NULL);
3626 /* Change the owner of the client if needed */
3627 if (detached_client->router != server_entry)
3628 detached_client->router = server_entry;
3630 /* Update channel information regarding global clients on channel. */
3631 if (server->server_type == SILC_SERVER) {
3632 silc_hash_table_list(detached_client->channels, &htl);
3633 while (silc_hash_table_get(&htl, NULL, (void **)&chl))
3634 chl->channel->global_users =
3635 silc_server_channel_has_global(chl->channel);
3636 silc_hash_table_list_reset(&htl);
3639 silc_schedule_task_del_by_context(server->schedule, detached_client);
3641 /* If the sender of this packet is server and we are router we need to
3642 broadcast this packet to other routers in the network. */
3643 if (server->server_type == SILC_ROUTER &&
3644 sock->type == SILC_SOCKET_TYPE_SERVER &&
3645 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
3646 SILC_LOG_DEBUG(("Broadcasting received Resume Client packet"));
3647 if (!server->standalone)
3648 silc_server_packet_send(server, server->router->connection,
3650 packet->flags | SILC_PACKET_FLAG_BROADCAST,
3651 buffer->data, buffer->len, FALSE);
3652 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
3653 packet->type, packet->flags,
3654 packet->buffer->data, packet->buffer->len,
3658 silc_free(server_id);
3661 silc_free(client_id);