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_add(server->expired_clients, client);
362 case SILC_NOTIFY_TYPE_TOPIC_SET:
364 * Distribute the notify to local clients on the channel
367 SILC_LOG_DEBUG(("TOPIC SET notify"));
370 if (!silc_argument_get_decoded(args, 1, SILC_ARGUMENT_ID, &id, NULL))
373 /* Get client entry */
374 if (id.type == SILC_ID_CLIENT) {
375 client = silc_idlist_find_client_by_id(server->global_list,
376 SILC_ID_GET_ID(id), TRUE, &cache);
378 client = silc_idlist_find_client_by_id(server->local_list,
387 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
391 if (!silc_id_str2id(packet->dst_id, packet->dst_id_len,
392 packet->dst_id_type, &channel_id,
396 /* Get channel entry */
397 channel = silc_idlist_find_channel_by_id(server->global_list,
400 channel = silc_idlist_find_channel_by_id(server->local_list,
403 SILC_LOG_DEBUG(("Notify for unknown channel %s",
404 silc_id_render(&channel_id, SILC_ID_CHANNEL)));
409 if (channel->topic && !strcmp(channel->topic, tmp)) {
410 SILC_LOG_DEBUG(("Topic is already set and same"));
415 /* Get user's channel entry and check that topic set is allowed. */
416 if (!silc_server_client_on_channel(client, channel, &chl))
418 if (channel->mode & SILC_CHANNEL_MODE_TOPIC &&
419 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
420 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
421 SILC_LOG_DEBUG(("Topic change is not allowed"));
426 /* Change the topic */
427 silc_free(channel->topic);
428 channel->topic = strdup(tmp);
430 /* Send the same notify to the channel */
431 silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
432 FALSE, TRUE, buffer->data,
433 silc_buffer_len(buffer));
436 case SILC_NOTIFY_TYPE_NICK_CHANGE:
439 * Distribute the notify to local clients on the channel
442 SilcUInt32 nickname_len;
444 SILC_LOG_DEBUG(("NICK CHANGE notify"));
446 /* Get old client ID */
447 if (!silc_argument_get_decoded(args, 1, SILC_ARGUMENT_ID, &id, NULL))
450 /* Get new client ID */
451 if (!silc_argument_get_decoded(args, 2, SILC_ARGUMENT_ID, &id2, NULL))
454 SILC_LOG_DEBUG(("Old Client ID id(%s)",
455 silc_id_render(SILC_ID_GET_ID(id), SILC_ID_CLIENT)));
456 SILC_LOG_DEBUG(("New Client ID id(%s)",
457 silc_id_render(SILC_ID_GET_ID(id2), SILC_ID_CLIENT)));
459 /* From protocol version 1.1 we also get the new nickname */
460 nickname = silc_argument_get_arg_type(args, 3, &nickname_len);;
462 /* Replace the Client ID */
463 client = silc_idlist_replace_client_id(server,
466 SILC_ID_GET_ID(id2), nickname);
468 client = silc_idlist_replace_client_id(server,
471 SILC_ID_GET_ID(id2), nickname);
474 /* Send the NICK_CHANGE notify type to local clients on the channels
475 this client is joined to. */
476 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
477 tmp2 = silc_argument_get_arg_type(args, 2, &tmp2_len);
478 silc_server_send_notify_on_channels(server, client, client,
479 SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
480 tmp, tmp_len, tmp2, tmp2_len,
488 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
490 * Distribute the notify to local clients on the channel
493 SILC_LOG_DEBUG(("CMODE CHANGE notify"));
496 if (!silc_argument_get_decoded(args, 1, SILC_ARGUMENT_ID, &id, NULL))
499 /* Get client entry */
500 if (id.type == SILC_ID_CLIENT) {
501 client = silc_idlist_find_client_by_id(server->global_list,
502 SILC_ID_GET_ID(id), TRUE, &cache);
504 client = silc_idlist_find_client_by_id(server->local_list,
512 if (!silc_id_str2id(packet->dst_id, packet->dst_id_len,
513 packet->dst_id_type, &channel_id,
517 /* Get channel entry */
518 channel = silc_idlist_find_channel_by_id(server->global_list,
521 channel = silc_idlist_find_channel_by_id(server->local_list,
524 SILC_LOG_DEBUG(("Notify for unknown channel %s",
525 silc_id_render(&channel_id, SILC_ID_CHANNEL)));
531 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
534 SILC_GET32_MSB(mode, tmp);
536 /* Check if mode changed */
537 if (channel->mode == mode) {
538 SILC_LOG_DEBUG(("Mode is changed already"));
540 /* If this mode change has founder mode then we'll enforce the
541 change so that the server gets the real founder public key */
542 if (server->server_type != SILC_SERVER &&
543 sock != SILC_PRIMARY_ROUTE(server) &&
544 mode & SILC_CHANNEL_MODE_FOUNDER_AUTH && channel->founder_key) {
545 SILC_LOG_DEBUG(("Sending founder public key to server"));
546 silc_server_send_notify_cmode(server, sock, FALSE, channel,
547 channel->mode, server->id,
548 SILC_ID_SERVER, channel->cipher,
551 channel->founder_key, NULL);
554 /* If we received same mode from our primary check whether founder
555 mode and key in the notify is set. We update the founder key
556 here since we may have wrong one */
557 if (server->server_type != SILC_ROUTER &&
558 sock == SILC_PRIMARY_ROUTE(server) &&
559 mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
560 SILC_LOG_DEBUG(("Founder public key received from router"));
561 tmp = silc_argument_get_arg_type(args, 6, &tmp_len);
565 if (channel->founder_key)
566 silc_pkcs_public_key_free(channel->founder_key);
567 channel->founder_key = NULL;
568 silc_public_key_payload_decode(tmp, tmp_len,
569 &channel->founder_key);
572 /* Check also for channel public key list */
573 if (server->server_type == SILC_SERVER &&
574 sock == SILC_PRIMARY_ROUTE(server) &&
575 mode & SILC_CHANNEL_MODE_CHANNEL_AUTH) {
578 unsigned char mask[4], ulimit[4];
580 SILC_LOG_DEBUG(("Channel public key list received from router"));
581 tmp = silc_argument_get_arg_type(args, 7, &tmp_len);
585 /* Set the router's list, and send the notify to channel too so that
586 channel gets the list */
587 silc_server_set_channel_pk_list(server, sock, channel, tmp, tmp_len);
588 chpklist = silc_server_get_channel_pk_list(server, channel,
592 sidp = silc_id_payload_encode(server->router->id, SILC_ID_SERVER);
593 SILC_PUT32_MSB(channel->mode, mask);
594 if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
595 SILC_PUT32_MSB(channel->user_limit, ulimit);
596 silc_server_send_notify_to_channel(server, NULL, channel, FALSE, TRUE,
597 SILC_NOTIFY_TYPE_CMODE_CHANGE, 8,
598 sidp->data, silc_buffer_len(sidp),
602 strlen(channel->cipher) : 0,
605 strlen(channel->hmac_name) : 0,
607 channel->passphrase ?
608 strlen(channel->passphrase) : 0,
611 silc_buffer_len(chpklist),
613 SILC_CHANNEL_MODE_ULIMIT ?
616 SILC_CHANNEL_MODE_ULIMIT ?
617 sizeof(ulimit) : 0));
618 silc_buffer_free(sidp);
619 silc_buffer_free(chpklist);
626 /* Get user's channel entry and check that mode change is allowed */
628 if (!silc_server_client_on_channel(client, channel, &chl))
630 if (!silc_server_check_cmode_rights(server, channel, chl, mode)) {
631 SILC_LOG_DEBUG(("CMODE change is not allowed"));
632 silc_server_send_notify_cmode(server, sock, FALSE, channel,
633 channel->mode, server->id,
634 SILC_ID_SERVER, channel->cipher,
637 channel->founder_key, NULL);
641 /* Assure that server is not removing founder mode from us */
642 if (server->server_type == SILC_ROUTER &&
643 sock != SILC_PRIMARY_ROUTE(server) &&
644 channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH &&
645 !(mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
646 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
647 silc_server_send_notify_cmode(server, sock, FALSE, channel,
648 channel->mode, server->id,
649 SILC_ID_SERVER, channel->cipher,
652 channel->founder_key, NULL);
656 /* If server is adding founder mode, check whether there is founder
657 on channel already and is not from this server */
658 if (server->server_type == SILC_ROUTER &&
659 sock != SILC_PRIMARY_ROUTE(server) &&
660 mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
661 silc_hash_table_list(channel->user_list, &htl);
662 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
663 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO &&
664 chl->client->router != (SilcServerEntry)idata) {
665 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
666 silc_server_send_notify_cmode(server, sock, FALSE, channel,
667 channel->mode, server->id,
668 SILC_ID_SERVER, channel->cipher,
671 channel->founder_key, NULL);
672 silc_hash_table_list_reset(&htl);
675 silc_hash_table_list_reset(&htl);
679 /* If the channel had private keys set and the mode was removed then
680 we must re-generate and re-distribute a new channel key */
681 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY &&
682 !(mode & SILC_CHANNEL_MODE_PRIVKEY)) {
683 /* Re-generate channel key */
684 if (!silc_server_create_channel_key(server, channel, 0))
687 /* Send the channel key. This sends it to our local clients and if
688 we are normal server to our router as well. */
689 silc_server_send_channel_key(server, NULL, channel,
690 server->server_type == SILC_ROUTER ?
691 FALSE : !server->standalone);
695 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
697 unsigned char hash[SILC_HASH_MAXLEN];
700 silc_hmac_free(channel->hmac);
701 if (!silc_hmac_alloc(tmp, NULL, &channel->hmac))
704 /* Set the HMAC key out of current channel key. The client must do
706 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key,
707 channel->key_len / 8, hash);
708 silc_hmac_set_key(channel->hmac, hash,
709 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
710 memset(hash, 0, sizeof(hash));
713 /* Get the passphrase */
714 tmp = silc_argument_get_arg_type(args, 5, &tmp_len);
716 silc_free(channel->passphrase);
717 channel->passphrase = silc_memdup(tmp, tmp_len);
720 /* Get founder public key */
721 tmp = silc_argument_get_arg_type(args, 6, &tmp_len);
722 if (tmp && mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
723 if (channel->founder_key)
724 silc_pkcs_public_key_free(channel->founder_key);
725 channel->founder_key = NULL;
726 SILC_LOG_DEBUG(("Founder public key received"));
727 if (!silc_public_key_payload_decode(tmp, tmp_len,
728 &channel->founder_key)) {
729 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
730 mode &= ~SILC_CHANNEL_MODE_FOUNDER_AUTH;
731 silc_server_send_notify_cmode(server, sock, FALSE, channel,
732 mode, server->id, SILC_ID_SERVER,
735 channel->passphrase, NULL, NULL);
736 if (channel->founder_key)
737 silc_pkcs_public_key_free(channel->founder_key);
738 channel->founder_key = NULL;
742 if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH && !channel->founder_key &&
743 server->server_type == SILC_ROUTER) {
744 SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
745 mode &= ~SILC_CHANNEL_MODE_FOUNDER_AUTH;
746 silc_server_send_notify_cmode(server, sock, FALSE, channel,
747 mode, server->id, SILC_ID_SERVER,
750 channel->passphrase, NULL, NULL);
753 /* Process channel public key(s). */
754 tmp = silc_argument_get_arg_type(args, 7, &tmp_len);
755 if (tmp && mode & SILC_CHANNEL_MODE_CHANNEL_AUTH) {
757 SILC_LOG_DEBUG(("Channel public key list received from router"));
760 silc_server_set_channel_pk_list(server, sock, channel, tmp, tmp_len);
762 /* If list was set already we will enforce the same list to server. */
763 if (ret == SILC_STATUS_ERR_OPERATION_ALLOWED) {
764 SilcBuffer chpklist = silc_server_get_channel_pk_list(server, channel,
766 silc_server_send_notify_cmode(server, sock, FALSE, channel,
767 mode, server->id, SILC_ID_SERVER,
770 channel->passphrase, NULL,
772 silc_buffer_free(chpklist);
776 /* Get the user limit */
777 tmp = silc_argument_get_arg_type(args, 8, &tmp_len);
778 if (tmp && tmp_len == 4 && mode & SILC_CHANNEL_MODE_ULIMIT)
779 SILC_GET32_MSB(channel->user_limit, tmp);
781 /* Send the same notify to the channel */
782 silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
783 FALSE, TRUE, buffer->data,
784 silc_buffer_len(buffer));
787 channel->mode = mode;
789 /* Cleanup if some modes are removed */
791 if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) &&
792 channel->founder_key) {
793 silc_pkcs_public_key_free(channel->founder_key);
794 channel->founder_key = NULL;
797 if (!(channel->mode & SILC_CHANNEL_MODE_CHANNEL_AUTH) &&
798 channel->channel_pubkeys) {
799 silc_hash_table_free(channel->channel_pubkeys);
800 channel->channel_pubkeys = NULL;
805 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
808 * Distribute the notify to local clients on the channel
810 SilcChannelClientEntry chl2 = NULL;
811 SilcBool notify_sent = FALSE;
813 SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
816 if (!silc_argument_get_decoded(args, 1, SILC_ARGUMENT_ID, &id, NULL))
819 /* Get client entry */
820 if (id.type == SILC_ID_CLIENT) {
821 client = silc_idlist_find_client_by_id(server->global_list,
825 client = silc_idlist_find_client_by_id(server->local_list,
833 if (!silc_id_str2id(packet->dst_id, packet->dst_id_len,
834 packet->dst_id_type, &channel_id,
838 /* Get channel entry */
839 channel = silc_idlist_find_channel_by_id(server->global_list,
842 channel = silc_idlist_find_channel_by_id(server->local_list,
845 SILC_LOG_DEBUG(("Notify for unknown channel %s",
846 silc_id_render(&channel_id, SILC_ID_CHANNEL)));
852 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
856 SILC_GET32_MSB(mode, tmp);
858 /* Get target client */
859 if (!silc_argument_get_decoded(args, 3, SILC_ARGUMENT_ID, &id, NULL))
862 /* Get client entry */
863 client2 = silc_idlist_find_client_by_id(server->global_list,
864 SILC_ID_GET_ID(id), TRUE, NULL);
866 client2 = silc_idlist_find_client_by_id(server->local_list,
874 /* Check that sender is on channel */
875 if (!silc_server_client_on_channel(client, channel, &chl))
878 if (client != client2 && server->server_type == SILC_ROUTER) {
879 /* Sender must be operator */
880 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
881 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
882 SILC_LOG_DEBUG(("CUMODE change is not allowed"));
886 if (!silc_server_client_on_channel(client2, channel, &chl))
889 /* If target is founder mode change is not allowed. */
890 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
891 SILC_LOG_DEBUG(("CUMODE change is not allowed"));
897 /* Get target channel user entry */
898 if (!silc_server_client_on_channel(client2, channel, &chl))
901 if (server->server_type == SILC_SERVER && chl->mode == mode) {
902 SILC_LOG_DEBUG(("Mode is changed already"));
906 /* Check whether to give founder rights to this user or not. The
907 problem here is that we get only the public key of the client,
908 but no authentication data. We must assume that server has
909 already authenticated the user (and thus we must trust the
911 if (mode & SILC_CHANNEL_UMODE_CHANFO &&
912 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO) &&
913 server->server_type == SILC_ROUTER &&
914 sock != SILC_PRIMARY_ROUTE(server)) {
915 SilcPublicKey founder_key = NULL;
917 /* If channel doesn't have founder auth mode then it's impossible
918 that someone would be getting founder rights with CUMODE command.
919 In that case there already either is founder or there isn't
920 founder at all on the channel (valid only when 'client' is
922 if (client && !(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
923 /* Force the mode to not have founder mode */
924 chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
925 silc_server_force_cumode_change(server, sock, channel, chl, mode);
930 /* Get the founder of the channel and if found then this client
931 cannot be the founder since there already is one. */
932 silc_hash_table_list(channel->user_list, &htl);
933 while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
934 if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
935 SILC_LOG_DEBUG(("Founder already on channel"));
936 chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
937 silc_server_force_cumode_change(server, sock, channel,
942 silc_hash_table_list_reset(&htl);
943 if (!(mode & SILC_CHANNEL_UMODE_CHANFO))
946 /* Founder not found on the channel. Since the founder auth mode
947 is set on the channel now check whether this is the client that
948 originally set the mode. */
950 if (channel->founder_key) {
951 /* Get public key that must be present in notify */
952 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
953 if (!tmp || !silc_public_key_payload_decode(tmp, tmp_len,
955 chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
956 SILC_LOG_DEBUG(("Founder public key not present"));
957 silc_server_force_cumode_change(server, sock, channel, chl, mode);
962 /* Now match the public key we have cached and public key sent.
964 if (!silc_pkcs_public_key_compare(channel->founder_key,
966 chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO;
967 SILC_LOG_DEBUG(("Founder public key mismatch"));
968 silc_server_force_cumode_change(server, sock, channel, chl, mode);
974 /* There cannot be anyone else as founder on the channel now. This
975 client is definitely the founder due to this 'authentication'.
976 We trust the server did the actual signature verification
977 earlier (bad, yes). */
978 silc_hash_table_list(channel->user_list, &htl);
979 while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
980 if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
981 chl2->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
982 SILC_LOG_DEBUG(("Removing old founder rights, new authenticated"));
983 silc_server_force_cumode_change(server, NULL, channel, chl2,
987 silc_hash_table_list_reset(&htl);
990 silc_pkcs_public_key_free(founder_key);
993 if (server->server_type != SILC_SERVER && chl->mode == mode) {
994 SILC_LOG_DEBUG(("Mode is changed already"));
998 SILC_LOG_DEBUG(("Changing %s channel user mode",
999 chl->client->nickname ? chl->client->nickname :
1000 (unsigned char *)""));
1002 /* Change the mode */
1005 /* Send the same notify to the channel */
1007 silc_server_packet_send_to_channel(server, sock, channel,
1009 FALSE, TRUE, buffer->data,
1010 silc_buffer_len(buffer));
1015 case SILC_NOTIFY_TYPE_INVITE:
1017 if (packet->dst_id_type == SILC_ID_CLIENT)
1020 SILC_LOG_DEBUG(("INVITE notify"));
1022 /* Get Channel ID */
1023 if (!silc_argument_get_decoded(args, 1, SILC_ARGUMENT_ID, &id, NULL))
1026 /* Get channel entry */
1027 channel = silc_idlist_find_channel_by_id(server->global_list,
1028 SILC_ID_GET_ID(id), NULL);
1030 channel = silc_idlist_find_channel_by_id(server->local_list,
1031 SILC_ID_GET_ID(id), NULL);
1033 SILC_LOG_DEBUG(("Notify for unknown channel %s",
1034 silc_id_render(SILC_ID_GET_ID(id), SILC_ID_CHANNEL)));
1039 /* Get the invite action */
1040 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
1041 if (tmp && tmp_len == 1) {
1042 SilcUInt8 action = (SilcUInt8)tmp[0];
1043 SilcUInt16 iargc = 0;
1044 SilcArgumentPayload iargs;
1046 /* Get invite list */
1047 tmp = silc_argument_get_arg_type(args, 5, &tmp_len);
1048 if (!tmp || tmp_len < 2)
1051 /* Parse the arguments to see they are constructed correctly */
1052 SILC_GET16_MSB(iargc, tmp);
1053 iargs = silc_argument_payload_parse(tmp + 2, tmp_len - 2, iargc);
1057 if (!channel->invite_list)
1058 channel->invite_list =
1059 silc_hash_table_alloc(0, silc_hash_ptr,
1061 silc_server_inviteban_destruct, channel, TRUE);
1063 /* Proces the invite action */
1064 if (!silc_server_inviteban_process(server, channel->invite_list, action,
1067 silc_argument_payload_free(iargs);
1069 /* If we are router we must send this notify to our local servers on
1070 the channel. Normal server does nothing. The notify is not
1072 if (server->server_type == SILC_ROUTER)
1073 silc_server_packet_send_to_channel(server, sock, channel,
1074 packet->type, FALSE, FALSE,
1076 silc_buffer_len(buffer));
1081 case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
1083 * Distribute to the local clients on the channel and change the
1087 SILC_LOG_DEBUG(("CHANNEL CHANGE"));
1089 if (idata->conn_type != SILC_CONN_ROUTER)
1092 /* Get the old Channel ID */
1093 if (!silc_argument_get_decoded(args, 1, SILC_ARGUMENT_ID, &id, NULL))
1096 /* Get the channel entry */
1097 channel = silc_idlist_find_channel_by_id(server->local_list,
1098 SILC_ID_GET_ID(id), NULL);
1100 channel = silc_idlist_find_channel_by_id(server->global_list,
1101 SILC_ID_GET_ID(id), NULL);
1103 SILC_LOG_DEBUG(("Notify for unknown channel %s",
1104 silc_id_render(SILC_ID_GET_ID(id), SILC_ID_CHANNEL)));
1109 /* Send the notify to the channel */
1110 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
1111 FALSE, TRUE, buffer->data,
1112 silc_buffer_len(buffer));
1114 /* Get the new Channel ID */
1115 if (!silc_argument_get_decoded(args, 2, SILC_ARGUMENT_ID, &id2, NULL))
1118 SILC_LOG_DEBUG(("Old Channel ID id(%s)",
1119 silc_id_render(SILC_ID_GET_ID(id), SILC_ID_CHANNEL)));
1120 SILC_LOG_DEBUG(("New Channel ID id(%s)",
1121 silc_id_render(SILC_ID_GET_ID(id2), SILC_ID_CHANNEL)));
1123 /* Replace the Channel ID */
1125 if (!silc_idlist_replace_channel_id(server->local_list,
1127 SILC_ID_GET_ID(id2)))
1128 if (!silc_idlist_replace_channel_id(server->global_list,
1130 SILC_ID_GET_ID(id2)))
1134 SilcBuffer modes = NULL, users = NULL, users_modes = NULL;
1136 /* Re-announce this channel which ID was changed. */
1137 silc_server_send_new_channel(server, sock, FALSE, channel->channel_name,
1139 silc_id_get_len(channel->id,
1143 /* Re-announce our clients on the channel as the ID has changed now */
1144 silc_server_announce_get_channel_users(server, channel, &modes, &users,
1147 silc_buffer_push(users, users->data - users->head);
1148 silc_server_packet_send(server, sock,
1149 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1150 users->data, silc_buffer_len(users));
1151 silc_buffer_free(users);
1154 silc_buffer_push(modes, modes->data - modes->head);
1155 silc_server_packet_send_dest(server, sock,
1156 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1157 channel->id, SILC_ID_CHANNEL,
1158 modes->data, silc_buffer_len(modes));
1159 silc_buffer_free(modes);
1162 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
1163 silc_server_packet_send_dest(server, sock,
1164 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1165 channel->id, SILC_ID_CHANNEL,
1167 silc_buffer_len(users_modes));
1168 silc_buffer_free(users_modes);
1171 /* Re-announce channel's topic */
1172 if (channel->topic) {
1173 silc_server_send_notify_topic_set(server, sock,
1174 server->server_type == SILC_ROUTER ?
1175 TRUE : FALSE, channel,
1176 server->id, SILC_ID_SERVER,
1183 case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
1185 * Remove the server entry and all clients that this server owns.
1188 SILC_LOG_DEBUG(("SERVER SIGNOFF notify"));
1190 /* Backup router shouldn't accept SERVER_SIGNOFF's from normal routers
1191 when the backup isn't acting as primary router. */
1192 if (idata->conn_type == SILC_CONN_SERVER &&
1193 server->backup_router && server->server_type == SILC_BACKUP_ROUTER)
1197 if (!silc_argument_get_decoded(args, 1, SILC_ARGUMENT_ID, &id, NULL))
1200 /* If the ID is mine, this notify is not allowed. */
1201 if (SILC_ID_SERVER_COMPARE(SILC_ID_GET_ID(id), server->id)) {
1202 SILC_LOG_DEBUG(("Ignoring my own ID for SERVER_SIGNOFF"));
1206 /* Get server entry */
1207 server_entry = silc_idlist_find_server_by_id(server->global_list,
1211 if (!server_entry) {
1212 server_entry = silc_idlist_find_server_by_id(server->local_list,
1216 if (!server_entry) {
1217 /* If we are normal server then we might not have the server. Check
1218 whether router was kind enough to send the list of all clients
1219 that actually was to be removed. Remove them if the list is
1221 if (server->server_type != SILC_ROUTER &&
1222 silc_argument_get_arg_num(args) > 1) {
1225 for (i = 1; i < silc_argument_get_arg_num(args); i++) {
1227 if (!silc_argument_get_decoded(args, i + 1, SILC_ARGUMENT_ID,
1231 /* Get client entry */
1232 client = silc_idlist_find_client_by_id(server->global_list,
1233 SILC_ID_GET_ID(id2),
1237 client = silc_idlist_find_client_by_id(server->local_list,
1238 SILC_ID_GET_ID(id2),
1245 /* Update statistics */
1246 server->stat.clients--;
1247 if (server->stat.cell_clients)
1248 server->stat.cell_clients--;
1249 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
1250 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
1252 /* Remove the client from all channels. */
1253 silc_server_remove_from_channels(server, NULL, client,
1254 TRUE, NULL, FALSE, FALSE);
1256 /* Check if anyone is watching this nickname */
1257 if (server->server_type == SILC_ROUTER)
1258 silc_server_check_watcher_list(server, client, NULL,
1259 SILC_NOTIFY_TYPE_SERVER_SIGNOFF);
1261 /* Remove this client from watcher list if it is */
1263 silc_server_del_from_watcher_list(server, client);
1265 /* Remove the client */
1266 silc_idlist_del_data(client);
1267 silc_idlist_del_client(local ? server->local_list :
1268 server->global_list, client);
1276 /* For local entrys SERVER_SIGNOFF is processed only on backup router.
1277 It is possible that router sends server signoff for a server. If
1278 backup router has it as local connection it will be closed. */
1279 if (SILC_IS_LOCAL(server_entry)) {
1280 if (server->server_type == SILC_BACKUP_ROUTER) {
1281 sock = server_entry->connection;
1282 SILC_LOG_DEBUG(("Closing connection after SERVER_SIGNOFF"));
1283 silc_server_free_sock_user_data(server, sock, NULL);
1284 silc_server_close_connection(server, sock);
1290 /* Remove all servers that are originated from this server, and
1291 remove the clients of those servers too. */
1292 silc_server_remove_servers_by_server(server, server_entry, TRUE);
1294 /* Remove the clients that this server owns as they will become
1296 silc_server_remove_clients_by_server(server, server_entry->router,
1297 server_entry, TRUE);
1298 silc_server_backup_del(server, server_entry);
1300 /* Remove the server entry */
1301 silc_idlist_del_server(local ? server->local_list :
1302 server->global_list, server_entry);
1304 /* Update statistics */
1305 if (server->server_type == SILC_ROUTER)
1306 server->stat.servers--;
1310 case SILC_NOTIFY_TYPE_KICKED:
1312 * Distribute the notify to local clients on the channel
1315 SILC_LOG_DEBUG(("KICKED notify"));
1317 if (!silc_id_str2id(packet->dst_id, packet->dst_id_len,
1318 packet->dst_id_type, &channel_id,
1319 sizeof(channel_id)))
1322 /* Get channel entry */
1323 channel = silc_idlist_find_channel_by_id(server->global_list,
1326 channel = silc_idlist_find_channel_by_id(server->local_list,
1329 SILC_LOG_DEBUG(("Notify for unknown channel %s",
1330 silc_id_render(SILC_ID_GET_ID(id), SILC_ID_CHANNEL)));
1336 if (!silc_argument_get_decoded(args, 1, SILC_ARGUMENT_ID, &id, NULL))
1339 /* If the the client is not in local list we check global list */
1340 client = silc_idlist_find_client_by_id(server->global_list,
1341 SILC_ID_GET_ID(id), TRUE, NULL);
1343 client = silc_idlist_find_client_by_id(server->local_list,
1344 SILC_ID_GET_ID(id), TRUE, NULL);
1349 /* If target is founder they cannot be kicked */
1350 if (!silc_server_client_on_channel(client, channel, &chl))
1352 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO)
1355 /* Get the kicker's Client ID */
1356 if (!silc_argument_get_decoded(args, 3, SILC_ARGUMENT_ID, &id, NULL))
1359 /* If the the client is not in local list we check global list */
1360 client2 = silc_idlist_find_client_by_id(server->global_list,
1361 SILC_ID_GET_ID(id), TRUE, NULL);
1363 client2 = silc_idlist_find_client_by_id(server->local_list,
1364 SILC_ID_GET_ID(id), TRUE, NULL);
1369 /* Kicker must be operator on channel */
1370 if (!silc_server_client_on_channel(client2, channel, &chl))
1372 if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
1373 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1374 SILC_LOG_DEBUG(("Kicking is not allowed"));
1378 /* Send to channel */
1379 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
1380 FALSE, TRUE, buffer->data,
1381 silc_buffer_len(buffer));
1383 /* Remove the client from channel's invite list */
1384 if (channel->invite_list && silc_hash_table_count(channel->invite_list)) {
1386 SilcArgumentPayload iargs;
1387 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1388 ab = silc_argument_payload_encode_one(NULL, tmp, tmp_len, 3);
1389 iargs = silc_argument_payload_parse(ab->data, silc_buffer_len(ab), 1);
1390 silc_server_inviteban_process(server, channel->invite_list, 1, iargs);
1391 silc_buffer_free(ab);
1392 silc_argument_payload_free(iargs);
1395 /* Remove the client from channel */
1396 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
1400 case SILC_NOTIFY_TYPE_KILLED:
1403 * Distribute the notify to local clients on channels
1405 unsigned char *comment;
1406 SilcUInt32 comment_len;
1408 SILC_LOG_DEBUG(("KILLED notify"));
1411 if (!silc_argument_get_decoded(args, 1, SILC_ARGUMENT_ID, &id, NULL))
1414 /* If the the client is not in local list we check global list */
1415 client = silc_idlist_find_client_by_id(server->global_list,
1416 SILC_ID_GET_ID(id), TRUE, &cache);
1418 client = silc_idlist_find_client_by_id(server->local_list,
1425 /* If the client is one of ours, then close the connection to the
1426 client now. This removes the client from all channels as well. */
1427 if (packet->dst_id_type == SILC_ID_CLIENT && client->connection) {
1428 sock = client->connection;
1429 silc_server_free_client_data(server, NULL, client, FALSE, NULL);
1430 silc_server_close_connection(server, sock);
1435 comment = silc_argument_get_arg_type(args, 2, &comment_len);
1436 if (comment_len > 128)
1439 /* Get the killer's Client ID */
1440 if (!silc_argument_get_decoded(args, 3, SILC_ARGUMENT_ID, &id, NULL))
1443 if (id.type == SILC_ID_CLIENT) {
1444 /* If the the client is not in local list we check global list */
1445 client2 = silc_idlist_find_client_by_id(server->global_list,
1449 client2 = silc_idlist_find_client_by_id(server->local_list,
1456 /* Killer must be router operator */
1457 if (server->server_type != SILC_SERVER &&
1458 !(client2->mode & SILC_UMODE_ROUTER_OPERATOR)) {
1459 SILC_LOG_DEBUG(("Killing is not allowed"));
1464 /* Send the notify to local clients on the channels except to the
1465 client who is killed. */
1466 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1467 tmp2 = silc_argument_get_arg_type(args, 3, &tmp2_len);
1468 silc_server_send_notify_on_channels(server, client, client,
1469 SILC_NOTIFY_TYPE_KILLED, 3,
1470 tmp, tmp_len, comment, comment_len,
1473 /* Remove the client from all channels */
1474 silc_server_remove_from_channels(server, NULL, client, FALSE, NULL,
1477 /* Check if anyone is watching this nickname */
1478 if (server->server_type == SILC_ROUTER)
1479 silc_server_check_watcher_list(server, client, NULL,
1480 SILC_NOTIFY_TYPE_KILLED);
1482 /* Remove client's public key from repository, this will free it too. */
1483 if (client->data.public_key) {
1484 silc_skr_del_public_key(server->repository, client->data.public_key,
1486 client->data.public_key = NULL;
1489 /* Update statistics */
1490 server->stat.clients--;
1491 if (server->stat.cell_clients)
1492 server->stat.cell_clients--;
1493 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
1494 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
1496 if (SILC_IS_LOCAL(client)) {
1497 server->stat.my_clients--;
1498 silc_schedule_task_del_by_context(server->schedule, client);
1499 silc_idlist_del_data(client);
1503 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
1505 client->router = NULL;
1506 client->connection = NULL;
1507 silc_dlist_add(server->expired_clients, client);
1511 case SILC_NOTIFY_TYPE_UMODE_CHANGE:
1513 * Save the mode of the client.
1516 SILC_LOG_DEBUG(("UMODE_CHANGE notify"));
1519 if (!silc_argument_get_decoded(args, 1, SILC_ARGUMENT_ID, &id, NULL))
1522 /* Get client entry */
1523 client = silc_idlist_find_client_by_id(server->global_list,
1524 SILC_ID_GET_ID(id), TRUE, NULL);
1526 client = silc_idlist_find_client_by_id(server->local_list,
1527 SILC_ID_GET_ID(id), TRUE, NULL);
1533 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1536 SILC_GET32_MSB(mode, tmp);
1538 /* Remove internal resumed flag if client is marked detached now */
1539 if (mode & SILC_UMODE_DETACHED)
1540 client->data.status &= ~SILC_IDLIST_STATUS_RESUMED;
1542 /* Update statistics */
1543 if (server->server_type == SILC_ROUTER) {
1544 if (mode & SILC_UMODE_GONE) {
1545 if (!(client->mode & SILC_UMODE_GONE))
1546 server->stat.aways++;
1548 if (client->mode & SILC_UMODE_GONE)
1549 server->stat.aways--;
1551 if (mode & SILC_UMODE_DETACHED) {
1552 if (!(client->mode & SILC_UMODE_DETACHED))
1553 server->stat.detached++;
1555 if (client->mode & SILC_UMODE_DETACHED)
1556 server->stat.detached--;
1559 SILC_UMODE_STATS_UPDATE(server, SILC_UMODE_SERVER_OPERATOR);
1560 SILC_UMODE_STATS_UPDATE(router, SILC_UMODE_ROUTER_OPERATOR);
1562 /* Change the mode */
1563 client->mode = mode;
1565 /* Check if anyone is watching this nickname */
1566 if (server->server_type == SILC_ROUTER)
1567 silc_server_check_watcher_list(server, client, NULL,
1568 SILC_NOTIFY_TYPE_UMODE_CHANGE);
1572 case SILC_NOTIFY_TYPE_BAN:
1577 SILC_LOG_DEBUG(("BAN notify"));
1579 /* Get Channel ID */
1580 if (!silc_argument_get_decoded(args, 1, SILC_ARGUMENT_ID, &id, NULL))
1583 /* Get channel entry */
1584 channel = silc_idlist_find_channel_by_id(server->global_list,
1585 SILC_ID_GET_ID(id), NULL);
1587 channel = silc_idlist_find_channel_by_id(server->local_list,
1588 SILC_ID_GET_ID(id), NULL);
1590 SILC_LOG_DEBUG(("Notify for unknown channel %s",
1591 silc_id_render(SILC_ID_GET_ID(id), SILC_ID_CHANNEL)));
1596 /* Get the ban action */
1597 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1598 if (tmp && tmp_len == 1) {
1599 SilcUInt8 action = (SilcUInt8)tmp[0];
1600 SilcUInt16 iargc = 0;
1601 SilcArgumentPayload iargs;
1604 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1605 if (!tmp || tmp_len < 2)
1608 /* Parse the arguments to see they are constructed correctly */
1609 SILC_GET16_MSB(iargc, tmp);
1610 iargs = silc_argument_payload_parse(tmp + 2, tmp_len - 2, iargc);
1614 if (!channel->ban_list)
1616 silc_hash_table_alloc(0, silc_hash_ptr,
1618 silc_server_inviteban_destruct, channel, TRUE);
1620 /* Proces the ban action */
1621 if (!silc_server_inviteban_process(server, channel->ban_list, action,
1624 silc_argument_payload_free(iargs);
1626 /* If we are router we must send this notify to our local servers on
1627 the channel. Normal server does nothing. The notify is not
1629 if (server->server_type == SILC_ROUTER)
1630 silc_server_packet_send_to_channel(server, sock, channel,
1631 packet->type, FALSE, FALSE,
1633 silc_buffer_len(buffer));
1637 case SILC_NOTIFY_TYPE_ERROR:
1644 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1645 if (!tmp && tmp_len != 1)
1647 error = (SilcStatus)tmp[0];
1649 SILC_LOG_DEBUG(("ERROR notify (%d)", error));
1651 if (error == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID &&
1652 idata->conn_type == SILC_CONN_ROUTER) {
1653 if (!silc_argument_get_decoded(args, 2, SILC_ARGUMENT_ID, &id, NULL))
1656 SILC_LOG_DEBUG(("Received invalid client ID notification, deleting "
1657 "the entry from cache"));
1659 client = silc_idlist_find_client_by_id(server->global_list,
1665 silc_server_remove_from_channels(server, NULL, client, TRUE,
1667 silc_idlist_del_data(client);
1668 silc_idlist_del_client(server->global_list, client);
1673 /* Ignore rest of the notify types for now */
1674 case SILC_NOTIFY_TYPE_NONE:
1675 case SILC_NOTIFY_TYPE_MOTD:
1679 SILC_LOG_DEBUG(("Unsupported notify %d", type));
1684 silc_notify_payload_free(payload);
1687 void silc_server_notify(SilcServer server,
1688 SilcPacketStream sock,
1691 silc_server_notify_process(server, sock, packet, &packet->buffer);
1692 silc_packet_free(packet);
1695 void silc_server_notify_list(SilcServer server,
1696 SilcPacketStream sock,
1699 SilcIDListData idata = silc_packet_get_context(sock);
1703 SILC_LOG_DEBUG(("Processing Notify List"));
1705 if (idata->conn_type == SILC_CONN_CLIENT ||
1706 packet->src_id_type != SILC_ID_SERVER)
1709 buffer = silc_buffer_alloc(1024);
1713 while (silc_buffer_len(&packet->buffer)) {
1714 SILC_GET16_MSB(len, packet->buffer.data + 2);
1715 if (len > silc_buffer_len(&packet->buffer))
1718 if (len > silc_buffer_truelen(buffer)) {
1719 silc_buffer_free(buffer);
1720 buffer = silc_buffer_alloc(1024 + len);
1723 silc_buffer_pull_tail(buffer, len);
1724 silc_buffer_put(buffer, packet->buffer.data, len);
1726 /* Process the Notify */
1727 silc_server_notify_process(server, sock, packet, buffer);
1729 silc_buffer_push_tail(buffer, len);
1730 silc_buffer_pull(&packet->buffer, len);
1733 silc_packet_free(packet);
1734 silc_buffer_free(buffer);
1737 /* Received private message. This resolves the destination of the message
1738 and sends the packet. This is used by both server and router. If the
1739 destination is our locally connected client this sends the packet to
1740 the client. This may also send the message for further routing if
1741 the destination is not in our server (or router). */
1743 void silc_server_private_message(SilcServer server,
1744 SilcPacketStream sock,
1747 SilcPacketStream dst_sock;
1748 SilcIDListData idata;
1749 SilcClientEntry client;
1750 SilcClientID client_id;
1752 SILC_LOG_DEBUG(("Start"));
1754 if (packet->src_id_type != SILC_ID_CLIENT ||
1755 packet->dst_id_type != SILC_ID_CLIENT || !packet->dst_id)
1758 /* Get the route to the client */
1759 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1760 packet->dst_id_len, NULL,
1764 unsigned char error;
1766 if (client && client->mode & SILC_UMODE_DETACHED) {
1767 SILC_LOG_DEBUG(("Client is detached, discarding packet"));
1771 /* Send SILC_NOTIFY_TYPE_ERROR to indicate that such destination ID
1772 does not exist or is invalid. */
1773 idp = silc_id_payload_encode_data(packet->dst_id,
1775 packet->dst_id_type);
1779 error = SILC_STATUS_ERR_NO_SUCH_CLIENT_ID;
1780 if (packet->src_id_type == SILC_ID_CLIENT) {
1781 silc_id_str2id(packet->src_id, packet->src_id_len,
1782 packet->src_id_type, &client_id, sizeof(client_id));
1783 silc_server_send_notify_dest(server, sock, FALSE,
1784 &client_id, SILC_ID_CLIENT,
1785 SILC_NOTIFY_TYPE_ERROR, 2,
1787 idp->data, silc_buffer_len(idp));
1789 silc_server_send_notify(server, sock, FALSE,
1790 SILC_NOTIFY_TYPE_ERROR, 2,
1792 idp->data, silc_buffer_len(idp));
1795 silc_buffer_free(idp);
1799 /* Check whether destination client wishes to receive private messages */
1800 if (client && !(packet->flags & SILC_PACKET_FLAG_PRIVMSG_KEY) &&
1801 client->mode & SILC_UMODE_BLOCK_PRIVMSG) {
1802 SILC_LOG_DEBUG(("Client blocks private messages, discarding packet"));
1806 /* Send the private message */
1807 silc_server_packet_route(server, dst_sock, packet);
1810 silc_packet_free(packet);
1813 /* Received private message key packet.. This packet is never for us. It is to
1814 the client in the packet's destination ID. Sending of this sort of packet
1815 equals sending private message, ie. it is sent point to point from
1816 one client to another. */
1818 void silc_server_private_message_key(SilcServer server,
1819 SilcPacketStream sock,
1822 SilcPacketStream dst_sock;
1823 SilcIDListData idata;
1825 SILC_LOG_DEBUG(("Start"));
1827 if (packet->src_id_type != SILC_ID_CLIENT ||
1828 packet->dst_id_type != SILC_ID_CLIENT || !packet->dst_id) {
1829 silc_packet_free(packet);
1833 /* Get the route to the client */
1834 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1835 packet->dst_id_len, NULL,
1838 silc_packet_free(packet);
1842 /* Relay the packet */
1843 silc_server_packet_route(server, dst_sock, packet);
1845 silc_packet_free(packet);
1848 /* Processes incoming command reply packet. The command reply packet may
1849 be destined to one of our clients or it may directly for us. We will
1850 call the command reply routine after processing the packet. */
1852 void silc_server_command_reply(SilcServer server,
1853 SilcPacketStream sock,
1856 SilcBuffer buffer = &packet->buffer;
1857 SilcClientEntry client = NULL;
1860 SILC_LOG_DEBUG(("Start"));
1862 if (packet->dst_id_type == SILC_ID_CHANNEL) {
1863 silc_packet_free(packet);
1867 if (packet->dst_id_type == SILC_ID_CLIENT) {
1868 /* Destination must be one of ours */
1869 if (!silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT,
1871 silc_packet_free(packet);
1874 client = silc_idlist_find_client_by_id(server->local_list, &id,
1877 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
1878 silc_packet_free(packet);
1883 if (packet->dst_id_type == SILC_ID_SERVER) {
1884 /* For now this must be for us */
1885 if (memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
1886 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
1887 silc_packet_free(packet);
1892 /* Execute command reply locally for the command */
1893 silc_server_command_reply_process(server, sock, buffer);
1895 /* Relay the packet to the client */
1896 if (packet->dst_id_type == SILC_ID_CLIENT && client)
1897 silc_server_packet_route(server, client->connection, packet);
1899 silc_packet_free(packet);
1902 /* Process received channel message. The message can be originated from
1903 client or server. */
1905 void silc_server_channel_message(SilcServer server,
1906 SilcPacketStream sock,
1909 SilcChannelEntry channel = NULL;
1913 SilcClientEntry sender_entry = NULL;
1914 SilcIDListData idata;
1915 SilcChannelClientEntry chl;
1916 SilcBool local = TRUE;
1918 SILC_LOG_DEBUG(("Processing channel message"));
1921 if (packet->dst_id_type != SILC_ID_CHANNEL) {
1922 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1926 /* Find channel entry */
1927 if (!silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL,
1930 channel = silc_idlist_find_channel_by_id(server->local_list, &id, NULL);
1932 channel = silc_idlist_find_channel_by_id(server->global_list, &id, NULL);
1935 unsigned char error;
1937 /* Send SILC_NOTIFY_TYPE_ERROR to indicate that such destination ID
1938 does not exist or is invalid. */
1939 idp = silc_id_payload_encode_data(packet->dst_id,
1941 packet->dst_id_type);
1945 error = SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID;
1946 if (packet->src_id_type == SILC_ID_CLIENT) {
1947 silc_id_str2id(packet->src_id, packet->src_id_len,
1948 packet->src_id_type, &cid, sizeof(cid));
1949 silc_server_send_notify_dest(server, sock, FALSE,
1950 &cid, SILC_ID_CLIENT,
1951 SILC_NOTIFY_TYPE_ERROR, 2,
1952 &error, 1, idp->data,
1953 silc_buffer_len(idp));
1955 silc_server_send_notify(server, sock, FALSE,
1956 SILC_NOTIFY_TYPE_ERROR, 2,
1957 &error, 1, idp->data, silc_buffer_len(idp));
1960 silc_buffer_free(idp);
1965 /* See that this client is on the channel. If the original sender is
1966 not client (as it can be server as well) we don't do the check. */
1967 if (!silc_id_str2id2(packet->src_id, packet->src_id_len,
1968 packet->src_id_type, &sid))
1970 if (sid.type == SILC_ID_CLIENT) {
1971 sender_entry = silc_idlist_find_client_by_id(server->local_list,
1972 SILC_ID_GET_ID(sid),
1974 if (!sender_entry) {
1976 sender_entry = silc_idlist_find_client_by_id(server->global_list,
1977 SILC_ID_GET_ID(sid),
1980 if (!sender_entry || !silc_server_client_on_channel(sender_entry,
1982 SILC_LOG_DEBUG(("Client not on channel"));
1986 /* If channel is moderated check that client is allowed to send
1988 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS &&
1989 !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
1990 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1991 SILC_LOG_DEBUG(("Channel is silenced from normal users"));
1994 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS &&
1995 chl->mode & SILC_CHANNEL_UMODE_CHANOP &&
1996 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1997 SILC_LOG_DEBUG(("Channel is silenced from operators"));
2000 if (chl->mode & SILC_CHANNEL_UMODE_QUIET) {
2001 SILC_LOG_DEBUG(("Sender is quieted on the channel"));
2005 /* If the packet is coming from router, but the client entry is local
2006 entry to us then some router is rerouting this to us and it is not
2007 allowed. When the client is local to us it means that we've routed
2008 this packet to network, and now someone is routing it back to us. */
2009 idata = silc_packet_get_context(sock);
2010 if (server->server_type == SILC_ROUTER &&
2011 idata->conn_type == SILC_CONN_ROUTER && local) {
2012 SILC_LOG_DEBUG(("Channel message rerouted to the sender, drop it"));
2017 /* Distribute the packet to our local clients. This will send the
2018 packet for further routing as well, if needed. */
2019 silc_server_packet_relay_to_channel(server, sock, channel,
2020 SILC_ID_GET_ID(sid), sid.type,
2021 sender_entry, packet->buffer.data,
2022 silc_buffer_len(&packet->buffer));
2025 silc_packet_free(packet);
2028 /* Received channel key packet. We distribute the key to all of our locally
2029 connected clients on the channel. */
2031 void silc_server_channel_key(SilcServer server,
2032 SilcPacketStream sock,
2035 SilcBuffer buffer = &packet->buffer;
2036 SilcIDListData idata = silc_packet_get_context(sock);
2037 SilcChannelEntry channel;
2039 if (packet->src_id_type != SILC_ID_SERVER ||
2040 (server->server_type == SILC_ROUTER && !server->backup_router &&
2041 idata->conn_type == SILC_CONN_ROUTER)) {
2042 silc_packet_free(packet);
2046 /* Save the channel key */
2047 channel = silc_server_save_channel_key(server, buffer, NULL);
2049 SILC_LOG_ERROR(("Bad channel key from %s", idata->sconn->remote_host));
2050 silc_packet_free(packet);
2054 /* Distribute the key to everybody who is on the channel. If we are router
2055 we will also send it to locally connected servers. */
2056 silc_server_send_channel_key(server, sock, channel, FALSE);
2058 if (server->server_type != SILC_BACKUP_ROUTER)
2059 /* Distribute to local cell backup routers. */
2060 silc_server_backup_send(server, (SilcServerEntry)idata,
2061 SILC_PACKET_CHANNEL_KEY, 0,
2062 buffer->data, silc_buffer_len(buffer),
2065 silc_packet_free(packet);
2068 /* Received New Client packet and processes it. Creates Client ID for the
2069 client. Client becomes registered after calling this functions. */
2071 SilcClientEntry silc_server_new_client(SilcServer server,
2072 SilcPacketStream sock,
2075 SilcBuffer buffer = &packet->buffer;
2076 SilcIDListData idata = silc_packet_get_context(sock);
2077 SilcClientEntry client;
2078 SilcClientID *client_id;
2079 char *username = NULL, *realname = NULL;
2080 SilcUInt16 username_len, nickname_len;
2081 SilcUInt32 id_len, tmp_len;
2083 char *host, *nickname = NULL, *nicknamec;
2084 const char *hostname, *ip;
2086 SILC_LOG_DEBUG(("Creating new client"));
2088 if (idata->conn_type != SILC_CONN_CLIENT) {
2089 silc_packet_free(packet);
2093 /* Take client entry */
2094 client = (SilcClientEntry)idata;
2095 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
2096 NULL, &hostname, &ip, NULL);
2098 SILC_LOG_DEBUG(("%s %s", ip, hostname));
2100 /* Make sure this client hasn't registered already */
2101 if (idata->status & SILC_IDLIST_STATUS_REGISTERED) {
2102 silc_packet_free(packet);
2106 /* Parse incoming packet */
2107 ret = silc_buffer_unformat(buffer,
2109 SILC_STR_UI16_NSTRING_ALLOC(&username,
2111 SILC_STR_UI16_STRING_ALLOC(&realname),
2114 silc_free(username);
2115 silc_free(realname);
2116 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2117 "connection", hostname, ip));
2118 silc_server_disconnect_remote(server, sock,
2119 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2121 silc_server_free_sock_user_data(server, sock, NULL);
2122 silc_packet_free(packet);
2127 silc_free(username);
2128 silc_free(realname);
2129 SILC_LOG_ERROR(("Client %s (%s) did not send its username, closing "
2130 "connection", hostname, ip));
2131 silc_server_disconnect_remote(server, sock,
2132 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2134 silc_server_free_sock_user_data(server, sock, NULL);
2135 silc_packet_free(packet);
2139 if (username_len > 128) {
2141 username[username_len - 1] = '\0';
2144 /* Take nickname from NEW_CLIENT packet, if present */
2145 if (silc_buffer_unformat(buffer,
2146 SILC_STR_UI16_NSTRING_ALLOC(&nickname,
2149 if (nickname_len > 128) {
2151 nickname[nickname_len - 1] = '\0';
2155 /* Nickname is initially same as username, if not present in NEW_CLIENT */
2157 nickname = strdup(username);
2158 nickname_len = strlen(nickname);
2161 /* Check for valid username string */
2162 nicknamec = silc_identifier_check(nickname, nickname_len,
2163 SILC_STRING_UTF8, 128, &tmp_len);
2165 silc_free(username);
2166 silc_free(realname);
2167 silc_free(nickname);
2168 SILC_LOG_ERROR(("Client %s (%s) sent bad username string '%s', closing "
2169 "connection", hostname, ip, username));
2170 silc_server_disconnect_remote(server, sock,
2171 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2173 silc_server_free_sock_user_data(server, sock, NULL);
2174 silc_packet_free(packet);
2178 /* Make sanity checks for the hostname of the client. If the hostname
2179 is provided in the `username' check that it is the same than the
2180 resolved hostname, or if not resolved the hostname that appears in
2181 the client's public key. If the hostname is not present then put
2182 it from the resolved name or from the public key. */
2183 if (strchr(username, '@')) {
2184 SilcSILCPublicKey silc_pubkey;
2185 int tlen = strcspn(username, "@");
2186 char *phostname = NULL;
2188 host = silc_memdup(username + tlen + 1, strlen(username) - tlen - 1);
2190 if (strcmp(hostname, ip) && strcmp(hostname, host)) {
2191 silc_free(nickname);
2192 silc_free(username);
2194 silc_free(realname);
2195 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2196 "connection", hostname, ip));
2197 silc_server_disconnect_remote(server, sock,
2198 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2200 silc_server_free_sock_user_data(server, sock, NULL);
2201 silc_packet_free(packet);
2205 silc_pubkey = silc_pkcs_get_context(SILC_PKCS_SILC,
2206 client->data.public_key);
2207 phostname = strdup(silc_pubkey->identifier.host);
2208 if (!strcmp(hostname, ip) && phostname && strcmp(phostname, host)) {
2209 silc_free(nickname);
2210 silc_free(username);
2212 silc_free(phostname);
2213 silc_free(realname);
2214 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
2215 "connection", hostname, ip));
2216 silc_server_disconnect_remote(server, sock,
2217 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2219 silc_server_free_sock_user_data(server, sock, NULL);
2220 silc_packet_free(packet);
2224 silc_free(phostname);
2226 /* The hostname is not present, add it. */
2228 newusername = silc_calloc(strlen(username) + strlen(hostname) + 2,
2229 sizeof(*newusername));
2230 strncat(newusername, username, strlen(username));
2231 strncat(newusername, "@", 1);
2232 strncat(newusername, hostname, strlen(hostname));
2233 silc_free(username);
2234 username = newusername;
2237 SILC_LOG_DEBUG(("%s %s", ip, hostname));
2239 /* Create Client ID */
2240 if (!silc_id_create_client_id(server, server->id, server->rng,
2241 server->md5hash, nicknamec,
2242 strlen(nicknamec), &client_id)) {
2243 silc_server_disconnect_remote(server, sock,
2244 SILC_STATUS_ERR_BAD_NICKNAME, NULL);
2245 silc_server_free_sock_user_data(server, sock, NULL);
2246 silc_packet_free(packet);
2250 /* If client marked as anonymous, scramble the username and hostname */
2251 if (client->mode & SILC_UMODE_ANONYMOUS) {
2254 if (strlen(username) >= 2) {
2255 username[0] = silc_rng_get_byte_fast(server->rng);
2256 username[1] = silc_rng_get_byte_fast(server->rng);
2259 scramble = silc_hash_babbleprint(server->sha1hash, username,
2263 memcpy(&scramble[16], ".silc", 5);
2264 scramble[21] = '\0';
2265 silc_free(username);
2266 username = scramble;
2269 /* Update client entry */
2270 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
2271 client->nickname = nickname;
2272 client->username = username;
2273 client->userinfo = realname ? realname : strdup(username);
2274 client->id = client_id;
2275 id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
2276 silc_idcache_update_by_context(server->local_list->clients, client,
2277 client_id, nicknamec, TRUE);
2279 /* Notify our router about new client on the SILC network */
2280 silc_server_send_new_id(server, SILC_PRIMARY_ROUTE(server),
2281 SILC_BROADCAST(server), client->id,
2282 SILC_ID_CLIENT, id_len);
2284 /* Distribute to backup routers */
2285 if (server->server_type == SILC_ROUTER) {
2286 SilcBuffer idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
2287 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_ID, 0,
2288 idp->data, silc_buffer_len(idp), FALSE, TRUE);
2289 silc_buffer_free(idp);
2292 /* Send the new client ID to the client. */
2293 silc_server_send_new_id(server, sock, FALSE, client->id, SILC_ID_CLIENT,
2294 silc_id_get_len(client->id, SILC_ID_CLIENT));
2296 /* Send some nice info to the client */
2297 silc_server_send_connect_notifys(server, sock, client);
2299 /* Check if anyone is watching this nickname */
2300 if (server->server_type == SILC_ROUTER)
2301 silc_server_check_watcher_list(server, client, NULL, 0);
2303 silc_packet_free(packet);
2307 /* Create new server. This processes received New Server packet and
2308 saves the received Server ID. The server is our locally connected
2309 server thus we save all the information and save it to local list.
2310 This funtion can be used by both normal server and router server.
2311 If normal server uses this it means that its router has connected
2312 to the server. If router uses this it means that one of the cell's
2313 servers is connected to the router. */
2315 SilcServerEntry silc_server_new_server(SilcServer server,
2316 SilcPacketStream sock,
2319 SilcBuffer buffer = &packet->buffer;
2320 SilcIDListData idata = silc_packet_get_context(sock);
2321 SilcServerEntry new_server, server_entry;
2322 SilcServerID server_id;
2323 unsigned char *server_name, *server_namec, *id_string;
2324 SilcUInt16 id_len, name_len;
2326 SilcBool local = TRUE;
2327 const char *hostname, *ip;
2329 SILC_LOG_DEBUG(("Creating new server"));
2331 if (idata->conn_type != SILC_CONN_SERVER &&
2332 idata->conn_type != SILC_CONN_ROUTER) {
2333 silc_packet_free(packet);
2337 /* Take server entry */
2338 new_server = (SilcServerEntry)idata;
2339 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
2340 NULL, &hostname, &ip, NULL);
2343 if (server->server_type == SILC_ROUTER)
2344 server->stat.cell_servers++;
2346 /* Remove the old cache entry */
2347 if (!silc_idcache_del_by_context(server->local_list->servers, new_server,
2349 if (!silc_idcache_del_by_context(server->global_list->servers,
2350 new_server, NULL)) {
2351 SILC_LOG_INFO(("Unauthenticated %s attempted to register to "
2352 "network", (idata->conn_type == SILC_CONN_SERVER ?
2353 "server" : "router")));
2354 silc_server_disconnect_remote(server, sock,
2355 SILC_STATUS_ERR_NOT_AUTHENTICATED, NULL);
2356 silc_server_free_sock_user_data(server, sock, NULL);
2362 /* Make sure this server hasn't registered already */
2363 if (idata->status & SILC_IDLIST_STATUS_REGISTERED) {
2364 silc_server_disconnect_remote(server, sock,
2365 SILC_STATUS_ERR_OPERATION_ALLOWED,
2366 "Too many registrations");
2367 silc_server_free_sock_user_data(server, sock, NULL);
2371 /* Parse the incoming packet */
2372 ret = silc_buffer_unformat(buffer,
2373 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
2374 SILC_STR_UI16_NSTRING_ALLOC(&server_name,
2378 silc_free(id_string);
2379 silc_free(server_name);
2380 silc_server_disconnect_remote(server, sock,
2381 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2383 silc_server_free_sock_user_data(server, sock, NULL);
2387 if (id_len > silc_buffer_len(buffer)) {
2388 silc_free(id_string);
2389 silc_free(server_name);
2390 silc_server_disconnect_remote(server, sock,
2391 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2393 silc_server_free_sock_user_data(server, sock, NULL);
2397 if (name_len > 256) {
2398 server_name[256] = '\0';
2403 if (!silc_id_str2id(id_string, id_len, SILC_ID_SERVER, &server_id,
2404 sizeof(server_id))) {
2405 silc_free(id_string);
2406 silc_free(server_name);
2407 silc_server_disconnect_remote(server, sock,
2408 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
2410 silc_server_free_sock_user_data(server, sock, NULL);
2413 silc_free(id_string);
2415 /* Check for valid server ID */
2416 if (!silc_id_is_valid_server_id(server, &server_id, sock)) {
2417 SILC_LOG_INFO(("Invalid server ID sent by %s (%s)",
2419 silc_server_disconnect_remote(server, sock,
2420 SILC_STATUS_ERR_BAD_SERVER_ID, NULL);
2421 silc_server_free_sock_user_data(server, sock, NULL);
2422 silc_free(server_name);
2426 /* Check that we do not have this ID already */
2427 server_entry = silc_idlist_find_server_by_id(server->local_list,
2428 &server_id, TRUE, NULL);
2430 if (SILC_IS_LOCAL(server_entry)) {
2431 SILC_LOG_ERROR(("Too many registrations from %s (%s)",
2433 silc_server_disconnect_remote(server, sock,
2434 SILC_STATUS_ERR_OPERATION_ALLOWED,
2435 "Too many registrations");
2436 silc_server_free_sock_user_data(server, sock, NULL);
2439 silc_idcache_del_by_context(server->local_list->servers, server_entry,
2443 server_entry = silc_idlist_find_server_by_id(server->global_list,
2444 &server_id, TRUE, NULL);
2446 if (SILC_IS_LOCAL(server_entry)) {
2447 SILC_LOG_ERROR(("Too many registrations from %s (%s)",
2449 silc_server_disconnect_remote(server, sock,
2450 SILC_STATUS_ERR_OPERATION_ALLOWED,
2451 "Too many registrations");
2452 silc_server_free_sock_user_data(server, sock, NULL);
2455 silc_idcache_del_by_context(server->global_list->servers,
2456 server_entry, NULL);
2461 /* Check server name */
2462 server_namec = silc_identifier_check(server_name, strlen(server_name),
2463 SILC_STRING_UTF8, 256, NULL);
2464 if (!server_namec) {
2465 SILC_LOG_ERROR(("Malformed server name from %s (%s)",
2467 silc_server_disconnect_remote(server, sock,
2468 SILC_STATUS_ERR_OPERATION_ALLOWED,
2469 "Malfromed server name");
2470 silc_server_free_sock_user_data(server, sock, NULL);
2474 /* Update server entry */
2475 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
2476 new_server->server_name = server_name;
2477 new_server->id = silc_id_dup(&server_id, SILC_ID_SERVER);
2479 SILC_LOG_DEBUG(("New server id(%s)",
2480 silc_id_render(&server_id, SILC_ID_SERVER)));
2482 /* Add again the entry to the ID cache. */
2483 silc_idcache_add(local ? server->local_list->servers :
2484 server->global_list->servers, server_namec,
2485 new_server->id, new_server);
2487 /* Distribute the information about new server in the SILC network
2488 to our router. If we are normal server we won't send anything
2489 since this connection must be our router connection. */
2490 if (server->server_type == SILC_ROUTER && !server->standalone &&
2491 SILC_PRIMARY_ROUTE(server) != sock)
2492 silc_server_send_new_id(server, SILC_PRIMARY_ROUTE(server),
2493 TRUE, new_server->id, SILC_ID_SERVER,
2494 silc_id_get_len(&server_id, SILC_ID_SERVER));
2496 if (server->server_type == SILC_ROUTER) {
2497 /* Distribute to backup routers */
2498 SilcBuffer idp = silc_id_payload_encode(new_server->id, SILC_ID_SERVER);
2499 silc_server_backup_send(server, NULL, SILC_PACKET_NEW_ID, 0, idp->data,
2500 silc_buffer_len(idp), FALSE, TRUE);
2501 silc_buffer_free(idp);
2504 /* Check whether this router connection has been replaced by an
2505 backup router. If it has been then we'll disable the server and will
2506 ignore everything it will send until the backup router resuming
2507 protocol has been completed. */
2508 if (idata->conn_type == SILC_CONN_ROUTER &&
2509 silc_server_backup_replaced_get(server, &server_id, NULL)) {
2510 /* Send packet to the router indicating that it cannot use this
2511 connection as it has been replaced by backup router. */
2512 SILC_LOG_DEBUG(("Remote router has been replaced by backup router, "
2513 "disabling its connection"));
2515 silc_server_backup_send_replaced(server, sock);
2517 /* Mark the router disabled. The data sent earlier will go but nothing
2518 after this goes to this connection. */
2519 idata->status |= SILC_IDLIST_STATUS_DISABLED;
2521 /* If it is router announce our stuff to it. */
2522 if (idata->conn_type == SILC_CONN_ROUTER &&
2523 server->server_type == SILC_ROUTER) {
2524 silc_server_announce_servers(server, FALSE, 0, sock);
2525 silc_server_announce_clients(server, 0, sock);
2526 silc_server_announce_channels(server, 0, sock);
2529 /* Announce our information to backup router */
2530 if (new_server->server_type == SILC_BACKUP_ROUTER &&
2531 idata->conn_type == SILC_CONN_SERVER &&
2532 server->server_type == SILC_ROUTER) {
2533 silc_server_announce_servers(server, TRUE, 0, sock);
2534 silc_server_announce_clients(server, 0, sock);
2535 silc_server_announce_channels(server, 0, sock);
2538 /* If backup router, mark it as one of ours. This server is considered
2539 to be backup router after this setting. */
2540 if (new_server->server_type == SILC_BACKUP_ROUTER) {
2541 SilcServerConfigRouter *backup;
2542 backup = silc_server_config_find_backup_conn(server, (char *)ip);
2544 backup = silc_server_config_find_backup_conn(server, (char *)hostname);
2546 /* Add as our backup router */
2547 silc_server_backup_add(server, new_server, backup->backup_replace_ip,
2548 backup->backup_replace_port,
2549 backup->backup_local);
2553 /* By default the servers connected to backup router are disabled
2554 until backup router has become the primary */
2555 if (server->server_type == SILC_BACKUP_ROUTER &&
2556 idata->conn_type == SILC_CONN_SERVER)
2557 idata->status |= SILC_IDLIST_STATUS_DISABLED;
2563 /* Processes incoming New ID packet. New ID Payload is used to distribute
2564 information about newly registered clients and servers. */
2566 static void silc_server_new_id_real(SilcServer server,
2567 SilcPacketStream sock,
2572 SilcIDListData idata = silc_packet_get_context(sock);
2574 SilcServerEntry router, server_entry;
2575 SilcPacketStream router_sock;
2578 SilcServerID sender_id;
2579 const char *hostname, *ip;
2581 SILC_LOG_DEBUG(("Processing new ID"));
2583 if (idata->conn_type == SILC_CONN_CLIENT ||
2584 server->server_type == SILC_SERVER ||
2585 packet->src_id_type != SILC_ID_SERVER)
2588 idp = silc_id_payload_parse(buffer->data, silc_buffer_len(buffer));
2592 id_type = silc_id_payload_get_type(idp);
2594 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
2595 NULL, &hostname, &ip, NULL);
2597 /* Normal server cannot have other normal server connections */
2598 server_entry = (SilcServerEntry)idata;
2599 if (id_type == SILC_ID_SERVER && idata->conn_type == SILC_CONN_SERVER &&
2600 server_entry->server_type == SILC_SERVER)
2603 /* If the packet is coming from server then use the sender as the
2604 origin of the the packet. If it came from router then check the real
2605 sender of the packet and use that as the origin. */
2606 if (idata->conn_type == SILC_CONN_SERVER) {
2607 id_list = server->local_list;
2609 router = server_entry;
2611 /* If the sender is backup router and ID is server (and we are not
2612 backup router) then switch the entry to global list. */
2613 if (server_entry->server_type == SILC_BACKUP_ROUTER &&
2614 id_type == SILC_ID_SERVER &&
2615 server->id_entry->server_type != SILC_BACKUP_ROUTER) {
2616 id_list = server->global_list;
2617 router_sock = server->router ? SILC_PRIMARY_ROUTE(server) : sock;
2620 silc_id_str2id(packet->src_id, packet->src_id_len,
2621 packet->src_id_type, &sender_id, sizeof(sender_id));
2622 router = silc_idlist_find_server_by_id(server->global_list,
2623 &sender_id, TRUE, NULL);
2625 router = silc_idlist_find_server_by_id(server->local_list,
2626 &sender_id, TRUE, NULL);
2628 id_list = server->global_list;
2635 case SILC_ID_CLIENT:
2637 SilcClientEntry entry;
2640 if (!silc_id_payload_get_id(idp, &id, sizeof(id)))
2643 /* Check that we do not have this client already */
2644 entry = silc_idlist_find_client_by_id(server->global_list,
2645 &id, server->server_type,
2648 entry = silc_idlist_find_client_by_id(server->local_list,
2649 &id, server->server_type,
2652 SILC_LOG_DEBUG(("Ignoring client that we already have"));
2656 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
2657 silc_id_render(&id, SILC_ID_CLIENT),
2658 idata->conn_type == SILC_CONN_SERVER ?
2659 "Server" : "Router", hostname));
2661 /* As a router we keep information of all global information in our
2662 global list. Cell wide information however is kept in the local
2664 entry = silc_idlist_add_client(id_list, NULL, NULL, NULL,
2665 silc_id_dup(&id, SILC_ID_CLIENT),
2668 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
2670 /* Inform the sender that the ID is not usable */
2671 silc_server_send_notify_signoff(server, sock, FALSE, &id, NULL);
2674 entry->nickname = NULL;
2675 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2677 if (idata->conn_type == SILC_CONN_SERVER)
2678 server->stat.cell_clients++;
2679 server->stat.clients++;
2681 /* Check if anyone is watching this nickname */
2682 if (server->server_type == SILC_ROUTER && id_list == server->local_list)
2683 silc_server_check_watcher_list(server, entry, NULL, 0);
2685 if (server->server_type == SILC_ROUTER) {
2686 /* Add the client's public key to repository or get the key with
2688 if (entry->data.public_key) {
2689 if (!silc_server_get_public_key_by_client(server, entry, NULL))
2690 silc_skr_add_public_key_simple(server->repository,
2691 entry->data.public_key,
2692 SILC_SKR_USAGE_IDENTIFICATION,
2695 silc_server_send_command(server, router_sock,
2696 SILC_COMMAND_GETKEY, ++server->cmd_ident,
2698 silc_buffer_len(buffer));
2704 case SILC_ID_SERVER:
2706 SilcServerEntry entry;
2709 if (!silc_id_payload_get_id(idp, &id, sizeof(id)))
2712 /* If the ID is mine, ignore it. */
2713 if (SILC_ID_SERVER_COMPARE(&id, server->id)) {
2714 SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
2718 /* If the ID is the sender's ID, ignore it (we have it already) */
2719 if (SILC_ID_SERVER_COMPARE(&id, router->id)) {
2720 SILC_LOG_DEBUG(("Ignoring sender's own ID"));
2724 /* Check that we do not have this server already */
2725 entry = silc_idlist_find_server_by_id(server->global_list,
2726 &id, server->server_type,
2729 entry = silc_idlist_find_server_by_id(server->local_list,
2730 &id, server->server_type,
2733 SILC_LOG_DEBUG(("Ignoring server that we already have"));
2737 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
2738 silc_id_render(&id, SILC_ID_SERVER),
2739 idata->conn_type == SILC_CONN_SERVER ?
2740 "Server" : "Router", hostname));
2742 /* As a router we keep information of all global information in our
2743 global list. Cell wide information however is kept in the local
2745 entry = silc_idlist_add_server(id_list, NULL, 0,
2746 silc_id_dup(&id, SILC_ID_SERVER), router,
2749 SILC_LOG_ERROR(("Could not add new server to the ID Cache"));
2752 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2754 if (idata->conn_type == SILC_CONN_SERVER)
2755 server->stat.cell_servers++;
2756 server->stat.servers++;
2760 case SILC_ID_CHANNEL:
2761 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
2770 /* If the sender of this packet is server and we are router we need to
2771 broadcast this packet to other routers in the network. */
2772 if (broadcast && server->server_type == SILC_ROUTER &&
2773 idata->conn_type == SILC_CONN_SERVER &&
2774 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2775 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
2776 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
2778 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2779 buffer->data, silc_buffer_len(buffer));
2780 silc_server_backup_send(server, (SilcServerEntry)idata,
2781 packet->type, packet->flags,
2782 packet->buffer.data,
2783 silc_buffer_len(&packet->buffer),
2788 silc_id_payload_free(idp);
2792 /* Processes incoming New ID packet. New ID Payload is used to distribute
2793 information about newly registered clients and servers. */
2795 void silc_server_new_id(SilcServer server, SilcPacketStream sock,
2798 silc_server_new_id_real(server, sock, packet, &packet->buffer, TRUE);
2799 silc_packet_free(packet);
2802 /* Receoved New Id List packet, list of New ID payloads inside one
2803 packet. Process the New ID payloads one by one. */
2805 void silc_server_new_id_list(SilcServer server, SilcPacketStream sock,
2808 SilcIDListData idata = silc_packet_get_context(sock);
2812 SILC_LOG_DEBUG(("Processing New ID List"));
2814 if (idata->conn_type == SILC_CONN_CLIENT ||
2815 packet->src_id_type != SILC_ID_SERVER) {
2816 silc_packet_free(packet);
2820 /* If the sender of this packet is server and we are router we need to
2821 broadcast this packet to other routers in the network. Broadcast
2822 this list packet instead of multiple New ID packets. */
2823 if (server->server_type == SILC_ROUTER &&
2824 idata->conn_type == SILC_CONN_SERVER &&
2825 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2826 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
2827 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
2829 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2830 packet->buffer.data,
2831 silc_buffer_len(&packet->buffer));
2832 silc_server_backup_send(server, (SilcServerEntry)idata,
2833 packet->type, packet->flags,
2834 packet->buffer.data,
2835 silc_buffer_len(&packet->buffer),
2839 idp = silc_buffer_alloc(256);
2841 silc_packet_free(packet);
2845 while (silc_buffer_len(&packet->buffer)) {
2846 SILC_GET16_MSB(id_len, packet->buffer.data + 2);
2847 if ((id_len > silc_buffer_len(&packet->buffer)) ||
2848 (id_len > silc_buffer_truelen(idp)))
2851 silc_buffer_pull_tail(idp, 4 + id_len);
2852 silc_buffer_put(idp, packet->buffer.data, 4 + id_len);
2854 /* Process the New ID */
2855 silc_server_new_id_real(server, sock, packet, idp, FALSE);
2857 silc_buffer_push_tail(idp, 4 + id_len);
2858 silc_buffer_pull(&packet->buffer, 4 + id_len);
2861 silc_buffer_free(idp);
2862 silc_packet_free(packet);
2865 /* Received New Channel packet. Information about new channels in the
2866 network are distributed using this packet. Save the information about
2867 the new channel. This usually comes from router but also normal server
2868 can send this to notify channels it has when it connects to us. */
2870 static void silc_server_new_channel_process(SilcServer server,
2871 SilcPacketStream sock,
2875 SilcIDListData idata = silc_packet_get_context(sock);
2876 SilcChannelPayload payload;
2877 SilcChannelID channel_id;
2878 char *channel_name, *channel_namec = NULL;
2879 SilcUInt32 name_len;
2880 unsigned char *id, cid[32];
2881 SilcUInt32 id_len, cipher_len;
2882 SilcServerEntry server_entry;
2883 SilcChannelEntry channel;
2886 if (idata->conn_type == SILC_CONN_CLIENT ||
2887 packet->src_id_type != SILC_ID_SERVER ||
2888 server->server_type == SILC_SERVER)
2891 /* Parse the channel payload */
2892 payload = silc_channel_payload_parse(buffer->data, silc_buffer_len(buffer));
2896 /* Get the channel ID */
2897 if (!silc_channel_get_id_parse(payload, &channel_id)) {
2898 silc_channel_payload_free(payload);
2902 channel_name = silc_channel_get_name(payload, &name_len);
2903 if (name_len > 256) {
2904 channel_name[256] = '\0';
2908 /* Check channel name */
2909 channel_namec = silc_channel_name_check(channel_name, strlen(channel_name),
2910 SILC_STRING_UTF8, 256, NULL);
2914 id = silc_channel_get_id(payload, &id_len);
2916 server_entry = (SilcServerEntry)idata;
2918 if (idata->conn_type == SILC_CONN_ROUTER) {
2919 /* Add the channel to global list as it is coming from router. It
2920 cannot be our own channel as it is coming from router. */
2922 /* Check that we don't already have this channel */
2923 channel = silc_idlist_find_channel_by_name(server->local_list,
2924 channel_namec, NULL);
2926 channel = silc_idlist_find_channel_by_name(server->global_list,
2927 channel_namec, NULL);
2929 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
2930 silc_id_render(&channel_id, SILC_ID_CHANNEL),
2931 idata->sconn->remote_host));
2934 silc_idlist_add_channel(server->global_list, strdup(channel_name),
2935 0, silc_id_dup(&channel_id, SILC_ID_CHANNEL),
2936 (SilcServerEntry)idata, NULL, NULL, NULL);
2938 silc_channel_payload_free(payload);
2941 channel->disabled = TRUE; /* Disabled until someone JOINs */
2943 server->stat.channels++;
2944 if (server->server_type == SILC_ROUTER)
2945 channel->users_resolved = TRUE;
2948 /* The channel is coming from our server, thus it is in our cell
2949 we will add it to our local list. */
2952 SILC_LOG_DEBUG(("Channel id(%s) from [Server] %s",
2953 silc_id_render(&channel_id, SILC_ID_CHANNEL),
2954 idata->sconn->remote_host));
2956 /* Check that we don't already have this channel */
2957 channel = silc_idlist_find_channel_by_name(server->local_list,
2958 channel_namec, NULL);
2960 channel = silc_idlist_find_channel_by_name(server->global_list,
2961 channel_namec, NULL);
2963 /* If the channel does not exist, then create it. This creates a new
2964 key to the channel as well that we will send to the server. */
2966 SILC_LOG_DEBUG(("Channel is new to us"));
2968 /* The protocol says that the Channel ID's IP address must be based
2969 on the router's IP address. Check whether the ID is based in our
2970 IP and if it is not then create a new ID and enforce the server
2971 to switch the ID. */
2972 if (server_entry->server_type != SILC_BACKUP_ROUTER &&
2973 !SILC_ID_COMPARE(&channel_id, server->id, server->id->ip.data_len)) {
2975 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2976 if (silc_id_create_channel_id(server, server->id, server->rng, &tmp)) {
2977 silc_server_send_notify_channel_change(server, sock, FALSE,
2979 silc_channel_payload_free(payload);
2983 /* Wait that server re-announces this channel */
2987 /* Create the channel with the provided Channel ID */
2989 silc_server_create_new_channel_with_id(
2992 silc_id_dup(&channel_id, SILC_ID_CHANNEL),
2995 silc_channel_payload_free(payload);
2998 channel->disabled = TRUE; /* Disabled until someone JOINs */
3000 #if 0 /* We assume that CMODE_CHANGE notify is sent to us after this. */
3002 /* XXX Dunno if this is supposed to be set in any server type. If set
3003 here the CMODE_CHANGE that may follow sets mode that we already
3004 have, and we may loose data from the CMODE_CHANGE notify. */
3005 if (server_entry->server_type != SILC_BACKUP_ROUTER)
3006 channel->mode = silc_channel_get_mode(payload);
3009 /* Send the new channel key to the server */
3010 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid),
3012 cipher = silc_cipher_get_name(channel->send_key);
3013 cipher_len = strlen(cipher);
3014 chk = silc_channel_key_payload_encode(id_len, cid,
3016 channel->key_len / 8,
3018 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
3019 chk->data, silc_buffer_len(chk));
3020 silc_buffer_free(chk);
3022 /* The channel exist by that name, check whether the ID's match.
3023 If they don't then we'll force the server to use the ID we have.
3024 We also create a new key for the channel. */
3025 SilcBuffer modes = NULL, users = NULL, users_modes = NULL;
3027 SILC_LOG_DEBUG(("Channel already exists"));
3029 if (!SILC_ID_CHANNEL_COMPARE(&channel_id, channel->id)) {
3030 /* They don't match, send CHANNEL_CHANGE notify to the server to
3031 force the ID change. */
3032 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
3033 silc_server_send_notify_channel_change(server, sock, FALSE,
3034 &channel_id, channel->id);
3035 silc_channel_payload_free(payload);
3037 /* Wait that server re-announces this channel */
3041 #if 0 /* We will announce our CMODE anyway for this channel, so no need
3042 to check it (implicit enforce). */
3044 /* If the mode is different from what we have then enforce the
3046 mode = silc_channel_get_mode(payload);
3047 if (channel->mode != mode) {
3048 SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
3049 silc_server_send_notify_cmode(server, sock, FALSE, channel,
3050 channel->mode, server->id,
3051 SILC_ID_SERVER, channel->cipher,
3053 channel->passphrase,
3054 channel->founder_key);
3058 /* Create new key for the channel and send it to the server and
3059 everybody else possibly on the channel. */
3060 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
3062 if (silc_hash_table_count(channel->user_list)) {
3063 if (!silc_server_create_channel_key(server, channel, 0)) {
3064 silc_channel_payload_free(payload);
3068 /* Send to the channel */
3069 silc_server_send_channel_key(server, sock, channel, FALSE);
3072 /* Send to the server */
3073 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid),
3075 cipher = silc_cipher_get_name(channel->send_key);
3076 cipher_len = strlen(cipher);
3077 chk = silc_channel_key_payload_encode(id_len, cid,
3079 channel->key_len / 8,
3081 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
3082 chk->data, silc_buffer_len(chk));
3083 silc_buffer_free(chk);
3086 /* Since the channel is coming from server and we also know about it
3087 then send the JOIN notify to the server so that it see's our
3088 users on the channel "joining" the channel. */
3089 silc_server_announce_get_channel_users(server, channel, &modes, &users,
3092 silc_buffer_push(users, users->data - users->head);
3093 silc_server_packet_send(server, sock,
3094 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3095 users->data, silc_buffer_len(users));
3096 silc_buffer_free(users);
3099 silc_buffer_push(modes, modes->data - modes->head);
3100 silc_server_packet_send_dest(server, sock,
3101 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3102 channel->id, SILC_ID_CHANNEL,
3103 modes->data, silc_buffer_len(modes));
3104 silc_buffer_free(modes);
3107 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
3108 silc_server_packet_send_dest(server, sock,
3109 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
3110 channel->id, SILC_ID_CHANNEL,
3112 silc_buffer_len(users_modes));
3113 silc_buffer_free(users_modes);
3115 if (channel->topic) {
3116 silc_server_send_notify_topic_set(server, sock,
3117 server->server_type == SILC_ROUTER ?
3118 TRUE : FALSE, channel,
3119 server->id, SILC_ID_SERVER,
3125 /* If the sender of this packet is server and we are router we need to
3126 broadcast this packet to other routers in the network. Broadcast
3127 this list packet instead of multiple New Channel packets. */
3128 if (server->server_type == SILC_ROUTER &&
3129 idata->conn_type == SILC_CONN_SERVER &&
3130 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
3131 SILC_LOG_DEBUG(("Broadcasting received New Channel packet"));
3132 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
3134 packet->flags | SILC_PACKET_FLAG_BROADCAST,
3135 buffer->data, silc_buffer_len(buffer));
3136 silc_server_backup_send(server, (SilcServerEntry)idata,
3137 packet->type, packet->flags,
3138 buffer->data, silc_buffer_len(buffer),
3142 silc_free(channel_namec);
3143 silc_channel_payload_free(payload);
3146 /* Received New Channel packet. Information about new channels in the
3147 network are distributed using this packet. Save the information about
3148 the new channel. This usually comes from router but also normal server
3149 can send this to notify channels it has when it connects to us. */
3151 void silc_server_new_channel(SilcServer server,
3152 SilcPacketStream sock,
3155 silc_server_new_channel_process(server, sock, packet, &packet->buffer);
3156 silc_packet_free(packet);
3159 /* Received New Channel List packet, list of New Channel List payloads inside
3160 one packet. Process the New Channel payloads one by one. */
3162 void silc_server_new_channel_list(SilcServer server,
3163 SilcPacketStream sock,
3166 SilcIDListData idata = silc_packet_get_context(sock);
3168 SilcUInt16 len1, len2;
3170 SILC_LOG_DEBUG(("Processing New Channel List"));
3172 if (idata->conn_type == SILC_CONN_CLIENT ||
3173 packet->src_id_type != SILC_ID_SERVER ||
3174 server->server_type == SILC_SERVER) {
3175 silc_packet_free(packet);
3179 buffer = silc_buffer_alloc(512);
3181 silc_packet_free(packet);
3185 while (silc_buffer_len(&packet->buffer)) {
3186 SILC_GET16_MSB(len1, packet->buffer.data);
3187 if ((len1 > silc_buffer_len(&packet->buffer)) ||
3188 (len1 > silc_buffer_truelen(buffer)))
3191 SILC_GET16_MSB(len2, packet->buffer.data + 2 + len1);
3192 if ((len2 > silc_buffer_len(&packet->buffer)) ||
3193 (len2 > silc_buffer_truelen(buffer)))
3196 silc_buffer_pull_tail(buffer, 8 + len1 + len2);
3197 silc_buffer_put(buffer, packet->buffer.data, 8 + len1 + len2);
3199 /* Process the New Channel */
3200 silc_server_new_channel_process(server, sock, packet, buffer);
3202 silc_buffer_push_tail(buffer, 8 + len1 + len2);
3203 silc_buffer_pull(&packet->buffer, 8 + len1 + len2);
3206 silc_buffer_free(buffer);
3207 silc_packet_free(packet);
3210 /* Received key agreement packet. This packet is never for us. It is to
3211 the client in the packet's destination ID. Sending of this sort of packet
3212 equals sending private message, ie. it is sent point to point from
3213 one client to another. */
3215 void silc_server_key_agreement(SilcServer server,
3216 SilcPacketStream sock,
3219 SilcPacketStream dst_sock;
3220 SilcIDListData idata;
3222 SILC_LOG_DEBUG(("Start"));
3224 if (packet->src_id_type != SILC_ID_CLIENT ||
3225 packet->dst_id_type != SILC_ID_CLIENT || !packet->dst_id) {
3226 silc_packet_free(packet);
3230 /* Get the route to the client */
3231 dst_sock = silc_server_get_client_route(server, packet->dst_id,
3232 packet->dst_id_len, NULL,
3235 silc_packet_free(packet);
3239 /* Relay the packet */
3240 silc_server_packet_route(server, dst_sock, packet);
3241 silc_packet_free(packet);
3244 /* Received connection auth request packet that is used during connection
3245 phase to resolve the mandatory authentication method. This packet can
3246 actually be received at anytime but usually it is used only during
3247 the connection authentication phase. Now, protocol says that this packet
3248 can come from client or server, however, we support only this coming
3249 from client and expect that server always knows what authentication
3252 void silc_server_connection_auth_request(SilcServer server,
3253 SilcPacketStream sock,
3256 SilcServerConfigClient *client = NULL;
3257 SilcUInt16 conn_type;
3259 SilcAuthMethod auth_meth = SILC_AUTH_NONE;
3260 const char *hostname, *ip;
3262 if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT) {
3263 SILC_LOG_DEBUG(("Request not from client"));
3264 silc_packet_free(packet);
3268 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
3269 NULL, &hostname, &ip, NULL);
3271 /* Parse the payload */
3272 ret = silc_buffer_unformat(&packet->buffer,
3273 SILC_STR_UI_SHORT(&conn_type),
3274 SILC_STR_UI_SHORT(NULL),
3276 if (ret == -1 || conn_type != SILC_CONN_CLIENT) {
3277 silc_packet_free(packet);
3281 /* Get the authentication method for the client */
3282 auth_meth = SILC_AUTH_NONE;
3283 client = silc_server_config_find_client(server, (char *)ip);
3285 client = silc_server_config_find_client(server, (char *)hostname);
3287 if (client->passphrase) {
3288 if (client->publickeys && !server->config->prefer_passphrase_auth)
3289 auth_meth = SILC_AUTH_PUBLIC_KEY;
3291 auth_meth = SILC_AUTH_PASSWORD;
3292 } else if (client->publickeys)
3293 auth_meth = SILC_AUTH_PUBLIC_KEY;
3296 SILC_LOG_DEBUG(("Authentication method is [%s]",
3297 (auth_meth == SILC_AUTH_NONE ? "None" :
3298 auth_meth == SILC_AUTH_PASSWORD ? "Passphrase" :
3299 "Digital signatures")));
3301 /* Send it back to the client */
3302 silc_server_send_connection_auth_request(server, sock, conn_type, auth_meth);
3303 silc_packet_free(packet);
3306 /* Received file transger packet. This packet is never for us. It is to
3307 the client in the packet's destination ID. Sending of this sort of packet
3308 equals sending private message, ie. it is sent point to point from
3309 one client to another. */
3311 void silc_server_ftp(SilcServer server,
3312 SilcPacketStream sock,
3315 SilcPacketStream dst_sock;
3316 SilcIDListData idata;
3318 SILC_LOG_DEBUG(("Start"));
3320 if (packet->src_id_type != SILC_ID_CLIENT ||
3321 packet->dst_id_type != SILC_ID_CLIENT || !packet->dst_id) {
3322 silc_packet_free(packet);
3326 /* Get the route to the client */
3327 dst_sock = silc_server_get_client_route(server, packet->dst_id,
3328 packet->dst_id_len, NULL,
3331 silc_packet_free(packet);
3335 /* Relay the packet */
3336 silc_server_packet_route(server, dst_sock, packet);
3337 silc_packet_free(packet);
3342 SilcPacketStream sock;
3344 SilcClientID client_id;
3345 } *SilcServerResumeResolve;
3347 SILC_SERVER_CMD_FUNC(resume_resolve)
3349 SilcServerResumeResolve r = (SilcServerResumeResolve)context;
3350 SilcServer server = r->server;
3351 SilcPacketStream sock = r->sock;
3352 SilcServerCommandReplyContext reply = context2;
3353 SilcClientEntry client;
3354 const char *hostname, *ip;
3356 SILC_LOG_DEBUG(("Start"));
3358 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
3359 NULL, &hostname, &ip, NULL);
3361 if (!reply || !silc_command_get_status(reply->payload, NULL, NULL)) {
3362 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3363 "closing connection", hostname, ip));
3364 silc_server_disconnect_remote(server, sock,
3365 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3366 "Resuming not possible");
3367 silc_server_free_sock_user_data(server, sock, NULL);
3371 if (reply && silc_command_get(reply->payload) == SILC_COMMAND_WHOIS) {
3372 /* Get entry to the client, and resolve it if we don't have it. */
3373 client = silc_idlist_find_client_by_id(server->local_list,
3374 &r->client_id, TRUE, NULL);
3376 client = silc_idlist_find_client_by_id(server->global_list,
3377 &r->client_id, TRUE, NULL);
3379 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3380 "closing connection", hostname, ip));
3381 silc_server_disconnect_remote(server, sock,
3382 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3383 "Resuming not possible");
3384 silc_server_free_sock_user_data(server, sock, NULL);
3389 if (!(client->mode & SILC_UMODE_DETACHED)) {
3390 SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, "
3391 "closing connection", hostname, ip));
3392 silc_server_disconnect_remote(server, sock,
3393 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3394 "Resuming not possible");
3395 silc_server_free_sock_user_data(server, sock, NULL);
3399 client->data.status |= SILC_IDLIST_STATUS_RESUME_RES;
3402 /* Reprocess the packet */
3403 silc_server_resume_client(server, sock, r->packet);
3406 silc_packet_stream_unref(r->sock);
3410 /* Received client resuming packet. This is used to resume detached
3411 client session. It can be sent by the client who wishes to resume
3412 but this is also sent by servers and routers to notify other routers
3413 that the client is not detached anymore. */
3415 void silc_server_resume_client(SilcServer server,
3416 SilcPacketStream sock,
3419 SilcBuffer buffer = &packet->buffer, buf;
3420 SilcIDListData idata = silc_packet_get_context(sock);
3421 SilcIDCacheEntry id_cache = NULL;
3422 SilcClientEntry detached_client;
3423 SilcClientID client_id;
3424 unsigned char *id_string, *auth = NULL, *nicknamec = NULL;
3425 unsigned char cid[32];
3427 SilcUInt16 id_len, auth_len = 0;
3428 SilcBool resolved, local, nick_change = FALSE, resolve = FALSE;
3429 SilcChannelEntry channel;
3430 SilcHashTableList htl;
3431 SilcChannelClientEntry chl;
3432 SilcServerResumeResolve r;
3433 SilcPublicKey public_key;
3434 const char *cipher, *hostname, *ip;
3436 SILC_LOG_DEBUG(("Resuming client"));
3438 silc_socket_stream_get_info(silc_packet_stream_get_stream(sock),
3439 NULL, &hostname, &ip, NULL);
3441 if (silc_buffer_unformat(buffer,
3442 SILC_STR_UI16_NSTRING(&id_string, &id_len),
3443 SILC_STR_END) < 0) {
3444 if (idata->conn_type == SILC_CONN_CLIENT) {
3445 SILC_LOG_ERROR(("Client %s (%s) sent incomplete resume information, "
3446 "closing connection", hostname, ip));
3447 silc_server_disconnect_remote(server, sock,
3448 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3449 "Resuming not possible");
3450 silc_server_free_sock_user_data(server, sock, NULL);
3455 silc_id_str2id(id_string, id_len, SILC_ID_CLIENT, &client_id,
3458 if (idata->conn_type == SILC_CONN_CLIENT) {
3459 /* Client send this and is attempting to resume to old client session */
3460 SilcClientEntry client;
3463 silc_buffer_pull(buffer, 2 + id_len);
3464 auth = buffer->data;
3465 auth_len = silc_buffer_len(buffer);
3466 silc_buffer_push(buffer, 2 + id_len);
3468 if (auth_len < 128) {
3469 SILC_LOG_ERROR(("Client %s (%s) sent incomplete resume information, "
3470 "closing connection", hostname, ip));
3471 silc_server_disconnect_remote(server, sock,
3472 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3473 "Resuming not possible");
3474 silc_server_free_sock_user_data(server, sock, NULL);
3478 /* Take client entry of this connection */
3479 client = (SilcClientEntry)idata;
3481 /* Get entry to the client, and resolve it if we don't have it. */
3482 detached_client = silc_server_query_client(server, &client_id, FALSE,
3484 if (!detached_client) {
3486 /* The client info is being resolved. Reprocess this packet after
3487 receiving the reply to the query. */
3488 SILC_LOG_DEBUG(("Resolving client"));
3489 r = silc_calloc(1, sizeof(*r));
3492 silc_packet_stream_ref(sock);
3496 r->client_id = client_id;
3497 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
3499 silc_server_command_resume_resolve, r);
3502 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
3503 "closing connection", hostname, ip));
3504 silc_server_disconnect_remote(server, sock,
3505 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3506 "Resuming not possible");
3507 silc_server_free_sock_user_data(server, sock, NULL);
3512 if (detached_client->data.status & SILC_IDLIST_STATUS_RESUMED) {
3513 SILC_LOG_ERROR(("Client %s (%s) tried to attach more than once, "
3514 "closing connection", hostname, ip));
3515 silc_server_disconnect_remote(server, sock,
3516 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3517 "Resuming not possible");
3518 silc_server_free_sock_user_data(server, sock, NULL);
3522 if (detached_client->resuming_client &&
3523 detached_client->resuming_client != client) {
3524 SILC_LOG_ERROR(("Client %s (%s) tried to attach more than once, "
3525 "closing connection", hostname, ip));
3526 silc_server_disconnect_remote(server, sock,
3527 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3528 "Resuming not possible");
3529 silc_server_free_sock_user_data(server, sock, NULL);
3533 if (!detached_client->resuming_client)
3534 detached_client->resuming_client = client;
3536 if (!(detached_client->mode & SILC_UMODE_DETACHED))
3538 if (!silc_hash_table_count(detached_client->channels) &&
3539 detached_client->router)
3541 if (!detached_client->nickname)
3543 if (detached_client->data.status & SILC_IDLIST_STATUS_RESUME_RES)
3547 if (server->server_type == SILC_SERVER && !server->standalone) {
3548 /* The client info is being resolved. Reprocess this packet after
3549 receiving the reply to the query. */
3550 SILC_LOG_DEBUG(("Resolving client info"));
3551 silc_server_query_client(server, &client_id, TRUE, NULL);
3552 r = silc_calloc(1, sizeof(*r));
3555 silc_packet_stream_ref(sock);
3559 r->client_id = client_id;
3560 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
3562 silc_server_command_resume_resolve, r);
3565 if (server->server_type == SILC_SERVER) {
3566 SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, "
3567 "closing connection", hostname, ip));
3568 silc_server_disconnect_remote(server, sock,
3569 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3570 "Resuming not possible");
3571 silc_server_free_sock_user_data(server, sock, NULL);
3576 /* Check that we have the public key of the client, if not then we must
3577 resolve it first. */
3578 if (!detached_client->data.public_key) {
3579 if (server->server_type == SILC_SERVER && server->standalone) {
3580 SILC_LOG_ERROR(("Detached client's public key not present, "
3581 "closing connection"));
3582 silc_server_disconnect_remote(server, sock,
3583 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3584 "Resuming not possible");
3585 silc_server_free_sock_user_data(server, sock, NULL);
3588 /* We must retrieve the detached client's public key by sending
3589 GETKEY command. Reprocess this packet after receiving the key */
3590 SilcBuffer idp = silc_id_payload_encode(&client_id, SILC_ID_CLIENT);
3591 SilcPacketStream dest_sock =
3592 silc_server_get_client_route(server, NULL, 0, &client_id,
3595 SILC_LOG_DEBUG(("Resolving client public key"));
3597 silc_server_send_command(server, dest_sock ? dest_sock :
3598 SILC_PRIMARY_ROUTE(server),
3599 SILC_COMMAND_GETKEY, ++server->cmd_ident,
3600 1, 1, idp->data, silc_buffer_len(idp));
3602 r = silc_calloc(1, sizeof(*r));
3605 silc_packet_stream_ref(sock);
3609 r->client_id = client_id;
3610 silc_server_command_pending(server, SILC_COMMAND_GETKEY,
3612 silc_server_command_resume_resolve, r);
3614 silc_buffer_free(idp);
3617 } else if (!silc_pkcs_public_key_compare(detached_client->data.public_key,
3618 idata->public_key)) {
3619 /* We require that the connection and resuming authentication data
3620 must be using same key pair. */
3621 SILC_LOG_ERROR(("Resuming attempted with wrong public key, "
3622 "closing connection"));
3623 silc_server_disconnect_remote(server, sock,
3624 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3625 "Resuming not possible");
3626 silc_server_free_sock_user_data(server, sock, NULL);
3630 /* Verify the authentication payload. This has to be successful in
3631 order to allow the resuming */
3633 !silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
3634 detached_client->data.public_key, 0,
3635 idata->hash, detached_client->id,
3637 SILC_LOG_ERROR(("Client %s (%s) resume authentication failed, "
3638 "closing connection", hostname, ip));
3639 silc_server_disconnect_remote(server, sock,
3640 SILC_STATUS_ERR_INCOMPLETE_INFORMATION,
3641 "Resuming not possible");
3642 silc_server_free_sock_user_data(server, sock, NULL);
3646 /* Check nickname */
3647 nicknamec = silc_identifier_check(detached_client->nickname,
3648 strlen(detached_client->nickname),
3649 SILC_STRING_UTF8, 128, NULL);
3651 silc_server_disconnect_remote(server, sock,
3652 SILC_STATUS_ERR_BAD_NICKNAME,
3653 "Malformed nickname, cannot resume");
3654 silc_server_free_sock_user_data(server, sock, NULL);
3658 /* If the ID is not based in our ID then change it */
3659 if (!SILC_ID_COMPARE(detached_client->id, server->id,
3660 server->id->ip.data_len)) {
3661 SilcClientID *new_id;
3662 if (!silc_id_create_client_id(server, server->id, server->rng,
3663 server->md5hash, nicknamec,
3664 strlen(nicknamec), &new_id)) {
3665 silc_server_disconnect_remote(server, sock,
3666 SILC_STATUS_ERR_BAD_NICKNAME,
3667 "Resuming not possible");
3668 silc_server_free_sock_user_data(server, sock, NULL);
3672 client_id = *new_id;
3676 /* Now resume the client to the network */
3678 silc_schedule_task_del_by_context(server->schedule, detached_client);
3679 silc_packet_set_context(sock, detached_client);
3680 detached_client->connection = sock;
3682 if (detached_client->data.public_key) {
3683 /* Delete the detached client's public key from repository */
3684 silc_skr_del_public_key(server->repository,
3685 detached_client->data.public_key,
3687 detached_client->data.public_key = NULL;
3690 if (idata->public_key) {
3691 /* Delete the resuming client's public key from repository. It will
3692 be added later again. */
3693 public_key = silc_pkcs_public_key_copy(idata->public_key);
3694 silc_skr_del_public_key(server->repository, idata->public_key, idata);
3695 idata->public_key = public_key;
3698 /* Take new keys and stuff into use in the old entry */
3699 silc_idlist_del_data(detached_client);
3700 silc_idlist_add_data(detached_client, idata);
3701 idata->public_key = NULL;
3703 if (detached_client->data.public_key) {
3704 /* Add the resumed client's public key back to repository. */
3705 if (!silc_server_get_public_key_by_client(server, detached_client, NULL))
3706 silc_skr_add_public_key_simple(server->repository,
3707 detached_client->data.public_key,
3708 SILC_SKR_USAGE_IDENTIFICATION,
3709 detached_client, NULL);
3712 detached_client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
3713 detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
3714 detached_client->data.status |= SILC_IDLIST_STATUS_LOCAL;
3715 detached_client->data.status &= ~SILC_IDLIST_STATUS_RESUME_RES;
3716 detached_client->mode &= ~SILC_UMODE_DETACHED;
3717 server->stat.my_detached--;
3719 /* We are finished - reset resuming client */
3720 detached_client->resuming_client = NULL;
3722 /* Check if anyone is watching this client */
3723 if (server->server_type == SILC_ROUTER)
3724 silc_server_check_watcher_list(server, detached_client, NULL,
3725 SILC_NOTIFY_TYPE_UMODE_CHANGE);
3727 /* Delete this current client entry since we're resuming to old one. */
3728 server->stat.my_clients--;
3729 server->stat.clients--;
3730 if (server->stat.cell_clients)
3731 server->stat.cell_clients--;
3732 silc_server_remove_from_channels(server, NULL, client, FALSE,
3733 NULL, FALSE, FALSE);
3734 silc_server_del_from_watcher_list(server, client);
3735 if (!silc_idlist_del_client(server->local_list, client))
3736 silc_idlist_del_client(server->global_list, client);
3737 client = detached_client;
3738 silc_free(client->servername);
3739 client->servername = strdup(server->server_name);
3741 /* Send the RESUME_CLIENT packet to our primary router so that others
3742 know this client isn't detached anymore. */
3743 buf = silc_buffer_alloc_size(2 + id_len);
3744 silc_buffer_format(buf,
3745 SILC_STR_UI_SHORT(id_len),
3746 SILC_STR_UI_XNSTRING(id_string, id_len),
3749 /* Send to primary router */
3750 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
3751 SILC_PACKET_RESUME_CLIENT, 0,
3752 buf->data, silc_buffer_len(buf));
3753 silc_server_backup_send(server, client->router,
3754 SILC_PACKET_RESUME_CLIENT, 0,
3755 buf->data, silc_buffer_len(buf), TRUE, TRUE);
3757 /* As router we must deliver this packet directly to the original
3758 server whom this client was earlier. */
3759 if (server->server_type == SILC_ROUTER && client->router &&
3760 client->router->server_type != SILC_ROUTER)
3761 silc_server_packet_send(server, client->router->connection,
3762 SILC_PACKET_RESUME_CLIENT, 0,
3763 buf->data, silc_buffer_len(buf));
3764 silc_buffer_free(buf);
3765 client->router = NULL;
3768 /* Notify about Client ID change, nickname doesn't actually change. */
3769 silc_server_send_notify_nick_change(server, SILC_PRIMARY_ROUTE(server),
3770 SILC_BROADCAST(server),
3771 client->id, &client_id,
3775 /* Resolve users on those channels that client has joined but we
3776 haven't resolved user list yet. */
3777 if (server->server_type == SILC_SERVER && !server->standalone) {
3778 silc_hash_table_list(client->channels, &htl);
3779 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3780 channel = chl->channel;
3781 SILC_LOG_DEBUG(("Resolving users for %s channel",
3782 channel->channel_name));
3783 if (channel->disabled || !channel->users_resolved) {
3784 silc_server_send_command(server, SILC_PRIMARY_ROUTE(server),
3785 SILC_COMMAND_USERS, ++server->cmd_ident,
3786 1, 2, channel->channel_name,
3787 strlen(channel->channel_name));
3790 silc_hash_table_list_reset(&htl);
3793 /* Send the new client ID to the client. After this client may start
3794 receiving other packets, and may start sending packets too. */
3795 silc_server_send_new_id(server, sock, FALSE, &client_id, SILC_ID_CLIENT,
3796 silc_id_get_len(&client_id, SILC_ID_CLIENT));
3799 /* Send NICK change notify to channels as well. */
3800 SilcBuffer oidp, nidp;
3801 oidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
3802 nidp = silc_id_payload_encode(&client_id, SILC_ID_CLIENT);
3803 silc_server_send_notify_on_channels(server, NULL, client,
3804 SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
3805 oidp->data, silc_buffer_len(oidp),
3806 nidp->data, silc_buffer_len(nidp),
3808 strlen(client->nickname));
3809 silc_buffer_free(oidp);
3810 silc_buffer_free(nidp);
3814 if (!silc_idcache_update_by_context(server->local_list->clients, client,
3815 &client_id, NULL, FALSE))
3816 silc_idcache_update_by_context(server->global_list->clients, client,
3817 &client_id, NULL, FALSE);
3819 /* Move entry to local list if it is in global list */
3820 if (silc_idcache_find_by_context(server->global_list->clients, client,
3822 silc_idcache_move(server->global_list->clients,
3823 server->local_list->clients, id_cache);
3825 /* Send some nice info to the client */
3826 silc_server_send_connect_notifys(server, sock, client);
3828 /* Send all channel keys of channels the client has joined */
3829 silc_hash_table_list(client->channels, &htl);
3830 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
3831 SilcBool created = FALSE;
3832 channel = chl->channel;
3834 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY)
3837 /* If we don't have channel key, then create one */
3838 if (!channel->send_key) {
3839 if (!silc_server_create_channel_key(server, channel, 0))
3844 silc_id_id2str(channel->id, SILC_ID_CHANNEL, cid, sizeof(cid),
3846 cipher = silc_cipher_get_name(channel->send_key);
3848 silc_channel_key_payload_encode(cid_len, cid,
3849 strlen(cipher), cipher,
3850 channel->key_len / 8, channel->key);
3852 /* Send the channel key to the client */
3853 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
3854 keyp->data, silc_buffer_len(keyp));
3856 /* Distribute the channel key to channel */
3858 silc_server_send_channel_key(server, NULL, channel,
3859 server->server_type == SILC_ROUTER ?
3860 FALSE : !server->standalone);
3861 silc_server_backup_send(server, NULL, SILC_PACKET_CHANNEL_KEY, 0,
3862 keyp->data, silc_buffer_len(keyp),
3866 silc_buffer_free(keyp);
3868 silc_hash_table_list_reset(&htl);
3870 } else if (idata->conn_type != SILC_CONN_CLIENT) {
3871 /* Server or router sent this to us to notify that that a client has
3873 SilcServerEntry server_entry;
3874 SilcServerID server_id;
3876 /* Get entry to the client, and resolve it if we don't have it. */
3877 detached_client = silc_idlist_find_client_by_id(server->local_list,
3880 if (!detached_client) {
3881 detached_client = silc_idlist_find_client_by_id(server->global_list,
3884 if (!detached_client) {
3885 SILC_LOG_DEBUG(("Resuming client is unknown"));
3890 /* Check that the client has not been resumed already because it is
3891 protocol error to attempt to resume more than once. The client
3892 will be killed if this protocol error occurs. */
3893 if (detached_client->data.status & SILC_IDLIST_STATUS_RESUMED &&
3894 !(detached_client->mode & SILC_UMODE_DETACHED)) {
3895 /* The client is clearly attempting to resume more than once and
3896 perhaps playing around by resuming from several different places
3897 at the same time. */
3898 SILC_LOG_DEBUG(("Attempting to re-resume client, killing both"));
3899 silc_server_kill_client(server, detached_client, NULL,
3900 server->id, SILC_ID_SERVER);
3904 /* Check whether client is detached at all */
3905 if (!(detached_client->mode & SILC_UMODE_DETACHED)) {
3906 SILC_LOG_DEBUG(("Client is not detached"));
3910 /* Check nickname */
3911 if (detached_client->nickname) {
3912 nicknamec = silc_identifier_check(detached_client->nickname,
3913 strlen(detached_client->nickname),
3914 SILC_STRING_UTF8, 128, NULL);
3919 SILC_LOG_DEBUG(("Resuming detached client"));
3921 /* If the sender of this packet is server and we are router we need to
3922 broadcast this packet to other routers in the network. */
3923 if (server->server_type == SILC_ROUTER &&
3924 idata->conn_type == SILC_CONN_SERVER &&
3925 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
3926 SILC_LOG_DEBUG(("Broadcasting received Resume Client packet"));
3927 silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server),
3929 packet->flags | SILC_PACKET_FLAG_BROADCAST,
3930 buffer->data, silc_buffer_len(buffer));
3931 silc_server_backup_send(server, (SilcServerEntry)idata,
3932 packet->type, packet->flags,
3933 packet->buffer.data,
3934 silc_buffer_len(&packet->buffer),
3938 /* Client is detached, and now it is resumed. Remove the detached
3939 mode and mark that it is resumed. */
3941 if (detached_client->data.public_key) {
3942 /* Delete the detached client's public key from repository */
3943 silc_skr_del_public_key(server->repository,
3944 detached_client->data.public_key,
3946 detached_client->data.public_key = NULL;
3949 silc_idlist_del_data(detached_client);
3950 detached_client->mode &= ~SILC_UMODE_DETACHED;
3951 detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
3952 detached_client->data.status &= ~SILC_IDLIST_STATUS_LOCAL;
3953 silc_dlist_del(server->expired_clients, detached_client);
3955 /* Check if anyone is watching this client */
3956 if (server->server_type == SILC_ROUTER)
3957 silc_server_check_watcher_list(server, detached_client, NULL,
3958 SILC_NOTIFY_TYPE_UMODE_CHANGE);
3960 silc_schedule_task_del_by_context(server->schedule, detached_client);
3962 /* Get the new owner of the resumed client */
3963 if (!silc_id_str2id(packet->src_id, packet->src_id_len,
3964 packet->src_id_type, &server_id, sizeof(server_id)))
3967 /* Get server entry */
3968 server_entry = silc_idlist_find_server_by_id(server->global_list,
3969 &server_id, TRUE, NULL);
3971 if (!server_entry) {
3972 server_entry = silc_idlist_find_server_by_id(server->local_list,
3973 &server_id, TRUE, NULL);
3979 if (server->server_type == SILC_ROUTER &&
3980 idata->conn_type == SILC_CONN_ROUTER &&
3981 server_entry->server_type == SILC_ROUTER)
3984 /* Move entry to correct list */
3985 if (local && server->server_type == SILC_ROUTER) {
3986 if (silc_idcache_find_by_context(server->global_list->clients,
3987 detached_client, &id_cache))
3988 silc_idcache_move(server->global_list->clients,
3989 server->local_list->clients, id_cache);
3991 if (silc_idcache_find_by_context(server->local_list->clients,
3992 detached_client, &id_cache))
3993 silc_idcache_move(server->local_list->clients,
3994 server->global_list->clients, id_cache);
3997 /* Change the owner of the client */
3998 detached_client->router = server_entry;
4000 /* Update channel information regarding global clients on channel. */
4001 if (server->server_type != SILC_ROUTER) {
4002 silc_hash_table_list(detached_client->channels, &htl);
4003 while (silc_hash_table_get(&htl, NULL, (void *)&chl))
4004 chl->channel->global_users =
4005 silc_server_channel_has_global(chl->channel);
4006 silc_hash_table_list_reset(&htl);
4011 silc_packet_free(packet);