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"));
1890 if (chl->mode & SILC_CHANNEL_UMODE_QUIET) {
1891 SILC_LOG_DEBUG(("Sender is quieted on the channel"));
1895 /* If the packet is coming from router, but the client entry is local
1896 entry to us then some router is rerouting this to us and it is not
1897 allowed. When the client is local to us it means that we've routed
1898 this packet to network, and now someone is routing it back to us. */
1899 if (server->server_type == SILC_ROUTER &&
1900 sock->type == SILC_SOCKET_TYPE_ROUTER && local) {
1901 SILC_LOG_DEBUG(("Channel message rerouted to the sender, drop it"));
1906 /* Distribute the packet to our local clients. This will send the
1907 packet for further routing as well, if needed. */
1908 silc_server_packet_relay_to_channel(server, sock, channel, sender_id,
1909 packet->src_id_type, sender_entry,
1910 packet->buffer->data,
1911 packet->buffer->len, FALSE);
1914 silc_free(sender_id);
1918 /* Received channel key packet. We distribute the key to all of our locally
1919 connected clients on the channel. */
1921 void silc_server_channel_key(SilcServer server,
1922 SilcSocketConnection sock,
1923 SilcPacketContext *packet)
1925 SilcBuffer buffer = packet->buffer;
1926 SilcChannelEntry channel;
1928 if (packet->src_id_type != SILC_ID_SERVER ||
1929 (server->server_type == SILC_ROUTER &&
1930 sock->type == SILC_SOCKET_TYPE_ROUTER))
1933 /* Save the channel key */
1934 channel = silc_server_save_channel_key(server, buffer, NULL);
1938 /* Distribute the key to everybody who is on the channel. If we are router
1939 we will also send it to locally connected servers. */
1940 silc_server_send_channel_key(server, sock, channel, FALSE);
1942 if (server->server_type != SILC_BACKUP_ROUTER) {
1943 /* Distribute to local cell backup routers. */
1944 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
1945 SILC_PACKET_CHANNEL_KEY, 0,
1946 buffer->data, buffer->len, FALSE, TRUE);
1950 /* Received New Client packet and processes it. Creates Client ID for the
1951 client. Client becomes registered after calling this functions. */
1953 SilcClientEntry silc_server_new_client(SilcServer server,
1954 SilcSocketConnection sock,
1955 SilcPacketContext *packet)
1957 SilcBuffer buffer = packet->buffer;
1958 SilcClientEntry client;
1959 SilcClientID *client_id;
1960 SilcIDListData idata;
1961 char *username = NULL, *realname = NULL;
1962 SilcUInt16 username_len;
1965 char *hostname, *nickname;
1968 SILC_LOG_DEBUG(("Creating new client"));
1970 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
1973 /* Take client entry */
1974 client = (SilcClientEntry)sock->user_data;
1975 idata = (SilcIDListData)client;
1977 /* Remove the old cache entry. */
1978 if (!silc_idcache_del_by_context(server->local_list->clients, client)) {
1979 SILC_LOG_INFO(("Unauthenticated client attempted to register to network"));
1980 silc_server_disconnect_remote(server, sock,
1981 SILC_STATUS_ERR_NOT_AUTHENTICATED, NULL);
1982 if (sock->user_data)
1983 silc_server_free_sock_user_data(server, sock, NULL);
1987 /* Parse incoming packet */
1988 ret = silc_buffer_unformat(buffer,
1989 SILC_STR_UI16_NSTRING_ALLOC(&username,
1991 SILC_STR_UI16_STRING_ALLOC(&realname),
1994 silc_free(username);
1995 silc_free(realname);
1996 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
1997 "connection", sock->hostname, sock->ip));
1998 silc_server_disconnect_remote(server, sock,
1999 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2001 if (sock->user_data)
2002 silc_server_free_sock_user_data(server, sock, NULL);
2007 silc_free(username);
2008 silc_free(realname);
2009 SILC_LOG_ERROR(("Client %s (%s) did not send its username, closing "
2010 "connection", sock->hostname, sock->ip));
2011 silc_server_disconnect_remote(server, sock,
2012 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2014 if (sock->user_data)
2015 silc_server_free_sock_user_data(server, sock, NULL);
2019 if (username_len > 128)
2020 username[128] = '\0';
2022 /* Check for bad characters for nickname, and modify the nickname if
2023 it includes those. */
2024 if (silc_server_name_bad_chars(username, username_len)) {
2025 nickname = silc_server_name_modify_bad(username, username_len);
2027 nickname = strdup(username);
2030 /* Make sanity checks for the hostname of the client. If the hostname
2031 is provided in the `username' check that it is the same than the
2032 resolved hostname, or if not resolved the hostname that appears in
2033 the client's public key. If the hostname is not present then put
2034 it from the resolved name or from the public key. */
2035 if (strchr(username, '@')) {
2036 SilcPublicKeyIdentifier pident;
2037 int tlen = strcspn(username, "@");
2038 char *phostname = NULL;
2040 hostname = silc_memdup(username + tlen + 1, strlen(username) - tlen - 1);
2042 if (strcmp(sock->hostname, sock->ip) &&
2043 strcmp(sock->hostname, hostname)) {
2044 silc_free(username);
2045 silc_free(hostname);
2046 silc_free(realname);
2047 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2048 "connection", sock->hostname, sock->ip));
2049 silc_server_disconnect_remote(server, sock,
2050 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2052 if (sock->user_data)
2053 silc_server_free_sock_user_data(server, sock, NULL);
2057 pident = silc_pkcs_decode_identifier(client->data.public_key->identifier);
2059 phostname = strdup(pident->host);
2060 silc_pkcs_free_identifier(pident);
2063 if (!strcmp(sock->hostname, sock->ip) &&
2064 phostname && strcmp(phostname, hostname)) {
2065 silc_free(username);
2066 silc_free(hostname);
2067 silc_free(phostname);
2068 silc_free(realname);
2069 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2070 "connection", sock->hostname, sock->ip));
2071 silc_server_disconnect_remote(server, sock,
2072 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2074 if (sock->user_data)
2075 silc_server_free_sock_user_data(server, sock, NULL);
2079 silc_free(phostname);
2081 /* The hostname is not present, add it. */
2083 /* XXX For now we cannot take the host name from the public key since
2084 they are not trusted or we cannot verify them as trusted. Just take
2085 what the resolved name or address is. */
2087 if (strcmp(sock->hostname, sock->ip)) {
2089 newusername = silc_calloc(strlen(username) +
2090 strlen(sock->hostname) + 2,
2091 sizeof(*newusername));
2092 strncat(newusername, username, strlen(username));
2093 strncat(newusername, "@", 1);
2094 strncat(newusername, sock->hostname, strlen(sock->hostname));
2095 silc_free(username);
2096 username = newusername;
2099 SilcPublicKeyIdentifier pident =
2100 silc_pkcs_decode_identifier(client->data.public_key->identifier);
2103 newusername = silc_calloc(strlen(username) +
2104 strlen(pident->host) + 2,
2105 sizeof(*newusername));
2106 strncat(newusername, username, strlen(username));
2107 strncat(newusername, "@", 1);
2108 strncat(newusername, pident->host, strlen(pident->host));
2109 silc_free(username);
2110 username = newusername;
2111 silc_pkcs_free_identifier(pident);
2117 /* Create Client ID */
2118 while (!silc_id_create_client_id(server, server->id, server->rng,
2119 server->md5hash, nickname, &client_id)) {
2122 silc_server_disconnect_remote(server, sock,
2123 SILC_STATUS_ERR_BAD_NICKNAME, NULL);
2124 if (sock->user_data)
2125 silc_server_free_sock_user_data(server, sock, NULL);
2128 snprintf(&nickname[strlen(nickname) - 1], 1, "%d", nickfail);
2131 /* Update client entry */
2132 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
2133 client->nickname = nickname;
2134 client->username = username;
2135 client->userinfo = realname ? realname : strdup(" ");
2136 client->id = client_id;
2137 id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
2139 /* Add the client again to the ID cache */
2140 silc_idcache_add(server->local_list->clients, client->nickname,
2141 client_id, client, 0, NULL);
2143 /* Notify our router about new client on the SILC network */
2144 if (!server->standalone)
2145 silc_server_send_new_id(server, (SilcSocketConnection)
2146 server->router->connection,
2147 server->server_type == SILC_ROUTER ? TRUE : FALSE,
2148 client->id, SILC_ID_CLIENT, id_len);
2150 /* Distribute to backup routers */
2151 if (server->server_type == SILC_ROUTER) {
2152 SilcBuffer idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
2153 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_ID, 0,
2154 idp->data, idp->len, FALSE, TRUE);
2155 silc_buffer_free(idp);
2158 /* Send the new client ID to the client. */
2159 silc_server_send_new_id(server, sock, FALSE, client->id, SILC_ID_CLIENT,
2160 silc_id_get_len(client->id, SILC_ID_CLIENT));
2162 /* Send some nice info to the client */
2163 silc_server_send_connect_notifys(server, sock, client);
2165 /* Check if anyone is watching this nickname */
2166 if (server->server_type == SILC_ROUTER)
2167 silc_server_check_watcher_list(server, client, NULL, 0);
2172 /* Create new server. This processes received New Server packet and
2173 saves the received Server ID. The server is our locally connected
2174 server thus we save all the information and save it to local list.
2175 This funtion can be used by both normal server and router server.
2176 If normal server uses this it means that its router has connected
2177 to the server. If router uses this it means that one of the cell's
2178 servers is connected to the router. */
2180 SilcServerEntry silc_server_new_server(SilcServer server,
2181 SilcSocketConnection sock,
2182 SilcPacketContext *packet)
2184 SilcBuffer buffer = packet->buffer;
2185 SilcServerEntry new_server, server_entry;
2186 SilcServerID *server_id;
2187 SilcIDListData idata;
2188 unsigned char *server_name, *id_string;
2189 SilcUInt16 id_len, name_len;
2193 SILC_LOG_DEBUG(("Creating new server"));
2195 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
2196 sock->type != SILC_SOCKET_TYPE_ROUTER)
2199 /* Take server entry */
2200 new_server = (SilcServerEntry)sock->user_data;
2201 idata = (SilcIDListData)new_server;
2203 /* Remove the old cache entry */
2204 if (!silc_idcache_del_by_context(server->local_list->servers, new_server)) {
2205 if (!silc_idcache_del_by_context(server->global_list->servers,
2207 SILC_LOG_INFO(("Unauthenticated %s attempted to register to "
2208 "network", (sock->type == SILC_SOCKET_TYPE_SERVER ?
2209 "server" : "router")));
2210 silc_server_disconnect_remote(server, sock,
2211 SILC_STATUS_ERR_NOT_AUTHENTICATED, NULL);
2212 if (sock->user_data)
2213 silc_server_free_sock_user_data(server, sock, NULL);
2219 /* Parse the incoming packet */
2220 ret = silc_buffer_unformat(buffer,
2221 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
2222 SILC_STR_UI16_NSTRING_ALLOC(&server_name,
2226 silc_free(id_string);
2227 silc_free(server_name);
2228 silc_server_disconnect_remote(server, sock,
2229 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2231 if (sock->user_data)
2232 silc_server_free_sock_user_data(server, sock, NULL);
2236 if (id_len > buffer->len) {
2237 silc_free(id_string);
2238 silc_free(server_name);
2239 silc_server_disconnect_remote(server, sock,
2240 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2242 if (sock->user_data)
2243 silc_server_free_sock_user_data(server, sock, NULL);
2248 server_name[255] = '\0';
2251 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
2253 silc_free(id_string);
2254 silc_free(server_name);
2255 silc_server_disconnect_remote(server, sock,
2256 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2258 if (sock->user_data)
2259 silc_server_free_sock_user_data(server, sock, NULL);
2262 silc_free(id_string);
2264 /* Check for valid server ID */
2265 if (!silc_id_is_valid_server_id(server, server_id, sock)) {
2266 SILC_LOG_INFO(("Invalid server ID sent by %s (%s)",
2267 sock->ip, sock->hostname));
2268 silc_server_disconnect_remote(server, sock,
2269 SILC_STATUS_ERR_BAD_SERVER_ID, NULL);
2270 if (sock->user_data)
2271 silc_server_free_sock_user_data(server, sock, NULL);
2272 silc_free(server_name);
2276 /* Check that we do not have this ID already */
2277 server_entry = silc_idlist_find_server_by_id(server->local_list,
2278 server_id, TRUE, NULL);
2280 silc_idcache_del_by_context(server->local_list->servers, server_entry);
2282 server_entry = silc_idlist_find_server_by_id(server->global_list,
2283 server_id, TRUE, NULL);
2285 silc_idcache_del_by_context(server->global_list->servers, server_entry);
2288 /* Update server entry */
2289 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
2290 new_server->server_name = server_name;
2291 new_server->id = server_id;
2293 SILC_LOG_DEBUG(("New server id(%s)",
2294 silc_id_render(server_id, SILC_ID_SERVER)));
2296 /* Add again the entry to the ID cache. */
2297 silc_idcache_add(local ? server->local_list->servers :
2298 server->global_list->servers, server_name, server_id,
2299 new_server, 0, NULL);
2301 /* Distribute the information about new server in the SILC network
2302 to our router. If we are normal server we won't send anything
2303 since this connection must be our router connection. */
2304 if (server->server_type == SILC_ROUTER && !server->standalone &&
2305 server->router->connection != sock)
2306 silc_server_send_new_id(server, server->router->connection,
2307 TRUE, new_server->id, SILC_ID_SERVER,
2308 silc_id_get_len(server_id, SILC_ID_SERVER));
2310 if (server->server_type == SILC_ROUTER) {
2311 /* Distribute to backup routers */
2312 SilcBuffer idp = silc_id_payload_encode(new_server->id, SILC_ID_SERVER);
2313 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_ID, 0,
2314 idp->data, idp->len, FALSE, TRUE);
2315 silc_buffer_free(idp);
2318 server->stat.cell_servers++;
2321 /* Check whether this router connection has been replaced by an
2322 backup router. If it has been then we'll disable the server and will
2323 ignore everything it will send until the backup router resuming
2324 protocol has been completed. */
2325 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
2326 silc_server_backup_replaced_get(server, server_id, NULL)) {
2327 /* Send packet to the server indicating that it cannot use this
2328 connection as it has been replaced by backup router. */
2329 SilcBuffer packet = silc_buffer_alloc(2);
2330 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
2331 silc_buffer_format(packet,
2332 SILC_STR_UI_CHAR(SILC_SERVER_BACKUP_REPLACED),
2333 SILC_STR_UI_CHAR(0),
2335 silc_server_packet_send(server, sock,
2336 SILC_PACKET_RESUME_ROUTER, 0,
2337 packet->data, packet->len, TRUE);
2338 silc_buffer_free(packet);
2340 /* Mark the router disabled. The data sent earlier will go but nothing
2341 after this does not go to this connection. */
2342 idata->status |= SILC_IDLIST_STATUS_DISABLED;
2344 /* If it is router announce our stuff to it. */
2345 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
2346 server->server_type == SILC_ROUTER) {
2347 silc_server_announce_servers(server, FALSE, 0, sock);
2348 silc_server_announce_clients(server, 0, sock);
2349 silc_server_announce_channels(server, 0, sock);
2356 /* Processes incoming New ID packet. New ID Payload is used to distribute
2357 information about newly registered clients and servers. */
2359 static void silc_server_new_id_real(SilcServer server,
2360 SilcSocketConnection sock,
2361 SilcPacketContext *packet,
2364 SilcBuffer buffer = packet->buffer;
2366 SilcServerEntry router, server_entry;
2367 SilcSocketConnection router_sock;
2372 SILC_LOG_DEBUG(("Processing new ID"));
2374 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2375 server->server_type == SILC_SERVER ||
2376 packet->src_id_type != SILC_ID_SERVER)
2379 idp = silc_id_payload_parse(buffer->data, buffer->len);
2383 id_type = silc_id_payload_get_type(idp);
2385 /* Normal server cannot have other normal server connections */
2386 server_entry = (SilcServerEntry)sock->user_data;
2387 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER &&
2388 server_entry->server_type == SILC_SERVER)
2391 id = silc_id_payload_get_id(idp);
2395 /* If the packet is coming from server then use the sender as the
2396 origin of the the packet. If it came from router then check the real
2397 sender of the packet and use that as the origin. */
2398 if (sock->type == SILC_SOCKET_TYPE_SERVER) {
2399 id_list = server->local_list;
2401 router = sock->user_data;
2403 /* If the sender is backup router and ID is server (and we are not
2404 backup router) then switch the entry to global list. */
2405 if (server_entry->server_type == SILC_BACKUP_ROUTER &&
2406 id_type == SILC_ID_SERVER &&
2407 server->id_entry->server_type != SILC_BACKUP_ROUTER) {
2408 id_list = server->global_list;
2409 router_sock = server->router ? server->router->connection : sock;
2412 void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2413 packet->src_id_type);
2414 router = silc_idlist_find_server_by_id(server->global_list,
2415 sender_id, TRUE, NULL);
2417 router = silc_idlist_find_server_by_id(server->local_list,
2418 sender_id, TRUE, NULL);
2419 silc_free(sender_id);
2421 id_list = server->global_list;
2428 case SILC_ID_CLIENT:
2430 SilcClientEntry entry;
2432 /* Check that we do not have this client already */
2433 entry = silc_idlist_find_client_by_id(server->global_list,
2434 id, server->server_type,
2437 entry = silc_idlist_find_client_by_id(server->local_list,
2438 id, server->server_type,
2441 SILC_LOG_DEBUG(("Ignoring client that we already have"));
2445 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
2446 silc_id_render(id, SILC_ID_CLIENT),
2447 sock->type == SILC_SOCKET_TYPE_SERVER ?
2448 "Server" : "Router", sock->hostname));
2450 /* As a router we keep information of all global information in our
2451 global list. Cell wide information however is kept in the local
2453 entry = silc_idlist_add_client(id_list, NULL, NULL, NULL,
2454 id, router, NULL, 0);
2456 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
2458 /* Inform the sender that the ID is not usable */
2459 silc_server_send_notify_signoff(server, sock, FALSE, id, NULL);
2462 entry->nickname = NULL;
2463 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2465 if (sock->type == SILC_SOCKET_TYPE_SERVER)
2466 server->stat.cell_clients++;
2467 server->stat.clients++;
2469 /* Check if anyone is watching this nickname */
2470 if (server->server_type == SILC_ROUTER && id_list == server->local_list)
2471 silc_server_check_watcher_list(server, entry, NULL, 0);
2475 case SILC_ID_SERVER:
2477 SilcServerEntry entry;
2479 /* If the ID is mine, ignore it. */
2480 if (SILC_ID_SERVER_COMPARE(id, server->id)) {
2481 SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
2485 /* If the ID is the sender's ID, ignore it (we have it already) */
2486 if (SILC_ID_SERVER_COMPARE(id, router->id)) {
2487 SILC_LOG_DEBUG(("Ignoring sender's own ID"));
2491 /* Check that we do not have this server already */
2492 entry = silc_idlist_find_server_by_id(server->global_list,
2493 id, server->server_type,
2496 entry = silc_idlist_find_server_by_id(server->local_list,
2497 id, server->server_type,
2500 SILC_LOG_DEBUG(("Ignoring server that we already have"));
2504 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
2505 silc_id_render(id, SILC_ID_SERVER),
2506 sock->type == SILC_SOCKET_TYPE_SERVER ?
2507 "Server" : "Router", sock->hostname));
2509 /* As a router we keep information of all global information in our
2510 global list. Cell wide information however is kept in the local
2512 entry = silc_idlist_add_server(id_list, NULL, 0, id, router,
2515 SILC_LOG_ERROR(("Could not add new server to the ID Cache"));
2518 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2520 if (sock->type == SILC_SOCKET_TYPE_SERVER)
2521 server->stat.cell_servers++;
2522 server->stat.servers++;
2526 case SILC_ID_CHANNEL:
2527 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
2536 /* If the sender of this packet is server and we are router we need to
2537 broadcast this packet to other routers in the network. */
2538 if (broadcast && server->server_type == SILC_ROUTER &&
2539 sock->type == SILC_SOCKET_TYPE_SERVER &&
2540 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2541 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
2542 if (!server->standalone)
2543 silc_server_packet_send(server, server->router->connection,
2545 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2546 buffer->data, buffer->len, FALSE);
2547 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
2548 packet->type, packet->flags,
2549 packet->buffer->data, packet->buffer->len,
2554 silc_id_payload_free(idp);
2558 /* Processes incoming New ID packet. New ID Payload is used to distribute
2559 information about newly registered clients and servers. */
2561 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
2562 SilcPacketContext *packet)
2564 silc_server_new_id_real(server, sock, packet, TRUE);
2567 /* Receoved New Id List packet, list of New ID payloads inside one
2568 packet. Process the New ID payloads one by one. */
2570 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
2571 SilcPacketContext *packet)
2573 SilcPacketContext *new_id;
2577 SILC_LOG_DEBUG(("Processing New ID List"));
2579 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2580 packet->src_id_type != SILC_ID_SERVER)
2583 /* If the sender of this packet is server and we are router we need to
2584 broadcast this packet to other routers in the network. Broadcast
2585 this list packet instead of multiple New ID packets. */
2586 if (server->server_type == SILC_ROUTER &&
2587 sock->type == SILC_SOCKET_TYPE_SERVER &&
2588 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2589 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
2590 if (!server->standalone)
2591 silc_server_packet_send(server, server->router->connection,
2593 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2594 packet->buffer->data,
2595 packet->buffer->len, FALSE);
2596 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
2597 packet->type, packet->flags,
2598 packet->buffer->data, packet->buffer->len,
2602 /* Make copy of the original packet context, except for the actual
2603 data buffer, which we will here now fetch from the original buffer. */
2604 new_id = silc_packet_context_alloc();
2605 new_id->type = SILC_PACKET_NEW_ID;
2606 new_id->flags = packet->flags;
2607 new_id->src_id = packet->src_id;
2608 new_id->src_id_len = packet->src_id_len;
2609 new_id->src_id_type = packet->src_id_type;
2610 new_id->dst_id = packet->dst_id;
2611 new_id->dst_id_len = packet->dst_id_len;
2612 new_id->dst_id_type = packet->dst_id_type;
2614 idp = silc_buffer_alloc(256);
2615 new_id->buffer = idp;
2617 while (packet->buffer->len) {
2618 SILC_GET16_MSB(id_len, packet->buffer->data + 2);
2619 if ((id_len > packet->buffer->len) ||
2620 (id_len > idp->truelen))
2623 silc_buffer_pull_tail(idp, 4 + id_len);
2624 silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
2626 /* Process the New ID */
2627 silc_server_new_id_real(server, sock, new_id, FALSE);
2629 silc_buffer_push_tail(idp, 4 + id_len);
2630 silc_buffer_pull(packet->buffer, 4 + id_len);
2633 silc_buffer_free(idp);
2637 /* Received New Channel packet. Information about new channels in the
2638 network are distributed using this packet. Save the information about
2639 the new channel. This usually comes from router but also normal server
2640 can send this to notify channels it has when it connects to us. */
2642 void silc_server_new_channel(SilcServer server,
2643 SilcSocketConnection sock,
2644 SilcPacketContext *packet)
2646 SilcChannelPayload payload;
2647 SilcChannelID *channel_id;
2649 SilcUInt32 name_len;
2653 SilcServerEntry server_entry;
2654 SilcChannelEntry channel;
2656 SILC_LOG_DEBUG(("Processing New Channel"));
2658 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2659 packet->src_id_type != SILC_ID_SERVER ||
2660 server->server_type == SILC_SERVER)
2663 /* Parse the channel payload */
2664 payload = silc_channel_payload_parse(packet->buffer->data,
2665 packet->buffer->len);
2669 /* Get the channel ID */
2670 channel_id = silc_channel_get_id_parse(payload);
2672 silc_channel_payload_free(payload);
2676 channel_name = silc_channel_get_name(payload, &name_len);
2678 channel_name[255] = '\0';
2680 id = silc_channel_get_id(payload, &id_len);
2682 server_entry = (SilcServerEntry)sock->user_data;
2684 if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
2685 /* Add the channel to global list as it is coming from router. It
2686 cannot be our own channel as it is coming from router. */
2688 /* Check that we don't already have this channel */
2689 channel = silc_idlist_find_channel_by_name(server->local_list,
2690 channel_name, NULL);
2692 channel = silc_idlist_find_channel_by_name(server->global_list,
2693 channel_name, NULL);
2695 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
2696 silc_id_render(channel_id, SILC_ID_CHANNEL),
2700 silc_idlist_add_channel(server->global_list, strdup(channel_name),
2701 0, channel_id, sock->user_data, NULL, NULL, 0);
2704 channel->disabled = TRUE;
2706 server->stat.channels++;
2707 if (server->server_type == SILC_ROUTER)
2708 channel->users_resolved = TRUE;
2711 /* The channel is coming from our server, thus it is in our cell
2712 we will add it to our local list. */
2715 SILC_LOG_DEBUG(("Channel id(%s) from [Server] %s",
2716 silc_id_render(channel_id, SILC_ID_CHANNEL),
2719 /* Check that we don't already have this channel */
2720 channel = silc_idlist_find_channel_by_name(server->local_list,
2721 channel_name, NULL);
2723 channel = silc_idlist_find_channel_by_name(server->global_list,
2724 channel_name, NULL);
2726 /* If the channel does not exist, then create it. This creates a new
2727 key to the channel as well that we will send to the server. */
2729 /* The protocol says that the Channel ID's IP address must be based
2730 on the router's IP address. Check whether the ID is based in our
2731 IP and if it is not then create a new ID and enforce the server
2732 to switch the ID. */
2733 if (server_entry->server_type != SILC_BACKUP_ROUTER &&
2734 !SILC_ID_COMPARE(channel_id, server->id, server->id->ip.data_len)) {
2736 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2738 if (silc_id_create_channel_id(server, server->id, server->rng, &tmp)) {
2739 silc_server_send_notify_channel_change(server, sock, FALSE,
2741 silc_free(channel_id);
2746 /* Create the channel with the provided Channel ID */
2747 channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
2751 silc_channel_payload_free(payload);
2752 silc_free(channel_id);
2755 channel->disabled = TRUE;
2758 /* CMODE change notify is expected */
2759 /* Get the mode and set it to the channel */
2760 channel->mode = silc_channel_get_mode(payload);
2763 /* Send the new channel key to the server */
2764 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2765 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
2766 chk = silc_channel_key_payload_encode(id_len, id,
2767 strlen(channel->channel_key->
2769 channel->channel_key->cipher->name,
2770 channel->key_len / 8,
2772 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
2773 chk->data, chk->len, FALSE);
2774 silc_buffer_free(chk);
2777 /* The channel exist by that name, check whether the ID's match.
2778 If they don't then we'll force the server to use the ID we have.
2779 We also create a new key for the channel. */
2780 SilcBuffer modes = NULL, users = NULL, users_modes = NULL;
2782 if (!SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
2783 /* They don't match, send CHANNEL_CHANGE notify to the server to
2784 force the ID change. */
2785 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2786 silc_server_send_notify_channel_change(server, sock, FALSE,
2787 channel_id, channel->id);
2790 /* If the mode is different from what we have then enforce the
2792 mode = silc_channel_get_mode(payload);
2793 if (channel->mode != mode) {
2794 SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
2795 silc_server_send_notify_cmode(server, sock, FALSE, channel,
2796 channel->mode, server->id,
2797 SILC_ID_SERVER, channel->cipher,
2799 channel->passphrase,
2800 channel->founder_key);
2803 /* Create new key for the channel and send it to the server and
2804 everybody else possibly on the channel. */
2805 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
2806 if (!silc_server_create_channel_key(server, channel, 0))
2809 /* Send to the channel */
2810 silc_server_send_channel_key(server, sock, channel, FALSE);
2811 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2812 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
2814 /* Send to the server */
2815 chk = silc_channel_key_payload_encode(id_len, id,
2816 strlen(channel->channel_key->
2818 channel->channel_key->
2820 channel->key_len / 8,
2822 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
2823 chk->data, chk->len, FALSE);
2824 silc_buffer_free(chk);
2828 silc_free(channel_id);
2830 /* Since the channel is coming from server and we also know about it
2831 then send the JOIN notify to the server so that it see's our
2832 users on the channel "joining" the channel. */
2833 silc_server_announce_get_channel_users(server, channel, &modes, &users,
2836 silc_buffer_push(modes, modes->data - modes->head);
2837 silc_server_packet_send_dest(server, sock,
2838 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2839 channel->id, SILC_ID_CHANNEL,
2840 modes->data, modes->len, FALSE);
2841 silc_buffer_free(modes);
2844 silc_buffer_push(users, users->data - users->head);
2845 silc_server_packet_send(server, sock,
2846 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2847 users->data, users->len, FALSE);
2848 silc_buffer_free(users);
2851 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
2852 silc_server_packet_send_dest(server, sock,
2853 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2854 channel->id, SILC_ID_CHANNEL,
2856 users_modes->len, FALSE);
2857 silc_buffer_free(users_modes);
2862 silc_channel_payload_free(payload);
2865 /* Received New Channel List packet, list of New Channel List payloads inside
2866 one packet. Process the New Channel payloads one by one. */
2868 void silc_server_new_channel_list(SilcServer server,
2869 SilcSocketConnection sock,
2870 SilcPacketContext *packet)
2872 SilcPacketContext *new;
2874 SilcUInt16 len1, len2;
2876 SILC_LOG_DEBUG(("Processing New Channel List"));
2878 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2879 packet->src_id_type != SILC_ID_SERVER ||
2880 server->server_type == SILC_SERVER)
2883 /* If the sender of this packet is server and we are router we need to
2884 broadcast this packet to other routers in the network. Broadcast
2885 this list packet instead of multiple New Channel packets. */
2886 if (server->server_type == SILC_ROUTER &&
2887 sock->type == SILC_SOCKET_TYPE_SERVER &&
2888 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2889 SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
2890 if (!server->standalone)
2891 silc_server_packet_send(server, server->router->connection,
2893 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2894 packet->buffer->data,
2895 packet->buffer->len, FALSE);
2896 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
2897 packet->type, packet->flags,
2898 packet->buffer->data, packet->buffer->len,
2902 /* Make copy of the original packet context, except for the actual
2903 data buffer, which we will here now fetch from the original buffer. */
2904 new = silc_packet_context_alloc();
2905 new->type = SILC_PACKET_NEW_CHANNEL;
2906 new->flags = packet->flags;
2907 new->src_id = packet->src_id;
2908 new->src_id_len = packet->src_id_len;
2909 new->src_id_type = packet->src_id_type;
2910 new->dst_id = packet->dst_id;
2911 new->dst_id_len = packet->dst_id_len;
2912 new->dst_id_type = packet->dst_id_type;
2914 buffer = silc_buffer_alloc(512);
2915 new->buffer = buffer;
2917 while (packet->buffer->len) {
2918 SILC_GET16_MSB(len1, packet->buffer->data);
2919 if ((len1 > packet->buffer->len) ||
2920 (len1 > buffer->truelen))
2923 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
2924 if ((len2 > packet->buffer->len) ||
2925 (len2 > buffer->truelen))
2928 silc_buffer_pull_tail(buffer, 8 + len1 + len2);
2929 silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
2931 /* Process the New Channel */
2932 silc_server_new_channel(server, sock, new);
2934 silc_buffer_push_tail(buffer, 8 + len1 + len2);
2935 silc_buffer_pull(packet->buffer, 8 + len1 + len2);
2938 silc_buffer_free(buffer);
2942 /* Received key agreement packet. This packet is never for us. It is to
2943 the client in the packet's destination ID. Sending of this sort of packet
2944 equals sending private message, ie. it is sent point to point from
2945 one client to another. */
2947 void silc_server_key_agreement(SilcServer server,
2948 SilcSocketConnection sock,
2949 SilcPacketContext *packet)
2951 SilcSocketConnection dst_sock;
2952 SilcIDListData idata;
2954 SILC_LOG_DEBUG(("Start"));
2956 if (packet->src_id_type != SILC_ID_CLIENT ||
2957 packet->dst_id_type != SILC_ID_CLIENT)
2960 if (!packet->dst_id)
2963 /* Get the route to the client */
2964 dst_sock = silc_server_get_client_route(server, packet->dst_id,
2965 packet->dst_id_len, NULL,
2970 /* Relay the packet */
2971 silc_server_relay_packet(server, dst_sock, idata->send_key,
2972 idata->hmac_send, idata->psn_send++,
2976 /* Received connection auth request packet that is used during connection
2977 phase to resolve the mandatory authentication method. This packet can
2978 actually be received at anytime but usually it is used only during
2979 the connection authentication phase. Now, protocol says that this packet
2980 can come from client or server, however, we support only this coming
2981 from client and expect that server always knows what authentication
2984 void silc_server_connection_auth_request(SilcServer server,
2985 SilcSocketConnection sock,
2986 SilcPacketContext *packet)
2988 SilcServerConfigClient *client = NULL;
2989 SilcUInt16 conn_type;
2991 SilcAuthMethod auth_meth = SILC_AUTH_NONE;
2993 SILC_LOG_DEBUG(("Start"));
2995 if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT)
2998 /* Parse the payload */
2999 ret = silc_buffer_unformat(packet->buffer,
3000 SILC_STR_UI_SHORT(&conn_type),
3001 SILC_STR_UI_SHORT(NULL),
3006 if (conn_type != SILC_SOCKET_TYPE_CLIENT)
3009 /* Get the authentication method for the client */
3010 auth_meth = SILC_AUTH_NONE;
3011 client = silc_server_config_find_client(server, sock->ip);
3013 client = silc_server_config_find_client(server, sock->hostname);
3015 if (client->passphrase) {
3016 if (client->publickeys && !server->config->prefer_passphrase_auth)
3017 auth_meth = SILC_AUTH_PUBLIC_KEY;
3019 auth_meth = SILC_AUTH_PASSWORD;
3020 } else if (client->publickeys)
3021 auth_meth = SILC_AUTH_PUBLIC_KEY;
3024 /* Send it back to the client */
3025 silc_server_send_connection_auth_request(server, sock, conn_type, auth_meth);
3028 /* Received REKEY packet. The sender of the packet wants to regenerate
3029 its session keys. This starts the REKEY protocol. */
3031 void silc_server_rekey(SilcServer server,
3032 SilcSocketConnection sock,
3033 SilcPacketContext *packet)
3035 SilcProtocol protocol;
3036 SilcServerRekeyInternalContext *proto_ctx;
3037 SilcIDListData idata = (SilcIDListData)sock->user_data;
3039 SILC_LOG_DEBUG(("Start"));
3041 /* Allocate internal protocol context. This is sent as context
3043 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
3044 proto_ctx->server = (void *)server;
3045 proto_ctx->sock = sock;
3046 proto_ctx->responder = TRUE;
3047 proto_ctx->pfs = idata->rekey->pfs;
3049 /* Perform rekey protocol. Will call the final callback after the
3050 protocol is over. */
3051 silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
3052 &protocol, proto_ctx, silc_server_rekey_final);
3053 sock->protocol = protocol;
3055 if (proto_ctx->pfs == FALSE)
3056 /* Run the protocol */
3057 silc_protocol_execute(protocol, server->schedule, 0, 0);
3060 /* Received file transger packet. This packet is never for us. It is to
3061 the client in the packet's destination ID. Sending of this sort of packet
3062 equals sending private message, ie. it is sent point to point from
3063 one client to another. */
3065 void silc_server_ftp(SilcServer server,
3066 SilcSocketConnection sock,
3067 SilcPacketContext *packet)
3069 SilcSocketConnection dst_sock;
3070 SilcIDListData idata;
3072 SILC_LOG_DEBUG(("Start"));
3074 if (packet->src_id_type != SILC_ID_CLIENT ||
3075 packet->dst_id_type != SILC_ID_CLIENT)
3078 if (!packet->dst_id)
3081 /* Get the route to the client */
3082 dst_sock = silc_server_get_client_route(server, packet->dst_id,
3083 packet->dst_id_len, NULL,
3088 /* Relay the packet */
3089 silc_server_relay_packet(server, dst_sock, idata->send_key,
3090 idata->hmac_send, idata->psn_send++,
3096 SilcSocketConnection sock;
3097 SilcPacketContext *packet;
3099 } *SilcServerResumeResolve;
3101 SILC_SERVER_CMD_FUNC(resume_resolve)
3103 SilcServerResumeResolve r = (SilcServerResumeResolve)context;
3104 SilcServer server = r->server;
3105 SilcSocketConnection sock = r->sock;
3106 SilcServerCommandReplyContext reply = context2;
3107 SilcClientEntry client;
3109 SILC_LOG_DEBUG(("Start"));
3111 if (!reply || !silc_command_get_status(reply->payload, NULL, NULL)) {
3112 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3113 "closing connection", sock->hostname, sock->ip));
3114 silc_server_disconnect_remote(server, sock,
3115 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3116 "Resuming not possible");
3120 if (reply && silc_command_get(reply->payload) == SILC_COMMAND_WHOIS) {
3121 /* Get entry to the client, and resolve it if we don't have it. */
3122 client = silc_idlist_find_client_by_id(server->local_list,
3123 r->data, TRUE, NULL);
3125 client = silc_idlist_find_client_by_id(server->global_list,
3126 r->data, TRUE, NULL);
3128 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3129 "closing connection", sock->hostname, sock->ip));
3130 silc_server_disconnect_remote(server, sock,
3131 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3132 "Resuming not possible");
3137 if (!(client->mode & SILC_UMODE_DETACHED)) {
3138 SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, "
3139 "closing connection", sock->hostname, sock->ip));
3140 silc_server_disconnect_remote(server, sock,
3141 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3142 "Resuming not possible");
3147 /* Reprocess the packet */
3148 silc_server_resume_client(server, sock, r->packet);
3151 silc_socket_free(r->sock);
3152 silc_packet_context_free(r->packet);
3157 /* Received client resuming packet. This is used to resume detached
3158 client session. It can be sent by the client who wishes to resume
3159 but this is also sent by servers and routers to notify other routers
3160 that the client is not detached anymore. */
3162 void silc_server_resume_client(SilcServer server,
3163 SilcSocketConnection sock,
3164 SilcPacketContext *packet)
3166 SilcBuffer buffer = packet->buffer, buf;
3167 SilcIDListData idata;
3168 SilcClientEntry detached_client;
3169 SilcClientID *client_id = NULL;
3170 unsigned char *id_string, *auth = NULL;
3171 SilcUInt16 id_len, auth_len = 0;
3172 int ret, nickfail = 0;
3173 bool resolved, local, nick_change = FALSE, resolve = FALSE;
3174 SilcChannelEntry channel;
3175 SilcHashTableList htl;
3176 SilcChannelClientEntry chl;
3177 SilcServerResumeResolve r;
3179 SILC_LOG_DEBUG(("Start"));
3181 ret = silc_buffer_unformat(buffer,
3182 SILC_STR_UI16_NSTRING(&id_string, &id_len),
3185 client_id = silc_id_str2id(id_string, id_len, SILC_ID_CLIENT);
3187 if (sock->type == SILC_SOCKET_TYPE_CLIENT) {
3188 /* Client send this and is attempting to resume to old client session */
3189 SilcClientEntry client;
3193 silc_buffer_pull(buffer, 2 + id_len);
3194 auth = buffer->data;
3195 auth_len = buffer->len;
3196 silc_buffer_push(buffer, 2 + id_len);
3199 if (!client_id || auth_len < 128) {
3200 SILC_LOG_ERROR(("Client %s (%s) sent incomplete resume information, "
3201 "closing connection", sock->hostname, sock->ip));
3202 silc_server_disconnect_remote(server, sock,
3203 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3204 "Resuming not possible");
3208 /* Take client entry of this connection */
3209 client = (SilcClientEntry)sock->user_data;
3210 idata = (SilcIDListData)client;
3212 /* Get entry to the client, and resolve it if we don't have it. */
3213 detached_client = silc_server_get_client_resolve(server, client_id, FALSE,
3215 if (!detached_client) {
3217 /* The client info is being resolved. Reprocess this packet after
3218 receiving the reply to the query. */
3219 SILC_LOG_DEBUG(("Resolving client"));
3220 r = silc_calloc(1, sizeof(*r));
3224 r->sock = silc_socket_dup(sock);
3225 r->packet = silc_packet_context_dup(packet);
3226 r->data = silc_id_dup(client_id, SILC_ID_CLIENT);
3227 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
3229 silc_server_command_resume_resolve, r);
3231 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3232 "closing connection", sock->hostname, sock->ip));
3233 silc_server_disconnect_remote(server, sock,
3234 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3235 "Resuming not possible");
3240 if (!(detached_client->mode & SILC_UMODE_DETACHED))
3242 if (!silc_hash_table_count(detached_client->channels) &&
3243 detached_client->router)
3245 if (!detached_client->nickname)
3249 if (server->server_type == SILC_SERVER && !server->standalone) {
3250 /* The client info is being resolved. Reprocess this packet after
3251 receiving the reply to the query. */
3252 SILC_LOG_DEBUG(("Resolving client info"));
3253 silc_server_get_client_resolve(server, client_id, TRUE, NULL);
3254 r = silc_calloc(1, sizeof(*r));
3258 r->sock = silc_socket_dup(sock);
3259 r->packet = silc_packet_context_dup(packet);
3260 r->data = silc_id_dup(client_id, SILC_ID_CLIENT);
3261 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
3263 silc_server_command_resume_resolve, r);
3266 if (server->server_type == SILC_SERVER) {
3267 SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, "
3268 "closing connection", sock->hostname, sock->ip));
3269 silc_server_disconnect_remote(server, sock,
3270 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3271 "Resuming not possible");
3276 /* Check that we have the public key of the client, if not then we must
3277 resolve it first. */
3278 if (!detached_client->data.public_key) {
3279 if (server->server_type == SILC_SERVER && server->standalone) {
3280 silc_server_disconnect_remote(server, sock,
3281 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3282 "Resuming not possible");
3284 /* We must retrieve the detached client's public key by sending
3285 GETKEY command. Reprocess this packet after receiving the key */
3286 SilcBuffer idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
3287 SilcSocketConnection dest_sock =
3288 silc_server_get_client_route(server, NULL, 0, client_id, NULL, NULL);
3290 SILC_LOG_DEBUG(("Resolving client public key"));
3292 silc_server_send_command(server, dest_sock ? dest_sock :
3293 server->router->connection,
3294 SILC_COMMAND_GETKEY, ++server->cmd_ident,
3295 1, 1, idp->data, idp->len);
3297 r = silc_calloc(1, sizeof(*r));
3302 r->sock = silc_socket_dup(sock);
3303 r->packet = silc_packet_context_dup(packet);
3304 silc_server_command_pending(server, SILC_COMMAND_GETKEY,
3306 silc_server_command_resume_resolve, r);
3308 silc_buffer_free(idp);
3311 } else if (!silc_pkcs_public_key_compare(detached_client->data.public_key,
3312 idata->public_key)) {
3313 /* We require that the connection and resuming authentication data
3314 must be using same key pair. */
3315 silc_server_disconnect_remote(server, sock,
3316 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3317 "Resuming not possible");
3321 /* Verify the authentication payload. This has to be successful in
3322 order to allow the resuming */
3324 !silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
3325 detached_client->data.public_key, 0,
3326 idata->hash, detached_client->id,
3328 SILC_LOG_ERROR(("Client %s (%s) resume authentication failed, "
3329 "closing connection", sock->hostname, sock->ip));
3330 silc_server_disconnect_remote(server, sock,
3331 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3332 "Resuming not possible");
3336 /* Now resume the client to the network */
3338 silc_schedule_task_del_by_context(server->schedule, detached_client);
3339 sock->user_data = detached_client;
3340 detached_client->connection = sock;
3342 /* Take new keys and stuff into use in the old entry */
3343 silc_idlist_del_data(detached_client);
3344 silc_idlist_add_data(detached_client, idata);
3345 detached_client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
3346 detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
3347 detached_client->mode &= ~SILC_UMODE_DETACHED;
3349 /* Send the RESUME_CLIENT packet to our primary router so that others
3350 know this client isn't detached anymore. */
3351 buf = silc_buffer_alloc_size(2 + id_len);
3352 silc_buffer_format(buf,
3353 SILC_STR_UI_SHORT(id_len),
3354 SILC_STR_UI_XNSTRING(id_string, id_len),
3357 /* Send to primary router */
3358 if (!server->standalone)
3359 silc_server_packet_send(server, server->router->connection,
3360 SILC_PACKET_RESUME_CLIENT, 0,
3361 buf->data, buf->len, TRUE);
3363 /* As router we must deliver this packet directly to the original
3364 server whom this client was earlier. */
3365 if (server->server_type == SILC_ROUTER && detached_client->router &&
3366 detached_client->router->server_type != SILC_ROUTER)
3367 silc_server_packet_send(server, detached_client->router->connection,
3368 SILC_PACKET_RESUME_CLIENT, 0,
3369 buf->data, buf->len, TRUE);
3370 silc_buffer_free(buf);
3372 detached_client->router = NULL;
3374 /* Delete this client entry since we're resuming to old one. */
3375 server->stat.my_clients--;
3376 server->stat.clients--;
3377 if (server->stat.cell_clients)
3378 server->stat.cell_clients--;
3379 silc_server_del_from_watcher_list(server, client);
3380 silc_idlist_del_client(server->local_list, client);
3381 client = detached_client;
3383 /* If the ID is not based in our ID then change it */
3384 if (!SILC_ID_COMPARE(client->id, server->id, server->id->ip.data_len)) {
3385 while (!silc_id_create_client_id(server, server->id, server->rng,
3386 server->md5hash, client->nickname,
3390 silc_server_disconnect_remote(server, sock,
3391 SILC_STATUS_ERR_BAD_NICKNAME, NULL);
3394 snprintf(&client->nickname[strlen(client->nickname) - 1], 1,
3401 /* Notify about Client ID change, nickname doesn't actually change. */
3402 if (!server->standalone)
3403 silc_server_send_notify_nick_change(server, server->router->connection,
3404 FALSE, client->id, client_id,
3408 /* Resolve users on those channels that client has joined but we
3409 haven't resolved user list yet. */
3410 if (server->server_type == SILC_SERVER && !server->standalone) {
3411 silc_hash_table_list(client->channels, &htl);
3412 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
3413 channel = chl->channel;
3414 SILC_LOG_DEBUG(("Resolving users for %s channel",
3415 channel->channel_name));
3416 if (channel->disabled || !channel->users_resolved) {
3417 silc_server_send_command(server, server->router->connection,
3418 SILC_COMMAND_USERS, ++server->cmd_ident,
3419 1, 2, channel->channel_name,
3420 strlen(channel->channel_name));
3423 silc_hash_table_list_reset(&htl);
3426 /* Send the new client ID to the client. After this client may start
3427 receiving other packets, and may start sending packets too. */
3428 silc_server_send_new_id(server, sock, FALSE, client_id, SILC_ID_CLIENT,
3429 silc_id_get_len(client_id, SILC_ID_CLIENT));
3432 /* Send NICK change notify to channels as well. */
3433 SilcBuffer oidp, nidp;
3434 oidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3435 nidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
3436 silc_server_send_notify_on_channels(server, NULL, client,
3437 SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
3438 oidp->data, oidp->len,
3439 nidp->data, nidp->len,
3441 strlen(client->nickname));
3442 silc_buffer_free(oidp);
3443 silc_buffer_free(nidp);
3446 /* Add the client again to the ID cache to get it to correct list */
3447 if (!silc_idcache_del_by_context(server->local_list->clients, client))
3448 silc_idcache_del_by_context(server->global_list->clients, client);
3449 silc_free(client->id);
3450 client->id = client_id;
3452 silc_idcache_add(server->local_list->clients, client->nickname,
3453 client->id, client, 0, NULL);
3455 /* Send some nice info to the client */
3456 silc_server_send_connect_notifys(server, sock, client);
3458 /* Send all channel keys of channels the client has joined */
3459 silc_hash_table_list(client->channels, &htl);
3460 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
3461 bool created = FALSE;
3462 channel = chl->channel;
3464 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY)
3467 /* If we don't have channel key, then create one */
3468 if (!channel->channel_key) {
3469 if (!silc_server_create_channel_key(server, channel, 0))
3474 id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3476 silc_channel_key_payload_encode(silc_id_get_len(channel->id,
3479 strlen(channel->channel_key->
3481 channel->channel_key->cipher->name,
3482 channel->key_len / 8, channel->key);
3483 silc_free(id_string);
3485 /* Send the key packet to client */
3486 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
3487 keyp->data, keyp->len, FALSE);
3489 if (created && server->server_type == SILC_SERVER &&
3490 !server->standalone)
3491 silc_server_packet_send(server, server->router->connection,
3492 SILC_PACKET_CHANNEL_KEY, 0,
3493 keyp->data, keyp->len, FALSE);
3495 silc_buffer_free(keyp);
3497 silc_hash_table_list_reset(&htl);
3499 } else if (sock->type != SILC_SOCKET_TYPE_CLIENT) {
3500 /* Server or router sent this to us to notify that that a client has
3502 SilcServerEntry server_entry;
3503 SilcServerID *server_id;
3508 /* Get entry to the client, and resolve it if we don't have it. */
3509 detached_client = silc_idlist_find_client_by_id(server->local_list,
3510 client_id, TRUE, NULL);
3511 if (!detached_client) {
3512 detached_client = silc_idlist_find_client_by_id(server->global_list,
3513 client_id, TRUE, NULL);
3514 if (!detached_client)
3518 /* Check that the client has not been resumed already because it is
3519 protocol error to attempt to resume more than once. The client
3520 will be killed if this protocol error occurs. */
3521 if (detached_client->data.status & SILC_IDLIST_STATUS_RESUMED &&
3522 !(detached_client->mode & SILC_UMODE_DETACHED)) {
3523 /* The client is clearly attempting to resume more than once and
3524 perhaps playing around by resuming from several different places
3525 at the same time. */
3526 silc_server_kill_client(server, detached_client, NULL,
3527 server->id, SILC_ID_SERVER);
3531 /* Check whether client is detached at all */
3532 if (!(detached_client->mode & SILC_UMODE_DETACHED))
3535 /* Client is detached, and now it is resumed. Remove the detached
3536 mode and mark that it is resumed. */
3537 detached_client->mode &= ~SILC_UMODE_DETACHED;
3538 detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
3540 /* Get the new owner of the resumed client */
3541 server_id = silc_id_str2id(packet->src_id, packet->src_id_len,
3542 packet->src_id_type);
3546 /* Get server entry */
3547 server_entry = silc_idlist_find_server_by_id(server->global_list,
3548 server_id, TRUE, NULL);
3550 if (!server_entry) {
3551 server_entry = silc_idlist_find_server_by_id(server->local_list,
3552 server_id, TRUE, NULL);
3554 if (!server_entry) {
3555 silc_free(server_id);
3560 if (server->server_type == SILC_ROUTER &&
3561 sock->type == SILC_SOCKET_TYPE_ROUTER &&
3562 server_entry->server_type == SILC_ROUTER)
3565 SILC_LOG_DEBUG(("Resuming detached client"));
3567 /* Change the client to correct list. */
3568 if (!silc_idcache_del_by_context(server->local_list->clients,
3570 silc_idcache_del_by_context(server->global_list->clients,
3572 silc_idcache_add(local && server->server_type == SILC_ROUTER ?
3573 server->local_list->clients :
3574 server->global_list->clients,
3575 detached_client->nickname,
3576 detached_client->id, detached_client, FALSE, NULL);
3578 /* Change the owner of the client if needed */
3579 if (detached_client->router != server_entry)
3580 detached_client->router = server_entry;
3582 /* Update channel information regarding global clients on channel. */
3583 if (server->server_type == SILC_SERVER) {
3584 silc_hash_table_list(detached_client->channels, &htl);
3585 while (silc_hash_table_get(&htl, NULL, (void **)&chl))
3586 chl->channel->global_users =
3587 silc_server_channel_has_global(chl->channel);
3588 silc_hash_table_list_reset(&htl);
3591 silc_schedule_task_del_by_context(server->schedule, detached_client);
3593 /* If the sender of this packet is server and we are router we need to
3594 broadcast this packet to other routers in the network. */
3595 if (server->server_type == SILC_ROUTER &&
3596 sock->type == SILC_SOCKET_TYPE_SERVER &&
3597 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
3598 SILC_LOG_DEBUG(("Broadcasting received Resume Client packet"));
3599 if (!server->standalone)
3600 silc_server_packet_send(server, server->router->connection,
3602 packet->flags | SILC_PACKET_FLAG_BROADCAST,
3603 buffer->data, buffer->len, FALSE);
3604 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
3605 packet->type, packet->flags,
3606 packet->buffer->data, packet->buffer->len,
3610 silc_free(server_id);
3613 silc_free(client_id);