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);
425 /* If the channel had private keys set and the mode was removed then
426 we must re-generate and re-distribute a new channel key */
427 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY &&
428 !(mode & SILC_CHANNEL_MODE_PRIVKEY)) {
429 /* Re-generate channel key */
430 silc_server_create_channel_key(server, channel, 0);
432 /* Send the channel key. This sends it to our local clients and if
433 we are normal server to our router as well. */
434 silc_server_send_channel_key(server, NULL, channel,
435 server->server_type == SILC_ROUTER ?
436 FALSE : !server->standalone);
440 channel->mode = mode;
441 silc_free(channel_id);
444 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
446 unsigned char hash[32];
449 silc_hmac_free(channel->hmac);
450 if (!silc_hmac_alloc(tmp, NULL, &channel->hmac))
453 /* Set the HMAC key out of current channel key. The client must do
455 silc_hash_make(channel->hmac->hash, channel->key, channel->key_len / 8,
457 silc_hmac_set_key(channel->hmac, hash,
458 silc_hash_len(channel->hmac->hash));
459 memset(hash, 0, sizeof(hash));
464 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
466 * Distribute the notify to local clients on the channel
469 SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
471 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
472 packet->dst_id_type);
476 /* Get channel entry */
477 channel = silc_idlist_find_channel_by_id(server->global_list,
480 channel = silc_idlist_find_channel_by_id(server->local_list,
483 silc_free(channel_id);
489 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
491 silc_free(channel_id);
495 SILC_GET32_MSB(mode, tmp);
497 /* Get target client */
498 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
501 client_id = silc_id_payload_parse_id(tmp, tmp_len);
505 /* Get client entry */
506 client = silc_idlist_find_client_by_id(server->global_list,
509 client = silc_idlist_find_client_by_id(server->local_list,
512 silc_free(client_id);
516 silc_free(client_id);
518 /* Get entry to the channel user list */
519 silc_list_start(channel->user_list);
520 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END)
521 if (chl->client == client) {
522 /* Change the mode */
527 /* Send the same notify to the channel */
528 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
529 FALSE, packet->buffer->data,
530 packet->buffer->len, FALSE);
531 silc_free(channel_id);
534 case SILC_NOTIFY_TYPE_INVITE:
536 if (packet->dst_id_type == SILC_ID_CLIENT)
539 SILC_LOG_DEBUG(("INVITE notify"));
542 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
545 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
549 /* Get channel entry */
550 channel = silc_idlist_find_channel_by_id(server->global_list,
553 channel = silc_idlist_find_channel_by_id(server->local_list,
556 silc_free(channel_id);
560 silc_free(channel_id);
562 /* Get the added invite */
563 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
565 if (!channel->invite_list)
566 channel->invite_list = silc_calloc(tmp_len + 2,
567 sizeof(*channel->invite_list));
569 channel->invite_list = silc_realloc(channel->invite_list,
570 sizeof(*channel->invite_list) *
572 strlen(channel->invite_list) +
574 if (tmp[tmp_len - 1] == ',')
575 tmp[tmp_len - 1] = '\0';
577 strncat(channel->invite_list, tmp, tmp_len);
578 strncat(channel->invite_list, ",", 1);
581 /* Get the deleted invite */
582 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
583 if (tmp && channel->invite_list) {
584 char *start, *end, *n;
586 if (!strncmp(channel->invite_list, tmp,
587 strlen(channel->invite_list) - 1)) {
588 silc_free(channel->invite_list);
589 channel->invite_list = NULL;
591 start = strstr(channel->invite_list, tmp);
592 if (start && strlen(start) >= tmp_len) {
593 end = start + tmp_len;
594 n = silc_calloc(strlen(channel->invite_list) - tmp_len, sizeof(*n));
595 strncat(n, channel->invite_list, start - channel->invite_list);
596 strncat(n, end + 1, ((channel->invite_list +
597 strlen(channel->invite_list)) - end) - 1);
598 silc_free(channel->invite_list);
599 channel->invite_list = n;
606 case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
608 * Distribute to the local clients on the channel and change the
612 SILC_LOG_DEBUG(("CHANNEL CHANGE"));
614 if (sock->type != SILC_SOCKET_TYPE_ROUTER)
617 /* Get the old Channel ID */
618 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
621 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
625 /* Get the channel entry */
626 channel = silc_idlist_find_channel_by_id(server->global_list,
629 channel = silc_idlist_find_channel_by_id(server->local_list,
632 silc_free(channel_id);
637 /* Send the notify to the channel */
638 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
639 FALSE, packet->buffer->data,
640 packet->buffer->len, FALSE);
642 /* Get the new Channel ID */
643 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
646 channel_id2 = silc_id_payload_parse_id(tmp, tmp_len);
650 SILC_LOG_DEBUG(("Old Channel ID id(%s)",
651 silc_id_render(channel_id, SILC_ID_CHANNEL)));
652 SILC_LOG_DEBUG(("New Channel ID id(%s)",
653 silc_id_render(channel_id2, SILC_ID_CHANNEL)));
655 /* Replace the Channel ID */
656 if (!silc_idlist_replace_channel_id(server->global_list, channel_id,
658 if (!silc_idlist_replace_channel_id(server->local_list, channel_id,
660 silc_free(channel_id2);
665 SilcBuffer users = NULL;
667 /* Re-announce our clients on the channel as the ID has changed now */
668 silc_server_announce_get_channel_users(server, channel, &users);
670 silc_buffer_push(users, users->data - users->head);
671 silc_server_packet_send(server, sock,
672 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
673 users->data, users->len, FALSE);
674 silc_buffer_free(users);
678 silc_free(channel_id);
682 case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
683 SILC_LOG_DEBUG(("SERVER SIGNOFF notify (not-impl XXX)"));
686 case SILC_NOTIFY_TYPE_KICKED:
688 * Distribute the notify to local clients on the channel
691 SILC_LOG_DEBUG(("KICKED notify"));
693 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
694 packet->dst_id_type);
698 /* Get channel entry */
699 channel = silc_idlist_find_channel_by_id(server->global_list,
702 channel = silc_idlist_find_channel_by_id(server->local_list,
705 silc_free(channel_id);
709 silc_free(channel_id);
712 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
715 client_id = silc_id_payload_parse_id(tmp, tmp_len);
719 /* Send to channel */
720 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
721 FALSE, packet->buffer->data,
722 packet->buffer->len, FALSE);
724 /* If the the client is not in local list we check global list */
725 client = silc_idlist_find_client_by_id(server->global_list,
728 client = silc_idlist_find_client_by_id(server->local_list,
731 silc_free(client_id);
736 /* Remove the client from channel */
737 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
741 case SILC_NOTIFY_TYPE_KILLED:
744 * Distribute the notify to local clients on channels
749 SILC_LOG_DEBUG(("KILLED notify"));
752 id = silc_argument_get_arg_type(args, 1, &id_len);
755 client_id = silc_id_payload_parse_id(id, id_len);
759 /* If the the client is not in local list we check global list */
760 client = silc_idlist_find_client_by_id(server->global_list,
763 client = silc_idlist_find_client_by_id(server->local_list,
766 silc_free(client_id);
770 silc_free(client_id);
772 /* If the client is one of ours, then close the connection to the
773 client now. This removes the client from all channels as well. */
774 if (packet->dst_id_type == SILC_ID_CLIENT && client->data.registered &&
775 client->connection) {
776 sock = client->connection;
777 silc_server_free_client_data(server, NULL, client, FALSE, NULL);
778 silc_server_close_connection(server, sock);
783 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
787 /* Send the notify to local clients on the channels except to the
788 client who is killed. */
789 silc_server_send_notify_on_channels(server, client, client,
790 SILC_NOTIFY_TYPE_KILLED,
795 /* Remove the client from all channels */
796 silc_server_remove_from_channels(server, NULL, client, FALSE, NULL,
802 case SILC_NOTIFY_TYPE_UMODE_CHANGE:
804 * Save the mode of the client.
807 SILC_LOG_DEBUG(("UMODE_CHANGE notify"));
810 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
813 client_id = silc_id_payload_parse_id(tmp, tmp_len);
817 /* Get client entry */
818 client = silc_idlist_find_client_by_id(server->global_list,
821 client = silc_idlist_find_client_by_id(server->local_list,
824 silc_free(client_id);
828 silc_free(client_id);
831 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
836 SILC_GET32_MSB(client->mode, tmp);
840 case SILC_NOTIFY_TYPE_BAN:
845 SILC_LOG_DEBUG(("BAN notify"));
848 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
851 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
855 /* Get channel entry */
856 channel = silc_idlist_find_channel_by_id(server->global_list,
859 channel = silc_idlist_find_channel_by_id(server->local_list,
862 silc_free(channel_id);
866 silc_free(channel_id);
868 /* Get the new ban and add it to the ban list */
869 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
871 if (!channel->ban_list)
872 channel->ban_list = silc_calloc(tmp_len + 2,
873 sizeof(*channel->ban_list));
875 channel->ban_list = silc_realloc(channel->ban_list,
876 sizeof(*channel->ban_list) *
878 strlen(channel->ban_list) + 2));
879 strncat(channel->ban_list, tmp, tmp_len);
880 strncat(channel->ban_list, ",", 1);
883 /* Get the ban to be removed and remove it from the list */
884 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
885 if (tmp && channel->ban_list) {
886 char *start, *end, *n;
888 if (!strcmp(channel->ban_list, tmp)) {
889 silc_free(channel->ban_list);
890 channel->ban_list = NULL;
892 start = strstr(channel->ban_list, tmp);
893 if (start && strlen(start) >= tmp_len) {
894 end = start + tmp_len;
895 n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
896 strncat(n, channel->ban_list, start - channel->ban_list);
897 strncat(n, end + 1, ((channel->ban_list +
898 strlen(channel->ban_list)) - end) - 1);
899 silc_free(channel->ban_list);
900 channel->ban_list = n;
907 /* Ignore rest of the notify types for now */
908 case SILC_NOTIFY_TYPE_NONE:
909 case SILC_NOTIFY_TYPE_MOTD:
916 silc_notify_payload_free(payload);
919 void silc_server_notify_list(SilcServer server,
920 SilcSocketConnection sock,
921 SilcPacketContext *packet)
923 SilcPacketContext *new;
927 SILC_LOG_DEBUG(("Processing New Notify List"));
929 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
930 packet->src_id_type != SILC_ID_SERVER)
933 /* Make copy of the original packet context, except for the actual
934 data buffer, which we will here now fetch from the original buffer. */
935 new = silc_packet_context_alloc();
936 new->type = SILC_PACKET_NOTIFY;
937 new->flags = packet->flags;
938 new->src_id = packet->src_id;
939 new->src_id_len = packet->src_id_len;
940 new->src_id_type = packet->src_id_type;
941 new->dst_id = packet->dst_id;
942 new->dst_id_len = packet->dst_id_len;
943 new->dst_id_type = packet->dst_id_type;
945 buffer = silc_buffer_alloc(1024);
946 new->buffer = buffer;
948 while (packet->buffer->len) {
949 SILC_GET16_MSB(len, packet->buffer->data + 2);
950 if (len > packet->buffer->len)
953 if (len > buffer->truelen) {
954 silc_buffer_free(buffer);
955 buffer = silc_buffer_alloc(1024 + len);
958 silc_buffer_pull_tail(buffer, len);
959 silc_buffer_put(buffer, packet->buffer->data, len);
961 /* Process the Notify */
962 silc_server_notify(server, sock, new);
964 silc_buffer_push_tail(buffer, len);
965 silc_buffer_pull(packet->buffer, len);
968 silc_buffer_free(buffer);
972 /* Received private message. This resolves the destination of the message
973 and sends the packet. This is used by both server and router. If the
974 destination is our locally connected client this sends the packet to
975 the client. This may also send the message for further routing if
976 the destination is not in our server (or router). */
978 void silc_server_private_message(SilcServer server,
979 SilcSocketConnection sock,
980 SilcPacketContext *packet)
982 SilcSocketConnection dst_sock;
983 SilcIDListData idata;
985 SILC_LOG_DEBUG(("Start"));
987 if (packet->src_id_type != SILC_ID_CLIENT ||
988 packet->dst_id_type != SILC_ID_CLIENT)
994 /* Get the route to the client */
995 dst_sock = silc_server_get_client_route(server, packet->dst_id,
996 packet->dst_id_len, NULL, &idata);
1000 /* Send the private message */
1001 silc_server_send_private_message(server, dst_sock, idata->send_key,
1002 idata->hmac, packet);
1005 /* Received private message key packet.. This packet is never for us. It is to
1006 the client in the packet's destination ID. Sending of this sort of packet
1007 equals sending private message, ie. it is sent point to point from
1008 one client to another. */
1010 void silc_server_private_message_key(SilcServer server,
1011 SilcSocketConnection sock,
1012 SilcPacketContext *packet)
1014 SilcSocketConnection dst_sock;
1015 SilcIDListData idata;
1017 SILC_LOG_DEBUG(("Start"));
1019 if (packet->src_id_type != SILC_ID_CLIENT ||
1020 packet->dst_id_type != SILC_ID_CLIENT)
1023 if (!packet->dst_id)
1026 /* Get the route to the client */
1027 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1028 packet->dst_id_len, NULL, &idata);
1032 /* Relay the packet */
1033 silc_server_relay_packet(server, dst_sock, idata->send_key,
1034 idata->hmac, packet, FALSE);
1037 /* Processes incoming command reply packet. The command reply packet may
1038 be destined to one of our clients or it may directly for us. We will
1039 call the command reply routine after processing the packet. */
1041 void silc_server_command_reply(SilcServer server,
1042 SilcSocketConnection sock,
1043 SilcPacketContext *packet)
1045 SilcBuffer buffer = packet->buffer;
1046 SilcClientEntry client = NULL;
1047 SilcSocketConnection dst_sock;
1048 SilcIDListData idata;
1049 SilcClientID *id = NULL;
1051 SILC_LOG_DEBUG(("Start"));
1053 /* Source must be server or router */
1054 if (packet->src_id_type != SILC_ID_SERVER &&
1055 sock->type != SILC_SOCKET_TYPE_ROUTER)
1058 if (packet->dst_id_type == SILC_ID_CHANNEL)
1061 if (packet->dst_id_type == SILC_ID_CLIENT) {
1062 /* Destination must be one of ours */
1063 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
1066 client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
1068 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
1074 if (packet->dst_id_type == SILC_ID_SERVER) {
1075 /* For now this must be for us */
1076 if (SILC_ID_SERVER_COMPARE(packet->dst_id, server->id_string)) {
1077 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
1082 /* Execute command reply locally for the command */
1083 silc_server_command_reply_process(server, sock, buffer);
1085 if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
1086 /* Relay the packet to the client */
1088 dst_sock = (SilcSocketConnection)client->connection;
1089 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
1090 + packet->dst_id_len + packet->padlen);
1092 silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
1093 silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
1095 idata = (SilcIDListData)client;
1097 /* Encrypt packet */
1098 silc_packet_encrypt(idata->send_key, idata->hmac, dst_sock->outbuf,
1101 /* Send the packet */
1102 silc_server_packet_send_real(server, dst_sock, TRUE);
1108 /* Process received channel message. The message can be originated from
1109 client or server. */
1111 void silc_server_channel_message(SilcServer server,
1112 SilcSocketConnection sock,
1113 SilcPacketContext *packet)
1115 SilcChannelEntry channel = NULL;
1116 SilcChannelClientEntry chl;
1117 SilcChannelID *id = NULL;
1118 void *sender = NULL;
1120 SILC_LOG_DEBUG(("Processing channel message"));
1123 if (packet->dst_id_type != SILC_ID_CHANNEL) {
1124 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1128 /* Find channel entry */
1129 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
1132 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
1134 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
1136 SILC_LOG_DEBUG(("Could not find channel"));
1141 /* See that this client is on the channel. If the message is coming
1142 from router we won't do the check as the message is from client that
1143 we don't know about. Also, if the original sender is not client
1144 (as it can be server as well) we don't do the check. */
1145 sender = silc_id_str2id(packet->src_id, packet->src_id_len,
1146 packet->src_id_type);
1149 if (sock->type != SILC_SOCKET_TYPE_ROUTER &&
1150 packet->src_id_type == SILC_ID_CLIENT) {
1151 silc_list_start(channel->user_list);
1152 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
1153 if (chl->client && !SILC_ID_CLIENT_COMPARE(chl->client->id, sender))
1156 if (chl == SILC_LIST_END) {
1157 SILC_LOG_DEBUG(("Client not on channel"));
1162 /* If we are router and the packet came from router and private key
1163 has not been set for the channel then we must encrypt the packet
1164 as it was decrypted with the session key shared between us and the
1165 router which sent it. This is so, because cells does not share the
1167 if (server->server_type == SILC_ROUTER &&
1168 sock->type == SILC_SOCKET_TYPE_ROUTER &&
1169 !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
1171 unsigned int iv_len, i;
1172 unsigned short data_len, flags;
1174 iv_len = silc_cipher_get_block_len(channel->channel_key);
1175 if (channel->iv[0] == '\0')
1176 for (i = 0; i < iv_len; i++) channel->iv[i] =
1177 silc_rng_get_byte(server->rng);
1179 silc_hash_make(server->md5hash, channel->iv, iv_len, channel->iv);
1181 /* Encode new payload. This encrypts it also. */
1182 SILC_GET16_MSB(flags, packet->buffer->data);
1183 SILC_GET16_MSB(data_len, packet->buffer->data + 2);
1184 chp = silc_channel_message_payload_encode(flags, data_len,
1185 packet->buffer->data + 4,
1186 iv_len, channel->iv,
1187 channel->channel_key,
1189 silc_buffer_put(packet->buffer, chp->data, chp->len);
1190 silc_buffer_free(chp);
1193 /* Distribute the packet to our local clients. This will send the
1194 packet for further routing as well, if needed. */
1195 silc_server_packet_relay_to_channel(server, sock, channel, sender,
1196 packet->src_id_type,
1197 packet->buffer->data,
1198 packet->buffer->len, FALSE);
1207 /* Received channel key packet. We distribute the key to all of our locally
1208 connected clients on the channel. */
1210 void silc_server_channel_key(SilcServer server,
1211 SilcSocketConnection sock,
1212 SilcPacketContext *packet)
1214 SilcBuffer buffer = packet->buffer;
1215 SilcChannelEntry channel;
1217 if (packet->src_id_type != SILC_ID_SERVER ||
1218 (server->server_type == SILC_ROUTER &&
1219 sock->type == SILC_SOCKET_TYPE_ROUTER))
1222 /* Save the channel key */
1223 channel = silc_server_save_channel_key(server, buffer, NULL);
1227 /* Distribute the key to everybody who is on the channel. If we are router
1228 we will also send it to locally connected servers. */
1229 silc_server_send_channel_key(server, sock, channel, FALSE);
1232 /* Received New Client packet and processes it. Creates Client ID for the
1233 client. Client becomes registered after calling this functions. */
1235 SilcClientEntry silc_server_new_client(SilcServer server,
1236 SilcSocketConnection sock,
1237 SilcPacketContext *packet)
1239 SilcBuffer buffer = packet->buffer;
1240 SilcClientEntry client;
1241 SilcIDCacheEntry cache;
1242 SilcClientID *client_id;
1244 SilcIDListData idata;
1245 char *username = NULL, *realname = NULL, *id_string;
1248 SILC_LOG_DEBUG(("Creating new client"));
1250 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
1253 /* Take client entry */
1254 client = (SilcClientEntry)sock->user_data;
1255 idata = (SilcIDListData)client;
1257 /* Fetch the old client cache entry so that we can update it. */
1258 if (!silc_idcache_find_by_context(server->local_list->clients,
1259 sock->user_data, &cache)) {
1260 SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
1264 /* Parse incoming packet */
1265 ret = silc_buffer_unformat(buffer,
1266 SILC_STR_UI16_STRING_ALLOC(&username),
1267 SILC_STR_UI16_STRING_ALLOC(&realname),
1271 silc_free(username);
1273 silc_free(realname);
1278 silc_free(username);
1280 silc_free(realname);
1281 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1282 "Incomplete client information");
1286 /* Create Client ID */
1287 silc_id_create_client_id(server->id, server->rng, server->md5hash,
1288 username, &client_id);
1290 if (strlen(username) > 128)
1291 username[127] = '\0';
1293 /* Update client entry */
1294 idata->registered = TRUE;
1295 client->nickname = strdup(username);
1296 client->username = username;
1297 client->userinfo = realname ? realname : strdup(" ");
1298 client->id = client_id;
1300 /* Update the cache entry */
1301 cache->id = (void *)client_id;
1302 cache->type = SILC_ID_CLIENT;
1303 cache->data = username;
1304 silc_idcache_sort_by_data(server->local_list->clients);
1306 /* Notify our router about new client on the SILC network */
1307 if (!server->standalone)
1308 silc_server_send_new_id(server, (SilcSocketConnection)
1309 server->router->connection,
1310 server->server_type == SILC_ROUTER ? TRUE : FALSE,
1311 client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
1313 /* Send the new client ID to the client. */
1314 id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
1315 reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
1316 silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
1317 silc_buffer_format(reply,
1318 SILC_STR_UI_SHORT(SILC_ID_CLIENT),
1319 SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
1320 SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
1322 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0,
1323 reply->data, reply->len, FALSE);
1324 silc_free(id_string);
1325 silc_buffer_free(reply);
1327 /* Send some nice info to the client */
1328 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1329 ("Welcome to the SILC Network %s@%s",
1330 username, sock->hostname));
1331 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1332 ("Your host is %s, running version %s",
1333 server->config->server_info->server_name,
1335 if (server->server_type == SILC_ROUTER) {
1336 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1337 ("There are %d clients on %d servers in SILC "
1338 "Network", server->stat.clients,
1339 server->stat.servers + 1));
1340 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1341 ("There are %d clients on %d server in our cell",
1342 server->stat.cell_clients,
1343 server->stat.cell_servers + 1));
1344 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1345 ("I have %d clients, %d channels, %d servers and "
1347 server->stat.my_clients,
1348 server->stat.my_channels,
1349 server->stat.my_servers,
1350 server->stat.my_routers));
1351 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1352 ("%d server operators and %d router operators "
1354 server->stat.my_server_ops,
1355 server->stat.my_router_ops));
1357 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1358 ("I have %d clients and %d channels formed",
1359 server->stat.my_clients,
1360 server->stat.my_channels));
1361 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1362 ("%d operators online",
1363 server->stat.my_server_ops));
1365 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1366 ("Your connection is secured with %s cipher, "
1367 "key length %d bits",
1368 idata->send_key->cipher->name,
1369 idata->send_key->cipher->key_len));
1370 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1371 ("Your current nickname is %s",
1375 silc_server_send_motd(server, sock);
1380 /* Create new server. This processes received New Server packet and
1381 saves the received Server ID. The server is our locally connected
1382 server thus we save all the information and save it to local list.
1383 This funtion can be used by both normal server and router server.
1384 If normal server uses this it means that its router has connected
1385 to the server. If router uses this it means that one of the cell's
1386 servers is connected to the router. */
1388 SilcServerEntry silc_server_new_server(SilcServer server,
1389 SilcSocketConnection sock,
1390 SilcPacketContext *packet)
1392 SilcBuffer buffer = packet->buffer;
1393 SilcServerEntry new_server;
1394 SilcIDCacheEntry cache;
1395 SilcServerID *server_id;
1396 SilcIDListData idata;
1397 unsigned char *server_name, *id_string;
1398 unsigned short id_len, name_len;
1401 SILC_LOG_DEBUG(("Creating new server"));
1403 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
1404 sock->type != SILC_SOCKET_TYPE_ROUTER)
1407 /* Take server entry */
1408 new_server = (SilcServerEntry)sock->user_data;
1409 idata = (SilcIDListData)new_server;
1411 /* Fetch the old server cache entry so that we can update it. */
1412 if (!silc_idcache_find_by_context(server->local_list->servers,
1413 sock->user_data, &cache)) {
1414 SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
1418 /* Parse the incoming packet */
1419 ret = silc_buffer_unformat(buffer,
1420 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
1421 SILC_STR_UI16_NSTRING_ALLOC(&server_name,
1426 silc_free(id_string);
1428 silc_free(server_name);
1432 if (id_len > buffer->len) {
1433 silc_free(id_string);
1434 silc_free(server_name);
1439 server_name[255] = '\0';
1442 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
1444 silc_free(id_string);
1445 silc_free(server_name);
1448 silc_free(id_string);
1450 /* Update client entry */
1451 idata->registered = TRUE;
1452 new_server->server_name = server_name;
1453 new_server->id = server_id;
1455 /* Update the cache entry */
1456 cache->id = (void *)server_id;
1457 cache->type = SILC_ID_SERVER;
1458 cache->data = server_name;
1459 cache->data_len = strlen(server_name);
1460 silc_idcache_sort_by_data(server->local_list->servers);
1462 /* Distribute the information about new server in the SILC network
1463 to our router. If we are normal server we won't send anything
1464 since this connection must be our router connection. */
1465 if (server->server_type == SILC_ROUTER && !server->standalone &&
1466 server->router->connection != sock)
1467 silc_server_send_new_id(server, server->router->connection,
1468 TRUE, new_server->id, SILC_ID_SERVER,
1469 SILC_ID_SERVER_LEN);
1471 if (server->server_type == SILC_ROUTER)
1472 server->stat.cell_servers++;
1477 /* Processes incoming New ID packet. New ID Payload is used to distribute
1478 information about newly registered clients and servers. */
1480 static void silc_server_new_id_real(SilcServer server,
1481 SilcSocketConnection sock,
1482 SilcPacketContext *packet,
1485 SilcBuffer buffer = packet->buffer;
1487 SilcServerEntry router;
1488 SilcSocketConnection router_sock;
1491 unsigned char *hash = NULL;
1494 SILC_LOG_DEBUG(("Processing new ID"));
1496 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1497 server->server_type == SILC_SERVER ||
1498 packet->src_id_type != SILC_ID_SERVER)
1501 idp = silc_id_payload_parse(buffer);
1505 id_type = silc_id_payload_get_type(idp);
1507 /* Normal server cannot have other normal server connections */
1508 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
1511 id = silc_id_payload_get_id(idp);
1515 /* If the sender of this packet is server and we are router we need to
1516 broadcast this packet to other routers in the network. */
1517 if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
1518 sock->type == SILC_SOCKET_TYPE_SERVER &&
1519 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1520 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
1521 silc_server_packet_send(server, server->router->connection,
1523 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1524 buffer->data, buffer->len, FALSE);
1527 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1528 id_list = server->local_list;
1530 id_list = server->global_list;
1533 router = sock->user_data;
1536 case SILC_ID_CLIENT:
1538 SilcClientEntry entry;
1540 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
1541 silc_id_render(id, SILC_ID_CLIENT),
1542 sock->type == SILC_SOCKET_TYPE_SERVER ?
1543 "Server" : "Router", sock->hostname));
1545 /* As a router we keep information of all global information in our
1546 global list. Cell wide information however is kept in the local
1547 list. The client is put to global list and we will take the hash
1548 value of the Client ID and save it to the ID Cache system for fast
1549 searching in the future. */
1550 hash = silc_calloc(sizeof(((SilcClientID *)id)->hash),
1551 sizeof(unsigned char));
1552 memcpy(hash, ((SilcClientID *)id)->hash,
1553 sizeof(((SilcClientID *)id)->hash));
1554 entry = silc_idlist_add_client(id_list, hash,
1555 sizeof(((SilcClientID *)id)->hash),
1556 NULL, NULL, id, router, NULL);
1557 entry->nickname = NULL;
1558 entry->data.registered = TRUE;
1560 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1561 server->stat.cell_clients++;
1562 server->stat.clients++;
1566 case SILC_ID_SERVER:
1567 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
1568 silc_id_render(id, SILC_ID_SERVER),
1569 sock->type == SILC_SOCKET_TYPE_SERVER ?
1570 "Server" : "Router", sock->hostname));
1572 /* As a router we keep information of all global information in our global
1573 list. Cell wide information however is kept in the local list. */
1574 silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
1576 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1577 server->stat.cell_servers++;
1578 server->stat.servers++;
1581 case SILC_ID_CHANNEL:
1582 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
1590 silc_id_payload_free(idp);
1594 /* Processes incoming New ID packet. New ID Payload is used to distribute
1595 information about newly registered clients and servers. */
1597 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
1598 SilcPacketContext *packet)
1600 silc_server_new_id_real(server, sock, packet, TRUE);
1603 /* Receoved New Id List packet, list of New ID payloads inside one
1604 packet. Process the New ID payloads one by one. */
1606 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
1607 SilcPacketContext *packet)
1609 SilcPacketContext *new_id;
1611 unsigned short id_len;
1613 SILC_LOG_DEBUG(("Processing New ID List"));
1615 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1616 packet->src_id_type != SILC_ID_SERVER)
1619 /* If the sender of this packet is server and we are router we need to
1620 broadcast this packet to other routers in the network. Broadcast
1621 this list packet instead of multiple New ID packets. */
1622 if (!server->standalone && server->server_type == SILC_ROUTER &&
1623 sock->type == SILC_SOCKET_TYPE_SERVER &&
1624 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1625 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
1626 silc_server_packet_send(server, server->router->connection,
1628 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1629 packet->buffer->data, packet->buffer->len, FALSE);
1632 /* Make copy of the original packet context, except for the actual
1633 data buffer, which we will here now fetch from the original buffer. */
1634 new_id = silc_packet_context_alloc();
1635 new_id->type = SILC_PACKET_NEW_ID;
1636 new_id->flags = packet->flags;
1637 new_id->src_id = packet->src_id;
1638 new_id->src_id_len = packet->src_id_len;
1639 new_id->src_id_type = packet->src_id_type;
1640 new_id->dst_id = packet->dst_id;
1641 new_id->dst_id_len = packet->dst_id_len;
1642 new_id->dst_id_type = packet->dst_id_type;
1644 idp = silc_buffer_alloc(256);
1645 new_id->buffer = idp;
1647 while (packet->buffer->len) {
1648 SILC_GET16_MSB(id_len, packet->buffer->data + 2);
1649 if ((id_len > packet->buffer->len) ||
1650 (id_len > idp->truelen))
1653 silc_buffer_pull_tail(idp, 4 + id_len);
1654 silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
1656 /* Process the New ID */
1657 silc_server_new_id_real(server, sock, new_id, FALSE);
1659 silc_buffer_push_tail(idp, 4 + id_len);
1660 silc_buffer_pull(packet->buffer, 4 + id_len);
1663 silc_buffer_free(idp);
1667 /* Received New Channel packet. Information about new channels in the
1668 network are distributed using this packet. Save the information about
1669 the new channel. This usually comes from router but also normal server
1670 can send this to notify channels it has when it connects to us. */
1672 void silc_server_new_channel(SilcServer server,
1673 SilcSocketConnection sock,
1674 SilcPacketContext *packet)
1676 SilcChannelPayload payload;
1677 SilcChannelID *channel_id;
1679 unsigned int name_len;
1681 unsigned int id_len;
1684 SILC_LOG_DEBUG(("Processing New Channel"));
1686 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1687 packet->src_id_type != SILC_ID_SERVER ||
1688 server->server_type == SILC_SERVER)
1691 /* Parse the channel payload */
1692 payload = silc_channel_payload_parse(packet->buffer);
1696 /* Get the channel ID */
1697 channel_id = silc_channel_get_id_parse(payload);
1699 silc_channel_payload_free(payload);
1703 channel_name = silc_channel_get_name(payload, &name_len);
1705 channel_name[255] = '\0';
1707 id = silc_channel_get_id(payload, &id_len);
1709 if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
1710 /* Add the server to global list as it is coming from router. It
1711 cannot be our own channel as it is coming from router. */
1713 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
1714 silc_id_render(channel_id, SILC_ID_CHANNEL),
1717 silc_idlist_add_channel(server->global_list, strdup(channel_name),
1718 0, channel_id, server->router->connection,
1721 server->stat.channels++;
1723 /* The channel is coming from our server, thus it is in our cell
1724 we will add it to our local list. */
1725 SilcChannelEntry channel;
1728 SILC_LOG_DEBUG(("New channel id(%s) from [Server] %s",
1729 silc_id_render(channel_id, SILC_ID_CHANNEL),
1732 /* Check that we don't already have this channel */
1733 channel = silc_idlist_find_channel_by_name(server->local_list,
1734 channel_name, NULL);
1736 channel = silc_idlist_find_channel_by_name(server->global_list,
1737 channel_name, NULL);
1739 /* If the channel does not exist, then create it. We create the channel
1740 with the channel ID provided by the server. This creates a new
1741 key to the channel as well that we will send to the server. */
1743 channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
1747 silc_channel_payload_free(payload);
1748 silc_free(channel_id);
1752 /* Send the new channel key to the server */
1753 chk = silc_channel_key_payload_encode(id_len, id,
1754 strlen(channel->channel_key->
1756 channel->channel_key->cipher->name,
1757 channel->key_len / 8,
1759 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
1760 chk->data, chk->len, FALSE);
1761 silc_buffer_free(chk);
1764 /* The channel exist by that name, check whether the ID's match.
1765 If they don't then we'll force the server to use the ID we have.
1766 We also create a new key for the channel. */
1767 SilcBuffer users = NULL;
1770 channel_id = silc_id_dup(channel_id, SILC_ID_CHANNEL);
1772 if (SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
1773 /* They don't match, send CHANNEL_CHANGE notify to the server to
1774 force the ID change. */
1775 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
1776 silc_server_send_notify_channel_change(server, sock, FALSE,
1779 SILC_ID_CHANNEL_LEN);
1782 /* If the mode is different from what we have then enforce the
1784 mode = silc_channel_get_mode(payload);
1785 if (channel->mode != mode) {
1786 SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
1787 silc_server_send_notify_cmode(server, sock, FALSE, channel,
1788 channel->mode, server->id,
1789 SILC_ID_SERVER, SILC_ID_SERVER_LEN,
1790 channel->cipher, channel->hmac_name);
1793 /* Create new key for the channel and send it to the server and
1794 everybody else possibly on the channel. */
1796 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
1797 silc_server_create_channel_key(server, channel, 0);
1799 /* Send to the channel */
1800 silc_server_send_channel_key(server, sock, channel, FALSE);
1801 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
1802 id_len = SILC_ID_CHANNEL_LEN;
1804 /* Send to the server */
1805 chk = silc_channel_key_payload_encode(id_len, id,
1806 strlen(channel->channel_key->
1808 channel->channel_key->
1810 channel->key_len / 8,
1812 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
1813 chk->data, chk->len, FALSE);
1814 silc_buffer_free(chk);
1818 silc_free(channel_id);
1820 /* Since the channel is coming from server and we also know about it
1821 then send the JOIN notify to the server so that it see's our
1822 users on the channel "joining" the channel. */
1823 silc_server_announce_get_channel_users(server, channel, &users);
1825 silc_buffer_push(users, users->data - users->head);
1826 silc_server_packet_send(server, sock,
1827 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1828 users->data, users->len, FALSE);
1829 silc_buffer_free(users);
1834 silc_channel_payload_free(payload);
1837 /* Received New Channel List packet, list of New Channel List payloads inside
1838 one packet. Process the New Channel payloads one by one. */
1840 void silc_server_new_channel_list(SilcServer server,
1841 SilcSocketConnection sock,
1842 SilcPacketContext *packet)
1844 SilcPacketContext *new;
1846 unsigned short len1, len2;
1848 SILC_LOG_DEBUG(("Processing New Channel List"));
1850 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1851 packet->src_id_type != SILC_ID_SERVER ||
1852 server->server_type == SILC_SERVER)
1855 /* If the sender of this packet is server and we are router we need to
1856 broadcast this packet to other routers in the network. Broadcast
1857 this list packet instead of multiple New Channel packets. */
1858 if (!server->standalone && server->server_type == SILC_ROUTER &&
1859 sock->type == SILC_SOCKET_TYPE_SERVER &&
1860 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1861 SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
1862 silc_server_packet_send(server, server->router->connection,
1864 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1865 packet->buffer->data, packet->buffer->len, FALSE);
1868 /* Make copy of the original packet context, except for the actual
1869 data buffer, which we will here now fetch from the original buffer. */
1870 new = silc_packet_context_alloc();
1871 new->type = SILC_PACKET_NEW_CHANNEL;
1872 new->flags = packet->flags;
1873 new->src_id = packet->src_id;
1874 new->src_id_len = packet->src_id_len;
1875 new->src_id_type = packet->src_id_type;
1876 new->dst_id = packet->dst_id;
1877 new->dst_id_len = packet->dst_id_len;
1878 new->dst_id_type = packet->dst_id_type;
1880 buffer = silc_buffer_alloc(512);
1881 new->buffer = buffer;
1883 while (packet->buffer->len) {
1884 SILC_GET16_MSB(len1, packet->buffer->data);
1885 if ((len1 > packet->buffer->len) ||
1886 (len1 > buffer->truelen))
1889 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
1890 if ((len2 > packet->buffer->len) ||
1891 (len2 > buffer->truelen))
1894 silc_buffer_pull_tail(buffer, 8 + len1 + len2);
1895 silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
1897 /* Process the New Channel */
1898 silc_server_new_channel(server, sock, new);
1900 silc_buffer_push_tail(buffer, 8 + len1 + len2);
1901 silc_buffer_pull(packet->buffer, 8 + len1 + len2);
1904 silc_buffer_free(buffer);
1908 /* Received key agreement packet. This packet is never for us. It is to
1909 the client in the packet's destination ID. Sending of this sort of packet
1910 equals sending private message, ie. it is sent point to point from
1911 one client to another. */
1913 void silc_server_key_agreement(SilcServer server,
1914 SilcSocketConnection sock,
1915 SilcPacketContext *packet)
1917 SilcSocketConnection dst_sock;
1918 SilcIDListData idata;
1920 SILC_LOG_DEBUG(("Start"));
1922 if (packet->src_id_type != SILC_ID_CLIENT ||
1923 packet->dst_id_type != SILC_ID_CLIENT)
1926 if (!packet->dst_id)
1929 /* Get the route to the client */
1930 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1931 packet->dst_id_len, NULL, &idata);
1935 /* Relay the packet */
1936 silc_server_relay_packet(server, dst_sock, idata->send_key,
1937 idata->hmac, packet, FALSE);
1940 /* Received connection auth request packet that is used during connection
1941 phase to resolve the mandatory authentication method. This packet can
1942 actually be received at anytime but usually it is used only during
1943 the connection authentication phase. Now, protocol says that this packet
1944 can come from client or server, however, we support only this coming
1945 from client and expect that server's always knows what authentication
1948 void silc_server_connection_auth_request(SilcServer server,
1949 SilcSocketConnection sock,
1950 SilcPacketContext *packet)
1952 SilcServerConfigSectionClientConnection *client = NULL;
1953 unsigned short conn_type;
1955 SilcAuthMethod auth_meth;
1957 SILC_LOG_DEBUG(("Start"));
1959 if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT)
1962 /* Parse the payload */
1963 ret = silc_buffer_unformat(packet->buffer,
1964 SILC_STR_UI_SHORT(&conn_type),
1965 SILC_STR_UI_SHORT(NULL),
1970 if (conn_type != SILC_SOCKET_TYPE_CLIENT)
1973 /* Get the authentication method for the client */
1974 auth_meth = SILC_AUTH_NONE;
1975 client = silc_server_config_find_client_conn(server->config,
1979 client = silc_server_config_find_client_conn(server->config,
1983 auth_meth = client->auth_meth;
1985 /* Send it back to the client */
1986 silc_server_send_connection_auth_request(server, sock,