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;
281 server->stat.clients--;
282 if (server->server_type == SILC_ROUTER)
283 server->stat.cell_clients--;
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 + 1, 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_hash_table_list(channel->user_list, &htl);
520 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
521 SilcChannelClientEntry chl2 = NULL;
523 /* If the mode is channel founder and we already find a client
524 to have that mode on the channel we will enforce the sender
525 to change the channel founder mode away. There can be only one
526 channel founder on the channel. */
527 if (server->server_type == SILC_ROUTER &&
528 mode & SILC_CHANNEL_UMODE_CHANFO &&
529 chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
530 silc_server_send_notify_cumode(server, sock, FALSE, channel,
531 (mode & (~SILC_CHANNEL_UMODE_CHANFO)),
532 server->id, SILC_ID_SERVER,
534 silc_free(channel_id);
536 /* Change the mode back if we changed it */
538 chl2->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
542 if (chl->client == client) {
543 /* Change the mode */
545 if (!(mode & SILC_CHANNEL_UMODE_CHANFO))
552 /* Send the same notify to the channel */
553 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
554 FALSE, packet->buffer->data,
555 packet->buffer->len, FALSE);
556 silc_free(channel_id);
559 case SILC_NOTIFY_TYPE_INVITE:
561 if (packet->dst_id_type == SILC_ID_CLIENT)
564 SILC_LOG_DEBUG(("INVITE notify"));
567 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
570 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
574 /* Get channel entry */
575 channel = silc_idlist_find_channel_by_id(server->global_list,
578 channel = silc_idlist_find_channel_by_id(server->local_list,
581 silc_free(channel_id);
585 silc_free(channel_id);
587 /* Get the added invite */
588 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
590 if (!channel->invite_list)
591 channel->invite_list = silc_calloc(tmp_len + 2,
592 sizeof(*channel->invite_list));
594 channel->invite_list = silc_realloc(channel->invite_list,
595 sizeof(*channel->invite_list) *
597 strlen(channel->invite_list) +
599 if (tmp[tmp_len - 1] == ',')
600 tmp[tmp_len - 1] = '\0';
602 strncat(channel->invite_list, tmp, tmp_len);
603 strncat(channel->invite_list, ",", 1);
606 /* Get the deleted invite */
607 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
608 if (tmp && channel->invite_list) {
609 char *start, *end, *n;
611 if (!strncmp(channel->invite_list, tmp,
612 strlen(channel->invite_list) - 1)) {
613 silc_free(channel->invite_list);
614 channel->invite_list = NULL;
616 start = strstr(channel->invite_list, tmp);
617 if (start && strlen(start) >= tmp_len) {
618 end = start + tmp_len;
619 n = silc_calloc(strlen(channel->invite_list) - tmp_len, sizeof(*n));
620 strncat(n, channel->invite_list, start - channel->invite_list);
621 strncat(n, end + 1, ((channel->invite_list +
622 strlen(channel->invite_list)) - end) - 1);
623 silc_free(channel->invite_list);
624 channel->invite_list = n;
631 case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
633 * Distribute to the local clients on the channel and change the
637 SILC_LOG_DEBUG(("CHANNEL CHANGE"));
639 if (sock->type != SILC_SOCKET_TYPE_ROUTER)
642 /* Get the old Channel ID */
643 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
646 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
650 /* Get the channel entry */
651 channel = silc_idlist_find_channel_by_id(server->global_list,
654 channel = silc_idlist_find_channel_by_id(server->local_list,
657 silc_free(channel_id);
662 /* Send the notify to the channel */
663 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
664 FALSE, packet->buffer->data,
665 packet->buffer->len, FALSE);
667 /* Get the new Channel ID */
668 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
671 channel_id2 = silc_id_payload_parse_id(tmp, tmp_len);
675 SILC_LOG_DEBUG(("Old Channel ID id(%s)",
676 silc_id_render(channel_id, SILC_ID_CHANNEL)));
677 SILC_LOG_DEBUG(("New Channel ID id(%s)",
678 silc_id_render(channel_id2, SILC_ID_CHANNEL)));
680 /* Replace the Channel ID */
681 if (!silc_idlist_replace_channel_id(server->global_list, channel_id,
683 if (!silc_idlist_replace_channel_id(server->local_list, channel_id,
685 silc_free(channel_id2);
690 SilcBuffer users = NULL, users_modes = NULL;
692 /* Re-announce our clients on the channel as the ID has changed now */
693 silc_server_announce_get_channel_users(server, channel, &users,
696 silc_buffer_push(users, users->data - users->head);
697 silc_server_packet_send(server, sock,
698 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
699 users->data, users->len, FALSE);
700 silc_buffer_free(users);
703 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
704 silc_server_packet_send(server, sock,
705 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
706 users_modes->data, users_modes->len, FALSE);
707 silc_buffer_free(users_modes);
711 silc_free(channel_id);
715 case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
717 * Remove the server entry and all clients that this server owns.
720 SILC_LOG_DEBUG(("SERVER SIGNOFF notify"));
723 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
726 server_id = silc_id_payload_parse_id(tmp, tmp_len);
730 /* Get server entry */
731 server_entry = silc_idlist_find_server_by_id(server->global_list,
734 server_entry = silc_idlist_find_server_by_id(server->local_list,
737 silc_free(server_id);
741 silc_free(server_id);
743 /* Free all client entries that this server owns as they will
744 become invalid now as well. */
745 silc_server_remove_clients_by_server(server, server_entry, TRUE);
747 /* Remove the server entry */
748 if (!silc_idlist_del_server(server->global_list, server_entry))
749 silc_idlist_del_server(server->local_list, server_entry);
751 /* XXX update statistics */
755 case SILC_NOTIFY_TYPE_KICKED:
757 * Distribute the notify to local clients on the channel
760 SILC_LOG_DEBUG(("KICKED notify"));
762 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
763 packet->dst_id_type);
767 /* Get channel entry */
768 channel = silc_idlist_find_channel_by_id(server->global_list,
771 channel = silc_idlist_find_channel_by_id(server->local_list,
774 silc_free(channel_id);
778 silc_free(channel_id);
781 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
784 client_id = silc_id_payload_parse_id(tmp, tmp_len);
788 /* Send to channel */
789 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
790 FALSE, packet->buffer->data,
791 packet->buffer->len, FALSE);
793 /* If the the client is not in local list we check global list */
794 client = silc_idlist_find_client_by_id(server->global_list,
797 client = silc_idlist_find_client_by_id(server->local_list,
800 silc_free(client_id);
805 /* Remove the client from channel */
806 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
810 case SILC_NOTIFY_TYPE_KILLED:
813 * Distribute the notify to local clients on channels
818 SILC_LOG_DEBUG(("KILLED notify"));
821 id = silc_argument_get_arg_type(args, 1, &id_len);
824 client_id = silc_id_payload_parse_id(id, id_len);
828 /* If the the client is not in local list we check global list */
829 client = silc_idlist_find_client_by_id(server->global_list,
832 client = silc_idlist_find_client_by_id(server->local_list,
835 silc_free(client_id);
839 silc_free(client_id);
841 /* If the client is one of ours, then close the connection to the
842 client now. This removes the client from all channels as well. */
843 if (packet->dst_id_type == SILC_ID_CLIENT && client->data.registered &&
844 client->connection) {
845 sock = client->connection;
846 silc_server_free_client_data(server, NULL, client, FALSE, NULL);
847 silc_server_close_connection(server, sock);
852 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
856 /* Send the notify to local clients on the channels except to the
857 client who is killed. */
858 silc_server_send_notify_on_channels(server, client, client,
859 SILC_NOTIFY_TYPE_KILLED,
864 /* Remove the client from all channels */
865 silc_server_remove_from_channels(server, NULL, client, FALSE, NULL,
871 case SILC_NOTIFY_TYPE_UMODE_CHANGE:
873 * Save the mode of the client.
876 SILC_LOG_DEBUG(("UMODE_CHANGE notify"));
879 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
882 client_id = silc_id_payload_parse_id(tmp, tmp_len);
886 /* Get client entry */
887 client = silc_idlist_find_client_by_id(server->global_list,
890 client = silc_idlist_find_client_by_id(server->local_list,
893 silc_free(client_id);
897 silc_free(client_id);
900 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
905 SILC_GET32_MSB(client->mode, tmp);
909 case SILC_NOTIFY_TYPE_BAN:
914 SILC_LOG_DEBUG(("BAN notify"));
917 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
920 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
924 /* Get channel entry */
925 channel = silc_idlist_find_channel_by_id(server->global_list,
928 channel = silc_idlist_find_channel_by_id(server->local_list,
931 silc_free(channel_id);
935 silc_free(channel_id);
937 /* Get the new ban and add it to the ban list */
938 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
940 if (!channel->ban_list)
941 channel->ban_list = silc_calloc(tmp_len + 2,
942 sizeof(*channel->ban_list));
944 channel->ban_list = silc_realloc(channel->ban_list,
945 sizeof(*channel->ban_list) *
947 strlen(channel->ban_list) + 2));
948 strncat(channel->ban_list, tmp, tmp_len);
949 strncat(channel->ban_list, ",", 1);
952 /* Get the ban to be removed and remove it from the list */
953 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
954 if (tmp && channel->ban_list) {
955 char *start, *end, *n;
957 if (!strcmp(channel->ban_list, tmp)) {
958 silc_free(channel->ban_list);
959 channel->ban_list = NULL;
961 start = strstr(channel->ban_list, tmp);
962 if (start && strlen(start) >= tmp_len) {
963 end = start + tmp_len;
964 n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
965 strncat(n, channel->ban_list, start - channel->ban_list);
966 strncat(n, end + 1, ((channel->ban_list +
967 strlen(channel->ban_list)) - end) - 1);
968 silc_free(channel->ban_list);
969 channel->ban_list = n;
976 /* Ignore rest of the notify types for now */
977 case SILC_NOTIFY_TYPE_NONE:
978 case SILC_NOTIFY_TYPE_MOTD:
985 silc_notify_payload_free(payload);
988 void silc_server_notify_list(SilcServer server,
989 SilcSocketConnection sock,
990 SilcPacketContext *packet)
992 SilcPacketContext *new;
996 SILC_LOG_DEBUG(("Processing Notify List"));
998 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
999 packet->src_id_type != SILC_ID_SERVER)
1002 /* Make copy of the original packet context, except for the actual
1003 data buffer, which we will here now fetch from the original buffer. */
1004 new = silc_packet_context_alloc();
1005 new->type = SILC_PACKET_NOTIFY;
1006 new->flags = packet->flags;
1007 new->src_id = packet->src_id;
1008 new->src_id_len = packet->src_id_len;
1009 new->src_id_type = packet->src_id_type;
1010 new->dst_id = packet->dst_id;
1011 new->dst_id_len = packet->dst_id_len;
1012 new->dst_id_type = packet->dst_id_type;
1014 buffer = silc_buffer_alloc(1024);
1015 new->buffer = buffer;
1017 while (packet->buffer->len) {
1018 SILC_GET16_MSB(len, packet->buffer->data + 2);
1019 if (len > packet->buffer->len)
1022 if (len > buffer->truelen) {
1023 silc_buffer_free(buffer);
1024 buffer = silc_buffer_alloc(1024 + len);
1027 silc_buffer_pull_tail(buffer, len);
1028 silc_buffer_put(buffer, packet->buffer->data, len);
1030 /* Process the Notify */
1031 silc_server_notify(server, sock, new);
1033 silc_buffer_push_tail(buffer, len);
1034 silc_buffer_pull(packet->buffer, len);
1037 silc_buffer_free(buffer);
1041 /* Received private message. This resolves the destination of the message
1042 and sends the packet. This is used by both server and router. If the
1043 destination is our locally connected client this sends the packet to
1044 the client. This may also send the message for further routing if
1045 the destination is not in our server (or router). */
1047 void silc_server_private_message(SilcServer server,
1048 SilcSocketConnection sock,
1049 SilcPacketContext *packet)
1051 SilcSocketConnection dst_sock;
1052 SilcIDListData idata;
1054 SILC_LOG_DEBUG(("Start"));
1056 if (packet->src_id_type != SILC_ID_CLIENT ||
1057 packet->dst_id_type != SILC_ID_CLIENT)
1060 if (!packet->dst_id)
1063 /* Get the route to the client */
1064 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1065 packet->dst_id_len, NULL, &idata);
1069 /* Send the private message */
1070 silc_server_send_private_message(server, dst_sock, idata->send_key,
1071 idata->hmac_send, packet);
1074 /* Received private message key packet.. This packet is never for us. It is to
1075 the client in the packet's destination ID. Sending of this sort of packet
1076 equals sending private message, ie. it is sent point to point from
1077 one client to another. */
1079 void silc_server_private_message_key(SilcServer server,
1080 SilcSocketConnection sock,
1081 SilcPacketContext *packet)
1083 SilcSocketConnection dst_sock;
1084 SilcIDListData idata;
1086 SILC_LOG_DEBUG(("Start"));
1088 if (packet->src_id_type != SILC_ID_CLIENT ||
1089 packet->dst_id_type != SILC_ID_CLIENT)
1092 if (!packet->dst_id)
1095 /* Get the route to the client */
1096 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1097 packet->dst_id_len, NULL, &idata);
1101 /* Relay the packet */
1102 silc_server_relay_packet(server, dst_sock, idata->send_key,
1103 idata->hmac_send, packet, FALSE);
1106 /* Processes incoming command reply packet. The command reply packet may
1107 be destined to one of our clients or it may directly for us. We will
1108 call the command reply routine after processing the packet. */
1110 void silc_server_command_reply(SilcServer server,
1111 SilcSocketConnection sock,
1112 SilcPacketContext *packet)
1114 SilcBuffer buffer = packet->buffer;
1115 SilcClientEntry client = NULL;
1116 SilcSocketConnection dst_sock;
1117 SilcIDListData idata;
1118 SilcClientID *id = NULL;
1120 SILC_LOG_DEBUG(("Start"));
1122 /* Source must be server or router */
1123 if (packet->src_id_type != SILC_ID_SERVER &&
1124 sock->type != SILC_SOCKET_TYPE_ROUTER)
1127 if (packet->dst_id_type == SILC_ID_CHANNEL)
1130 if (packet->dst_id_type == SILC_ID_CLIENT) {
1131 /* Destination must be one of ours */
1132 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
1135 client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
1137 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
1143 if (packet->dst_id_type == SILC_ID_SERVER) {
1144 /* For now this must be for us */
1145 if (memcmp(packet->dst_id, server->id_string, packet->dst_id_len)) {
1146 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
1151 /* Execute command reply locally for the command */
1152 silc_server_command_reply_process(server, sock, buffer);
1154 if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
1155 /* Relay the packet to the client */
1157 dst_sock = (SilcSocketConnection)client->connection;
1158 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
1159 + packet->dst_id_len + packet->padlen);
1161 silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
1162 silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
1164 idata = (SilcIDListData)client;
1166 /* Encrypt packet */
1167 silc_packet_encrypt(idata->send_key, idata->hmac_send, dst_sock->outbuf,
1170 /* Send the packet */
1171 silc_server_packet_send_real(server, dst_sock, TRUE);
1177 /* Process received channel message. The message can be originated from
1178 client or server. */
1180 void silc_server_channel_message(SilcServer server,
1181 SilcSocketConnection sock,
1182 SilcPacketContext *packet)
1184 SilcChannelEntry channel = NULL;
1185 SilcChannelID *id = NULL;
1186 void *sender = NULL;
1187 void *sender_entry = NULL;
1189 SILC_LOG_DEBUG(("Processing channel message"));
1192 if (packet->dst_id_type != SILC_ID_CHANNEL) {
1193 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1197 /* Find channel entry */
1198 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
1201 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
1203 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
1205 SILC_LOG_DEBUG(("Could not find channel"));
1210 /* See that this client is on the channel. If the original sender is
1211 not client (as it can be server as well) we don't do the check. */
1212 sender = silc_id_str2id(packet->src_id, packet->src_id_len,
1213 packet->src_id_type);
1216 if (packet->src_id_type == SILC_ID_CLIENT) {
1217 sender_entry = silc_idlist_find_client_by_id(server->local_list,
1220 sender_entry = silc_idlist_find_client_by_id(server->global_list,
1222 if (!sender_entry || !silc_server_client_on_channel(sender_entry,
1224 SILC_LOG_DEBUG(("Client not on channel"));
1229 /* Distribute the packet to our local clients. This will send the
1230 packet for further routing as well, if needed. */
1231 silc_server_packet_relay_to_channel(server, sock, channel, sender,
1232 packet->src_id_type, sender_entry,
1233 packet->buffer->data,
1234 packet->buffer->len, FALSE);
1243 /* Received channel key packet. We distribute the key to all of our locally
1244 connected clients on the channel. */
1246 void silc_server_channel_key(SilcServer server,
1247 SilcSocketConnection sock,
1248 SilcPacketContext *packet)
1250 SilcBuffer buffer = packet->buffer;
1251 SilcChannelEntry channel;
1253 if (packet->src_id_type != SILC_ID_SERVER ||
1254 (server->server_type == SILC_ROUTER &&
1255 sock->type == SILC_SOCKET_TYPE_ROUTER))
1258 /* Save the channel key */
1259 channel = silc_server_save_channel_key(server, buffer, NULL);
1263 /* Distribute the key to everybody who is on the channel. If we are router
1264 we will also send it to locally connected servers. */
1265 silc_server_send_channel_key(server, sock, channel, FALSE);
1268 /* Received New Client packet and processes it. Creates Client ID for the
1269 client. Client becomes registered after calling this functions. */
1271 SilcClientEntry silc_server_new_client(SilcServer server,
1272 SilcSocketConnection sock,
1273 SilcPacketContext *packet)
1275 SilcBuffer buffer = packet->buffer;
1276 SilcClientEntry client;
1277 SilcClientID *client_id;
1279 SilcIDListData idata;
1280 char *username = NULL, *realname = NULL, *id_string;
1283 char *hostname, *nickname;
1285 SILC_LOG_DEBUG(("Creating new client"));
1287 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
1290 /* Take client entry */
1291 client = (SilcClientEntry)sock->user_data;
1292 idata = (SilcIDListData)client;
1294 /* Remove the old cache entry */
1295 if (!silc_idcache_del_by_context(server->local_list->clients, client)) {
1296 SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
1297 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1302 /* Parse incoming packet */
1303 ret = silc_buffer_unformat(buffer,
1304 SILC_STR_UI16_STRING_ALLOC(&username),
1305 SILC_STR_UI16_STRING_ALLOC(&realname),
1309 silc_free(username);
1311 silc_free(realname);
1312 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1313 "Incomplete client information");
1318 silc_free(username);
1320 silc_free(realname);
1321 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1322 "Incomplete client information");
1326 if (strlen(username) > 128)
1327 username[127] = '\0';
1329 nickname = strdup(username);
1331 /* Make sanity checks for the hostname of the client. If the hostname
1332 is provided in the `username' check that it is the same than the
1333 resolved hostname, or if not resolved the hostname that appears in
1334 the client's public key. If the hostname is not present then put
1335 it from the resolved name or from the public key. */
1336 if (strchr(username, '@')) {
1337 SilcPublicKeyIdentifier pident;
1338 int tlen = strcspn(username, "@");
1339 char *phostname = NULL;
1341 hostname = silc_calloc((strlen(username) - tlen) + 1, sizeof(char));
1342 memcpy(hostname, username + tlen + 1, strlen(username) - tlen - 1);
1344 if (strcmp(sock->hostname, sock->ip) &&
1345 strcmp(sock->hostname, hostname)) {
1346 silc_free(username);
1347 silc_free(hostname);
1349 silc_free(realname);
1350 silc_server_disconnect_remote(server, sock,
1351 "Server closed connection: "
1352 "Incomplete client information");
1356 pident = silc_pkcs_decode_identifier(client->data.public_key->identifier);
1358 phostname = strdup(pident->host);
1359 silc_pkcs_free_identifier(pident);
1362 if (!strcmp(sock->hostname, sock->ip) &&
1363 phostname && strcmp(phostname, hostname)) {
1364 silc_free(username);
1365 silc_free(hostname);
1367 silc_free(phostname);
1369 silc_free(realname);
1370 silc_server_disconnect_remote(server, sock,
1371 "Server closed connection: "
1372 "Incomplete client information");
1377 silc_free(phostname);
1379 /* The hostname is not present, add it. */
1381 /* XXX For now we cannot take the host name from the public key since
1382 they are not trusted or we cannot verify them as trusted. Just take
1383 what the resolved name or address is. */
1385 if (strcmp(sock->hostname, sock->ip)) {
1387 newusername = silc_calloc(strlen(username) +
1388 strlen(sock->hostname) + 2,
1389 sizeof(*newusername));
1390 strncat(newusername, username, strlen(username));
1391 strncat(newusername, "@", 1);
1392 strncat(newusername, sock->hostname, strlen(sock->hostname));
1393 silc_free(username);
1394 username = newusername;
1397 SilcPublicKeyIdentifier pident =
1398 silc_pkcs_decode_identifier(client->data.public_key->identifier);
1401 newusername = silc_calloc(strlen(username) +
1402 strlen(pident->host) + 2,
1403 sizeof(*newusername));
1404 strncat(newusername, username, strlen(username));
1405 strncat(newusername, "@", 1);
1406 strncat(newusername, pident->host, strlen(pident->host));
1407 silc_free(username);
1408 username = newusername;
1409 silc_pkcs_free_identifier(pident);
1415 /* Create Client ID */
1416 silc_id_create_client_id(server->id, server->rng, server->md5hash,
1417 username, &client_id);
1419 /* Update client entry */
1420 idata->registered = TRUE;
1421 client->nickname = nickname;
1422 client->username = username;
1423 client->userinfo = realname ? realname : strdup(" ");
1424 client->id = client_id;
1425 id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
1427 /* Add the client again to the ID cache */
1428 silc_idcache_add(server->local_list->clients, client->nickname,
1429 client_id, client, FALSE);
1431 /* Notify our router about new client on the SILC network */
1432 if (!server->standalone)
1433 silc_server_send_new_id(server, (SilcSocketConnection)
1434 server->router->connection,
1435 server->server_type == SILC_ROUTER ? TRUE : FALSE,
1436 client->id, SILC_ID_CLIENT, id_len);
1438 /* Send the new client ID to the client. */
1439 id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
1440 reply = silc_buffer_alloc(2 + 2 + id_len);
1441 silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
1442 silc_buffer_format(reply,
1443 SILC_STR_UI_SHORT(SILC_ID_CLIENT),
1444 SILC_STR_UI_SHORT(id_len),
1445 SILC_STR_UI_XNSTRING(id_string, id_len),
1447 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0,
1448 reply->data, reply->len, FALSE);
1449 silc_free(id_string);
1450 silc_buffer_free(reply);
1452 /* Send some nice info to the client */
1453 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1454 ("Welcome to the SILC Network %s",
1456 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1457 ("Your host is %s, running version %s",
1458 server->config->server_info->server_name,
1460 if (server->server_type == SILC_ROUTER) {
1461 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1462 ("There are %d clients on %d servers in SILC "
1463 "Network", server->stat.clients,
1464 server->stat.servers + 1));
1465 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1466 ("There are %d clients on %d server in our cell",
1467 server->stat.cell_clients,
1468 server->stat.cell_servers + 1));
1469 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1470 ("I have %d clients, %d channels, %d servers and "
1472 server->stat.my_clients,
1473 server->stat.my_channels,
1474 server->stat.my_servers,
1475 server->stat.my_routers));
1476 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1477 ("%d server operators and %d router operators "
1479 server->stat.my_server_ops,
1480 server->stat.my_router_ops));
1482 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1483 ("I have %d clients and %d channels formed",
1484 server->stat.my_clients,
1485 server->stat.my_channels));
1486 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1487 ("%d operators online",
1488 server->stat.my_server_ops));
1490 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1491 ("Your connection is secured with %s cipher, "
1492 "key length %d bits",
1493 idata->send_key->cipher->name,
1494 idata->send_key->cipher->key_len));
1495 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1496 ("Your current nickname is %s",
1500 silc_server_send_motd(server, sock);
1505 /* Create new server. This processes received New Server packet and
1506 saves the received Server ID. The server is our locally connected
1507 server thus we save all the information and save it to local list.
1508 This funtion can be used by both normal server and router server.
1509 If normal server uses this it means that its router has connected
1510 to the server. If router uses this it means that one of the cell's
1511 servers is connected to the router. */
1513 SilcServerEntry silc_server_new_server(SilcServer server,
1514 SilcSocketConnection sock,
1515 SilcPacketContext *packet)
1517 SilcBuffer buffer = packet->buffer;
1518 SilcServerEntry new_server;
1519 SilcServerID *server_id;
1520 SilcIDListData idata;
1521 unsigned char *server_name, *id_string;
1522 uint16 id_len, name_len;
1525 SILC_LOG_DEBUG(("Creating new server"));
1527 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
1528 sock->type != SILC_SOCKET_TYPE_ROUTER)
1531 /* Take server entry */
1532 new_server = (SilcServerEntry)sock->user_data;
1533 idata = (SilcIDListData)new_server;
1535 /* Remove the old cache entry */
1536 silc_idcache_del_by_context(server->local_list->servers, new_server);
1538 /* Parse the incoming packet */
1539 ret = silc_buffer_unformat(buffer,
1540 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
1541 SILC_STR_UI16_NSTRING_ALLOC(&server_name,
1546 silc_free(id_string);
1548 silc_free(server_name);
1552 if (id_len > buffer->len) {
1553 silc_free(id_string);
1554 silc_free(server_name);
1559 server_name[255] = '\0';
1562 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
1564 silc_free(id_string);
1565 silc_free(server_name);
1568 silc_free(id_string);
1570 /* Update server entry */
1571 idata->registered = TRUE;
1572 new_server->server_name = server_name;
1573 new_server->id = server_id;
1575 /* Add again the entry to the ID cache. */
1576 silc_idcache_add(server->local_list->servers, server_name, server_id,
1579 /* Distribute the information about new server in the SILC network
1580 to our router. If we are normal server we won't send anything
1581 since this connection must be our router connection. */
1582 if (server->server_type == SILC_ROUTER && !server->standalone &&
1583 server->router->connection != sock)
1584 silc_server_send_new_id(server, server->router->connection,
1585 TRUE, new_server->id, SILC_ID_SERVER,
1586 silc_id_get_len(server_id, SILC_ID_SERVER));
1588 if (server->server_type == SILC_ROUTER)
1589 server->stat.cell_servers++;
1594 /* Processes incoming New ID packet. New ID Payload is used to distribute
1595 information about newly registered clients and servers. */
1597 static void silc_server_new_id_real(SilcServer server,
1598 SilcSocketConnection sock,
1599 SilcPacketContext *packet,
1602 SilcBuffer buffer = packet->buffer;
1604 SilcServerEntry router;
1605 SilcSocketConnection router_sock;
1610 SILC_LOG_DEBUG(("Processing new ID"));
1612 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1613 server->server_type == SILC_SERVER ||
1614 packet->src_id_type != SILC_ID_SERVER)
1617 idp = silc_id_payload_parse(buffer);
1621 id_type = silc_id_payload_get_type(idp);
1623 /* Normal server cannot have other normal server connections */
1624 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
1627 id = silc_id_payload_get_id(idp);
1631 /* If the sender of this packet is server and we are router we need to
1632 broadcast this packet to other routers in the network. */
1633 if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
1634 sock->type == SILC_SOCKET_TYPE_SERVER &&
1635 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1636 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
1637 silc_server_packet_send(server, server->router->connection,
1639 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1640 buffer->data, buffer->len, FALSE);
1643 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1644 id_list = server->local_list;
1646 id_list = server->global_list;
1648 /* If the packet is coming from server then use the sender as the
1649 origin of the the packet. If it came from router then check the real
1650 sender of the packet and use that as the origin. */
1651 if (sock->type == SILC_SOCKET_TYPE_SERVER) {
1653 router = sock->user_data;
1655 void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1656 packet->src_id_type);
1657 router = silc_idlist_find_server_by_id(server->global_list,
1660 router = silc_idlist_find_server_by_id(server->local_list,
1662 silc_free(sender_id);
1669 case SILC_ID_CLIENT:
1671 SilcClientEntry entry;
1673 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
1674 silc_id_render(id, SILC_ID_CLIENT),
1675 sock->type == SILC_SOCKET_TYPE_SERVER ?
1676 "Server" : "Router", sock->hostname));
1678 /* As a router we keep information of all global information in our
1679 global list. Cell wide information however is kept in the local
1681 entry = silc_idlist_add_client(id_list, NULL, NULL, NULL,
1683 entry->nickname = NULL;
1684 entry->data.registered = TRUE;
1686 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1687 server->stat.cell_clients++;
1688 server->stat.clients++;
1692 case SILC_ID_SERVER:
1693 /* If the ID is mine, ignore it. */
1694 if (SILC_ID_SERVER_COMPARE(id, server->id)) {
1695 SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
1699 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
1700 silc_id_render(id, SILC_ID_SERVER),
1701 sock->type == SILC_SOCKET_TYPE_SERVER ?
1702 "Server" : "Router", sock->hostname));
1704 /* As a router we keep information of all global information in our global
1705 list. Cell wide information however is kept in the local list. */
1706 silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
1708 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1709 server->stat.cell_servers++;
1710 server->stat.servers++;
1713 case SILC_ID_CHANNEL:
1714 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
1722 silc_id_payload_free(idp);
1726 /* Processes incoming New ID packet. New ID Payload is used to distribute
1727 information about newly registered clients and servers. */
1729 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
1730 SilcPacketContext *packet)
1732 silc_server_new_id_real(server, sock, packet, TRUE);
1735 /* Receoved New Id List packet, list of New ID payloads inside one
1736 packet. Process the New ID payloads one by one. */
1738 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
1739 SilcPacketContext *packet)
1741 SilcPacketContext *new_id;
1745 SILC_LOG_DEBUG(("Processing New ID List"));
1747 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1748 packet->src_id_type != SILC_ID_SERVER)
1751 /* If the sender of this packet is server and we are router we need to
1752 broadcast this packet to other routers in the network. Broadcast
1753 this list packet instead of multiple New ID packets. */
1754 if (!server->standalone && server->server_type == SILC_ROUTER &&
1755 sock->type == SILC_SOCKET_TYPE_SERVER &&
1756 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1757 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
1758 silc_server_packet_send(server, server->router->connection,
1760 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1761 packet->buffer->data, packet->buffer->len, FALSE);
1764 /* Make copy of the original packet context, except for the actual
1765 data buffer, which we will here now fetch from the original buffer. */
1766 new_id = silc_packet_context_alloc();
1767 new_id->type = SILC_PACKET_NEW_ID;
1768 new_id->flags = packet->flags;
1769 new_id->src_id = packet->src_id;
1770 new_id->src_id_len = packet->src_id_len;
1771 new_id->src_id_type = packet->src_id_type;
1772 new_id->dst_id = packet->dst_id;
1773 new_id->dst_id_len = packet->dst_id_len;
1774 new_id->dst_id_type = packet->dst_id_type;
1776 idp = silc_buffer_alloc(256);
1777 new_id->buffer = idp;
1779 while (packet->buffer->len) {
1780 SILC_GET16_MSB(id_len, packet->buffer->data + 2);
1781 if ((id_len > packet->buffer->len) ||
1782 (id_len > idp->truelen))
1785 silc_buffer_pull_tail(idp, 4 + id_len);
1786 silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
1788 /* Process the New ID */
1789 silc_server_new_id_real(server, sock, new_id, FALSE);
1791 silc_buffer_push_tail(idp, 4 + id_len);
1792 silc_buffer_pull(packet->buffer, 4 + id_len);
1795 silc_buffer_free(idp);
1799 /* Received New Channel packet. Information about new channels in the
1800 network are distributed using this packet. Save the information about
1801 the new channel. This usually comes from router but also normal server
1802 can send this to notify channels it has when it connects to us. */
1804 void silc_server_new_channel(SilcServer server,
1805 SilcSocketConnection sock,
1806 SilcPacketContext *packet)
1808 SilcChannelPayload payload;
1809 SilcChannelID *channel_id;
1816 SILC_LOG_DEBUG(("Processing New Channel"));
1818 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1819 packet->src_id_type != SILC_ID_SERVER ||
1820 server->server_type == SILC_SERVER)
1823 /* Parse the channel payload */
1824 payload = silc_channel_payload_parse(packet->buffer);
1828 /* Get the channel ID */
1829 channel_id = silc_channel_get_id_parse(payload);
1831 silc_channel_payload_free(payload);
1835 channel_name = silc_channel_get_name(payload, &name_len);
1837 channel_name[255] = '\0';
1839 id = silc_channel_get_id(payload, &id_len);
1841 if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
1842 /* Add the server to global list as it is coming from router. It
1843 cannot be our own channel as it is coming from router. */
1845 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
1846 silc_id_render(channel_id, SILC_ID_CHANNEL),
1849 silc_idlist_add_channel(server->global_list, strdup(channel_name),
1850 0, channel_id, server->router->connection,
1853 server->stat.channels++;
1855 /* The channel is coming from our server, thus it is in our cell
1856 we will add it to our local list. */
1857 SilcChannelEntry channel;
1860 SILC_LOG_DEBUG(("New channel id(%s) from [Server] %s",
1861 silc_id_render(channel_id, SILC_ID_CHANNEL),
1864 /* Check that we don't already have this channel */
1865 channel = silc_idlist_find_channel_by_name(server->local_list,
1866 channel_name, NULL);
1868 channel = silc_idlist_find_channel_by_name(server->global_list,
1869 channel_name, NULL);
1871 /* If the channel does not exist, then create it. We create the channel
1872 with the channel ID provided by the server. This creates a new
1873 key to the channel as well that we will send to the server. */
1875 channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
1879 silc_channel_payload_free(payload);
1880 silc_free(channel_id);
1884 /* Get the mode and set it to the channel */
1885 channel->mode = silc_channel_get_mode(payload);
1887 /* Send the new channel key to the server */
1888 chk = silc_channel_key_payload_encode(id_len, id,
1889 strlen(channel->channel_key->
1891 channel->channel_key->cipher->name,
1892 channel->key_len / 8,
1894 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
1895 chk->data, chk->len, FALSE);
1896 silc_buffer_free(chk);
1899 /* The channel exist by that name, check whether the ID's match.
1900 If they don't then we'll force the server to use the ID we have.
1901 We also create a new key for the channel. */
1902 SilcBuffer users = NULL, users_modes = NULL;
1905 channel_id = silc_id_dup(channel_id, SILC_ID_CHANNEL);
1907 if (!SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
1908 /* They don't match, send CHANNEL_CHANGE notify to the server to
1909 force the ID change. */
1910 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
1911 silc_server_send_notify_channel_change(server, sock, FALSE,
1912 channel_id, channel->id);
1915 /* If the mode is different from what we have then enforce the
1917 mode = silc_channel_get_mode(payload);
1918 if (channel->mode != mode) {
1919 SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
1920 silc_server_send_notify_cmode(server, sock, FALSE, channel,
1921 channel->mode, server->id,
1923 channel->cipher, channel->hmac_name);
1926 /* Create new key for the channel and send it to the server and
1927 everybody else possibly on the channel. */
1929 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
1930 silc_server_create_channel_key(server, channel, 0);
1932 /* Send to the channel */
1933 silc_server_send_channel_key(server, sock, channel, FALSE);
1934 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
1935 id_len = SILC_ID_CHANNEL_LEN;
1937 /* Send to the server */
1938 chk = silc_channel_key_payload_encode(id_len, id,
1939 strlen(channel->channel_key->
1941 channel->channel_key->
1943 channel->key_len / 8,
1945 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
1946 chk->data, chk->len, FALSE);
1947 silc_buffer_free(chk);
1951 silc_free(channel_id);
1953 /* Since the channel is coming from server and we also know about it
1954 then send the JOIN notify to the server so that it see's our
1955 users on the channel "joining" the channel. */
1956 silc_server_announce_get_channel_users(server, channel, &users,
1959 silc_buffer_push(users, users->data - users->head);
1960 silc_server_packet_send(server, sock,
1961 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1962 users->data, users->len, FALSE);
1963 silc_buffer_free(users);
1966 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
1967 silc_server_packet_send(server, sock,
1968 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1969 users_modes->data, users_modes->len, FALSE);
1970 silc_buffer_free(users_modes);
1975 silc_channel_payload_free(payload);
1978 /* Received New Channel List packet, list of New Channel List payloads inside
1979 one packet. Process the New Channel payloads one by one. */
1981 void silc_server_new_channel_list(SilcServer server,
1982 SilcSocketConnection sock,
1983 SilcPacketContext *packet)
1985 SilcPacketContext *new;
1989 SILC_LOG_DEBUG(("Processing New Channel List"));
1991 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1992 packet->src_id_type != SILC_ID_SERVER ||
1993 server->server_type == SILC_SERVER)
1996 /* If the sender of this packet is server and we are router we need to
1997 broadcast this packet to other routers in the network. Broadcast
1998 this list packet instead of multiple New Channel packets. */
1999 if (!server->standalone && server->server_type == SILC_ROUTER &&
2000 sock->type == SILC_SOCKET_TYPE_SERVER &&
2001 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2002 SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
2003 silc_server_packet_send(server, server->router->connection,
2005 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2006 packet->buffer->data, packet->buffer->len, FALSE);
2009 /* Make copy of the original packet context, except for the actual
2010 data buffer, which we will here now fetch from the original buffer. */
2011 new = silc_packet_context_alloc();
2012 new->type = SILC_PACKET_NEW_CHANNEL;
2013 new->flags = packet->flags;
2014 new->src_id = packet->src_id;
2015 new->src_id_len = packet->src_id_len;
2016 new->src_id_type = packet->src_id_type;
2017 new->dst_id = packet->dst_id;
2018 new->dst_id_len = packet->dst_id_len;
2019 new->dst_id_type = packet->dst_id_type;
2021 buffer = silc_buffer_alloc(512);
2022 new->buffer = buffer;
2024 while (packet->buffer->len) {
2025 SILC_GET16_MSB(len1, packet->buffer->data);
2026 if ((len1 > packet->buffer->len) ||
2027 (len1 > buffer->truelen))
2030 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
2031 if ((len2 > packet->buffer->len) ||
2032 (len2 > buffer->truelen))
2035 silc_buffer_pull_tail(buffer, 8 + len1 + len2);
2036 silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
2038 /* Process the New Channel */
2039 silc_server_new_channel(server, sock, new);
2041 silc_buffer_push_tail(buffer, 8 + len1 + len2);
2042 silc_buffer_pull(packet->buffer, 8 + len1 + len2);
2045 silc_buffer_free(buffer);
2049 /* Received key agreement packet. This packet is never for us. It is to
2050 the client in the packet's destination ID. Sending of this sort of packet
2051 equals sending private message, ie. it is sent point to point from
2052 one client to another. */
2054 void silc_server_key_agreement(SilcServer server,
2055 SilcSocketConnection sock,
2056 SilcPacketContext *packet)
2058 SilcSocketConnection dst_sock;
2059 SilcIDListData idata;
2061 SILC_LOG_DEBUG(("Start"));
2063 if (packet->src_id_type != SILC_ID_CLIENT ||
2064 packet->dst_id_type != SILC_ID_CLIENT)
2067 if (!packet->dst_id)
2070 /* Get the route to the client */
2071 dst_sock = silc_server_get_client_route(server, packet->dst_id,
2072 packet->dst_id_len, NULL, &idata);
2076 /* Relay the packet */
2077 silc_server_relay_packet(server, dst_sock, idata->send_key,
2078 idata->hmac_send, packet, FALSE);
2081 /* Received connection auth request packet that is used during connection
2082 phase to resolve the mandatory authentication method. This packet can
2083 actually be received at anytime but usually it is used only during
2084 the connection authentication phase. Now, protocol says that this packet
2085 can come from client or server, however, we support only this coming
2086 from client and expect that server's always knows what authentication
2089 void silc_server_connection_auth_request(SilcServer server,
2090 SilcSocketConnection sock,
2091 SilcPacketContext *packet)
2093 SilcServerConfigSectionClientConnection *client = NULL;
2096 SilcAuthMethod auth_meth;
2098 SILC_LOG_DEBUG(("Start"));
2100 if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT)
2103 /* Parse the payload */
2104 ret = silc_buffer_unformat(packet->buffer,
2105 SILC_STR_UI_SHORT(&conn_type),
2106 SILC_STR_UI_SHORT(NULL),
2111 if (conn_type != SILC_SOCKET_TYPE_CLIENT)
2114 /* Get the authentication method for the client */
2115 auth_meth = SILC_AUTH_NONE;
2116 client = silc_server_config_find_client_conn(server->config,
2120 client = silc_server_config_find_client_conn(server->config,
2124 auth_meth = client->auth_meth;
2126 /* Send it back to the client */
2127 silc_server_send_connection_auth_request(server, sock,
2132 /* Received REKEY packet. The sender of the packet wants to regenerate
2133 its session keys. This starts the REKEY protocol. */
2135 void silc_server_rekey(SilcServer server,
2136 SilcSocketConnection sock,
2137 SilcPacketContext *packet)
2139 SilcProtocol protocol;
2140 SilcServerRekeyInternalContext *proto_ctx;
2141 SilcIDListData idata = (SilcIDListData)sock->user_data;
2143 SILC_LOG_DEBUG(("Start"));
2145 /* Allocate internal protocol context. This is sent as context
2147 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
2148 proto_ctx->server = (void *)server;
2149 proto_ctx->sock = sock;
2150 proto_ctx->responder = TRUE;
2151 proto_ctx->pfs = idata->rekey->pfs;
2153 /* Perform rekey protocol. Will call the final callback after the
2154 protocol is over. */
2155 silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
2156 &protocol, proto_ctx, silc_server_rekey_final);
2157 sock->protocol = protocol;
2159 if (proto_ctx->pfs == FALSE)
2160 /* Run the protocol */
2161 silc_protocol_execute(protocol, server->timeout_queue, 0, 0);