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 SilcServerID *server_id;
43 SilcChannelEntry channel;
44 SilcClientEntry client;
45 SilcServerEntry server_entry;
46 SilcChannelClientEntry chl;
47 SilcIDCacheEntry cache;
48 SilcHashTableList htl;
53 SILC_LOG_DEBUG(("Start"));
55 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
56 packet->src_id_type != SILC_ID_SERVER)
62 /* If the packet is destined directly to a client then relay the packet
63 before processing it. */
64 if (packet->dst_id_type == SILC_ID_CLIENT) {
66 SilcSocketConnection dst_sock;
68 /* Get the route to the client */
69 dst_sock = silc_server_get_client_route(server, packet->dst_id,
70 packet->dst_id_len, NULL, &idata);
72 /* Relay the packet */
73 silc_server_relay_packet(server, dst_sock, idata->send_key,
74 idata->hmac_receive, packet, TRUE);
77 /* If we are router and this packet is not already broadcast packet
78 we will broadcast it. The sending socket really cannot be router or
79 the router is buggy. If this packet is coming from router then it must
80 have the broadcast flag set already and we won't do anything. */
81 if (!server->standalone && server->server_type == SILC_ROUTER &&
82 sock->type == SILC_SOCKET_TYPE_SERVER &&
83 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
84 SILC_LOG_DEBUG(("Broadcasting received Notify packet"));
85 silc_server_packet_send(server, server->router->connection, packet->type,
86 packet->flags | SILC_PACKET_FLAG_BROADCAST,
87 packet->buffer->data, packet->buffer->len, FALSE);
90 payload = silc_notify_payload_parse(packet->buffer);
94 type = silc_notify_get_type(payload);
95 args = silc_notify_get_args(payload);
100 case SILC_NOTIFY_TYPE_JOIN:
102 * Distribute the notify to local clients on the channel
104 SILC_LOG_DEBUG(("JOIN notify"));
107 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
110 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
114 /* Get channel entry */
115 channel = silc_idlist_find_channel_by_id(server->global_list,
118 channel = silc_idlist_find_channel_by_id(server->local_list,
121 silc_free(channel_id);
125 silc_free(channel_id);
128 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
131 client_id = silc_id_payload_parse_id(tmp, tmp_len);
135 /* Send to channel */
136 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
137 FALSE, packet->buffer->data,
138 packet->buffer->len, FALSE);
140 /* If the the client is not in local list we check global list (ie. the
141 channel will be global channel) and if it does not exist then create
142 entry for the client. */
143 client = silc_idlist_find_client_by_id(server->global_list,
146 client = silc_idlist_find_client_by_id(server->local_list,
149 /* If router did not find the client the it is bogus */
150 if (server->server_type == SILC_ROUTER)
154 silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
155 silc_id_dup(client_id, SILC_ID_CLIENT),
156 sock->user_data, NULL);
158 silc_free(client_id);
162 client->data.registered = TRUE;
166 /* Do not add client to channel if it is there already */
167 if (silc_server_client_on_channel(client, channel))
170 if (server->server_type == SILC_SERVER &&
171 sock->type == SILC_SOCKET_TYPE_ROUTER)
172 /* The channel is global now */
173 channel->global_users = TRUE;
175 /* JOIN the global client to the channel (local clients (if router
176 created the channel) is joined in the pending JOIN command). */
177 chl = silc_calloc(1, sizeof(*chl));
178 chl->client = client;
179 chl->channel = channel;
180 silc_hash_table_add(channel->user_list, client, chl);
181 silc_hash_table_add(client->channels, channel, chl);
182 silc_free(client_id);
186 case SILC_NOTIFY_TYPE_LEAVE:
188 * Distribute the notify to local clients on the channel
190 SILC_LOG_DEBUG(("LEAVE notify"));
192 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
193 packet->dst_id_type);
197 /* Get channel entry */
198 channel = silc_idlist_find_channel_by_id(server->global_list,
201 channel = silc_idlist_find_channel_by_id(server->local_list,
204 silc_free(channel_id);
210 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
212 silc_free(channel_id);
215 client_id = silc_id_payload_parse_id(tmp, tmp_len);
217 silc_free(channel_id);
221 /* Send to channel */
222 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
223 FALSE, packet->buffer->data,
224 packet->buffer->len, FALSE);
226 /* Get client entry */
227 client = silc_idlist_find_client_by_id(server->global_list,
230 client = silc_idlist_find_client_by_id(server->local_list,
233 silc_free(client_id);
234 silc_free(channel_id);
238 silc_free(client_id);
240 /* Remove the user from channel */
241 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
244 case SILC_NOTIFY_TYPE_SIGNOFF:
246 * Distribute the notify to local clients on the channel
248 SILC_LOG_DEBUG(("SIGNOFF notify"));
251 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
254 client_id = silc_id_payload_parse_id(tmp, tmp_len);
258 /* Get client entry */
259 client = silc_idlist_find_client_by_id(server->global_list,
262 client = silc_idlist_find_client_by_id(server->local_list,
265 silc_free(client_id);
269 silc_free(client_id);
271 /* Get signoff message */
272 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
276 /* Remove the client from all channels. */
277 silc_server_remove_from_channels(server, NULL, client, TRUE, tmp, FALSE);
279 client->data.registered = FALSE;
280 cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
283 case SILC_NOTIFY_TYPE_TOPIC_SET:
285 * Distribute the notify to local clients on the channel
288 SILC_LOG_DEBUG(("TOPIC SET notify"));
290 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
291 packet->dst_id_type);
295 /* Get channel entry */
296 channel = silc_idlist_find_channel_by_id(server->global_list,
299 channel = silc_idlist_find_channel_by_id(server->local_list,
302 silc_free(channel_id);
308 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
310 silc_free(channel_id);
315 silc_free(channel->topic);
316 channel->topic = silc_calloc(tmp_len, sizeof(*channel->topic));
317 memcpy(channel->topic, tmp, tmp_len);
319 /* Send the same notify to the channel */
320 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
321 FALSE, packet->buffer->data,
322 packet->buffer->len, FALSE);
323 silc_free(channel_id);
326 case SILC_NOTIFY_TYPE_NICK_CHANGE:
329 * Distribute the notify to local clients on the channel
331 unsigned char *id, *id2;
333 SILC_LOG_DEBUG(("NICK CHANGE notify"));
335 /* Get old client ID */
336 id = silc_argument_get_arg_type(args, 1, &tmp_len);
339 client_id = silc_id_payload_parse_id(id, tmp_len);
343 /* Get new client ID */
344 id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
347 client_id2 = silc_id_payload_parse_id(id2, tmp_len);
351 SILC_LOG_DEBUG(("Old Client ID id(%s)",
352 silc_id_render(client_id, SILC_ID_CLIENT)));
353 SILC_LOG_DEBUG(("New Client ID id(%s)",
354 silc_id_render(client_id2, SILC_ID_CLIENT)));
356 /* Replace the Client ID */
357 client = silc_idlist_replace_client_id(server->global_list, client_id,
360 client = silc_idlist_replace_client_id(server->local_list, client_id,
364 /* The nickname is not valid anymore, set it NULL. This causes that
365 the nickname will be queried if someone wants to know it. */
366 if (client->nickname)
367 silc_free(client->nickname);
368 client->nickname = NULL;
370 /* Send the NICK_CHANGE notify type to local clients on the channels
371 this client is joined to. */
372 silc_server_send_notify_on_channels(server, NULL, client,
373 SILC_NOTIFY_TYPE_NICK_CHANGE, 2,
378 silc_free(client_id);
380 silc_free(client_id2);
384 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
386 * Distribute the notify to local clients on the channel
389 SILC_LOG_DEBUG(("CMODE CHANGE notify"));
391 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
392 packet->dst_id_type);
396 /* Get channel entry */
397 channel = silc_idlist_find_channel_by_id(server->global_list,
400 channel = silc_idlist_find_channel_by_id(server->local_list,
403 silc_free(channel_id);
408 /* Send the same notify to the channel */
409 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
410 FALSE, packet->buffer->data,
411 packet->buffer->len, FALSE);
414 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
416 silc_free(channel_id);
420 SILC_GET32_MSB(mode, tmp);
422 /* If the channel had private keys set and the mode was removed then
423 we must re-generate and re-distribute a new channel key */
424 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY &&
425 !(mode & SILC_CHANNEL_MODE_PRIVKEY)) {
426 /* Re-generate channel key */
427 silc_server_create_channel_key(server, channel, 0);
429 /* Send the channel key. This sends it to our local clients and if
430 we are normal server to our router as well. */
431 silc_server_send_channel_key(server, NULL, channel,
432 server->server_type == SILC_ROUTER ?
433 FALSE : !server->standalone);
437 channel->mode = mode;
438 silc_free(channel_id);
441 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
443 unsigned char hash[32];
446 silc_hmac_free(channel->hmac);
447 if (!silc_hmac_alloc(tmp, NULL, &channel->hmac))
450 /* Set the HMAC key out of current channel key. The client must do
452 silc_hash_make(channel->hmac->hash, channel->key, channel->key_len / 8,
454 silc_hmac_set_key(channel->hmac, hash,
455 silc_hash_len(channel->hmac->hash));
456 memset(hash, 0, sizeof(hash));
461 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
463 * Distribute the notify to local clients on the channel
466 SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
468 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
469 packet->dst_id_type);
473 /* Get channel entry */
474 channel = silc_idlist_find_channel_by_id(server->global_list,
477 channel = silc_idlist_find_channel_by_id(server->local_list,
480 silc_free(channel_id);
486 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
488 silc_free(channel_id);
492 SILC_GET32_MSB(mode, tmp);
494 /* Get target client */
495 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
498 client_id = silc_id_payload_parse_id(tmp, tmp_len);
502 /* Get client entry */
503 client = silc_idlist_find_client_by_id(server->global_list,
506 client = silc_idlist_find_client_by_id(server->local_list,
509 silc_free(client_id);
513 silc_free(client_id);
515 /* Get entry to the channel user list */
516 silc_hash_table_list(channel->user_list, &htl);
517 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
518 SilcChannelClientEntry chl2 = NULL;
520 /* If the mode is channel founder and we already find a client
521 to have that mode on the channel we will enforce the sender
522 to change the channel founder mode away. There can be only one
523 channel founder on the channel. */
524 if (server->server_type == SILC_ROUTER &&
525 mode & SILC_CHANNEL_UMODE_CHANFO &&
526 chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
527 silc_server_send_notify_cumode(server, sock, FALSE, channel,
528 (mode & (~SILC_CHANNEL_UMODE_CHANFO)),
529 server->id, SILC_ID_SERVER,
531 silc_free(channel_id);
533 /* Change the mode back if we changed it */
535 chl2->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
539 if (chl->client == client) {
540 /* Change the mode */
542 if (!(mode & SILC_CHANNEL_UMODE_CHANFO))
549 /* Send the same notify to the channel */
550 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
551 FALSE, packet->buffer->data,
552 packet->buffer->len, FALSE);
553 silc_free(channel_id);
556 case SILC_NOTIFY_TYPE_INVITE:
558 if (packet->dst_id_type == SILC_ID_CLIENT)
561 SILC_LOG_DEBUG(("INVITE notify"));
564 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
567 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
571 /* Get channel entry */
572 channel = silc_idlist_find_channel_by_id(server->global_list,
575 channel = silc_idlist_find_channel_by_id(server->local_list,
578 silc_free(channel_id);
582 silc_free(channel_id);
584 /* Get the added invite */
585 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
587 if (!channel->invite_list)
588 channel->invite_list = silc_calloc(tmp_len + 2,
589 sizeof(*channel->invite_list));
591 channel->invite_list = silc_realloc(channel->invite_list,
592 sizeof(*channel->invite_list) *
594 strlen(channel->invite_list) +
596 if (tmp[tmp_len - 1] == ',')
597 tmp[tmp_len - 1] = '\0';
599 strncat(channel->invite_list, tmp, tmp_len);
600 strncat(channel->invite_list, ",", 1);
603 /* Get the deleted invite */
604 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
605 if (tmp && channel->invite_list) {
606 char *start, *end, *n;
608 if (!strncmp(channel->invite_list, tmp,
609 strlen(channel->invite_list) - 1)) {
610 silc_free(channel->invite_list);
611 channel->invite_list = NULL;
613 start = strstr(channel->invite_list, tmp);
614 if (start && strlen(start) >= tmp_len) {
615 end = start + tmp_len;
616 n = silc_calloc(strlen(channel->invite_list) - tmp_len, sizeof(*n));
617 strncat(n, channel->invite_list, start - channel->invite_list);
618 strncat(n, end + 1, ((channel->invite_list +
619 strlen(channel->invite_list)) - end) - 1);
620 silc_free(channel->invite_list);
621 channel->invite_list = n;
628 case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
630 * Distribute to the local clients on the channel and change the
634 SILC_LOG_DEBUG(("CHANNEL CHANGE"));
636 if (sock->type != SILC_SOCKET_TYPE_ROUTER)
639 /* Get the old Channel ID */
640 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
643 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
647 /* Get the channel entry */
648 channel = silc_idlist_find_channel_by_id(server->global_list,
651 channel = silc_idlist_find_channel_by_id(server->local_list,
654 silc_free(channel_id);
659 /* Send the notify to the channel */
660 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
661 FALSE, packet->buffer->data,
662 packet->buffer->len, FALSE);
664 /* Get the new Channel ID */
665 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
668 channel_id2 = silc_id_payload_parse_id(tmp, tmp_len);
672 SILC_LOG_DEBUG(("Old Channel ID id(%s)",
673 silc_id_render(channel_id, SILC_ID_CHANNEL)));
674 SILC_LOG_DEBUG(("New Channel ID id(%s)",
675 silc_id_render(channel_id2, SILC_ID_CHANNEL)));
677 /* Replace the Channel ID */
678 if (!silc_idlist_replace_channel_id(server->global_list, channel_id,
680 if (!silc_idlist_replace_channel_id(server->local_list, channel_id,
682 silc_free(channel_id2);
687 SilcBuffer users = NULL, users_modes = NULL;
689 /* Re-announce our clients on the channel as the ID has changed now */
690 silc_server_announce_get_channel_users(server, channel, &users,
693 silc_buffer_push(users, users->data - users->head);
694 silc_server_packet_send(server, sock,
695 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
696 users->data, users->len, FALSE);
697 silc_buffer_free(users);
700 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
701 silc_server_packet_send(server, sock,
702 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
703 users_modes->data, users_modes->len, FALSE);
704 silc_buffer_free(users_modes);
708 silc_free(channel_id);
712 case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
714 * Remove the server entry and all clients that this server owns.
717 SILC_LOG_DEBUG(("SERVER SIGNOFF notify"));
720 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
723 server_id = silc_id_payload_parse_id(tmp, tmp_len);
727 /* Get server entry */
728 server_entry = silc_idlist_find_server_by_id(server->global_list,
731 server_entry = silc_idlist_find_server_by_id(server->local_list,
734 silc_free(server_id);
738 silc_free(server_id);
740 /* Free all client entries that this server owns as they will
741 become invalid now as well. */
742 silc_server_remove_clients_by_server(server, server_entry, TRUE);
744 /* Remove the server entry */
745 if (!silc_idlist_del_server(server->global_list, server_entry))
746 silc_idlist_del_server(server->local_list, server_entry);
748 /* XXX update statistics */
752 case SILC_NOTIFY_TYPE_KICKED:
754 * Distribute the notify to local clients on the channel
757 SILC_LOG_DEBUG(("KICKED notify"));
759 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
760 packet->dst_id_type);
764 /* Get channel entry */
765 channel = silc_idlist_find_channel_by_id(server->global_list,
768 channel = silc_idlist_find_channel_by_id(server->local_list,
771 silc_free(channel_id);
775 silc_free(channel_id);
778 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
781 client_id = silc_id_payload_parse_id(tmp, tmp_len);
785 /* Send to channel */
786 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
787 FALSE, packet->buffer->data,
788 packet->buffer->len, FALSE);
790 /* If the the client is not in local list we check global list */
791 client = silc_idlist_find_client_by_id(server->global_list,
794 client = silc_idlist_find_client_by_id(server->local_list,
797 silc_free(client_id);
802 /* Remove the client from channel */
803 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
807 case SILC_NOTIFY_TYPE_KILLED:
810 * Distribute the notify to local clients on channels
815 SILC_LOG_DEBUG(("KILLED notify"));
818 id = silc_argument_get_arg_type(args, 1, &id_len);
821 client_id = silc_id_payload_parse_id(id, id_len);
825 /* If the the client is not in local list we check global list */
826 client = silc_idlist_find_client_by_id(server->global_list,
829 client = silc_idlist_find_client_by_id(server->local_list,
832 silc_free(client_id);
836 silc_free(client_id);
838 /* If the client is one of ours, then close the connection to the
839 client now. This removes the client from all channels as well. */
840 if (packet->dst_id_type == SILC_ID_CLIENT && client->data.registered &&
841 client->connection) {
842 sock = client->connection;
843 silc_server_free_client_data(server, NULL, client, FALSE, NULL);
844 silc_server_close_connection(server, sock);
849 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
853 /* Send the notify to local clients on the channels except to the
854 client who is killed. */
855 silc_server_send_notify_on_channels(server, client, client,
856 SILC_NOTIFY_TYPE_KILLED,
861 /* Remove the client from all channels */
862 silc_server_remove_from_channels(server, NULL, client, FALSE, NULL,
868 case SILC_NOTIFY_TYPE_UMODE_CHANGE:
870 * Save the mode of the client.
873 SILC_LOG_DEBUG(("UMODE_CHANGE notify"));
876 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
879 client_id = silc_id_payload_parse_id(tmp, tmp_len);
883 /* Get client entry */
884 client = silc_idlist_find_client_by_id(server->global_list,
887 client = silc_idlist_find_client_by_id(server->local_list,
890 silc_free(client_id);
894 silc_free(client_id);
897 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
902 SILC_GET32_MSB(client->mode, tmp);
906 case SILC_NOTIFY_TYPE_BAN:
911 SILC_LOG_DEBUG(("BAN notify"));
914 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
917 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
921 /* Get channel entry */
922 channel = silc_idlist_find_channel_by_id(server->global_list,
925 channel = silc_idlist_find_channel_by_id(server->local_list,
928 silc_free(channel_id);
932 silc_free(channel_id);
934 /* Get the new ban and add it to the ban list */
935 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
937 if (!channel->ban_list)
938 channel->ban_list = silc_calloc(tmp_len + 2,
939 sizeof(*channel->ban_list));
941 channel->ban_list = silc_realloc(channel->ban_list,
942 sizeof(*channel->ban_list) *
944 strlen(channel->ban_list) + 2));
945 strncat(channel->ban_list, tmp, tmp_len);
946 strncat(channel->ban_list, ",", 1);
949 /* Get the ban to be removed and remove it from the list */
950 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
951 if (tmp && channel->ban_list) {
952 char *start, *end, *n;
954 if (!strcmp(channel->ban_list, tmp)) {
955 silc_free(channel->ban_list);
956 channel->ban_list = NULL;
958 start = strstr(channel->ban_list, tmp);
959 if (start && strlen(start) >= tmp_len) {
960 end = start + tmp_len;
961 n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
962 strncat(n, channel->ban_list, start - channel->ban_list);
963 strncat(n, end + 1, ((channel->ban_list +
964 strlen(channel->ban_list)) - end) - 1);
965 silc_free(channel->ban_list);
966 channel->ban_list = n;
973 /* Ignore rest of the notify types for now */
974 case SILC_NOTIFY_TYPE_NONE:
975 case SILC_NOTIFY_TYPE_MOTD:
982 silc_notify_payload_free(payload);
985 void silc_server_notify_list(SilcServer server,
986 SilcSocketConnection sock,
987 SilcPacketContext *packet)
989 SilcPacketContext *new;
993 SILC_LOG_DEBUG(("Processing Notify List"));
995 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
996 packet->src_id_type != SILC_ID_SERVER)
999 /* Make copy of the original packet context, except for the actual
1000 data buffer, which we will here now fetch from the original buffer. */
1001 new = silc_packet_context_alloc();
1002 new->type = SILC_PACKET_NOTIFY;
1003 new->flags = packet->flags;
1004 new->src_id = packet->src_id;
1005 new->src_id_len = packet->src_id_len;
1006 new->src_id_type = packet->src_id_type;
1007 new->dst_id = packet->dst_id;
1008 new->dst_id_len = packet->dst_id_len;
1009 new->dst_id_type = packet->dst_id_type;
1011 buffer = silc_buffer_alloc(1024);
1012 new->buffer = buffer;
1014 while (packet->buffer->len) {
1015 SILC_GET16_MSB(len, packet->buffer->data + 2);
1016 if (len > packet->buffer->len)
1019 if (len > buffer->truelen) {
1020 silc_buffer_free(buffer);
1021 buffer = silc_buffer_alloc(1024 + len);
1024 silc_buffer_pull_tail(buffer, len);
1025 silc_buffer_put(buffer, packet->buffer->data, len);
1027 /* Process the Notify */
1028 silc_server_notify(server, sock, new);
1030 silc_buffer_push_tail(buffer, len);
1031 silc_buffer_pull(packet->buffer, len);
1034 silc_buffer_free(buffer);
1038 /* Received private message. This resolves the destination of the message
1039 and sends the packet. This is used by both server and router. If the
1040 destination is our locally connected client this sends the packet to
1041 the client. This may also send the message for further routing if
1042 the destination is not in our server (or router). */
1044 void silc_server_private_message(SilcServer server,
1045 SilcSocketConnection sock,
1046 SilcPacketContext *packet)
1048 SilcSocketConnection dst_sock;
1049 SilcIDListData idata;
1051 SILC_LOG_DEBUG(("Start"));
1053 if (packet->src_id_type != SILC_ID_CLIENT ||
1054 packet->dst_id_type != SILC_ID_CLIENT)
1057 if (!packet->dst_id)
1060 /* Get the route to the client */
1061 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1062 packet->dst_id_len, NULL, &idata);
1066 /* Send the private message */
1067 silc_server_send_private_message(server, dst_sock, idata->send_key,
1068 idata->hmac_send, packet);
1071 /* Received private message key packet.. This packet is never for us. It is to
1072 the client in the packet's destination ID. Sending of this sort of packet
1073 equals sending private message, ie. it is sent point to point from
1074 one client to another. */
1076 void silc_server_private_message_key(SilcServer server,
1077 SilcSocketConnection sock,
1078 SilcPacketContext *packet)
1080 SilcSocketConnection dst_sock;
1081 SilcIDListData idata;
1083 SILC_LOG_DEBUG(("Start"));
1085 if (packet->src_id_type != SILC_ID_CLIENT ||
1086 packet->dst_id_type != SILC_ID_CLIENT)
1089 if (!packet->dst_id)
1092 /* Get the route to the client */
1093 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1094 packet->dst_id_len, NULL, &idata);
1098 /* Relay the packet */
1099 silc_server_relay_packet(server, dst_sock, idata->send_key,
1100 idata->hmac_send, packet, FALSE);
1103 /* Processes incoming command reply packet. The command reply packet may
1104 be destined to one of our clients or it may directly for us. We will
1105 call the command reply routine after processing the packet. */
1107 void silc_server_command_reply(SilcServer server,
1108 SilcSocketConnection sock,
1109 SilcPacketContext *packet)
1111 SilcBuffer buffer = packet->buffer;
1112 SilcClientEntry client = NULL;
1113 SilcSocketConnection dst_sock;
1114 SilcIDListData idata;
1115 SilcClientID *id = NULL;
1117 SILC_LOG_DEBUG(("Start"));
1119 /* Source must be server or router */
1120 if (packet->src_id_type != SILC_ID_SERVER &&
1121 sock->type != SILC_SOCKET_TYPE_ROUTER)
1124 if (packet->dst_id_type == SILC_ID_CHANNEL)
1127 if (packet->dst_id_type == SILC_ID_CLIENT) {
1128 /* Destination must be one of ours */
1129 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
1132 client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
1134 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
1140 if (packet->dst_id_type == SILC_ID_SERVER) {
1141 /* For now this must be for us */
1142 if (memcmp(packet->dst_id, server->id_string, packet->dst_id_len)) {
1143 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
1148 /* Execute command reply locally for the command */
1149 silc_server_command_reply_process(server, sock, buffer);
1151 if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
1152 /* Relay the packet to the client */
1154 dst_sock = (SilcSocketConnection)client->connection;
1155 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
1156 + packet->dst_id_len + packet->padlen);
1158 silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
1159 silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
1161 idata = (SilcIDListData)client;
1163 /* Encrypt packet */
1164 silc_packet_encrypt(idata->send_key, idata->hmac_send, dst_sock->outbuf,
1167 /* Send the packet */
1168 silc_server_packet_send_real(server, dst_sock, TRUE);
1174 /* Process received channel message. The message can be originated from
1175 client or server. */
1177 void silc_server_channel_message(SilcServer server,
1178 SilcSocketConnection sock,
1179 SilcPacketContext *packet)
1181 SilcChannelEntry channel = NULL;
1182 SilcChannelID *id = NULL;
1183 void *sender = NULL;
1184 void *sender_entry = NULL;
1186 SILC_LOG_DEBUG(("Processing channel message"));
1189 if (packet->dst_id_type != SILC_ID_CHANNEL) {
1190 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1194 /* Find channel entry */
1195 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
1198 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
1200 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
1202 SILC_LOG_DEBUG(("Could not find channel"));
1207 /* See that this client is on the channel. If the original sender is
1208 not client (as it can be server as well) we don't do the check. */
1209 sender = silc_id_str2id(packet->src_id, packet->src_id_len,
1210 packet->src_id_type);
1213 if (packet->src_id_type == SILC_ID_CLIENT) {
1214 sender_entry = silc_idlist_find_client_by_id(server->local_list,
1217 sender_entry = silc_idlist_find_client_by_id(server->global_list,
1219 if (!sender_entry || !silc_server_client_on_channel(sender_entry,
1221 SILC_LOG_DEBUG(("Client not on channel"));
1226 /* Distribute the packet to our local clients. This will send the
1227 packet for further routing as well, if needed. */
1228 silc_server_packet_relay_to_channel(server, sock, channel, sender,
1229 packet->src_id_type, sender_entry,
1230 packet->buffer->data,
1231 packet->buffer->len, FALSE);
1240 /* Received channel key packet. We distribute the key to all of our locally
1241 connected clients on the channel. */
1243 void silc_server_channel_key(SilcServer server,
1244 SilcSocketConnection sock,
1245 SilcPacketContext *packet)
1247 SilcBuffer buffer = packet->buffer;
1248 SilcChannelEntry channel;
1250 if (packet->src_id_type != SILC_ID_SERVER ||
1251 (server->server_type == SILC_ROUTER &&
1252 sock->type == SILC_SOCKET_TYPE_ROUTER))
1255 /* Save the channel key */
1256 channel = silc_server_save_channel_key(server, buffer, NULL);
1260 /* Distribute the key to everybody who is on the channel. If we are router
1261 we will also send it to locally connected servers. */
1262 silc_server_send_channel_key(server, sock, channel, FALSE);
1265 /* Received New Client packet and processes it. Creates Client ID for the
1266 client. Client becomes registered after calling this functions. */
1268 SilcClientEntry silc_server_new_client(SilcServer server,
1269 SilcSocketConnection sock,
1270 SilcPacketContext *packet)
1272 SilcBuffer buffer = packet->buffer;
1273 SilcClientEntry client;
1274 SilcClientID *client_id;
1276 SilcIDListData idata;
1277 char *username = NULL, *realname = NULL, *id_string;
1281 SILC_LOG_DEBUG(("Creating new client"));
1283 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
1286 /* Take client entry */
1287 client = (SilcClientEntry)sock->user_data;
1288 idata = (SilcIDListData)client;
1290 /* Remove the old cache entry */
1291 if (!silc_idcache_del_by_context(server->local_list->clients, client)) {
1292 SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
1293 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1298 /* Parse incoming packet */
1299 ret = silc_buffer_unformat(buffer,
1300 SILC_STR_UI16_STRING_ALLOC(&username),
1301 SILC_STR_UI16_STRING_ALLOC(&realname),
1305 silc_free(username);
1307 silc_free(realname);
1308 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1309 "Incomplete client information");
1314 silc_free(username);
1316 silc_free(realname);
1317 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1318 "Incomplete client information");
1322 /* Create Client ID */
1323 silc_id_create_client_id(server->id, server->rng, server->md5hash,
1324 username, &client_id);
1326 if (strlen(username) > 128)
1327 username[127] = '\0';
1329 /* Update client entry */
1330 idata->registered = TRUE;
1331 client->nickname = strdup(username);
1332 client->username = username;
1333 client->userinfo = realname ? realname : strdup(" ");
1334 client->id = client_id;
1335 id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
1337 /* Add the client again to the ID cache */
1338 silc_idcache_add(server->local_list->clients, client->nickname,
1339 client_id, client, FALSE);
1341 /* Notify our router about new client on the SILC network */
1342 if (!server->standalone)
1343 silc_server_send_new_id(server, (SilcSocketConnection)
1344 server->router->connection,
1345 server->server_type == SILC_ROUTER ? TRUE : FALSE,
1346 client->id, SILC_ID_CLIENT, id_len);
1348 /* Send the new client ID to the client. */
1349 id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
1350 reply = silc_buffer_alloc(2 + 2 + id_len);
1351 silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
1352 silc_buffer_format(reply,
1353 SILC_STR_UI_SHORT(SILC_ID_CLIENT),
1354 SILC_STR_UI_SHORT(id_len),
1355 SILC_STR_UI_XNSTRING(id_string, id_len),
1357 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0,
1358 reply->data, reply->len, FALSE);
1359 silc_free(id_string);
1360 silc_buffer_free(reply);
1362 /* Send some nice info to the client */
1363 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1364 ("Welcome to the SILC Network %s@%s",
1365 username, sock->hostname));
1366 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1367 ("Your host is %s, running version %s",
1368 server->config->server_info->server_name,
1370 if (server->server_type == SILC_ROUTER) {
1371 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1372 ("There are %d clients on %d servers in SILC "
1373 "Network", server->stat.clients,
1374 server->stat.servers + 1));
1375 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1376 ("There are %d clients on %d server in our cell",
1377 server->stat.cell_clients,
1378 server->stat.cell_servers + 1));
1379 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1380 ("I have %d clients, %d channels, %d servers and "
1382 server->stat.my_clients,
1383 server->stat.my_channels,
1384 server->stat.my_servers,
1385 server->stat.my_routers));
1386 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1387 ("%d server operators and %d router operators "
1389 server->stat.my_server_ops,
1390 server->stat.my_router_ops));
1392 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1393 ("I have %d clients and %d channels formed",
1394 server->stat.my_clients,
1395 server->stat.my_channels));
1396 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1397 ("%d operators online",
1398 server->stat.my_server_ops));
1400 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1401 ("Your connection is secured with %s cipher, "
1402 "key length %d bits",
1403 idata->send_key->cipher->name,
1404 idata->send_key->cipher->key_len));
1405 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1406 ("Your current nickname is %s",
1410 silc_server_send_motd(server, sock);
1415 /* Create new server. This processes received New Server packet and
1416 saves the received Server ID. The server is our locally connected
1417 server thus we save all the information and save it to local list.
1418 This funtion can be used by both normal server and router server.
1419 If normal server uses this it means that its router has connected
1420 to the server. If router uses this it means that one of the cell's
1421 servers is connected to the router. */
1423 SilcServerEntry silc_server_new_server(SilcServer server,
1424 SilcSocketConnection sock,
1425 SilcPacketContext *packet)
1427 SilcBuffer buffer = packet->buffer;
1428 SilcServerEntry new_server;
1429 SilcServerID *server_id;
1430 SilcIDListData idata;
1431 unsigned char *server_name, *id_string;
1432 uint16 id_len, name_len;
1435 SILC_LOG_DEBUG(("Creating new server"));
1437 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
1438 sock->type != SILC_SOCKET_TYPE_ROUTER)
1441 /* Take server entry */
1442 new_server = (SilcServerEntry)sock->user_data;
1443 idata = (SilcIDListData)new_server;
1445 /* Remove the old cache entry */
1446 silc_idcache_del_by_context(server->local_list->servers, new_server);
1448 /* Parse the incoming packet */
1449 ret = silc_buffer_unformat(buffer,
1450 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
1451 SILC_STR_UI16_NSTRING_ALLOC(&server_name,
1456 silc_free(id_string);
1458 silc_free(server_name);
1462 if (id_len > buffer->len) {
1463 silc_free(id_string);
1464 silc_free(server_name);
1469 server_name[255] = '\0';
1472 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
1474 silc_free(id_string);
1475 silc_free(server_name);
1478 silc_free(id_string);
1480 /* Update server entry */
1481 idata->registered = TRUE;
1482 new_server->server_name = server_name;
1483 new_server->id = server_id;
1485 /* Add again the entry to the ID cache. */
1486 silc_idcache_add(server->local_list->servers, server_name, server_id,
1489 /* Distribute the information about new server in the SILC network
1490 to our router. If we are normal server we won't send anything
1491 since this connection must be our router connection. */
1492 if (server->server_type == SILC_ROUTER && !server->standalone &&
1493 server->router->connection != sock)
1494 silc_server_send_new_id(server, server->router->connection,
1495 TRUE, new_server->id, SILC_ID_SERVER,
1496 silc_id_get_len(server_id, SILC_ID_SERVER));
1498 if (server->server_type == SILC_ROUTER)
1499 server->stat.cell_servers++;
1504 /* Processes incoming New ID packet. New ID Payload is used to distribute
1505 information about newly registered clients and servers. */
1507 static void silc_server_new_id_real(SilcServer server,
1508 SilcSocketConnection sock,
1509 SilcPacketContext *packet,
1512 SilcBuffer buffer = packet->buffer;
1514 SilcServerEntry router;
1515 SilcSocketConnection router_sock;
1520 SILC_LOG_DEBUG(("Processing new ID"));
1522 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1523 server->server_type == SILC_SERVER ||
1524 packet->src_id_type != SILC_ID_SERVER)
1527 idp = silc_id_payload_parse(buffer);
1531 id_type = silc_id_payload_get_type(idp);
1533 /* Normal server cannot have other normal server connections */
1534 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
1537 id = silc_id_payload_get_id(idp);
1541 /* If the sender of this packet is server and we are router we need to
1542 broadcast this packet to other routers in the network. */
1543 if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
1544 sock->type == SILC_SOCKET_TYPE_SERVER &&
1545 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1546 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
1547 silc_server_packet_send(server, server->router->connection,
1549 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1550 buffer->data, buffer->len, FALSE);
1553 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1554 id_list = server->local_list;
1556 id_list = server->global_list;
1558 /* If the packet is coming from server then use the sender as the
1559 origin of the the packet. If it came from router then check the real
1560 sender of the packet and use that as the origin. */
1561 if (sock->type == SILC_SOCKET_TYPE_SERVER) {
1563 router = sock->user_data;
1565 void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1566 packet->src_id_type);
1567 router = silc_idlist_find_server_by_id(server->global_list,
1570 router = silc_idlist_find_server_by_id(server->local_list,
1572 silc_free(sender_id);
1579 case SILC_ID_CLIENT:
1581 SilcClientEntry entry;
1583 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
1584 silc_id_render(id, SILC_ID_CLIENT),
1585 sock->type == SILC_SOCKET_TYPE_SERVER ?
1586 "Server" : "Router", sock->hostname));
1588 /* As a router we keep information of all global information in our
1589 global list. Cell wide information however is kept in the local
1591 entry = silc_idlist_add_client(id_list, NULL, NULL, NULL,
1593 entry->nickname = NULL;
1594 entry->data.registered = TRUE;
1596 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1597 server->stat.cell_clients++;
1598 server->stat.clients++;
1602 case SILC_ID_SERVER:
1603 /* If the ID is mine, ignore it. */
1604 if (SILC_ID_SERVER_COMPARE(id, server->id)) {
1605 SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
1609 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
1610 silc_id_render(id, SILC_ID_SERVER),
1611 sock->type == SILC_SOCKET_TYPE_SERVER ?
1612 "Server" : "Router", sock->hostname));
1614 /* As a router we keep information of all global information in our global
1615 list. Cell wide information however is kept in the local list. */
1616 silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
1618 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1619 server->stat.cell_servers++;
1620 server->stat.servers++;
1623 case SILC_ID_CHANNEL:
1624 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
1632 silc_id_payload_free(idp);
1636 /* Processes incoming New ID packet. New ID Payload is used to distribute
1637 information about newly registered clients and servers. */
1639 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
1640 SilcPacketContext *packet)
1642 silc_server_new_id_real(server, sock, packet, TRUE);
1645 /* Receoved New Id List packet, list of New ID payloads inside one
1646 packet. Process the New ID payloads one by one. */
1648 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
1649 SilcPacketContext *packet)
1651 SilcPacketContext *new_id;
1655 SILC_LOG_DEBUG(("Processing New ID List"));
1657 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1658 packet->src_id_type != SILC_ID_SERVER)
1661 /* If the sender of this packet is server and we are router we need to
1662 broadcast this packet to other routers in the network. Broadcast
1663 this list packet instead of multiple New ID packets. */
1664 if (!server->standalone && server->server_type == SILC_ROUTER &&
1665 sock->type == SILC_SOCKET_TYPE_SERVER &&
1666 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1667 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
1668 silc_server_packet_send(server, server->router->connection,
1670 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1671 packet->buffer->data, packet->buffer->len, FALSE);
1674 /* Make copy of the original packet context, except for the actual
1675 data buffer, which we will here now fetch from the original buffer. */
1676 new_id = silc_packet_context_alloc();
1677 new_id->type = SILC_PACKET_NEW_ID;
1678 new_id->flags = packet->flags;
1679 new_id->src_id = packet->src_id;
1680 new_id->src_id_len = packet->src_id_len;
1681 new_id->src_id_type = packet->src_id_type;
1682 new_id->dst_id = packet->dst_id;
1683 new_id->dst_id_len = packet->dst_id_len;
1684 new_id->dst_id_type = packet->dst_id_type;
1686 idp = silc_buffer_alloc(256);
1687 new_id->buffer = idp;
1689 while (packet->buffer->len) {
1690 SILC_GET16_MSB(id_len, packet->buffer->data + 2);
1691 if ((id_len > packet->buffer->len) ||
1692 (id_len > idp->truelen))
1695 silc_buffer_pull_tail(idp, 4 + id_len);
1696 silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
1698 /* Process the New ID */
1699 silc_server_new_id_real(server, sock, new_id, FALSE);
1701 silc_buffer_push_tail(idp, 4 + id_len);
1702 silc_buffer_pull(packet->buffer, 4 + id_len);
1705 silc_buffer_free(idp);
1709 /* Received New Channel packet. Information about new channels in the
1710 network are distributed using this packet. Save the information about
1711 the new channel. This usually comes from router but also normal server
1712 can send this to notify channels it has when it connects to us. */
1714 void silc_server_new_channel(SilcServer server,
1715 SilcSocketConnection sock,
1716 SilcPacketContext *packet)
1718 SilcChannelPayload payload;
1719 SilcChannelID *channel_id;
1726 SILC_LOG_DEBUG(("Processing New Channel"));
1728 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1729 packet->src_id_type != SILC_ID_SERVER ||
1730 server->server_type == SILC_SERVER)
1733 /* Parse the channel payload */
1734 payload = silc_channel_payload_parse(packet->buffer);
1738 /* Get the channel ID */
1739 channel_id = silc_channel_get_id_parse(payload);
1741 silc_channel_payload_free(payload);
1745 channel_name = silc_channel_get_name(payload, &name_len);
1747 channel_name[255] = '\0';
1749 id = silc_channel_get_id(payload, &id_len);
1751 if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
1752 /* Add the server to global list as it is coming from router. It
1753 cannot be our own channel as it is coming from router. */
1755 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
1756 silc_id_render(channel_id, SILC_ID_CHANNEL),
1759 silc_idlist_add_channel(server->global_list, strdup(channel_name),
1760 0, channel_id, server->router->connection,
1763 server->stat.channels++;
1765 /* The channel is coming from our server, thus it is in our cell
1766 we will add it to our local list. */
1767 SilcChannelEntry channel;
1770 SILC_LOG_DEBUG(("New channel id(%s) from [Server] %s",
1771 silc_id_render(channel_id, SILC_ID_CHANNEL),
1774 /* Check that we don't already have this channel */
1775 channel = silc_idlist_find_channel_by_name(server->local_list,
1776 channel_name, NULL);
1778 channel = silc_idlist_find_channel_by_name(server->global_list,
1779 channel_name, NULL);
1781 /* If the channel does not exist, then create it. We create the channel
1782 with the channel ID provided by the server. This creates a new
1783 key to the channel as well that we will send to the server. */
1785 channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
1789 silc_channel_payload_free(payload);
1790 silc_free(channel_id);
1794 /* Send the new channel key to the server */
1795 chk = silc_channel_key_payload_encode(id_len, id,
1796 strlen(channel->channel_key->
1798 channel->channel_key->cipher->name,
1799 channel->key_len / 8,
1801 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
1802 chk->data, chk->len, FALSE);
1803 silc_buffer_free(chk);
1806 /* The channel exist by that name, check whether the ID's match.
1807 If they don't then we'll force the server to use the ID we have.
1808 We also create a new key for the channel. */
1809 SilcBuffer users = NULL, users_modes = NULL;
1812 channel_id = silc_id_dup(channel_id, SILC_ID_CHANNEL);
1814 if (!SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
1815 /* They don't match, send CHANNEL_CHANGE notify to the server to
1816 force the ID change. */
1817 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
1818 silc_server_send_notify_channel_change(server, sock, FALSE,
1819 channel_id, channel->id);
1822 /* If the mode is different from what we have then enforce the
1824 mode = silc_channel_get_mode(payload);
1825 if (channel->mode != mode) {
1826 SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
1827 silc_server_send_notify_cmode(server, sock, FALSE, channel,
1828 channel->mode, server->id,
1830 channel->cipher, channel->hmac_name);
1833 /* Create new key for the channel and send it to the server and
1834 everybody else possibly on the channel. */
1836 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
1837 silc_server_create_channel_key(server, channel, 0);
1839 /* Send to the channel */
1840 silc_server_send_channel_key(server, sock, channel, FALSE);
1841 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
1842 id_len = SILC_ID_CHANNEL_LEN;
1844 /* Send to the server */
1845 chk = silc_channel_key_payload_encode(id_len, id,
1846 strlen(channel->channel_key->
1848 channel->channel_key->
1850 channel->key_len / 8,
1852 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
1853 chk->data, chk->len, FALSE);
1854 silc_buffer_free(chk);
1858 silc_free(channel_id);
1860 /* Since the channel is coming from server and we also know about it
1861 then send the JOIN notify to the server so that it see's our
1862 users on the channel "joining" the channel. */
1863 silc_server_announce_get_channel_users(server, channel, &users,
1866 silc_buffer_push(users, users->data - users->head);
1867 silc_server_packet_send(server, sock,
1868 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1869 users->data, users->len, FALSE);
1870 silc_buffer_free(users);
1873 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
1874 silc_server_packet_send(server, sock,
1875 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1876 users_modes->data, users_modes->len, FALSE);
1877 silc_buffer_free(users_modes);
1882 silc_channel_payload_free(payload);
1885 /* Received New Channel List packet, list of New Channel List payloads inside
1886 one packet. Process the New Channel payloads one by one. */
1888 void silc_server_new_channel_list(SilcServer server,
1889 SilcSocketConnection sock,
1890 SilcPacketContext *packet)
1892 SilcPacketContext *new;
1896 SILC_LOG_DEBUG(("Processing New Channel List"));
1898 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1899 packet->src_id_type != SILC_ID_SERVER ||
1900 server->server_type == SILC_SERVER)
1903 /* If the sender of this packet is server and we are router we need to
1904 broadcast this packet to other routers in the network. Broadcast
1905 this list packet instead of multiple New Channel packets. */
1906 if (!server->standalone && server->server_type == SILC_ROUTER &&
1907 sock->type == SILC_SOCKET_TYPE_SERVER &&
1908 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1909 SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
1910 silc_server_packet_send(server, server->router->connection,
1912 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1913 packet->buffer->data, packet->buffer->len, FALSE);
1916 /* Make copy of the original packet context, except for the actual
1917 data buffer, which we will here now fetch from the original buffer. */
1918 new = silc_packet_context_alloc();
1919 new->type = SILC_PACKET_NEW_CHANNEL;
1920 new->flags = packet->flags;
1921 new->src_id = packet->src_id;
1922 new->src_id_len = packet->src_id_len;
1923 new->src_id_type = packet->src_id_type;
1924 new->dst_id = packet->dst_id;
1925 new->dst_id_len = packet->dst_id_len;
1926 new->dst_id_type = packet->dst_id_type;
1928 buffer = silc_buffer_alloc(512);
1929 new->buffer = buffer;
1931 while (packet->buffer->len) {
1932 SILC_GET16_MSB(len1, packet->buffer->data);
1933 if ((len1 > packet->buffer->len) ||
1934 (len1 > buffer->truelen))
1937 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
1938 if ((len2 > packet->buffer->len) ||
1939 (len2 > buffer->truelen))
1942 silc_buffer_pull_tail(buffer, 8 + len1 + len2);
1943 silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
1945 /* Process the New Channel */
1946 silc_server_new_channel(server, sock, new);
1948 silc_buffer_push_tail(buffer, 8 + len1 + len2);
1949 silc_buffer_pull(packet->buffer, 8 + len1 + len2);
1952 silc_buffer_free(buffer);
1956 /* Received key agreement packet. This packet is never for us. It is to
1957 the client in the packet's destination ID. Sending of this sort of packet
1958 equals sending private message, ie. it is sent point to point from
1959 one client to another. */
1961 void silc_server_key_agreement(SilcServer server,
1962 SilcSocketConnection sock,
1963 SilcPacketContext *packet)
1965 SilcSocketConnection dst_sock;
1966 SilcIDListData idata;
1968 SILC_LOG_DEBUG(("Start"));
1970 if (packet->src_id_type != SILC_ID_CLIENT ||
1971 packet->dst_id_type != SILC_ID_CLIENT)
1974 if (!packet->dst_id)
1977 /* Get the route to the client */
1978 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1979 packet->dst_id_len, NULL, &idata);
1983 /* Relay the packet */
1984 silc_server_relay_packet(server, dst_sock, idata->send_key,
1985 idata->hmac_send, packet, FALSE);
1988 /* Received connection auth request packet that is used during connection
1989 phase to resolve the mandatory authentication method. This packet can
1990 actually be received at anytime but usually it is used only during
1991 the connection authentication phase. Now, protocol says that this packet
1992 can come from client or server, however, we support only this coming
1993 from client and expect that server's always knows what authentication
1996 void silc_server_connection_auth_request(SilcServer server,
1997 SilcSocketConnection sock,
1998 SilcPacketContext *packet)
2000 SilcServerConfigSectionClientConnection *client = NULL;
2003 SilcAuthMethod auth_meth;
2005 SILC_LOG_DEBUG(("Start"));
2007 if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT)
2010 /* Parse the payload */
2011 ret = silc_buffer_unformat(packet->buffer,
2012 SILC_STR_UI_SHORT(&conn_type),
2013 SILC_STR_UI_SHORT(NULL),
2018 if (conn_type != SILC_SOCKET_TYPE_CLIENT)
2021 /* Get the authentication method for the client */
2022 auth_meth = SILC_AUTH_NONE;
2023 client = silc_server_config_find_client_conn(server->config,
2027 client = silc_server_config_find_client_conn(server->config,
2031 auth_meth = client->auth_meth;
2033 /* Send it back to the client */
2034 silc_server_send_connection_auth_request(server, sock,
2039 /* Received REKEY packet. The sender of the packet wants to regenerate
2040 its session keys. This starts the REKEY protocol. */
2042 void silc_server_rekey(SilcServer server,
2043 SilcSocketConnection sock,
2044 SilcPacketContext *packet)
2046 SilcProtocol protocol;
2047 SilcServerRekeyInternalContext *proto_ctx;
2048 SilcIDListData idata = (SilcIDListData)sock->user_data;
2050 SILC_LOG_DEBUG(("Start"));
2052 /* Allocate internal protocol context. This is sent as context
2054 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
2055 proto_ctx->server = (void *)server;
2056 proto_ctx->sock = sock;
2057 proto_ctx->responder = TRUE;
2058 proto_ctx->pfs = idata->rekey->pfs;
2060 /* Perform rekey protocol. Will call the final callback after the
2061 protocol is over. */
2062 silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
2063 &protocol, proto_ctx, silc_server_rekey_final);
2064 sock->protocol = protocol;
2066 if (proto_ctx->pfs == FALSE)
2067 /* Run the protocol */
2068 protocol->execute(server->timeout_queue, 0, protocol, sock->sock, 0, 0);