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;
238 case SILC_NOTIFY_TYPE_LEAVE:
240 * Distribute the notify to local clients on the channel
242 SILC_LOG_DEBUG(("LEAVE notify"));
245 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
246 packet->dst_id_type);
251 /* Get channel entry */
252 channel = silc_idlist_find_channel_by_id(server->global_list,
255 channel = silc_idlist_find_channel_by_id(server->local_list,
258 silc_free(channel_id);
264 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
266 silc_free(channel_id);
269 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
271 silc_free(channel_id);
275 /* Get client entry */
276 client = silc_idlist_find_client_by_id(server->global_list,
277 client_id, TRUE, NULL);
279 client = silc_idlist_find_client_by_id(server->local_list,
280 client_id, TRUE, NULL);
282 silc_free(client_id);
283 silc_free(channel_id);
287 silc_free(client_id);
289 /* Check if on channel */
290 if (!silc_server_client_on_channel(client, channel, NULL))
293 /* Send the leave notify to channel */
294 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
295 FALSE, packet->buffer->data,
296 packet->buffer->len, FALSE);
298 /* Remove the user from channel */
299 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
302 case SILC_NOTIFY_TYPE_SIGNOFF:
304 * Distribute the notify to local clients on the channel
306 SILC_LOG_DEBUG(("SIGNOFF notify"));
309 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
312 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
316 /* Get client entry */
317 client = silc_idlist_find_client_by_id(server->global_list,
318 client_id, TRUE, &cache);
320 client = silc_idlist_find_client_by_id(server->local_list,
321 client_id, TRUE, &cache);
323 silc_free(client_id);
327 silc_free(client_id);
329 /* Get signoff message */
330 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
334 /* Update statistics */
335 server->stat.clients--;
336 if (server->stat.cell_clients)
337 server->stat.cell_clients--;
338 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
339 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
341 /* Remove the client from all channels. */
342 silc_server_remove_from_channels(server, NULL, client, TRUE, tmp, FALSE);
344 /* Check if anyone is watching this nickname */
345 if (server->server_type == SILC_ROUTER)
346 silc_server_check_watcher_list(server, client, NULL,
347 SILC_NOTIFY_TYPE_SIGNOFF);
349 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
350 cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
353 case SILC_NOTIFY_TYPE_TOPIC_SET:
355 * Distribute the notify to local clients on the channel
358 SILC_LOG_DEBUG(("TOPIC SET notify"));
361 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
364 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
368 /* Get client entry */
369 client = silc_idlist_find_client_by_id(server->global_list,
370 client_id, TRUE, &cache);
372 client = silc_idlist_find_client_by_id(server->local_list,
373 client_id, TRUE, &cache);
375 silc_free(client_id);
379 silc_free(client_id);
382 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
384 silc_free(channel_id);
389 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
390 packet->dst_id_type);
395 /* Get channel entry */
396 channel = silc_idlist_find_channel_by_id(server->global_list,
399 channel = silc_idlist_find_channel_by_id(server->local_list,
402 silc_free(channel_id);
407 if (channel->topic && !strcmp(channel->topic, tmp))
410 /* Get user's channel entry and check that topic set is allowed. */
411 if (!silc_server_client_on_channel(client, channel, &chl))
413 if (channel->mode & SILC_CHANNEL_MODE_TOPIC &&
414 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
415 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
416 SILC_LOG_DEBUG(("Topic change is not allowed"));
420 /* Change the topic */
421 silc_free(channel->topic);
422 channel->topic = strdup(tmp);
424 /* Send the same notify to the channel */
425 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
426 FALSE, packet->buffer->data,
427 packet->buffer->len, FALSE);
428 silc_free(channel_id);
431 case SILC_NOTIFY_TYPE_NICK_CHANGE:
434 * Distribute the notify to local clients on the channel
436 unsigned char *id, *id2;
438 SilcUInt32 nickname_len;
440 SILC_LOG_DEBUG(("NICK CHANGE notify"));
442 /* Get old client ID */
443 id = silc_argument_get_arg_type(args, 1, &tmp_len);
446 client_id = silc_id_payload_parse_id(id, tmp_len, NULL);
450 /* Get new client ID */
451 id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
454 client_id2 = silc_id_payload_parse_id(id2, tmp_len, NULL);
458 SILC_LOG_DEBUG(("Old Client ID id(%s)",
459 silc_id_render(client_id, SILC_ID_CLIENT)));
460 SILC_LOG_DEBUG(("New Client ID id(%s)",
461 silc_id_render(client_id2, SILC_ID_CLIENT)));
463 /* From protocol version 1.1 we also get the new nickname */
464 nickname = silc_argument_get_arg_type(args, 3, &nickname_len);;
466 /* Replace the Client ID */
467 client = silc_idlist_replace_client_id(server,
468 server->global_list, client_id,
469 client_id2, nickname);
471 client = silc_idlist_replace_client_id(server,
472 server->local_list, client_id,
473 client_id2, nickname);
476 /* Send the NICK_CHANGE notify type to local clients on the channels
477 this client is joined to. */
478 silc_server_send_notify_on_channels(server, client, client,
479 SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
480 id, tmp_len, id2, tmp_len,
485 silc_free(client_id);
487 silc_free(client_id2);
491 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
493 * Distribute the notify to local clients on the channel
496 SILC_LOG_DEBUG(("CMODE CHANGE notify"));
499 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
502 client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
506 /* Get client entry */
507 if (id_type == SILC_ID_CLIENT) {
508 client = silc_idlist_find_client_by_id(server->global_list,
509 client_id, TRUE, &cache);
511 client = silc_idlist_find_client_by_id(server->local_list,
512 client_id, TRUE, &cache);
514 silc_free(client_id);
518 silc_free(client_id);
522 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
523 packet->dst_id_type);
528 /* Get channel entry */
529 channel = silc_idlist_find_channel_by_id(server->global_list,
532 channel = silc_idlist_find_channel_by_id(server->local_list,
535 silc_free(channel_id);
539 silc_free(channel_id);
542 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
545 SILC_GET32_MSB(mode, tmp);
547 /* Check if mode changed */
548 if (channel->mode == mode)
551 /* Get user's channel entry and check that mode change is allowed */
553 if (!silc_server_client_on_channel(client, channel, &chl))
555 if (!silc_server_check_cmode_rights(server, channel, chl, mode)) {
556 SILC_LOG_DEBUG(("CMODE change is not allowed"));
560 if (server->server_type == SILC_ROUTER &&
561 channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH &&
562 !(mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
563 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
564 silc_server_send_notify_cmode(server, sock, FALSE, channel,
565 channel->mode, server->id,
570 channel->founder_key);
575 /* Send the same notify to the channel */
576 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
577 FALSE, packet->buffer->data,
578 packet->buffer->len, FALSE);
580 /* If the channel had private keys set and the mode was removed then
581 we must re-generate and re-distribute a new channel key */
582 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY &&
583 !(mode & SILC_CHANNEL_MODE_PRIVKEY)) {
584 /* Re-generate channel key */
585 if (!silc_server_create_channel_key(server, channel, 0))
588 /* Send the channel key. This sends it to our local clients and if
589 we are normal server to our router as well. */
590 silc_server_send_channel_key(server, NULL, channel,
591 server->server_type == SILC_ROUTER ?
592 FALSE : !server->standalone);
596 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
598 unsigned char hash[32];
601 silc_hmac_free(channel->hmac);
602 if (!silc_hmac_alloc(tmp, NULL, &channel->hmac))
605 /* Set the HMAC key out of current channel key. The client must do
607 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key,
608 channel->key_len / 8, hash);
609 silc_hmac_set_key(channel->hmac, hash,
610 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
611 memset(hash, 0, sizeof(hash));
614 /* Get the passphrase */
615 tmp = silc_argument_get_arg_type(args, 5, &tmp_len);
617 silc_free(channel->passphrase);
618 channel->passphrase = silc_memdup(tmp, tmp_len);
621 /* Get founder public key */
622 tmp = silc_argument_get_arg_type(args, 6, &tmp_len);
623 if (tmp && mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
624 if (channel->founder_key)
625 silc_pkcs_public_key_free(channel->founder_key);
626 channel->founder_key = NULL;
627 silc_pkcs_public_key_decode(tmp, tmp_len, &channel->founder_key);
629 if (!channel->founder_key ||
630 (client && client->data.public_key &&
631 server->server_type == SILC_ROUTER &&
632 !silc_pkcs_public_key_compare(channel->founder_key,
633 client->data.public_key))) {
634 /* A really buggy server isn't checking public keys correctly.
635 It's not possible that the mode setter and founder wouldn't
636 have same public key. */
637 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
639 mode &= ~SILC_CHANNEL_MODE_FOUNDER_AUTH;
640 silc_server_send_notify_cmode(server, sock, FALSE, channel,
641 mode, server->id, SILC_ID_SERVER,
644 channel->passphrase, NULL);
645 if (channel->founder_key)
646 silc_pkcs_public_key_free(channel->founder_key);
647 channel->founder_key = NULL;
648 } else if (client && !client->data.public_key) {
649 client->data.public_key =
650 silc_pkcs_public_key_copy(channel->founder_key);
654 if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH && !channel->founder_key &&
655 server->server_type == SILC_ROUTER) {
656 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
657 mode &= ~SILC_CHANNEL_MODE_FOUNDER_AUTH;
658 silc_server_send_notify_cmode(server, sock, FALSE, channel,
659 mode, server->id, SILC_ID_SERVER,
662 channel->passphrase, NULL);
666 channel->mode = mode;
668 if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) &&
669 channel->founder_key) {
670 silc_pkcs_public_key_free(channel->founder_key);
671 channel->founder_key = NULL;
676 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
679 * Distribute the notify to local clients on the channel
681 SilcChannelClientEntry chl2 = NULL;
682 bool notify_sent = FALSE;
684 SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
687 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
690 client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
694 /* Get client entry */
695 if (id_type == SILC_ID_CLIENT) {
696 client = silc_idlist_find_client_by_id(server->global_list,
697 client_id, TRUE, &cache);
699 client = silc_idlist_find_client_by_id(server->local_list,
700 client_id, TRUE, &cache);
702 silc_free(client_id);
706 silc_free(client_id);
710 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
711 packet->dst_id_type);
716 /* Get channel entry */
717 channel = silc_idlist_find_channel_by_id(server->global_list,
720 channel = silc_idlist_find_channel_by_id(server->local_list,
723 silc_free(channel_id);
729 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
731 silc_free(channel_id);
735 SILC_GET32_MSB(mode, tmp);
737 /* Get target client */
738 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
741 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
745 /* Get client entry */
746 client2 = silc_idlist_find_client_by_id(server->global_list,
747 client_id, TRUE, NULL);
749 client2 = silc_idlist_find_client_by_id(server->local_list,
750 client_id, TRUE, NULL);
752 silc_free(client_id);
756 silc_free(client_id);
759 /* Check that sender is on channel */
760 if (!silc_server_client_on_channel(client, channel, &chl))
763 if (client != client2 && server->server_type == SILC_ROUTER) {
764 /* Sender must be operator */
765 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
766 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
767 SILC_LOG_DEBUG(("CUMODE change is not allowed"));
771 if (!silc_server_client_on_channel(client2, channel, &chl))
774 /* If target is founder mode change is not allowed. */
775 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
776 SILC_LOG_DEBUG(("CUMODE change is not allowed"));
782 /* Get target channel entry */
783 if (!silc_server_client_on_channel(client2, channel, &chl))
786 if (mode & SILC_CHANNEL_UMODE_CHANFO &&
787 !(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) && !client &&
788 server->server_type == SILC_ROUTER) {
789 /* Get the founder of the channel and if found then this client
790 cannot be the founder since there already is one. */
791 silc_hash_table_list(channel->user_list, &htl);
792 while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
793 if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
794 mode &= ~SILC_CHANNEL_UMODE_CHANFO;
795 silc_server_force_cumode_change(server, sock, channel, chl, mode);
799 silc_hash_table_list_reset(&htl);
800 if (!(mode & SILC_CHANNEL_UMODE_CHANFO))
804 if (client && mode & SILC_CHANNEL_UMODE_CHANFO &&
805 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO) &&
806 server->server_type == SILC_ROUTER) {
807 /* Check whether this client is allowed to be channel founder on
809 SilcPublicKey founder_key = NULL;
811 /* If channel doesn't have founder auth mode then it's impossible
812 that someone would be getting founder rights with CUMODE command.
813 In that case there already either is founder or there isn't
814 founder at all on the channel. */
815 if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
816 /* Force the mode to not have founder mode */
817 mode &= ~SILC_CHANNEL_UMODE_CHANFO;
818 silc_server_force_cumode_change(server, sock, channel, chl, mode);
823 /* Get the founder of the channel and if found then this client
824 cannot be the founder since there already is one. */
825 silc_hash_table_list(channel->user_list, &htl);
826 while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
827 if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
828 mode &= ~SILC_CHANNEL_UMODE_CHANFO;
829 silc_server_force_cumode_change(server, sock, channel, chl, mode);
833 silc_hash_table_list_reset(&htl);
834 if (!(mode & SILC_CHANNEL_UMODE_CHANFO))
837 /* Founder not found of the channel. Since the founder auth mode
838 is set on the channel now check whether this is the client that
839 originally set the mode. */
841 /* Get public key that must be present in notify */
842 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
843 if (!tmp || !silc_pkcs_public_key_decode(tmp, tmp_len,
845 mode &= ~SILC_CHANNEL_UMODE_CHANFO;
846 silc_server_force_cumode_change(server, sock, channel, chl, mode);
851 /* Now match the public key we have cached and public key sent.
853 if (client->data.public_key &&
854 !silc_pkcs_public_key_compare(channel->founder_key,
855 client->data.public_key)) {
856 mode &= ~SILC_CHANNEL_UMODE_CHANFO;
857 silc_server_force_cumode_change(server, sock, channel, chl, mode);
861 if (!silc_pkcs_public_key_compare(channel->founder_key,
863 mode &= ~SILC_CHANNEL_UMODE_CHANFO;
864 silc_server_force_cumode_change(server, sock, channel, chl, mode);
870 silc_pkcs_public_key_free(founder_key);
873 SILC_LOG_DEBUG(("Changing the channel user mode"));
875 /* Change the mode */
878 /* Send the same notify to the channel */
880 silc_server_packet_send_to_channel(server, sock, channel,
882 FALSE, packet->buffer->data,
883 packet->buffer->len, FALSE);
885 silc_free(channel_id);
889 case SILC_NOTIFY_TYPE_INVITE:
891 if (packet->dst_id_type == SILC_ID_CLIENT)
894 SILC_LOG_DEBUG(("INVITE notify"));
897 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
900 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
904 /* Get channel entry */
905 channel = silc_idlist_find_channel_by_id(server->global_list,
908 channel = silc_idlist_find_channel_by_id(server->local_list,
911 silc_free(channel_id);
915 silc_free(channel_id);
918 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
921 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
925 /* Get client entry */
926 client = silc_idlist_find_client_by_id(server->global_list,
927 client_id, TRUE, &cache);
929 client = silc_idlist_find_client_by_id(server->local_list,
930 client_id, TRUE, &cache);
932 silc_free(client_id);
936 silc_free(client_id);
938 /* Get user's channel entry and check that inviting is allowed. */
939 if (!silc_server_client_on_channel(client, channel, &chl))
941 if (channel->mode & SILC_CHANNEL_MODE_INVITE &&
942 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
943 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
944 SILC_LOG_DEBUG(("Inviting is not allowed"));
948 /* Get the added invite */
949 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
951 if (!channel->invite_list)
952 channel->invite_list = silc_calloc(tmp_len + 2,
953 sizeof(*channel->invite_list));
955 channel->invite_list = silc_realloc(channel->invite_list,
956 sizeof(*channel->invite_list) *
958 strlen(channel->invite_list) +
960 if (tmp[tmp_len - 1] == ',')
961 tmp[tmp_len - 1] = '\0';
963 strncat(channel->invite_list, tmp, tmp_len);
964 strncat(channel->invite_list, ",", 1);
967 /* Get the deleted invite */
968 tmp = silc_argument_get_arg_type(args, 5, &tmp_len);
969 if (tmp && channel->invite_list) {
970 char *start, *end, *n;
972 if (!strncmp(channel->invite_list, tmp,
973 strlen(channel->invite_list) - 1)) {
974 silc_free(channel->invite_list);
975 channel->invite_list = NULL;
977 start = strstr(channel->invite_list, tmp);
978 if (start && strlen(start) >= tmp_len) {
979 end = start + tmp_len;
980 n = silc_calloc(strlen(channel->invite_list) - tmp_len, sizeof(*n));
981 strncat(n, channel->invite_list, start - channel->invite_list);
982 strncat(n, end + 1, ((channel->invite_list +
983 strlen(channel->invite_list)) - end) - 1);
984 silc_free(channel->invite_list);
985 channel->invite_list = n;
992 case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
994 * Distribute to the local clients on the channel and change the
998 SILC_LOG_DEBUG(("CHANNEL CHANGE"));
1000 if (sock->type != SILC_SOCKET_TYPE_ROUTER)
1003 /* Get the old Channel ID */
1004 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1007 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1011 /* Get the channel entry */
1012 channel = silc_idlist_find_channel_by_id(server->local_list,
1015 channel = silc_idlist_find_channel_by_id(server->global_list,
1018 silc_free(channel_id);
1023 /* Send the notify to the channel */
1024 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
1025 FALSE, packet->buffer->data,
1026 packet->buffer->len, FALSE);
1028 /* Get the new Channel ID */
1029 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1032 channel_id2 = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1036 SILC_LOG_DEBUG(("Old Channel ID id(%s)",
1037 silc_id_render(channel_id, SILC_ID_CHANNEL)));
1038 SILC_LOG_DEBUG(("New Channel ID id(%s)",
1039 silc_id_render(channel_id2, SILC_ID_CHANNEL)));
1041 /* Replace the Channel ID */
1042 if (!silc_idlist_replace_channel_id(server->local_list, channel_id,
1044 if (!silc_idlist_replace_channel_id(server->global_list, channel_id,
1046 silc_free(channel_id2);
1051 SilcBuffer modes = NULL, users = NULL, users_modes = NULL;
1053 /* Re-announce this channel which ID was changed. */
1054 silc_server_send_new_channel(server, sock, FALSE, channel->channel_name,
1056 silc_id_get_len(channel->id,
1060 /* Re-announce our clients on the channel as the ID has changed now */
1061 silc_server_announce_get_channel_users(server, channel, &modes, &users,
1064 silc_buffer_push(modes, modes->data - modes->head);
1065 silc_server_packet_send_dest(server, sock,
1066 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1067 channel->id, SILC_ID_CHANNEL,
1068 modes->data, modes->len, FALSE);
1069 silc_buffer_free(modes);
1072 silc_buffer_push(users, users->data - users->head);
1073 silc_server_packet_send(server, sock,
1074 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1075 users->data, users->len, FALSE);
1076 silc_buffer_free(users);
1079 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
1080 silc_server_packet_send_dest(server, sock,
1081 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1082 channel->id, SILC_ID_CHANNEL,
1084 users_modes->len, FALSE);
1085 silc_buffer_free(users_modes);
1088 /* Re-announce channel's topic */
1089 if (channel->topic) {
1090 silc_server_send_notify_topic_set(server, sock,
1091 server->server_type == SILC_ROUTER ?
1092 TRUE : FALSE, channel,
1093 channel->id, SILC_ID_CHANNEL,
1098 silc_free(channel_id);
1102 case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
1104 * Remove the server entry and all clients that this server owns.
1107 SILC_LOG_DEBUG(("SERVER SIGNOFF notify"));
1110 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1113 server_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1117 /* Get server entry */
1118 server_entry = silc_idlist_find_server_by_id(server->global_list,
1119 server_id, TRUE, NULL);
1121 if (!server_entry) {
1122 server_entry = silc_idlist_find_server_by_id(server->local_list,
1123 server_id, TRUE, NULL);
1125 if (!server_entry) {
1126 /* If we are normal server then we might not have the server. Check
1127 whether router was kind enough to send the list of all clients
1128 that actually was to be removed. Remove them if the list is
1130 if (server->server_type != SILC_ROUTER &&
1131 silc_argument_get_arg_num(args) > 1) {
1134 for (i = 1; i < silc_argument_get_arg_num(args); i++) {
1136 tmp = silc_argument_get_arg_type(args, i + 1, &tmp_len);
1139 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1143 /* Get client entry */
1144 client = silc_idlist_find_client_by_id(server->global_list,
1145 client_id, TRUE, &cache);
1148 client = silc_idlist_find_client_by_id(server->local_list,
1149 client_id, TRUE, &cache);
1152 silc_free(client_id);
1156 silc_free(client_id);
1158 /* Update statistics */
1159 server->stat.clients--;
1160 if (server->stat.cell_clients)
1161 server->stat.cell_clients--;
1162 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
1163 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
1165 /* Remove the client from all channels. */
1166 silc_server_remove_from_channels(server, NULL, client,
1169 /* Check if anyone is watching this nickname */
1170 if (server->server_type == SILC_ROUTER)
1171 silc_server_check_watcher_list(server, client, NULL,
1172 SILC_NOTIFY_TYPE_SERVER_SIGNOFF);
1174 /* Remove this client from watcher list if it is */
1176 silc_server_del_from_watcher_list(server, client);
1178 /* Remove the client */
1179 silc_idlist_del_client(local ? server->local_list :
1180 server->global_list, client);
1184 silc_free(server_id);
1188 silc_free(server_id);
1190 /* Free all client entries that this server owns as they will
1191 become invalid now as well. */
1192 silc_server_remove_clients_by_server(server, server_entry, TRUE);
1194 /* Remove the server entry */
1195 silc_idlist_del_server(local ? server->local_list :
1196 server->global_list, server_entry);
1198 /* XXX update statistics */
1202 case SILC_NOTIFY_TYPE_KICKED:
1204 * Distribute the notify to local clients on the channel
1207 SILC_LOG_DEBUG(("KICKED notify"));
1210 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
1211 packet->dst_id_type);
1216 /* Get channel entry */
1217 channel = silc_idlist_find_channel_by_id(server->global_list,
1220 channel = silc_idlist_find_channel_by_id(server->local_list,
1223 silc_free(channel_id);
1227 silc_free(channel_id);
1230 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1233 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1237 /* If the the client is not in local list we check global list */
1238 client = silc_idlist_find_client_by_id(server->global_list,
1239 client_id, TRUE, NULL);
1241 client = silc_idlist_find_client_by_id(server->local_list,
1242 client_id, TRUE, NULL);
1244 silc_free(client_id);
1248 silc_free(client_id);
1250 /* If target is founder they cannot be kicked */
1251 if (!silc_server_client_on_channel(client, channel, &chl))
1253 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO)
1256 /* From protocol version 1.1 we get the kicker's ID as well. */
1257 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1259 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1263 /* If the the client is not in local list we check global list */
1264 client2 = silc_idlist_find_client_by_id(server->global_list,
1265 client_id, TRUE, NULL);
1267 client2 = silc_idlist_find_client_by_id(server->local_list,
1268 client_id, TRUE, NULL);
1270 silc_free(client_id);
1274 silc_free(client_id);
1276 /* Kicker must be operator on channel */
1277 if (!silc_server_client_on_channel(client2, channel, &chl))
1279 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
1280 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1281 SILC_LOG_DEBUG(("Kicking is not allowed"));
1286 /* Send to channel */
1287 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
1288 FALSE, packet->buffer->data,
1289 packet->buffer->len, FALSE);
1291 /* Remove the client from channel */
1292 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
1296 case SILC_NOTIFY_TYPE_KILLED:
1299 * Distribute the notify to local clients on channels
1301 unsigned char *id, *comment;
1302 SilcUInt32 id_len, comment_len;
1304 SILC_LOG_DEBUG(("KILLED notify"));
1307 id = silc_argument_get_arg_type(args, 1, &id_len);
1310 client_id = silc_id_payload_parse_id(id, id_len, NULL);
1314 /* If the the client is not in local list we check global list */
1315 client = silc_idlist_find_client_by_id(server->global_list,
1316 client_id, TRUE, NULL);
1318 client = silc_idlist_find_client_by_id(server->local_list,
1319 client_id, TRUE, NULL);
1321 silc_free(client_id);
1325 silc_free(client_id);
1327 /* If the client is one of ours, then close the connection to the
1328 client now. This removes the client from all channels as well. */
1329 if (packet->dst_id_type == SILC_ID_CLIENT && client->connection) {
1330 sock = client->connection;
1331 silc_server_free_client_data(server, NULL, client, FALSE, NULL);
1332 silc_server_close_connection(server, sock);
1337 comment = silc_argument_get_arg_type(args, 2, &comment_len);
1338 if (comment_len > 128)
1341 /* From protocol version 1.1 we get the killer's ID as well. */
1342 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1344 client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
1348 if (id_type == SILC_ID_CLIENT) {
1349 /* If the the client is not in local list we check global list */
1350 client2 = silc_idlist_find_client_by_id(server->global_list,
1351 client_id, TRUE, NULL);
1353 client2 = silc_idlist_find_client_by_id(server->local_list,
1354 client_id, TRUE, NULL);
1356 silc_free(client_id);
1360 silc_free(client_id);
1362 /* Killer must be router operator */
1363 if (!(client2->mode & SILC_UMODE_ROUTER_OPERATOR)) {
1364 SILC_LOG_DEBUG(("Killing is not allowed"));
1370 /* Send the notify to local clients on the channels except to the
1371 client who is killed. */
1372 silc_server_send_notify_on_channels(server, client, client,
1373 SILC_NOTIFY_TYPE_KILLED, 3,
1374 id, id_len, comment, comment_len,
1377 /* Remove the client from all channels */
1378 silc_server_remove_from_channels(server, NULL, client, FALSE, NULL,
1381 /* Check if anyone is watching this nickname */
1382 if (server->server_type == SILC_ROUTER)
1383 silc_server_check_watcher_list(server, client, NULL,
1384 SILC_NOTIFY_TYPE_KILLED);
1389 case SILC_NOTIFY_TYPE_UMODE_CHANGE:
1391 * Save the mode of the client.
1394 SILC_LOG_DEBUG(("UMODE_CHANGE notify"));
1397 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1400 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1404 /* Get client entry */
1405 client = silc_idlist_find_client_by_id(server->global_list,
1406 client_id, TRUE, NULL);
1408 client = silc_idlist_find_client_by_id(server->local_list,
1409 client_id, TRUE, NULL);
1411 silc_free(client_id);
1415 silc_free(client_id);
1418 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1421 SILC_GET32_MSB(mode, tmp);
1423 /* Check that mode changing is allowed. */
1424 if (!silc_server_check_umode_rights(server, client, mode)) {
1425 SILC_LOG_DEBUG(("UMODE change is not allowed"));
1429 /* Remove internal resumed flag if client is marked detached now */
1430 if (mode & SILC_UMODE_DETACHED)
1431 client->data.status &= ~SILC_IDLIST_STATUS_RESUMED;
1433 /* Change the mode */
1434 client->mode = mode;
1436 /* Check if anyone is watching this nickname */
1437 if (server->server_type == SILC_ROUTER)
1438 silc_server_check_watcher_list(server, client, NULL,
1439 SILC_NOTIFY_TYPE_UMODE_CHANGE);
1443 case SILC_NOTIFY_TYPE_BAN:
1448 SILC_LOG_DEBUG(("BAN notify"));
1450 /* Get Channel ID */
1451 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1454 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1458 /* Get channel entry */
1459 channel = silc_idlist_find_channel_by_id(server->global_list,
1462 channel = silc_idlist_find_channel_by_id(server->local_list,
1465 silc_free(channel_id);
1469 silc_free(channel_id);
1471 /* Get the new ban and add it to the ban list */
1472 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1474 if (!channel->ban_list)
1475 channel->ban_list = silc_calloc(tmp_len + 2,
1476 sizeof(*channel->ban_list));
1478 channel->ban_list = silc_realloc(channel->ban_list,
1479 sizeof(*channel->ban_list) *
1481 strlen(channel->ban_list) + 2));
1482 strncat(channel->ban_list, tmp, tmp_len);
1483 strncat(channel->ban_list, ",", 1);
1486 /* Get the ban to be removed and remove it from the list */
1487 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1488 if (tmp && channel->ban_list) {
1489 char *start, *end, *n;
1491 if (!strncmp(channel->ban_list, tmp, strlen(channel->ban_list) - 1)) {
1492 silc_free(channel->ban_list);
1493 channel->ban_list = NULL;
1495 start = strstr(channel->ban_list, tmp);
1496 if (start && strlen(start) >= tmp_len) {
1497 end = start + tmp_len;
1498 n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
1499 strncat(n, channel->ban_list, start - channel->ban_list);
1500 strncat(n, end + 1, ((channel->ban_list +
1501 strlen(channel->ban_list)) - end) - 1);
1502 silc_free(channel->ban_list);
1503 channel->ban_list = n;
1509 case SILC_NOTIFY_TYPE_ERROR:
1516 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1517 if (!tmp && tmp_len != 1)
1519 error = (SilcStatus)tmp[0];
1521 SILC_LOG_DEBUG(("ERROR notify (%d)", error));
1523 if (error == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID &&
1524 sock->type == SILC_SOCKET_TYPE_ROUTER) {
1525 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1527 SILC_LOG_DEBUG(("Received invalid client ID notification, deleting "
1528 "the entry from cache"));
1529 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1532 client = silc_idlist_find_client_by_id(server->global_list,
1533 client_id, FALSE, NULL);
1535 silc_server_remove_from_channels(server, NULL, client, TRUE,
1537 silc_idlist_del_client(server->global_list, client);
1539 silc_free(client_id);
1545 /* Ignore rest of the notify types for now */
1546 case SILC_NOTIFY_TYPE_NONE:
1547 case SILC_NOTIFY_TYPE_MOTD:
1554 silc_notify_payload_free(payload);
1557 void silc_server_notify_list(SilcServer server,
1558 SilcSocketConnection sock,
1559 SilcPacketContext *packet)
1561 SilcPacketContext *new;
1565 SILC_LOG_DEBUG(("Processing Notify List"));
1567 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1568 packet->src_id_type != SILC_ID_SERVER)
1571 /* Make copy of the original packet context, except for the actual
1572 data buffer, which we will here now fetch from the original buffer. */
1573 new = silc_packet_context_alloc();
1574 new->type = SILC_PACKET_NOTIFY;
1575 new->flags = packet->flags;
1576 new->src_id = packet->src_id;
1577 new->src_id_len = packet->src_id_len;
1578 new->src_id_type = packet->src_id_type;
1579 new->dst_id = packet->dst_id;
1580 new->dst_id_len = packet->dst_id_len;
1581 new->dst_id_type = packet->dst_id_type;
1583 buffer = silc_buffer_alloc(1024);
1584 new->buffer = buffer;
1586 while (packet->buffer->len) {
1587 SILC_GET16_MSB(len, packet->buffer->data + 2);
1588 if (len > packet->buffer->len)
1591 if (len > buffer->truelen) {
1592 silc_buffer_free(buffer);
1593 buffer = silc_buffer_alloc(1024 + len);
1596 silc_buffer_pull_tail(buffer, len);
1597 silc_buffer_put(buffer, packet->buffer->data, len);
1599 /* Process the Notify */
1600 silc_server_notify(server, sock, new);
1602 silc_buffer_push_tail(buffer, len);
1603 silc_buffer_pull(packet->buffer, len);
1606 silc_buffer_free(buffer);
1610 /* Received private message. This resolves the destination of the message
1611 and sends the packet. This is used by both server and router. If the
1612 destination is our locally connected client this sends the packet to
1613 the client. This may also send the message for further routing if
1614 the destination is not in our server (or router). */
1616 void silc_server_private_message(SilcServer server,
1617 SilcSocketConnection sock,
1618 SilcPacketContext *packet)
1620 SilcSocketConnection dst_sock;
1621 SilcIDListData idata;
1622 SilcClientEntry client;
1624 SILC_LOG_DEBUG(("Start"));
1626 if (packet->src_id_type != SILC_ID_CLIENT ||
1627 packet->dst_id_type != SILC_ID_CLIENT || !packet->dst_id)
1630 /* Get the route to the client */
1631 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1632 packet->dst_id_len, NULL,
1636 unsigned char error;
1638 if (client && client->mode & SILC_UMODE_DETACHED) {
1639 SILC_LOG_DEBUG(("Client is detached, discarding packet"));
1643 /* Send SILC_NOTIFY_TYPE_ERROR to indicate that such destination ID
1644 does not exist or is invalid. */
1645 idp = silc_id_payload_encode_data(packet->dst_id,
1647 packet->dst_id_type);
1651 error = SILC_STATUS_ERR_NO_SUCH_CLIENT_ID;
1652 if (packet->src_id_type == SILC_ID_CLIENT) {
1653 SilcClientID *client_id = silc_id_str2id(packet->src_id,
1655 packet->src_id_type);
1656 silc_server_send_notify_dest(server, sock, FALSE,
1657 client_id, SILC_ID_CLIENT,
1658 SILC_NOTIFY_TYPE_ERROR, 2,
1660 idp->data, idp->len);
1661 silc_free(client_id);
1663 silc_server_send_notify(server, sock, FALSE,
1664 SILC_NOTIFY_TYPE_ERROR, 2,
1666 idp->data, idp->len);
1669 silc_buffer_free(idp);
1673 /* Check whether destination client wishes to receive private messages */
1674 if (client && !(packet->flags & SILC_PACKET_FLAG_PRIVMSG_KEY) &&
1675 client->mode & SILC_UMODE_BLOCK_PRIVMSG) {
1676 SILC_LOG_DEBUG(("Client blocks private messages, discarding packet"));
1680 /* Send the private message */
1681 silc_server_send_private_message(server, dst_sock, idata->send_key,
1682 idata->hmac_send, idata->psn_send++,
1686 /* Received private message key packet.. This packet is never for us. It is to
1687 the client in the packet's destination ID. Sending of this sort of packet
1688 equals sending private message, ie. it is sent point to point from
1689 one client to another. */
1691 void silc_server_private_message_key(SilcServer server,
1692 SilcSocketConnection sock,
1693 SilcPacketContext *packet)
1695 SilcSocketConnection dst_sock;
1696 SilcIDListData idata;
1698 SILC_LOG_DEBUG(("Start"));
1700 if (packet->src_id_type != SILC_ID_CLIENT ||
1701 packet->dst_id_type != SILC_ID_CLIENT)
1704 if (!packet->dst_id)
1707 /* Get the route to the client */
1708 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1709 packet->dst_id_len, NULL,
1714 /* Relay the packet */
1715 silc_server_relay_packet(server, dst_sock, idata->send_key,
1716 idata->hmac_send, idata->psn_send++, packet, FALSE);
1719 /* Processes incoming command reply packet. The command reply packet may
1720 be destined to one of our clients or it may directly for us. We will
1721 call the command reply routine after processing the packet. */
1723 void silc_server_command_reply(SilcServer server,
1724 SilcSocketConnection sock,
1725 SilcPacketContext *packet)
1727 SilcBuffer buffer = packet->buffer;
1728 SilcClientEntry client = NULL;
1729 SilcSocketConnection dst_sock;
1730 SilcIDListData idata;
1731 SilcClientID *id = NULL;
1733 SILC_LOG_DEBUG(("Start"));
1735 /* Source must be server or router */
1736 if (packet->src_id_type != SILC_ID_SERVER &&
1737 sock->type != SILC_SOCKET_TYPE_ROUTER)
1740 if (packet->dst_id_type == SILC_ID_CHANNEL)
1743 if (packet->dst_id_type == SILC_ID_CLIENT) {
1744 /* Destination must be one of ours */
1745 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
1748 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
1750 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
1756 if (packet->dst_id_type == SILC_ID_SERVER) {
1757 /* For now this must be for us */
1758 if (memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
1759 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
1764 /* Execute command reply locally for the command */
1765 silc_server_command_reply_process(server, sock, buffer);
1767 if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
1768 /* Relay the packet to the client */
1769 const SilcBufferStruct p;
1771 dst_sock = (SilcSocketConnection)client->connection;
1772 idata = (SilcIDListData)client;
1774 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
1775 + packet->dst_id_len + packet->padlen);
1776 if (!silc_packet_send_prepare(dst_sock, 0, 0, buffer->len,
1777 idata->hmac_send, (const SilcBuffer)&p)) {
1778 SILC_LOG_ERROR(("Cannot send packet"));
1781 silc_buffer_put((SilcBuffer)&p, buffer->data, buffer->len);
1783 /* Encrypt packet */
1784 silc_packet_encrypt(idata->send_key, idata->hmac_send, idata->psn_send++,
1785 (SilcBuffer)&p, buffer->len);
1787 /* Send the packet */
1788 silc_server_packet_send_real(server, dst_sock, TRUE);
1794 /* Process received channel message. The message can be originated from
1795 client or server. */
1797 void silc_server_channel_message(SilcServer server,
1798 SilcSocketConnection sock,
1799 SilcPacketContext *packet)
1801 SilcChannelEntry channel = NULL;
1802 SilcChannelID *id = NULL;
1803 void *sender_id = NULL;
1804 SilcClientEntry sender_entry = NULL;
1805 SilcChannelClientEntry chl;
1808 SILC_LOG_DEBUG(("Processing channel message"));
1811 if (packet->dst_id_type != SILC_ID_CHANNEL) {
1812 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1816 /* Find channel entry */
1817 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
1820 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
1822 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
1825 unsigned char error;
1827 /* Send SILC_NOTIFY_TYPE_ERROR to indicate that such destination ID
1828 does not exist or is invalid. */
1829 idp = silc_id_payload_encode_data(packet->dst_id,
1831 packet->dst_id_type);
1835 error = SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID;
1836 if (packet->src_id_type == SILC_ID_CLIENT) {
1837 SilcClientID *client_id = silc_id_str2id(packet->src_id,
1839 packet->src_id_type);
1840 silc_server_send_notify_dest(server, sock, FALSE,
1841 client_id, SILC_ID_CLIENT,
1842 SILC_NOTIFY_TYPE_ERROR, 2,
1843 &error, 1, idp->data, idp->len);
1844 silc_free(client_id);
1846 silc_server_send_notify(server, sock, FALSE,
1847 SILC_NOTIFY_TYPE_ERROR, 2,
1848 &error, 1, idp->data, idp->len);
1851 silc_buffer_free(idp);
1856 /* See that this client is on the channel. If the original sender is
1857 not client (as it can be server as well) we don't do the check. */
1858 sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1859 packet->src_id_type);
1862 if (packet->src_id_type == SILC_ID_CLIENT) {
1863 sender_entry = silc_idlist_find_client_by_id(server->local_list,
1864 sender_id, TRUE, NULL);
1865 if (!sender_entry) {
1867 sender_entry = silc_idlist_find_client_by_id(server->global_list,
1868 sender_id, TRUE, NULL);
1870 if (!sender_entry || !silc_server_client_on_channel(sender_entry,
1872 SILC_LOG_DEBUG(("Client not on channel"));
1876 /* If channel is moderated check that client is allowed to send
1878 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS &&
1879 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
1880 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1881 SILC_LOG_DEBUG(("Channel is silenced from normal users"));
1884 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS &&
1885 chl->mode & SILC_CHANNEL_UMODE_CHANOP &&
1886 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1887 SILC_LOG_DEBUG(("Channel is silenced from operators"));
1891 /* If the packet is coming from router, but the client entry is local
1892 entry to us then some router is rerouting this to us and it is not
1893 allowed. When the client is local to us it means that we've routed
1894 this packet to network, and now someone is routing it back to us. */
1895 if (server->server_type == SILC_ROUTER &&
1896 sock->type == SILC_SOCKET_TYPE_ROUTER && local) {
1897 SILC_LOG_DEBUG(("Channel message rerouted to the sender, drop it"));
1902 /* Distribute the packet to our local clients. This will send the
1903 packet for further routing as well, if needed. */
1904 silc_server_packet_relay_to_channel(server, sock, channel, sender_id,
1905 packet->src_id_type, sender_entry,
1906 packet->buffer->data,
1907 packet->buffer->len, FALSE);
1910 silc_free(sender_id);
1914 /* Received channel key packet. We distribute the key to all of our locally
1915 connected clients on the channel. */
1917 void silc_server_channel_key(SilcServer server,
1918 SilcSocketConnection sock,
1919 SilcPacketContext *packet)
1921 SilcBuffer buffer = packet->buffer;
1922 SilcChannelEntry channel;
1924 if (packet->src_id_type != SILC_ID_SERVER ||
1925 (server->server_type == SILC_ROUTER &&
1926 sock->type == SILC_SOCKET_TYPE_ROUTER))
1929 /* Save the channel key */
1930 channel = silc_server_save_channel_key(server, buffer, NULL);
1934 /* Distribute the key to everybody who is on the channel. If we are router
1935 we will also send it to locally connected servers. */
1936 silc_server_send_channel_key(server, sock, channel, FALSE);
1938 if (server->server_type != SILC_BACKUP_ROUTER) {
1939 /* Distribute to local cell backup routers. */
1940 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
1941 SILC_PACKET_CHANNEL_KEY, 0,
1942 buffer->data, buffer->len, FALSE, TRUE);
1946 /* Received New Client packet and processes it. Creates Client ID for the
1947 client. Client becomes registered after calling this functions. */
1949 SilcClientEntry silc_server_new_client(SilcServer server,
1950 SilcSocketConnection sock,
1951 SilcPacketContext *packet)
1953 SilcBuffer buffer = packet->buffer;
1954 SilcClientEntry client;
1955 SilcClientID *client_id;
1956 SilcIDListData idata;
1957 char *username = NULL, *realname = NULL;
1958 SilcUInt16 username_len;
1961 char *hostname, *nickname;
1964 SILC_LOG_DEBUG(("Creating new client"));
1966 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
1969 /* Take client entry */
1970 client = (SilcClientEntry)sock->user_data;
1971 idata = (SilcIDListData)client;
1973 /* Remove the old cache entry. */
1974 if (!silc_idcache_del_by_context(server->local_list->clients, client)) {
1975 SILC_LOG_INFO(("Unauthenticated client attempted to register to network"));
1976 silc_server_disconnect_remote(server, sock,
1977 SILC_STATUS_ERR_NOT_AUTHENTICATED, NULL);
1978 if (sock->user_data)
1979 silc_server_free_sock_user_data(server, sock, NULL);
1983 /* Parse incoming packet */
1984 ret = silc_buffer_unformat(buffer,
1985 SILC_STR_UI16_NSTRING_ALLOC(&username,
1987 SILC_STR_UI16_STRING_ALLOC(&realname),
1990 silc_free(username);
1991 silc_free(realname);
1992 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
1993 "connection", sock->hostname, sock->ip));
1994 silc_server_disconnect_remote(server, sock,
1995 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
1997 if (sock->user_data)
1998 silc_server_free_sock_user_data(server, sock, NULL);
2003 silc_free(username);
2004 silc_free(realname);
2005 SILC_LOG_ERROR(("Client %s (%s) did not send its username, closing "
2006 "connection", sock->hostname, sock->ip));
2007 silc_server_disconnect_remote(server, sock,
2008 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2010 if (sock->user_data)
2011 silc_server_free_sock_user_data(server, sock, NULL);
2015 if (username_len > 128)
2016 username[128] = '\0';
2018 /* Check for bad characters for nickname, and modify the nickname if
2019 it includes those. */
2020 if (silc_server_name_bad_chars(username, username_len)) {
2021 nickname = silc_server_name_modify_bad(username, username_len);
2023 nickname = strdup(username);
2026 /* Make sanity checks for the hostname of the client. If the hostname
2027 is provided in the `username' check that it is the same than the
2028 resolved hostname, or if not resolved the hostname that appears in
2029 the client's public key. If the hostname is not present then put
2030 it from the resolved name or from the public key. */
2031 if (strchr(username, '@')) {
2032 SilcPublicKeyIdentifier pident;
2033 int tlen = strcspn(username, "@");
2034 char *phostname = NULL;
2036 hostname = silc_memdup(username + tlen + 1, strlen(username) - tlen - 1);
2038 if (strcmp(sock->hostname, sock->ip) &&
2039 strcmp(sock->hostname, hostname)) {
2040 silc_free(username);
2041 silc_free(hostname);
2042 silc_free(realname);
2043 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2044 "connection", sock->hostname, sock->ip));
2045 silc_server_disconnect_remote(server, sock,
2046 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2048 if (sock->user_data)
2049 silc_server_free_sock_user_data(server, sock, NULL);
2053 pident = silc_pkcs_decode_identifier(client->data.public_key->identifier);
2055 phostname = strdup(pident->host);
2056 silc_pkcs_free_identifier(pident);
2059 if (!strcmp(sock->hostname, sock->ip) &&
2060 phostname && strcmp(phostname, hostname)) {
2061 silc_free(username);
2062 silc_free(hostname);
2063 silc_free(phostname);
2064 silc_free(realname);
2065 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2066 "connection", sock->hostname, sock->ip));
2067 silc_server_disconnect_remote(server, sock,
2068 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2070 if (sock->user_data)
2071 silc_server_free_sock_user_data(server, sock, NULL);
2075 silc_free(phostname);
2077 /* The hostname is not present, add it. */
2079 /* XXX For now we cannot take the host name from the public key since
2080 they are not trusted or we cannot verify them as trusted. Just take
2081 what the resolved name or address is. */
2083 if (strcmp(sock->hostname, sock->ip)) {
2085 newusername = silc_calloc(strlen(username) +
2086 strlen(sock->hostname) + 2,
2087 sizeof(*newusername));
2088 strncat(newusername, username, strlen(username));
2089 strncat(newusername, "@", 1);
2090 strncat(newusername, sock->hostname, strlen(sock->hostname));
2091 silc_free(username);
2092 username = newusername;
2095 SilcPublicKeyIdentifier pident =
2096 silc_pkcs_decode_identifier(client->data.public_key->identifier);
2099 newusername = silc_calloc(strlen(username) +
2100 strlen(pident->host) + 2,
2101 sizeof(*newusername));
2102 strncat(newusername, username, strlen(username));
2103 strncat(newusername, "@", 1);
2104 strncat(newusername, pident->host, strlen(pident->host));
2105 silc_free(username);
2106 username = newusername;
2107 silc_pkcs_free_identifier(pident);
2113 /* Create Client ID */
2114 while (!silc_id_create_client_id(server, server->id, server->rng,
2115 server->md5hash, nickname, &client_id)) {
2118 silc_server_disconnect_remote(server, sock,
2119 SILC_STATUS_ERR_BAD_NICKNAME, NULL);
2120 if (sock->user_data)
2121 silc_server_free_sock_user_data(server, sock, NULL);
2124 snprintf(&nickname[strlen(nickname) - 1], 1, "%d", nickfail);
2127 /* Update client entry */
2128 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
2129 client->nickname = nickname;
2130 client->username = username;
2131 client->userinfo = realname ? realname : strdup(" ");
2132 client->id = client_id;
2133 id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
2135 /* Add the client again to the ID cache */
2136 silc_idcache_add(server->local_list->clients, client->nickname,
2137 client_id, client, 0, NULL);
2139 /* Notify our router about new client on the SILC network */
2140 if (!server->standalone)
2141 silc_server_send_new_id(server, (SilcSocketConnection)
2142 server->router->connection,
2143 server->server_type == SILC_ROUTER ? TRUE : FALSE,
2144 client->id, SILC_ID_CLIENT, id_len);
2146 /* Distribute to backup routers */
2147 if (server->server_type == SILC_ROUTER) {
2148 SilcBuffer idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
2149 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_ID, 0,
2150 idp->data, idp->len, FALSE, TRUE);
2151 silc_buffer_free(idp);
2154 /* Send the new client ID to the client. */
2155 silc_server_send_new_id(server, sock, FALSE, client->id, SILC_ID_CLIENT,
2156 silc_id_get_len(client->id, SILC_ID_CLIENT));
2158 /* Send some nice info to the client */
2159 silc_server_send_connect_notifys(server, sock, client);
2161 /* Check if anyone is watching this nickname */
2162 if (server->server_type == SILC_ROUTER)
2163 silc_server_check_watcher_list(server, client, NULL, 0);
2168 /* Create new server. This processes received New Server packet and
2169 saves the received Server ID. The server is our locally connected
2170 server thus we save all the information and save it to local list.
2171 This funtion can be used by both normal server and router server.
2172 If normal server uses this it means that its router has connected
2173 to the server. If router uses this it means that one of the cell's
2174 servers is connected to the router. */
2176 SilcServerEntry silc_server_new_server(SilcServer server,
2177 SilcSocketConnection sock,
2178 SilcPacketContext *packet)
2180 SilcBuffer buffer = packet->buffer;
2181 SilcServerEntry new_server, server_entry;
2182 SilcServerID *server_id;
2183 SilcIDListData idata;
2184 unsigned char *server_name, *id_string;
2185 SilcUInt16 id_len, name_len;
2189 SILC_LOG_DEBUG(("Creating new server"));
2191 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
2192 sock->type != SILC_SOCKET_TYPE_ROUTER)
2195 /* Take server entry */
2196 new_server = (SilcServerEntry)sock->user_data;
2197 idata = (SilcIDListData)new_server;
2199 /* Remove the old cache entry */
2200 if (!silc_idcache_del_by_context(server->local_list->servers, new_server)) {
2201 if (!silc_idcache_del_by_context(server->global_list->servers,
2203 SILC_LOG_INFO(("Unauthenticated %s attempted to register to "
2204 "network", (sock->type == SILC_SOCKET_TYPE_SERVER ?
2205 "server" : "router")));
2206 silc_server_disconnect_remote(server, sock,
2207 SILC_STATUS_ERR_NOT_AUTHENTICATED, NULL);
2208 if (sock->user_data)
2209 silc_server_free_sock_user_data(server, sock, NULL);
2215 /* Parse the incoming packet */
2216 ret = silc_buffer_unformat(buffer,
2217 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
2218 SILC_STR_UI16_NSTRING_ALLOC(&server_name,
2222 silc_free(id_string);
2223 silc_free(server_name);
2224 silc_server_disconnect_remote(server, sock,
2225 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2227 if (sock->user_data)
2228 silc_server_free_sock_user_data(server, sock, NULL);
2232 if (id_len > buffer->len) {
2233 silc_free(id_string);
2234 silc_free(server_name);
2235 silc_server_disconnect_remote(server, sock,
2236 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2238 if (sock->user_data)
2239 silc_server_free_sock_user_data(server, sock, NULL);
2244 server_name[255] = '\0';
2247 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
2249 silc_free(id_string);
2250 silc_free(server_name);
2251 silc_server_disconnect_remote(server, sock,
2252 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2254 if (sock->user_data)
2255 silc_server_free_sock_user_data(server, sock, NULL);
2258 silc_free(id_string);
2260 /* Check for valid server ID */
2261 if (!silc_id_is_valid_server_id(server, server_id, sock)) {
2262 SILC_LOG_INFO(("Invalid server ID sent by %s (%s)",
2263 sock->ip, sock->hostname));
2264 silc_server_disconnect_remote(server, sock,
2265 SILC_STATUS_ERR_BAD_SERVER_ID, NULL);
2266 if (sock->user_data)
2267 silc_server_free_sock_user_data(server, sock, NULL);
2268 silc_free(server_name);
2272 /* Check that we do not have this ID already */
2273 server_entry = silc_idlist_find_server_by_id(server->local_list,
2274 server_id, TRUE, NULL);
2276 silc_idcache_del_by_context(server->local_list->servers, server_entry);
2278 server_entry = silc_idlist_find_server_by_id(server->global_list,
2279 server_id, TRUE, NULL);
2281 silc_idcache_del_by_context(server->global_list->servers, server_entry);
2284 /* Update server entry */
2285 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
2286 new_server->server_name = server_name;
2287 new_server->id = server_id;
2289 SILC_LOG_DEBUG(("New server id(%s)",
2290 silc_id_render(server_id, SILC_ID_SERVER)));
2292 /* Add again the entry to the ID cache. */
2293 silc_idcache_add(local ? server->local_list->servers :
2294 server->global_list->servers, server_name, server_id,
2295 new_server, 0, NULL);
2297 /* Distribute the information about new server in the SILC network
2298 to our router. If we are normal server we won't send anything
2299 since this connection must be our router connection. */
2300 if (server->server_type == SILC_ROUTER && !server->standalone &&
2301 server->router->connection != sock)
2302 silc_server_send_new_id(server, server->router->connection,
2303 TRUE, new_server->id, SILC_ID_SERVER,
2304 silc_id_get_len(server_id, SILC_ID_SERVER));
2306 if (server->server_type == SILC_ROUTER) {
2307 /* Distribute to backup routers */
2308 SilcBuffer idp = silc_id_payload_encode(new_server->id, SILC_ID_SERVER);
2309 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_ID, 0,
2310 idp->data, idp->len, FALSE, TRUE);
2311 silc_buffer_free(idp);
2314 server->stat.cell_servers++;
2317 /* Check whether this router connection has been replaced by an
2318 backup router. If it has been then we'll disable the server and will
2319 ignore everything it will send until the backup router resuming
2320 protocol has been completed. */
2321 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
2322 silc_server_backup_replaced_get(server, server_id, NULL)) {
2323 /* Send packet to the server indicating that it cannot use this
2324 connection as it has been replaced by backup router. */
2325 SilcBuffer packet = silc_buffer_alloc(2);
2326 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
2327 silc_buffer_format(packet,
2328 SILC_STR_UI_CHAR(SILC_SERVER_BACKUP_REPLACED),
2329 SILC_STR_UI_CHAR(0),
2331 silc_server_packet_send(server, sock,
2332 SILC_PACKET_RESUME_ROUTER, 0,
2333 packet->data, packet->len, TRUE);
2334 silc_buffer_free(packet);
2336 /* Mark the router disabled. The data sent earlier will go but nothing
2337 after this does not go to this connection. */
2338 idata->status |= SILC_IDLIST_STATUS_DISABLED;
2340 /* If it is router announce our stuff to it. */
2341 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
2342 server->server_type == SILC_ROUTER) {
2343 silc_server_announce_servers(server, FALSE, 0, sock);
2344 silc_server_announce_clients(server, 0, sock);
2345 silc_server_announce_channels(server, 0, sock);
2352 /* Processes incoming New ID packet. New ID Payload is used to distribute
2353 information about newly registered clients and servers. */
2355 static void silc_server_new_id_real(SilcServer server,
2356 SilcSocketConnection sock,
2357 SilcPacketContext *packet,
2360 SilcBuffer buffer = packet->buffer;
2362 SilcServerEntry router, server_entry;
2363 SilcSocketConnection router_sock;
2368 SILC_LOG_DEBUG(("Processing new ID"));
2370 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2371 server->server_type == SILC_SERVER ||
2372 packet->src_id_type != SILC_ID_SERVER)
2375 idp = silc_id_payload_parse(buffer->data, buffer->len);
2379 id_type = silc_id_payload_get_type(idp);
2381 /* Normal server cannot have other normal server connections */
2382 server_entry = (SilcServerEntry)sock->user_data;
2383 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER &&
2384 server_entry->server_type == SILC_SERVER)
2387 id = silc_id_payload_get_id(idp);
2391 /* If the packet is coming from server then use the sender as the
2392 origin of the the packet. If it came from router then check the real
2393 sender of the packet and use that as the origin. */
2394 if (sock->type == SILC_SOCKET_TYPE_SERVER) {
2395 id_list = server->local_list;
2397 router = sock->user_data;
2399 /* If the sender is backup router and ID is server (and we are not
2400 backup router) then switch the entry to global list. */
2401 if (server_entry->server_type == SILC_BACKUP_ROUTER &&
2402 id_type == SILC_ID_SERVER &&
2403 server->id_entry->server_type != SILC_BACKUP_ROUTER) {
2404 id_list = server->global_list;
2405 router_sock = server->router ? server->router->connection : sock;
2408 void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2409 packet->src_id_type);
2410 router = silc_idlist_find_server_by_id(server->global_list,
2411 sender_id, TRUE, NULL);
2413 router = silc_idlist_find_server_by_id(server->local_list,
2414 sender_id, TRUE, NULL);
2415 silc_free(sender_id);
2417 id_list = server->global_list;
2424 case SILC_ID_CLIENT:
2426 SilcClientEntry entry;
2428 /* Check that we do not have this client already */
2429 entry = silc_idlist_find_client_by_id(server->global_list,
2430 id, server->server_type,
2433 entry = silc_idlist_find_client_by_id(server->local_list,
2434 id, server->server_type,
2437 SILC_LOG_DEBUG(("Ignoring client that we already have"));
2441 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
2442 silc_id_render(id, SILC_ID_CLIENT),
2443 sock->type == SILC_SOCKET_TYPE_SERVER ?
2444 "Server" : "Router", sock->hostname));
2446 /* As a router we keep information of all global information in our
2447 global list. Cell wide information however is kept in the local
2449 entry = silc_idlist_add_client(id_list, NULL, NULL, NULL,
2450 id, router, NULL, 0);
2452 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
2454 /* Inform the sender that the ID is not usable */
2455 silc_server_send_notify_signoff(server, sock, FALSE, id, NULL);
2458 entry->nickname = NULL;
2459 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2461 if (sock->type == SILC_SOCKET_TYPE_SERVER)
2462 server->stat.cell_clients++;
2463 server->stat.clients++;
2465 /* Check if anyone is watching this nickname */
2466 if (server->server_type == SILC_ROUTER && id_list == server->local_list)
2467 silc_server_check_watcher_list(server, entry, NULL, 0);
2471 case SILC_ID_SERVER:
2473 SilcServerEntry entry;
2475 /* If the ID is mine, ignore it. */
2476 if (SILC_ID_SERVER_COMPARE(id, server->id)) {
2477 SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
2481 /* If the ID is the sender's ID, ignore it (we have it already) */
2482 if (SILC_ID_SERVER_COMPARE(id, router->id)) {
2483 SILC_LOG_DEBUG(("Ignoring sender's own ID"));
2487 /* Check that we do not have this server already */
2488 entry = silc_idlist_find_server_by_id(server->global_list,
2489 id, server->server_type,
2492 entry = silc_idlist_find_server_by_id(server->local_list,
2493 id, server->server_type,
2496 SILC_LOG_DEBUG(("Ignoring server that we already have"));
2500 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
2501 silc_id_render(id, SILC_ID_SERVER),
2502 sock->type == SILC_SOCKET_TYPE_SERVER ?
2503 "Server" : "Router", sock->hostname));
2505 /* As a router we keep information of all global information in our
2506 global list. Cell wide information however is kept in the local
2508 entry = silc_idlist_add_server(id_list, NULL, 0, id, router,
2511 SILC_LOG_ERROR(("Could not add new server to the ID Cache"));
2514 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2516 if (sock->type == SILC_SOCKET_TYPE_SERVER)
2517 server->stat.cell_servers++;
2518 server->stat.servers++;
2522 case SILC_ID_CHANNEL:
2523 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
2532 /* If the sender of this packet is server and we are router we need to
2533 broadcast this packet to other routers in the network. */
2534 if (broadcast && server->server_type == SILC_ROUTER &&
2535 sock->type == SILC_SOCKET_TYPE_SERVER &&
2536 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2537 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
2538 if (!server->standalone)
2539 silc_server_packet_send(server, server->router->connection,
2541 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2542 buffer->data, buffer->len, FALSE);
2543 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
2544 packet->type, packet->flags,
2545 packet->buffer->data, packet->buffer->len,
2550 silc_id_payload_free(idp);
2554 /* Processes incoming New ID packet. New ID Payload is used to distribute
2555 information about newly registered clients and servers. */
2557 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
2558 SilcPacketContext *packet)
2560 silc_server_new_id_real(server, sock, packet, TRUE);
2563 /* Receoved New Id List packet, list of New ID payloads inside one
2564 packet. Process the New ID payloads one by one. */
2566 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
2567 SilcPacketContext *packet)
2569 SilcPacketContext *new_id;
2573 SILC_LOG_DEBUG(("Processing New ID List"));
2575 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2576 packet->src_id_type != SILC_ID_SERVER)
2579 /* If the sender of this packet is server and we are router we need to
2580 broadcast this packet to other routers in the network. Broadcast
2581 this list packet instead of multiple New ID packets. */
2582 if (server->server_type == SILC_ROUTER &&
2583 sock->type == SILC_SOCKET_TYPE_SERVER &&
2584 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2585 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
2586 if (!server->standalone)
2587 silc_server_packet_send(server, server->router->connection,
2589 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2590 packet->buffer->data,
2591 packet->buffer->len, FALSE);
2592 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
2593 packet->type, packet->flags,
2594 packet->buffer->data, packet->buffer->len,
2598 /* Make copy of the original packet context, except for the actual
2599 data buffer, which we will here now fetch from the original buffer. */
2600 new_id = silc_packet_context_alloc();
2601 new_id->type = SILC_PACKET_NEW_ID;
2602 new_id->flags = packet->flags;
2603 new_id->src_id = packet->src_id;
2604 new_id->src_id_len = packet->src_id_len;
2605 new_id->src_id_type = packet->src_id_type;
2606 new_id->dst_id = packet->dst_id;
2607 new_id->dst_id_len = packet->dst_id_len;
2608 new_id->dst_id_type = packet->dst_id_type;
2610 idp = silc_buffer_alloc(256);
2611 new_id->buffer = idp;
2613 while (packet->buffer->len) {
2614 SILC_GET16_MSB(id_len, packet->buffer->data + 2);
2615 if ((id_len > packet->buffer->len) ||
2616 (id_len > idp->truelen))
2619 silc_buffer_pull_tail(idp, 4 + id_len);
2620 silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
2622 /* Process the New ID */
2623 silc_server_new_id_real(server, sock, new_id, FALSE);
2625 silc_buffer_push_tail(idp, 4 + id_len);
2626 silc_buffer_pull(packet->buffer, 4 + id_len);
2629 silc_buffer_free(idp);
2633 /* Received New Channel packet. Information about new channels in the
2634 network are distributed using this packet. Save the information about
2635 the new channel. This usually comes from router but also normal server
2636 can send this to notify channels it has when it connects to us. */
2638 void silc_server_new_channel(SilcServer server,
2639 SilcSocketConnection sock,
2640 SilcPacketContext *packet)
2642 SilcChannelPayload payload;
2643 SilcChannelID *channel_id;
2645 SilcUInt32 name_len;
2649 SilcServerEntry server_entry;
2650 SilcChannelEntry channel;
2652 SILC_LOG_DEBUG(("Processing New Channel"));
2654 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2655 packet->src_id_type != SILC_ID_SERVER ||
2656 server->server_type == SILC_SERVER)
2659 /* Parse the channel payload */
2660 payload = silc_channel_payload_parse(packet->buffer->data,
2661 packet->buffer->len);
2665 /* Get the channel ID */
2666 channel_id = silc_channel_get_id_parse(payload);
2668 silc_channel_payload_free(payload);
2672 channel_name = silc_channel_get_name(payload, &name_len);
2674 channel_name[255] = '\0';
2676 id = silc_channel_get_id(payload, &id_len);
2678 server_entry = (SilcServerEntry)sock->user_data;
2680 if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
2681 /* Add the channel to global list as it is coming from router. It
2682 cannot be our own channel as it is coming from router. */
2684 /* Check that we don't already have this channel */
2685 channel = silc_idlist_find_channel_by_name(server->local_list,
2686 channel_name, NULL);
2688 channel = silc_idlist_find_channel_by_name(server->global_list,
2689 channel_name, NULL);
2691 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
2692 silc_id_render(channel_id, SILC_ID_CHANNEL),
2696 silc_idlist_add_channel(server->global_list, strdup(channel_name),
2697 0, channel_id, sock->user_data, NULL, NULL, 0);
2700 channel->disabled = TRUE;
2702 server->stat.channels++;
2703 if (server->server_type == SILC_ROUTER)
2704 channel->users_resolved = TRUE;
2707 /* The channel is coming from our server, thus it is in our cell
2708 we will add it to our local list. */
2711 SILC_LOG_DEBUG(("Channel id(%s) from [Server] %s",
2712 silc_id_render(channel_id, SILC_ID_CHANNEL),
2715 /* Check that we don't already have this channel */
2716 channel = silc_idlist_find_channel_by_name(server->local_list,
2717 channel_name, NULL);
2719 channel = silc_idlist_find_channel_by_name(server->global_list,
2720 channel_name, NULL);
2722 /* If the channel does not exist, then create it. This creates a new
2723 key to the channel as well that we will send to the server. */
2725 /* The protocol says that the Channel ID's IP address must be based
2726 on the router's IP address. Check whether the ID is based in our
2727 IP and if it is not then create a new ID and enforce the server
2728 to switch the ID. */
2729 if (server_entry->server_type != SILC_BACKUP_ROUTER &&
2730 !SILC_ID_COMPARE(channel_id, server->id, server->id->ip.data_len)) {
2732 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2734 if (silc_id_create_channel_id(server, server->id, server->rng, &tmp)) {
2735 silc_server_send_notify_channel_change(server, sock, FALSE,
2737 silc_free(channel_id);
2742 /* Create the channel with the provided Channel ID */
2743 channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
2747 silc_channel_payload_free(payload);
2748 silc_free(channel_id);
2751 channel->disabled = TRUE;
2754 /* CMODE change notify is expected */
2755 /* Get the mode and set it to the channel */
2756 channel->mode = silc_channel_get_mode(payload);
2759 /* Send the new channel key to the server */
2760 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2761 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
2762 chk = silc_channel_key_payload_encode(id_len, id,
2763 strlen(channel->channel_key->
2765 channel->channel_key->cipher->name,
2766 channel->key_len / 8,
2768 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
2769 chk->data, chk->len, FALSE);
2770 silc_buffer_free(chk);
2773 /* The channel exist by that name, check whether the ID's match.
2774 If they don't then we'll force the server to use the ID we have.
2775 We also create a new key for the channel. */
2776 SilcBuffer modes = NULL, users = NULL, users_modes = NULL;
2778 if (!SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
2779 /* They don't match, send CHANNEL_CHANGE notify to the server to
2780 force the ID change. */
2781 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2782 silc_server_send_notify_channel_change(server, sock, FALSE,
2783 channel_id, channel->id);
2786 /* If the mode is different from what we have then enforce the
2788 mode = silc_channel_get_mode(payload);
2789 if (channel->mode != mode) {
2790 SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
2791 silc_server_send_notify_cmode(server, sock, FALSE, channel,
2792 channel->mode, server->id,
2793 SILC_ID_SERVER, channel->cipher,
2795 channel->passphrase,
2796 channel->founder_key);
2799 /* Create new key for the channel and send it to the server and
2800 everybody else possibly on the channel. */
2801 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
2802 if (!silc_server_create_channel_key(server, channel, 0))
2805 /* Send to the channel */
2806 silc_server_send_channel_key(server, sock, channel, FALSE);
2807 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2808 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
2810 /* Send to the server */
2811 chk = silc_channel_key_payload_encode(id_len, id,
2812 strlen(channel->channel_key->
2814 channel->channel_key->
2816 channel->key_len / 8,
2818 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
2819 chk->data, chk->len, FALSE);
2820 silc_buffer_free(chk);
2824 silc_free(channel_id);
2826 /* Since the channel is coming from server and we also know about it
2827 then send the JOIN notify to the server so that it see's our
2828 users on the channel "joining" the channel. */
2829 silc_server_announce_get_channel_users(server, channel, &modes, &users,
2832 silc_buffer_push(modes, modes->data - modes->head);
2833 silc_server_packet_send_dest(server, sock,
2834 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2835 channel->id, SILC_ID_CHANNEL,
2836 modes->data, modes->len, FALSE);
2837 silc_buffer_free(modes);
2840 silc_buffer_push(users, users->data - users->head);
2841 silc_server_packet_send(server, sock,
2842 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2843 users->data, users->len, FALSE);
2844 silc_buffer_free(users);
2847 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
2848 silc_server_packet_send_dest(server, sock,
2849 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2850 channel->id, SILC_ID_CHANNEL,
2852 users_modes->len, FALSE);
2853 silc_buffer_free(users_modes);
2858 silc_channel_payload_free(payload);
2861 /* Received New Channel List packet, list of New Channel List payloads inside
2862 one packet. Process the New Channel payloads one by one. */
2864 void silc_server_new_channel_list(SilcServer server,
2865 SilcSocketConnection sock,
2866 SilcPacketContext *packet)
2868 SilcPacketContext *new;
2870 SilcUInt16 len1, len2;
2872 SILC_LOG_DEBUG(("Processing New Channel List"));
2874 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2875 packet->src_id_type != SILC_ID_SERVER ||
2876 server->server_type == SILC_SERVER)
2879 /* If the sender of this packet is server and we are router we need to
2880 broadcast this packet to other routers in the network. Broadcast
2881 this list packet instead of multiple New Channel packets. */
2882 if (server->server_type == SILC_ROUTER &&
2883 sock->type == SILC_SOCKET_TYPE_SERVER &&
2884 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2885 SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
2886 if (!server->standalone)
2887 silc_server_packet_send(server, server->router->connection,
2889 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2890 packet->buffer->data,
2891 packet->buffer->len, FALSE);
2892 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
2893 packet->type, packet->flags,
2894 packet->buffer->data, packet->buffer->len,
2898 /* Make copy of the original packet context, except for the actual
2899 data buffer, which we will here now fetch from the original buffer. */
2900 new = silc_packet_context_alloc();
2901 new->type = SILC_PACKET_NEW_CHANNEL;
2902 new->flags = packet->flags;
2903 new->src_id = packet->src_id;
2904 new->src_id_len = packet->src_id_len;
2905 new->src_id_type = packet->src_id_type;
2906 new->dst_id = packet->dst_id;
2907 new->dst_id_len = packet->dst_id_len;
2908 new->dst_id_type = packet->dst_id_type;
2910 buffer = silc_buffer_alloc(512);
2911 new->buffer = buffer;
2913 while (packet->buffer->len) {
2914 SILC_GET16_MSB(len1, packet->buffer->data);
2915 if ((len1 > packet->buffer->len) ||
2916 (len1 > buffer->truelen))
2919 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
2920 if ((len2 > packet->buffer->len) ||
2921 (len2 > buffer->truelen))
2924 silc_buffer_pull_tail(buffer, 8 + len1 + len2);
2925 silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
2927 /* Process the New Channel */
2928 silc_server_new_channel(server, sock, new);
2930 silc_buffer_push_tail(buffer, 8 + len1 + len2);
2931 silc_buffer_pull(packet->buffer, 8 + len1 + len2);
2934 silc_buffer_free(buffer);
2938 /* Received key agreement packet. This packet is never for us. It is to
2939 the client in the packet's destination ID. Sending of this sort of packet
2940 equals sending private message, ie. it is sent point to point from
2941 one client to another. */
2943 void silc_server_key_agreement(SilcServer server,
2944 SilcSocketConnection sock,
2945 SilcPacketContext *packet)
2947 SilcSocketConnection dst_sock;
2948 SilcIDListData idata;
2950 SILC_LOG_DEBUG(("Start"));
2952 if (packet->src_id_type != SILC_ID_CLIENT ||
2953 packet->dst_id_type != SILC_ID_CLIENT)
2956 if (!packet->dst_id)
2959 /* Get the route to the client */
2960 dst_sock = silc_server_get_client_route(server, packet->dst_id,
2961 packet->dst_id_len, NULL,
2966 /* Relay the packet */
2967 silc_server_relay_packet(server, dst_sock, idata->send_key,
2968 idata->hmac_send, idata->psn_send++,
2972 /* Received connection auth request packet that is used during connection
2973 phase to resolve the mandatory authentication method. This packet can
2974 actually be received at anytime but usually it is used only during
2975 the connection authentication phase. Now, protocol says that this packet
2976 can come from client or server, however, we support only this coming
2977 from client and expect that server always knows what authentication
2980 void silc_server_connection_auth_request(SilcServer server,
2981 SilcSocketConnection sock,
2982 SilcPacketContext *packet)
2984 SilcServerConfigClient *client = NULL;
2985 SilcUInt16 conn_type;
2987 SilcAuthMethod auth_meth = SILC_AUTH_NONE;
2989 SILC_LOG_DEBUG(("Start"));
2991 if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT)
2994 /* Parse the payload */
2995 ret = silc_buffer_unformat(packet->buffer,
2996 SILC_STR_UI_SHORT(&conn_type),
2997 SILC_STR_UI_SHORT(NULL),
3002 if (conn_type != SILC_SOCKET_TYPE_CLIENT)
3005 /* Get the authentication method for the client */
3006 auth_meth = SILC_AUTH_NONE;
3007 client = silc_server_config_find_client(server, sock->ip);
3009 client = silc_server_config_find_client(server, sock->hostname);
3011 if (client->passphrase) {
3012 if (client->publickeys && !server->config->prefer_passphrase_auth)
3013 auth_meth = SILC_AUTH_PUBLIC_KEY;
3015 auth_meth = SILC_AUTH_PASSWORD;
3016 } else if (client->publickeys)
3017 auth_meth = SILC_AUTH_PUBLIC_KEY;
3020 /* Send it back to the client */
3021 silc_server_send_connection_auth_request(server, sock, conn_type, auth_meth);
3024 /* Received REKEY packet. The sender of the packet wants to regenerate
3025 its session keys. This starts the REKEY protocol. */
3027 void silc_server_rekey(SilcServer server,
3028 SilcSocketConnection sock,
3029 SilcPacketContext *packet)
3031 SilcProtocol protocol;
3032 SilcServerRekeyInternalContext *proto_ctx;
3033 SilcIDListData idata = (SilcIDListData)sock->user_data;
3035 SILC_LOG_DEBUG(("Start"));
3037 /* Allocate internal protocol context. This is sent as context
3039 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
3040 proto_ctx->server = (void *)server;
3041 proto_ctx->sock = sock;
3042 proto_ctx->responder = TRUE;
3043 proto_ctx->pfs = idata->rekey->pfs;
3045 /* Perform rekey protocol. Will call the final callback after the
3046 protocol is over. */
3047 silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
3048 &protocol, proto_ctx, silc_server_rekey_final);
3049 sock->protocol = protocol;
3051 if (proto_ctx->pfs == FALSE)
3052 /* Run the protocol */
3053 silc_protocol_execute(protocol, server->schedule, 0, 0);
3056 /* Received file transger packet. This packet is never for us. It is to
3057 the client in the packet's destination ID. Sending of this sort of packet
3058 equals sending private message, ie. it is sent point to point from
3059 one client to another. */
3061 void silc_server_ftp(SilcServer server,
3062 SilcSocketConnection sock,
3063 SilcPacketContext *packet)
3065 SilcSocketConnection dst_sock;
3066 SilcIDListData idata;
3068 SILC_LOG_DEBUG(("Start"));
3070 if (packet->src_id_type != SILC_ID_CLIENT ||
3071 packet->dst_id_type != SILC_ID_CLIENT)
3074 if (!packet->dst_id)
3077 /* Get the route to the client */
3078 dst_sock = silc_server_get_client_route(server, packet->dst_id,
3079 packet->dst_id_len, NULL,
3084 /* Relay the packet */
3085 silc_server_relay_packet(server, dst_sock, idata->send_key,
3086 idata->hmac_send, idata->psn_send++,
3092 SilcSocketConnection sock;
3093 SilcPacketContext *packet;
3095 } *SilcServerResumeResolve;
3097 SILC_SERVER_CMD_FUNC(resume_resolve)
3099 SilcServerResumeResolve r = (SilcServerResumeResolve)context;
3100 SilcServer server = r->server;
3101 SilcSocketConnection sock = r->sock;
3102 SilcServerCommandReplyContext reply = context2;
3103 SilcClientEntry client;
3105 SILC_LOG_DEBUG(("Start"));
3107 if (!reply || !silc_command_get_status(reply->payload, NULL, NULL)) {
3108 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3109 "closing connection", sock->hostname, sock->ip));
3110 silc_server_disconnect_remote(server, sock,
3111 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3112 "Resuming not possible");
3116 if (reply && silc_command_get(reply->payload) == SILC_COMMAND_WHOIS) {
3117 /* Get entry to the client, and resolve it if we don't have it. */
3118 client = silc_idlist_find_client_by_id(server->local_list,
3119 r->data, TRUE, NULL);
3121 client = silc_idlist_find_client_by_id(server->global_list,
3122 r->data, TRUE, NULL);
3124 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3125 "closing connection", sock->hostname, sock->ip));
3126 silc_server_disconnect_remote(server, sock,
3127 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3128 "Resuming not possible");
3133 if (!(client->mode & SILC_UMODE_DETACHED)) {
3134 SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, "
3135 "closing connection", sock->hostname, sock->ip));
3136 silc_server_disconnect_remote(server, sock,
3137 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3138 "Resuming not possible");
3143 /* Reprocess the packet */
3144 silc_server_resume_client(server, sock, r->packet);
3147 silc_socket_free(r->sock);
3148 silc_packet_context_free(r->packet);
3153 /* Received client resuming packet. This is used to resume detached
3154 client session. It can be sent by the client who wishes to resume
3155 but this is also sent by servers and routers to notify other routers
3156 that the client is not detached anymore. */
3158 void silc_server_resume_client(SilcServer server,
3159 SilcSocketConnection sock,
3160 SilcPacketContext *packet)
3162 SilcBuffer buffer = packet->buffer, buf;
3163 SilcIDListData idata;
3164 SilcClientEntry detached_client;
3165 SilcClientID *client_id = NULL;
3166 unsigned char *id_string, *auth = NULL;
3167 SilcUInt16 id_len, auth_len = 0;
3168 int ret, nickfail = 0;
3169 bool resolved, local, nick_change = FALSE, resolve = FALSE;
3170 SilcChannelEntry channel;
3171 SilcHashTableList htl;
3172 SilcChannelClientEntry chl;
3173 SilcServerResumeResolve r;
3175 SILC_LOG_DEBUG(("Start"));
3177 ret = silc_buffer_unformat(buffer,
3178 SILC_STR_UI16_NSTRING(&id_string, &id_len),
3181 client_id = silc_id_str2id(id_string, id_len, SILC_ID_CLIENT);
3183 if (sock->type == SILC_SOCKET_TYPE_CLIENT) {
3184 /* Client send this and is attempting to resume to old client session */
3185 SilcClientEntry client;
3189 silc_buffer_pull(buffer, 2 + id_len);
3190 auth = buffer->data;
3191 auth_len = buffer->len;
3192 silc_buffer_push(buffer, 2 + id_len);
3195 if (!client_id || auth_len < 128) {
3196 SILC_LOG_ERROR(("Client %s (%s) sent incomplete resume information, "
3197 "closing connection", sock->hostname, sock->ip));
3198 silc_server_disconnect_remote(server, sock,
3199 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3200 "Resuming not possible");
3204 /* Take client entry of this connection */
3205 client = (SilcClientEntry)sock->user_data;
3206 idata = (SilcIDListData)client;
3208 /* Get entry to the client, and resolve it if we don't have it. */
3209 detached_client = silc_server_get_client_resolve(server, client_id, FALSE,
3211 if (!detached_client) {
3213 /* The client info is being resolved. Reprocess this packet after
3214 receiving the reply to the query. */
3215 SILC_LOG_DEBUG(("Resolving client"));
3216 r = silc_calloc(1, sizeof(*r));
3220 r->sock = silc_socket_dup(sock);
3221 r->packet = silc_packet_context_dup(packet);
3222 r->data = silc_id_dup(client_id, SILC_ID_CLIENT);
3223 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
3225 silc_server_command_resume_resolve, r);
3227 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3228 "closing connection", sock->hostname, sock->ip));
3229 silc_server_disconnect_remote(server, sock,
3230 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3231 "Resuming not possible");
3236 if (!(detached_client->mode & SILC_UMODE_DETACHED))
3238 if (!silc_hash_table_count(detached_client->channels) &&
3239 detached_client->router)
3241 if (!detached_client->nickname)
3245 if (server->server_type == SILC_SERVER && !server->standalone) {
3246 /* The client info is being resolved. Reprocess this packet after
3247 receiving the reply to the query. */
3248 SILC_LOG_DEBUG(("Resolving client info"));
3249 silc_server_get_client_resolve(server, client_id, TRUE, NULL);
3250 r = silc_calloc(1, sizeof(*r));
3254 r->sock = silc_socket_dup(sock);
3255 r->packet = silc_packet_context_dup(packet);
3256 r->data = silc_id_dup(client_id, SILC_ID_CLIENT);
3257 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
3259 silc_server_command_resume_resolve, r);
3262 if (server->server_type == SILC_SERVER) {
3263 SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, "
3264 "closing connection", sock->hostname, sock->ip));
3265 silc_server_disconnect_remote(server, sock,
3266 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3267 "Resuming not possible");
3272 /* Check that we have the public key of the client, if not then we must
3273 resolve it first. */
3274 if (!detached_client->data.public_key) {
3275 if (server->server_type == SILC_SERVER && server->standalone) {
3276 silc_server_disconnect_remote(server, sock,
3277 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3278 "Resuming not possible");
3280 /* We must retrieve the detached client's public key by sending
3281 GETKEY command. Reprocess this packet after receiving the key */
3282 SilcBuffer idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
3283 SilcSocketConnection dest_sock =
3284 silc_server_get_client_route(server, NULL, 0, client_id, NULL, NULL);
3286 SILC_LOG_DEBUG(("Resolving client public key"));
3288 silc_server_send_command(server, dest_sock ? dest_sock :
3289 server->router->connection,
3290 SILC_COMMAND_GETKEY, ++server->cmd_ident,
3291 1, 1, idp->data, idp->len);
3293 r = silc_calloc(1, sizeof(*r));
3298 r->sock = silc_socket_dup(sock);
3299 r->packet = silc_packet_context_dup(packet);
3300 silc_server_command_pending(server, SILC_COMMAND_GETKEY,
3302 silc_server_command_resume_resolve, r);
3304 silc_buffer_free(idp);
3307 } else if (!silc_pkcs_public_key_compare(detached_client->data.public_key,
3308 idata->public_key)) {
3309 /* We require that the connection and resuming authentication data
3310 must be using same key pair. */
3311 silc_server_disconnect_remote(server, sock,
3312 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3313 "Resuming not possible");
3317 /* Verify the authentication payload. This has to be successful in
3318 order to allow the resuming */
3320 !silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
3321 detached_client->data.public_key, 0,
3322 idata->hash, detached_client->id,
3324 SILC_LOG_ERROR(("Client %s (%s) resume authentication failed, "
3325 "closing connection", sock->hostname, sock->ip));
3326 silc_server_disconnect_remote(server, sock,
3327 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3328 "Resuming not possible");
3332 /* Now resume the client to the network */
3334 silc_schedule_task_del_by_context(server->schedule, detached_client);
3335 sock->user_data = detached_client;
3336 detached_client->connection = sock;
3338 /* Take new keys and stuff into use in the old entry */
3339 silc_idlist_del_data(detached_client);
3340 silc_idlist_add_data(detached_client, idata);
3341 detached_client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
3342 detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
3343 detached_client->mode &= ~SILC_UMODE_DETACHED;
3345 /* Send the RESUME_CLIENT packet to our primary router so that others
3346 know this client isn't detached anymore. */
3347 buf = silc_buffer_alloc_size(2 + id_len);
3348 silc_buffer_format(buf,
3349 SILC_STR_UI_SHORT(id_len),
3350 SILC_STR_UI_XNSTRING(id_string, id_len),
3353 /* Send to primary router */
3354 if (!server->standalone)
3355 silc_server_packet_send(server, server->router->connection,
3356 SILC_PACKET_RESUME_CLIENT, 0,
3357 buf->data, buf->len, TRUE);
3359 /* As router we must deliver this packet directly to the original
3360 server whom this client was earlier. */
3361 if (server->server_type == SILC_ROUTER && detached_client->router &&
3362 detached_client->router->server_type != SILC_ROUTER)
3363 silc_server_packet_send(server, detached_client->router->connection,
3364 SILC_PACKET_RESUME_CLIENT, 0,
3365 buf->data, buf->len, TRUE);
3366 silc_buffer_free(buf);
3368 detached_client->router = NULL;
3370 /* Delete this client entry since we're resuming to old one. */
3371 server->stat.my_clients--;
3372 server->stat.clients--;
3373 if (server->stat.cell_clients)
3374 server->stat.cell_clients--;
3375 silc_server_del_from_watcher_list(server, client);
3376 silc_idlist_del_client(server->local_list, client);
3377 client = detached_client;
3379 /* If the ID is not based in our ID then change it */
3380 if (!SILC_ID_COMPARE(client->id, server->id, server->id->ip.data_len)) {
3381 while (!silc_id_create_client_id(server, server->id, server->rng,
3382 server->md5hash, client->nickname,
3386 silc_server_disconnect_remote(server, sock,
3387 SILC_STATUS_ERR_BAD_NICKNAME, NULL);
3390 snprintf(&client->nickname[strlen(client->nickname) - 1], 1,
3397 /* Notify about Client ID change, nickname doesn't actually change. */
3398 if (!server->standalone)
3399 silc_server_send_notify_nick_change(server, server->router->connection,
3400 FALSE, client->id, client_id,
3404 /* Resolve users on those channels that client has joined but we
3405 haven't resolved user list yet. */
3406 if (server->server_type == SILC_SERVER && !server->standalone) {
3407 silc_hash_table_list(client->channels, &htl);
3408 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
3409 channel = chl->channel;
3410 SILC_LOG_DEBUG(("Resolving users for %s channel",
3411 channel->channel_name));
3412 if (channel->disabled || !channel->users_resolved) {
3413 silc_server_send_command(server, server->router->connection,
3414 SILC_COMMAND_USERS, ++server->cmd_ident,
3415 1, 2, channel->channel_name,
3416 strlen(channel->channel_name));
3419 silc_hash_table_list_reset(&htl);
3422 /* Send the new client ID to the client. After this client may start
3423 receiving other packets, and may start sending packets too. */
3424 silc_server_send_new_id(server, sock, FALSE, client_id, SILC_ID_CLIENT,
3425 silc_id_get_len(client_id, SILC_ID_CLIENT));
3428 /* Send NICK change notify to channels as well. */
3429 SilcBuffer oidp, nidp;
3430 oidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3431 nidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
3432 silc_server_send_notify_on_channels(server, NULL, client,
3433 SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
3434 oidp->data, oidp->len,
3435 nidp->data, nidp->len,
3437 strlen(client->nickname));
3438 silc_buffer_free(oidp);
3439 silc_buffer_free(nidp);
3442 /* Add the client again to the ID cache to get it to correct list */
3443 if (!silc_idcache_del_by_context(server->local_list->clients, client))
3444 silc_idcache_del_by_context(server->global_list->clients, client);
3445 silc_free(client->id);
3446 client->id = client_id;
3448 silc_idcache_add(server->local_list->clients, client->nickname,
3449 client->id, client, 0, NULL);
3451 /* Send some nice info to the client */
3452 silc_server_send_connect_notifys(server, sock, client);
3454 /* Send all channel keys of channels the client has joined */
3455 silc_hash_table_list(client->channels, &htl);
3456 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
3457 bool created = FALSE;
3458 channel = chl->channel;
3460 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY)
3463 /* If we don't have channel key, then create one */
3464 if (!channel->channel_key) {
3465 if (!silc_server_create_channel_key(server, channel, 0))
3470 id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3472 silc_channel_key_payload_encode(silc_id_get_len(channel->id,
3475 strlen(channel->channel_key->
3477 channel->channel_key->cipher->name,
3478 channel->key_len / 8, channel->key);
3479 silc_free(id_string);
3481 /* Send the key packet to client */
3482 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
3483 keyp->data, keyp->len, FALSE);
3485 if (created && server->server_type == SILC_SERVER &&
3486 !server->standalone)
3487 silc_server_packet_send(server, server->router->connection,
3488 SILC_PACKET_CHANNEL_KEY, 0,
3489 keyp->data, keyp->len, FALSE);
3491 silc_buffer_free(keyp);
3493 silc_hash_table_list_reset(&htl);
3495 } else if (sock->type != SILC_SOCKET_TYPE_CLIENT) {
3496 /* Server or router sent this to us to notify that that a client has
3498 SilcServerEntry server_entry;
3499 SilcServerID *server_id;
3504 /* Get entry to the client, and resolve it if we don't have it. */
3505 detached_client = silc_idlist_find_client_by_id(server->local_list,
3506 client_id, TRUE, NULL);
3507 if (!detached_client) {
3508 detached_client = silc_idlist_find_client_by_id(server->global_list,
3509 client_id, TRUE, NULL);
3510 if (!detached_client)
3514 /* Check that the client has not been resumed already because it is
3515 protocol error to attempt to resume more than once. The client
3516 will be killed if this protocol error occurs. */
3517 if (detached_client->data.status & SILC_IDLIST_STATUS_RESUMED &&
3518 !(detached_client->mode & SILC_UMODE_DETACHED)) {
3519 /* The client is clearly attempting to resume more than once and
3520 perhaps playing around by resuming from several different places
3521 at the same time. */
3522 silc_server_kill_client(server, detached_client, NULL,
3523 server->id, SILC_ID_SERVER);
3527 /* Check whether client is detached at all */
3528 if (!(detached_client->mode & SILC_UMODE_DETACHED))
3531 /* Client is detached, and now it is resumed. Remove the detached
3532 mode and mark that it is resumed. */
3533 detached_client->mode &= ~SILC_UMODE_DETACHED;
3534 detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
3536 /* Get the new owner of the resumed client */
3537 server_id = silc_id_str2id(packet->src_id, packet->src_id_len,
3538 packet->src_id_type);
3542 /* Get server entry */
3543 server_entry = silc_idlist_find_server_by_id(server->global_list,
3544 server_id, TRUE, NULL);
3546 if (!server_entry) {
3547 server_entry = silc_idlist_find_server_by_id(server->local_list,
3548 server_id, TRUE, NULL);
3550 if (!server_entry) {
3551 silc_free(server_id);
3556 if (server->server_type == SILC_ROUTER &&
3557 sock->type == SILC_SOCKET_TYPE_ROUTER &&
3558 server_entry->server_type == SILC_ROUTER)
3561 SILC_LOG_DEBUG(("Resuming detached client"));
3563 /* Change the client to correct list. */
3564 if (!silc_idcache_del_by_context(server->local_list->clients,
3566 silc_idcache_del_by_context(server->global_list->clients,
3568 silc_idcache_add(local && server->server_type == SILC_ROUTER ?
3569 server->local_list->clients :
3570 server->global_list->clients,
3571 detached_client->nickname,
3572 detached_client->id, detached_client, FALSE, NULL);
3574 /* Change the owner of the client if needed */
3575 if (detached_client->router != server_entry)
3576 detached_client->router = server_entry;
3578 /* Update channel information regarding global clients on channel. */
3579 if (server->server_type == SILC_SERVER) {
3580 silc_hash_table_list(detached_client->channels, &htl);
3581 while (silc_hash_table_get(&htl, NULL, (void **)&chl))
3582 chl->channel->global_users =
3583 silc_server_channel_has_global(chl->channel);
3584 silc_hash_table_list_reset(&htl);
3587 silc_schedule_task_del_by_context(server->schedule, detached_client);
3589 /* If the sender of this packet is server and we are router we need to
3590 broadcast this packet to other routers in the network. */
3591 if (server->server_type == SILC_ROUTER &&
3592 sock->type == SILC_SOCKET_TYPE_SERVER &&
3593 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
3594 SILC_LOG_DEBUG(("Broadcasting received Resume Client packet"));
3595 if (!server->standalone)
3596 silc_server_packet_send(server, server->router->connection,
3598 packet->flags | SILC_PACKET_FLAG_BROADCAST,
3599 buffer->data, buffer->len, FALSE);
3600 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
3601 packet->type, packet->flags,
3602 packet->buffer->data, packet->buffer->len,
3606 silc_free(server_id);
3609 silc_free(client_id);