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, data_len;
1135 iv_len = silc_cipher_get_block_len(channel->channel_key);
1136 if (channel->iv[0] == '\0')
1137 for (i = 0; i < iv_len; i++) channel->iv[i] =
1138 silc_rng_get_byte(server->rng);
1140 silc_hash_make(server->md5hash, channel->iv, iv_len, channel->iv);
1142 /* Encode new payload. This encrypts it also. */
1143 SILC_GET16_MSB(data_len, packet->buffer->data);
1144 chp = silc_channel_message_payload_encode(data_len,
1145 packet->buffer->data + 2,
1146 iv_len, channel->iv,
1147 channel->channel_key,
1148 channel->hmac, server->rng);
1149 silc_buffer_put(packet->buffer, chp->data, chp->len);
1150 silc_buffer_free(chp);
1153 /* Distribute the packet to our local clients. This will send the
1154 packet for further routing as well, if needed. */
1155 silc_server_packet_relay_to_channel(server, sock, channel, sender,
1156 packet->src_id_type,
1157 packet->buffer->data,
1158 packet->buffer->len, FALSE);
1167 /* Received channel key packet. We distribute the key to all of our locally
1168 connected clients on the channel. */
1170 void silc_server_channel_key(SilcServer server,
1171 SilcSocketConnection sock,
1172 SilcPacketContext *packet)
1174 SilcBuffer buffer = packet->buffer;
1175 SilcChannelEntry channel;
1177 if (packet->src_id_type != SILC_ID_SERVER)
1180 /* Save the channel key */
1181 channel = silc_server_save_channel_key(server, buffer, NULL);
1185 /* Distribute the key to everybody who is on the channel. If we are router
1186 we will also send it to locally connected servers. */
1187 silc_server_send_channel_key(server, sock, channel, FALSE);
1190 /* Received New Client packet and processes it. Creates Client ID for the
1191 client. Client becomes registered after calling this functions. */
1193 SilcClientEntry silc_server_new_client(SilcServer server,
1194 SilcSocketConnection sock,
1195 SilcPacketContext *packet)
1197 SilcBuffer buffer = packet->buffer;
1198 SilcClientEntry client;
1199 SilcIDCacheEntry cache;
1200 SilcClientID *client_id;
1202 SilcIDListData idata;
1203 char *username = NULL, *realname = NULL, *id_string;
1206 SILC_LOG_DEBUG(("Creating new client"));
1208 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
1211 /* Take client entry */
1212 client = (SilcClientEntry)sock->user_data;
1213 idata = (SilcIDListData)client;
1215 /* Fetch the old client cache entry so that we can update it. */
1216 if (!silc_idcache_find_by_context(server->local_list->clients,
1217 sock->user_data, &cache)) {
1218 SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
1222 /* Parse incoming packet */
1223 ret = silc_buffer_unformat(buffer,
1224 SILC_STR_UI16_STRING_ALLOC(&username),
1225 SILC_STR_UI16_STRING_ALLOC(&realname),
1229 silc_free(username);
1231 silc_free(realname);
1236 silc_free(username);
1238 silc_free(realname);
1239 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1240 "Incomplete client information");
1244 /* Create Client ID */
1245 silc_id_create_client_id(server->id, server->rng, server->md5hash,
1246 username, &client_id);
1248 if (strlen(username) > 128)
1249 username[127] = '\0';
1251 /* Update client entry */
1252 idata->registered = TRUE;
1253 client->nickname = strdup(username);
1254 client->username = username;
1255 client->userinfo = realname ? realname : strdup(" ");
1256 client->id = client_id;
1258 /* Update the cache entry */
1259 cache->id = (void *)client_id;
1260 cache->type = SILC_ID_CLIENT;
1261 cache->data = username;
1262 silc_idcache_sort_by_data(server->local_list->clients);
1264 /* Notify our router about new client on the SILC network */
1265 if (!server->standalone)
1266 silc_server_send_new_id(server, (SilcSocketConnection)
1267 server->router->connection,
1268 server->server_type == SILC_ROUTER ? TRUE : FALSE,
1269 client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
1271 /* Send the new client ID to the client. */
1272 id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
1273 reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
1274 silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
1275 silc_buffer_format(reply,
1276 SILC_STR_UI_SHORT(SILC_ID_CLIENT),
1277 SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
1278 SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
1280 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0,
1281 reply->data, reply->len, FALSE);
1282 silc_free(id_string);
1283 silc_buffer_free(reply);
1285 /* Send some nice info to the client */
1286 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1287 ("Welcome to the SILC Network %s@%s",
1288 username, sock->hostname));
1289 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1290 ("Your host is %s, running version %s",
1291 server->config->server_info->server_name,
1293 if (server->server_type == SILC_ROUTER) {
1294 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1295 ("There are %d clients on %d servers in SILC "
1296 "Network", server->stat.clients,
1297 server->stat.servers + 1));
1298 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1299 ("There are %d clients on %d server in our cell",
1300 server->stat.cell_clients,
1301 server->stat.cell_servers + 1));
1302 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1303 ("I have %d clients, %d channels, %d servers and "
1305 server->stat.my_clients,
1306 server->stat.my_channels,
1307 server->stat.my_servers,
1308 server->stat.my_routers));
1309 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1310 ("%d server operators and %d router operators "
1312 server->stat.my_server_ops,
1313 server->stat.my_router_ops));
1315 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1316 ("I have %d clients and %d channels formed",
1317 server->stat.my_clients,
1318 server->stat.my_channels));
1319 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1320 ("%d operators online",
1321 server->stat.my_server_ops));
1323 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1324 ("Your connection is secured with %s cipher, "
1325 "key length %d bits",
1326 idata->send_key->cipher->name,
1327 idata->send_key->cipher->key_len));
1328 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1329 ("Your current nickname is %s",
1333 silc_server_send_motd(server, sock);
1338 /* Create new server. This processes received New Server packet and
1339 saves the received Server ID. The server is our locally connected
1340 server thus we save all the information and save it to local list.
1341 This funtion can be used by both normal server and router server.
1342 If normal server uses this it means that its router has connected
1343 to the server. If router uses this it means that one of the cell's
1344 servers is connected to the router. */
1346 SilcServerEntry silc_server_new_server(SilcServer server,
1347 SilcSocketConnection sock,
1348 SilcPacketContext *packet)
1350 SilcBuffer buffer = packet->buffer;
1351 SilcServerEntry new_server;
1352 SilcIDCacheEntry cache;
1353 SilcServerID *server_id;
1354 SilcIDListData idata;
1355 unsigned char *server_name, *id_string;
1356 unsigned short id_len, name_len;
1359 SILC_LOG_DEBUG(("Creating new server"));
1361 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
1362 sock->type != SILC_SOCKET_TYPE_ROUTER)
1365 /* Take server entry */
1366 new_server = (SilcServerEntry)sock->user_data;
1367 idata = (SilcIDListData)new_server;
1369 /* Fetch the old server cache entry so that we can update it. */
1370 if (!silc_idcache_find_by_context(server->local_list->servers,
1371 sock->user_data, &cache)) {
1372 SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
1376 /* Parse the incoming packet */
1377 ret = silc_buffer_unformat(buffer,
1378 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
1379 SILC_STR_UI16_NSTRING_ALLOC(&server_name,
1384 silc_free(id_string);
1386 silc_free(server_name);
1390 if (id_len > buffer->len) {
1391 silc_free(id_string);
1392 silc_free(server_name);
1397 server_name[255] = '\0';
1400 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
1402 silc_free(id_string);
1403 silc_free(server_name);
1406 silc_free(id_string);
1408 /* Update client entry */
1409 idata->registered = TRUE;
1410 new_server->server_name = server_name;
1411 new_server->id = server_id;
1413 /* Update the cache entry */
1414 cache->id = (void *)server_id;
1415 cache->type = SILC_ID_SERVER;
1416 cache->data = server_name;
1417 silc_idcache_sort_by_data(server->local_list->servers);
1419 /* Distribute the information about new server in the SILC network
1420 to our router. If we are normal server we won't send anything
1421 since this connection must be our router connection. */
1422 if (server->server_type == SILC_ROUTER && !server->standalone &&
1423 server->router->connection != sock)
1424 silc_server_send_new_id(server, server->router->connection,
1425 TRUE, new_server->id, SILC_ID_SERVER,
1426 SILC_ID_SERVER_LEN);
1428 if (server->server_type == SILC_ROUTER)
1429 server->stat.cell_servers++;
1434 /* Processes incoming New ID packet. New ID Payload is used to distribute
1435 information about newly registered clients and servers. */
1437 static void silc_server_new_id_real(SilcServer server,
1438 SilcSocketConnection sock,
1439 SilcPacketContext *packet,
1442 SilcBuffer buffer = packet->buffer;
1444 SilcServerEntry router;
1445 SilcSocketConnection router_sock;
1448 unsigned char *hash = NULL;
1451 SILC_LOG_DEBUG(("Processing new ID"));
1453 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1454 server->server_type == SILC_SERVER ||
1455 packet->src_id_type != SILC_ID_SERVER)
1458 idp = silc_id_payload_parse(buffer);
1462 id_type = silc_id_payload_get_type(idp);
1464 /* Normal server cannot have other normal server connections */
1465 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
1468 id = silc_id_payload_get_id(idp);
1472 /* If the sender of this packet is server and we are router we need to
1473 broadcast this packet to other routers in the network. */
1474 if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
1475 sock->type == SILC_SOCKET_TYPE_SERVER &&
1476 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1477 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
1478 silc_server_packet_send(server, server->router->connection,
1480 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1481 buffer->data, buffer->len, FALSE);
1484 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1485 id_list = server->local_list;
1487 id_list = server->global_list;
1490 router = sock->user_data;
1493 case SILC_ID_CLIENT:
1495 SilcClientEntry entry;
1497 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
1498 silc_id_render(id, SILC_ID_CLIENT),
1499 sock->type == SILC_SOCKET_TYPE_SERVER ?
1500 "Server" : "Router", sock->hostname));
1502 /* As a router we keep information of all global information in our
1503 global list. Cell wide information however is kept in the local
1504 list. The client is put to global list and we will take the hash
1505 value of the Client ID and save it to the ID Cache system for fast
1506 searching in the future. */
1507 hash = silc_calloc(sizeof(((SilcClientID *)id)->hash),
1508 sizeof(unsigned char));
1509 memcpy(hash, ((SilcClientID *)id)->hash,
1510 sizeof(((SilcClientID *)id)->hash));
1511 entry = silc_idlist_add_client(id_list, hash,
1512 sizeof(((SilcClientID *)id)->hash),
1513 NULL, NULL, id, router, NULL);
1514 entry->nickname = NULL;
1515 entry->data.registered = TRUE;
1517 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1518 server->stat.cell_clients++;
1519 server->stat.clients++;
1523 case SILC_ID_SERVER:
1524 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
1525 silc_id_render(id, SILC_ID_SERVER),
1526 sock->type == SILC_SOCKET_TYPE_SERVER ?
1527 "Server" : "Router", sock->hostname));
1529 /* As a router we keep information of all global information in our global
1530 list. Cell wide information however is kept in the local list. */
1531 silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
1533 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1534 server->stat.cell_servers++;
1535 server->stat.servers++;
1538 case SILC_ID_CHANNEL:
1539 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
1547 silc_id_payload_free(idp);
1551 /* Processes incoming New ID packet. New ID Payload is used to distribute
1552 information about newly registered clients and servers. */
1554 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
1555 SilcPacketContext *packet)
1557 silc_server_new_id_real(server, sock, packet, TRUE);
1560 /* Receoved New Id List packet, list of New ID payloads inside one
1561 packet. Process the New ID payloads one by one. */
1563 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
1564 SilcPacketContext *packet)
1566 SilcPacketContext *new_id;
1568 unsigned short id_len;
1570 SILC_LOG_DEBUG(("Processing New ID List"));
1572 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1573 packet->src_id_type != SILC_ID_SERVER)
1576 /* If the sender of this packet is server and we are router we need to
1577 broadcast this packet to other routers in the network. Broadcast
1578 this list packet instead of multiple New ID packets. */
1579 if (!server->standalone && server->server_type == SILC_ROUTER &&
1580 sock->type == SILC_SOCKET_TYPE_SERVER &&
1581 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1582 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
1583 silc_server_packet_send(server, server->router->connection,
1585 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1586 packet->buffer->data, packet->buffer->len, FALSE);
1589 /* Make copy of the original packet context, except for the actual
1590 data buffer, which we will here now fetch from the original buffer. */
1591 new_id = silc_packet_context_alloc();
1592 new_id->type = SILC_PACKET_NEW_ID;
1593 new_id->flags = packet->flags;
1594 new_id->src_id = packet->src_id;
1595 new_id->src_id_len = packet->src_id_len;
1596 new_id->src_id_type = packet->src_id_type;
1597 new_id->dst_id = packet->dst_id;
1598 new_id->dst_id_len = packet->dst_id_len;
1599 new_id->dst_id_type = packet->dst_id_type;
1601 idp = silc_buffer_alloc(256);
1602 new_id->buffer = idp;
1604 while (packet->buffer->len) {
1605 SILC_GET16_MSB(id_len, packet->buffer->data + 2);
1606 if ((id_len > packet->buffer->len) ||
1607 (id_len > idp->truelen))
1610 silc_buffer_pull_tail(idp, 4 + id_len);
1611 silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
1613 /* Process the New ID */
1614 silc_server_new_id_real(server, sock, new_id, FALSE);
1616 silc_buffer_push_tail(idp, 4 + id_len);
1617 silc_buffer_pull(packet->buffer, 4 + id_len);
1620 silc_buffer_free(idp);
1624 /* Received New Channel packet. Information about new channels in the
1625 network are distributed using this packet. Save the information about
1626 the new channel. This usually comes from router but also normal server
1627 can send this to notify channels it has when it connects to us. */
1629 void silc_server_new_channel(SilcServer server,
1630 SilcSocketConnection sock,
1631 SilcPacketContext *packet)
1633 SilcChannelPayload payload;
1634 SilcChannelID *channel_id;
1636 unsigned int name_len;
1638 unsigned int id_len;
1640 SILC_LOG_DEBUG(("Processing New Channel"));
1642 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1643 packet->src_id_type != SILC_ID_SERVER ||
1644 server->server_type == SILC_SERVER)
1647 /* Parse the channel payload */
1648 payload = silc_channel_payload_parse(packet->buffer);
1652 /* Get the channel ID */
1653 channel_id = silc_channel_get_id_parse(payload);
1655 silc_channel_payload_free(payload);
1659 channel_name = silc_channel_get_name(payload, &name_len);
1661 channel_name[255] = '\0';
1663 id = silc_channel_get_id(payload, &id_len);
1665 if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
1666 /* Add the server to global list as it is coming from router. It
1667 cannot be our own channel as it is coming from router. */
1669 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
1670 silc_id_render(channel_id, SILC_ID_CHANNEL),
1673 silc_idlist_add_channel(server->global_list, strdup(channel_name),
1674 0, channel_id, server->router->connection,
1677 server->stat.channels++;
1679 /* The channel is coming from our server, thus it is in our cell
1680 we will add it to our local list. */
1681 SilcChannelEntry channel;
1684 SILC_LOG_DEBUG(("New channel id(%s) from [Server] %s",
1685 silc_id_render(channel_id, SILC_ID_CHANNEL),
1688 /* Check that we don't already have this channel */
1689 channel = silc_idlist_find_channel_by_name(server->local_list,
1690 channel_name, NULL);
1692 channel = silc_idlist_find_channel_by_name(server->global_list,
1693 channel_name, NULL);
1695 /* If the channel does not exist, then create it. We create the channel
1696 with the channel ID provided by the server. This creates a new
1697 key to the channel as well that we will send to the server. */
1699 channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
1703 silc_channel_payload_free(payload);
1704 silc_free(channel_id);
1708 /* Send the new channel key to the server */
1709 chk = silc_channel_key_payload_encode(id_len, id,
1710 strlen(channel->channel_key->
1712 channel->channel_key->cipher->name,
1713 channel->key_len / 8,
1715 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
1716 chk->data, chk->len, FALSE);
1717 silc_buffer_free(chk);
1720 /* The channel exist by that name, check whether the ID's match.
1721 If they don't then we'll force the server to use the ID we have.
1722 We also create a new key for the channel. */
1724 if (SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
1725 /* They don't match, send CHANNEL_CHANGE notify to the server to
1726 force the ID change. */
1727 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
1728 silc_server_send_notify_channel_change(server, sock, FALSE,
1731 SILC_ID_CHANNEL_LEN);
1734 /* Create new key for the channel and send it to the server and
1735 everybody else possibly on the channel. */
1737 silc_server_create_channel_key(server, channel, 0);
1739 /* Send to the channel */
1740 silc_server_send_channel_key(server, sock, channel, FALSE);
1742 /* Send to the server */
1743 chk = silc_channel_key_payload_encode(id_len, id,
1744 strlen(channel->channel_key->
1746 channel->channel_key->cipher->name,
1747 channel->key_len / 8,
1749 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
1750 chk->data, chk->len, FALSE);
1751 silc_buffer_free(chk);
1752 silc_free(channel_id);
1754 /* Since the channel is coming from server and we also know about it
1755 then send the JOIN notify to the server so that it see's our
1756 users on the channel "joining" the channel. */
1762 /* Received New Channel List packet, list of New Channel List payloads inside
1763 one packet. Process the New Channel payloads one by one. */
1765 void silc_server_new_channel_list(SilcServer server,
1766 SilcSocketConnection sock,
1767 SilcPacketContext *packet)
1769 SilcPacketContext *new;
1771 unsigned short len1, len2;
1773 SILC_LOG_DEBUG(("Processing New Channel List"));
1775 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1776 packet->src_id_type != SILC_ID_SERVER ||
1777 server->server_type == SILC_SERVER)
1780 /* If the sender of this packet is server and we are router we need to
1781 broadcast this packet to other routers in the network. Broadcast
1782 this list packet instead of multiple New Channel packets. */
1783 if (!server->standalone && server->server_type == SILC_ROUTER &&
1784 sock->type == SILC_SOCKET_TYPE_SERVER &&
1785 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1786 SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
1787 silc_server_packet_send(server, server->router->connection,
1789 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1790 packet->buffer->data, packet->buffer->len, FALSE);
1793 /* Make copy of the original packet context, except for the actual
1794 data buffer, which we will here now fetch from the original buffer. */
1795 new = silc_packet_context_alloc();
1796 new->type = SILC_PACKET_NEW_CHANNEL;
1797 new->flags = packet->flags;
1798 new->src_id = packet->src_id;
1799 new->src_id_len = packet->src_id_len;
1800 new->src_id_type = packet->src_id_type;
1801 new->dst_id = packet->dst_id;
1802 new->dst_id_len = packet->dst_id_len;
1803 new->dst_id_type = packet->dst_id_type;
1805 buffer = silc_buffer_alloc(512);
1806 new->buffer = buffer;
1808 while (packet->buffer->len) {
1809 SILC_GET16_MSB(len1, packet->buffer->data);
1810 if ((len1 > packet->buffer->len) ||
1811 (len1 > buffer->truelen))
1814 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
1815 if ((len2 > packet->buffer->len) ||
1816 (len2 > buffer->truelen))
1819 silc_buffer_pull_tail(buffer, 8 + len1 + len2);
1820 silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
1822 /* Process the New Channel */
1823 silc_server_new_channel(server, sock, new);
1825 silc_buffer_push_tail(buffer, 8 + len1 + len2);
1826 silc_buffer_pull(packet->buffer, 8 + len1 + len2);
1829 silc_buffer_free(buffer);
1833 /* Received key agreement packet. This packet is never for us. It is to
1834 the client in the packet's destination ID. Sending of this sort of packet
1835 equals sending private message, ie. it is sent point to point from
1836 one client to another. */
1838 void silc_server_key_agreement(SilcServer server,
1839 SilcSocketConnection sock,
1840 SilcPacketContext *packet)
1842 SilcSocketConnection dst_sock;
1843 SilcIDListData idata;
1845 SILC_LOG_DEBUG(("Start"));
1847 if (packet->src_id_type != SILC_ID_CLIENT ||
1848 packet->dst_id_type != SILC_ID_CLIENT)
1851 if (!packet->dst_id)
1854 /* Get the route to the client */
1855 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1856 packet->dst_id_len, NULL, &idata);
1860 /* Relay the packet */
1861 silc_server_relay_packet(server, dst_sock, idata->send_key,
1862 idata->hmac, packet, FALSE);
1865 /* Received connection auth request packet that is used during connection
1866 phase to resolve the mandatory authentication method. This packet can
1867 actually be received at anytime but usually it is used only during
1868 the connection authentication phase. Now, protocol says that this packet
1869 can come from client or server, however, we support only this coming
1870 from client and expect that server's always knows what authentication
1873 void silc_server_connection_auth_request(SilcServer server,
1874 SilcSocketConnection sock,
1875 SilcPacketContext *packet)
1877 SilcServerConfigSectionClientConnection *client = NULL;
1878 unsigned short conn_type;
1880 SilcAuthMethod auth_meth;
1882 SILC_LOG_DEBUG(("Start"));
1884 if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT)
1887 /* Parse the payload */
1888 ret = silc_buffer_unformat(packet->buffer,
1889 SILC_STR_UI_SHORT(&conn_type),
1890 SILC_STR_UI_SHORT(NULL),
1895 if (conn_type != SILC_SOCKET_TYPE_CLIENT)
1898 /* Get the authentication method for the client */
1899 auth_meth = SILC_AUTH_NONE;
1900 client = silc_server_config_find_client_conn(server->config,
1904 client = silc_server_config_find_client_conn(server->config,
1908 auth_meth = client->auth_meth;
1910 /* Send it back to the client */
1911 silc_server_send_connection_auth_request(server, sock,