5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2007 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 #include "serverincludes.h"
22 #include "server_internal.h"
24 /* Received notify packet. Server can receive notify packets from router.
25 Server then relays the notify messages to clients if needed. */
27 static void silc_server_notify_process(SilcServer server,
28 SilcPacketStream sock,
32 SilcIDListData idata = silc_packet_get_context(sock);
33 SilcNotifyPayload payload;
35 SilcArgumentPayload args;
36 SilcChannelID channel_id;
38 SilcChannelEntry channel = NULL;
39 SilcClientEntry client = NULL, client2 = NULL;
40 SilcServerEntry server_entry = NULL;
41 SilcChannelClientEntry chl;
42 SilcIDCacheEntry cache = NULL;
43 SilcHashTableList htl;
45 unsigned char *tmp, *tmp2;
46 SilcUInt32 tmp_len, tmp2_len;
49 if (idata->conn_type == SILC_CONN_CLIENT) {
50 SILC_LOG_DEBUG(("Notify received from client, drop it"));
54 if (packet->src_id_type != SILC_ID_SERVER){
55 SILC_LOG_DEBUG(("Bad notify packet received"));
59 if (!packet->dst_id) {
60 SILC_LOG_DEBUG(("Bad notify packet received"));
64 /* If the packet is destined directly to a client then relay the packet
65 before processing it. */
66 if (packet->dst_id_type == SILC_ID_CLIENT) {
68 SilcPacketStream dst_sock;
70 /* Get the route to the client */
71 dst_sock = silc_server_get_client_route(server, packet->dst_id,
72 packet->dst_id_len, NULL,
75 /* Relay the packet */
76 silc_server_packet_route(server, dst_sock, packet);
79 /* Parse the Notify Payload */
80 payload = silc_notify_payload_parse(buffer->data, silc_buffer_len(buffer));
82 SILC_LOG_DEBUG(("Marlformed notify payload"));
86 /* If we are router and this packet is not already broadcast packet
87 we will broadcast it. The sending socket really cannot be router or
88 the router is buggy. If this packet is coming from router then it must
89 have the broadcast flag set already and we won't do anything. */
90 if (server->server_type == SILC_ROUTER &&
91 idata->conn_type == SILC_CONN_SERVER &&
92 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
93 SILC_LOG_DEBUG(("Broadcasting received Notify packet"));
94 if (packet->dst_id_type == SILC_ID_CHANNEL) {
95 /* Packet is destined to channel */
96 if (!silc_id_str2id(packet->dst_id, packet->dst_id_len,
97 packet->dst_id_type, &channel_id,
98 sizeof(channel_id))) {
99 SILC_LOG_DEBUG(("Malformed destination ID in notify packet"));
103 silc_server_packet_send_dest(server, SILC_PRIMARY_ROUTE(server),
104 packet->type, packet->flags |
105 SILC_PACKET_FLAG_BROADCAST,
106 &channel_id, SILC_ID_CHANNEL,
107 buffer->data, silc_buffer_len(buffer));
108 silc_server_backup_send_dest(server, (SilcServerEntry)idata,
109 packet->type, packet->flags,
110 &channel_id, SILC_ID_CHANNEL,
111 buffer->data, silc_buffer_len(buffer),
114 /* Packet is destined to client or server */
115 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
117 packet->flags | SILC_PACKET_FLAG_BROADCAST,
118 buffer->data, silc_buffer_len(buffer));
119 silc_server_backup_send(server, (SilcServerEntry)idata,
120 packet->type, packet->flags,
121 buffer->data, silc_buffer_len(buffer),
126 type = silc_notify_get_type(payload);
127 args = silc_notify_get_args(payload);
129 SILC_LOG_DEBUG(("Notify doesn't have any arguments, drop it"));
134 case SILC_NOTIFY_TYPE_JOIN:
136 * Distribute the notify to local clients on the channel
138 SILC_LOG_DEBUG(("JOIN notify"));
141 if (!silc_argument_get_decoded(args, 2, SILC_ARGUMENT_ID, &id, NULL))
144 /* Get channel entry */
145 channel = silc_idlist_find_channel_by_id(server->global_list,
146 SILC_ID_GET_ID(id), NULL);
148 channel = silc_idlist_find_channel_by_id(server->local_list,
149 SILC_ID_GET_ID(id), NULL);
151 SILC_LOG_DEBUG(("Notify for unknown channel %s",
152 silc_id_render(SILC_ID_GET_ID(id), SILC_ID_CHANNEL)));
158 if (!silc_argument_get_decoded(args, 1, SILC_ARGUMENT_ID, &id, NULL))
161 /* If the the client is not in local list we check global list (ie. the
162 channel will be global channel) and if it does not exist then create
163 entry for the client. */
164 client = silc_idlist_find_client_by_id(server->global_list,
169 client = silc_idlist_find_client_by_id(server->local_list,
174 /* If router did not find the client the it is bogus */
175 if (server->server_type != SILC_SERVER)
179 silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
180 silc_id_dup(SILC_ID_GET_ID(id),
182 (SilcServerEntry)idata, NULL);
184 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
188 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
192 /* Do not process the notify if the client is not registered */
193 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
196 /* Do not add client to channel if it is there already */
197 if (silc_server_client_on_channel(client, channel, NULL)) {
198 SILC_LOG_DEBUG(("Client already on channel %s",
199 channel->channel_name));
203 /* Send to channel */
204 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
205 FALSE, TRUE, buffer->data,
206 silc_buffer_len(buffer));
208 if (server->server_type != SILC_ROUTER &&
209 idata->conn_type == SILC_CONN_ROUTER)
210 /* The channel is global now */
211 channel->global_users = TRUE;
213 SILC_LOG_DEBUG(("Joining to channel %s", channel->channel_name));
215 /* JOIN the global client to the channel (local clients (if router
216 created the channel) is joined in the pending JOIN command). */
217 chl = silc_calloc(1, sizeof(*chl));
220 chl->client = client;
221 chl->channel = channel;
223 if (server->server_type != SILC_ROUTER ||
224 idata->conn_type == SILC_CONN_ROUTER) {
225 /* If founder auth is set, first client is not automatically founder. */
226 if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
227 /* If this is the first one on the channel then it is the founder of
228 the channel. This is done on normal server and on router if this
229 notify is coming from router */
230 if (!silc_hash_table_count(channel->user_list)) {
231 SILC_LOG_DEBUG(("Client %s is founder on channel",
232 silc_id_render(chl->client->id, SILC_ID_CLIENT)));
233 chl->mode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
238 silc_hash_table_add(channel->user_list, client, chl);
239 silc_hash_table_add(client->channels, channel, chl);
240 channel->user_count++;
241 channel->disabled = FALSE;
243 /* Update statistics */
244 if (server->server_type == SILC_ROUTER) {
245 if (idata->conn_type != SILC_CONN_ROUTER)
246 server->stat.cell_chanclients++;
247 server->stat.chanclients++;
252 case SILC_NOTIFY_TYPE_LEAVE:
254 * Distribute the notify to local clients on the channel
256 SILC_LOG_DEBUG(("LEAVE notify"));
258 if (!silc_id_str2id(packet->dst_id, packet->dst_id_len,
259 packet->dst_id_type, &channel_id,
263 /* Get channel entry */
264 channel = silc_idlist_find_channel_by_id(server->global_list,
267 channel = silc_idlist_find_channel_by_id(server->local_list,
270 SILC_LOG_DEBUG(("Notify for unknown channel %s",
271 silc_id_render(&channel_id, SILC_ID_CHANNEL)));
277 if (!silc_argument_get_decoded(args, 1, SILC_ARGUMENT_ID, &id, NULL))
280 /* Get client entry */
281 client = silc_idlist_find_client_by_id(server->global_list,
282 SILC_ID_GET_ID(id), TRUE, NULL);
284 client = silc_idlist_find_client_by_id(server->local_list,
285 SILC_ID_GET_ID(id), TRUE, NULL);
290 /* Check if on channel */
291 if (!silc_server_client_on_channel(client, channel, NULL))
294 /* Send the leave notify to channel */
295 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
296 FALSE, TRUE, buffer->data,
297 silc_buffer_len(buffer));
299 /* Remove the user from channel */
300 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
303 case SILC_NOTIFY_TYPE_SIGNOFF:
305 * Distribute the notify to local clients on the channel
307 SILC_LOG_DEBUG(("SIGNOFF notify"));
310 if (!silc_argument_get_decoded(args, 1, SILC_ARGUMENT_ID, &id, NULL))
313 /* Get client entry */
314 client = silc_idlist_find_client_by_id(server->global_list,
315 SILC_ID_GET_ID(id), TRUE, &cache);
317 client = silc_idlist_find_client_by_id(server->local_list,
318 SILC_ID_GET_ID(id), TRUE, &cache);
323 /* Get signoff message */
324 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
328 /* Update statistics */
329 server->stat.clients--;
330 if (server->stat.cell_clients)
331 server->stat.cell_clients--;
332 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
333 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
334 silc_schedule_task_del_by_context(server->schedule, client);
336 /* Remove client's public key from repository, this will free it too. */
337 if (client->data.public_key) {
338 silc_skr_del_public_key(server->repository, client->data.public_key,
340 client->data.public_key = NULL;
343 /* Remove the client from all channels. */
344 silc_server_remove_from_channels(server, NULL, client, TRUE,
347 /* Check if anyone is watching this nickname */
348 if (server->server_type == SILC_ROUTER)
349 silc_server_check_watcher_list(server, client, NULL,
350 SILC_NOTIFY_TYPE_SIGNOFF);
352 /* Remove this client from watcher list if it is */
353 silc_server_del_from_watcher_list(server, client);
355 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
357 client->router = NULL;
358 client->connection = NULL;
359 silc_dlist_del(server->expired_clients, client);
360 silc_dlist_add(server->expired_clients, client);
363 case SILC_NOTIFY_TYPE_TOPIC_SET:
365 * Distribute the notify to local clients on the channel
368 SILC_LOG_DEBUG(("TOPIC SET notify"));
371 if (!silc_argument_get_decoded(args, 1, SILC_ARGUMENT_ID, &id, NULL))
374 /* Get client entry */
375 if (id.type == SILC_ID_CLIENT) {
376 client = silc_idlist_find_client_by_id(server->global_list,
377 SILC_ID_GET_ID(id), TRUE, &cache);
379 client = silc_idlist_find_client_by_id(server->local_list,
388 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
392 if (!silc_id_str2id(packet->dst_id, packet->dst_id_len,
393 packet->dst_id_type, &channel_id,
397 /* Get channel entry */
398 channel = silc_idlist_find_channel_by_id(server->global_list,
401 channel = silc_idlist_find_channel_by_id(server->local_list,
404 SILC_LOG_DEBUG(("Notify for unknown channel %s",
405 silc_id_render(&channel_id, SILC_ID_CHANNEL)));
410 if (channel->topic && !strcmp(channel->topic, tmp)) {
411 SILC_LOG_DEBUG(("Topic is already set and same"));
416 /* Get user's channel entry and check that topic set is allowed. */
417 if (!silc_server_client_on_channel(client, channel, &chl))
419 if (channel->mode & SILC_CHANNEL_MODE_TOPIC &&
420 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
421 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
422 SILC_LOG_DEBUG(("Topic change is not allowed"));
427 /* Change the topic */
428 silc_free(channel->topic);
429 channel->topic = strdup(tmp);
431 /* Send the same notify to the channel */
432 silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
433 FALSE, TRUE, buffer->data,
434 silc_buffer_len(buffer));
437 case SILC_NOTIFY_TYPE_NICK_CHANGE:
440 * Distribute the notify to local clients on the channel
443 SilcUInt32 nickname_len;
445 SILC_LOG_DEBUG(("NICK CHANGE notify"));
447 /* Get old client ID */
448 if (!silc_argument_get_decoded(args, 1, SILC_ARGUMENT_ID, &id, NULL))
451 /* Get new client ID */
452 if (!silc_argument_get_decoded(args, 2, SILC_ARGUMENT_ID, &id2, NULL))
455 SILC_LOG_DEBUG(("Old Client ID id(%s)",
456 silc_id_render(SILC_ID_GET_ID(id), SILC_ID_CLIENT)));
457 SILC_LOG_DEBUG(("New Client ID id(%s)",
458 silc_id_render(SILC_ID_GET_ID(id2), SILC_ID_CLIENT)));
460 /* From protocol version 1.1 we also get the new nickname */
461 nickname = silc_argument_get_arg_type(args, 3, &nickname_len);;
463 /* Replace the Client ID */
464 client = silc_idlist_replace_client_id(server,
467 SILC_ID_GET_ID(id2), nickname);
469 client = silc_idlist_replace_client_id(server,
472 SILC_ID_GET_ID(id2), nickname);
475 /* Send the NICK_CHANGE notify type to local clients on the channels
476 this client is joined to. */
477 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
478 tmp2 = silc_argument_get_arg_type(args, 2, &tmp2_len);
479 silc_server_send_notify_on_channels(server, client, client,
480 SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
481 tmp, tmp_len, tmp2, tmp2_len,
489 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
491 * Distribute the notify to local clients on the channel
494 SILC_LOG_DEBUG(("CMODE CHANGE notify"));
497 if (!silc_argument_get_decoded(args, 1, SILC_ARGUMENT_ID, &id, NULL))
500 /* Get client entry */
501 if (id.type == SILC_ID_CLIENT) {
502 client = silc_idlist_find_client_by_id(server->global_list,
503 SILC_ID_GET_ID(id), TRUE, &cache);
505 client = silc_idlist_find_client_by_id(server->local_list,
513 if (!silc_id_str2id(packet->dst_id, packet->dst_id_len,
514 packet->dst_id_type, &channel_id,
518 /* Get channel entry */
519 channel = silc_idlist_find_channel_by_id(server->global_list,
522 channel = silc_idlist_find_channel_by_id(server->local_list,
525 SILC_LOG_DEBUG(("Notify for unknown channel %s",
526 silc_id_render(&channel_id, SILC_ID_CHANNEL)));
532 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
535 SILC_GET32_MSB(mode, tmp);
537 /* Check if mode changed */
538 if (channel->mode == mode) {
539 SILC_LOG_DEBUG(("Mode is changed already"));
541 /* If this mode change has founder mode then we'll enforce the
542 change so that the server gets the real founder public key */
543 if (server->server_type != SILC_SERVER &&
544 sock != SILC_PRIMARY_ROUTE(server) &&
545 mode & SILC_CHANNEL_MODE_FOUNDER_AUTH && channel->founder_key) {
546 SILC_LOG_DEBUG(("Sending founder public key to server"));
547 silc_server_send_notify_cmode(server, sock, FALSE, channel,
548 channel->mode, server->id,
549 SILC_ID_SERVER, channel->cipher,
552 channel->founder_key, NULL);
555 /* If we received same mode from our primary check whether founder
556 mode and key in the notify is set. We update the founder key
557 here since we may have wrong one */
558 if (server->server_type != SILC_ROUTER &&
559 sock == SILC_PRIMARY_ROUTE(server) &&
560 mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
561 SILC_LOG_DEBUG(("Founder public key received from router"));
562 tmp = silc_argument_get_arg_type(args, 6, &tmp_len);
566 if (channel->founder_key)
567 silc_pkcs_public_key_free(channel->founder_key);
568 channel->founder_key = NULL;
569 silc_public_key_payload_decode(tmp, tmp_len,
570 &channel->founder_key);
573 /* Check also for channel public key list */
574 if (server->server_type == SILC_SERVER &&
575 sock == SILC_PRIMARY_ROUTE(server) &&
576 mode & SILC_CHANNEL_MODE_CHANNEL_AUTH) {
579 unsigned char mask[4], ulimit[4];
581 SILC_LOG_DEBUG(("Channel public key list received from router"));
582 tmp = silc_argument_get_arg_type(args, 7, &tmp_len);
586 /* Set the router's list, and send the notify to channel too so that
587 channel gets the list */
588 silc_server_set_channel_pk_list(server, sock, channel, tmp, tmp_len);
589 chpklist = silc_server_get_channel_pk_list(server, channel,
593 sidp = silc_id_payload_encode(server->router->id, SILC_ID_SERVER);
594 SILC_PUT32_MSB(channel->mode, mask);
595 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
596 SILC_PUT32_MSB(channel->user_limit, ulimit);
597 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
598 SILC_NOTIFY_TYPE_CMODE_CHANGE, 8,
599 sidp->data, silc_buffer_len(sidp),
603 strlen(channel->cipher) : 0,
606 strlen(channel->hmac_name) : 0,
608 channel->passphrase ?
609 strlen(channel->passphrase) : 0,
612 silc_buffer_len(chpklist),
614 SILC_CHANNEL_MODE_ULIMIT ?
617 SILC_CHANNEL_MODE_ULIMIT ?
618 sizeof(ulimit) : 0));
619 silc_buffer_free(sidp);
620 silc_buffer_free(chpklist);
627 /* Get user's channel entry and check that mode change is allowed */
629 if (!silc_server_client_on_channel(client, channel, &chl))
631 if (!silc_server_check_cmode_rights(server, channel, chl, mode)) {
632 SILC_LOG_DEBUG(("CMODE change is not allowed"));
633 silc_server_send_notify_cmode(server, sock, FALSE, channel,
634 channel->mode, server->id,
635 SILC_ID_SERVER, channel->cipher,
638 channel->founder_key, NULL);
642 /* Assure that server is not removing founder mode from us */
643 if (server->server_type == SILC_ROUTER &&
644 sock != SILC_PRIMARY_ROUTE(server) &&
645 channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH &&
646 !(mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
647 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
648 silc_server_send_notify_cmode(server, sock, FALSE, channel,
649 channel->mode, server->id,
650 SILC_ID_SERVER, channel->cipher,
653 channel->founder_key, NULL);
657 /* If server is adding founder mode, check whether there is founder
658 on channel already and is not from this server */
659 if (server->server_type == SILC_ROUTER &&
660 sock != SILC_PRIMARY_ROUTE(server) &&
661 mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
662 silc_hash_table_list(channel->user_list, &htl);
663 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
664 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO &&
665 chl->client->router != (SilcServerEntry)idata) {
666 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
667 silc_server_send_notify_cmode(server, sock, FALSE, channel,
668 channel->mode, server->id,
669 SILC_ID_SERVER, channel->cipher,
672 channel->founder_key, NULL);
673 silc_hash_table_list_reset(&htl);
676 silc_hash_table_list_reset(&htl);
680 /* If the channel had private keys set and the mode was removed then
681 we must re-generate and re-distribute a new channel key */
682 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY &&
683 !(mode & SILC_CHANNEL_MODE_PRIVKEY)) {
684 /* Re-generate channel key */
685 if (!silc_server_create_channel_key(server, channel, 0))
688 /* Send the channel key. This sends it to our local clients and if
689 we are normal server to our router as well. */
690 silc_server_send_channel_key(server, NULL, channel,
691 server->server_type == SILC_ROUTER ?
692 FALSE : !server->standalone);
696 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
698 unsigned char hash[SILC_HASH_MAXLEN];
701 silc_hmac_free(channel->hmac);
702 if (!silc_hmac_alloc(tmp, NULL, &channel->hmac))
705 /* Set the HMAC key out of current channel key. The client must do
707 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key,
708 channel->key_len / 8, hash);
709 silc_hmac_set_key(channel->hmac, hash,
710 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
711 memset(hash, 0, sizeof(hash));
714 /* Get the passphrase */
715 tmp = silc_argument_get_arg_type(args, 5, &tmp_len);
717 silc_free(channel->passphrase);
718 channel->passphrase = silc_memdup(tmp, tmp_len);
721 /* Get founder public key */
722 tmp = silc_argument_get_arg_type(args, 6, &tmp_len);
723 if (tmp && mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
724 if (channel->founder_key)
725 silc_pkcs_public_key_free(channel->founder_key);
726 channel->founder_key = NULL;
727 SILC_LOG_DEBUG(("Founder public key received"));
728 if (!silc_public_key_payload_decode(tmp, tmp_len,
729 &channel->founder_key)) {
730 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
731 mode &= ~SILC_CHANNEL_MODE_FOUNDER_AUTH;
732 silc_server_send_notify_cmode(server, sock, FALSE, channel,
733 mode, server->id, SILC_ID_SERVER,
736 channel->passphrase, NULL, NULL);
737 if (channel->founder_key)
738 silc_pkcs_public_key_free(channel->founder_key);
739 channel->founder_key = NULL;
743 if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH && !channel->founder_key &&
744 server->server_type == SILC_ROUTER) {
745 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
746 mode &= ~SILC_CHANNEL_MODE_FOUNDER_AUTH;
747 silc_server_send_notify_cmode(server, sock, FALSE, channel,
748 mode, server->id, SILC_ID_SERVER,
751 channel->passphrase, NULL, NULL);
754 /* Process channel public key(s). */
755 tmp = silc_argument_get_arg_type(args, 7, &tmp_len);
756 if (tmp && mode & SILC_CHANNEL_MODE_CHANNEL_AUTH) {
758 SILC_LOG_DEBUG(("Channel public key list received from router"));
761 silc_server_set_channel_pk_list(server, sock, channel, tmp, tmp_len);
763 /* If list was set already we will enforce the same list to server. */
764 if (ret == SILC_STATUS_ERR_OPERATION_ALLOWED) {
765 SilcBuffer chpklist = silc_server_get_channel_pk_list(server, channel,
767 silc_server_send_notify_cmode(server, sock, FALSE, channel,
768 mode, server->id, SILC_ID_SERVER,
771 channel->passphrase, NULL,
773 silc_buffer_free(chpklist);
777 /* Get the user limit */
778 tmp = silc_argument_get_arg_type(args, 8, &tmp_len);
779 if (tmp && tmp_len == 4 && mode & SILC_CHANNEL_MODE_ULIMIT)
780 SILC_GET32_MSB(channel->user_limit, tmp);
782 /* Send the same notify to the channel */
783 silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
784 FALSE, TRUE, buffer->data,
785 silc_buffer_len(buffer));
788 channel->mode = mode;
790 /* Cleanup if some modes are removed */
792 if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) &&
793 channel->founder_key) {
794 silc_pkcs_public_key_free(channel->founder_key);
795 channel->founder_key = NULL;
798 if (!(channel->mode & SILC_CHANNEL_MODE_CHANNEL_AUTH) &&
799 channel->channel_pubkeys) {
800 silc_hash_table_free(channel->channel_pubkeys);
801 channel->channel_pubkeys = NULL;
806 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
809 * Distribute the notify to local clients on the channel
811 SilcChannelClientEntry chl2 = NULL;
812 SilcBool notify_sent = FALSE;
814 SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
817 if (!silc_argument_get_decoded(args, 1, SILC_ARGUMENT_ID, &id, NULL))
820 /* Get client entry */
821 if (id.type == SILC_ID_CLIENT) {
822 client = silc_idlist_find_client_by_id(server->global_list,
826 client = silc_idlist_find_client_by_id(server->local_list,
834 if (!silc_id_str2id(packet->dst_id, packet->dst_id_len,
835 packet->dst_id_type, &channel_id,
839 /* Get channel entry */
840 channel = silc_idlist_find_channel_by_id(server->global_list,
843 channel = silc_idlist_find_channel_by_id(server->local_list,
846 SILC_LOG_DEBUG(("Notify for unknown channel %s",
847 silc_id_render(&channel_id, SILC_ID_CHANNEL)));
853 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
857 SILC_GET32_MSB(mode, tmp);
859 /* Get target client */
860 if (!silc_argument_get_decoded(args, 3, SILC_ARGUMENT_ID, &id, NULL))
863 /* Get client entry */
864 client2 = silc_idlist_find_client_by_id(server->global_list,
865 SILC_ID_GET_ID(id), TRUE, NULL);
867 client2 = silc_idlist_find_client_by_id(server->local_list,
875 /* Check that sender is on channel */
876 if (!silc_server_client_on_channel(client, channel, &chl))
879 if (client != client2 && server->server_type == SILC_ROUTER) {
880 /* Sender must be operator */
881 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
882 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
883 SILC_LOG_DEBUG(("CUMODE change is not allowed"));
887 if (!silc_server_client_on_channel(client2, channel, &chl))
890 /* If target is founder mode change is not allowed. */
891 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
892 SILC_LOG_DEBUG(("CUMODE change is not allowed"));
898 /* Get target channel user entry */
899 if (!silc_server_client_on_channel(client2, channel, &chl))
902 if (server->server_type == SILC_SERVER && chl->mode == mode) {
903 SILC_LOG_DEBUG(("Mode is changed already"));
907 /* Check whether to give founder rights to this user or not. The
908 problem here is that we get only the public key of the client,
909 but no authentication data. We must assume that server has
910 already authenticated the user (and thus we must trust the
912 if (mode & SILC_CHANNEL_UMODE_CHANFO &&
913 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO) &&
914 server->server_type == SILC_ROUTER &&
915 sock != SILC_PRIMARY_ROUTE(server)) {
916 SilcPublicKey founder_key = NULL;
918 /* If channel doesn't have founder auth mode then it's impossible
919 that someone would be getting founder rights with CUMODE command.
920 In that case there already either is founder or there isn't
921 founder at all on the channel (valid only when 'client' is
923 if (client && !(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
924 /* Force the mode to not have founder mode */
925 chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
926 silc_server_force_cumode_change(server, sock, channel, chl, mode);
931 /* Get the founder of the channel and if found then this client
932 cannot be the founder since there already is one. */
933 silc_hash_table_list(channel->user_list, &htl);
934 while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
935 if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
936 SILC_LOG_DEBUG(("Founder already on channel"));
937 chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
938 silc_server_force_cumode_change(server, sock, channel,
943 silc_hash_table_list_reset(&htl);
944 if (!(mode & SILC_CHANNEL_UMODE_CHANFO))
947 /* Founder not found on the channel. Since the founder auth mode
948 is set on the channel now check whether this is the client that
949 originally set the mode. */
951 if (channel->founder_key) {
952 /* Get public key that must be present in notify */
953 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
954 if (!tmp || !silc_public_key_payload_decode(tmp, tmp_len,
956 chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
957 SILC_LOG_DEBUG(("Founder public key not present"));
958 silc_server_force_cumode_change(server, sock, channel, chl, mode);
963 /* Now match the public key we have cached and public key sent.
965 if (!silc_pkcs_public_key_compare(channel->founder_key,
967 chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
968 SILC_LOG_DEBUG(("Founder public key mismatch"));
969 silc_server_force_cumode_change(server, sock, channel, chl, mode);
975 /* There cannot be anyone else as founder on the channel now. This
976 client is definitely the founder due to this 'authentication'.
977 We trust the server did the actual signature verification
978 earlier (bad, yes). */
979 silc_hash_table_list(channel->user_list, &htl);
980 while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
981 if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
982 chl2->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
983 SILC_LOG_DEBUG(("Removing old founder rights, new authenticated"));
984 silc_server_force_cumode_change(server, NULL, channel, chl2,
988 silc_hash_table_list_reset(&htl);
991 silc_pkcs_public_key_free(founder_key);
994 if (server->server_type != SILC_SERVER && chl->mode == mode) {
995 SILC_LOG_DEBUG(("Mode is changed already"));
999 SILC_LOG_DEBUG(("Changing %s channel user mode",
1000 chl->client->nickname ? chl->client->nickname :
1001 (unsigned char *)""));
1003 /* Change the mode */
1006 /* Send the same notify to the channel */
1008 silc_server_packet_send_to_channel(server, sock, channel,
1010 FALSE, TRUE, buffer->data,
1011 silc_buffer_len(buffer));
1016 case SILC_NOTIFY_TYPE_INVITE:
1018 if (packet->dst_id_type == SILC_ID_CLIENT)
1021 SILC_LOG_DEBUG(("INVITE notify"));
1023 /* Get Channel ID */
1024 if (!silc_argument_get_decoded(args, 1, SILC_ARGUMENT_ID, &id, NULL))
1027 /* Get channel entry */
1028 channel = silc_idlist_find_channel_by_id(server->global_list,
1029 SILC_ID_GET_ID(id), NULL);
1031 channel = silc_idlist_find_channel_by_id(server->local_list,
1032 SILC_ID_GET_ID(id), NULL);
1034 SILC_LOG_DEBUG(("Notify for unknown channel %s",
1035 silc_id_render(SILC_ID_GET_ID(id), SILC_ID_CHANNEL)));
1040 /* Get the invite action */
1041 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
1042 if (tmp && tmp_len == 1) {
1043 SilcUInt8 action = (SilcUInt8)tmp[0];
1044 SilcUInt16 iargc = 0;
1045 SilcArgumentPayload iargs;
1047 /* Get invite list */
1048 tmp = silc_argument_get_arg_type(args, 5, &tmp_len);
1049 if (!tmp || tmp_len < 2)
1052 /* Parse the arguments to see they are constructed correctly */
1053 SILC_GET16_MSB(iargc, tmp);
1054 iargs = silc_argument_payload_parse(tmp + 2, tmp_len - 2, iargc);
1058 if (!channel->invite_list)
1059 channel->invite_list =
1060 silc_hash_table_alloc(0, silc_hash_ptr,
1062 silc_server_inviteban_destruct, channel, TRUE);
1064 /* Proces the invite action */
1065 if (!silc_server_inviteban_process(server, channel->invite_list, action,
1068 silc_argument_payload_free(iargs);
1070 /* If we are router we must send this notify to our local servers on
1071 the channel. Normal server does nothing. The notify is not
1073 if (server->server_type == SILC_ROUTER)
1074 silc_server_packet_send_to_channel(server, sock, channel,
1075 packet->type, FALSE, FALSE,
1077 silc_buffer_len(buffer));
1082 case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
1084 * Distribute to the local clients on the channel and change the
1088 SILC_LOG_DEBUG(("CHANNEL CHANGE"));
1090 if (idata->conn_type != SILC_CONN_ROUTER)
1093 /* Get the old Channel ID */
1094 if (!silc_argument_get_decoded(args, 1, SILC_ARGUMENT_ID, &id, NULL))
1097 /* Get the channel entry */
1098 channel = silc_idlist_find_channel_by_id(server->local_list,
1099 SILC_ID_GET_ID(id), NULL);
1101 channel = silc_idlist_find_channel_by_id(server->global_list,
1102 SILC_ID_GET_ID(id), NULL);
1104 SILC_LOG_DEBUG(("Notify for unknown channel %s",
1105 silc_id_render(SILC_ID_GET_ID(id), SILC_ID_CHANNEL)));
1110 /* Send the notify to the channel */
1111 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
1112 FALSE, TRUE, buffer->data,
1113 silc_buffer_len(buffer));
1115 /* Get the new Channel ID */
1116 if (!silc_argument_get_decoded(args, 2, SILC_ARGUMENT_ID, &id2, NULL))
1119 SILC_LOG_DEBUG(("Old Channel ID id(%s)",
1120 silc_id_render(SILC_ID_GET_ID(id), SILC_ID_CHANNEL)));
1121 SILC_LOG_DEBUG(("New Channel ID id(%s)",
1122 silc_id_render(SILC_ID_GET_ID(id2), SILC_ID_CHANNEL)));
1124 /* Replace the Channel ID */
1126 if (!silc_idlist_replace_channel_id(server->local_list,
1128 SILC_ID_GET_ID(id2)))
1129 if (!silc_idlist_replace_channel_id(server->global_list,
1131 SILC_ID_GET_ID(id2)))
1135 SilcBuffer modes = NULL, users = NULL, users_modes = NULL;
1137 /* Re-announce this channel which ID was changed. */
1138 silc_server_send_new_channel(server, sock, FALSE, channel->channel_name,
1140 silc_id_get_len(channel->id,
1144 /* Re-announce our clients on the channel as the ID has changed now */
1145 silc_server_announce_get_channel_users(server, channel, &modes, &users,
1148 silc_buffer_push(users, users->data - users->head);
1149 silc_server_packet_send(server, sock,
1150 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1151 users->data, silc_buffer_len(users));
1152 silc_buffer_free(users);
1155 silc_buffer_push(modes, modes->data - modes->head);
1156 silc_server_packet_send_dest(server, sock,
1157 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1158 channel->id, SILC_ID_CHANNEL,
1159 modes->data, silc_buffer_len(modes));
1160 silc_buffer_free(modes);
1163 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
1164 silc_server_packet_send_dest(server, sock,
1165 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1166 channel->id, SILC_ID_CHANNEL,
1168 silc_buffer_len(users_modes));
1169 silc_buffer_free(users_modes);
1172 /* Re-announce channel's topic */
1173 if (channel->topic) {
1174 silc_server_send_notify_topic_set(server, sock,
1175 server->server_type == SILC_ROUTER ?
1176 TRUE : FALSE, channel,
1177 server->id, SILC_ID_SERVER,
1184 case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
1186 * Remove the server entry and all clients that this server owns.
1189 SILC_LOG_DEBUG(("SERVER SIGNOFF notify"));
1191 /* Backup router shouldn't accept SERVER_SIGNOFF's from normal routers
1192 when the backup isn't acting as primary router. */
1193 if (idata->conn_type == SILC_CONN_SERVER &&
1194 server->backup_router && server->server_type == SILC_BACKUP_ROUTER)
1198 if (!silc_argument_get_decoded(args, 1, SILC_ARGUMENT_ID, &id, NULL))
1201 /* If the ID is mine, this notify is not allowed. */
1202 if (SILC_ID_SERVER_COMPARE(SILC_ID_GET_ID(id), server->id)) {
1203 SILC_LOG_DEBUG(("Ignoring my own ID for SERVER_SIGNOFF"));
1207 /* Get server entry */
1208 server_entry = silc_idlist_find_server_by_id(server->global_list,
1212 if (!server_entry) {
1213 server_entry = silc_idlist_find_server_by_id(server->local_list,
1217 if (!server_entry) {
1218 /* If we are normal server then we might not have the server. Check
1219 whether router was kind enough to send the list of all clients
1220 that actually was to be removed. Remove them if the list is
1222 if (server->server_type != SILC_ROUTER &&
1223 silc_argument_get_arg_num(args) > 1) {
1226 for (i = 1; i < silc_argument_get_arg_num(args); i++) {
1228 if (!silc_argument_get_decoded(args, i + 1, SILC_ARGUMENT_ID,
1232 /* Get client entry */
1233 client = silc_idlist_find_client_by_id(server->global_list,
1234 SILC_ID_GET_ID(id2),
1238 client = silc_idlist_find_client_by_id(server->local_list,
1239 SILC_ID_GET_ID(id2),
1246 /* Update statistics */
1247 server->stat.clients--;
1248 if (server->stat.cell_clients)
1249 server->stat.cell_clients--;
1250 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
1251 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
1253 /* Remove the client from all channels. */
1254 silc_server_remove_from_channels(server, NULL, client,
1255 TRUE, NULL, FALSE, FALSE);
1257 /* Check if anyone is watching this nickname */
1258 if (server->server_type == SILC_ROUTER)
1259 silc_server_check_watcher_list(server, client, NULL,
1260 SILC_NOTIFY_TYPE_SERVER_SIGNOFF);
1262 /* Remove this client from watcher list if it is */
1264 silc_server_del_from_watcher_list(server, client);
1266 /* Remove the client */
1267 silc_idlist_del_data(client);
1268 silc_idlist_del_client(local ? server->local_list :
1269 server->global_list, client);
1277 /* For local entrys SERVER_SIGNOFF is processed only on backup router.
1278 It is possible that router sends server signoff for a server. If
1279 backup router has it as local connection it will be closed. */
1280 if (SILC_IS_LOCAL(server_entry)) {
1281 if (server->server_type == SILC_BACKUP_ROUTER) {
1282 sock = server_entry->connection;
1283 SILC_LOG_DEBUG(("Closing connection after SERVER_SIGNOFF"));
1284 silc_server_free_sock_user_data(server, sock, NULL);
1285 silc_server_close_connection(server, sock);
1291 /* Remove all servers that are originated from this server, and
1292 remove the clients of those servers too. */
1293 silc_server_remove_servers_by_server(server, server_entry, TRUE);
1295 /* Remove the clients that this server owns as they will become
1297 silc_server_remove_clients_by_server(server, server_entry->router,
1298 server_entry, TRUE);
1299 silc_server_backup_del(server, server_entry);
1301 /* Remove the server entry */
1302 silc_idlist_del_server(local ? server->local_list :
1303 server->global_list, server_entry);
1305 /* Update statistics */
1306 if (server->server_type == SILC_ROUTER)
1307 server->stat.servers--;
1311 case SILC_NOTIFY_TYPE_KICKED:
1313 * Distribute the notify to local clients on the channel
1316 SILC_LOG_DEBUG(("KICKED notify"));
1318 if (!silc_id_str2id(packet->dst_id, packet->dst_id_len,
1319 packet->dst_id_type, &channel_id,
1320 sizeof(channel_id)))
1323 /* Get channel entry */
1324 channel = silc_idlist_find_channel_by_id(server->global_list,
1327 channel = silc_idlist_find_channel_by_id(server->local_list,
1330 SILC_LOG_DEBUG(("Notify for unknown channel %s",
1331 silc_id_render(SILC_ID_GET_ID(id), SILC_ID_CHANNEL)));
1337 if (!silc_argument_get_decoded(args, 1, SILC_ARGUMENT_ID, &id, NULL))
1340 /* If the the client is not in local list we check global list */
1341 client = silc_idlist_find_client_by_id(server->global_list,
1342 SILC_ID_GET_ID(id), TRUE, NULL);
1344 client = silc_idlist_find_client_by_id(server->local_list,
1345 SILC_ID_GET_ID(id), TRUE, NULL);
1350 /* If target is founder they cannot be kicked */
1351 if (!silc_server_client_on_channel(client, channel, &chl))
1353 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO)
1356 /* Get the kicker's Client ID */
1357 if (!silc_argument_get_decoded(args, 3, SILC_ARGUMENT_ID, &id, NULL))
1360 /* If the the client is not in local list we check global list */
1361 client2 = silc_idlist_find_client_by_id(server->global_list,
1362 SILC_ID_GET_ID(id), TRUE, NULL);
1364 client2 = silc_idlist_find_client_by_id(server->local_list,
1365 SILC_ID_GET_ID(id), TRUE, NULL);
1370 /* Kicker must be operator on channel */
1371 if (!silc_server_client_on_channel(client2, channel, &chl))
1373 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
1374 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1375 SILC_LOG_DEBUG(("Kicking is not allowed"));
1379 /* Send to channel */
1380 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
1381 FALSE, TRUE, buffer->data,
1382 silc_buffer_len(buffer));
1384 /* Remove the client from channel's invite list */
1385 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
1387 SilcArgumentPayload iargs;
1388 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1389 ab = silc_argument_payload_encode_one(NULL, tmp, tmp_len, 3);
1390 iargs = silc_argument_payload_parse(ab->data, silc_buffer_len(ab), 1);
1391 silc_server_inviteban_process(server, channel->invite_list, 1, iargs);
1392 silc_buffer_free(ab);
1393 silc_argument_payload_free(iargs);
1396 /* Remove the client from channel */
1397 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
1401 case SILC_NOTIFY_TYPE_KILLED:
1404 * Distribute the notify to local clients on channels
1406 unsigned char *comment;
1407 SilcUInt32 comment_len;
1409 SILC_LOG_DEBUG(("KILLED notify"));
1412 if (!silc_argument_get_decoded(args, 1, SILC_ARGUMENT_ID, &id, NULL))
1415 /* If the the client is not in local list we check global list */
1416 client = silc_idlist_find_client_by_id(server->global_list,
1417 SILC_ID_GET_ID(id), TRUE, &cache);
1419 client = silc_idlist_find_client_by_id(server->local_list,
1426 /* If the client is one of ours, then close the connection to the
1427 client now. This removes the client from all channels as well. */
1428 if (packet->dst_id_type == SILC_ID_CLIENT && client->connection) {
1429 sock = client->connection;
1430 silc_server_free_client_data(server, NULL, client, FALSE, NULL);
1431 silc_server_close_connection(server, sock);
1436 comment = silc_argument_get_arg_type(args, 2, &comment_len);
1437 if (comment_len > 128)
1440 /* Get the killer's Client ID */
1441 if (!silc_argument_get_decoded(args, 3, SILC_ARGUMENT_ID, &id, NULL))
1444 if (id.type == SILC_ID_CLIENT) {
1445 /* If the the client is not in local list we check global list */
1446 client2 = silc_idlist_find_client_by_id(server->global_list,
1450 client2 = silc_idlist_find_client_by_id(server->local_list,
1457 /* Killer must be router operator */
1458 if (server->server_type != SILC_SERVER &&
1459 !(client2->mode & SILC_UMODE_ROUTER_OPERATOR)) {
1460 SILC_LOG_DEBUG(("Killing is not allowed"));
1465 /* Send the notify to local clients on the channels except to the
1466 client who is killed. */
1467 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1468 tmp2 = silc_argument_get_arg_type(args, 3, &tmp2_len);
1469 silc_server_send_notify_on_channels(server, client, client,
1470 SILC_NOTIFY_TYPE_KILLED, 3,
1471 tmp, tmp_len, comment, comment_len,
1474 /* Remove the client from all channels */
1475 silc_server_remove_from_channels(server, NULL, client, FALSE, NULL,
1478 /* Check if anyone is watching this nickname */
1479 if (server->server_type == SILC_ROUTER)
1480 silc_server_check_watcher_list(server, client, NULL,
1481 SILC_NOTIFY_TYPE_KILLED);
1483 /* Remove client's public key from repository, this will free it too. */
1484 if (client->data.public_key) {
1485 silc_skr_del_public_key(server->repository, client->data.public_key,
1487 client->data.public_key = NULL;
1490 /* Update statistics */
1491 server->stat.clients--;
1492 if (server->stat.cell_clients)
1493 server->stat.cell_clients--;
1494 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
1495 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
1497 if (SILC_IS_LOCAL(client)) {
1498 server->stat.my_clients--;
1499 silc_schedule_task_del_by_context(server->schedule, client);
1500 silc_idlist_del_data(client);
1504 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
1506 client->router = NULL;
1507 client->connection = NULL;
1508 silc_dlist_del(server->expired_clients, client);
1509 silc_dlist_add(server->expired_clients, client);
1513 case SILC_NOTIFY_TYPE_UMODE_CHANGE:
1515 * Save the mode of the client.
1518 SILC_LOG_DEBUG(("UMODE_CHANGE notify"));
1521 if (!silc_argument_get_decoded(args, 1, SILC_ARGUMENT_ID, &id, NULL))
1524 /* Get client entry */
1525 client = silc_idlist_find_client_by_id(server->global_list,
1526 SILC_ID_GET_ID(id), TRUE, NULL);
1528 client = silc_idlist_find_client_by_id(server->local_list,
1529 SILC_ID_GET_ID(id), TRUE, NULL);
1535 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1538 SILC_GET32_MSB(mode, tmp);
1540 /* Remove internal resumed flag if client is marked detached now */
1541 if (mode & SILC_UMODE_DETACHED)
1542 client->data.status &= ~SILC_IDLIST_STATUS_RESUMED;
1544 /* Update statistics */
1545 if (server->server_type == SILC_ROUTER) {
1546 if (mode & SILC_UMODE_GONE) {
1547 if (!(client->mode & SILC_UMODE_GONE))
1548 server->stat.aways++;
1550 if (client->mode & SILC_UMODE_GONE)
1551 server->stat.aways--;
1553 if (mode & SILC_UMODE_DETACHED) {
1554 if (!(client->mode & SILC_UMODE_DETACHED))
1555 server->stat.detached++;
1557 if (client->mode & SILC_UMODE_DETACHED)
1558 server->stat.detached--;
1561 SILC_UMODE_STATS_UPDATE(server, SILC_UMODE_SERVER_OPERATOR);
1562 SILC_UMODE_STATS_UPDATE(router, SILC_UMODE_ROUTER_OPERATOR);
1564 /* Change the mode */
1565 client->mode = mode;
1567 /* Check if anyone is watching this nickname */
1568 if (server->server_type == SILC_ROUTER)
1569 silc_server_check_watcher_list(server, client, NULL,
1570 SILC_NOTIFY_TYPE_UMODE_CHANGE);
1574 case SILC_NOTIFY_TYPE_BAN:
1579 SILC_LOG_DEBUG(("BAN notify"));
1581 /* Get Channel ID */
1582 if (!silc_argument_get_decoded(args, 1, SILC_ARGUMENT_ID, &id, NULL))
1585 /* Get channel entry */
1586 channel = silc_idlist_find_channel_by_id(server->global_list,
1587 SILC_ID_GET_ID(id), NULL);
1589 channel = silc_idlist_find_channel_by_id(server->local_list,
1590 SILC_ID_GET_ID(id), NULL);
1592 SILC_LOG_DEBUG(("Notify for unknown channel %s",
1593 silc_id_render(SILC_ID_GET_ID(id), SILC_ID_CHANNEL)));
1598 /* Get the ban action */
1599 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1600 if (tmp && tmp_len == 1) {
1601 SilcUInt8 action = (SilcUInt8)tmp[0];
1602 SilcUInt16 iargc = 0;
1603 SilcArgumentPayload iargs;
1606 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1607 if (!tmp || tmp_len < 2)
1610 /* Parse the arguments to see they are constructed correctly */
1611 SILC_GET16_MSB(iargc, tmp);
1612 iargs = silc_argument_payload_parse(tmp + 2, tmp_len - 2, iargc);
1616 if (!channel->ban_list)
1618 silc_hash_table_alloc(0, silc_hash_ptr,
1620 silc_server_inviteban_destruct, channel, TRUE);
1622 /* Proces the ban action */
1623 if (!silc_server_inviteban_process(server, channel->ban_list, action,
1626 silc_argument_payload_free(iargs);
1628 /* If we are router we must send this notify to our local servers on
1629 the channel. Normal server does nothing. The notify is not
1631 if (server->server_type == SILC_ROUTER)
1632 silc_server_packet_send_to_channel(server, sock, channel,
1633 packet->type, FALSE, FALSE,
1635 silc_buffer_len(buffer));
1639 case SILC_NOTIFY_TYPE_ERROR:
1646 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1647 if (!tmp && tmp_len != 1)
1649 error = (SilcStatus)tmp[0];
1651 SILC_LOG_DEBUG(("ERROR notify (%d)", error));
1653 if (error == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID &&
1654 idata->conn_type == SILC_CONN_ROUTER) {
1655 if (!silc_argument_get_decoded(args, 2, SILC_ARGUMENT_ID, &id, NULL))
1658 SILC_LOG_DEBUG(("Received invalid client ID notification, deleting "
1659 "the entry from cache"));
1661 client = silc_idlist_find_client_by_id(server->global_list,
1667 silc_server_remove_from_channels(server, NULL, client, TRUE,
1669 silc_idlist_del_data(client);
1670 silc_idlist_del_client(server->global_list, client);
1675 /* Ignore rest of the notify types for now */
1676 case SILC_NOTIFY_TYPE_NONE:
1677 case SILC_NOTIFY_TYPE_MOTD:
1681 SILC_LOG_DEBUG(("Unsupported notify %d", type));
1686 silc_notify_payload_free(payload);
1689 void silc_server_notify(SilcServer server,
1690 SilcPacketStream sock,
1693 silc_server_notify_process(server, sock, packet, &packet->buffer);
1694 silc_packet_free(packet);
1697 void silc_server_notify_list(SilcServer server,
1698 SilcPacketStream sock,
1701 SilcIDListData idata = silc_packet_get_context(sock);
1705 SILC_LOG_DEBUG(("Processing Notify List"));
1707 if (idata->conn_type == SILC_CONN_CLIENT ||
1708 packet->src_id_type != SILC_ID_SERVER)
1711 buffer = silc_buffer_alloc(1024);
1715 while (silc_buffer_len(&packet->buffer)) {
1716 SILC_GET16_MSB(len, packet->buffer.data + 2);
1717 if (len > silc_buffer_len(&packet->buffer))
1720 if (len > silc_buffer_truelen(buffer)) {
1721 silc_buffer_free(buffer);
1722 buffer = silc_buffer_alloc(1024 + len);
1725 silc_buffer_pull_tail(buffer, len);
1726 silc_buffer_put(buffer, packet->buffer.data, len);
1728 /* Process the Notify */
1729 silc_server_notify_process(server, sock, packet, buffer);
1731 silc_buffer_push_tail(buffer, len);
1732 silc_buffer_pull(&packet->buffer, len);
1735 silc_packet_free(packet);
1736 silc_buffer_free(buffer);
1739 /* Received private message. This resolves the destination of the message
1740 and sends the packet. This is used by both server and router. If the
1741 destination is our locally connected client this sends the packet to
1742 the client. This may also send the message for further routing if
1743 the destination is not in our server (or router). */
1745 void silc_server_private_message(SilcServer server,
1746 SilcPacketStream sock,
1749 SilcPacketStream dst_sock;
1750 SilcIDListData idata;
1751 SilcClientEntry client;
1752 SilcClientID client_id;
1754 SILC_LOG_DEBUG(("Start"));
1756 if (packet->src_id_type != SILC_ID_CLIENT ||
1757 packet->dst_id_type != SILC_ID_CLIENT || !packet->dst_id)
1760 /* Get the route to the client */
1761 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1762 packet->dst_id_len, NULL,
1766 unsigned char error;
1768 if (client && client->mode & SILC_UMODE_DETACHED) {
1769 SILC_LOG_DEBUG(("Client is detached, discarding packet"));
1773 /* Send SILC_NOTIFY_TYPE_ERROR to indicate that such destination ID
1774 does not exist or is invalid. */
1775 idp = silc_id_payload_encode_data(packet->dst_id,
1777 packet->dst_id_type);
1781 error = SILC_STATUS_ERR_NO_SUCH_CLIENT_ID;
1782 if (packet->src_id_type == SILC_ID_CLIENT) {
1783 silc_id_str2id(packet->src_id, packet->src_id_len,
1784 packet->src_id_type, &client_id, sizeof(client_id));
1785 silc_server_send_notify_dest(server, sock, FALSE,
1786 &client_id, SILC_ID_CLIENT,
1787 SILC_NOTIFY_TYPE_ERROR, 2,
1789 idp->data, silc_buffer_len(idp));
1791 silc_server_send_notify(server, sock, FALSE,
1792 SILC_NOTIFY_TYPE_ERROR, 2,
1794 idp->data, silc_buffer_len(idp));
1797 silc_buffer_free(idp);
1801 /* Check whether destination client wishes to receive private messages */
1802 if (client && !(packet->flags & SILC_PACKET_FLAG_PRIVMSG_KEY) &&
1803 client->mode & SILC_UMODE_BLOCK_PRIVMSG) {
1804 SILC_LOG_DEBUG(("Client blocks private messages, discarding packet"));
1808 /* Send the private message */
1809 silc_server_packet_route(server, dst_sock, packet);
1812 silc_packet_free(packet);
1815 /* Received private message key packet.. This packet is never for us. It is to
1816 the client in the packet's destination ID. Sending of this sort of packet
1817 equals sending private message, ie. it is sent point to point from
1818 one client to another. */
1820 void silc_server_private_message_key(SilcServer server,
1821 SilcPacketStream sock,
1824 SilcPacketStream dst_sock;
1825 SilcIDListData idata;
1827 SILC_LOG_DEBUG(("Start"));
1829 if (packet->src_id_type != SILC_ID_CLIENT ||
1830 packet->dst_id_type != SILC_ID_CLIENT || !packet->dst_id) {
1831 silc_packet_free(packet);
1835 /* Get the route to the client */
1836 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1837 packet->dst_id_len, NULL,
1840 silc_packet_free(packet);
1844 /* Relay the packet */
1845 silc_server_packet_route(server, dst_sock, packet);
1847 silc_packet_free(packet);
1850 /* Processes incoming command reply packet. The command reply packet may
1851 be destined to one of our clients or it may directly for us. We will
1852 call the command reply routine after processing the packet. */
1854 void silc_server_command_reply(SilcServer server,
1855 SilcPacketStream sock,
1858 SilcBuffer buffer = &packet->buffer;
1859 SilcClientEntry client = NULL;
1862 SILC_LOG_DEBUG(("Start"));
1864 if (packet->dst_id_type == SILC_ID_CHANNEL) {
1865 silc_packet_free(packet);
1869 if (packet->dst_id_type == SILC_ID_CLIENT) {
1870 /* Destination must be one of ours */
1871 if (!silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT,
1873 silc_packet_free(packet);
1876 client = silc_idlist_find_client_by_id(server->local_list, &id,
1879 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
1880 silc_packet_free(packet);
1885 if (packet->dst_id_type == SILC_ID_SERVER) {
1886 /* For now this must be for us */
1887 if (memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
1888 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
1889 silc_packet_free(packet);
1894 /* Execute command reply locally for the command */
1895 silc_server_command_reply_process(server, sock, buffer);
1897 /* Relay the packet to the client */
1898 if (packet->dst_id_type == SILC_ID_CLIENT && client)
1899 silc_server_packet_route(server, client->connection, packet);
1901 silc_packet_free(packet);
1904 /* Process received channel message. The message can be originated from
1905 client or server. */
1907 void silc_server_channel_message(SilcServer server,
1908 SilcPacketStream sock,
1911 SilcChannelEntry channel = NULL;
1915 SilcClientEntry sender_entry = NULL;
1916 SilcIDListData idata;
1917 SilcChannelClientEntry chl;
1918 SilcBool local = TRUE;
1920 SILC_LOG_DEBUG(("Processing channel message"));
1923 if (packet->dst_id_type != SILC_ID_CHANNEL) {
1924 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1928 /* Find channel entry */
1929 if (!silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL,
1932 channel = silc_idlist_find_channel_by_id(server->local_list, &id, NULL);
1934 channel = silc_idlist_find_channel_by_id(server->global_list, &id, NULL);
1937 unsigned char error;
1939 /* Send SILC_NOTIFY_TYPE_ERROR to indicate that such destination ID
1940 does not exist or is invalid. */
1941 idp = silc_id_payload_encode_data(packet->dst_id,
1943 packet->dst_id_type);
1947 error = SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID;
1948 if (packet->src_id_type == SILC_ID_CLIENT) {
1949 silc_id_str2id(packet->src_id, packet->src_id_len,
1950 packet->src_id_type, &cid, sizeof(cid));
1951 silc_server_send_notify_dest(server, sock, FALSE,
1952 &cid, SILC_ID_CLIENT,
1953 SILC_NOTIFY_TYPE_ERROR, 2,
1954 &error, 1, idp->data,
1955 silc_buffer_len(idp));
1957 silc_server_send_notify(server, sock, FALSE,
1958 SILC_NOTIFY_TYPE_ERROR, 2,
1959 &error, 1, idp->data, silc_buffer_len(idp));
1962 silc_buffer_free(idp);
1967 /* See that this client is on the channel. If the original sender is
1968 not client (as it can be server as well) we don't do the check. */
1969 if (!silc_id_str2id2(packet->src_id, packet->src_id_len,
1970 packet->src_id_type, &sid))
1972 if (sid.type == SILC_ID_CLIENT) {
1973 sender_entry = silc_idlist_find_client_by_id(server->local_list,
1974 SILC_ID_GET_ID(sid),
1976 if (!sender_entry) {
1978 sender_entry = silc_idlist_find_client_by_id(server->global_list,
1979 SILC_ID_GET_ID(sid),
1982 if (!sender_entry || !silc_server_client_on_channel(sender_entry,
1984 SILC_LOG_DEBUG(("Client not on channel"));
1988 /* If channel is moderated check that client is allowed to send
1990 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS &&
1991 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
1992 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1993 SILC_LOG_DEBUG(("Channel is silenced from normal users"));
1996 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS &&
1997 chl->mode & SILC_CHANNEL_UMODE_CHANOP &&
1998 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1999 SILC_LOG_DEBUG(("Channel is silenced from operators"));
2002 if (chl->mode & SILC_CHANNEL_UMODE_QUIET) {
2003 SILC_LOG_DEBUG(("Sender is quieted on the channel"));
2007 /* If the packet is coming from router, but the client entry is local
2008 entry to us then some router is rerouting this to us and it is not
2009 allowed. When the client is local to us it means that we've routed
2010 this packet to network, and now someone is routing it back to us. */
2011 idata = silc_packet_get_context(sock);
2012 if (server->server_type == SILC_ROUTER &&
2013 idata->conn_type == SILC_CONN_ROUTER && local) {
2014 SILC_LOG_DEBUG(("Channel message rerouted to the sender, drop it"));
2019 /* Distribute the packet to our local clients. This will send the
2020 packet for further routing as well, if needed. */
2021 silc_server_packet_relay_to_channel(server, sock, channel,
2022 SILC_ID_GET_ID(sid), sid.type,
2023 sender_entry, packet->buffer.data,
2024 silc_buffer_len(&packet->buffer));
2027 silc_packet_free(packet);
2030 /* Received channel key packet. We distribute the key to all of our locally
2031 connected clients on the channel. */
2033 void silc_server_channel_key(SilcServer server,
2034 SilcPacketStream sock,
2037 SilcBuffer buffer = &packet->buffer;
2038 SilcIDListData idata = silc_packet_get_context(sock);
2039 SilcChannelEntry channel;
2041 if (packet->src_id_type != SILC_ID_SERVER ||
2042 (server->server_type == SILC_ROUTER && !server->backup_router &&
2043 idata->conn_type == SILC_CONN_ROUTER)) {
2044 silc_packet_free(packet);
2048 /* Save the channel key */
2049 channel = silc_server_save_channel_key(server, buffer, NULL);
2051 SILC_LOG_ERROR(("Bad channel key from %s", idata->sconn->remote_host));
2052 silc_packet_free(packet);
2056 /* Distribute the key to everybody who is on the channel. If we are router
2057 we will also send it to locally connected servers. */
2058 silc_server_send_channel_key(server, sock, channel, FALSE);
2060 if (server->server_type != SILC_BACKUP_ROUTER)
2061 /* Distribute to local cell backup routers. */
2062 silc_server_backup_send(server, (SilcServerEntry)idata,
2063 SILC_PACKET_CHANNEL_KEY, 0,
2064 buffer->data, silc_buffer_len(buffer),
2067 silc_packet_free(packet);
2070 /* Received New Client packet and processes it. Creates Client ID for the
2071 client. Client becomes registered after calling this functions. */
2073 SilcClientEntry silc_server_new_client(SilcServer server,
2074 SilcPacketStream sock,
2077 SilcBuffer buffer = &packet->buffer;
2078 SilcIDListData idata = silc_packet_get_context(sock);
2079 SilcClientEntry client;
2080 SilcClientID *client_id;
2081 char *username = NULL, *realname = NULL;
2082 SilcUInt16 username_len, nickname_len;
2083 SilcUInt32 id_len, tmp_len;
2085 char *host, *nickname = NULL, *nicknamec;
2086 const char *hostname, *ip;
2088 SILC_LOG_DEBUG(("Creating new client"));
2090 if (idata->conn_type != SILC_CONN_CLIENT) {
2091 silc_packet_free(packet);
2095 /* Take client entry */
2096 client = (SilcClientEntry)idata;
2097 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
2098 NULL, &hostname, &ip, NULL);
2100 SILC_LOG_DEBUG(("%s %s", ip, hostname));
2102 /* Make sure this client hasn't registered already */
2103 if (idata->status & SILC_IDLIST_STATUS_REGISTERED) {
2104 silc_packet_free(packet);
2108 /* Parse incoming packet */
2109 ret = silc_buffer_unformat(buffer,
2111 SILC_STR_UI16_NSTRING_ALLOC(&username,
2113 SILC_STR_UI16_STRING_ALLOC(&realname),
2116 silc_free(username);
2117 silc_free(realname);
2118 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2119 "connection", hostname, ip));
2120 silc_server_disconnect_remote(server, sock,
2121 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2123 silc_server_free_sock_user_data(server, sock, NULL);
2124 silc_packet_free(packet);
2129 silc_free(username);
2130 silc_free(realname);
2131 SILC_LOG_ERROR(("Client %s (%s) did not send its username, closing "
2132 "connection", hostname, ip));
2133 silc_server_disconnect_remote(server, sock,
2134 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2136 silc_server_free_sock_user_data(server, sock, NULL);
2137 silc_packet_free(packet);
2141 if (username_len > 128) {
2143 username[username_len - 1] = '\0';
2146 /* Take nickname from NEW_CLIENT packet, if present */
2147 if (silc_buffer_unformat(buffer,
2148 SILC_STR_UI16_NSTRING_ALLOC(&nickname,
2150 SILC_STR_END) >= 0) {
2151 if (nickname_len > 128) {
2153 nickname[nickname_len - 1] = '\0';
2157 /* Nickname is initially same as username, if not present in NEW_CLIENT */
2159 nickname = strdup(username);
2160 nickname_len = strlen(nickname);
2163 /* Check for valid username string */
2164 nicknamec = silc_identifier_check(nickname, nickname_len,
2165 SILC_STRING_UTF8, 128, &tmp_len);
2167 silc_free(username);
2168 silc_free(realname);
2169 silc_free(nickname);
2170 SILC_LOG_ERROR(("Client %s (%s) sent bad username string '%s', closing "
2171 "connection", hostname, ip, username));
2172 silc_server_disconnect_remote(server, sock,
2173 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2175 silc_server_free_sock_user_data(server, sock, NULL);
2176 silc_packet_free(packet);
2180 /* Make sanity checks for the hostname of the client. If the hostname
2181 is provided in the `username' check that it is the same than the
2182 resolved hostname, or if not resolved the hostname that appears in
2183 the client's public key. If the hostname is not present then put
2184 it from the resolved name or from the public key. */
2185 if (strchr(username, '@')) {
2186 SilcSILCPublicKey silc_pubkey;
2187 int tlen = strcspn(username, "@");
2188 char *phostname = NULL;
2190 host = silc_memdup(username + tlen + 1, strlen(username) - tlen - 1);
2192 if (strcmp(hostname, ip) && strcmp(hostname, host)) {
2193 silc_free(nickname);
2194 silc_free(username);
2196 silc_free(realname);
2197 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2198 "connection", hostname, ip));
2199 silc_server_disconnect_remote(server, sock,
2200 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2202 silc_server_free_sock_user_data(server, sock, NULL);
2203 silc_packet_free(packet);
2207 silc_pubkey = silc_pkcs_get_context(SILC_PKCS_SILC,
2208 client->data.public_key);
2209 phostname = strdup(silc_pubkey->identifier.host);
2210 if (!strcmp(hostname, ip) && phostname && strcmp(phostname, host)) {
2211 silc_free(nickname);
2212 silc_free(username);
2214 silc_free(phostname);
2215 silc_free(realname);
2216 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2217 "connection", hostname, ip));
2218 silc_server_disconnect_remote(server, sock,
2219 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2221 silc_server_free_sock_user_data(server, sock, NULL);
2222 silc_packet_free(packet);
2226 silc_free(phostname);
2228 /* The hostname is not present, add it. */
2230 newusername = silc_calloc(strlen(username) + strlen(hostname) + 2,
2231 sizeof(*newusername));
2232 strncat(newusername, username, strlen(username));
2233 strncat(newusername, "@", 1);
2234 strncat(newusername, hostname, strlen(hostname));
2235 silc_free(username);
2236 username = newusername;
2239 SILC_LOG_DEBUG(("%s %s", ip, hostname));
2241 /* Create Client ID */
2242 if (!silc_id_create_client_id(server, server->id, server->rng,
2243 server->md5hash, nicknamec,
2244 strlen(nicknamec), &client_id)) {
2245 silc_server_disconnect_remote(server, sock,
2246 SILC_STATUS_ERR_BAD_NICKNAME, NULL);
2247 silc_server_free_sock_user_data(server, sock, NULL);
2248 silc_packet_free(packet);
2252 /* If client marked as anonymous, scramble the username and hostname */
2253 if (client->mode & SILC_UMODE_ANONYMOUS) {
2256 if (strlen(username) >= 2) {
2257 username[0] = silc_rng_get_byte_fast(server->rng);
2258 username[1] = silc_rng_get_byte_fast(server->rng);
2261 scramble = silc_hash_babbleprint(server->sha1hash, username,
2265 memcpy(&scramble[16], ".silc", 5);
2266 scramble[21] = '\0';
2267 silc_free(username);
2268 username = scramble;
2271 /* Update client entry */
2272 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
2273 client->nickname = nickname;
2274 client->username = username;
2275 client->userinfo = realname ? realname : strdup(username);
2276 client->id = client_id;
2277 id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
2278 silc_idcache_update_by_context(server->local_list->clients, client,
2279 client_id, nicknamec, TRUE);
2281 /* Notify our router about new client on the SILC network */
2282 silc_server_send_new_id(server, SILC_PRIMARY_ROUTE(server),
2283 SILC_BROADCAST(server), client->id,
2284 SILC_ID_CLIENT, id_len);
2286 /* Distribute to backup routers */
2287 if (server->server_type == SILC_ROUTER) {
2288 SilcBuffer idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
2289 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_ID, 0,
2290 idp->data, silc_buffer_len(idp), FALSE, TRUE);
2291 silc_buffer_free(idp);
2294 /* Send the new client ID to the client. */
2295 silc_server_send_new_id(server, sock, FALSE, client->id, SILC_ID_CLIENT,
2296 silc_id_get_len(client->id, SILC_ID_CLIENT));
2298 /* Send some nice info to the client */
2299 silc_server_send_connect_notifys(server, sock, client);
2301 /* Check if anyone is watching this nickname */
2302 if (server->server_type == SILC_ROUTER)
2303 silc_server_check_watcher_list(server, client, NULL, 0);
2305 silc_packet_free(packet);
2309 /* Create new server. This processes received New Server packet and
2310 saves the received Server ID. The server is our locally connected
2311 server thus we save all the information and save it to local list.
2312 This funtion can be used by both normal server and router server.
2313 If normal server uses this it means that its router has connected
2314 to the server. If router uses this it means that one of the cell's
2315 servers is connected to the router. */
2317 SilcServerEntry silc_server_new_server(SilcServer server,
2318 SilcPacketStream sock,
2321 SilcBuffer buffer = &packet->buffer;
2322 SilcIDListData idata = silc_packet_get_context(sock);
2323 SilcServerEntry new_server, server_entry;
2324 SilcServerID server_id;
2325 unsigned char *server_name, *server_namec, *id_string;
2326 SilcUInt16 id_len, name_len;
2328 SilcBool local = TRUE;
2329 const char *hostname, *ip;
2331 SILC_LOG_DEBUG(("Creating new server"));
2333 if (idata->conn_type != SILC_CONN_SERVER &&
2334 idata->conn_type != SILC_CONN_ROUTER) {
2335 silc_packet_free(packet);
2339 /* Take server entry */
2340 new_server = (SilcServerEntry)idata;
2341 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
2342 NULL, &hostname, &ip, NULL);
2345 if (server->server_type == SILC_ROUTER)
2346 server->stat.cell_servers++;
2348 /* Remove the old cache entry */
2349 if (!silc_idcache_del_by_context(server->local_list->servers, new_server,
2351 if (!silc_idcache_del_by_context(server->global_list->servers,
2352 new_server, NULL)) {
2353 SILC_LOG_INFO(("Unauthenticated %s attempted to register to "
2354 "network", (idata->conn_type == SILC_CONN_SERVER ?
2355 "server" : "router")));
2356 silc_server_disconnect_remote(server, sock,
2357 SILC_STATUS_ERR_NOT_AUTHENTICATED, NULL);
2358 silc_server_free_sock_user_data(server, sock, NULL);
2364 /* Make sure this server hasn't registered already */
2365 if (idata->status & SILC_IDLIST_STATUS_REGISTERED) {
2366 silc_server_disconnect_remote(server, sock,
2367 SILC_STATUS_ERR_OPERATION_ALLOWED,
2368 "Too many registrations");
2369 silc_server_free_sock_user_data(server, sock, NULL);
2373 /* Parse the incoming packet */
2374 ret = silc_buffer_unformat(buffer,
2375 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
2376 SILC_STR_UI16_NSTRING_ALLOC(&server_name,
2380 silc_free(id_string);
2381 silc_free(server_name);
2382 silc_server_disconnect_remote(server, sock,
2383 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2385 silc_server_free_sock_user_data(server, sock, NULL);
2389 if (id_len > silc_buffer_len(buffer)) {
2390 silc_free(id_string);
2391 silc_free(server_name);
2392 silc_server_disconnect_remote(server, sock,
2393 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2395 silc_server_free_sock_user_data(server, sock, NULL);
2399 if (name_len > 256) {
2400 server_name[256] = '\0';
2405 if (!silc_id_str2id(id_string, id_len, SILC_ID_SERVER, &server_id,
2406 sizeof(server_id))) {
2407 silc_free(id_string);
2408 silc_free(server_name);
2409 silc_server_disconnect_remote(server, sock,
2410 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2412 silc_server_free_sock_user_data(server, sock, NULL);
2415 silc_free(id_string);
2417 /* Check for valid server ID */
2418 if (!silc_id_is_valid_server_id(server, &server_id, sock)) {
2419 SILC_LOG_INFO(("Invalid server ID sent by %s (%s)",
2421 silc_server_disconnect_remote(server, sock,
2422 SILC_STATUS_ERR_BAD_SERVER_ID, NULL);
2423 silc_server_free_sock_user_data(server, sock, NULL);
2424 silc_free(server_name);
2428 /* Check that we do not have this ID already */
2429 server_entry = silc_idlist_find_server_by_id(server->local_list,
2430 &server_id, TRUE, NULL);
2432 if (SILC_IS_LOCAL(server_entry)) {
2433 SILC_LOG_ERROR(("Too many registrations from %s (%s)",
2435 silc_server_disconnect_remote(server, sock,
2436 SILC_STATUS_ERR_OPERATION_ALLOWED,
2437 "Too many registrations");
2438 silc_server_free_sock_user_data(server, sock, NULL);
2441 silc_idcache_del_by_context(server->local_list->servers, server_entry,
2445 server_entry = silc_idlist_find_server_by_id(server->global_list,
2446 &server_id, TRUE, NULL);
2448 if (SILC_IS_LOCAL(server_entry)) {
2449 SILC_LOG_ERROR(("Too many registrations from %s (%s)",
2451 silc_server_disconnect_remote(server, sock,
2452 SILC_STATUS_ERR_OPERATION_ALLOWED,
2453 "Too many registrations");
2454 silc_server_free_sock_user_data(server, sock, NULL);
2457 silc_idcache_del_by_context(server->global_list->servers,
2458 server_entry, NULL);
2463 /* Check server name */
2464 server_namec = silc_identifier_check(server_name, strlen(server_name),
2465 SILC_STRING_UTF8, 256, NULL);
2466 if (!server_namec) {
2467 SILC_LOG_ERROR(("Malformed server name from %s (%s)",
2469 silc_server_disconnect_remote(server, sock,
2470 SILC_STATUS_ERR_OPERATION_ALLOWED,
2471 "Malfromed server name");
2472 silc_server_free_sock_user_data(server, sock, NULL);
2476 /* Update server entry */
2477 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
2478 new_server->server_name = server_name;
2479 new_server->id = silc_id_dup(&server_id, SILC_ID_SERVER);
2481 SILC_LOG_DEBUG(("New server id(%s)",
2482 silc_id_render(&server_id, SILC_ID_SERVER)));
2484 /* Add again the entry to the ID cache. */
2485 silc_idcache_add(local ? server->local_list->servers :
2486 server->global_list->servers, server_namec,
2487 new_server->id, new_server);
2489 /* Distribute the information about new server in the SILC network
2490 to our router. If we are normal server we won't send anything
2491 since this connection must be our router connection. */
2492 if (server->server_type == SILC_ROUTER && !server->standalone &&
2493 SILC_PRIMARY_ROUTE(server) != sock)
2494 silc_server_send_new_id(server, SILC_PRIMARY_ROUTE(server),
2495 TRUE, new_server->id, SILC_ID_SERVER,
2496 silc_id_get_len(&server_id, SILC_ID_SERVER));
2498 if (server->server_type == SILC_ROUTER) {
2499 /* Distribute to backup routers */
2500 SilcBuffer idp = silc_id_payload_encode(new_server->id, SILC_ID_SERVER);
2501 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_ID, 0, idp->data,
2502 silc_buffer_len(idp), FALSE, TRUE);
2503 silc_buffer_free(idp);
2506 /* Check whether this router connection has been replaced by an
2507 backup router. If it has been then we'll disable the server and will
2508 ignore everything it will send until the backup router resuming
2509 protocol has been completed. */
2510 if (idata->conn_type == SILC_CONN_ROUTER &&
2511 silc_server_backup_replaced_get(server, &server_id, NULL)) {
2512 /* Send packet to the router indicating that it cannot use this
2513 connection as it has been replaced by backup router. */
2514 SILC_LOG_DEBUG(("Remote router has been replaced by backup router, "
2515 "disabling its connection"));
2517 silc_server_backup_send_replaced(server, sock);
2519 /* Mark the router disabled. The data sent earlier will go but nothing
2520 after this goes to this connection. */
2521 idata->status |= SILC_IDLIST_STATUS_DISABLED;
2523 /* If it is router announce our stuff to it. */
2524 if (idata->conn_type == SILC_CONN_ROUTER &&
2525 server->server_type == SILC_ROUTER) {
2526 silc_server_announce_servers(server, FALSE, 0, sock);
2527 silc_server_announce_clients(server, 0, sock);
2528 silc_server_announce_channels(server, 0, sock);
2531 /* Announce our information to backup router */
2532 if (new_server->server_type == SILC_BACKUP_ROUTER &&
2533 idata->conn_type == SILC_CONN_SERVER &&
2534 server->server_type == SILC_ROUTER) {
2535 silc_server_announce_servers(server, TRUE, 0, sock);
2536 silc_server_announce_clients(server, 0, sock);
2537 silc_server_announce_channels(server, 0, sock);
2540 /* If backup router, mark it as one of ours. This server is considered
2541 to be backup router after this setting. */
2542 if (new_server->server_type == SILC_BACKUP_ROUTER) {
2543 SilcServerConfigRouter *backup;
2544 backup = silc_server_config_find_backup_conn(server, (char *)ip);
2546 backup = silc_server_config_find_backup_conn(server, (char *)hostname);
2548 /* Add as our backup router */
2549 silc_server_backup_add(server, new_server, backup->backup_replace_ip,
2550 backup->backup_replace_port,
2551 backup->backup_local);
2555 /* By default the servers connected to backup router are disabled
2556 until backup router has become the primary */
2557 if (server->server_type == SILC_BACKUP_ROUTER &&
2558 idata->conn_type == SILC_CONN_SERVER)
2559 idata->status |= SILC_IDLIST_STATUS_DISABLED;
2565 /* Processes incoming New ID packet. New ID Payload is used to distribute
2566 information about newly registered clients and servers. */
2568 static void silc_server_new_id_real(SilcServer server,
2569 SilcPacketStream sock,
2574 SilcIDListData idata = silc_packet_get_context(sock);
2576 SilcServerEntry router, server_entry;
2577 SilcPacketStream router_sock;
2580 SilcServerID sender_id;
2581 const char *hostname, *ip;
2583 SILC_LOG_DEBUG(("Processing new ID"));
2585 if (idata->conn_type == SILC_CONN_CLIENT ||
2586 server->server_type == SILC_SERVER ||
2587 packet->src_id_type != SILC_ID_SERVER)
2590 idp = silc_id_payload_parse(buffer->data, silc_buffer_len(buffer));
2594 id_type = silc_id_payload_get_type(idp);
2596 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
2597 NULL, &hostname, &ip, NULL);
2599 /* Normal server cannot have other normal server connections */
2600 server_entry = (SilcServerEntry)idata;
2601 if (id_type == SILC_ID_SERVER && idata->conn_type == SILC_CONN_SERVER &&
2602 server_entry->server_type == SILC_SERVER)
2605 /* If the packet is coming from server then use the sender as the
2606 origin of the the packet. If it came from router then check the real
2607 sender of the packet and use that as the origin. */
2608 if (idata->conn_type == SILC_CONN_SERVER) {
2609 id_list = server->local_list;
2611 router = server_entry;
2613 /* If the sender is backup router and ID is server (and we are not
2614 backup router) then switch the entry to global list. */
2615 if (server_entry->server_type == SILC_BACKUP_ROUTER &&
2616 id_type == SILC_ID_SERVER &&
2617 server->id_entry->server_type != SILC_BACKUP_ROUTER) {
2618 id_list = server->global_list;
2619 router_sock = server->router ? SILC_PRIMARY_ROUTE(server) : sock;
2622 silc_id_str2id(packet->src_id, packet->src_id_len,
2623 packet->src_id_type, &sender_id, sizeof(sender_id));
2624 router = silc_idlist_find_server_by_id(server->global_list,
2625 &sender_id, TRUE, NULL);
2627 router = silc_idlist_find_server_by_id(server->local_list,
2628 &sender_id, TRUE, NULL);
2630 id_list = server->global_list;
2637 case SILC_ID_CLIENT:
2639 SilcClientEntry entry;
2642 if (!silc_id_payload_get_id(idp, &id, sizeof(id)))
2645 /* Check that we do not have this client already */
2646 entry = silc_idlist_find_client_by_id(server->global_list,
2647 &id, server->server_type,
2650 entry = silc_idlist_find_client_by_id(server->local_list,
2651 &id, server->server_type,
2654 SILC_LOG_DEBUG(("Ignoring client that we already have"));
2658 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
2659 silc_id_render(&id, SILC_ID_CLIENT),
2660 idata->conn_type == SILC_CONN_SERVER ?
2661 "Server" : "Router", hostname));
2663 /* As a router we keep information of all global information in our
2664 global list. Cell wide information however is kept in the local
2666 entry = silc_idlist_add_client(id_list, NULL, NULL, NULL,
2667 silc_id_dup(&id, SILC_ID_CLIENT),
2670 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
2672 /* Inform the sender that the ID is not usable */
2673 silc_server_send_notify_signoff(server, sock, FALSE, &id, NULL);
2676 entry->nickname = NULL;
2677 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2679 if (idata->conn_type == SILC_CONN_SERVER)
2680 server->stat.cell_clients++;
2681 server->stat.clients++;
2683 /* Check if anyone is watching this nickname */
2684 if (server->server_type == SILC_ROUTER && id_list == server->local_list)
2685 silc_server_check_watcher_list(server, entry, NULL, 0);
2687 if (server->server_type == SILC_ROUTER) {
2688 /* Add the client's public key to repository or get the key with
2690 if (entry->data.public_key) {
2691 if (!silc_server_get_public_key_by_client(server, entry, NULL))
2692 silc_skr_add_public_key_simple(server->repository,
2693 entry->data.public_key,
2694 SILC_SKR_USAGE_IDENTIFICATION,
2697 silc_server_send_command(server, router_sock,
2698 SILC_COMMAND_GETKEY, ++server->cmd_ident,
2700 silc_buffer_len(buffer));
2706 case SILC_ID_SERVER:
2708 SilcServerEntry entry;
2711 if (!silc_id_payload_get_id(idp, &id, sizeof(id)))
2714 /* If the ID is mine, ignore it. */
2715 if (SILC_ID_SERVER_COMPARE(&id, server->id)) {
2716 SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
2720 /* If the ID is the sender's ID, ignore it (we have it already) */
2721 if (SILC_ID_SERVER_COMPARE(&id, router->id)) {
2722 SILC_LOG_DEBUG(("Ignoring sender's own ID"));
2726 /* Check that we do not have this server already */
2727 entry = silc_idlist_find_server_by_id(server->global_list,
2728 &id, server->server_type,
2731 entry = silc_idlist_find_server_by_id(server->local_list,
2732 &id, server->server_type,
2735 SILC_LOG_DEBUG(("Ignoring server that we already have"));
2739 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
2740 silc_id_render(&id, SILC_ID_SERVER),
2741 idata->conn_type == SILC_CONN_SERVER ?
2742 "Server" : "Router", hostname));
2744 /* As a router we keep information of all global information in our
2745 global list. Cell wide information however is kept in the local
2747 entry = silc_idlist_add_server(id_list, NULL, 0,
2748 silc_id_dup(&id, SILC_ID_SERVER), router,
2751 SILC_LOG_ERROR(("Could not add new server to the ID Cache"));
2754 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2756 if (idata->conn_type == SILC_CONN_SERVER)
2757 server->stat.cell_servers++;
2758 server->stat.servers++;
2762 case SILC_ID_CHANNEL:
2763 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
2772 /* If the sender of this packet is server and we are router we need to
2773 broadcast this packet to other routers in the network. */
2774 if (broadcast && server->server_type == SILC_ROUTER &&
2775 idata->conn_type == SILC_CONN_SERVER &&
2776 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2777 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
2778 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
2780 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2781 buffer->data, silc_buffer_len(buffer));
2782 silc_server_backup_send(server, (SilcServerEntry)idata,
2783 packet->type, packet->flags,
2784 packet->buffer.data,
2785 silc_buffer_len(&packet->buffer),
2790 silc_id_payload_free(idp);
2794 /* Processes incoming New ID packet. New ID Payload is used to distribute
2795 information about newly registered clients and servers. */
2797 void silc_server_new_id(SilcServer server, SilcPacketStream sock,
2800 silc_server_new_id_real(server, sock, packet, &packet->buffer, TRUE);
2801 silc_packet_free(packet);
2804 /* Receoved New Id List packet, list of New ID payloads inside one
2805 packet. Process the New ID payloads one by one. */
2807 void silc_server_new_id_list(SilcServer server, SilcPacketStream sock,
2810 SilcIDListData idata = silc_packet_get_context(sock);
2814 SILC_LOG_DEBUG(("Processing New ID List"));
2816 if (idata->conn_type == SILC_CONN_CLIENT ||
2817 packet->src_id_type != SILC_ID_SERVER) {
2818 silc_packet_free(packet);
2822 /* If the sender of this packet is server and we are router we need to
2823 broadcast this packet to other routers in the network. Broadcast
2824 this list packet instead of multiple New ID packets. */
2825 if (server->server_type == SILC_ROUTER &&
2826 idata->conn_type == SILC_CONN_SERVER &&
2827 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2828 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
2829 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
2831 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2832 packet->buffer.data,
2833 silc_buffer_len(&packet->buffer));
2834 silc_server_backup_send(server, (SilcServerEntry)idata,
2835 packet->type, packet->flags,
2836 packet->buffer.data,
2837 silc_buffer_len(&packet->buffer),
2841 idp = silc_buffer_alloc(256);
2843 silc_packet_free(packet);
2847 while (silc_buffer_len(&packet->buffer)) {
2848 SILC_GET16_MSB(id_len, packet->buffer.data + 2);
2849 if ((id_len > silc_buffer_len(&packet->buffer)) ||
2850 (id_len > silc_buffer_truelen(idp)))
2853 silc_buffer_pull_tail(idp, 4 + id_len);
2854 silc_buffer_put(idp, packet->buffer.data, 4 + id_len);
2856 /* Process the New ID */
2857 silc_server_new_id_real(server, sock, packet, idp, FALSE);
2859 silc_buffer_push_tail(idp, 4 + id_len);
2860 silc_buffer_pull(&packet->buffer, 4 + id_len);
2863 silc_buffer_free(idp);
2864 silc_packet_free(packet);
2867 /* Received New Channel packet. Information about new channels in the
2868 network are distributed using this packet. Save the information about
2869 the new channel. This usually comes from router but also normal server
2870 can send this to notify channels it has when it connects to us. */
2872 static void silc_server_new_channel_process(SilcServer server,
2873 SilcPacketStream sock,
2877 SilcIDListData idata = silc_packet_get_context(sock);
2878 SilcChannelPayload payload;
2879 SilcChannelID channel_id;
2880 char *channel_name, *channel_namec = NULL;
2881 SilcUInt32 name_len;
2882 unsigned char *id, cid[32];
2883 SilcUInt32 id_len, cipher_len;
2884 SilcServerEntry server_entry;
2885 SilcChannelEntry channel;
2888 if (idata->conn_type == SILC_CONN_CLIENT ||
2889 packet->src_id_type != SILC_ID_SERVER ||
2890 server->server_type == SILC_SERVER)
2893 /* Parse the channel payload */
2894 payload = silc_channel_payload_parse(buffer->data, silc_buffer_len(buffer));
2898 /* Get the channel ID */
2899 if (!silc_channel_get_id_parse(payload, &channel_id)) {
2900 silc_channel_payload_free(payload);
2904 channel_name = silc_channel_get_name(payload, &name_len);
2905 if (name_len > 256) {
2906 channel_name[256] = '\0';
2910 /* Check channel name */
2911 channel_namec = silc_channel_name_check(channel_name, strlen(channel_name),
2912 SILC_STRING_UTF8, 256, NULL);
2916 id = silc_channel_get_id(payload, &id_len);
2918 server_entry = (SilcServerEntry)idata;
2920 if (idata->conn_type == SILC_CONN_ROUTER) {
2921 /* Add the channel to global list as it is coming from router. It
2922 cannot be our own channel as it is coming from router. */
2924 /* Check that we don't already have this channel */
2925 channel = silc_idlist_find_channel_by_name(server->local_list,
2926 channel_namec, NULL);
2928 channel = silc_idlist_find_channel_by_name(server->global_list,
2929 channel_namec, NULL);
2931 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
2932 silc_id_render(&channel_id, SILC_ID_CHANNEL),
2933 idata->sconn->remote_host));
2936 silc_idlist_add_channel(server->global_list, strdup(channel_name),
2937 0, silc_id_dup(&channel_id, SILC_ID_CHANNEL),
2938 (SilcServerEntry)idata, NULL, NULL, NULL);
2940 silc_channel_payload_free(payload);
2943 channel->disabled = TRUE; /* Disabled until someone JOINs */
2945 server->stat.channels++;
2946 if (server->server_type == SILC_ROUTER)
2947 channel->users_resolved = TRUE;
2950 /* The channel is coming from our server, thus it is in our cell
2951 we will add it to our local list. */
2954 SILC_LOG_DEBUG(("Channel id(%s) from [Server] %s",
2955 silc_id_render(&channel_id, SILC_ID_CHANNEL),
2956 idata->sconn->remote_host));
2958 /* Check that we don't already have this channel */
2959 channel = silc_idlist_find_channel_by_name(server->local_list,
2960 channel_namec, NULL);
2962 channel = silc_idlist_find_channel_by_name(server->global_list,
2963 channel_namec, NULL);
2965 /* If the channel does not exist, then create it. This creates a new
2966 key to the channel as well that we will send to the server. */
2968 SILC_LOG_DEBUG(("Channel is new to us"));
2970 /* The protocol says that the Channel ID's IP address must be based
2971 on the router's IP address. Check whether the ID is based in our
2972 IP and if it is not then create a new ID and enforce the server
2973 to switch the ID. */
2974 if (server_entry->server_type != SILC_BACKUP_ROUTER &&
2975 !SILC_ID_COMPARE(&channel_id, server->id, server->id->ip.data_len)) {
2977 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2978 if (silc_id_create_channel_id(server, server->id, server->rng, &tmp)) {
2979 silc_server_send_notify_channel_change(server, sock, FALSE,
2981 silc_channel_payload_free(payload);
2985 /* Wait that server re-announces this channel */
2989 /* Create the channel with the provided Channel ID */
2991 silc_server_create_new_channel_with_id(
2994 silc_id_dup(&channel_id, SILC_ID_CHANNEL),
2997 silc_channel_payload_free(payload);
3000 channel->disabled = TRUE; /* Disabled until someone JOINs */
3002 #if 0 /* We assume that CMODE_CHANGE notify is sent to us after this. */
3004 /* XXX Dunno if this is supposed to be set in any server type. If set
3005 here the CMODE_CHANGE that may follow sets mode that we already
3006 have, and we may loose data from the CMODE_CHANGE notify. */
3007 if (server_entry->server_type != SILC_BACKUP_ROUTER)
3008 channel->mode = silc_channel_get_mode(payload);
3011 /* Send the new channel key to the server */
3012 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid),
3014 cipher = silc_cipher_get_name(channel->send_key);
3015 cipher_len = strlen(cipher);
3016 chk = silc_channel_key_payload_encode(id_len, cid,
3018 channel->key_len / 8,
3020 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
3021 chk->data, silc_buffer_len(chk));
3022 silc_buffer_free(chk);
3024 /* The channel exist by that name, check whether the ID's match.
3025 If they don't then we'll force the server to use the ID we have.
3026 We also create a new key for the channel. */
3027 SilcBuffer modes = NULL, users = NULL, users_modes = NULL;
3029 SILC_LOG_DEBUG(("Channel already exists"));
3031 if (!SILC_ID_CHANNEL_COMPARE(&channel_id, channel->id)) {
3032 /* They don't match, send CHANNEL_CHANGE notify to the server to
3033 force the ID change. */
3034 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
3035 silc_server_send_notify_channel_change(server, sock, FALSE,
3036 &channel_id, channel->id);
3037 silc_channel_payload_free(payload);
3039 /* Wait that server re-announces this channel */
3043 #if 0 /* We will announce our CMODE anyway for this channel, so no need
3044 to check it (implicit enforce). */
3046 /* If the mode is different from what we have then enforce the
3048 mode = silc_channel_get_mode(payload);
3049 if (channel->mode != mode) {
3050 SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
3051 silc_server_send_notify_cmode(server, sock, FALSE, channel,
3052 channel->mode, server->id,
3053 SILC_ID_SERVER, channel->cipher,
3055 channel->passphrase,
3056 channel->founder_key);
3060 /* Create new key for the channel and send it to the server and
3061 everybody else possibly on the channel. */
3062 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3064 if (silc_hash_table_count(channel->user_list)) {
3065 if (!silc_server_create_channel_key(server, channel, 0)) {
3066 silc_channel_payload_free(payload);
3070 /* Send to the channel */
3071 silc_server_send_channel_key(server, sock, channel, FALSE);
3074 /* Send to the server */
3075 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid),
3077 cipher = silc_cipher_get_name(channel->send_key);
3078 cipher_len = strlen(cipher);
3079 chk = silc_channel_key_payload_encode(id_len, cid,
3081 channel->key_len / 8,
3083 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
3084 chk->data, silc_buffer_len(chk));
3085 silc_buffer_free(chk);
3088 /* Since the channel is coming from server and we also know about it
3089 then send the JOIN notify to the server so that it see's our
3090 users on the channel "joining" the channel. */
3091 silc_server_announce_get_channel_users(server, channel, &modes, &users,
3094 silc_buffer_push(users, users->data - users->head);
3095 silc_server_packet_send(server, sock,
3096 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3097 users->data, silc_buffer_len(users));
3098 silc_buffer_free(users);
3101 silc_buffer_push(modes, modes->data - modes->head);
3102 silc_server_packet_send_dest(server, sock,
3103 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3104 channel->id, SILC_ID_CHANNEL,
3105 modes->data, silc_buffer_len(modes));
3106 silc_buffer_free(modes);
3109 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
3110 silc_server_packet_send_dest(server, sock,
3111 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3112 channel->id, SILC_ID_CHANNEL,
3114 silc_buffer_len(users_modes));
3115 silc_buffer_free(users_modes);
3117 if (channel->topic) {
3118 silc_server_send_notify_topic_set(server, sock,
3119 server->server_type == SILC_ROUTER ?
3120 TRUE : FALSE, channel,
3121 server->id, SILC_ID_SERVER,
3127 /* If the sender of this packet is server and we are router we need to
3128 broadcast this packet to other routers in the network. Broadcast
3129 this list packet instead of multiple New Channel packets. */
3130 if (server->server_type == SILC_ROUTER &&
3131 idata->conn_type == SILC_CONN_SERVER &&
3132 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
3133 SILC_LOG_DEBUG(("Broadcasting received New Channel packet"));
3134 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
3136 packet->flags | SILC_PACKET_FLAG_BROADCAST,
3137 buffer->data, silc_buffer_len(buffer));
3138 silc_server_backup_send(server, (SilcServerEntry)idata,
3139 packet->type, packet->flags,
3140 buffer->data, silc_buffer_len(buffer),
3144 silc_free(channel_namec);
3145 silc_channel_payload_free(payload);
3148 /* Received New Channel packet. Information about new channels in the
3149 network are distributed using this packet. Save the information about
3150 the new channel. This usually comes from router but also normal server
3151 can send this to notify channels it has when it connects to us. */
3153 void silc_server_new_channel(SilcServer server,
3154 SilcPacketStream sock,
3157 silc_server_new_channel_process(server, sock, packet, &packet->buffer);
3158 silc_packet_free(packet);
3161 /* Received New Channel List packet, list of New Channel List payloads inside
3162 one packet. Process the New Channel payloads one by one. */
3164 void silc_server_new_channel_list(SilcServer server,
3165 SilcPacketStream sock,
3168 SilcIDListData idata = silc_packet_get_context(sock);
3170 SilcUInt16 len1, len2;
3172 SILC_LOG_DEBUG(("Processing New Channel List"));
3174 if (idata->conn_type == SILC_CONN_CLIENT ||
3175 packet->src_id_type != SILC_ID_SERVER ||
3176 server->server_type == SILC_SERVER) {
3177 silc_packet_free(packet);
3181 buffer = silc_buffer_alloc(512);
3183 silc_packet_free(packet);
3187 while (silc_buffer_len(&packet->buffer)) {
3188 SILC_GET16_MSB(len1, packet->buffer.data);
3189 if ((len1 > silc_buffer_len(&packet->buffer)) ||
3190 (len1 > silc_buffer_truelen(buffer)))
3193 SILC_GET16_MSB(len2, packet->buffer.data + 2 + len1);
3194 if ((len2 > silc_buffer_len(&packet->buffer)) ||
3195 (len2 > silc_buffer_truelen(buffer)))
3198 silc_buffer_pull_tail(buffer, 8 + len1 + len2);
3199 silc_buffer_put(buffer, packet->buffer.data, 8 + len1 + len2);
3201 /* Process the New Channel */
3202 silc_server_new_channel_process(server, sock, packet, buffer);
3204 silc_buffer_push_tail(buffer, 8 + len1 + len2);
3205 silc_buffer_pull(&packet->buffer, 8 + len1 + len2);
3208 silc_buffer_free(buffer);
3209 silc_packet_free(packet);
3212 /* Received key agreement packet. This packet is never for us. It is to
3213 the client in the packet's destination ID. Sending of this sort of packet
3214 equals sending private message, ie. it is sent point to point from
3215 one client to another. */
3217 void silc_server_key_agreement(SilcServer server,
3218 SilcPacketStream sock,
3221 SilcPacketStream dst_sock;
3222 SilcIDListData idata;
3224 SILC_LOG_DEBUG(("Start"));
3226 if (packet->src_id_type != SILC_ID_CLIENT ||
3227 packet->dst_id_type != SILC_ID_CLIENT || !packet->dst_id) {
3228 silc_packet_free(packet);
3232 /* Get the route to the client */
3233 dst_sock = silc_server_get_client_route(server, packet->dst_id,
3234 packet->dst_id_len, NULL,
3237 silc_packet_free(packet);
3241 /* Relay the packet */
3242 silc_server_packet_route(server, dst_sock, packet);
3243 silc_packet_free(packet);
3246 /* Received connection auth request packet that is used during connection
3247 phase to resolve the mandatory authentication method. This packet can
3248 actually be received at anytime but usually it is used only during
3249 the connection authentication phase. Now, protocol says that this packet
3250 can come from client or server, however, we support only this coming
3251 from client and expect that server always knows what authentication
3254 void silc_server_connection_auth_request(SilcServer server,
3255 SilcPacketStream sock,
3258 SilcServerConfigClient *client = NULL;
3259 SilcUInt16 conn_type;
3261 SilcAuthMethod auth_meth = SILC_AUTH_NONE;
3262 const char *hostname, *ip;
3264 if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT) {
3265 SILC_LOG_DEBUG(("Request not from client"));
3266 silc_packet_free(packet);
3270 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
3271 NULL, &hostname, &ip, NULL);
3273 /* Parse the payload */
3274 ret = silc_buffer_unformat(&packet->buffer,
3275 SILC_STR_UI_SHORT(&conn_type),
3276 SILC_STR_UI_SHORT(NULL),
3278 if (ret == -1 || conn_type != SILC_CONN_CLIENT) {
3279 silc_packet_free(packet);
3283 /* Get the authentication method for the client */
3284 auth_meth = SILC_AUTH_NONE;
3285 client = silc_server_config_find_client(server, (char *)ip);
3287 client = silc_server_config_find_client(server, (char *)hostname);
3289 if (client->passphrase) {
3290 if (client->publickeys && !server->config->prefer_passphrase_auth)
3291 auth_meth = SILC_AUTH_PUBLIC_KEY;
3293 auth_meth = SILC_AUTH_PASSWORD;
3294 } else if (client->publickeys)
3295 auth_meth = SILC_AUTH_PUBLIC_KEY;
3298 SILC_LOG_DEBUG(("Authentication method is [%s]",
3299 (auth_meth == SILC_AUTH_NONE ? "None" :
3300 auth_meth == SILC_AUTH_PASSWORD ? "Passphrase" :
3301 "Digital signatures")));
3303 /* Send it back to the client */
3304 silc_server_send_connection_auth_request(server, sock, conn_type, auth_meth);
3305 silc_packet_free(packet);
3308 /* Received file transger packet. This packet is never for us. It is to
3309 the client in the packet's destination ID. Sending of this sort of packet
3310 equals sending private message, ie. it is sent point to point from
3311 one client to another. */
3313 void silc_server_ftp(SilcServer server,
3314 SilcPacketStream sock,
3317 SilcPacketStream dst_sock;
3318 SilcIDListData idata;
3320 SILC_LOG_DEBUG(("Start"));
3322 if (packet->src_id_type != SILC_ID_CLIENT ||
3323 packet->dst_id_type != SILC_ID_CLIENT || !packet->dst_id) {
3324 silc_packet_free(packet);
3328 /* Get the route to the client */
3329 dst_sock = silc_server_get_client_route(server, packet->dst_id,
3330 packet->dst_id_len, NULL,
3333 silc_packet_free(packet);
3337 /* Relay the packet */
3338 silc_server_packet_route(server, dst_sock, packet);
3339 silc_packet_free(packet);
3344 SilcPacketStream sock;
3346 SilcClientID client_id;
3347 } *SilcServerResumeResolve;
3349 SILC_SERVER_CMD_FUNC(resume_resolve)
3351 SilcServerResumeResolve r = (SilcServerResumeResolve)context;
3352 SilcServer server = r->server;
3353 SilcPacketStream sock = r->sock;
3354 SilcServerCommandReplyContext reply = context2;
3355 SilcClientEntry client;
3356 const char *hostname, *ip;
3358 SILC_LOG_DEBUG(("Start"));
3360 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
3361 NULL, &hostname, &ip, NULL);
3363 if (!reply || !silc_command_get_status(reply->payload, NULL, NULL)) {
3364 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3365 "closing connection", hostname, ip));
3366 silc_server_disconnect_remote(server, sock,
3367 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3368 "Resuming not possible");
3369 silc_server_free_sock_user_data(server, sock, NULL);
3373 if (reply && silc_command_get(reply->payload) == SILC_COMMAND_WHOIS) {
3374 /* Get entry to the client, and resolve it if we don't have it. */
3375 client = silc_idlist_find_client_by_id(server->local_list,
3376 &r->client_id, TRUE, NULL);
3378 client = silc_idlist_find_client_by_id(server->global_list,
3379 &r->client_id, TRUE, NULL);
3381 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3382 "closing connection", hostname, ip));
3383 silc_server_disconnect_remote(server, sock,
3384 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3385 "Resuming not possible");
3386 silc_server_free_sock_user_data(server, sock, NULL);
3391 if (!(client->mode & SILC_UMODE_DETACHED)) {
3392 SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, "
3393 "closing connection", hostname, ip));
3394 silc_server_disconnect_remote(server, sock,
3395 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3396 "Resuming not possible");
3397 silc_server_free_sock_user_data(server, sock, NULL);
3401 client->data.status |= SILC_IDLIST_STATUS_RESUME_RES;
3404 /* Reprocess the packet */
3405 silc_server_resume_client(server, sock, r->packet);
3408 silc_packet_stream_unref(r->sock);
3412 /* Received client resuming packet. This is used to resume detached
3413 client session. It can be sent by the client who wishes to resume
3414 but this is also sent by servers and routers to notify other routers
3415 that the client is not detached anymore. */
3417 void silc_server_resume_client(SilcServer server,
3418 SilcPacketStream sock,
3421 SilcBuffer buffer = &packet->buffer, buf;
3422 SilcIDListData idata = silc_packet_get_context(sock);
3423 SilcIDCacheEntry id_cache = NULL;
3424 SilcClientEntry detached_client;
3425 SilcClientID client_id;
3426 unsigned char *id_string, *auth = NULL, *nicknamec = NULL;
3427 unsigned char cid[32];
3429 SilcUInt16 id_len, auth_len = 0;
3430 SilcBool resolved, local, nick_change = FALSE, resolve = FALSE;
3431 SilcChannelEntry channel;
3432 SilcHashTableList htl;
3433 SilcChannelClientEntry chl;
3434 SilcServerResumeResolve r;
3435 SilcPublicKey public_key;
3436 const char *cipher, *hostname, *ip;
3438 SILC_LOG_DEBUG(("Resuming client"));
3440 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
3441 NULL, &hostname, &ip, NULL);
3443 if (silc_buffer_unformat(buffer,
3444 SILC_STR_UI16_NSTRING(&id_string, &id_len),
3445 SILC_STR_END) < 0) {
3446 if (idata->conn_type == SILC_CONN_CLIENT) {
3447 SILC_LOG_ERROR(("Client %s (%s) sent incomplete resume information, "
3448 "closing connection", hostname, ip));
3449 silc_server_disconnect_remote(server, sock,
3450 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3451 "Resuming not possible");
3452 silc_server_free_sock_user_data(server, sock, NULL);
3457 silc_id_str2id(id_string, id_len, SILC_ID_CLIENT, &client_id,
3460 if (idata->conn_type == SILC_CONN_CLIENT) {
3461 /* Client send this and is attempting to resume to old client session */
3462 SilcClientEntry client;
3465 silc_buffer_pull(buffer, 2 + id_len);
3466 auth = buffer->data;
3467 auth_len = silc_buffer_len(buffer);
3468 silc_buffer_push(buffer, 2 + id_len);
3470 if (auth_len < 128) {
3471 SILC_LOG_ERROR(("Client %s (%s) sent incomplete resume information, "
3472 "closing connection", hostname, ip));
3473 silc_server_disconnect_remote(server, sock,
3474 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3475 "Resuming not possible");
3476 silc_server_free_sock_user_data(server, sock, NULL);
3480 /* Take client entry of this connection */
3481 client = (SilcClientEntry)idata;
3483 /* Get entry to the client, and resolve it if we don't have it. */
3484 detached_client = silc_server_query_client(server, &client_id, FALSE,
3486 if (!detached_client) {
3488 /* The client info is being resolved. Reprocess this packet after
3489 receiving the reply to the query. */
3490 SILC_LOG_DEBUG(("Resolving client"));
3491 r = silc_calloc(1, sizeof(*r));
3494 silc_packet_stream_ref(sock);
3498 r->client_id = client_id;
3499 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
3501 silc_server_command_resume_resolve, r);
3504 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3505 "closing connection", hostname, ip));
3506 silc_server_disconnect_remote(server, sock,
3507 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3508 "Resuming not possible");
3509 silc_server_free_sock_user_data(server, sock, NULL);
3514 if (detached_client->data.status & SILC_IDLIST_STATUS_RESUMED) {
3515 SILC_LOG_ERROR(("Client %s (%s) tried to attach more than once, "
3516 "closing connection", hostname, ip));
3517 silc_server_disconnect_remote(server, sock,
3518 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3519 "Resuming not possible");
3520 silc_server_free_sock_user_data(server, sock, NULL);
3524 if (detached_client->resuming_client &&
3525 detached_client->resuming_client != client) {
3526 SILC_LOG_ERROR(("Client %s (%s) tried to attach more than once, "
3527 "closing connection", hostname, ip));
3528 silc_server_disconnect_remote(server, sock,
3529 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3530 "Resuming not possible");
3531 silc_server_free_sock_user_data(server, sock, NULL);
3535 if (!detached_client->resuming_client)
3536 detached_client->resuming_client = client;
3538 if (!(detached_client->mode & SILC_UMODE_DETACHED))
3540 if (!silc_hash_table_count(detached_client->channels) &&
3541 detached_client->router)
3543 if (!detached_client->nickname)
3545 if (detached_client->data.status & SILC_IDLIST_STATUS_RESUME_RES)
3549 if (server->server_type == SILC_SERVER && !server->standalone) {
3550 /* The client info is being resolved. Reprocess this packet after
3551 receiving the reply to the query. */
3552 SILC_LOG_DEBUG(("Resolving client info"));
3553 silc_server_query_client(server, &client_id, TRUE, NULL);
3554 r = silc_calloc(1, sizeof(*r));
3557 silc_packet_stream_ref(sock);
3561 r->client_id = client_id;
3562 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
3564 silc_server_command_resume_resolve, r);
3567 if (server->server_type == SILC_SERVER) {
3568 SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, "
3569 "closing connection", hostname, ip));
3570 silc_server_disconnect_remote(server, sock,
3571 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3572 "Resuming not possible");
3573 silc_server_free_sock_user_data(server, sock, NULL);
3578 /* Check that we have the public key of the client, if not then we must
3579 resolve it first. */
3580 if (!detached_client->data.public_key) {
3581 if (server->server_type == SILC_SERVER && server->standalone) {
3582 SILC_LOG_ERROR(("Detached client's public key not present, "
3583 "closing connection"));
3584 silc_server_disconnect_remote(server, sock,
3585 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3586 "Resuming not possible");
3587 silc_server_free_sock_user_data(server, sock, NULL);
3590 /* We must retrieve the detached client's public key by sending
3591 GETKEY command. Reprocess this packet after receiving the key */
3592 SilcBuffer idp = silc_id_payload_encode(&client_id, SILC_ID_CLIENT);
3593 SilcPacketStream dest_sock =
3594 silc_server_get_client_route(server, NULL, 0, &client_id,
3597 SILC_LOG_DEBUG(("Resolving client public key"));
3599 silc_server_send_command(server, dest_sock ? dest_sock :
3600 SILC_PRIMARY_ROUTE(server),
3601 SILC_COMMAND_GETKEY, ++server->cmd_ident,
3602 1, 1, idp->data, silc_buffer_len(idp));
3604 r = silc_calloc(1, sizeof(*r));
3607 silc_packet_stream_ref(sock);
3611 r->client_id = client_id;
3612 silc_server_command_pending(server, SILC_COMMAND_GETKEY,
3614 silc_server_command_resume_resolve, r);
3616 silc_buffer_free(idp);
3619 } else if (!silc_pkcs_public_key_compare(detached_client->data.public_key,
3620 idata->public_key)) {
3621 /* We require that the connection and resuming authentication data
3622 must be using same key pair. */
3623 SILC_LOG_ERROR(("Resuming attempted with wrong public key, "
3624 "closing connection"));
3625 silc_server_disconnect_remote(server, sock,
3626 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3627 "Resuming not possible");
3628 silc_server_free_sock_user_data(server, sock, NULL);
3632 /* Verify the authentication payload. This has to be successful in
3633 order to allow the resuming */
3635 !silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
3636 detached_client->data.public_key, 0,
3637 idata->hash, detached_client->id,
3639 SILC_LOG_ERROR(("Client %s (%s) resume authentication failed, "
3640 "closing connection", hostname, ip));
3641 silc_server_disconnect_remote(server, sock,
3642 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3643 "Resuming not possible");
3644 silc_server_free_sock_user_data(server, sock, NULL);
3648 /* Check nickname */
3649 nicknamec = silc_identifier_check(detached_client->nickname,
3650 strlen(detached_client->nickname),
3651 SILC_STRING_UTF8, 128, NULL);
3653 silc_server_disconnect_remote(server, sock,
3654 SILC_STATUS_ERR_BAD_NICKNAME,
3655 "Malformed nickname, cannot resume");
3656 silc_server_free_sock_user_data(server, sock, NULL);
3660 /* If the ID is not based in our ID then change it */
3661 if (!SILC_ID_COMPARE(detached_client->id, server->id,
3662 server->id->ip.data_len)) {
3663 SilcClientID *new_id;
3664 if (!silc_id_create_client_id(server, server->id, server->rng,
3665 server->md5hash, nicknamec,
3666 strlen(nicknamec), &new_id)) {
3667 silc_server_disconnect_remote(server, sock,
3668 SILC_STATUS_ERR_BAD_NICKNAME,
3669 "Resuming not possible");
3670 silc_server_free_sock_user_data(server, sock, NULL);
3674 client_id = *new_id;
3678 /* Now resume the client to the network */
3680 silc_schedule_task_del_by_context(server->schedule, detached_client);
3681 silc_packet_set_context(sock, detached_client);
3682 detached_client->connection = sock;
3684 if (detached_client->data.public_key) {
3685 /* Delete the detached client's public key from repository */
3686 silc_skr_del_public_key(server->repository,
3687 detached_client->data.public_key,
3689 detached_client->data.public_key = NULL;
3692 if (idata->public_key) {
3693 /* Delete the resuming client's public key from repository. It will
3694 be added later again. */
3695 public_key = silc_pkcs_public_key_copy(idata->public_key);
3696 silc_skr_del_public_key(server->repository, idata->public_key, idata);
3697 idata->public_key = public_key;
3700 /* Take new keys and stuff into use in the old entry */
3701 silc_idlist_del_data(detached_client);
3702 silc_idlist_add_data(detached_client, idata);
3703 idata->public_key = NULL;
3705 if (detached_client->data.public_key) {
3706 /* Add the resumed client's public key back to repository. */
3707 if (!silc_server_get_public_key_by_client(server, detached_client, NULL))
3708 silc_skr_add_public_key_simple(server->repository,
3709 detached_client->data.public_key,
3710 SILC_SKR_USAGE_IDENTIFICATION,
3711 detached_client, NULL);
3714 detached_client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
3715 detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
3716 detached_client->data.status |= SILC_IDLIST_STATUS_LOCAL;
3717 detached_client->data.status &= ~SILC_IDLIST_STATUS_RESUME_RES;
3718 detached_client->mode &= ~SILC_UMODE_DETACHED;
3719 server->stat.my_detached--;
3721 /* We are finished - reset resuming client */
3722 detached_client->resuming_client = NULL;
3724 /* Check if anyone is watching this client */
3725 if (server->server_type == SILC_ROUTER)
3726 silc_server_check_watcher_list(server, detached_client, NULL,
3727 SILC_NOTIFY_TYPE_UMODE_CHANGE);
3729 /* Delete this current client entry since we're resuming to old one. */
3730 server->stat.my_clients--;
3731 server->stat.clients--;
3732 if (server->stat.cell_clients)
3733 server->stat.cell_clients--;
3734 silc_server_remove_from_channels(server, NULL, client, FALSE,
3735 NULL, FALSE, FALSE);
3736 silc_server_del_from_watcher_list(server, client);
3737 if (!silc_idlist_del_client(server->local_list, client))
3738 silc_idlist_del_client(server->global_list, client);
3739 client = detached_client;
3740 silc_free(client->servername);
3741 client->servername = strdup(server->server_name);
3743 /* Send the RESUME_CLIENT packet to our primary router so that others
3744 know this client isn't detached anymore. */
3745 buf = silc_buffer_alloc_size(2 + id_len);
3746 silc_buffer_format(buf,
3747 SILC_STR_UI_SHORT(id_len),
3748 SILC_STR_UI_XNSTRING(id_string, id_len),
3751 /* Send to primary router */
3752 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
3753 SILC_PACKET_RESUME_CLIENT, 0,
3754 buf->data, silc_buffer_len(buf));
3755 silc_server_backup_send(server, client->router,
3756 SILC_PACKET_RESUME_CLIENT, 0,
3757 buf->data, silc_buffer_len(buf), TRUE, TRUE);
3759 /* As router we must deliver this packet directly to the original
3760 server whom this client was earlier. */
3761 if (server->server_type == SILC_ROUTER && client->router &&
3762 client->router->server_type != SILC_ROUTER)
3763 silc_server_packet_send(server, client->router->connection,
3764 SILC_PACKET_RESUME_CLIENT, 0,
3765 buf->data, silc_buffer_len(buf));
3766 silc_buffer_free(buf);
3767 client->router = NULL;
3770 /* Notify about Client ID change, nickname doesn't actually change. */
3771 silc_server_send_notify_nick_change(server, SILC_PRIMARY_ROUTE(server),
3772 SILC_BROADCAST(server),
3773 client->id, &client_id,
3777 /* Resolve users on those channels that client has joined but we
3778 haven't resolved user list yet. */
3779 if (server->server_type == SILC_SERVER && !server->standalone) {
3780 silc_hash_table_list(client->channels, &htl);
3781 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3782 channel = chl->channel;
3783 SILC_LOG_DEBUG(("Resolving users for %s channel",
3784 channel->channel_name));
3785 if (channel->disabled || !channel->users_resolved) {
3786 silc_server_send_command(server, SILC_PRIMARY_ROUTE(server),
3787 SILC_COMMAND_USERS, ++server->cmd_ident,
3788 1, 2, channel->channel_name,
3789 strlen(channel->channel_name));
3792 silc_hash_table_list_reset(&htl);
3795 /* Send the new client ID to the client. After this client may start
3796 receiving other packets, and may start sending packets too. */
3797 silc_server_send_new_id(server, sock, FALSE, &client_id, SILC_ID_CLIENT,
3798 silc_id_get_len(&client_id, SILC_ID_CLIENT));
3801 /* Send NICK change notify to channels as well. */
3802 SilcBuffer oidp, nidp;
3803 oidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3804 nidp = silc_id_payload_encode(&client_id, SILC_ID_CLIENT);
3805 silc_server_send_notify_on_channels(server, NULL, client,
3806 SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
3807 oidp->data, silc_buffer_len(oidp),
3808 nidp->data, silc_buffer_len(nidp),
3810 strlen(client->nickname));
3811 silc_buffer_free(oidp);
3812 silc_buffer_free(nidp);
3816 if (!silc_idcache_update_by_context(server->local_list->clients, client,
3817 &client_id, NULL, FALSE))
3818 silc_idcache_update_by_context(server->global_list->clients, client,
3819 &client_id, NULL, FALSE);
3821 /* Move entry to local list if it is in global list */
3822 if (silc_idcache_find_by_context(server->global_list->clients, client,
3824 silc_idcache_move(server->global_list->clients,
3825 server->local_list->clients, id_cache);
3827 /* Send some nice info to the client */
3828 silc_server_send_connect_notifys(server, sock, client);
3830 /* Send all channel keys of channels the client has joined */
3831 silc_hash_table_list(client->channels, &htl);
3832 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3833 SilcBool created = FALSE;
3834 channel = chl->channel;
3836 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY)
3839 /* If we don't have channel key, then create one */
3840 if (!channel->send_key) {
3841 if (!silc_server_create_channel_key(server, channel, 0))
3846 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid),
3848 cipher = silc_cipher_get_name(channel->send_key);
3850 silc_channel_key_payload_encode(cid_len, cid,
3851 strlen(cipher), cipher,
3852 channel->key_len / 8, channel->key);
3854 /* Send the channel key to the client */
3855 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
3856 keyp->data, silc_buffer_len(keyp));
3858 /* Distribute the channel key to channel */
3860 silc_server_send_channel_key(server, NULL, channel,
3861 server->server_type == SILC_ROUTER ?
3862 FALSE : !server->standalone);
3863 silc_server_backup_send(server, NULL, SILC_PACKET_CHANNEL_KEY, 0,
3864 keyp->data, silc_buffer_len(keyp),
3868 silc_buffer_free(keyp);
3870 silc_hash_table_list_reset(&htl);
3872 } else if (idata->conn_type != SILC_CONN_CLIENT) {
3873 /* Server or router sent this to us to notify that that a client has
3875 SilcServerEntry server_entry;
3876 SilcServerID server_id;
3878 /* Get entry to the client, and resolve it if we don't have it. */
3879 detached_client = silc_idlist_find_client_by_id(server->local_list,
3882 if (!detached_client) {
3883 detached_client = silc_idlist_find_client_by_id(server->global_list,
3886 if (!detached_client) {
3887 SILC_LOG_DEBUG(("Resuming client is unknown"));
3892 /* Check that the client has not been resumed already because it is
3893 protocol error to attempt to resume more than once. The client
3894 will be killed if this protocol error occurs. */
3895 if (detached_client->data.status & SILC_IDLIST_STATUS_RESUMED &&
3896 !(detached_client->mode & SILC_UMODE_DETACHED)) {
3897 /* The client is clearly attempting to resume more than once and
3898 perhaps playing around by resuming from several different places
3899 at the same time. */
3900 SILC_LOG_DEBUG(("Attempting to re-resume client, killing both"));
3901 silc_server_kill_client(server, detached_client, NULL,
3902 server->id, SILC_ID_SERVER);
3906 /* Check whether client is detached at all */
3907 if (!(detached_client->mode & SILC_UMODE_DETACHED)) {
3908 SILC_LOG_DEBUG(("Client is not detached"));
3912 /* Check nickname */
3913 if (detached_client->nickname) {
3914 nicknamec = silc_identifier_check(detached_client->nickname,
3915 strlen(detached_client->nickname),
3916 SILC_STRING_UTF8, 128, NULL);
3921 SILC_LOG_DEBUG(("Resuming detached client"));
3923 /* If the sender of this packet is server and we are router we need to
3924 broadcast this packet to other routers in the network. */
3925 if (server->server_type == SILC_ROUTER &&
3926 idata->conn_type == SILC_CONN_SERVER &&
3927 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
3928 SILC_LOG_DEBUG(("Broadcasting received Resume Client packet"));
3929 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
3931 packet->flags | SILC_PACKET_FLAG_BROADCAST,
3932 buffer->data, silc_buffer_len(buffer));
3933 silc_server_backup_send(server, (SilcServerEntry)idata,
3934 packet->type, packet->flags,
3935 packet->buffer.data,
3936 silc_buffer_len(&packet->buffer),
3940 /* Client is detached, and now it is resumed. Remove the detached
3941 mode and mark that it is resumed. */
3943 if (detached_client->data.public_key) {
3944 /* Delete the detached client's public key from repository */
3945 silc_skr_del_public_key(server->repository,
3946 detached_client->data.public_key,
3948 detached_client->data.public_key = NULL;
3951 silc_idlist_del_data(detached_client);
3952 detached_client->mode &= ~SILC_UMODE_DETACHED;
3953 detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
3954 detached_client->data.status &= ~SILC_IDLIST_STATUS_LOCAL;
3955 silc_dlist_del(server->expired_clients, detached_client);
3956 silc_dlist_del(server->expired_clients, detached_client);
3958 /* Check if anyone is watching this client */
3959 if (server->server_type == SILC_ROUTER)
3960 silc_server_check_watcher_list(server, detached_client, NULL,
3961 SILC_NOTIFY_TYPE_UMODE_CHANGE);
3963 silc_schedule_task_del_by_context(server->schedule, detached_client);
3965 /* Get the new owner of the resumed client */
3966 if (!silc_id_str2id(packet->src_id, packet->src_id_len,
3967 packet->src_id_type, &server_id, sizeof(server_id)))
3970 /* Get server entry */
3971 server_entry = silc_idlist_find_server_by_id(server->global_list,
3972 &server_id, TRUE, NULL);
3974 if (!server_entry) {
3975 server_entry = silc_idlist_find_server_by_id(server->local_list,
3976 &server_id, TRUE, NULL);
3982 if (server->server_type == SILC_ROUTER &&
3983 idata->conn_type == SILC_CONN_ROUTER &&
3984 server_entry->server_type == SILC_ROUTER)
3987 /* Move entry to correct list */
3988 if (local && server->server_type == SILC_ROUTER) {
3989 if (silc_idcache_find_by_context(server->global_list->clients,
3990 detached_client, &id_cache))
3991 silc_idcache_move(server->global_list->clients,
3992 server->local_list->clients, id_cache);
3994 if (silc_idcache_find_by_context(server->local_list->clients,
3995 detached_client, &id_cache))
3996 silc_idcache_move(server->local_list->clients,
3997 server->global_list->clients, id_cache);
4000 /* Change the owner of the client */
4001 detached_client->router = server_entry;
4003 /* Update channel information regarding global clients on channel. */
4004 if (server->server_type != SILC_ROUTER) {
4005 silc_hash_table_list(detached_client->channels, &htl);
4006 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
4007 chl->channel->global_users =
4008 silc_server_channel_has_global(chl->channel);
4009 silc_hash_table_list_reset(&htl);
4014 silc_packet_free(packet);