5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2001 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 extern char *server_version;
30 /* Received notify packet. Server can receive notify packets from router.
31 Server then relays the notify messages to clients if needed. */
33 void silc_server_notify(SilcServer server,
34 SilcSocketConnection sock,
35 SilcPacketContext *packet)
37 SilcNotifyPayload payload;
39 SilcArgumentPayload args;
40 SilcChannelID *channel_id, *channel_id2;
41 SilcClientID *client_id, *client_id2;
42 SilcChannelEntry channel;
43 SilcClientEntry client;
44 SilcChannelClientEntry chl;
45 SilcIDCacheEntry cache;
50 SILC_LOG_DEBUG(("Start"));
52 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
53 packet->src_id_type != SILC_ID_SERVER)
59 /* If the packet is destined directly to a client then relay the packet
60 before processing it. */
61 if (packet->dst_id_type == SILC_ID_CLIENT) {
63 SilcSocketConnection dst_sock;
65 /* Get the route to the client */
66 dst_sock = silc_server_get_client_route(server, packet->dst_id,
67 packet->dst_id_len, NULL, &idata);
69 /* Relay the packet */
70 silc_server_relay_packet(server, dst_sock, idata->send_key,
71 idata->hmac, packet, TRUE);
74 /* If we are router and this packet is not already broadcast packet
75 we will broadcast it. The sending socket really cannot be router or
76 the router is buggy. If this packet is coming from router then it must
77 have the broadcast flag set already and we won't do anything. */
78 if (!server->standalone && server->server_type == SILC_ROUTER &&
79 sock->type == SILC_SOCKET_TYPE_SERVER &&
80 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
81 SILC_LOG_DEBUG(("Broadcasting received Notify packet"));
82 silc_server_packet_send(server, server->router->connection, packet->type,
83 packet->flags | SILC_PACKET_FLAG_BROADCAST,
84 packet->buffer->data, packet->buffer->len, FALSE);
87 payload = silc_notify_payload_parse(packet->buffer);
91 type = silc_notify_get_type(payload);
92 args = silc_notify_get_args(payload);
97 case SILC_NOTIFY_TYPE_JOIN:
99 * Distribute the notify to local clients on the channel
101 SILC_LOG_DEBUG(("JOIN notify"));
104 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
107 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
111 /* Get channel entry */
112 channel = silc_idlist_find_channel_by_id(server->global_list,
115 channel = silc_idlist_find_channel_by_id(server->local_list,
118 silc_free(channel_id);
122 silc_free(channel_id);
125 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
128 client_id = silc_id_payload_parse_id(tmp, tmp_len);
132 /* Send to channel */
133 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
134 FALSE, packet->buffer->data,
135 packet->buffer->len, FALSE);
137 /* If the the client is not in local list we check global list (ie. the
138 channel will be global channel) and if it does not exist then create
139 entry for the client. */
140 client = silc_idlist_find_client_by_id(server->global_list,
143 client = silc_idlist_find_client_by_id(server->local_list,
146 /* If router did not find the client the it is bogus */
147 if (server->server_type == SILC_ROUTER)
151 silc_idlist_add_client(server->global_list, NULL, 0, NULL, NULL,
152 silc_id_dup(client_id, SILC_ID_CLIENT),
153 sock->user_data, NULL);
155 silc_free(client_id);
159 client->data.registered = TRUE;
163 /* Do not add client to channel if it is there already */
164 if (silc_server_client_on_channel(client, channel))
167 if (server->server_type == SILC_SERVER &&
168 sock->type == SILC_SOCKET_TYPE_ROUTER)
169 /* The channel is global now */
170 channel->global_users = TRUE;
172 /* JOIN the global client to the channel (local clients (if router
173 created the channel) is joined in the pending JOIN command). */
174 chl = silc_calloc(1, sizeof(*chl));
175 chl->client = client;
176 chl->channel = channel;
177 silc_list_add(channel->user_list, chl);
178 silc_list_add(client->channels, chl);
179 silc_free(client_id);
183 case SILC_NOTIFY_TYPE_LEAVE:
185 * Distribute the notify to local clients on the channel
187 SILC_LOG_DEBUG(("LEAVE notify"));
189 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
190 packet->dst_id_type);
194 /* Get channel entry */
195 channel = silc_idlist_find_channel_by_id(server->global_list,
198 channel = silc_idlist_find_channel_by_id(server->local_list,
201 silc_free(channel_id);
207 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
209 silc_free(channel_id);
212 client_id = silc_id_payload_parse_id(tmp, tmp_len);
214 silc_free(channel_id);
218 /* Send to channel */
219 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
220 FALSE, packet->buffer->data,
221 packet->buffer->len, FALSE);
223 /* Get client entry */
224 client = silc_idlist_find_client_by_id(server->global_list,
227 client = silc_idlist_find_client_by_id(server->local_list,
230 silc_free(client_id);
231 silc_free(channel_id);
235 silc_free(client_id);
237 /* Remove the user from channel */
238 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
241 case SILC_NOTIFY_TYPE_SIGNOFF:
243 * Distribute the notify to local clients on the channel
245 SILC_LOG_DEBUG(("SIGNOFF notify"));
248 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
251 client_id = silc_id_payload_parse_id(tmp, tmp_len);
255 /* Get client entry */
256 client = silc_idlist_find_client_by_id(server->global_list,
259 client = silc_idlist_find_client_by_id(server->local_list,
262 silc_free(client_id);
266 silc_free(client_id);
268 /* Get signoff message */
269 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
273 /* Remove the client from all channels */
274 silc_server_remove_from_channels(server, NULL, client, TRUE, tmp, TRUE);
276 client->data.registered = FALSE;
277 cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
280 /* Remove the client entry */
281 if (!silc_idlist_del_client(server->global_list, client))
282 silc_idlist_del_client(server->local_list, client);
286 case SILC_NOTIFY_TYPE_TOPIC_SET:
288 * Distribute the notify to local clients on the channel
291 SILC_LOG_DEBUG(("TOPIC SET notify"));
293 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
294 packet->dst_id_type);
298 /* Get channel entry */
299 channel = silc_idlist_find_channel_by_id(server->global_list,
302 channel = silc_idlist_find_channel_by_id(server->local_list,
305 silc_free(channel_id);
311 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
313 silc_free(channel_id);
318 silc_free(channel->topic);
319 channel->topic = silc_calloc(tmp_len, sizeof(*channel->topic));
320 memcpy(channel->topic, tmp, tmp_len);
322 /* Send the same notify to the channel */
323 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
324 FALSE, packet->buffer->data,
325 packet->buffer->len, FALSE);
326 silc_free(channel_id);
329 case SILC_NOTIFY_TYPE_NICK_CHANGE:
332 * Distribute the notify to local clients on the channel
334 unsigned char *id, *id2;
336 SILC_LOG_DEBUG(("NICK CHANGE notify"));
338 /* Get old client ID */
339 id = silc_argument_get_arg_type(args, 1, &tmp_len);
342 client_id = silc_id_payload_parse_id(id, tmp_len);
346 /* Get new client ID */
347 id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
350 client_id2 = silc_id_payload_parse_id(id2, tmp_len);
354 SILC_LOG_DEBUG(("Old Client ID id(%s)",
355 silc_id_render(client_id, SILC_ID_CLIENT)));
356 SILC_LOG_DEBUG(("New Client ID id(%s)",
357 silc_id_render(client_id2, SILC_ID_CLIENT)));
359 /* Replace the Client ID */
360 client = silc_idlist_replace_client_id(server->global_list, client_id,
363 client = silc_idlist_replace_client_id(server->local_list, client_id,
367 /* The nickname is not valid anymore, set it NULL. This causes that
368 the nickname will be queried if someone wants to know it. */
369 if (client->nickname)
370 silc_free(client->nickname);
371 client->nickname = NULL;
373 /* Send the NICK_CHANGE notify type to local clients on the channels
374 this client is joined to. */
375 silc_server_send_notify_on_channels(server, NULL, client,
376 SILC_NOTIFY_TYPE_NICK_CHANGE, 2,
381 silc_free(client_id);
383 silc_free(client_id2);
387 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
389 * Distribute the notify to local clients on the channel
392 SILC_LOG_DEBUG(("CMODE CHANGE notify"));
394 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
395 packet->dst_id_type);
399 /* Get channel entry */
400 channel = silc_idlist_find_channel_by_id(server->global_list,
403 channel = silc_idlist_find_channel_by_id(server->local_list,
406 silc_free(channel_id);
411 /* Send the same notify to the channel */
412 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
413 FALSE, packet->buffer->data,
414 packet->buffer->len, FALSE);
417 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
419 silc_free(channel_id);
423 SILC_GET32_MSB(mode, tmp);
426 channel->mode = mode;
427 silc_free(channel_id);
430 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
432 unsigned char hash[32];
435 silc_hmac_free(channel->hmac);
436 if (!silc_hmac_alloc(tmp, NULL, &channel->hmac))
439 /* Set the HMAC key out of current channel key. The client must do
441 silc_hash_make(channel->hmac->hash, channel->key, channel->key_len / 8,
443 silc_hmac_set_key(channel->hmac, hash,
444 silc_hash_len(channel->hmac->hash));
445 memset(hash, 0, sizeof(hash));
450 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
452 * Distribute the notify to local clients on the channel
455 SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
457 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
458 packet->dst_id_type);
462 /* Get channel entry */
463 channel = silc_idlist_find_channel_by_id(server->global_list,
466 channel = silc_idlist_find_channel_by_id(server->local_list,
469 silc_free(channel_id);
475 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
477 silc_free(channel_id);
481 SILC_GET32_MSB(mode, tmp);
483 /* Get target client */
484 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
487 client_id = silc_id_payload_parse_id(tmp, tmp_len);
491 /* Get client entry */
492 client = silc_idlist_find_client_by_id(server->global_list,
495 client = silc_idlist_find_client_by_id(server->local_list,
498 silc_free(client_id);
502 silc_free(client_id);
504 /* Get entry to the channel user list */
505 silc_list_start(channel->user_list);
506 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END)
507 if (chl->client == client) {
508 /* Change the mode */
513 /* Send the same notify to the channel */
514 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
515 FALSE, packet->buffer->data,
516 packet->buffer->len, FALSE);
517 silc_free(channel_id);
520 case SILC_NOTIFY_TYPE_INVITE:
522 if (packet->dst_id_type == SILC_ID_CLIENT)
525 SILC_LOG_DEBUG(("INVITE notify"));
528 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
531 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
535 /* Get channel entry */
536 channel = silc_idlist_find_channel_by_id(server->global_list,
539 channel = silc_idlist_find_channel_by_id(server->local_list,
542 silc_free(channel_id);
546 silc_free(channel_id);
548 /* Get the added invite */
549 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
551 if (!channel->invite_list)
552 channel->invite_list = silc_calloc(tmp_len + 2,
553 sizeof(*channel->invite_list));
555 channel->invite_list = silc_realloc(channel->invite_list,
556 sizeof(*channel->invite_list) *
558 strlen(channel->invite_list) +
560 if (tmp[tmp_len - 1] == ',')
561 tmp[tmp_len - 1] = '\0';
563 strncat(channel->invite_list, tmp, tmp_len);
564 strncat(channel->invite_list, ",", 1);
567 /* Get the deleted invite */
568 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
569 if (tmp && channel->invite_list) {
570 char *start, *end, *n;
572 if (!strncmp(channel->invite_list, tmp,
573 strlen(channel->invite_list) - 1)) {
574 silc_free(channel->invite_list);
575 channel->invite_list = NULL;
577 start = strstr(channel->invite_list, tmp);
578 if (start && strlen(start) >= tmp_len) {
579 end = start + tmp_len;
580 n = silc_calloc(strlen(channel->invite_list) - tmp_len, sizeof(*n));
581 strncat(n, channel->invite_list, start - channel->invite_list);
582 strncat(n, end + 1, ((channel->invite_list +
583 strlen(channel->invite_list)) - end) - 1);
584 silc_free(channel->invite_list);
585 channel->invite_list = n;
592 case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
594 * Distribute to the local clients on the channel and change the
598 SILC_LOG_DEBUG(("CHANNEL CHANGE"));
600 /* Get the old Channel ID */
601 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
604 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
608 /* Get the channel entry */
609 channel = silc_idlist_find_channel_by_id(server->global_list,
612 channel = silc_idlist_find_channel_by_id(server->local_list,
615 silc_free(channel_id);
620 /* Send the notify to the channel */
621 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
622 FALSE, packet->buffer->data,
623 packet->buffer->len, FALSE);
625 /* Get the new Channel ID */
626 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
629 channel_id2 = silc_id_payload_parse_id(tmp, tmp_len);
633 /* Replace the Channel ID */
634 if (!silc_idlist_replace_channel_id(server->global_list, channel_id,
636 silc_idlist_replace_channel_id(server->local_list, channel_id,
639 silc_free(channel_id);
640 silc_free(channel_id2);
644 case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
645 SILC_LOG_DEBUG(("SERVER SIGNOFF notify (not-impl XXX)"));
648 case SILC_NOTIFY_TYPE_KICKED:
650 * Distribute the notify to local clients on the channel
653 SILC_LOG_DEBUG(("KICKED notify"));
655 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
656 packet->dst_id_type);
660 /* Get channel entry */
661 channel = silc_idlist_find_channel_by_id(server->global_list,
664 channel = silc_idlist_find_channel_by_id(server->local_list,
667 silc_free(channel_id);
671 silc_free(channel_id);
674 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
677 client_id = silc_id_payload_parse_id(tmp, tmp_len);
681 /* Send to channel */
682 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
683 FALSE, packet->buffer->data,
684 packet->buffer->len, FALSE);
686 /* If the the client is not in local list we check global list */
687 client = silc_idlist_find_client_by_id(server->global_list,
690 client = silc_idlist_find_client_by_id(server->local_list,
693 silc_free(client_id);
698 /* Remove the client from channel */
699 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
703 case SILC_NOTIFY_TYPE_KILLED:
706 * Distribute the notify to local clients on channels
711 SILC_LOG_DEBUG(("KILLED notify"));
714 id = silc_argument_get_arg_type(args, 1, &id_len);
717 client_id = silc_id_payload_parse_id(id, id_len);
721 /* If the the client is not in local list we check global list */
722 client = silc_idlist_find_client_by_id(server->global_list,
725 client = silc_idlist_find_client_by_id(server->local_list,
728 silc_free(client_id);
732 silc_free(client_id);
734 /* If the client is one of ours, then close the connection to the
735 client now. This removes the client from all channels as well. */
736 if (packet->dst_id_type == SILC_ID_CLIENT && client->data.registered &&
737 client->connection) {
738 sock = client->connection;
739 silc_server_free_client_data(server, NULL, client, FALSE, NULL);
740 silc_server_close_connection(server, sock);
745 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
749 /* Send the notify to local clients on the channels except to the
750 client who is killed. */
751 silc_server_send_notify_on_channels(server, client, client,
752 SILC_NOTIFY_TYPE_KILLED,
757 /* Remove the client from all channels */
758 silc_server_remove_from_channels(server, NULL, client, FALSE, NULL,
764 case SILC_NOTIFY_TYPE_UMODE_CHANGE:
766 * Save the mode of the client.
769 SILC_LOG_DEBUG(("UMODE_CHANGE notify"));
772 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
775 client_id = silc_id_payload_parse_id(tmp, tmp_len);
779 /* Get client entry */
780 client = silc_idlist_find_client_by_id(server->global_list,
783 client = silc_idlist_find_client_by_id(server->local_list,
786 silc_free(client_id);
790 silc_free(client_id);
793 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
798 SILC_GET32_MSB(client->mode, tmp);
802 case SILC_NOTIFY_TYPE_BAN:
807 SILC_LOG_DEBUG(("BAN notify"));
810 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
813 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
817 /* Get channel entry */
818 channel = silc_idlist_find_channel_by_id(server->global_list,
821 channel = silc_idlist_find_channel_by_id(server->local_list,
824 silc_free(channel_id);
828 silc_free(channel_id);
830 /* Get the new ban and add it to the ban list */
831 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
833 if (!channel->ban_list)
834 channel->ban_list = silc_calloc(tmp_len + 2,
835 sizeof(*channel->ban_list));
837 channel->ban_list = silc_realloc(channel->ban_list,
838 sizeof(*channel->ban_list) *
840 strlen(channel->ban_list) + 2));
841 strncat(channel->ban_list, tmp, tmp_len);
842 strncat(channel->ban_list, ",", 1);
845 /* Get the ban to be removed and remove it from the list */
846 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
847 if (tmp && channel->ban_list) {
848 char *start, *end, *n;
850 if (!strcmp(channel->ban_list, tmp)) {
851 silc_free(channel->ban_list);
852 channel->ban_list = NULL;
854 start = strstr(channel->ban_list, tmp);
855 if (start && strlen(start) >= tmp_len) {
856 end = start + tmp_len;
857 n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
858 strncat(n, channel->ban_list, start - channel->ban_list);
859 strncat(n, end + 1, ((channel->ban_list +
860 strlen(channel->ban_list)) - end) - 1);
861 silc_free(channel->ban_list);
862 channel->ban_list = n;
869 /* Ignore rest of the notify types for now */
870 case SILC_NOTIFY_TYPE_NONE:
871 case SILC_NOTIFY_TYPE_MOTD:
878 silc_notify_payload_free(payload);
881 void silc_server_notify_list(SilcServer server,
882 SilcSocketConnection sock,
883 SilcPacketContext *packet)
885 SilcPacketContext *new;
889 SILC_LOG_DEBUG(("Processing New Notify List"));
891 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
892 packet->src_id_type != SILC_ID_SERVER)
895 /* Make copy of the original packet context, except for the actual
896 data buffer, which we will here now fetch from the original buffer. */
897 new = silc_packet_context_alloc();
898 new->type = SILC_PACKET_NOTIFY;
899 new->flags = packet->flags;
900 new->src_id = packet->src_id;
901 new->src_id_len = packet->src_id_len;
902 new->src_id_type = packet->src_id_type;
903 new->dst_id = packet->dst_id;
904 new->dst_id_len = packet->dst_id_len;
905 new->dst_id_type = packet->dst_id_type;
907 buffer = silc_buffer_alloc(1024);
908 new->buffer = buffer;
910 while (packet->buffer->len) {
911 SILC_GET16_MSB(len, packet->buffer->data + 2);
912 if (len > packet->buffer->len)
915 if (len > buffer->truelen) {
916 silc_buffer_free(buffer);
917 buffer = silc_buffer_alloc(1024 + len);
920 silc_buffer_pull_tail(buffer, len);
921 silc_buffer_put(buffer, packet->buffer->data, len);
923 /* Process the Notify */
924 silc_server_notify(server, sock, new);
926 silc_buffer_push_tail(buffer, len);
927 silc_buffer_pull(packet->buffer, len);
930 silc_buffer_free(buffer);
934 /* Received private message. This resolves the destination of the message
935 and sends the packet. This is used by both server and router. If the
936 destination is our locally connected client this sends the packet to
937 the client. This may also send the message for further routing if
938 the destination is not in our server (or router). */
940 void silc_server_private_message(SilcServer server,
941 SilcSocketConnection sock,
942 SilcPacketContext *packet)
944 SilcSocketConnection dst_sock;
945 SilcIDListData idata;
947 SILC_LOG_DEBUG(("Start"));
949 if (packet->src_id_type != SILC_ID_CLIENT ||
950 packet->dst_id_type != SILC_ID_CLIENT)
956 /* Get the route to the client */
957 dst_sock = silc_server_get_client_route(server, packet->dst_id,
958 packet->dst_id_len, NULL, &idata);
962 /* Send the private message */
963 silc_server_send_private_message(server, dst_sock, idata->send_key,
964 idata->hmac, packet);
967 /* Received private message key packet.. This packet is never for us. It is to
968 the client in the packet's destination ID. Sending of this sort of packet
969 equals sending private message, ie. it is sent point to point from
970 one client to another. */
972 void silc_server_private_message_key(SilcServer server,
973 SilcSocketConnection sock,
974 SilcPacketContext *packet)
976 SilcSocketConnection dst_sock;
977 SilcIDListData idata;
979 SILC_LOG_DEBUG(("Start"));
981 if (packet->src_id_type != SILC_ID_CLIENT ||
982 packet->dst_id_type != SILC_ID_CLIENT)
988 /* Get the route to the client */
989 dst_sock = silc_server_get_client_route(server, packet->dst_id,
990 packet->dst_id_len, NULL, &idata);
994 /* Relay the packet */
995 silc_server_relay_packet(server, dst_sock, idata->send_key,
996 idata->hmac, packet, FALSE);
999 /* Processes incoming command reply packet. The command reply packet may
1000 be destined to one of our clients or it may directly for us. We will
1001 call the command reply routine after processing the packet. */
1003 void silc_server_command_reply(SilcServer server,
1004 SilcSocketConnection sock,
1005 SilcPacketContext *packet)
1007 SilcBuffer buffer = packet->buffer;
1008 SilcClientEntry client = NULL;
1009 SilcSocketConnection dst_sock;
1010 SilcIDListData idata;
1011 SilcClientID *id = NULL;
1013 SILC_LOG_DEBUG(("Start"));
1015 /* Source must be server or router */
1016 if (packet->src_id_type != SILC_ID_SERVER &&
1017 sock->type != SILC_SOCKET_TYPE_ROUTER)
1020 if (packet->dst_id_type == SILC_ID_CHANNEL)
1023 if (packet->dst_id_type == SILC_ID_CLIENT) {
1024 /* Destination must be one of ours */
1025 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
1028 client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
1030 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
1036 if (packet->dst_id_type == SILC_ID_SERVER) {
1037 /* For now this must be for us */
1038 if (SILC_ID_SERVER_COMPARE(packet->dst_id, server->id_string)) {
1039 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
1044 /* Execute command reply locally for the command */
1045 silc_server_command_reply_process(server, sock, buffer);
1047 if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
1048 /* Relay the packet to the client */
1050 dst_sock = (SilcSocketConnection)client->connection;
1051 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
1052 + packet->dst_id_len + packet->padlen);
1054 silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
1055 silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
1057 idata = (SilcIDListData)client;
1059 /* Encrypt packet */
1060 silc_packet_encrypt(idata->send_key, idata->hmac, dst_sock->outbuf,
1063 /* Send the packet */
1064 silc_server_packet_send_real(server, dst_sock, TRUE);
1070 /* Process received channel message. The message can be originated from
1071 client or server. */
1073 void silc_server_channel_message(SilcServer server,
1074 SilcSocketConnection sock,
1075 SilcPacketContext *packet)
1077 SilcChannelEntry channel = NULL;
1078 SilcChannelClientEntry chl;
1079 SilcChannelID *id = NULL;
1080 void *sender = NULL;
1082 SILC_LOG_DEBUG(("Processing channel message"));
1085 if (packet->dst_id_type != SILC_ID_CHANNEL) {
1086 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1090 /* Find channel entry */
1091 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
1094 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
1096 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
1098 SILC_LOG_DEBUG(("Could not find channel"));
1103 /* See that this client is on the channel. If the message is coming
1104 from router we won't do the check as the message is from client that
1105 we don't know about. Also, if the original sender is not client
1106 (as it can be server as well) we don't do the check. */
1107 sender = silc_id_str2id(packet->src_id, packet->src_id_len,
1108 packet->src_id_type);
1111 if (sock->type != SILC_SOCKET_TYPE_ROUTER &&
1112 packet->src_id_type == SILC_ID_CLIENT) {
1113 silc_list_start(channel->user_list);
1114 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
1115 if (chl->client && !SILC_ID_CLIENT_COMPARE(chl->client->id, sender))
1118 if (chl == SILC_LIST_END) {
1119 SILC_LOG_DEBUG(("Client not on channel"));
1124 /* If we are router and the packet came from router and private key
1125 has not been set for the channel then we must encrypt the packet
1126 as it was decrypted with the session key shared between us and the
1127 router which sent it. This is so, because cells does not share the
1129 if (server->server_type == SILC_ROUTER &&
1130 sock->type == SILC_SOCKET_TYPE_ROUTER &&
1131 !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
1133 unsigned int iv_len, i;
1134 unsigned short data_len, flags;
1136 iv_len = silc_cipher_get_block_len(channel->channel_key);
1137 if (channel->iv[0] == '\0')
1138 for (i = 0; i < iv_len; i++) channel->iv[i] =
1139 silc_rng_get_byte(server->rng);
1141 silc_hash_make(server->md5hash, channel->iv, iv_len, channel->iv);
1143 /* Encode new payload. This encrypts it also. */
1144 SILC_GET16_MSB(flags, packet->buffer->data);
1145 SILC_GET16_MSB(data_len, packet->buffer->data + 2);
1146 chp = silc_channel_message_payload_encode(flags, data_len,
1147 packet->buffer->data + 4,
1148 iv_len, channel->iv,
1149 channel->channel_key,
1151 silc_buffer_put(packet->buffer, chp->data, chp->len);
1152 silc_buffer_free(chp);
1155 /* Distribute the packet to our local clients. This will send the
1156 packet for further routing as well, if needed. */
1157 silc_server_packet_relay_to_channel(server, sock, channel, sender,
1158 packet->src_id_type,
1159 packet->buffer->data,
1160 packet->buffer->len, FALSE);
1169 /* Received channel key packet. We distribute the key to all of our locally
1170 connected clients on the channel. */
1172 void silc_server_channel_key(SilcServer server,
1173 SilcSocketConnection sock,
1174 SilcPacketContext *packet)
1176 SilcBuffer buffer = packet->buffer;
1177 SilcChannelEntry channel;
1179 if (packet->src_id_type != SILC_ID_SERVER)
1182 /* Save the channel key */
1183 channel = silc_server_save_channel_key(server, buffer, NULL);
1187 /* Distribute the key to everybody who is on the channel. If we are router
1188 we will also send it to locally connected servers. */
1189 silc_server_send_channel_key(server, sock, channel, FALSE);
1192 /* Received New Client packet and processes it. Creates Client ID for the
1193 client. Client becomes registered after calling this functions. */
1195 SilcClientEntry silc_server_new_client(SilcServer server,
1196 SilcSocketConnection sock,
1197 SilcPacketContext *packet)
1199 SilcBuffer buffer = packet->buffer;
1200 SilcClientEntry client;
1201 SilcIDCacheEntry cache;
1202 SilcClientID *client_id;
1204 SilcIDListData idata;
1205 char *username = NULL, *realname = NULL, *id_string;
1208 SILC_LOG_DEBUG(("Creating new client"));
1210 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
1213 /* Take client entry */
1214 client = (SilcClientEntry)sock->user_data;
1215 idata = (SilcIDListData)client;
1217 /* Fetch the old client cache entry so that we can update it. */
1218 if (!silc_idcache_find_by_context(server->local_list->clients,
1219 sock->user_data, &cache)) {
1220 SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
1224 /* Parse incoming packet */
1225 ret = silc_buffer_unformat(buffer,
1226 SILC_STR_UI16_STRING_ALLOC(&username),
1227 SILC_STR_UI16_STRING_ALLOC(&realname),
1231 silc_free(username);
1233 silc_free(realname);
1238 silc_free(username);
1240 silc_free(realname);
1241 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1242 "Incomplete client information");
1246 /* Create Client ID */
1247 silc_id_create_client_id(server->id, server->rng, server->md5hash,
1248 username, &client_id);
1250 if (strlen(username) > 128)
1251 username[127] = '\0';
1253 /* Update client entry */
1254 idata->registered = TRUE;
1255 client->nickname = strdup(username);
1256 client->username = username;
1257 client->userinfo = realname ? realname : strdup(" ");
1258 client->id = client_id;
1260 /* Update the cache entry */
1261 cache->id = (void *)client_id;
1262 cache->type = SILC_ID_CLIENT;
1263 cache->data = username;
1264 silc_idcache_sort_by_data(server->local_list->clients);
1266 /* Notify our router about new client on the SILC network */
1267 if (!server->standalone)
1268 silc_server_send_new_id(server, (SilcSocketConnection)
1269 server->router->connection,
1270 server->server_type == SILC_ROUTER ? TRUE : FALSE,
1271 client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
1273 /* Send the new client ID to the client. */
1274 id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
1275 reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
1276 silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
1277 silc_buffer_format(reply,
1278 SILC_STR_UI_SHORT(SILC_ID_CLIENT),
1279 SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
1280 SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
1282 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0,
1283 reply->data, reply->len, FALSE);
1284 silc_free(id_string);
1285 silc_buffer_free(reply);
1287 /* Send some nice info to the client */
1288 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1289 ("Welcome to the SILC Network %s@%s",
1290 username, sock->hostname));
1291 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1292 ("Your host is %s, running version %s",
1293 server->config->server_info->server_name,
1295 if (server->server_type == SILC_ROUTER) {
1296 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1297 ("There are %d clients on %d servers in SILC "
1298 "Network", server->stat.clients,
1299 server->stat.servers + 1));
1300 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1301 ("There are %d clients on %d server in our cell",
1302 server->stat.cell_clients,
1303 server->stat.cell_servers + 1));
1304 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1305 ("I have %d clients, %d channels, %d servers and "
1307 server->stat.my_clients,
1308 server->stat.my_channels,
1309 server->stat.my_servers,
1310 server->stat.my_routers));
1311 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1312 ("%d server operators and %d router operators "
1314 server->stat.my_server_ops,
1315 server->stat.my_router_ops));
1317 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1318 ("I have %d clients and %d channels formed",
1319 server->stat.my_clients,
1320 server->stat.my_channels));
1321 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1322 ("%d operators online",
1323 server->stat.my_server_ops));
1325 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1326 ("Your connection is secured with %s cipher, "
1327 "key length %d bits",
1328 idata->send_key->cipher->name,
1329 idata->send_key->cipher->key_len));
1330 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1331 ("Your current nickname is %s",
1335 silc_server_send_motd(server, sock);
1340 /* Create new server. This processes received New Server packet and
1341 saves the received Server ID. The server is our locally connected
1342 server thus we save all the information and save it to local list.
1343 This funtion can be used by both normal server and router server.
1344 If normal server uses this it means that its router has connected
1345 to the server. If router uses this it means that one of the cell's
1346 servers is connected to the router. */
1348 SilcServerEntry silc_server_new_server(SilcServer server,
1349 SilcSocketConnection sock,
1350 SilcPacketContext *packet)
1352 SilcBuffer buffer = packet->buffer;
1353 SilcServerEntry new_server;
1354 SilcIDCacheEntry cache;
1355 SilcServerID *server_id;
1356 SilcIDListData idata;
1357 unsigned char *server_name, *id_string;
1358 unsigned short id_len, name_len;
1361 SILC_LOG_DEBUG(("Creating new server"));
1363 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
1364 sock->type != SILC_SOCKET_TYPE_ROUTER)
1367 /* Take server entry */
1368 new_server = (SilcServerEntry)sock->user_data;
1369 idata = (SilcIDListData)new_server;
1371 /* Fetch the old server cache entry so that we can update it. */
1372 if (!silc_idcache_find_by_context(server->local_list->servers,
1373 sock->user_data, &cache)) {
1374 SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
1378 /* Parse the incoming packet */
1379 ret = silc_buffer_unformat(buffer,
1380 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
1381 SILC_STR_UI16_NSTRING_ALLOC(&server_name,
1386 silc_free(id_string);
1388 silc_free(server_name);
1392 if (id_len > buffer->len) {
1393 silc_free(id_string);
1394 silc_free(server_name);
1399 server_name[255] = '\0';
1402 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
1404 silc_free(id_string);
1405 silc_free(server_name);
1408 silc_free(id_string);
1410 /* Update client entry */
1411 idata->registered = TRUE;
1412 new_server->server_name = server_name;
1413 new_server->id = server_id;
1415 /* Update the cache entry */
1416 cache->id = (void *)server_id;
1417 cache->type = SILC_ID_SERVER;
1418 cache->data = server_name;
1419 silc_idcache_sort_by_data(server->local_list->servers);
1421 /* Distribute the information about new server in the SILC network
1422 to our router. If we are normal server we won't send anything
1423 since this connection must be our router connection. */
1424 if (server->server_type == SILC_ROUTER && !server->standalone &&
1425 server->router->connection != sock)
1426 silc_server_send_new_id(server, server->router->connection,
1427 TRUE, new_server->id, SILC_ID_SERVER,
1428 SILC_ID_SERVER_LEN);
1430 if (server->server_type == SILC_ROUTER)
1431 server->stat.cell_servers++;
1436 /* Processes incoming New ID packet. New ID Payload is used to distribute
1437 information about newly registered clients and servers. */
1439 static void silc_server_new_id_real(SilcServer server,
1440 SilcSocketConnection sock,
1441 SilcPacketContext *packet,
1444 SilcBuffer buffer = packet->buffer;
1446 SilcServerEntry router;
1447 SilcSocketConnection router_sock;
1450 unsigned char *hash = NULL;
1453 SILC_LOG_DEBUG(("Processing new ID"));
1455 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1456 server->server_type == SILC_SERVER ||
1457 packet->src_id_type != SILC_ID_SERVER)
1460 idp = silc_id_payload_parse(buffer);
1464 id_type = silc_id_payload_get_type(idp);
1466 /* Normal server cannot have other normal server connections */
1467 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
1470 id = silc_id_payload_get_id(idp);
1474 /* If the sender of this packet is server and we are router we need to
1475 broadcast this packet to other routers in the network. */
1476 if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
1477 sock->type == SILC_SOCKET_TYPE_SERVER &&
1478 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1479 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
1480 silc_server_packet_send(server, server->router->connection,
1482 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1483 buffer->data, buffer->len, FALSE);
1486 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1487 id_list = server->local_list;
1489 id_list = server->global_list;
1492 router = sock->user_data;
1495 case SILC_ID_CLIENT:
1497 SilcClientEntry entry;
1499 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
1500 silc_id_render(id, SILC_ID_CLIENT),
1501 sock->type == SILC_SOCKET_TYPE_SERVER ?
1502 "Server" : "Router", sock->hostname));
1504 /* As a router we keep information of all global information in our
1505 global list. Cell wide information however is kept in the local
1506 list. The client is put to global list and we will take the hash
1507 value of the Client ID and save it to the ID Cache system for fast
1508 searching in the future. */
1509 hash = silc_calloc(sizeof(((SilcClientID *)id)->hash),
1510 sizeof(unsigned char));
1511 memcpy(hash, ((SilcClientID *)id)->hash,
1512 sizeof(((SilcClientID *)id)->hash));
1513 entry = silc_idlist_add_client(id_list, hash,
1514 sizeof(((SilcClientID *)id)->hash),
1515 NULL, NULL, id, router, NULL);
1516 entry->nickname = NULL;
1517 entry->data.registered = TRUE;
1519 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1520 server->stat.cell_clients++;
1521 server->stat.clients++;
1525 case SILC_ID_SERVER:
1526 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
1527 silc_id_render(id, SILC_ID_SERVER),
1528 sock->type == SILC_SOCKET_TYPE_SERVER ?
1529 "Server" : "Router", sock->hostname));
1531 /* As a router we keep information of all global information in our global
1532 list. Cell wide information however is kept in the local list. */
1533 silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
1535 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1536 server->stat.cell_servers++;
1537 server->stat.servers++;
1540 case SILC_ID_CHANNEL:
1541 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
1549 silc_id_payload_free(idp);
1553 /* Processes incoming New ID packet. New ID Payload is used to distribute
1554 information about newly registered clients and servers. */
1556 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
1557 SilcPacketContext *packet)
1559 silc_server_new_id_real(server, sock, packet, TRUE);
1562 /* Receoved New Id List packet, list of New ID payloads inside one
1563 packet. Process the New ID payloads one by one. */
1565 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
1566 SilcPacketContext *packet)
1568 SilcPacketContext *new_id;
1570 unsigned short id_len;
1572 SILC_LOG_DEBUG(("Processing New ID List"));
1574 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1575 packet->src_id_type != SILC_ID_SERVER)
1578 /* If the sender of this packet is server and we are router we need to
1579 broadcast this packet to other routers in the network. Broadcast
1580 this list packet instead of multiple New ID packets. */
1581 if (!server->standalone && server->server_type == SILC_ROUTER &&
1582 sock->type == SILC_SOCKET_TYPE_SERVER &&
1583 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1584 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
1585 silc_server_packet_send(server, server->router->connection,
1587 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1588 packet->buffer->data, packet->buffer->len, FALSE);
1591 /* Make copy of the original packet context, except for the actual
1592 data buffer, which we will here now fetch from the original buffer. */
1593 new_id = silc_packet_context_alloc();
1594 new_id->type = SILC_PACKET_NEW_ID;
1595 new_id->flags = packet->flags;
1596 new_id->src_id = packet->src_id;
1597 new_id->src_id_len = packet->src_id_len;
1598 new_id->src_id_type = packet->src_id_type;
1599 new_id->dst_id = packet->dst_id;
1600 new_id->dst_id_len = packet->dst_id_len;
1601 new_id->dst_id_type = packet->dst_id_type;
1603 idp = silc_buffer_alloc(256);
1604 new_id->buffer = idp;
1606 while (packet->buffer->len) {
1607 SILC_GET16_MSB(id_len, packet->buffer->data + 2);
1608 if ((id_len > packet->buffer->len) ||
1609 (id_len > idp->truelen))
1612 silc_buffer_pull_tail(idp, 4 + id_len);
1613 silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
1615 /* Process the New ID */
1616 silc_server_new_id_real(server, sock, new_id, FALSE);
1618 silc_buffer_push_tail(idp, 4 + id_len);
1619 silc_buffer_pull(packet->buffer, 4 + id_len);
1622 silc_buffer_free(idp);
1626 /* Received New Channel packet. Information about new channels in the
1627 network are distributed using this packet. Save the information about
1628 the new channel. This usually comes from router but also normal server
1629 can send this to notify channels it has when it connects to us. */
1631 void silc_server_new_channel(SilcServer server,
1632 SilcSocketConnection sock,
1633 SilcPacketContext *packet)
1635 SilcChannelPayload payload;
1636 SilcChannelID *channel_id;
1638 unsigned int name_len;
1640 unsigned int id_len;
1642 SILC_LOG_DEBUG(("Processing New Channel"));
1644 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1645 packet->src_id_type != SILC_ID_SERVER ||
1646 server->server_type == SILC_SERVER)
1649 /* Parse the channel payload */
1650 payload = silc_channel_payload_parse(packet->buffer);
1654 /* Get the channel ID */
1655 channel_id = silc_channel_get_id_parse(payload);
1657 silc_channel_payload_free(payload);
1661 channel_name = silc_channel_get_name(payload, &name_len);
1663 channel_name[255] = '\0';
1665 id = silc_channel_get_id(payload, &id_len);
1667 if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
1668 /* Add the server to global list as it is coming from router. It
1669 cannot be our own channel as it is coming from router. */
1671 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
1672 silc_id_render(channel_id, SILC_ID_CHANNEL),
1675 silc_idlist_add_channel(server->global_list, strdup(channel_name),
1676 0, channel_id, server->router->connection,
1679 server->stat.channels++;
1681 /* The channel is coming from our server, thus it is in our cell
1682 we will add it to our local list. */
1683 SilcChannelEntry channel;
1686 SILC_LOG_DEBUG(("New channel id(%s) from [Server] %s",
1687 silc_id_render(channel_id, SILC_ID_CHANNEL),
1690 /* Check that we don't already have this channel */
1691 channel = silc_idlist_find_channel_by_name(server->local_list,
1692 channel_name, NULL);
1694 channel = silc_idlist_find_channel_by_name(server->global_list,
1695 channel_name, NULL);
1697 /* If the channel does not exist, then create it. We create the channel
1698 with the channel ID provided by the server. This creates a new
1699 key to the channel as well that we will send to the server. */
1701 channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
1705 silc_channel_payload_free(payload);
1706 silc_free(channel_id);
1710 /* Send the new channel key to the server */
1711 chk = silc_channel_key_payload_encode(id_len, id,
1712 strlen(channel->channel_key->
1714 channel->channel_key->cipher->name,
1715 channel->key_len / 8,
1717 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
1718 chk->data, chk->len, FALSE);
1719 silc_buffer_free(chk);
1722 /* The channel exist by that name, check whether the ID's match.
1723 If they don't then we'll force the server to use the ID we have.
1724 We also create a new key for the channel. */
1726 if (SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
1727 /* They don't match, send CHANNEL_CHANGE notify to the server to
1728 force the ID change. */
1729 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
1730 silc_server_send_notify_channel_change(server, sock, FALSE,
1733 SILC_ID_CHANNEL_LEN);
1736 /* Create new key for the channel and send it to the server and
1737 everybody else possibly on the channel. */
1739 silc_server_create_channel_key(server, channel, 0);
1741 /* Send to the channel */
1742 silc_server_send_channel_key(server, sock, channel, FALSE);
1744 /* Send to the server */
1745 chk = silc_channel_key_payload_encode(id_len, id,
1746 strlen(channel->channel_key->
1748 channel->channel_key->cipher->name,
1749 channel->key_len / 8,
1751 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
1752 chk->data, chk->len, FALSE);
1753 silc_buffer_free(chk);
1754 silc_free(channel_id);
1756 /* Since the channel is coming from server and we also know about it
1757 then send the JOIN notify to the server so that it see's our
1758 users on the channel "joining" the channel. */
1764 /* Received New Channel List packet, list of New Channel List payloads inside
1765 one packet. Process the New Channel payloads one by one. */
1767 void silc_server_new_channel_list(SilcServer server,
1768 SilcSocketConnection sock,
1769 SilcPacketContext *packet)
1771 SilcPacketContext *new;
1773 unsigned short len1, len2;
1775 SILC_LOG_DEBUG(("Processing New Channel List"));
1777 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1778 packet->src_id_type != SILC_ID_SERVER ||
1779 server->server_type == SILC_SERVER)
1782 /* If the sender of this packet is server and we are router we need to
1783 broadcast this packet to other routers in the network. Broadcast
1784 this list packet instead of multiple New Channel packets. */
1785 if (!server->standalone && server->server_type == SILC_ROUTER &&
1786 sock->type == SILC_SOCKET_TYPE_SERVER &&
1787 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1788 SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
1789 silc_server_packet_send(server, server->router->connection,
1791 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1792 packet->buffer->data, packet->buffer->len, FALSE);
1795 /* Make copy of the original packet context, except for the actual
1796 data buffer, which we will here now fetch from the original buffer. */
1797 new = silc_packet_context_alloc();
1798 new->type = SILC_PACKET_NEW_CHANNEL;
1799 new->flags = packet->flags;
1800 new->src_id = packet->src_id;
1801 new->src_id_len = packet->src_id_len;
1802 new->src_id_type = packet->src_id_type;
1803 new->dst_id = packet->dst_id;
1804 new->dst_id_len = packet->dst_id_len;
1805 new->dst_id_type = packet->dst_id_type;
1807 buffer = silc_buffer_alloc(512);
1808 new->buffer = buffer;
1810 while (packet->buffer->len) {
1811 SILC_GET16_MSB(len1, packet->buffer->data);
1812 if ((len1 > packet->buffer->len) ||
1813 (len1 > buffer->truelen))
1816 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
1817 if ((len2 > packet->buffer->len) ||
1818 (len2 > buffer->truelen))
1821 silc_buffer_pull_tail(buffer, 8 + len1 + len2);
1822 silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
1824 /* Process the New Channel */
1825 silc_server_new_channel(server, sock, new);
1827 silc_buffer_push_tail(buffer, 8 + len1 + len2);
1828 silc_buffer_pull(packet->buffer, 8 + len1 + len2);
1831 silc_buffer_free(buffer);
1835 /* Received key agreement packet. This packet is never for us. It is to
1836 the client in the packet's destination ID. Sending of this sort of packet
1837 equals sending private message, ie. it is sent point to point from
1838 one client to another. */
1840 void silc_server_key_agreement(SilcServer server,
1841 SilcSocketConnection sock,
1842 SilcPacketContext *packet)
1844 SilcSocketConnection dst_sock;
1845 SilcIDListData idata;
1847 SILC_LOG_DEBUG(("Start"));
1849 if (packet->src_id_type != SILC_ID_CLIENT ||
1850 packet->dst_id_type != SILC_ID_CLIENT)
1853 if (!packet->dst_id)
1856 /* Get the route to the client */
1857 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1858 packet->dst_id_len, NULL, &idata);
1862 /* Relay the packet */
1863 silc_server_relay_packet(server, dst_sock, idata->send_key,
1864 idata->hmac, packet, FALSE);
1867 /* Received connection auth request packet that is used during connection
1868 phase to resolve the mandatory authentication method. This packet can
1869 actually be received at anytime but usually it is used only during
1870 the connection authentication phase. Now, protocol says that this packet
1871 can come from client or server, however, we support only this coming
1872 from client and expect that server's always knows what authentication
1875 void silc_server_connection_auth_request(SilcServer server,
1876 SilcSocketConnection sock,
1877 SilcPacketContext *packet)
1879 SilcServerConfigSectionClientConnection *client = NULL;
1880 unsigned short conn_type;
1882 SilcAuthMethod auth_meth;
1884 SILC_LOG_DEBUG(("Start"));
1886 if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT)
1889 /* Parse the payload */
1890 ret = silc_buffer_unformat(packet->buffer,
1891 SILC_STR_UI_SHORT(&conn_type),
1892 SILC_STR_UI_SHORT(NULL),
1897 if (conn_type != SILC_SOCKET_TYPE_CLIENT)
1900 /* Get the authentication method for the client */
1901 auth_meth = SILC_AUTH_NONE;
1902 client = silc_server_config_find_client_conn(server->config,
1906 client = silc_server_config_find_client_conn(server->config,
1910 auth_meth = client->auth_meth;
1912 /* Send it back to the client */
1913 silc_server_send_connection_auth_request(server, sock,