5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2002 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
21 * Server packet routines to handle received packets.
25 #include "serverincludes.h"
26 #include "server_internal.h"
28 /* Received notify packet. Server can receive notify packets from router.
29 Server then relays the notify messages to clients if needed. */
31 void silc_server_notify(SilcServer server,
32 SilcSocketConnection sock,
33 SilcPacketContext *packet)
35 SilcNotifyPayload payload;
37 SilcArgumentPayload args;
38 SilcChannelID *channel_id = NULL, *channel_id2;
39 SilcClientID *client_id, *client_id2;
40 SilcServerID *server_id;
42 SilcChannelEntry channel = NULL;
43 SilcClientEntry client = NULL, client2 = NULL;
44 SilcServerEntry server_entry = NULL;
45 SilcChannelClientEntry chl;
46 SilcIDCacheEntry cache;
47 SilcHashTableList htl;
53 SILC_LOG_DEBUG(("Start"));
55 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
56 packet->src_id_type != SILC_ID_SERVER)
62 /* If the packet is destined directly to a client then relay the packet
63 before processing it. */
64 if (packet->dst_id_type == SILC_ID_CLIENT) {
66 SilcSocketConnection dst_sock;
68 /* Get the route to the client */
69 dst_sock = silc_server_get_client_route(server, packet->dst_id,
70 packet->dst_id_len, NULL,
73 /* Relay the packet */
74 silc_server_relay_packet(server, dst_sock, idata->send_key,
75 idata->hmac_send, idata->psn_send++,
79 /* Parse the Notify Payload */
80 payload = silc_notify_payload_parse(packet->buffer->data,
85 /* If we are router and this packet is not already broadcast packet
86 we will broadcast it. The sending socket really cannot be router or
87 the router is buggy. If this packet is coming from router then it must
88 have the broadcast flag set already and we won't do anything. */
89 if (!server->standalone && server->server_type == SILC_ROUTER &&
90 sock->type == SILC_SOCKET_TYPE_SERVER &&
91 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
92 SILC_LOG_DEBUG(("Broadcasting received Notify packet"));
93 if (packet->dst_id_type == SILC_ID_CHANNEL) {
94 /* Packet is destined to channel */
95 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
100 silc_server_packet_send_dest(server, server->router->connection,
102 packet->flags | SILC_PACKET_FLAG_BROADCAST,
103 channel_id, SILC_ID_CHANNEL,
104 packet->buffer->data, packet->buffer->len,
106 silc_server_backup_send_dest(server, (SilcServerEntry)sock->user_data,
107 packet->type, packet->flags,
108 channel_id, SILC_ID_CHANNEL,
109 packet->buffer->data, packet->buffer->len,
112 /* Packet is destined to client or server */
113 silc_server_packet_send(server, server->router->connection,
115 packet->flags | SILC_PACKET_FLAG_BROADCAST,
116 packet->buffer->data, packet->buffer->len,
118 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
119 packet->type, packet->flags,
120 packet->buffer->data, packet->buffer->len,
125 type = silc_notify_get_type(payload);
126 args = silc_notify_get_args(payload);
131 case SILC_NOTIFY_TYPE_JOIN:
133 * Distribute the notify to local clients on the channel
135 SILC_LOG_DEBUG(("JOIN notify"));
138 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
141 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
145 /* Get channel entry */
146 channel = silc_idlist_find_channel_by_id(server->global_list,
149 channel = silc_idlist_find_channel_by_id(server->local_list,
152 silc_free(channel_id);
156 silc_free(channel_id);
159 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
162 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
166 /* If the the client is not in local list we check global list (ie. the
167 channel will be global channel) and if it does not exist then create
168 entry for the client. */
169 client = silc_idlist_find_client_by_id(server->global_list,
170 client_id, server->server_type,
173 client = silc_idlist_find_client_by_id(server->local_list,
174 client_id, server->server_type,
177 /* If router did not find the client the it is bogus */
178 if (server->server_type != SILC_SERVER)
182 silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
183 silc_id_dup(client_id, SILC_ID_CLIENT),
184 sock->user_data, NULL, 0);
186 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
187 silc_free(client_id);
191 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
195 /* Do not process the notify if the client is not registered */
196 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
199 /* Do not add client to channel if it is there already */
200 if (silc_server_client_on_channel(client, channel, NULL)) {
201 SILC_LOG_DEBUG(("Client already on channel"));
205 /* Send to channel */
206 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
207 FALSE, packet->buffer->data,
208 packet->buffer->len, FALSE);
210 if (server->server_type != SILC_ROUTER &&
211 sock->type == SILC_SOCKET_TYPE_ROUTER)
212 /* The channel is global now */
213 channel->global_users = TRUE;
215 SILC_LOG_DEBUG(("Joining to channel %s", channel->channel_name));
217 /* JOIN the global client to the channel (local clients (if router
218 created the channel) is joined in the pending JOIN command). */
219 chl = silc_calloc(1, sizeof(*chl));
220 chl->client = client;
221 chl->channel = channel;
223 /* If this is the first one on the channel then it is the founder of
225 if (!silc_hash_table_count(channel->user_list))
226 chl->mode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
228 silc_hash_table_add(channel->user_list, client, chl);
229 silc_hash_table_add(client->channels, channel, chl);
230 silc_free(client_id);
231 channel->user_count++;
235 case SILC_NOTIFY_TYPE_LEAVE:
237 * Distribute the notify to local clients on the channel
239 SILC_LOG_DEBUG(("LEAVE notify"));
242 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
243 packet->dst_id_type);
248 /* Get channel entry */
249 channel = silc_idlist_find_channel_by_id(server->global_list,
252 channel = silc_idlist_find_channel_by_id(server->local_list,
255 silc_free(channel_id);
261 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
263 silc_free(channel_id);
266 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
268 silc_free(channel_id);
272 /* Get client entry */
273 client = silc_idlist_find_client_by_id(server->global_list,
274 client_id, TRUE, NULL);
276 client = silc_idlist_find_client_by_id(server->local_list,
277 client_id, TRUE, NULL);
279 silc_free(client_id);
280 silc_free(channel_id);
284 silc_free(client_id);
286 /* Check if on channel */
287 if (!silc_server_client_on_channel(client, channel, NULL))
290 /* Send the leave notify to channel */
291 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
292 FALSE, packet->buffer->data,
293 packet->buffer->len, FALSE);
295 /* Remove the user from channel */
296 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
299 case SILC_NOTIFY_TYPE_SIGNOFF:
301 * Distribute the notify to local clients on the channel
303 SILC_LOG_DEBUG(("SIGNOFF notify"));
306 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
309 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
313 /* Get client entry */
314 client = silc_idlist_find_client_by_id(server->global_list,
315 client_id, TRUE, &cache);
317 client = silc_idlist_find_client_by_id(server->local_list,
318 client_id, TRUE, &cache);
320 silc_free(client_id);
324 silc_free(client_id);
326 /* Get signoff message */
327 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
331 /* Update statistics */
332 server->stat.clients--;
333 if (server->stat.cell_clients)
334 server->stat.cell_clients--;
335 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
336 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
338 /* Remove the client from all channels. */
339 silc_server_remove_from_channels(server, NULL, client, TRUE, tmp, FALSE);
341 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
342 cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
345 case SILC_NOTIFY_TYPE_TOPIC_SET:
347 * Distribute the notify to local clients on the channel
350 SILC_LOG_DEBUG(("TOPIC SET notify"));
353 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
356 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
360 /* Get client entry */
361 client = silc_idlist_find_client_by_id(server->global_list,
362 client_id, TRUE, &cache);
364 client = silc_idlist_find_client_by_id(server->local_list,
365 client_id, TRUE, &cache);
367 silc_free(client_id);
371 silc_free(client_id);
374 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
376 silc_free(channel_id);
381 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
382 packet->dst_id_type);
387 /* Get channel entry */
388 channel = silc_idlist_find_channel_by_id(server->global_list,
391 channel = silc_idlist_find_channel_by_id(server->local_list,
394 silc_free(channel_id);
399 if (channel->topic && !strcmp(channel->topic, tmp))
402 /* Get user's channel entry and check that topic set is allowed. */
403 if (!silc_server_client_on_channel(client, channel, &chl))
405 if (chl->mode == SILC_CHANNEL_UMODE_NONE &&
406 channel->mode & SILC_CHANNEL_MODE_TOPIC) {
407 SILC_LOG_DEBUG(("Topic change is not allowed"));
411 /* Change the topic */
412 silc_free(channel->topic);
413 channel->topic = strdup(tmp);
415 /* Send the same notify to the channel */
416 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
417 FALSE, packet->buffer->data,
418 packet->buffer->len, FALSE);
419 silc_free(channel_id);
422 case SILC_NOTIFY_TYPE_NICK_CHANGE:
425 * Distribute the notify to local clients on the channel
427 unsigned char *id, *id2;
429 SilcUInt32 nickname_len;
431 SILC_LOG_DEBUG(("NICK CHANGE notify"));
433 /* Get old client ID */
434 id = silc_argument_get_arg_type(args, 1, &tmp_len);
437 client_id = silc_id_payload_parse_id(id, tmp_len, NULL);
441 /* Get new client ID */
442 id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
445 client_id2 = silc_id_payload_parse_id(id2, tmp_len, NULL);
449 SILC_LOG_DEBUG(("Old Client ID id(%s)",
450 silc_id_render(client_id, SILC_ID_CLIENT)));
451 SILC_LOG_DEBUG(("New Client ID id(%s)",
452 silc_id_render(client_id2, SILC_ID_CLIENT)));
454 /* From protocol version 1.1 we also get the new nickname */
455 nickname = silc_argument_get_arg_type(args, 3, &nickname_len);;
457 /* Replace the Client ID */
458 client = silc_idlist_replace_client_id(server->global_list, client_id,
459 client_id2, nickname);
461 client = silc_idlist_replace_client_id(server->local_list, client_id,
462 client_id2, nickname);
465 /* Send the NICK_CHANGE notify type to local clients on the channels
466 this client is joined to. */
467 silc_server_send_notify_on_channels(server, NULL, client,
468 SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
469 id, tmp_len, id2, tmp_len,
474 silc_free(client_id);
476 silc_free(client_id2);
480 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
482 * Distribute the notify to local clients on the channel
485 SILC_LOG_DEBUG(("CMODE CHANGE notify"));
488 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
491 client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
495 /* Get client entry */
496 if (id_type == SILC_ID_CLIENT) {
497 client = silc_idlist_find_client_by_id(server->global_list,
498 client_id, TRUE, &cache);
500 client = silc_idlist_find_client_by_id(server->local_list,
501 client_id, TRUE, &cache);
503 silc_free(client_id);
507 silc_free(client_id);
511 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
512 packet->dst_id_type);
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_free(channel_id);
528 silc_free(channel_id);
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)
540 /* Get user's channel entry and check that mode change is allowed */
542 if (!silc_server_client_on_channel(client, channel, &chl))
544 if (!silc_server_check_cmode_rights(server, channel, chl, mode)) {
545 SILC_LOG_DEBUG(("CMODE change is not allowed"));
550 /* Send the same notify to the channel */
551 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
552 FALSE, packet->buffer->data,
553 packet->buffer->len, FALSE);
555 /* If the channel had private keys set and the mode was removed then
556 we must re-generate and re-distribute a new channel key */
557 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY &&
558 !(mode & SILC_CHANNEL_MODE_PRIVKEY)) {
559 /* Re-generate channel key */
560 if (!silc_server_create_channel_key(server, channel, 0))
563 /* Send the channel key. This sends it to our local clients and if
564 we are normal server to our router as well. */
565 silc_server_send_channel_key(server, NULL, channel,
566 server->server_type == SILC_ROUTER ?
567 FALSE : !server->standalone);
571 channel->mode = mode;
574 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
576 unsigned char hash[32];
579 silc_hmac_free(channel->hmac);
580 if (!silc_hmac_alloc(tmp, NULL, &channel->hmac))
583 /* Set the HMAC key out of current channel key. The client must do
585 silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key,
586 channel->key_len / 8,
588 silc_hmac_set_key(channel->hmac, hash,
589 silc_hash_len(silc_hmac_get_hash(channel->hmac)));
590 memset(hash, 0, sizeof(hash));
593 /* Get the passphrase */
594 tmp = silc_argument_get_arg_type(args, 5, &tmp_len);
596 silc_free(channel->passphrase);
597 channel->passphrase = silc_memdup(tmp, tmp_len);
602 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
605 * Distribute the notify to local clients on the channel
607 SilcChannelClientEntry chl2 = NULL;
608 bool notify_sent = FALSE;
610 SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
613 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
616 client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
620 /* Get client entry */
621 if (id_type == SILC_ID_CLIENT) {
622 client = silc_idlist_find_client_by_id(server->global_list,
623 client_id, TRUE, &cache);
625 client = silc_idlist_find_client_by_id(server->local_list,
626 client_id, TRUE, &cache);
628 silc_free(client_id);
632 silc_free(client_id);
636 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
637 packet->dst_id_type);
642 /* Get channel entry */
643 channel = silc_idlist_find_channel_by_id(server->global_list,
646 channel = silc_idlist_find_channel_by_id(server->local_list,
649 silc_free(channel_id);
655 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
657 silc_free(channel_id);
661 SILC_GET32_MSB(mode, tmp);
663 /* Get target client */
664 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
667 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
671 /* Get client entry */
672 client2 = silc_idlist_find_client_by_id(server->global_list,
673 client_id, TRUE, NULL);
675 client2 = silc_idlist_find_client_by_id(server->local_list,
676 client_id, TRUE, NULL);
678 silc_free(client_id);
682 silc_free(client_id);
685 /* Check that sender is on channel */
686 if (!silc_server_client_on_channel(client, channel, &chl))
689 if (client != client2) {
690 /* Sender must be operator */
691 if (chl->mode == SILC_CHANNEL_UMODE_NONE) {
692 SILC_LOG_DEBUG(("CUMODE change is not allowed"));
696 /* Check that target is on channel */
697 if (!silc_server_client_on_channel(client2, channel, &chl))
700 /* If target is founder mode change is not allowed. */
701 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
702 SILC_LOG_DEBUG(("CUMODE change is not allowed"));
708 /* Get entry to the channel user list */
709 silc_hash_table_list(channel->user_list, &htl);
710 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
711 /* If the mode is channel founder and we already find a client
712 to have that mode on the channel we will enforce the sender
713 to change the channel founder mode away. There can be only one
714 channel founder on the channel. */
715 if (server->server_type == SILC_ROUTER &&
716 mode & SILC_CHANNEL_UMODE_CHANFO &&
717 chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
719 unsigned char cumode[4];
721 if (chl->client == client && chl->mode == mode) {
726 mode &= ~SILC_CHANNEL_UMODE_CHANFO;
727 silc_server_send_notify_cumode(server, sock, FALSE, channel, mode,
728 client2->id, SILC_ID_CLIENT,
731 idp = silc_id_payload_encode(client2->id, SILC_ID_CLIENT);
732 SILC_PUT32_MSB(mode, cumode);
733 silc_server_send_notify_to_channel(server, sock, channel, FALSE,
734 SILC_NOTIFY_TYPE_CUMODE_CHANGE,
735 3, idp->data, idp->len,
737 idp->data, idp->len);
738 silc_buffer_free(idp);
741 /* Force the mode change if we alredy set the mode */
744 silc_free(channel_id);
745 silc_hash_table_list_reset(&htl);
750 if (chl->client == client2) {
751 if (chl->mode == mode) {
756 SILC_LOG_DEBUG(("Changing the channel user mode"));
758 /* Change the mode */
760 if (!(mode & SILC_CHANNEL_UMODE_CHANFO))
766 silc_hash_table_list_reset(&htl);
768 /* Send the same notify to the channel */
770 silc_server_packet_send_to_channel(server, sock, channel,
772 FALSE, packet->buffer->data,
773 packet->buffer->len, FALSE);
775 silc_free(channel_id);
779 case SILC_NOTIFY_TYPE_INVITE:
781 if (packet->dst_id_type == SILC_ID_CLIENT)
784 SILC_LOG_DEBUG(("INVITE notify"));
787 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
790 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
794 /* Get channel entry */
795 channel = silc_idlist_find_channel_by_id(server->global_list,
798 channel = silc_idlist_find_channel_by_id(server->local_list,
801 silc_free(channel_id);
805 silc_free(channel_id);
808 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
811 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
815 /* Get client entry */
816 client = silc_idlist_find_client_by_id(server->global_list,
817 client_id, TRUE, &cache);
819 client = silc_idlist_find_client_by_id(server->local_list,
820 client_id, TRUE, &cache);
822 silc_free(client_id);
826 silc_free(client_id);
828 /* Get user's channel entry and check that inviting is allowed. */
829 if (!silc_server_client_on_channel(client, channel, &chl))
831 if (chl->mode == SILC_CHANNEL_UMODE_NONE &&
832 channel->mode & SILC_CHANNEL_MODE_INVITE) {
833 SILC_LOG_DEBUG(("Inviting is not allowed"));
837 /* Get the added invite */
838 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
840 if (!channel->invite_list)
841 channel->invite_list = silc_calloc(tmp_len + 2,
842 sizeof(*channel->invite_list));
844 channel->invite_list = silc_realloc(channel->invite_list,
845 sizeof(*channel->invite_list) *
847 strlen(channel->invite_list) +
849 if (tmp[tmp_len - 1] == ',')
850 tmp[tmp_len - 1] = '\0';
852 strncat(channel->invite_list, tmp, tmp_len);
853 strncat(channel->invite_list, ",", 1);
856 /* Get the deleted invite */
857 tmp = silc_argument_get_arg_type(args, 5, &tmp_len);
858 if (tmp && channel->invite_list) {
859 char *start, *end, *n;
861 if (!strncmp(channel->invite_list, tmp,
862 strlen(channel->invite_list) - 1)) {
863 silc_free(channel->invite_list);
864 channel->invite_list = NULL;
866 start = strstr(channel->invite_list, tmp);
867 if (start && strlen(start) >= tmp_len) {
868 end = start + tmp_len;
869 n = silc_calloc(strlen(channel->invite_list) - tmp_len, sizeof(*n));
870 strncat(n, channel->invite_list, start - channel->invite_list);
871 strncat(n, end + 1, ((channel->invite_list +
872 strlen(channel->invite_list)) - end) - 1);
873 silc_free(channel->invite_list);
874 channel->invite_list = n;
881 case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
883 * Distribute to the local clients on the channel and change the
887 SILC_LOG_DEBUG(("CHANNEL CHANGE"));
889 if (sock->type != SILC_SOCKET_TYPE_ROUTER)
892 /* Get the old Channel ID */
893 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
896 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
900 /* Get the channel entry */
901 channel = silc_idlist_find_channel_by_id(server->local_list,
904 channel = silc_idlist_find_channel_by_id(server->global_list,
907 silc_free(channel_id);
912 /* Send the notify to the channel */
913 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
914 FALSE, packet->buffer->data,
915 packet->buffer->len, FALSE);
917 /* Get the new Channel ID */
918 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
921 channel_id2 = silc_id_payload_parse_id(tmp, tmp_len, NULL);
925 SILC_LOG_DEBUG(("Old Channel ID id(%s)",
926 silc_id_render(channel_id, SILC_ID_CHANNEL)));
927 SILC_LOG_DEBUG(("New Channel ID id(%s)",
928 silc_id_render(channel_id2, SILC_ID_CHANNEL)));
930 /* Replace the Channel ID */
931 if (!silc_idlist_replace_channel_id(server->local_list, channel_id,
933 if (!silc_idlist_replace_channel_id(server->global_list, channel_id,
935 silc_free(channel_id2);
940 SilcBuffer users = NULL, users_modes = NULL;
942 /* Re-announce this channel which ID was changed. */
943 silc_server_send_new_channel(server, sock, FALSE, channel->channel_name,
945 silc_id_get_len(channel->id,
949 /* Re-announce our clients on the channel as the ID has changed now */
950 silc_server_announce_get_channel_users(server, channel, &users,
953 silc_buffer_push(users, users->data - users->head);
954 silc_server_packet_send(server, sock,
955 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
956 users->data, users->len, FALSE);
957 silc_buffer_free(users);
960 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
961 silc_server_packet_send_dest(server, sock,
962 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
963 channel->id, SILC_ID_CHANNEL,
965 users_modes->len, FALSE);
966 silc_buffer_free(users_modes);
969 /* Re-announce channel's topic */
970 if (channel->topic) {
971 silc_server_send_notify_topic_set(server, sock,
972 server->server_type == SILC_ROUTER ?
973 TRUE : FALSE, channel,
974 channel->id, SILC_ID_CHANNEL,
979 silc_free(channel_id);
983 case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
985 * Remove the server entry and all clients that this server owns.
988 SILC_LOG_DEBUG(("SERVER SIGNOFF notify"));
991 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
994 server_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
998 /* Get server entry */
999 server_entry = silc_idlist_find_server_by_id(server->global_list,
1000 server_id, TRUE, NULL);
1002 if (!server_entry) {
1003 server_entry = silc_idlist_find_server_by_id(server->local_list,
1004 server_id, TRUE, NULL);
1006 if (!server_entry) {
1007 /* If we are normal server then we might not have the server. Check
1008 whether router was kind enough to send the list of all clients
1009 that actually was to be removed. Remove them if the list is
1011 if (server->server_type != SILC_ROUTER &&
1012 silc_argument_get_arg_num(args) > 1) {
1015 for (i = 1; i < silc_argument_get_arg_num(args); i++) {
1017 tmp = silc_argument_get_arg_type(args, i + 1, &tmp_len);
1020 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1024 /* Get client entry */
1025 client = silc_idlist_find_client_by_id(server->global_list,
1026 client_id, TRUE, &cache);
1029 client = silc_idlist_find_client_by_id(server->local_list,
1030 client_id, TRUE, &cache);
1033 silc_free(client_id);
1037 silc_free(client_id);
1039 /* Update statistics */
1040 server->stat.clients--;
1041 if (server->stat.cell_clients)
1042 server->stat.cell_clients--;
1043 SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
1044 SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
1046 /* Remove the client from all channels. */
1047 silc_server_remove_from_channels(server, NULL, client,
1050 /* Remove the client */
1051 silc_idlist_del_client(local ? server->local_list :
1052 server->global_list, client);
1056 silc_free(server_id);
1060 silc_free(server_id);
1062 /* Free all client entries that this server owns as they will
1063 become invalid now as well. */
1064 silc_server_remove_clients_by_server(server, server_entry, TRUE);
1066 /* Remove the server entry */
1067 silc_idlist_del_server(local ? server->local_list :
1068 server->global_list, server_entry);
1070 /* XXX update statistics */
1074 case SILC_NOTIFY_TYPE_KICKED:
1076 * Distribute the notify to local clients on the channel
1079 SILC_LOG_DEBUG(("KICKED notify"));
1082 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
1083 packet->dst_id_type);
1088 /* Get channel entry */
1089 channel = silc_idlist_find_channel_by_id(server->global_list,
1092 channel = silc_idlist_find_channel_by_id(server->local_list,
1095 silc_free(channel_id);
1099 silc_free(channel_id);
1102 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1105 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1109 /* If the the client is not in local list we check global list */
1110 client = silc_idlist_find_client_by_id(server->global_list,
1111 client_id, TRUE, NULL);
1113 client = silc_idlist_find_client_by_id(server->local_list,
1114 client_id, TRUE, NULL);
1116 silc_free(client_id);
1120 silc_free(client_id);
1122 /* If target is founder they cannot be kicked */
1123 if (!silc_server_client_on_channel(client, channel, &chl))
1125 if (chl->mode & SILC_CHANNEL_UMODE_CHANFO)
1128 /* From protocol version 1.1 we get the kicker's ID as well. */
1129 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1131 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1135 /* If the the client is not in local list we check global list */
1136 client2 = silc_idlist_find_client_by_id(server->global_list,
1137 client_id, TRUE, NULL);
1139 client2 = silc_idlist_find_client_by_id(server->local_list,
1140 client_id, TRUE, NULL);
1142 silc_free(client_id);
1146 silc_free(client_id);
1148 /* Kicker must be operator on channel */
1149 if (!silc_server_client_on_channel(client2, channel, &chl))
1151 if (chl->mode == SILC_CHANNEL_UMODE_NONE) {
1152 SILC_LOG_DEBUG(("Kicking is not allowed"));
1157 /* Send to channel */
1158 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
1159 FALSE, packet->buffer->data,
1160 packet->buffer->len, FALSE);
1162 /* Remove the client from channel */
1163 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
1167 case SILC_NOTIFY_TYPE_KILLED:
1170 * Distribute the notify to local clients on channels
1172 unsigned char *id, *comment;
1173 SilcUInt32 id_len, comment_len;
1175 SILC_LOG_DEBUG(("KILLED notify"));
1178 id = silc_argument_get_arg_type(args, 1, &id_len);
1181 client_id = silc_id_payload_parse_id(id, id_len, NULL);
1185 /* If the the client is not in local list we check global list */
1186 client = silc_idlist_find_client_by_id(server->global_list,
1187 client_id, TRUE, NULL);
1189 client = silc_idlist_find_client_by_id(server->local_list,
1190 client_id, TRUE, NULL);
1192 silc_free(client_id);
1196 silc_free(client_id);
1198 /* If the client is one of ours, then close the connection to the
1199 client now. This removes the client from all channels as well. */
1200 if (packet->dst_id_type == SILC_ID_CLIENT && client->connection) {
1201 sock = client->connection;
1202 silc_server_free_client_data(server, NULL, client, FALSE, NULL);
1203 silc_server_close_connection(server, sock);
1208 comment = silc_argument_get_arg_type(args, 2, &comment_len);
1209 if (comment_len > 128)
1212 /* From protocol version 1.1 we get the killer's ID as well. */
1213 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1215 client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
1219 if (id_type == SILC_ID_CLIENT) {
1220 /* If the the client is not in local list we check global list */
1221 client2 = silc_idlist_find_client_by_id(server->global_list,
1222 client_id, TRUE, NULL);
1224 client2 = silc_idlist_find_client_by_id(server->local_list,
1225 client_id, TRUE, NULL);
1227 silc_free(client_id);
1231 silc_free(client_id);
1233 /* Killer must be router operator */
1234 if (!(client2->mode & SILC_UMODE_ROUTER_OPERATOR)) {
1235 SILC_LOG_DEBUG(("Killing is not allowed"));
1241 /* Send the notify to local clients on the channels except to the
1242 client who is killed. */
1243 silc_server_send_notify_on_channels(server, client, client,
1244 SILC_NOTIFY_TYPE_KILLED, 3,
1245 id, id_len, comment, comment_len,
1248 /* Remove the client from all channels */
1249 silc_server_remove_from_channels(server, NULL, client, FALSE, NULL,
1255 case SILC_NOTIFY_TYPE_UMODE_CHANGE:
1257 * Save the mode of the client.
1260 SILC_LOG_DEBUG(("UMODE_CHANGE notify"));
1263 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1266 client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1270 /* Get client entry */
1271 client = silc_idlist_find_client_by_id(server->global_list,
1272 client_id, TRUE, NULL);
1274 client = silc_idlist_find_client_by_id(server->local_list,
1275 client_id, TRUE, NULL);
1277 silc_free(client_id);
1281 silc_free(client_id);
1284 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1287 SILC_GET32_MSB(mode, tmp);
1289 /* Check that mode changing is allowed. */
1290 if (!silc_server_check_umode_rights(server, client, mode)) {
1291 SILC_LOG_DEBUG(("UMODE change is not allowed"));
1295 /* Remove internal resumed flag if client is marked detached now */
1296 if (mode & SILC_UMODE_DETACHED)
1297 client->data.status &= ~SILC_IDLIST_STATUS_RESUMED;
1299 /* Change the mode */
1300 client->mode = mode;
1304 case SILC_NOTIFY_TYPE_BAN:
1309 SILC_LOG_DEBUG(("BAN notify"));
1311 /* Get Channel ID */
1312 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1315 channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
1319 /* Get channel entry */
1320 channel = silc_idlist_find_channel_by_id(server->global_list,
1323 channel = silc_idlist_find_channel_by_id(server->local_list,
1326 silc_free(channel_id);
1330 silc_free(channel_id);
1332 /* Get the new ban and add it to the ban list */
1333 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1335 if (!channel->ban_list)
1336 channel->ban_list = silc_calloc(tmp_len + 2,
1337 sizeof(*channel->ban_list));
1339 channel->ban_list = silc_realloc(channel->ban_list,
1340 sizeof(*channel->ban_list) *
1342 strlen(channel->ban_list) + 2));
1343 strncat(channel->ban_list, tmp, tmp_len);
1344 strncat(channel->ban_list, ",", 1);
1347 /* Get the ban to be removed and remove it from the list */
1348 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1349 if (tmp && channel->ban_list) {
1350 char *start, *end, *n;
1352 if (!strncmp(channel->ban_list, tmp, strlen(channel->ban_list) - 1)) {
1353 silc_free(channel->ban_list);
1354 channel->ban_list = NULL;
1356 start = strstr(channel->ban_list, tmp);
1357 if (start && strlen(start) >= tmp_len) {
1358 end = start + tmp_len;
1359 n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
1360 strncat(n, channel->ban_list, start - channel->ban_list);
1361 strncat(n, end + 1, ((channel->ban_list +
1362 strlen(channel->ban_list)) - end) - 1);
1363 silc_free(channel->ban_list);
1364 channel->ban_list = n;
1370 /* Ignore rest of the notify types for now */
1371 case SILC_NOTIFY_TYPE_NONE:
1372 case SILC_NOTIFY_TYPE_MOTD:
1379 silc_notify_payload_free(payload);
1382 void silc_server_notify_list(SilcServer server,
1383 SilcSocketConnection sock,
1384 SilcPacketContext *packet)
1386 SilcPacketContext *new;
1390 SILC_LOG_DEBUG(("Processing Notify List"));
1392 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1393 packet->src_id_type != SILC_ID_SERVER)
1396 /* Make copy of the original packet context, except for the actual
1397 data buffer, which we will here now fetch from the original buffer. */
1398 new = silc_packet_context_alloc();
1399 new->type = SILC_PACKET_NOTIFY;
1400 new->flags = packet->flags;
1401 new->src_id = packet->src_id;
1402 new->src_id_len = packet->src_id_len;
1403 new->src_id_type = packet->src_id_type;
1404 new->dst_id = packet->dst_id;
1405 new->dst_id_len = packet->dst_id_len;
1406 new->dst_id_type = packet->dst_id_type;
1408 buffer = silc_buffer_alloc(1024);
1409 new->buffer = buffer;
1411 while (packet->buffer->len) {
1412 SILC_GET16_MSB(len, packet->buffer->data + 2);
1413 if (len > packet->buffer->len)
1416 if (len > buffer->truelen) {
1417 silc_buffer_free(buffer);
1418 buffer = silc_buffer_alloc(1024 + len);
1421 silc_buffer_pull_tail(buffer, len);
1422 silc_buffer_put(buffer, packet->buffer->data, len);
1424 /* Process the Notify */
1425 silc_server_notify(server, sock, new);
1427 silc_buffer_push_tail(buffer, len);
1428 silc_buffer_pull(packet->buffer, len);
1431 silc_buffer_free(buffer);
1435 /* Received private message. This resolves the destination of the message
1436 and sends the packet. This is used by both server and router. If the
1437 destination is our locally connected client this sends the packet to
1438 the client. This may also send the message for further routing if
1439 the destination is not in our server (or router). */
1441 void silc_server_private_message(SilcServer server,
1442 SilcSocketConnection sock,
1443 SilcPacketContext *packet)
1445 SilcSocketConnection dst_sock;
1446 SilcIDListData idata;
1447 SilcClientEntry client;
1449 SILC_LOG_DEBUG(("Start"));
1451 if (packet->src_id_type != SILC_ID_CLIENT ||
1452 packet->dst_id_type != SILC_ID_CLIENT || !packet->dst_id)
1455 /* Get the route to the client */
1456 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1457 packet->dst_id_len, NULL,
1462 if (client && client->mode & SILC_UMODE_DETACHED) {
1463 SILC_LOG_DEBUG(("Locally connected client is detached, "
1464 "discarding packet"));
1468 /* Send IDENTIFY command reply with error status to indicate that
1469 such destination ID does not exist or is invalid */
1470 idp = silc_id_payload_encode_data(packet->dst_id,
1472 packet->dst_id_type);
1476 if (packet->src_id_type == SILC_ID_CLIENT) {
1477 SilcClientID *client_id = silc_id_str2id(packet->src_id,
1479 packet->src_id_type);
1480 silc_server_send_dest_command_reply(server, sock,
1481 client_id, SILC_ID_CLIENT,
1482 SILC_COMMAND_IDENTIFY,
1483 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
1484 0, 0, 1, 2, idp->data, idp->len);
1485 silc_free(client_id);
1487 silc_server_send_command_reply(server, sock, SILC_COMMAND_IDENTIFY,
1488 SILC_STATUS_ERR_NO_SUCH_CLIENT_ID, 0,
1489 0, 1, 2, idp->data, idp->len);
1492 silc_buffer_free(idp);
1496 /* Check whether destination client wishes to receive private messages */
1497 if (client && !(packet->flags & SILC_PACKET_FLAG_PRIVMSG_KEY) &&
1498 client->mode & SILC_UMODE_BLOCK_PRIVMSG) {
1499 SILC_LOG_DEBUG(("Client blocks private messages, discarding packet"));
1503 /* Send the private message */
1504 silc_server_send_private_message(server, dst_sock, idata->send_key,
1505 idata->hmac_send, idata->psn_send++,
1509 /* Received private message key packet.. This packet is never for us. It is to
1510 the client in the packet's destination ID. Sending of this sort of packet
1511 equals sending private message, ie. it is sent point to point from
1512 one client to another. */
1514 void silc_server_private_message_key(SilcServer server,
1515 SilcSocketConnection sock,
1516 SilcPacketContext *packet)
1518 SilcSocketConnection dst_sock;
1519 SilcIDListData idata;
1521 SILC_LOG_DEBUG(("Start"));
1523 if (packet->src_id_type != SILC_ID_CLIENT ||
1524 packet->dst_id_type != SILC_ID_CLIENT)
1527 if (!packet->dst_id)
1530 /* Get the route to the client */
1531 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1532 packet->dst_id_len, NULL,
1537 /* Relay the packet */
1538 silc_server_relay_packet(server, dst_sock, idata->send_key,
1539 idata->hmac_send, idata->psn_send++, packet, FALSE);
1542 /* Processes incoming command reply packet. The command reply packet may
1543 be destined to one of our clients or it may directly for us. We will
1544 call the command reply routine after processing the packet. */
1546 void silc_server_command_reply(SilcServer server,
1547 SilcSocketConnection sock,
1548 SilcPacketContext *packet)
1550 SilcBuffer buffer = packet->buffer;
1551 SilcClientEntry client = NULL;
1552 SilcSocketConnection dst_sock;
1553 SilcIDListData idata;
1554 SilcClientID *id = NULL;
1556 SILC_LOG_DEBUG(("Start"));
1558 /* Source must be server or router */
1559 if (packet->src_id_type != SILC_ID_SERVER &&
1560 sock->type != SILC_SOCKET_TYPE_ROUTER)
1563 if (packet->dst_id_type == SILC_ID_CHANNEL)
1566 if (packet->dst_id_type == SILC_ID_CLIENT) {
1567 /* Destination must be one of ours */
1568 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
1571 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
1573 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
1579 if (packet->dst_id_type == SILC_ID_SERVER) {
1580 /* For now this must be for us */
1581 if (memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
1582 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
1587 /* Execute command reply locally for the command */
1588 silc_server_command_reply_process(server, sock, buffer);
1590 if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
1591 /* Relay the packet to the client */
1592 const SilcBufferStruct p;
1594 dst_sock = (SilcSocketConnection)client->connection;
1595 idata = (SilcIDListData)client;
1597 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
1598 + packet->dst_id_len + packet->padlen);
1599 if (!silc_packet_send_prepare(dst_sock, 0, 0, buffer->len,
1600 idata->hmac_send, (const SilcBuffer)&p)) {
1601 SILC_LOG_ERROR(("Cannot send packet"));
1604 silc_buffer_put((SilcBuffer)&p, buffer->data, buffer->len);
1606 /* Encrypt packet */
1607 silc_packet_encrypt(idata->send_key, idata->hmac_send, idata->psn_send++,
1608 (SilcBuffer)&p, buffer->len);
1610 /* Send the packet */
1611 silc_server_packet_send_real(server, dst_sock, TRUE);
1617 /* Process received channel message. The message can be originated from
1618 client or server. */
1620 void silc_server_channel_message(SilcServer server,
1621 SilcSocketConnection sock,
1622 SilcPacketContext *packet)
1624 SilcChannelEntry channel = NULL;
1625 SilcChannelID *id = NULL;
1626 void *sender_id = NULL;
1627 SilcClientEntry sender_entry = NULL;
1628 SilcChannelClientEntry chl;
1631 SILC_LOG_DEBUG(("Processing channel message"));
1634 if (packet->dst_id_type != SILC_ID_CHANNEL) {
1635 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1639 /* Find channel entry */
1640 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
1643 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
1645 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
1647 SILC_LOG_DEBUG(("Could not find channel"));
1652 /* See that this client is on the channel. If the original sender is
1653 not client (as it can be server as well) we don't do the check. */
1654 sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1655 packet->src_id_type);
1658 if (packet->src_id_type == SILC_ID_CLIENT) {
1659 sender_entry = silc_idlist_find_client_by_id(server->local_list,
1660 sender_id, TRUE, NULL);
1661 if (!sender_entry) {
1663 sender_entry = silc_idlist_find_client_by_id(server->global_list,
1664 sender_id, TRUE, NULL);
1666 if (!sender_entry || !silc_server_client_on_channel(sender_entry,
1668 SILC_LOG_DEBUG(("Client not on channel"));
1672 /* If channel is moderated check that client is allowed to send
1674 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS && !chl->mode) {
1675 SILC_LOG_DEBUG(("Channel is silenced from normal users"));
1678 if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS &&
1679 chl->mode & SILC_CHANNEL_UMODE_CHANOP &&
1680 !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
1681 SILC_LOG_DEBUG(("Channel is silenced from operators"));
1685 /* If the packet is coming from router, but the client entry is local
1686 entry to us then some router is rerouting this to us and it is not
1687 allowed. When the client is local to us it means that we've routed
1688 this packet to network, and now someone is routing it back to us. */
1689 if (server->server_type == SILC_ROUTER &&
1690 sock->type == SILC_SOCKET_TYPE_ROUTER && local) {
1691 SILC_LOG_DEBUG(("Channel message rerouted to the sender, drop it"));
1696 /* Distribute the packet to our local clients. This will send the
1697 packet for further routing as well, if needed. */
1698 silc_server_packet_relay_to_channel(server, sock, channel, sender_id,
1699 packet->src_id_type, sender_entry,
1700 packet->buffer->data,
1701 packet->buffer->len, FALSE);
1704 silc_free(sender_id);
1708 /* Received channel key packet. We distribute the key to all of our locally
1709 connected clients on the channel. */
1711 void silc_server_channel_key(SilcServer server,
1712 SilcSocketConnection sock,
1713 SilcPacketContext *packet)
1715 SilcBuffer buffer = packet->buffer;
1716 SilcChannelEntry channel;
1718 if (packet->src_id_type != SILC_ID_SERVER ||
1719 (server->server_type == SILC_ROUTER &&
1720 sock->type == SILC_SOCKET_TYPE_ROUTER))
1723 /* Save the channel key */
1724 channel = silc_server_save_channel_key(server, buffer, NULL);
1728 /* Distribute the key to everybody who is on the channel. If we are router
1729 we will also send it to locally connected servers. */
1730 silc_server_send_channel_key(server, sock, channel, FALSE);
1732 if (server->server_type != SILC_BACKUP_ROUTER) {
1733 /* Distribute to local cell backup routers. */
1734 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
1735 SILC_PACKET_CHANNEL_KEY, 0,
1736 buffer->data, buffer->len, FALSE, TRUE);
1740 /* Received New Client packet and processes it. Creates Client ID for the
1741 client. Client becomes registered after calling this functions. */
1743 SilcClientEntry silc_server_new_client(SilcServer server,
1744 SilcSocketConnection sock,
1745 SilcPacketContext *packet)
1747 SilcBuffer buffer = packet->buffer;
1748 SilcClientEntry client;
1749 SilcClientID *client_id;
1751 SilcIDListData idata;
1752 char *username = NULL, *realname = NULL, *id_string;
1753 SilcUInt16 username_len;
1756 char *hostname, *nickname;
1759 SILC_LOG_DEBUG(("Creating new client"));
1761 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
1764 /* Take client entry */
1765 client = (SilcClientEntry)sock->user_data;
1766 idata = (SilcIDListData)client;
1768 /* Remove the old cache entry. */
1769 if (!silc_idcache_del_by_context(server->local_list->clients, client)) {
1770 SILC_LOG_INFO(("Unauthenticated client attempted to register to network"));
1771 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1772 "You have not been authenticated");
1776 /* Parse incoming packet */
1777 ret = silc_buffer_unformat(buffer,
1778 SILC_STR_UI16_NSTRING_ALLOC(&username,
1780 SILC_STR_UI16_STRING_ALLOC(&realname),
1783 silc_free(username);
1784 silc_free(realname);
1785 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
1786 "connection", sock->hostname, sock->ip));
1787 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1788 "Incomplete client information");
1793 silc_free(username);
1794 silc_free(realname);
1795 SILC_LOG_ERROR(("Client %s (%s) did not send its username, closing "
1796 "connection", sock->hostname, sock->ip));
1797 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1798 "Incomplete client information");
1802 if (username_len > 128)
1803 username[128] = '\0';
1805 /* Check for bad characters for nickname, and modify the nickname if
1806 it includes those. */
1807 if (silc_server_name_bad_chars(username, username_len)) {
1808 nickname = silc_server_name_modify_bad(username, username_len);
1810 nickname = strdup(username);
1813 /* Make sanity checks for the hostname of the client. If the hostname
1814 is provided in the `username' check that it is the same than the
1815 resolved hostname, or if not resolved the hostname that appears in
1816 the client's public key. If the hostname is not present then put
1817 it from the resolved name or from the public key. */
1818 if (strchr(username, '@')) {
1819 SilcPublicKeyIdentifier pident;
1820 int tlen = strcspn(username, "@");
1821 char *phostname = NULL;
1823 hostname = silc_memdup(username + tlen + 1, strlen(username) - tlen - 1);
1825 if (strcmp(sock->hostname, sock->ip) &&
1826 strcmp(sock->hostname, hostname)) {
1827 silc_free(username);
1828 silc_free(hostname);
1829 silc_free(realname);
1830 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
1831 "connection", sock->hostname, sock->ip));
1832 silc_server_disconnect_remote(server, sock,
1833 "Server closed connection: "
1834 "Incomplete client information");
1838 pident = silc_pkcs_decode_identifier(client->data.public_key->identifier);
1840 phostname = strdup(pident->host);
1841 silc_pkcs_free_identifier(pident);
1844 if (!strcmp(sock->hostname, sock->ip) &&
1845 phostname && strcmp(phostname, hostname)) {
1846 silc_free(username);
1847 silc_free(hostname);
1848 silc_free(phostname);
1849 silc_free(realname);
1850 SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing "
1851 "connection", sock->hostname, sock->ip));
1852 silc_server_disconnect_remote(server, sock,
1853 "Server closed connection: "
1854 "Incomplete client information");
1858 silc_free(phostname);
1860 /* The hostname is not present, add it. */
1862 /* XXX For now we cannot take the host name from the public key since
1863 they are not trusted or we cannot verify them as trusted. Just take
1864 what the resolved name or address is. */
1866 if (strcmp(sock->hostname, sock->ip)) {
1868 newusername = silc_calloc(strlen(username) +
1869 strlen(sock->hostname) + 2,
1870 sizeof(*newusername));
1871 strncat(newusername, username, strlen(username));
1872 strncat(newusername, "@", 1);
1873 strncat(newusername, sock->hostname, strlen(sock->hostname));
1874 silc_free(username);
1875 username = newusername;
1878 SilcPublicKeyIdentifier pident =
1879 silc_pkcs_decode_identifier(client->data.public_key->identifier);
1882 newusername = silc_calloc(strlen(username) +
1883 strlen(pident->host) + 2,
1884 sizeof(*newusername));
1885 strncat(newusername, username, strlen(username));
1886 strncat(newusername, "@", 1);
1887 strncat(newusername, pident->host, strlen(pident->host));
1888 silc_free(username);
1889 username = newusername;
1890 silc_pkcs_free_identifier(pident);
1896 /* Create Client ID */
1897 while (!silc_id_create_client_id(server, server->id, server->rng,
1898 server->md5hash, nickname, &client_id)) {
1901 silc_server_disconnect_remote(server, sock,
1902 "Server closed connection: Bad nickname");
1905 snprintf(&nickname[strlen(nickname) - 1], 1, "%d", nickfail);
1908 /* Update client entry */
1909 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
1910 client->nickname = nickname;
1911 client->username = username;
1912 client->userinfo = realname ? realname : strdup(" ");
1913 client->id = client_id;
1914 id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
1916 /* Add the client again to the ID cache */
1917 silc_idcache_add(server->local_list->clients, client->nickname,
1918 client_id, client, 0, NULL);
1920 /* Notify our router about new client on the SILC network */
1921 if (!server->standalone)
1922 silc_server_send_new_id(server, (SilcSocketConnection)
1923 server->router->connection,
1924 server->server_type == SILC_ROUTER ? TRUE : FALSE,
1925 client->id, SILC_ID_CLIENT, id_len);
1927 /* Send the new client ID to the client. */
1928 id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
1929 reply = silc_buffer_alloc_size(2 + 2 + id_len);
1930 silc_buffer_format(reply,
1931 SILC_STR_UI_SHORT(SILC_ID_CLIENT),
1932 SILC_STR_UI_SHORT(id_len),
1933 SILC_STR_UI_XNSTRING(id_string, id_len),
1935 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0,
1936 reply->data, reply->len, FALSE);
1937 silc_free(id_string);
1938 silc_buffer_free(reply);
1940 /* Send some nice info to the client */
1941 silc_server_send_connect_notifys(server, sock, client);
1946 /* Create new server. This processes received New Server packet and
1947 saves the received Server ID. The server is our locally connected
1948 server thus we save all the information and save it to local list.
1949 This funtion can be used by both normal server and router server.
1950 If normal server uses this it means that its router has connected
1951 to the server. If router uses this it means that one of the cell's
1952 servers is connected to the router. */
1954 SilcServerEntry silc_server_new_server(SilcServer server,
1955 SilcSocketConnection sock,
1956 SilcPacketContext *packet)
1958 SilcBuffer buffer = packet->buffer;
1959 SilcServerEntry new_server, server_entry;
1960 SilcServerID *server_id;
1961 SilcIDListData idata;
1962 unsigned char *server_name, *id_string;
1963 SilcUInt16 id_len, name_len;
1967 SILC_LOG_DEBUG(("Creating new server"));
1969 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
1970 sock->type != SILC_SOCKET_TYPE_ROUTER)
1973 /* Take server entry */
1974 new_server = (SilcServerEntry)sock->user_data;
1975 idata = (SilcIDListData)new_server;
1977 /* Remove the old cache entry */
1978 if (!silc_idcache_del_by_context(server->local_list->servers, new_server)) {
1979 if (!silc_idcache_del_by_context(server->global_list->servers,
1981 SILC_LOG_INFO(("Unauthenticated %s attempted to register to "
1982 "network", (sock->type == SILC_SOCKET_TYPE_SERVER ?
1983 "server" : "router")));
1984 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1985 "You have not been authenticated");
1991 /* Parse the incoming packet */
1992 ret = silc_buffer_unformat(buffer,
1993 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
1994 SILC_STR_UI16_NSTRING_ALLOC(&server_name,
1999 silc_free(id_string);
2001 silc_free(server_name);
2005 if (id_len > buffer->len) {
2006 silc_free(id_string);
2007 silc_free(server_name);
2012 server_name[255] = '\0';
2015 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
2017 silc_free(id_string);
2018 silc_free(server_name);
2021 silc_free(id_string);
2023 /* Check for valid server ID */
2024 if (!silc_id_is_valid_server_id(server, server_id, sock)) {
2025 SILC_LOG_INFO(("Invalid server ID sent by %s (%s)",
2026 sock->ip, sock->hostname));
2027 silc_server_disconnect_remote(server, sock, "Server closed connection: "
2028 "Your Server ID is not valid");
2029 silc_free(server_name);
2033 /* Check that we do not have this ID already */
2034 server_entry = silc_idlist_find_server_by_id(server->local_list,
2035 server_id, TRUE, NULL);
2037 silc_idcache_del_by_context(server->local_list->servers, server_entry);
2039 server_entry = silc_idlist_find_server_by_id(server->global_list,
2040 server_id, TRUE, NULL);
2042 silc_idcache_del_by_context(server->global_list->servers, server_entry);
2045 /* Update server entry */
2046 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
2047 new_server->server_name = server_name;
2048 new_server->id = server_id;
2050 SILC_LOG_DEBUG(("New server id(%s)",
2051 silc_id_render(server_id, SILC_ID_SERVER)));
2053 /* Add again the entry to the ID cache. */
2054 silc_idcache_add(local ? server->local_list->servers :
2055 server->global_list->servers, server_name, server_id,
2056 new_server, 0, NULL);
2058 /* Distribute the information about new server in the SILC network
2059 to our router. If we are normal server we won't send anything
2060 since this connection must be our router connection. */
2061 if (server->server_type == SILC_ROUTER && !server->standalone &&
2062 server->router->connection != sock)
2063 silc_server_send_new_id(server, server->router->connection,
2064 TRUE, new_server->id, SILC_ID_SERVER,
2065 silc_id_get_len(server_id, SILC_ID_SERVER));
2067 if (server->server_type == SILC_ROUTER)
2068 server->stat.cell_servers++;
2070 /* Check whether this router connection has been replaced by an
2071 backup router. If it has been then we'll disable the server and will
2072 ignore everything it will send until the backup router resuming
2073 protocol has been completed. */
2074 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
2075 silc_server_backup_replaced_get(server, server_id, NULL)) {
2076 /* Send packet to the server indicating that it cannot use this
2077 connection as it has been replaced by backup router. */
2078 SilcBuffer packet = silc_buffer_alloc(2);
2079 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
2080 silc_buffer_format(packet,
2081 SILC_STR_UI_CHAR(SILC_SERVER_BACKUP_REPLACED),
2082 SILC_STR_UI_CHAR(0),
2084 silc_server_packet_send(server, sock,
2085 SILC_PACKET_RESUME_ROUTER, 0,
2086 packet->data, packet->len, TRUE);
2087 silc_buffer_free(packet);
2089 /* Mark the router disabled. The data sent earlier will go but nothing
2090 after this does not go to this connection. */
2091 idata->status |= SILC_IDLIST_STATUS_DISABLED;
2093 /* If it is router announce our stuff to it. */
2094 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
2095 server->server_type == SILC_ROUTER) {
2096 silc_server_announce_servers(server, FALSE, 0, sock);
2097 silc_server_announce_clients(server, 0, sock);
2098 silc_server_announce_channels(server, 0, sock);
2105 /* Processes incoming New ID packet. New ID Payload is used to distribute
2106 information about newly registered clients and servers. */
2108 static void silc_server_new_id_real(SilcServer server,
2109 SilcSocketConnection sock,
2110 SilcPacketContext *packet,
2113 SilcBuffer buffer = packet->buffer;
2115 SilcServerEntry router, server_entry;
2116 SilcSocketConnection router_sock;
2121 SILC_LOG_DEBUG(("Processing new ID"));
2123 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2124 server->server_type == SILC_SERVER ||
2125 packet->src_id_type != SILC_ID_SERVER)
2128 idp = silc_id_payload_parse(buffer->data, buffer->len);
2132 id_type = silc_id_payload_get_type(idp);
2134 /* Normal server cannot have other normal server connections */
2135 server_entry = (SilcServerEntry)sock->user_data;
2136 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER &&
2137 server_entry->server_type == SILC_SERVER)
2140 id = silc_id_payload_get_id(idp);
2144 /* If the packet is coming from server then use the sender as the
2145 origin of the the packet. If it came from router then check the real
2146 sender of the packet and use that as the origin. */
2147 if (sock->type == SILC_SOCKET_TYPE_SERVER) {
2148 id_list = server->local_list;
2150 router = sock->user_data;
2152 /* If the sender is backup router and ID is server (and we are not
2153 backup router) then switch the entry to global list. */
2154 if (server_entry->server_type == SILC_BACKUP_ROUTER &&
2155 id_type == SILC_ID_SERVER &&
2156 server->id_entry->server_type != SILC_BACKUP_ROUTER) {
2157 id_list = server->global_list;
2158 router_sock = server->router ? server->router->connection : sock;
2161 void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
2162 packet->src_id_type);
2163 router = silc_idlist_find_server_by_id(server->global_list,
2164 sender_id, TRUE, NULL);
2166 router = silc_idlist_find_server_by_id(server->local_list,
2167 sender_id, TRUE, NULL);
2168 silc_free(sender_id);
2170 id_list = server->global_list;
2177 case SILC_ID_CLIENT:
2179 SilcClientEntry entry;
2181 /* Check that we do not have this client already */
2182 entry = silc_idlist_find_client_by_id(server->global_list,
2183 id, server->server_type,
2186 entry = silc_idlist_find_client_by_id(server->local_list,
2187 id, server->server_type,
2190 SILC_LOG_DEBUG(("Ignoring client that we already have"));
2194 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
2195 silc_id_render(id, SILC_ID_CLIENT),
2196 sock->type == SILC_SOCKET_TYPE_SERVER ?
2197 "Server" : "Router", sock->hostname));
2199 /* As a router we keep information of all global information in our
2200 global list. Cell wide information however is kept in the local
2202 entry = silc_idlist_add_client(id_list, NULL, NULL, NULL,
2203 id, router, NULL, 0);
2205 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
2207 /* Inform the sender that the ID is not usable */
2208 silc_server_send_notify_signoff(server, sock, FALSE, id, NULL);
2211 entry->nickname = NULL;
2212 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2214 if (sock->type == SILC_SOCKET_TYPE_SERVER)
2215 server->stat.cell_clients++;
2216 server->stat.clients++;
2220 case SILC_ID_SERVER:
2222 SilcServerEntry entry;
2224 /* If the ID is mine, ignore it. */
2225 if (SILC_ID_SERVER_COMPARE(id, server->id)) {
2226 SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
2230 /* If the ID is the sender's ID, ignore it (we have it already) */
2231 if (SILC_ID_SERVER_COMPARE(id, router->id)) {
2232 SILC_LOG_DEBUG(("Ignoring sender's own ID"));
2236 /* Check that we do not have this server already */
2237 entry = silc_idlist_find_server_by_id(server->global_list,
2238 id, server->server_type,
2241 entry = silc_idlist_find_server_by_id(server->local_list,
2242 id, server->server_type,
2245 SILC_LOG_DEBUG(("Ignoring server that we already have"));
2249 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
2250 silc_id_render(id, SILC_ID_SERVER),
2251 sock->type == SILC_SOCKET_TYPE_SERVER ?
2252 "Server" : "Router", sock->hostname));
2254 /* As a router we keep information of all global information in our
2255 global list. Cell wide information however is kept in the local
2257 entry = silc_idlist_add_server(id_list, NULL, 0, id, router,
2260 SILC_LOG_ERROR(("Could not add new server to the ID Cache"));
2263 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2265 if (sock->type == SILC_SOCKET_TYPE_SERVER)
2266 server->stat.cell_servers++;
2267 server->stat.servers++;
2271 case SILC_ID_CHANNEL:
2272 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
2281 /* If the sender of this packet is server and we are router we need to
2282 broadcast this packet to other routers in the network. */
2283 if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
2284 sock->type == SILC_SOCKET_TYPE_SERVER &&
2285 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2286 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
2287 silc_server_packet_send(server, server->router->connection,
2289 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2290 buffer->data, buffer->len, FALSE);
2291 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
2292 packet->type, packet->flags,
2293 packet->buffer->data, packet->buffer->len,
2298 silc_id_payload_free(idp);
2302 /* Processes incoming New ID packet. New ID Payload is used to distribute
2303 information about newly registered clients and servers. */
2305 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
2306 SilcPacketContext *packet)
2308 silc_server_new_id_real(server, sock, packet, TRUE);
2311 /* Receoved New Id List packet, list of New ID payloads inside one
2312 packet. Process the New ID payloads one by one. */
2314 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
2315 SilcPacketContext *packet)
2317 SilcPacketContext *new_id;
2321 SILC_LOG_DEBUG(("Processing New ID List"));
2323 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2324 packet->src_id_type != SILC_ID_SERVER)
2327 /* If the sender of this packet is server and we are router we need to
2328 broadcast this packet to other routers in the network. Broadcast
2329 this list packet instead of multiple New ID packets. */
2330 if (!server->standalone && server->server_type == SILC_ROUTER &&
2331 sock->type == SILC_SOCKET_TYPE_SERVER &&
2332 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2333 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
2334 silc_server_packet_send(server, server->router->connection,
2336 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2337 packet->buffer->data, packet->buffer->len, FALSE);
2338 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
2339 packet->type, packet->flags,
2340 packet->buffer->data, packet->buffer->len,
2344 /* Make copy of the original packet context, except for the actual
2345 data buffer, which we will here now fetch from the original buffer. */
2346 new_id = silc_packet_context_alloc();
2347 new_id->type = SILC_PACKET_NEW_ID;
2348 new_id->flags = packet->flags;
2349 new_id->src_id = packet->src_id;
2350 new_id->src_id_len = packet->src_id_len;
2351 new_id->src_id_type = packet->src_id_type;
2352 new_id->dst_id = packet->dst_id;
2353 new_id->dst_id_len = packet->dst_id_len;
2354 new_id->dst_id_type = packet->dst_id_type;
2356 idp = silc_buffer_alloc(256);
2357 new_id->buffer = idp;
2359 while (packet->buffer->len) {
2360 SILC_GET16_MSB(id_len, packet->buffer->data + 2);
2361 if ((id_len > packet->buffer->len) ||
2362 (id_len > idp->truelen))
2365 silc_buffer_pull_tail(idp, 4 + id_len);
2366 silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
2368 /* Process the New ID */
2369 silc_server_new_id_real(server, sock, new_id, FALSE);
2371 silc_buffer_push_tail(idp, 4 + id_len);
2372 silc_buffer_pull(packet->buffer, 4 + id_len);
2375 silc_buffer_free(idp);
2379 /* Received New Channel packet. Information about new channels in the
2380 network are distributed using this packet. Save the information about
2381 the new channel. This usually comes from router but also normal server
2382 can send this to notify channels it has when it connects to us. */
2384 void silc_server_new_channel(SilcServer server,
2385 SilcSocketConnection sock,
2386 SilcPacketContext *packet)
2388 SilcChannelPayload payload;
2389 SilcChannelID *channel_id;
2391 SilcUInt32 name_len;
2395 SilcServerEntry server_entry;
2396 SilcChannelEntry channel;
2398 SILC_LOG_DEBUG(("Processing New Channel"));
2400 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2401 packet->src_id_type != SILC_ID_SERVER ||
2402 server->server_type == SILC_SERVER)
2405 /* Parse the channel payload */
2406 payload = silc_channel_payload_parse(packet->buffer->data,
2407 packet->buffer->len);
2411 /* Get the channel ID */
2412 channel_id = silc_channel_get_id_parse(payload);
2414 silc_channel_payload_free(payload);
2418 channel_name = silc_channel_get_name(payload, &name_len);
2420 channel_name[255] = '\0';
2422 id = silc_channel_get_id(payload, &id_len);
2424 server_entry = (SilcServerEntry)sock->user_data;
2426 if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
2427 /* Add the channel to global list as it is coming from router. It
2428 cannot be our own channel as it is coming from router. */
2430 /* Check that we don't already have this channel */
2431 channel = silc_idlist_find_channel_by_name(server->local_list,
2432 channel_name, NULL);
2434 channel = silc_idlist_find_channel_by_name(server->global_list,
2435 channel_name, NULL);
2437 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
2438 silc_id_render(channel_id, SILC_ID_CHANNEL),
2441 silc_idlist_add_channel(server->global_list, strdup(channel_name),
2442 0, channel_id, sock->user_data, NULL, NULL, 0);
2443 server->stat.channels++;
2446 /* The channel is coming from our server, thus it is in our cell
2447 we will add it to our local list. */
2450 SILC_LOG_DEBUG(("Channel id(%s) from [Server] %s",
2451 silc_id_render(channel_id, SILC_ID_CHANNEL),
2454 /* Check that we don't already have this channel */
2455 channel = silc_idlist_find_channel_by_name(server->local_list,
2456 channel_name, NULL);
2458 channel = silc_idlist_find_channel_by_name(server->global_list,
2459 channel_name, NULL);
2461 /* If the channel does not exist, then create it. This creates a new
2462 key to the channel as well that we will send to the server. */
2464 /* The protocol says that the Channel ID's IP address must be based
2465 on the router's IP address. Check whether the ID is based in our
2466 IP and if it is not then create a new ID and enforce the server
2467 to switch the ID. */
2468 if (server_entry->server_type != SILC_BACKUP_ROUTER &&
2469 !SILC_ID_COMPARE(channel_id, server->id, server->id->ip.data_len)) {
2471 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2473 if (silc_id_create_channel_id(server, server->id, server->rng, &tmp)) {
2474 silc_server_send_notify_channel_change(server, sock, FALSE,
2476 silc_free(channel_id);
2481 /* Create the channel with the provided Channel ID */
2482 channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
2486 silc_channel_payload_free(payload);
2487 silc_free(channel_id);
2491 /* Get the mode and set it to the channel */
2492 channel->mode = silc_channel_get_mode(payload);
2494 /* Send the new channel key to the server */
2495 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2496 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
2497 chk = silc_channel_key_payload_encode(id_len, id,
2498 strlen(channel->channel_key->
2500 channel->channel_key->cipher->name,
2501 channel->key_len / 8,
2503 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
2504 chk->data, chk->len, FALSE);
2505 silc_buffer_free(chk);
2508 /* The channel exist by that name, check whether the ID's match.
2509 If they don't then we'll force the server to use the ID we have.
2510 We also create a new key for the channel. */
2511 SilcBuffer users = NULL, users_modes = NULL;
2513 if (!SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
2514 /* They don't match, send CHANNEL_CHANGE notify to the server to
2515 force the ID change. */
2516 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2517 silc_server_send_notify_channel_change(server, sock, FALSE,
2518 channel_id, channel->id);
2521 /* If the mode is different from what we have then enforce the
2523 mode = silc_channel_get_mode(payload);
2524 if (channel->mode != mode) {
2525 SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
2526 silc_server_send_notify_cmode(server, sock, FALSE, channel,
2527 channel->mode, server->id,
2529 channel->cipher, channel->hmac_name,
2530 channel->passphrase);
2533 /* Create new key for the channel and send it to the server and
2534 everybody else possibly on the channel. */
2536 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
2537 if (!silc_server_create_channel_key(server, channel, 0))
2540 /* Send to the channel */
2541 silc_server_send_channel_key(server, sock, channel, FALSE);
2542 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2543 id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
2545 /* Send to the server */
2546 chk = silc_channel_key_payload_encode(id_len, id,
2547 strlen(channel->channel_key->
2549 channel->channel_key->
2551 channel->key_len / 8,
2553 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
2554 chk->data, chk->len, FALSE);
2555 silc_buffer_free(chk);
2559 silc_free(channel_id);
2561 /* Since the channel is coming from server and we also know about it
2562 then send the JOIN notify to the server so that it see's our
2563 users on the channel "joining" the channel. */
2564 silc_server_announce_get_channel_users(server, channel, &users,
2567 silc_buffer_push(users, users->data - users->head);
2568 silc_server_packet_send(server, sock,
2569 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2570 users->data, users->len, FALSE);
2571 silc_buffer_free(users);
2574 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
2575 silc_server_packet_send_dest(server, sock,
2576 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2577 channel->id, SILC_ID_CHANNEL,
2579 users_modes->len, FALSE);
2580 silc_buffer_free(users_modes);
2585 silc_channel_payload_free(payload);
2588 /* Received New Channel List packet, list of New Channel List payloads inside
2589 one packet. Process the New Channel payloads one by one. */
2591 void silc_server_new_channel_list(SilcServer server,
2592 SilcSocketConnection sock,
2593 SilcPacketContext *packet)
2595 SilcPacketContext *new;
2597 SilcUInt16 len1, len2;
2599 SILC_LOG_DEBUG(("Processing New Channel List"));
2601 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2602 packet->src_id_type != SILC_ID_SERVER ||
2603 server->server_type == SILC_SERVER)
2606 /* If the sender of this packet is server and we are router we need to
2607 broadcast this packet to other routers in the network. Broadcast
2608 this list packet instead of multiple New Channel packets. */
2609 if (!server->standalone && server->server_type == SILC_ROUTER &&
2610 sock->type == SILC_SOCKET_TYPE_SERVER &&
2611 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2612 SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
2613 silc_server_packet_send(server, server->router->connection,
2615 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2616 packet->buffer->data, packet->buffer->len, FALSE);
2617 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
2618 packet->type, packet->flags,
2619 packet->buffer->data, packet->buffer->len,
2623 /* Make copy of the original packet context, except for the actual
2624 data buffer, which we will here now fetch from the original buffer. */
2625 new = silc_packet_context_alloc();
2626 new->type = SILC_PACKET_NEW_CHANNEL;
2627 new->flags = packet->flags;
2628 new->src_id = packet->src_id;
2629 new->src_id_len = packet->src_id_len;
2630 new->src_id_type = packet->src_id_type;
2631 new->dst_id = packet->dst_id;
2632 new->dst_id_len = packet->dst_id_len;
2633 new->dst_id_type = packet->dst_id_type;
2635 buffer = silc_buffer_alloc(512);
2636 new->buffer = buffer;
2638 while (packet->buffer->len) {
2639 SILC_GET16_MSB(len1, packet->buffer->data);
2640 if ((len1 > packet->buffer->len) ||
2641 (len1 > buffer->truelen))
2644 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
2645 if ((len2 > packet->buffer->len) ||
2646 (len2 > buffer->truelen))
2649 silc_buffer_pull_tail(buffer, 8 + len1 + len2);
2650 silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
2652 /* Process the New Channel */
2653 silc_server_new_channel(server, sock, new);
2655 silc_buffer_push_tail(buffer, 8 + len1 + len2);
2656 silc_buffer_pull(packet->buffer, 8 + len1 + len2);
2659 silc_buffer_free(buffer);
2663 /* Received key agreement packet. This packet is never for us. It is to
2664 the client in the packet's destination ID. Sending of this sort of packet
2665 equals sending private message, ie. it is sent point to point from
2666 one client to another. */
2668 void silc_server_key_agreement(SilcServer server,
2669 SilcSocketConnection sock,
2670 SilcPacketContext *packet)
2672 SilcSocketConnection dst_sock;
2673 SilcIDListData idata;
2675 SILC_LOG_DEBUG(("Start"));
2677 if (packet->src_id_type != SILC_ID_CLIENT ||
2678 packet->dst_id_type != SILC_ID_CLIENT)
2681 if (!packet->dst_id)
2684 /* Get the route to the client */
2685 dst_sock = silc_server_get_client_route(server, packet->dst_id,
2686 packet->dst_id_len, NULL,
2691 /* Relay the packet */
2692 silc_server_relay_packet(server, dst_sock, idata->send_key,
2693 idata->hmac_send, idata->psn_send++,
2697 /* Received connection auth request packet that is used during connection
2698 phase to resolve the mandatory authentication method. This packet can
2699 actually be received at anytime but usually it is used only during
2700 the connection authentication phase. Now, protocol says that this packet
2701 can come from client or server, however, we support only this coming
2702 from client and expect that server always knows what authentication
2705 void silc_server_connection_auth_request(SilcServer server,
2706 SilcSocketConnection sock,
2707 SilcPacketContext *packet)
2709 SilcServerConfigClient *client = NULL;
2710 SilcUInt16 conn_type;
2712 SilcAuthMethod auth_meth = SILC_AUTH_NONE;
2714 SILC_LOG_DEBUG(("Start"));
2716 if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT)
2719 /* Parse the payload */
2720 ret = silc_buffer_unformat(packet->buffer,
2721 SILC_STR_UI_SHORT(&conn_type),
2722 SILC_STR_UI_SHORT(NULL),
2727 if (conn_type != SILC_SOCKET_TYPE_CLIENT)
2730 /* Get the authentication method for the client */
2731 auth_meth = SILC_AUTH_NONE;
2732 client = silc_server_config_find_client(server, sock->ip);
2734 client = silc_server_config_find_client(server, sock->hostname);
2736 if (client->passphrase) {
2737 if (client->publickeys && !server->config->prefer_passphrase_auth)
2738 auth_meth = SILC_AUTH_PUBLIC_KEY;
2740 auth_meth = SILC_AUTH_PASSWORD;
2741 } else if (client->publickeys)
2742 auth_meth = SILC_AUTH_PUBLIC_KEY;
2745 /* Send it back to the client */
2746 silc_server_send_connection_auth_request(server, sock, conn_type, auth_meth);
2749 /* Received REKEY packet. The sender of the packet wants to regenerate
2750 its session keys. This starts the REKEY protocol. */
2752 void silc_server_rekey(SilcServer server,
2753 SilcSocketConnection sock,
2754 SilcPacketContext *packet)
2756 SilcProtocol protocol;
2757 SilcServerRekeyInternalContext *proto_ctx;
2758 SilcIDListData idata = (SilcIDListData)sock->user_data;
2760 SILC_LOG_DEBUG(("Start"));
2762 /* Allocate internal protocol context. This is sent as context
2764 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
2765 proto_ctx->server = (void *)server;
2766 proto_ctx->sock = sock;
2767 proto_ctx->responder = TRUE;
2768 proto_ctx->pfs = idata->rekey->pfs;
2770 /* Perform rekey protocol. Will call the final callback after the
2771 protocol is over. */
2772 silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
2773 &protocol, proto_ctx, silc_server_rekey_final);
2774 sock->protocol = protocol;
2776 if (proto_ctx->pfs == FALSE)
2777 /* Run the protocol */
2778 silc_protocol_execute(protocol, server->schedule, 0, 0);
2781 /* Received file transger packet. This packet is never for us. It is to
2782 the client in the packet's destination ID. Sending of this sort of packet
2783 equals sending private message, ie. it is sent point to point from
2784 one client to another. */
2786 void silc_server_ftp(SilcServer server,
2787 SilcSocketConnection sock,
2788 SilcPacketContext *packet)
2790 SilcSocketConnection dst_sock;
2791 SilcIDListData idata;
2793 SILC_LOG_DEBUG(("Start"));
2795 if (packet->src_id_type != SILC_ID_CLIENT ||
2796 packet->dst_id_type != SILC_ID_CLIENT)
2799 if (!packet->dst_id)
2802 /* Get the route to the client */
2803 dst_sock = silc_server_get_client_route(server, packet->dst_id,
2804 packet->dst_id_len, NULL,
2809 /* Relay the packet */
2810 silc_server_relay_packet(server, dst_sock, idata->send_key,
2811 idata->hmac_send, idata->psn_send++,
2817 SilcSocketConnection sock;
2818 SilcPacketContext *packet;
2819 } *SilcServerResumeResolve;
2821 SILC_SERVER_CMD_FUNC(resume_resolve)
2823 SilcServerResumeResolve r = (SilcServerResumeResolve)context;
2824 SilcServer server = r->server;
2825 SilcSocketConnection sock = r->sock;
2826 SilcServerCommandReplyContext reply = context2;
2828 if (!context2 || !silc_command_get_status(reply->payload, NULL, NULL)) {
2829 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
2830 "closing connection", sock->hostname, sock->ip));
2831 silc_server_disconnect_remote(server, sock,
2832 "Server closed connection: "
2833 "Incomplete resume information");
2837 /* Reprocess the packet */
2838 silc_server_resume_client(server, sock, r->packet);
2841 silc_socket_free(r->sock);
2842 silc_packet_context_free(r->packet);
2846 /* Received client resuming packet. This is used to resume detached
2847 client session. It can be sent by the client who wishes to resume
2848 but this is also sent by servers and routers to notify other routers
2849 that the client is not detached anymore. */
2851 void silc_server_resume_client(SilcServer server,
2852 SilcSocketConnection sock,
2853 SilcPacketContext *packet)
2855 SilcBuffer buffer = packet->buffer, buf;
2856 SilcIDListData idata;
2857 SilcClientEntry detached_client;
2858 SilcClientID *client_id = NULL;
2859 unsigned char *id_string, *auth = NULL;
2860 SilcUInt16 id_len, auth_len = 0;
2861 int ret, nickfail = 0;
2862 bool resolved, local;
2863 SilcServerResumeResolve r;
2865 ret = silc_buffer_unformat(buffer,
2866 SILC_STR_UI16_NSTRING(&id_string, &id_len),
2869 client_id = silc_id_str2id(id_string, id_len, SILC_ID_CLIENT);
2871 if (sock->type == SILC_SOCKET_TYPE_CLIENT) {
2872 /* Client send this and is attempting to resume to old client session */
2873 SilcClientEntry client;
2874 SilcChannelEntry channel;
2875 SilcHashTableList htl;
2876 SilcChannelClientEntry chl;
2880 silc_buffer_pull(buffer, 2 + id_len);
2881 auth = buffer->data;
2882 auth_len = buffer->len;
2883 silc_buffer_push(buffer, 2 + id_len);
2886 if (!client_id || auth_len < 128) {
2887 SILC_LOG_ERROR(("Client %s (%s) sent incomplete resume information, "
2888 "closing connection", sock->hostname, sock->ip));
2889 silc_server_disconnect_remote(server, sock, "Server closed connection: "
2890 "Incomplete resume information");
2894 /* Take client entry of this connection */
2895 client = (SilcClientEntry)sock->user_data;
2896 idata = (SilcIDListData)client;
2898 /* Get entry to the client, and resolve it if we don't have it. */
2899 detached_client = silc_server_get_client_resolve(server, client_id,
2901 if (!detached_client) {
2903 /* The client info is being resolved. Reprocess this packet after
2904 receiving the reply to the query. */
2905 r = silc_calloc(1, sizeof(*r));
2910 r->sock = silc_socket_dup(sock);
2911 r->packet = silc_packet_context_dup(packet);
2912 silc_server_command_pending(server, SILC_COMMAND_WHOIS,
2914 silc_server_command_resume_resolve, r);
2916 SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, "
2917 "closing connection", sock->hostname, sock->ip));
2918 silc_server_disconnect_remote(server, sock,
2919 "Server closed connection: "
2920 "Incomplete resume information");
2925 /* Check that the client is detached */
2926 if (!(detached_client->mode & SILC_UMODE_DETACHED)) {
2927 SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, "
2928 "closing connection", sock->hostname, sock->ip));
2929 silc_server_disconnect_remote(server, sock, "Server closed connection: "
2930 "Incomplete resume information");
2934 /* Check that we have the public key of the client, if not then we must
2935 resolve it first. */
2936 if (!detached_client->data.public_key) {
2937 if (server->standalone) {
2938 silc_server_disconnect_remote(server, sock,
2939 "Server closed connection: "
2940 "Incomplete resume information");
2942 /* We must retrieve the detached client's public key by sending
2943 GETKEY command. Reprocess this packet after receiving the key */
2944 SilcBuffer idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
2945 SilcSocketConnection dest_sock =
2946 silc_server_get_client_route(server, NULL, 0, client_id, NULL, NULL);
2948 silc_server_send_command(server, dest_sock ? dest_sock :
2949 server->router->connection,
2950 SILC_COMMAND_GETKEY, ++server->cmd_ident,
2951 1, idp->data, idp->len);
2953 r = silc_calloc(1, sizeof(*r));
2958 r->sock = silc_socket_dup(sock);
2959 r->packet = silc_packet_context_dup(packet);
2960 silc_server_command_pending(server, SILC_COMMAND_GETKEY,
2962 silc_server_command_resume_resolve, r);
2964 silc_buffer_free(idp);
2969 /* Verify the authentication payload. This has to be successful in
2970 order to allow the resuming */
2971 if (!silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
2972 detached_client->data.public_key, 0,
2973 idata->hash, detached_client->id,
2975 SILC_LOG_ERROR(("Client %s (%s) resume authentication failed, "
2976 "closing connection", sock->hostname, sock->ip));
2977 silc_server_disconnect_remote(server, sock, "Server closed connection: "
2978 "Incomplete resume information");
2982 /* Now resume the client to the network */
2984 sock->user_data = detached_client;
2985 detached_client->connection = sock;
2987 /* Take new keys and stuff into use in the old entry */
2988 silc_idlist_del_data(detached_client);
2989 silc_idlist_add_data(detached_client, idata);
2990 detached_client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
2991 detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
2992 detached_client->mode &= ~SILC_UMODE_DETACHED;
2994 /* Send the RESUME_CLIENT packet to our primary router so that others
2995 know this client isn't detached anymore. */
2996 if (!server->standalone) {
2997 buf = silc_buffer_alloc_size(2 + id_len);
2998 silc_buffer_format(buf,
2999 SILC_STR_UI_SHORT(id_len),
3000 SILC_STR_UI_XNSTRING(id_string, id_len),
3002 silc_server_packet_send(server, server->router->connection,
3003 SILC_PACKET_RESUME_CLIENT, 0,
3004 buf->data, buf->len, TRUE);
3005 silc_buffer_free(buf);
3008 /* Delete this client entry since we're resuming to old one. */
3009 server->stat.my_clients--;
3010 server->stat.clients--;
3011 if (server->stat.cell_clients)
3012 server->stat.cell_clients--;
3013 silc_idlist_del_client(server->local_list, client);
3014 client = detached_client;
3016 /* If the ID is not based in our ID then change it */
3017 if (!SILC_ID_COMPARE(client->id, server->id, server->id->ip.data_len)) {
3018 while (!silc_id_create_client_id(server, server->id, server->rng,
3019 server->md5hash, client->nickname,
3023 silc_server_disconnect_remote(server, sock,
3024 "Server closed connection: "
3028 snprintf(&client->nickname[strlen(client->nickname) - 1], 1,
3032 /* Notify about Client ID change, nickname doesn't actually change. */
3033 if (!server->standalone)
3034 silc_server_send_notify_nick_change(server, server->router->connection,
3035 FALSE, client->id, client_id,
3038 silc_free(client->id);
3039 client->id = client_id;
3042 /* Add the client again to the ID cache to get it to correct list */
3043 if (!silc_idcache_del_by_context(server->local_list->clients, client))
3044 silc_idcache_del_by_context(server->global_list->clients, client);
3045 silc_idcache_add(server->local_list->clients, client->nickname,
3046 client->id, client, client->mode, NULL);
3048 /* Send the new client ID to the client. */
3049 id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
3050 buf = silc_buffer_alloc_size(2 + 2 + id_len);
3051 silc_buffer_format(buf,
3052 SILC_STR_UI_SHORT(SILC_ID_CLIENT),
3053 SILC_STR_UI_SHORT(id_len),
3054 SILC_STR_UI_XNSTRING(id_string, id_len),
3056 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0,
3057 buf->data, buf->len, FALSE);
3058 silc_free(id_string);
3059 silc_buffer_free(buf);
3061 /* Send some nice info to the client */
3062 silc_server_send_connect_notifys(server, sock, client);
3064 /* Send all channel keys of channels the client has joined */
3065 silc_hash_table_list(client->channels, &htl);
3066 while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
3067 channel = chl->channel;
3068 id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
3070 silc_channel_key_payload_encode(silc_id_get_len(channel->id,
3073 strlen(channel->channel_key->
3075 channel->channel_key->cipher->name,
3076 channel->key_len / 8, channel->key);
3077 silc_free(id_string);
3079 /* Send the key packet to client */
3080 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
3081 keyp->data, keyp->len, FALSE);
3083 silc_hash_table_list_reset(&htl);
3085 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
3086 ("Your session is successfully resumed"));
3088 } else if (sock->type != SILC_SOCKET_TYPE_CLIENT) {
3089 /* Server or router sent this to us to notify that that a client has
3091 SilcServerEntry server_entry;
3092 SilcServerID *server_id;
3097 /* Get entry to the client, and resolve it if we don't have it. */
3098 detached_client = silc_idlist_find_client_by_id(server->local_list,
3099 client_id, TRUE, NULL);
3100 if (!detached_client) {
3101 detached_client = silc_idlist_find_client_by_id(server->global_list,
3102 client_id, TRUE, NULL);
3103 if (!detached_client)
3107 /* Check that the client has not been resumed already because it is
3108 protocol error to attempt to resume more than once. The client
3109 will be killed if this protocol error occurs. */
3110 if (detached_client->data.status & SILC_IDLIST_STATUS_RESUMED &&
3111 !(detached_client->mode & SILC_UMODE_DETACHED)) {
3112 /* The client is clearly attempting to resume more than once and
3113 perhaps playing around by resuming from several different places
3114 at the same time. */
3115 silc_server_kill_client(server, detached_client, NULL,
3116 server->id, SILC_ID_SERVER);
3120 /* Check whether client is detached at all */
3121 if (!(detached_client->mode & SILC_UMODE_DETACHED))
3124 /* Client is detached, and now it is resumed. Remove the detached
3125 mode and mark that it is resumed. */
3126 detached_client->mode &= ~SILC_UMODE_DETACHED;
3127 detached_client->data.status |= SILC_IDLIST_STATUS_RESUMED;
3129 /* Get the new owner of the resumed client */
3130 server_id = silc_id_str2id(packet->src_id, packet->src_id_len,
3131 packet->src_id_type);
3135 /* Get server entry */
3136 server_entry = silc_idlist_find_server_by_id(server->global_list,
3137 server_id, TRUE, NULL);
3139 if (!server_entry) {
3140 server_entry = silc_idlist_find_server_by_id(server->local_list,
3141 server_id, TRUE, NULL);
3143 if (!server_entry) {
3144 silc_free(server_id);
3149 /* Change the client to correct list. */
3150 if (!silc_idcache_del_by_context(server->local_list->clients,
3152 silc_idcache_del_by_context(server->global_list->clients,
3154 silc_idcache_add(local ? server->local_list->clients :
3155 server->global_list->clients, detached_client->nickname,
3156 detached_client->id, detached_client, FALSE, NULL);
3158 /* Change the owner of the client if needed */
3159 if (detached_client->router != server_entry)
3160 detached_client->router = server_entry;
3162 /* If the sender of this packet is server and we are router we need to
3163 broadcast this packet to other routers in the network. */
3164 if (!server->standalone && server->server_type == SILC_ROUTER &&
3165 sock->type == SILC_SOCKET_TYPE_SERVER &&
3166 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
3167 SILC_LOG_DEBUG(("Broadcasting received Resume Client packet"));
3168 silc_server_packet_send(server, server->router->connection,
3170 packet->flags | SILC_PACKET_FLAG_BROADCAST,
3171 buffer->data, buffer->len, FALSE);
3172 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
3173 packet->type, packet->flags,
3174 packet->buffer->data, packet->buffer->len,
3178 silc_free(server_id);
3181 silc_free(client_id);