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,
144 client_id, server->server_type,
147 client = silc_idlist_find_client_by_id(server->local_list,
148 client_id, server->server_type,
151 /* If router did not find the client the it is bogus */
152 if (server->server_type == SILC_ROUTER)
156 silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
157 silc_id_dup(client_id, SILC_ID_CLIENT),
158 sock->user_data, NULL);
160 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
161 silc_free(client_id);
165 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
169 /* Do not process the notify if the client is not registered */
170 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
173 /* Do not add client to channel if it is there already */
174 if (silc_server_client_on_channel(client, channel))
177 if (server->server_type == SILC_SERVER &&
178 sock->type == SILC_SOCKET_TYPE_ROUTER)
179 /* The channel is global now */
180 channel->global_users = TRUE;
182 /* JOIN the global client to the channel (local clients (if router
183 created the channel) is joined in the pending JOIN command). */
184 chl = silc_calloc(1, sizeof(*chl));
185 chl->client = client;
186 chl->channel = channel;
188 /* If this is the first one on the channel then it is the founder off
190 if (!silc_hash_table_count(channel->user_list))
191 chl->mode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
193 silc_hash_table_add(channel->user_list, client, chl);
194 silc_hash_table_add(client->channels, channel, chl);
195 silc_free(client_id);
199 case SILC_NOTIFY_TYPE_LEAVE:
201 * Distribute the notify to local clients on the channel
203 SILC_LOG_DEBUG(("LEAVE notify"));
205 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
206 packet->dst_id_type);
210 /* Get channel entry */
211 channel = silc_idlist_find_channel_by_id(server->global_list,
214 channel = silc_idlist_find_channel_by_id(server->local_list,
217 silc_free(channel_id);
223 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
225 silc_free(channel_id);
228 client_id = silc_id_payload_parse_id(tmp, tmp_len);
230 silc_free(channel_id);
234 /* Send to channel */
235 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
236 FALSE, packet->buffer->data,
237 packet->buffer->len, FALSE);
239 /* Get client entry */
240 client = silc_idlist_find_client_by_id(server->global_list,
241 client_id, TRUE, NULL);
243 client = silc_idlist_find_client_by_id(server->local_list,
244 client_id, TRUE, NULL);
246 silc_free(client_id);
247 silc_free(channel_id);
251 silc_free(client_id);
253 /* Remove the user from channel */
254 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
257 case SILC_NOTIFY_TYPE_SIGNOFF:
259 * Distribute the notify to local clients on the channel
261 SILC_LOG_DEBUG(("SIGNOFF notify"));
264 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
267 client_id = silc_id_payload_parse_id(tmp, tmp_len);
271 /* Get client entry */
272 client = silc_idlist_find_client_by_id(server->global_list,
273 client_id, TRUE, &cache);
275 client = silc_idlist_find_client_by_id(server->local_list,
276 client_id, TRUE, &cache);
278 silc_free(client_id);
282 silc_free(client_id);
284 /* Get signoff message */
285 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
289 /* Remove the client from all channels. */
290 silc_server_remove_from_channels(server, NULL, client, TRUE, tmp, FALSE);
292 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
293 cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
294 server->stat.clients--;
295 if (server->server_type == SILC_ROUTER)
296 server->stat.cell_clients--;
299 case SILC_NOTIFY_TYPE_TOPIC_SET:
301 * Distribute the notify to local clients on the channel
304 SILC_LOG_DEBUG(("TOPIC SET notify"));
306 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
307 packet->dst_id_type);
311 /* Get channel entry */
312 channel = silc_idlist_find_channel_by_id(server->global_list,
315 channel = silc_idlist_find_channel_by_id(server->local_list,
318 silc_free(channel_id);
324 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
326 silc_free(channel_id);
331 silc_free(channel->topic);
332 channel->topic = silc_calloc(tmp_len + 1, sizeof(*channel->topic));
333 memcpy(channel->topic, tmp, tmp_len);
335 /* Send the same notify to the channel */
336 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
337 FALSE, packet->buffer->data,
338 packet->buffer->len, FALSE);
339 silc_free(channel_id);
342 case SILC_NOTIFY_TYPE_NICK_CHANGE:
345 * Distribute the notify to local clients on the channel
347 unsigned char *id, *id2;
349 SILC_LOG_DEBUG(("NICK CHANGE notify"));
351 /* Get old client ID */
352 id = silc_argument_get_arg_type(args, 1, &tmp_len);
355 client_id = silc_id_payload_parse_id(id, tmp_len);
359 /* Get new client ID */
360 id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
363 client_id2 = silc_id_payload_parse_id(id2, tmp_len);
367 SILC_LOG_DEBUG(("Old Client ID id(%s)",
368 silc_id_render(client_id, SILC_ID_CLIENT)));
369 SILC_LOG_DEBUG(("New Client ID id(%s)",
370 silc_id_render(client_id2, SILC_ID_CLIENT)));
372 /* Replace the Client ID */
373 client = silc_idlist_replace_client_id(server->global_list, client_id,
376 client = silc_idlist_replace_client_id(server->local_list, client_id,
380 /* The nickname is not valid anymore, set it NULL. This causes that
381 the nickname will be queried if someone wants to know it. */
382 if (client->nickname)
383 silc_free(client->nickname);
384 client->nickname = NULL;
386 /* Send the NICK_CHANGE notify type to local clients on the channels
387 this client is joined to. */
388 silc_server_send_notify_on_channels(server, NULL, client,
389 SILC_NOTIFY_TYPE_NICK_CHANGE, 2,
394 silc_free(client_id);
396 silc_free(client_id2);
400 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
402 * Distribute the notify to local clients on the channel
405 SILC_LOG_DEBUG(("CMODE CHANGE notify"));
407 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
408 packet->dst_id_type);
412 /* Get channel entry */
413 channel = silc_idlist_find_channel_by_id(server->global_list,
416 channel = silc_idlist_find_channel_by_id(server->local_list,
419 silc_free(channel_id);
424 /* Send the same notify to the channel */
425 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
426 FALSE, packet->buffer->data,
427 packet->buffer->len, FALSE);
430 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
432 silc_free(channel_id);
436 SILC_GET32_MSB(mode, tmp);
438 /* If the channel had private keys set and the mode was removed then
439 we must re-generate and re-distribute a new channel key */
440 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY &&
441 !(mode & SILC_CHANNEL_MODE_PRIVKEY)) {
442 /* Re-generate channel key */
443 if (!silc_server_create_channel_key(server, channel, 0))
446 /* Send the channel key. This sends it to our local clients and if
447 we are normal server to our router as well. */
448 silc_server_send_channel_key(server, NULL, channel,
449 server->server_type == SILC_ROUTER ?
450 FALSE : !server->standalone);
454 channel->mode = mode;
455 silc_free(channel_id);
458 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
460 unsigned char hash[32];
463 silc_hmac_free(channel->hmac);
464 if (!silc_hmac_alloc(tmp, NULL, &channel->hmac))
467 /* Set the HMAC key out of current channel key. The client must do
469 silc_hash_make(channel->hmac->hash, channel->key, channel->key_len / 8,
471 silc_hmac_set_key(channel->hmac, hash,
472 silc_hash_len(channel->hmac->hash));
473 memset(hash, 0, sizeof(hash));
478 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
481 * Distribute the notify to local clients on the channel
483 SilcChannelClientEntry chl2 = NULL;
484 bool notify_sent = FALSE;
486 SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
488 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
489 packet->dst_id_type);
493 /* Get channel entry */
494 channel = silc_idlist_find_channel_by_id(server->global_list,
497 channel = silc_idlist_find_channel_by_id(server->local_list,
500 silc_free(channel_id);
506 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
508 silc_free(channel_id);
512 SILC_GET32_MSB(mode, tmp);
514 /* Get target client */
515 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
518 client_id = silc_id_payload_parse_id(tmp, tmp_len);
522 /* Get client entry */
523 client = silc_idlist_find_client_by_id(server->global_list,
524 client_id, TRUE, NULL);
526 client = silc_idlist_find_client_by_id(server->local_list,
527 client_id, TRUE, NULL);
529 silc_free(client_id);
533 silc_free(client_id);
535 /* Get entry to the channel user list */
536 silc_hash_table_list(channel->user_list, &htl);
537 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
538 /* If the mode is channel founder and we already find a client
539 to have that mode on the channel we will enforce the sender
540 to change the channel founder mode away. There can be only one
541 channel founder on the channel. */
542 if (server->server_type == SILC_ROUTER &&
543 mode & SILC_CHANNEL_UMODE_CHANFO &&
544 chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
546 unsigned char cumode[4];
548 mode &= ~SILC_CHANNEL_UMODE_CHANFO;
549 silc_server_send_notify_cumode(server, sock, FALSE, channel, mode,
550 client->id, SILC_ID_CLIENT,
553 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
554 SILC_PUT32_MSB(mode, cumode);
555 silc_server_send_notify_to_channel(server, sock, channel, FALSE,
556 SILC_NOTIFY_TYPE_CUMODE_CHANGE,
557 3, idp->data, idp->len,
559 idp->data, idp->len);
560 silc_buffer_free(idp);
563 /* Force the mode change if we alredy set the mode */
566 silc_free(channel_id);
571 if (chl->client == client) {
572 /* Change the mode */
574 if (!(mode & SILC_CHANNEL_UMODE_CHANFO))
581 /* Send the same notify to the channel */
583 silc_server_packet_send_to_channel(server, sock, channel,
585 FALSE, packet->buffer->data,
586 packet->buffer->len, FALSE);
588 silc_free(channel_id);
592 case SILC_NOTIFY_TYPE_INVITE:
594 if (packet->dst_id_type == SILC_ID_CLIENT)
597 SILC_LOG_DEBUG(("INVITE notify"));
600 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
603 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
607 /* Get channel entry */
608 channel = silc_idlist_find_channel_by_id(server->global_list,
611 channel = silc_idlist_find_channel_by_id(server->local_list,
614 silc_free(channel_id);
618 silc_free(channel_id);
620 /* Get the added invite */
621 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
623 if (!channel->invite_list)
624 channel->invite_list = silc_calloc(tmp_len + 2,
625 sizeof(*channel->invite_list));
627 channel->invite_list = silc_realloc(channel->invite_list,
628 sizeof(*channel->invite_list) *
630 strlen(channel->invite_list) +
632 if (tmp[tmp_len - 1] == ',')
633 tmp[tmp_len - 1] = '\0';
635 strncat(channel->invite_list, tmp, tmp_len);
636 strncat(channel->invite_list, ",", 1);
639 /* Get the deleted invite */
640 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
641 if (tmp && channel->invite_list) {
642 char *start, *end, *n;
644 if (!strncmp(channel->invite_list, tmp,
645 strlen(channel->invite_list) - 1)) {
646 silc_free(channel->invite_list);
647 channel->invite_list = NULL;
649 start = strstr(channel->invite_list, tmp);
650 if (start && strlen(start) >= tmp_len) {
651 end = start + tmp_len;
652 n = silc_calloc(strlen(channel->invite_list) - tmp_len, sizeof(*n));
653 strncat(n, channel->invite_list, start - channel->invite_list);
654 strncat(n, end + 1, ((channel->invite_list +
655 strlen(channel->invite_list)) - end) - 1);
656 silc_free(channel->invite_list);
657 channel->invite_list = n;
664 case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
666 * Distribute to the local clients on the channel and change the
670 SILC_LOG_DEBUG(("CHANNEL CHANGE"));
672 if (sock->type != SILC_SOCKET_TYPE_ROUTER)
675 /* Get the old Channel ID */
676 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
679 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
683 /* Get the channel entry */
684 channel = silc_idlist_find_channel_by_id(server->global_list,
687 channel = silc_idlist_find_channel_by_id(server->local_list,
690 silc_free(channel_id);
695 /* Send the notify to the channel */
696 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
697 FALSE, packet->buffer->data,
698 packet->buffer->len, FALSE);
700 /* Get the new Channel ID */
701 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
704 channel_id2 = silc_id_payload_parse_id(tmp, tmp_len);
708 SILC_LOG_DEBUG(("Old Channel ID id(%s)",
709 silc_id_render(channel_id, SILC_ID_CHANNEL)));
710 SILC_LOG_DEBUG(("New Channel ID id(%s)",
711 silc_id_render(channel_id2, SILC_ID_CHANNEL)));
713 /* Replace the Channel ID */
714 if (!silc_idlist_replace_channel_id(server->global_list, channel_id,
716 if (!silc_idlist_replace_channel_id(server->local_list, channel_id,
718 silc_free(channel_id2);
723 SilcBuffer users = NULL, users_modes = NULL;
725 /* Re-announce our clients on the channel as the ID has changed now */
726 silc_server_announce_get_channel_users(server, channel, &users,
729 silc_buffer_push(users, users->data - users->head);
730 silc_server_packet_send(server, sock,
731 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
732 users->data, users->len, FALSE);
733 silc_buffer_free(users);
736 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
737 silc_server_packet_send_dest(server, sock,
738 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
739 channel->id, SILC_ID_CHANNEL,
741 users_modes->len, FALSE);
742 silc_buffer_free(users_modes);
746 silc_free(channel_id);
750 case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
752 * Remove the server entry and all clients that this server owns.
755 SILC_LOG_DEBUG(("SERVER SIGNOFF notify"));
758 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
761 server_id = silc_id_payload_parse_id(tmp, tmp_len);
765 /* Get server entry */
766 server_entry = silc_idlist_find_server_by_id(server->global_list,
767 server_id, TRUE, NULL);
769 server_entry = silc_idlist_find_server_by_id(server->local_list,
770 server_id, TRUE, NULL);
772 silc_free(server_id);
776 silc_free(server_id);
778 /* Free all client entries that this server owns as they will
779 become invalid now as well. */
780 silc_server_remove_clients_by_server(server, server_entry, TRUE);
782 /* Remove the server entry */
783 if (!silc_idlist_del_server(server->global_list, server_entry))
784 silc_idlist_del_server(server->local_list, server_entry);
786 /* XXX update statistics */
790 case SILC_NOTIFY_TYPE_KICKED:
792 * Distribute the notify to local clients on the channel
795 SILC_LOG_DEBUG(("KICKED notify"));
797 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
798 packet->dst_id_type);
802 /* Get channel entry */
803 channel = silc_idlist_find_channel_by_id(server->global_list,
806 channel = silc_idlist_find_channel_by_id(server->local_list,
809 silc_free(channel_id);
813 silc_free(channel_id);
816 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
819 client_id = silc_id_payload_parse_id(tmp, tmp_len);
823 /* Send to channel */
824 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
825 FALSE, packet->buffer->data,
826 packet->buffer->len, FALSE);
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,
830 client_id, TRUE, NULL);
832 client = silc_idlist_find_client_by_id(server->local_list,
833 client_id, TRUE, NULL);
835 silc_free(client_id);
840 /* Remove the client from channel */
841 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
845 case SILC_NOTIFY_TYPE_KILLED:
848 * Distribute the notify to local clients on channels
853 SILC_LOG_DEBUG(("KILLED notify"));
856 id = silc_argument_get_arg_type(args, 1, &id_len);
859 client_id = silc_id_payload_parse_id(id, id_len);
863 /* If the the client is not in local list we check global list */
864 client = silc_idlist_find_client_by_id(server->global_list,
865 client_id, TRUE, NULL);
867 client = silc_idlist_find_client_by_id(server->local_list,
868 client_id, TRUE, NULL);
870 silc_free(client_id);
874 silc_free(client_id);
876 /* If the client is one of ours, then close the connection to the
877 client now. This removes the client from all channels as well. */
878 if (packet->dst_id_type == SILC_ID_CLIENT && client->connection) {
879 sock = client->connection;
880 silc_server_free_client_data(server, NULL, client, FALSE, NULL);
881 silc_server_close_connection(server, sock);
886 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
890 /* Send the notify to local clients on the channels except to the
891 client who is killed. */
892 silc_server_send_notify_on_channels(server, client, client,
893 SILC_NOTIFY_TYPE_KILLED,
898 /* Remove the client from all channels */
899 silc_server_remove_from_channels(server, NULL, client, FALSE, NULL,
905 case SILC_NOTIFY_TYPE_UMODE_CHANGE:
907 * Save the mode of the client.
910 SILC_LOG_DEBUG(("UMODE_CHANGE notify"));
913 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
916 client_id = silc_id_payload_parse_id(tmp, tmp_len);
920 /* Get client entry */
921 client = silc_idlist_find_client_by_id(server->global_list,
922 client_id, TRUE, NULL);
924 client = silc_idlist_find_client_by_id(server->local_list,
925 client_id, TRUE, NULL);
927 silc_free(client_id);
931 silc_free(client_id);
934 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
939 SILC_GET32_MSB(client->mode, tmp);
943 case SILC_NOTIFY_TYPE_BAN:
948 SILC_LOG_DEBUG(("BAN notify"));
951 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
954 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
958 /* Get channel entry */
959 channel = silc_idlist_find_channel_by_id(server->global_list,
962 channel = silc_idlist_find_channel_by_id(server->local_list,
965 silc_free(channel_id);
969 silc_free(channel_id);
971 /* Get the new ban and add it to the ban list */
972 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
974 if (!channel->ban_list)
975 channel->ban_list = silc_calloc(tmp_len + 2,
976 sizeof(*channel->ban_list));
978 channel->ban_list = silc_realloc(channel->ban_list,
979 sizeof(*channel->ban_list) *
981 strlen(channel->ban_list) + 2));
982 strncat(channel->ban_list, tmp, tmp_len);
983 strncat(channel->ban_list, ",", 1);
986 /* Get the ban to be removed and remove it from the list */
987 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
988 if (tmp && channel->ban_list) {
989 char *start, *end, *n;
991 if (!strcmp(channel->ban_list, tmp)) {
992 silc_free(channel->ban_list);
993 channel->ban_list = NULL;
995 start = strstr(channel->ban_list, tmp);
996 if (start && strlen(start) >= tmp_len) {
997 end = start + tmp_len;
998 n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
999 strncat(n, channel->ban_list, start - channel->ban_list);
1000 strncat(n, end + 1, ((channel->ban_list +
1001 strlen(channel->ban_list)) - end) - 1);
1002 silc_free(channel->ban_list);
1003 channel->ban_list = n;
1010 /* Ignore rest of the notify types for now */
1011 case SILC_NOTIFY_TYPE_NONE:
1012 case SILC_NOTIFY_TYPE_MOTD:
1019 silc_notify_payload_free(payload);
1022 void silc_server_notify_list(SilcServer server,
1023 SilcSocketConnection sock,
1024 SilcPacketContext *packet)
1026 SilcPacketContext *new;
1030 SILC_LOG_DEBUG(("Processing Notify List"));
1032 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1033 packet->src_id_type != SILC_ID_SERVER)
1036 /* Make copy of the original packet context, except for the actual
1037 data buffer, which we will here now fetch from the original buffer. */
1038 new = silc_packet_context_alloc();
1039 new->type = SILC_PACKET_NOTIFY;
1040 new->flags = packet->flags;
1041 new->src_id = packet->src_id;
1042 new->src_id_len = packet->src_id_len;
1043 new->src_id_type = packet->src_id_type;
1044 new->dst_id = packet->dst_id;
1045 new->dst_id_len = packet->dst_id_len;
1046 new->dst_id_type = packet->dst_id_type;
1048 buffer = silc_buffer_alloc(1024);
1049 new->buffer = buffer;
1051 while (packet->buffer->len) {
1052 SILC_GET16_MSB(len, packet->buffer->data + 2);
1053 if (len > packet->buffer->len)
1056 if (len > buffer->truelen) {
1057 silc_buffer_free(buffer);
1058 buffer = silc_buffer_alloc(1024 + len);
1061 silc_buffer_pull_tail(buffer, len);
1062 silc_buffer_put(buffer, packet->buffer->data, len);
1064 /* Process the Notify */
1065 silc_server_notify(server, sock, new);
1067 silc_buffer_push_tail(buffer, len);
1068 silc_buffer_pull(packet->buffer, len);
1071 silc_buffer_free(buffer);
1075 /* Received private message. This resolves the destination of the message
1076 and sends the packet. This is used by both server and router. If the
1077 destination is our locally connected client this sends the packet to
1078 the client. This may also send the message for further routing if
1079 the destination is not in our server (or router). */
1081 void silc_server_private_message(SilcServer server,
1082 SilcSocketConnection sock,
1083 SilcPacketContext *packet)
1085 SilcSocketConnection dst_sock;
1086 SilcIDListData idata;
1088 SILC_LOG_DEBUG(("Start"));
1090 if (packet->src_id_type != SILC_ID_CLIENT ||
1091 packet->dst_id_type != SILC_ID_CLIENT)
1094 if (!packet->dst_id)
1097 /* Get the route to the client */
1098 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1099 packet->dst_id_len, NULL, &idata);
1103 /* Send the private message */
1104 silc_server_send_private_message(server, dst_sock, idata->send_key,
1105 idata->hmac_send, packet);
1108 /* Received private message key packet.. This packet is never for us. It is to
1109 the client in the packet's destination ID. Sending of this sort of packet
1110 equals sending private message, ie. it is sent point to point from
1111 one client to another. */
1113 void silc_server_private_message_key(SilcServer server,
1114 SilcSocketConnection sock,
1115 SilcPacketContext *packet)
1117 SilcSocketConnection dst_sock;
1118 SilcIDListData idata;
1120 SILC_LOG_DEBUG(("Start"));
1122 if (packet->src_id_type != SILC_ID_CLIENT ||
1123 packet->dst_id_type != SILC_ID_CLIENT)
1126 if (!packet->dst_id)
1129 /* Get the route to the client */
1130 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1131 packet->dst_id_len, NULL, &idata);
1135 /* Relay the packet */
1136 silc_server_relay_packet(server, dst_sock, idata->send_key,
1137 idata->hmac_send, packet, FALSE);
1140 /* Processes incoming command reply packet. The command reply packet may
1141 be destined to one of our clients or it may directly for us. We will
1142 call the command reply routine after processing the packet. */
1144 void silc_server_command_reply(SilcServer server,
1145 SilcSocketConnection sock,
1146 SilcPacketContext *packet)
1148 SilcBuffer buffer = packet->buffer;
1149 SilcClientEntry client = NULL;
1150 SilcSocketConnection dst_sock;
1151 SilcIDListData idata;
1152 SilcClientID *id = NULL;
1154 SILC_LOG_DEBUG(("Start"));
1156 /* Source must be server or router */
1157 if (packet->src_id_type != SILC_ID_SERVER &&
1158 sock->type != SILC_SOCKET_TYPE_ROUTER)
1161 if (packet->dst_id_type == SILC_ID_CHANNEL)
1164 if (packet->dst_id_type == SILC_ID_CLIENT) {
1165 /* Destination must be one of ours */
1166 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
1169 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
1171 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
1177 if (packet->dst_id_type == SILC_ID_SERVER) {
1178 /* For now this must be for us */
1179 if (memcmp(packet->dst_id, server->id_string, packet->dst_id_len)) {
1180 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
1185 /* Execute command reply locally for the command */
1186 silc_server_command_reply_process(server, sock, buffer);
1188 if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
1189 /* Relay the packet to the client */
1191 dst_sock = (SilcSocketConnection)client->connection;
1192 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
1193 + packet->dst_id_len + packet->padlen);
1195 silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
1196 silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
1198 idata = (SilcIDListData)client;
1200 /* Encrypt packet */
1201 silc_packet_encrypt(idata->send_key, idata->hmac_send, dst_sock->outbuf,
1204 /* Send the packet */
1205 silc_server_packet_send_real(server, dst_sock, TRUE);
1211 /* Process received channel message. The message can be originated from
1212 client or server. */
1214 void silc_server_channel_message(SilcServer server,
1215 SilcSocketConnection sock,
1216 SilcPacketContext *packet)
1218 SilcChannelEntry channel = NULL;
1219 SilcChannelID *id = NULL;
1220 void *sender = NULL;
1221 void *sender_entry = NULL;
1223 SILC_LOG_DEBUG(("Processing channel message"));
1226 if (packet->dst_id_type != SILC_ID_CHANNEL) {
1227 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1231 /* Find channel entry */
1232 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
1235 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
1237 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
1239 SILC_LOG_DEBUG(("Could not find channel"));
1244 /* See that this client is on the channel. If the original sender is
1245 not client (as it can be server as well) we don't do the check. */
1246 sender = silc_id_str2id(packet->src_id, packet->src_id_len,
1247 packet->src_id_type);
1250 if (packet->src_id_type == SILC_ID_CLIENT) {
1251 sender_entry = silc_idlist_find_client_by_id(server->local_list,
1252 sender, TRUE, NULL);
1254 sender_entry = silc_idlist_find_client_by_id(server->global_list,
1255 sender, TRUE, NULL);
1256 if (!sender_entry || !silc_server_client_on_channel(sender_entry,
1258 SILC_LOG_DEBUG(("Client not on channel"));
1263 /* Distribute the packet to our local clients. This will send the
1264 packet for further routing as well, if needed. */
1265 silc_server_packet_relay_to_channel(server, sock, channel, sender,
1266 packet->src_id_type, sender_entry,
1267 packet->buffer->data,
1268 packet->buffer->len, FALSE);
1277 /* Received channel key packet. We distribute the key to all of our locally
1278 connected clients on the channel. */
1280 void silc_server_channel_key(SilcServer server,
1281 SilcSocketConnection sock,
1282 SilcPacketContext *packet)
1284 SilcBuffer buffer = packet->buffer;
1285 SilcChannelEntry channel;
1287 if (packet->src_id_type != SILC_ID_SERVER ||
1288 (server->server_type == SILC_ROUTER &&
1289 sock->type == SILC_SOCKET_TYPE_ROUTER))
1292 /* Save the channel key */
1293 channel = silc_server_save_channel_key(server, buffer, NULL);
1297 /* Distribute the key to everybody who is on the channel. If we are router
1298 we will also send it to locally connected servers. */
1299 silc_server_send_channel_key(server, sock, channel, FALSE);
1302 /* Received New Client packet and processes it. Creates Client ID for the
1303 client. Client becomes registered after calling this functions. */
1305 SilcClientEntry silc_server_new_client(SilcServer server,
1306 SilcSocketConnection sock,
1307 SilcPacketContext *packet)
1309 SilcBuffer buffer = packet->buffer;
1310 SilcClientEntry client;
1311 SilcClientID *client_id;
1313 SilcIDListData idata;
1314 char *username = NULL, *realname = NULL, *id_string;
1317 char *hostname, *nickname;
1320 SILC_LOG_DEBUG(("Creating new client"));
1322 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
1325 /* Take client entry */
1326 client = (SilcClientEntry)sock->user_data;
1327 idata = (SilcIDListData)client;
1329 /* Remove the old cache entry */
1330 if (!silc_idcache_del_by_context(server->local_list->clients, client)) {
1331 SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
1332 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1337 /* Parse incoming packet */
1338 ret = silc_buffer_unformat(buffer,
1339 SILC_STR_UI16_STRING_ALLOC(&username),
1340 SILC_STR_UI16_STRING_ALLOC(&realname),
1344 silc_free(username);
1346 silc_free(realname);
1347 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1348 "Incomplete client information");
1353 silc_free(username);
1355 silc_free(realname);
1356 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1357 "Incomplete client information");
1361 if (strlen(username) > 128)
1362 username[127] = '\0';
1364 nickname = strdup(username);
1366 /* Make sanity checks for the hostname of the client. If the hostname
1367 is provided in the `username' check that it is the same than the
1368 resolved hostname, or if not resolved the hostname that appears in
1369 the client's public key. If the hostname is not present then put
1370 it from the resolved name or from the public key. */
1371 if (strchr(username, '@')) {
1372 SilcPublicKeyIdentifier pident;
1373 int tlen = strcspn(username, "@");
1374 char *phostname = NULL;
1376 hostname = silc_calloc((strlen(username) - tlen) + 1, sizeof(char));
1377 memcpy(hostname, username + tlen + 1, strlen(username) - tlen - 1);
1379 if (strcmp(sock->hostname, sock->ip) &&
1380 strcmp(sock->hostname, hostname)) {
1381 silc_free(username);
1382 silc_free(hostname);
1384 silc_free(realname);
1385 silc_server_disconnect_remote(server, sock,
1386 "Server closed connection: "
1387 "Incomplete client information");
1391 pident = silc_pkcs_decode_identifier(client->data.public_key->identifier);
1393 phostname = strdup(pident->host);
1394 silc_pkcs_free_identifier(pident);
1397 if (!strcmp(sock->hostname, sock->ip) &&
1398 phostname && strcmp(phostname, hostname)) {
1399 silc_free(username);
1400 silc_free(hostname);
1402 silc_free(phostname);
1404 silc_free(realname);
1405 silc_server_disconnect_remote(server, sock,
1406 "Server closed connection: "
1407 "Incomplete client information");
1412 silc_free(phostname);
1414 /* The hostname is not present, add it. */
1416 /* XXX For now we cannot take the host name from the public key since
1417 they are not trusted or we cannot verify them as trusted. Just take
1418 what the resolved name or address is. */
1420 if (strcmp(sock->hostname, sock->ip)) {
1422 newusername = silc_calloc(strlen(username) +
1423 strlen(sock->hostname) + 2,
1424 sizeof(*newusername));
1425 strncat(newusername, username, strlen(username));
1426 strncat(newusername, "@", 1);
1427 strncat(newusername, sock->hostname, strlen(sock->hostname));
1428 silc_free(username);
1429 username = newusername;
1432 SilcPublicKeyIdentifier pident =
1433 silc_pkcs_decode_identifier(client->data.public_key->identifier);
1436 newusername = silc_calloc(strlen(username) +
1437 strlen(pident->host) + 2,
1438 sizeof(*newusername));
1439 strncat(newusername, username, strlen(username));
1440 strncat(newusername, "@", 1);
1441 strncat(newusername, pident->host, strlen(pident->host));
1442 silc_free(username);
1443 username = newusername;
1444 silc_pkcs_free_identifier(pident);
1450 /* Create Client ID */
1451 while (!silc_id_create_client_id(server, server->id, server->rng,
1452 server->md5hash, nickname, &client_id)) {
1454 snprintf(&nickname[strlen(nickname) - 1], 1, "%d", nickfail);
1457 /* Update client entry */
1458 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
1459 client->nickname = nickname;
1460 client->username = username;
1461 client->userinfo = realname ? realname : strdup(" ");
1462 client->id = client_id;
1463 id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
1465 /* Add the client again to the ID cache */
1466 silc_idcache_add(server->local_list->clients, client->nickname,
1467 client_id, client, FALSE);
1469 /* Notify our router about new client on the SILC network */
1470 if (!server->standalone)
1471 silc_server_send_new_id(server, (SilcSocketConnection)
1472 server->router->connection,
1473 server->server_type == SILC_ROUTER ? TRUE : FALSE,
1474 client->id, SILC_ID_CLIENT, id_len);
1476 /* Send the new client ID to the client. */
1477 id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
1478 reply = silc_buffer_alloc(2 + 2 + id_len);
1479 silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
1480 silc_buffer_format(reply,
1481 SILC_STR_UI_SHORT(SILC_ID_CLIENT),
1482 SILC_STR_UI_SHORT(id_len),
1483 SILC_STR_UI_XNSTRING(id_string, id_len),
1485 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0,
1486 reply->data, reply->len, FALSE);
1487 silc_free(id_string);
1488 silc_buffer_free(reply);
1490 /* Send some nice info to the client */
1491 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1492 ("Welcome to the SILC Network %s",
1494 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1495 ("Your host is %s, running version %s",
1496 server->config->server_info->server_name,
1498 if (server->server_type == SILC_ROUTER) {
1499 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1500 ("There are %d clients on %d servers in SILC "
1501 "Network", server->stat.clients,
1502 server->stat.servers + 1));
1503 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1504 ("There are %d clients on %d server in our cell",
1505 server->stat.cell_clients,
1506 server->stat.cell_servers + 1));
1507 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1508 ("I have %d clients, %d channels, %d servers and "
1510 server->stat.my_clients,
1511 server->stat.my_channels,
1512 server->stat.my_servers,
1513 server->stat.my_routers));
1514 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1515 ("%d server operators and %d router operators "
1517 server->stat.my_server_ops,
1518 server->stat.my_router_ops));
1520 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1521 ("I have %d clients and %d channels formed",
1522 server->stat.my_clients,
1523 server->stat.my_channels));
1524 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1525 ("%d operators online",
1526 server->stat.my_server_ops));
1528 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1529 ("Your connection is secured with %s cipher, "
1530 "key length %d bits",
1531 idata->send_key->cipher->name,
1532 idata->send_key->cipher->key_len));
1533 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1534 ("Your current nickname is %s",
1538 silc_server_send_motd(server, sock);
1543 /* Create new server. This processes received New Server packet and
1544 saves the received Server ID. The server is our locally connected
1545 server thus we save all the information and save it to local list.
1546 This funtion can be used by both normal server and router server.
1547 If normal server uses this it means that its router has connected
1548 to the server. If router uses this it means that one of the cell's
1549 servers is connected to the router. */
1551 SilcServerEntry silc_server_new_server(SilcServer server,
1552 SilcSocketConnection sock,
1553 SilcPacketContext *packet)
1555 SilcBuffer buffer = packet->buffer;
1556 SilcServerEntry new_server;
1557 SilcServerID *server_id;
1558 SilcIDListData idata;
1559 unsigned char *server_name, *id_string;
1560 uint16 id_len, name_len;
1563 SILC_LOG_DEBUG(("Creating new server"));
1565 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
1566 sock->type != SILC_SOCKET_TYPE_ROUTER)
1569 /* Take server entry */
1570 new_server = (SilcServerEntry)sock->user_data;
1571 idata = (SilcIDListData)new_server;
1573 /* Remove the old cache entry */
1574 silc_idcache_del_by_context(server->local_list->servers, new_server);
1576 /* Parse the incoming packet */
1577 ret = silc_buffer_unformat(buffer,
1578 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
1579 SILC_STR_UI16_NSTRING_ALLOC(&server_name,
1584 silc_free(id_string);
1586 silc_free(server_name);
1590 if (id_len > buffer->len) {
1591 silc_free(id_string);
1592 silc_free(server_name);
1597 server_name[255] = '\0';
1600 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
1602 silc_free(id_string);
1603 silc_free(server_name);
1606 silc_free(id_string);
1608 /* Update server entry */
1609 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
1610 new_server->server_name = server_name;
1611 new_server->id = server_id;
1613 /* Add again the entry to the ID cache. */
1614 silc_idcache_add(server->local_list->servers, server_name, server_id,
1617 /* Distribute the information about new server in the SILC network
1618 to our router. If we are normal server we won't send anything
1619 since this connection must be our router connection. */
1620 if (server->server_type == SILC_ROUTER && !server->standalone &&
1621 server->router->connection != sock)
1622 silc_server_send_new_id(server, server->router->connection,
1623 TRUE, new_server->id, SILC_ID_SERVER,
1624 silc_id_get_len(server_id, SILC_ID_SERVER));
1626 if (server->server_type == SILC_ROUTER)
1627 server->stat.cell_servers++;
1632 /* Processes incoming New ID packet. New ID Payload is used to distribute
1633 information about newly registered clients and servers. */
1635 static void silc_server_new_id_real(SilcServer server,
1636 SilcSocketConnection sock,
1637 SilcPacketContext *packet,
1640 SilcBuffer buffer = packet->buffer;
1642 SilcServerEntry router;
1643 SilcSocketConnection router_sock;
1648 SILC_LOG_DEBUG(("Processing new ID"));
1650 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1651 server->server_type == SILC_SERVER ||
1652 packet->src_id_type != SILC_ID_SERVER)
1655 idp = silc_id_payload_parse(buffer);
1659 id_type = silc_id_payload_get_type(idp);
1661 /* Normal server cannot have other normal server connections */
1662 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
1665 id = silc_id_payload_get_id(idp);
1669 /* If the sender of this packet is server and we are router we need to
1670 broadcast this packet to other routers in the network. */
1671 if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
1672 sock->type == SILC_SOCKET_TYPE_SERVER &&
1673 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1674 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
1675 silc_server_packet_send(server, server->router->connection,
1677 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1678 buffer->data, buffer->len, FALSE);
1681 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1682 id_list = server->local_list;
1684 id_list = server->global_list;
1686 /* If the packet is coming from server then use the sender as the
1687 origin of the the packet. If it came from router then check the real
1688 sender of the packet and use that as the origin. */
1689 if (sock->type == SILC_SOCKET_TYPE_SERVER) {
1691 router = sock->user_data;
1693 void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1694 packet->src_id_type);
1695 router = silc_idlist_find_server_by_id(server->global_list,
1696 sender_id, TRUE, NULL);
1698 router = silc_idlist_find_server_by_id(server->local_list,
1699 sender_id, TRUE, NULL);
1700 silc_free(sender_id);
1707 case SILC_ID_CLIENT:
1709 SilcClientEntry entry;
1711 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
1712 silc_id_render(id, SILC_ID_CLIENT),
1713 sock->type == SILC_SOCKET_TYPE_SERVER ?
1714 "Server" : "Router", sock->hostname));
1716 /* As a router we keep information of all global information in our
1717 global list. Cell wide information however is kept in the local
1719 entry = silc_idlist_add_client(id_list, NULL, NULL, NULL,
1722 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
1724 /* Inform the sender that the ID is not usable */
1725 silc_server_send_notify_signoff(server, sock, FALSE, id, NULL);
1728 entry->nickname = NULL;
1729 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
1731 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1732 server->stat.cell_clients++;
1733 server->stat.clients++;
1737 case SILC_ID_SERVER:
1739 SilcServerEntry entry;
1741 /* If the ID is mine, ignore it. */
1742 if (SILC_ID_SERVER_COMPARE(id, server->id)) {
1743 SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
1747 /* If the ID is the sender's ID, ignore it (we have it already) */
1748 if (SILC_ID_SERVER_COMPARE(id, router->id)) {
1749 SILC_LOG_DEBUG(("Ignoring sender's own ID"));
1753 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
1754 silc_id_render(id, SILC_ID_SERVER),
1755 sock->type == SILC_SOCKET_TYPE_SERVER ?
1756 "Server" : "Router", sock->hostname));
1758 /* As a router we keep information of all global information in our
1759 global list. Cell wide information however is kept in the local
1761 entry = silc_idlist_add_server(id_list, NULL, 0, id, router,
1764 SILC_LOG_ERROR(("Could not add new server to the ID Cache"));
1767 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
1769 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1770 server->stat.cell_servers++;
1771 server->stat.servers++;
1775 case SILC_ID_CHANNEL:
1776 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
1784 silc_id_payload_free(idp);
1788 /* Processes incoming New ID packet. New ID Payload is used to distribute
1789 information about newly registered clients and servers. */
1791 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
1792 SilcPacketContext *packet)
1794 silc_server_new_id_real(server, sock, packet, TRUE);
1797 /* Receoved New Id List packet, list of New ID payloads inside one
1798 packet. Process the New ID payloads one by one. */
1800 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
1801 SilcPacketContext *packet)
1803 SilcPacketContext *new_id;
1807 SILC_LOG_DEBUG(("Processing New ID List"));
1809 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1810 packet->src_id_type != SILC_ID_SERVER)
1813 /* If the sender of this packet is server and we are router we need to
1814 broadcast this packet to other routers in the network. Broadcast
1815 this list packet instead of multiple New ID packets. */
1816 if (!server->standalone && server->server_type == SILC_ROUTER &&
1817 sock->type == SILC_SOCKET_TYPE_SERVER &&
1818 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1819 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
1820 silc_server_packet_send(server, server->router->connection,
1822 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1823 packet->buffer->data, packet->buffer->len, FALSE);
1826 /* Make copy of the original packet context, except for the actual
1827 data buffer, which we will here now fetch from the original buffer. */
1828 new_id = silc_packet_context_alloc();
1829 new_id->type = SILC_PACKET_NEW_ID;
1830 new_id->flags = packet->flags;
1831 new_id->src_id = packet->src_id;
1832 new_id->src_id_len = packet->src_id_len;
1833 new_id->src_id_type = packet->src_id_type;
1834 new_id->dst_id = packet->dst_id;
1835 new_id->dst_id_len = packet->dst_id_len;
1836 new_id->dst_id_type = packet->dst_id_type;
1838 idp = silc_buffer_alloc(256);
1839 new_id->buffer = idp;
1841 while (packet->buffer->len) {
1842 SILC_GET16_MSB(id_len, packet->buffer->data + 2);
1843 if ((id_len > packet->buffer->len) ||
1844 (id_len > idp->truelen))
1847 silc_buffer_pull_tail(idp, 4 + id_len);
1848 silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
1850 /* Process the New ID */
1851 silc_server_new_id_real(server, sock, new_id, FALSE);
1853 silc_buffer_push_tail(idp, 4 + id_len);
1854 silc_buffer_pull(packet->buffer, 4 + id_len);
1857 silc_buffer_free(idp);
1861 /* Received New Channel packet. Information about new channels in the
1862 network are distributed using this packet. Save the information about
1863 the new channel. This usually comes from router but also normal server
1864 can send this to notify channels it has when it connects to us. */
1866 void silc_server_new_channel(SilcServer server,
1867 SilcSocketConnection sock,
1868 SilcPacketContext *packet)
1870 SilcChannelPayload payload;
1871 SilcChannelID *channel_id;
1878 SILC_LOG_DEBUG(("Processing New Channel"));
1880 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1881 packet->src_id_type != SILC_ID_SERVER ||
1882 server->server_type == SILC_SERVER)
1885 /* Parse the channel payload */
1886 payload = silc_channel_payload_parse(packet->buffer);
1890 /* Get the channel ID */
1891 channel_id = silc_channel_get_id_parse(payload);
1893 silc_channel_payload_free(payload);
1897 channel_name = silc_channel_get_name(payload, &name_len);
1899 channel_name[255] = '\0';
1901 id = silc_channel_get_id(payload, &id_len);
1903 if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
1904 /* Add the channel to global list as it is coming from router. It
1905 cannot be our own channel as it is coming from router. */
1907 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
1908 silc_id_render(channel_id, SILC_ID_CHANNEL),
1911 silc_idlist_add_channel(server->global_list, strdup(channel_name),
1912 0, channel_id, sock->user_data, NULL, NULL);
1914 server->stat.channels++;
1916 /* The channel is coming from our server, thus it is in our cell
1917 we will add it to our local list. */
1918 SilcChannelEntry channel;
1921 SILC_LOG_DEBUG(("New channel id(%s) from [Server] %s",
1922 silc_id_render(channel_id, SILC_ID_CHANNEL),
1925 /* Check that we don't already have this channel */
1926 channel = silc_idlist_find_channel_by_name(server->local_list,
1927 channel_name, NULL);
1929 channel = silc_idlist_find_channel_by_name(server->global_list,
1930 channel_name, NULL);
1932 /* If the channel does not exist, then create it. We create the channel
1933 with the channel ID provided by the server. This creates a new
1934 key to the channel as well that we will send to the server. */
1936 channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
1940 silc_channel_payload_free(payload);
1941 silc_free(channel_id);
1945 /* Get the mode and set it to the channel */
1946 channel->mode = silc_channel_get_mode(payload);
1948 /* Send the new channel key to the server */
1949 chk = silc_channel_key_payload_encode(id_len, id,
1950 strlen(channel->channel_key->
1952 channel->channel_key->cipher->name,
1953 channel->key_len / 8,
1955 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
1956 chk->data, chk->len, FALSE);
1957 silc_buffer_free(chk);
1960 /* The channel exist by that name, check whether the ID's match.
1961 If they don't then we'll force the server to use the ID we have.
1962 We also create a new key for the channel. */
1963 SilcBuffer users = NULL, users_modes = NULL;
1966 channel_id = silc_id_dup(channel_id, SILC_ID_CHANNEL);
1968 if (!SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
1969 /* They don't match, send CHANNEL_CHANGE notify to the server to
1970 force the ID change. */
1971 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
1972 silc_server_send_notify_channel_change(server, sock, FALSE,
1973 channel_id, channel->id);
1976 /* If the mode is different from what we have then enforce the
1978 mode = silc_channel_get_mode(payload);
1979 if (channel->mode != mode) {
1980 SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
1981 silc_server_send_notify_cmode(server, sock, FALSE, channel,
1982 channel->mode, server->id,
1984 channel->cipher, channel->hmac_name);
1987 /* Create new key for the channel and send it to the server and
1988 everybody else possibly on the channel. */
1990 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
1991 if (!silc_server_create_channel_key(server, channel, 0))
1994 /* Send to the channel */
1995 silc_server_send_channel_key(server, sock, channel, FALSE);
1996 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
1997 id_len = SILC_ID_CHANNEL_LEN;
1999 /* Send to the server */
2000 chk = silc_channel_key_payload_encode(id_len, id,
2001 strlen(channel->channel_key->
2003 channel->channel_key->
2005 channel->key_len / 8,
2007 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
2008 chk->data, chk->len, FALSE);
2009 silc_buffer_free(chk);
2013 silc_free(channel_id);
2015 /* Since the channel is coming from server and we also know about it
2016 then send the JOIN notify to the server so that it see's our
2017 users on the channel "joining" the channel. */
2018 silc_server_announce_get_channel_users(server, channel, &users,
2021 silc_buffer_push(users, users->data - users->head);
2022 silc_server_packet_send(server, sock,
2023 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2024 users->data, users->len, FALSE);
2025 silc_buffer_free(users);
2028 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
2029 silc_server_packet_send_dest(server, sock,
2030 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2031 channel->id, SILC_ID_CHANNEL,
2033 users_modes->len, FALSE);
2034 silc_buffer_free(users_modes);
2039 silc_channel_payload_free(payload);
2042 /* Received New Channel List packet, list of New Channel List payloads inside
2043 one packet. Process the New Channel payloads one by one. */
2045 void silc_server_new_channel_list(SilcServer server,
2046 SilcSocketConnection sock,
2047 SilcPacketContext *packet)
2049 SilcPacketContext *new;
2053 SILC_LOG_DEBUG(("Processing New Channel List"));
2055 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2056 packet->src_id_type != SILC_ID_SERVER ||
2057 server->server_type == SILC_SERVER)
2060 /* If the sender of this packet is server and we are router we need to
2061 broadcast this packet to other routers in the network. Broadcast
2062 this list packet instead of multiple New Channel packets. */
2063 if (!server->standalone && server->server_type == SILC_ROUTER &&
2064 sock->type == SILC_SOCKET_TYPE_SERVER &&
2065 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2066 SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
2067 silc_server_packet_send(server, server->router->connection,
2069 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2070 packet->buffer->data, packet->buffer->len, FALSE);
2073 /* Make copy of the original packet context, except for the actual
2074 data buffer, which we will here now fetch from the original buffer. */
2075 new = silc_packet_context_alloc();
2076 new->type = SILC_PACKET_NEW_CHANNEL;
2077 new->flags = packet->flags;
2078 new->src_id = packet->src_id;
2079 new->src_id_len = packet->src_id_len;
2080 new->src_id_type = packet->src_id_type;
2081 new->dst_id = packet->dst_id;
2082 new->dst_id_len = packet->dst_id_len;
2083 new->dst_id_type = packet->dst_id_type;
2085 buffer = silc_buffer_alloc(512);
2086 new->buffer = buffer;
2088 while (packet->buffer->len) {
2089 SILC_GET16_MSB(len1, packet->buffer->data);
2090 if ((len1 > packet->buffer->len) ||
2091 (len1 > buffer->truelen))
2094 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
2095 if ((len2 > packet->buffer->len) ||
2096 (len2 > buffer->truelen))
2099 silc_buffer_pull_tail(buffer, 8 + len1 + len2);
2100 silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
2102 /* Process the New Channel */
2103 silc_server_new_channel(server, sock, new);
2105 silc_buffer_push_tail(buffer, 8 + len1 + len2);
2106 silc_buffer_pull(packet->buffer, 8 + len1 + len2);
2109 silc_buffer_free(buffer);
2113 /* Received key agreement packet. This packet is never for us. It is to
2114 the client in the packet's destination ID. Sending of this sort of packet
2115 equals sending private message, ie. it is sent point to point from
2116 one client to another. */
2118 void silc_server_key_agreement(SilcServer server,
2119 SilcSocketConnection sock,
2120 SilcPacketContext *packet)
2122 SilcSocketConnection dst_sock;
2123 SilcIDListData idata;
2125 SILC_LOG_DEBUG(("Start"));
2127 if (packet->src_id_type != SILC_ID_CLIENT ||
2128 packet->dst_id_type != SILC_ID_CLIENT)
2131 if (!packet->dst_id)
2134 /* Get the route to the client */
2135 dst_sock = silc_server_get_client_route(server, packet->dst_id,
2136 packet->dst_id_len, NULL, &idata);
2140 /* Relay the packet */
2141 silc_server_relay_packet(server, dst_sock, idata->send_key,
2142 idata->hmac_send, packet, FALSE);
2145 /* Received connection auth request packet that is used during connection
2146 phase to resolve the mandatory authentication method. This packet can
2147 actually be received at anytime but usually it is used only during
2148 the connection authentication phase. Now, protocol says that this packet
2149 can come from client or server, however, we support only this coming
2150 from client and expect that server always knows what authentication
2153 void silc_server_connection_auth_request(SilcServer server,
2154 SilcSocketConnection sock,
2155 SilcPacketContext *packet)
2157 SilcServerConfigSectionClientConnection *client = NULL;
2160 SilcAuthMethod auth_meth;
2162 SILC_LOG_DEBUG(("Start"));
2164 if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT)
2167 /* Parse the payload */
2168 ret = silc_buffer_unformat(packet->buffer,
2169 SILC_STR_UI_SHORT(&conn_type),
2170 SILC_STR_UI_SHORT(NULL),
2175 if (conn_type != SILC_SOCKET_TYPE_CLIENT)
2178 /* Get the authentication method for the client */
2179 auth_meth = SILC_AUTH_NONE;
2180 port = server->sockets[server->sock]->port; /* Listenning port */
2181 client = silc_server_config_find_client_conn(server->config,
2185 client = silc_server_config_find_client_conn(server->config,
2189 auth_meth = client->auth_meth;
2191 /* Send it back to the client */
2192 silc_server_send_connection_auth_request(server, sock,
2197 /* Received REKEY packet. The sender of the packet wants to regenerate
2198 its session keys. This starts the REKEY protocol. */
2200 void silc_server_rekey(SilcServer server,
2201 SilcSocketConnection sock,
2202 SilcPacketContext *packet)
2204 SilcProtocol protocol;
2205 SilcServerRekeyInternalContext *proto_ctx;
2206 SilcIDListData idata = (SilcIDListData)sock->user_data;
2208 SILC_LOG_DEBUG(("Start"));
2210 /* Allocate internal protocol context. This is sent as context
2212 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
2213 proto_ctx->server = (void *)server;
2214 proto_ctx->sock = sock;
2215 proto_ctx->responder = TRUE;
2216 proto_ctx->pfs = idata->rekey->pfs;
2218 /* Perform rekey protocol. Will call the final callback after the
2219 protocol is over. */
2220 silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
2221 &protocol, proto_ctx, silc_server_rekey_final);
2222 sock->protocol = protocol;
2224 if (proto_ctx->pfs == FALSE)
2225 /* Run the protocol */
2226 silc_protocol_execute(protocol, server->schedule, 0, 0);