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 = NULL, *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 /* Parse the Notify Payload */
78 payload = silc_notify_payload_parse(packet->buffer);
82 /* If we are router and this packet is not already broadcast packet
83 we will broadcast it. The sending socket really cannot be router or
84 the router is buggy. If this packet is coming from router then it must
85 have the broadcast flag set already and we won't do anything. */
86 if (!server->standalone && server->server_type == SILC_ROUTER &&
87 sock->type == SILC_SOCKET_TYPE_SERVER &&
88 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
89 SILC_LOG_DEBUG(("Broadcasting received Notify packet"));
90 if (packet->dst_id_type == SILC_ID_CHANNEL) {
91 /* Packet is destined to channel */
92 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
97 silc_server_packet_send_dest(server, server->router->connection,
99 packet->flags | SILC_PACKET_FLAG_BROADCAST,
100 channel_id, SILC_ID_CHANNEL,
101 packet->buffer->data, packet->buffer->len,
103 silc_server_backup_send_dest(server, (SilcServerEntry)sock->user_data,
104 packet->type, packet->flags,
105 channel_id, SILC_ID_CHANNEL,
106 packet->buffer->data, packet->buffer->len,
109 /* Packet is destined to client or server */
110 silc_server_packet_send(server, server->router->connection,
112 packet->flags | SILC_PACKET_FLAG_BROADCAST,
113 packet->buffer->data, packet->buffer->len,
115 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
116 packet->type, packet->flags,
117 packet->buffer->data, packet->buffer->len,
122 type = silc_notify_get_type(payload);
123 args = silc_notify_get_args(payload);
128 case SILC_NOTIFY_TYPE_JOIN:
130 * Distribute the notify to local clients on the channel
132 SILC_LOG_DEBUG(("JOIN notify"));
135 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
138 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
142 /* Get channel entry */
143 channel = silc_idlist_find_channel_by_id(server->global_list,
146 channel = silc_idlist_find_channel_by_id(server->local_list,
149 silc_free(channel_id);
153 silc_free(channel_id);
156 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
159 client_id = silc_id_payload_parse_id(tmp, tmp_len);
163 /* If the the client is not in local list we check global list (ie. the
164 channel will be global channel) and if it does not exist then create
165 entry for the client. */
166 client = silc_idlist_find_client_by_id(server->global_list,
167 client_id, server->server_type,
170 client = silc_idlist_find_client_by_id(server->local_list,
171 client_id, server->server_type,
174 /* If router did not find the client the it is bogus */
175 if (server->server_type != SILC_SERVER)
179 silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
180 silc_id_dup(client_id, SILC_ID_CLIENT),
181 sock->user_data, NULL);
183 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
184 silc_free(client_id);
188 client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
192 /* Do not process the notify if the client is not registered */
193 if (!(client->data.status & SILC_IDLIST_STATUS_REGISTERED))
196 /* Do not add client to channel if it is there already */
197 if (silc_server_client_on_channel(client, channel)) {
198 SILC_LOG_DEBUG(("Client already on channel"));
202 /* Send to channel */
203 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
204 FALSE, packet->buffer->data,
205 packet->buffer->len, FALSE);
207 if (server->server_type != SILC_ROUTER &&
208 sock->type == SILC_SOCKET_TYPE_ROUTER)
209 /* The channel is global now */
210 channel->global_users = TRUE;
212 /* JOIN the global client to the channel (local clients (if router
213 created the channel) is joined in the pending JOIN command). */
214 chl = silc_calloc(1, sizeof(*chl));
215 chl->client = client;
216 chl->channel = channel;
218 /* If this is the first one on the channel then it is the founder of
220 if (!silc_hash_table_count(channel->user_list))
221 chl->mode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
223 silc_hash_table_add(channel->user_list, client, chl);
224 silc_hash_table_add(client->channels, channel, chl);
225 silc_free(client_id);
229 case SILC_NOTIFY_TYPE_LEAVE:
231 * Distribute the notify to local clients on the channel
233 SILC_LOG_DEBUG(("LEAVE notify"));
236 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
237 packet->dst_id_type);
242 /* Get channel entry */
243 channel = silc_idlist_find_channel_by_id(server->global_list,
246 channel = silc_idlist_find_channel_by_id(server->local_list,
249 silc_free(channel_id);
255 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
257 silc_free(channel_id);
260 client_id = silc_id_payload_parse_id(tmp, tmp_len);
262 silc_free(channel_id);
266 /* Get client entry */
267 client = silc_idlist_find_client_by_id(server->global_list,
268 client_id, TRUE, NULL);
270 client = silc_idlist_find_client_by_id(server->local_list,
271 client_id, TRUE, NULL);
273 silc_free(client_id);
274 silc_free(channel_id);
278 silc_free(client_id);
280 /* Check if on channel */
281 if (!silc_server_client_on_channel(client, channel))
284 /* Send the leave notify to channel */
285 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
286 FALSE, packet->buffer->data,
287 packet->buffer->len, FALSE);
289 /* Remove the user from channel */
290 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
293 case SILC_NOTIFY_TYPE_SIGNOFF:
295 * Distribute the notify to local clients on the channel
297 SILC_LOG_DEBUG(("SIGNOFF notify"));
300 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
303 client_id = silc_id_payload_parse_id(tmp, tmp_len);
307 /* Get client entry */
308 client = silc_idlist_find_client_by_id(server->global_list,
309 client_id, TRUE, &cache);
311 client = silc_idlist_find_client_by_id(server->local_list,
312 client_id, TRUE, &cache);
314 silc_free(client_id);
318 silc_free(client_id);
320 /* Get signoff message */
321 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
325 /* Remove the client from all channels. */
326 silc_server_remove_from_channels(server, NULL, client, TRUE, tmp, FALSE);
328 client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
329 cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
330 server->stat.clients--;
331 if (server->server_type == SILC_ROUTER)
332 server->stat.cell_clients--;
335 case SILC_NOTIFY_TYPE_TOPIC_SET:
337 * Distribute the notify to local clients on the channel
340 SILC_LOG_DEBUG(("TOPIC SET notify"));
343 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
344 packet->dst_id_type);
349 /* Get channel entry */
350 channel = silc_idlist_find_channel_by_id(server->global_list,
353 channel = silc_idlist_find_channel_by_id(server->local_list,
356 silc_free(channel_id);
362 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
364 silc_free(channel_id);
369 silc_free(channel->topic);
370 channel->topic = silc_calloc(tmp_len + 1, sizeof(*channel->topic));
371 memcpy(channel->topic, tmp, tmp_len);
373 /* Send the same notify to the channel */
374 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
375 FALSE, packet->buffer->data,
376 packet->buffer->len, FALSE);
377 silc_free(channel_id);
380 case SILC_NOTIFY_TYPE_NICK_CHANGE:
383 * Distribute the notify to local clients on the channel
385 unsigned char *id, *id2;
387 SILC_LOG_DEBUG(("NICK CHANGE notify"));
389 /* Get old client ID */
390 id = silc_argument_get_arg_type(args, 1, &tmp_len);
393 client_id = silc_id_payload_parse_id(id, tmp_len);
397 /* Get new client ID */
398 id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
401 client_id2 = silc_id_payload_parse_id(id2, tmp_len);
405 SILC_LOG_DEBUG(("Old Client ID id(%s)",
406 silc_id_render(client_id, SILC_ID_CLIENT)));
407 SILC_LOG_DEBUG(("New Client ID id(%s)",
408 silc_id_render(client_id2, SILC_ID_CLIENT)));
410 /* Replace the Client ID */
411 client = silc_idlist_replace_client_id(server->global_list, client_id,
414 client = silc_idlist_replace_client_id(server->local_list, client_id,
418 /* The nickname is not valid anymore, set it NULL. This causes that
419 the nickname will be queried if someone wants to know it. */
420 if (client->nickname)
421 silc_free(client->nickname);
422 client->nickname = NULL;
424 /* Send the NICK_CHANGE notify type to local clients on the channels
425 this client is joined to. */
426 silc_server_send_notify_on_channels(server, NULL, client,
427 SILC_NOTIFY_TYPE_NICK_CHANGE, 2,
432 silc_free(client_id);
434 silc_free(client_id2);
438 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
440 * Distribute the notify to local clients on the channel
443 SILC_LOG_DEBUG(("CMODE CHANGE notify"));
446 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
447 packet->dst_id_type);
452 /* Get channel entry */
453 channel = silc_idlist_find_channel_by_id(server->global_list,
456 channel = silc_idlist_find_channel_by_id(server->local_list,
459 silc_free(channel_id);
465 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
467 silc_free(channel_id);
471 SILC_GET32_MSB(mode, tmp);
473 /* Check if mode changed */
474 if (channel->mode == mode)
477 /* Send the same notify to the channel */
478 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
479 FALSE, packet->buffer->data,
480 packet->buffer->len, FALSE);
482 /* If the channel had private keys set and the mode was removed then
483 we must re-generate and re-distribute a new channel key */
484 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY &&
485 !(mode & SILC_CHANNEL_MODE_PRIVKEY)) {
486 /* Re-generate channel key */
487 if (!silc_server_create_channel_key(server, channel, 0))
490 /* Send the channel key. This sends it to our local clients and if
491 we are normal server to our router as well. */
492 silc_server_send_channel_key(server, NULL, channel,
493 server->server_type == SILC_ROUTER ?
494 FALSE : !server->standalone);
498 channel->mode = mode;
499 silc_free(channel_id);
502 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
504 unsigned char hash[32];
507 silc_hmac_free(channel->hmac);
508 if (!silc_hmac_alloc(tmp, NULL, &channel->hmac))
511 /* Set the HMAC key out of current channel key. The client must do
513 silc_hash_make(channel->hmac->hash, channel->key, channel->key_len / 8,
515 silc_hmac_set_key(channel->hmac, hash,
516 silc_hash_len(channel->hmac->hash));
517 memset(hash, 0, sizeof(hash));
522 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
525 * Distribute the notify to local clients on the channel
527 SilcChannelClientEntry chl2 = NULL;
528 bool notify_sent = FALSE;
530 SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
533 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
534 packet->dst_id_type);
539 /* Get channel entry */
540 channel = silc_idlist_find_channel_by_id(server->global_list,
543 channel = silc_idlist_find_channel_by_id(server->local_list,
546 silc_free(channel_id);
552 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
554 silc_free(channel_id);
558 SILC_GET32_MSB(mode, tmp);
560 /* Get target client */
561 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
564 client_id = silc_id_payload_parse_id(tmp, tmp_len);
568 /* Get client entry */
569 client = silc_idlist_find_client_by_id(server->global_list,
570 client_id, TRUE, NULL);
572 client = silc_idlist_find_client_by_id(server->local_list,
573 client_id, TRUE, NULL);
575 silc_free(client_id);
579 silc_free(client_id);
581 /* Get entry to the channel user list */
582 silc_hash_table_list(channel->user_list, &htl);
583 while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
584 /* If the mode is channel founder and we already find a client
585 to have that mode on the channel we will enforce the sender
586 to change the channel founder mode away. There can be only one
587 channel founder on the channel. */
588 if (server->server_type == SILC_ROUTER &&
589 mode & SILC_CHANNEL_UMODE_CHANFO &&
590 chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
592 unsigned char cumode[4];
594 if (chl->client == client && chl->mode == mode) {
599 mode &= ~SILC_CHANNEL_UMODE_CHANFO;
600 silc_server_send_notify_cumode(server, sock, FALSE, channel, mode,
601 client->id, SILC_ID_CLIENT,
604 idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
605 SILC_PUT32_MSB(mode, cumode);
606 silc_server_send_notify_to_channel(server, sock, channel, FALSE,
607 SILC_NOTIFY_TYPE_CUMODE_CHANGE,
608 3, idp->data, idp->len,
610 idp->data, idp->len);
611 silc_buffer_free(idp);
614 /* Force the mode change if we alredy set the mode */
617 silc_free(channel_id);
622 if (chl->client == client) {
623 if (chl->mode == mode) {
628 /* Change the mode */
630 if (!(mode & SILC_CHANNEL_UMODE_CHANFO))
637 /* Send the same notify to the channel */
639 silc_server_packet_send_to_channel(server, sock, channel,
641 FALSE, packet->buffer->data,
642 packet->buffer->len, FALSE);
644 silc_free(channel_id);
648 case SILC_NOTIFY_TYPE_INVITE:
650 if (packet->dst_id_type == SILC_ID_CLIENT)
653 SILC_LOG_DEBUG(("INVITE notify"));
656 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
659 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
663 /* Get channel entry */
664 channel = silc_idlist_find_channel_by_id(server->global_list,
667 channel = silc_idlist_find_channel_by_id(server->local_list,
670 silc_free(channel_id);
674 silc_free(channel_id);
676 /* Get the added invite */
677 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
679 if (!channel->invite_list)
680 channel->invite_list = silc_calloc(tmp_len + 2,
681 sizeof(*channel->invite_list));
683 channel->invite_list = silc_realloc(channel->invite_list,
684 sizeof(*channel->invite_list) *
686 strlen(channel->invite_list) +
688 if (tmp[tmp_len - 1] == ',')
689 tmp[tmp_len - 1] = '\0';
691 strncat(channel->invite_list, tmp, tmp_len);
692 strncat(channel->invite_list, ",", 1);
695 /* Get the deleted invite */
696 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
697 if (tmp && channel->invite_list) {
698 char *start, *end, *n;
700 if (!strncmp(channel->invite_list, tmp,
701 strlen(channel->invite_list) - 1)) {
702 silc_free(channel->invite_list);
703 channel->invite_list = NULL;
705 start = strstr(channel->invite_list, tmp);
706 if (start && strlen(start) >= tmp_len) {
707 end = start + tmp_len;
708 n = silc_calloc(strlen(channel->invite_list) - tmp_len, sizeof(*n));
709 strncat(n, channel->invite_list, start - channel->invite_list);
710 strncat(n, end + 1, ((channel->invite_list +
711 strlen(channel->invite_list)) - end) - 1);
712 silc_free(channel->invite_list);
713 channel->invite_list = n;
720 case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
722 * Distribute to the local clients on the channel and change the
726 SILC_LOG_DEBUG(("CHANNEL CHANGE"));
728 if (sock->type != SILC_SOCKET_TYPE_ROUTER)
731 /* Get the old Channel ID */
732 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
735 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
739 /* Get the channel entry */
740 channel = silc_idlist_find_channel_by_id(server->global_list,
743 channel = silc_idlist_find_channel_by_id(server->local_list,
746 silc_free(channel_id);
751 /* Send the notify to the channel */
752 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
753 FALSE, packet->buffer->data,
754 packet->buffer->len, FALSE);
756 /* Get the new Channel ID */
757 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
760 channel_id2 = silc_id_payload_parse_id(tmp, tmp_len);
764 SILC_LOG_DEBUG(("Old Channel ID id(%s)",
765 silc_id_render(channel_id, SILC_ID_CHANNEL)));
766 SILC_LOG_DEBUG(("New Channel ID id(%s)",
767 silc_id_render(channel_id2, SILC_ID_CHANNEL)));
769 /* Replace the Channel ID */
770 if (!silc_idlist_replace_channel_id(server->global_list, channel_id,
772 if (!silc_idlist_replace_channel_id(server->local_list, channel_id,
774 silc_free(channel_id2);
779 SilcBuffer users = NULL, users_modes = NULL;
781 /* Re-announce our clients on the channel as the ID has changed now */
782 silc_server_announce_get_channel_users(server, channel, &users,
785 silc_buffer_push(users, users->data - users->head);
786 silc_server_packet_send(server, sock,
787 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
788 users->data, users->len, FALSE);
789 silc_buffer_free(users);
792 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
793 silc_server_packet_send_dest(server, sock,
794 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
795 channel->id, SILC_ID_CHANNEL,
797 users_modes->len, FALSE);
798 silc_buffer_free(users_modes);
802 silc_free(channel_id);
806 case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
808 * Remove the server entry and all clients that this server owns.
811 SILC_LOG_DEBUG(("SERVER SIGNOFF notify"));
814 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
817 server_id = silc_id_payload_parse_id(tmp, tmp_len);
821 /* Get server entry */
822 server_entry = silc_idlist_find_server_by_id(server->global_list,
823 server_id, TRUE, NULL);
825 server_entry = silc_idlist_find_server_by_id(server->local_list,
826 server_id, TRUE, NULL);
828 silc_free(server_id);
832 silc_free(server_id);
834 /* Free all client entries that this server owns as they will
835 become invalid now as well. */
836 silc_server_remove_clients_by_server(server, server_entry, TRUE);
838 /* Remove the server entry */
839 if (!silc_idlist_del_server(server->global_list, server_entry))
840 silc_idlist_del_server(server->local_list, server_entry);
842 /* XXX update statistics */
846 case SILC_NOTIFY_TYPE_KICKED:
848 * Distribute the notify to local clients on the channel
851 SILC_LOG_DEBUG(("KICKED notify"));
854 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
855 packet->dst_id_type);
860 /* Get channel entry */
861 channel = silc_idlist_find_channel_by_id(server->global_list,
864 channel = silc_idlist_find_channel_by_id(server->local_list,
867 silc_free(channel_id);
871 silc_free(channel_id);
874 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
877 client_id = silc_id_payload_parse_id(tmp, tmp_len);
881 /* If the the client is not in local list we check global list */
882 client = silc_idlist_find_client_by_id(server->global_list,
883 client_id, TRUE, NULL);
885 client = silc_idlist_find_client_by_id(server->local_list,
886 client_id, TRUE, NULL);
888 silc_free(client_id);
893 /* Send to channel */
894 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
895 FALSE, packet->buffer->data,
896 packet->buffer->len, FALSE);
898 /* Remove the client from channel */
899 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
903 case SILC_NOTIFY_TYPE_KILLED:
906 * Distribute the notify to local clients on channels
911 SILC_LOG_DEBUG(("KILLED notify"));
914 id = silc_argument_get_arg_type(args, 1, &id_len);
917 client_id = silc_id_payload_parse_id(id, id_len);
921 /* If the the client is not in local list we check global list */
922 client = silc_idlist_find_client_by_id(server->global_list,
923 client_id, TRUE, NULL);
925 client = silc_idlist_find_client_by_id(server->local_list,
926 client_id, TRUE, NULL);
928 silc_free(client_id);
932 silc_free(client_id);
934 /* If the client is one of ours, then close the connection to the
935 client now. This removes the client from all channels as well. */
936 if (packet->dst_id_type == SILC_ID_CLIENT && client->connection) {
937 sock = client->connection;
938 silc_server_free_client_data(server, NULL, client, FALSE, NULL);
939 silc_server_close_connection(server, sock);
944 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
948 /* Send the notify to local clients on the channels except to the
949 client who is killed. */
950 silc_server_send_notify_on_channels(server, client, client,
951 SILC_NOTIFY_TYPE_KILLED,
956 /* Remove the client from all channels */
957 silc_server_remove_from_channels(server, NULL, client, FALSE, NULL,
963 case SILC_NOTIFY_TYPE_UMODE_CHANGE:
965 * Save the mode of the client.
968 SILC_LOG_DEBUG(("UMODE_CHANGE notify"));
971 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
974 client_id = silc_id_payload_parse_id(tmp, tmp_len);
978 /* Get client entry */
979 client = silc_idlist_find_client_by_id(server->global_list,
980 client_id, TRUE, NULL);
982 client = silc_idlist_find_client_by_id(server->local_list,
983 client_id, TRUE, NULL);
985 silc_free(client_id);
989 silc_free(client_id);
992 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
997 SILC_GET32_MSB(client->mode, tmp);
1001 case SILC_NOTIFY_TYPE_BAN:
1006 SILC_LOG_DEBUG(("BAN notify"));
1008 /* Get Channel ID */
1009 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
1012 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
1016 /* Get channel entry */
1017 channel = silc_idlist_find_channel_by_id(server->global_list,
1020 channel = silc_idlist_find_channel_by_id(server->local_list,
1023 silc_free(channel_id);
1027 silc_free(channel_id);
1029 /* Get the new ban and add it to the ban list */
1030 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
1032 if (!channel->ban_list)
1033 channel->ban_list = silc_calloc(tmp_len + 2,
1034 sizeof(*channel->ban_list));
1036 channel->ban_list = silc_realloc(channel->ban_list,
1037 sizeof(*channel->ban_list) *
1039 strlen(channel->ban_list) + 2));
1040 strncat(channel->ban_list, tmp, tmp_len);
1041 strncat(channel->ban_list, ",", 1);
1044 /* Get the ban to be removed and remove it from the list */
1045 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
1046 if (tmp && channel->ban_list) {
1047 char *start, *end, *n;
1049 if (!strcmp(channel->ban_list, tmp)) {
1050 silc_free(channel->ban_list);
1051 channel->ban_list = NULL;
1053 start = strstr(channel->ban_list, tmp);
1054 if (start && strlen(start) >= tmp_len) {
1055 end = start + tmp_len;
1056 n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
1057 strncat(n, channel->ban_list, start - channel->ban_list);
1058 strncat(n, end + 1, ((channel->ban_list +
1059 strlen(channel->ban_list)) - end) - 1);
1060 silc_free(channel->ban_list);
1061 channel->ban_list = n;
1068 /* Ignore rest of the notify types for now */
1069 case SILC_NOTIFY_TYPE_NONE:
1070 case SILC_NOTIFY_TYPE_MOTD:
1077 silc_notify_payload_free(payload);
1080 void silc_server_notify_list(SilcServer server,
1081 SilcSocketConnection sock,
1082 SilcPacketContext *packet)
1084 SilcPacketContext *new;
1088 SILC_LOG_DEBUG(("Processing Notify List"));
1090 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1091 packet->src_id_type != SILC_ID_SERVER)
1094 /* Make copy of the original packet context, except for the actual
1095 data buffer, which we will here now fetch from the original buffer. */
1096 new = silc_packet_context_alloc();
1097 new->type = SILC_PACKET_NOTIFY;
1098 new->flags = packet->flags;
1099 new->src_id = packet->src_id;
1100 new->src_id_len = packet->src_id_len;
1101 new->src_id_type = packet->src_id_type;
1102 new->dst_id = packet->dst_id;
1103 new->dst_id_len = packet->dst_id_len;
1104 new->dst_id_type = packet->dst_id_type;
1106 buffer = silc_buffer_alloc(1024);
1107 new->buffer = buffer;
1109 while (packet->buffer->len) {
1110 SILC_GET16_MSB(len, packet->buffer->data + 2);
1111 if (len > packet->buffer->len)
1114 if (len > buffer->truelen) {
1115 silc_buffer_free(buffer);
1116 buffer = silc_buffer_alloc(1024 + len);
1119 silc_buffer_pull_tail(buffer, len);
1120 silc_buffer_put(buffer, packet->buffer->data, len);
1122 /* Process the Notify */
1123 silc_server_notify(server, sock, new);
1125 silc_buffer_push_tail(buffer, len);
1126 silc_buffer_pull(packet->buffer, len);
1129 silc_buffer_free(buffer);
1133 /* Received private message. This resolves the destination of the message
1134 and sends the packet. This is used by both server and router. If the
1135 destination is our locally connected client this sends the packet to
1136 the client. This may also send the message for further routing if
1137 the destination is not in our server (or router). */
1139 void silc_server_private_message(SilcServer server,
1140 SilcSocketConnection sock,
1141 SilcPacketContext *packet)
1143 SilcSocketConnection dst_sock;
1144 SilcIDListData idata;
1146 SILC_LOG_DEBUG(("Start"));
1148 if (packet->src_id_type != SILC_ID_CLIENT ||
1149 packet->dst_id_type != SILC_ID_CLIENT)
1152 if (!packet->dst_id)
1155 /* Get the route to the client */
1156 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1157 packet->dst_id_len, NULL, &idata);
1161 /* Send the private message */
1162 silc_server_send_private_message(server, dst_sock, idata->send_key,
1163 idata->hmac_send, packet);
1166 /* Received private message key packet.. This packet is never for us. It is to
1167 the client in the packet's destination ID. Sending of this sort of packet
1168 equals sending private message, ie. it is sent point to point from
1169 one client to another. */
1171 void silc_server_private_message_key(SilcServer server,
1172 SilcSocketConnection sock,
1173 SilcPacketContext *packet)
1175 SilcSocketConnection dst_sock;
1176 SilcIDListData idata;
1178 SILC_LOG_DEBUG(("Start"));
1180 if (packet->src_id_type != SILC_ID_CLIENT ||
1181 packet->dst_id_type != SILC_ID_CLIENT)
1184 if (!packet->dst_id)
1187 /* Get the route to the client */
1188 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1189 packet->dst_id_len, NULL, &idata);
1193 /* Relay the packet */
1194 silc_server_relay_packet(server, dst_sock, idata->send_key,
1195 idata->hmac_send, packet, FALSE);
1198 /* Processes incoming command reply packet. The command reply packet may
1199 be destined to one of our clients or it may directly for us. We will
1200 call the command reply routine after processing the packet. */
1202 void silc_server_command_reply(SilcServer server,
1203 SilcSocketConnection sock,
1204 SilcPacketContext *packet)
1206 SilcBuffer buffer = packet->buffer;
1207 SilcClientEntry client = NULL;
1208 SilcSocketConnection dst_sock;
1209 SilcIDListData idata;
1210 SilcClientID *id = NULL;
1212 SILC_LOG_DEBUG(("Start"));
1214 /* Source must be server or router */
1215 if (packet->src_id_type != SILC_ID_SERVER &&
1216 sock->type != SILC_SOCKET_TYPE_ROUTER)
1219 if (packet->dst_id_type == SILC_ID_CHANNEL)
1222 if (packet->dst_id_type == SILC_ID_CLIENT) {
1223 /* Destination must be one of ours */
1224 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
1227 client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
1229 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
1235 if (packet->dst_id_type == SILC_ID_SERVER) {
1236 /* For now this must be for us */
1237 if (memcmp(packet->dst_id, server->id_string, packet->dst_id_len)) {
1238 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
1243 /* Execute command reply locally for the command */
1244 silc_server_command_reply_process(server, sock, buffer);
1246 if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
1247 /* Relay the packet to the client */
1249 dst_sock = (SilcSocketConnection)client->connection;
1250 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
1251 + packet->dst_id_len + packet->padlen);
1253 silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
1254 silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
1256 idata = (SilcIDListData)client;
1258 /* Encrypt packet */
1259 silc_packet_encrypt(idata->send_key, idata->hmac_send, dst_sock->outbuf,
1262 /* Send the packet */
1263 silc_server_packet_send_real(server, dst_sock, TRUE);
1269 /* Process received channel message. The message can be originated from
1270 client or server. */
1272 void silc_server_channel_message(SilcServer server,
1273 SilcSocketConnection sock,
1274 SilcPacketContext *packet)
1276 SilcChannelEntry channel = NULL;
1277 SilcChannelID *id = NULL;
1278 void *sender = NULL;
1279 void *sender_entry = NULL;
1282 SILC_LOG_DEBUG(("Processing channel message"));
1285 if (packet->dst_id_type != SILC_ID_CHANNEL) {
1286 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1290 /* Find channel entry */
1291 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
1294 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
1296 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
1298 SILC_LOG_DEBUG(("Could not find channel"));
1303 /* See that this client is on the channel. If the original sender is
1304 not client (as it can be server as well) we don't do the check. */
1305 sender = silc_id_str2id(packet->src_id, packet->src_id_len,
1306 packet->src_id_type);
1309 if (packet->src_id_type == SILC_ID_CLIENT) {
1310 sender_entry = silc_idlist_find_client_by_id(server->local_list,
1311 sender, TRUE, NULL);
1312 if (!sender_entry) {
1314 sender_entry = silc_idlist_find_client_by_id(server->global_list,
1315 sender, TRUE, NULL);
1317 if (!sender_entry || !silc_server_client_on_channel(sender_entry,
1319 SILC_LOG_DEBUG(("Client not on channel"));
1323 /* If the packet is coming from router, but the client entry is
1324 local entry to us then some router is rerouting this to us and it is
1326 if (server->server_type == SILC_ROUTER &&
1327 sock->type == SILC_SOCKET_TYPE_ROUTER && local) {
1328 SILC_LOG_DEBUG(("Channel message rerouted to the sender, drop it"));
1333 /* Distribute the packet to our local clients. This will send the
1334 packet for further routing as well, if needed. */
1335 silc_server_packet_relay_to_channel(server, sock, channel, sender,
1336 packet->src_id_type, sender_entry,
1337 packet->buffer->data,
1338 packet->buffer->len, FALSE);
1347 /* Received channel key packet. We distribute the key to all of our locally
1348 connected clients on the channel. */
1350 void silc_server_channel_key(SilcServer server,
1351 SilcSocketConnection sock,
1352 SilcPacketContext *packet)
1354 SilcBuffer buffer = packet->buffer;
1355 SilcChannelEntry channel;
1357 if (packet->src_id_type != SILC_ID_SERVER ||
1358 (server->server_type == SILC_ROUTER &&
1359 sock->type == SILC_SOCKET_TYPE_ROUTER))
1362 /* Save the channel key */
1363 channel = silc_server_save_channel_key(server, buffer, NULL);
1367 /* Distribute the key to everybody who is on the channel. If we are router
1368 we will also send it to locally connected servers. */
1369 silc_server_send_channel_key(server, sock, channel, FALSE);
1371 if (server->server_type != SILC_BACKUP_ROUTER) {
1372 /* Distribute to local cell backup routers. */
1373 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
1374 SILC_PACKET_CHANNEL_KEY, 0,
1375 buffer->data, buffer->len, FALSE, TRUE);
1379 /* Received New Client packet and processes it. Creates Client ID for the
1380 client. Client becomes registered after calling this functions. */
1382 SilcClientEntry silc_server_new_client(SilcServer server,
1383 SilcSocketConnection sock,
1384 SilcPacketContext *packet)
1386 SilcBuffer buffer = packet->buffer;
1387 SilcClientEntry client;
1388 SilcClientID *client_id;
1390 SilcIDListData idata;
1391 char *username = NULL, *realname = NULL, *id_string;
1394 char *hostname, *nickname;
1397 SILC_LOG_DEBUG(("Creating new client"));
1399 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
1402 /* Take client entry */
1403 client = (SilcClientEntry)sock->user_data;
1404 idata = (SilcIDListData)client;
1406 /* Remove the old cache entry */
1407 if (!silc_idcache_del_by_context(server->local_list->clients, client)) {
1408 SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
1409 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1414 /* Parse incoming packet */
1415 ret = silc_buffer_unformat(buffer,
1416 SILC_STR_UI16_STRING_ALLOC(&username),
1417 SILC_STR_UI16_STRING_ALLOC(&realname),
1421 silc_free(username);
1423 silc_free(realname);
1424 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1425 "Incomplete client information");
1430 silc_free(username);
1432 silc_free(realname);
1433 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1434 "Incomplete client information");
1438 if (strlen(username) > 128)
1439 username[127] = '\0';
1441 nickname = strdup(username);
1443 /* Make sanity checks for the hostname of the client. If the hostname
1444 is provided in the `username' check that it is the same than the
1445 resolved hostname, or if not resolved the hostname that appears in
1446 the client's public key. If the hostname is not present then put
1447 it from the resolved name or from the public key. */
1448 if (strchr(username, '@')) {
1449 SilcPublicKeyIdentifier pident;
1450 int tlen = strcspn(username, "@");
1451 char *phostname = NULL;
1453 hostname = silc_calloc((strlen(username) - tlen) + 1, sizeof(char));
1454 memcpy(hostname, username + tlen + 1, strlen(username) - tlen - 1);
1456 if (strcmp(sock->hostname, sock->ip) &&
1457 strcmp(sock->hostname, hostname)) {
1458 silc_free(username);
1459 silc_free(hostname);
1461 silc_free(realname);
1462 silc_server_disconnect_remote(server, sock,
1463 "Server closed connection: "
1464 "Incomplete client information");
1468 pident = silc_pkcs_decode_identifier(client->data.public_key->identifier);
1470 phostname = strdup(pident->host);
1471 silc_pkcs_free_identifier(pident);
1474 if (!strcmp(sock->hostname, sock->ip) &&
1475 phostname && strcmp(phostname, hostname)) {
1476 silc_free(username);
1477 silc_free(hostname);
1479 silc_free(phostname);
1481 silc_free(realname);
1482 silc_server_disconnect_remote(server, sock,
1483 "Server closed connection: "
1484 "Incomplete client information");
1489 silc_free(phostname);
1491 /* The hostname is not present, add it. */
1493 /* XXX For now we cannot take the host name from the public key since
1494 they are not trusted or we cannot verify them as trusted. Just take
1495 what the resolved name or address is. */
1497 if (strcmp(sock->hostname, sock->ip)) {
1499 newusername = silc_calloc(strlen(username) +
1500 strlen(sock->hostname) + 2,
1501 sizeof(*newusername));
1502 strncat(newusername, username, strlen(username));
1503 strncat(newusername, "@", 1);
1504 strncat(newusername, sock->hostname, strlen(sock->hostname));
1505 silc_free(username);
1506 username = newusername;
1509 SilcPublicKeyIdentifier pident =
1510 silc_pkcs_decode_identifier(client->data.public_key->identifier);
1513 newusername = silc_calloc(strlen(username) +
1514 strlen(pident->host) + 2,
1515 sizeof(*newusername));
1516 strncat(newusername, username, strlen(username));
1517 strncat(newusername, "@", 1);
1518 strncat(newusername, pident->host, strlen(pident->host));
1519 silc_free(username);
1520 username = newusername;
1521 silc_pkcs_free_identifier(pident);
1527 /* Create Client ID */
1528 while (!silc_id_create_client_id(server, server->id, server->rng,
1529 server->md5hash, nickname, &client_id)) {
1531 snprintf(&nickname[strlen(nickname) - 1], 1, "%d", nickfail);
1534 /* Update client entry */
1535 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
1536 client->nickname = nickname;
1537 client->username = username;
1538 client->userinfo = realname ? realname : strdup(" ");
1539 client->id = client_id;
1540 id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
1542 /* Add the client again to the ID cache */
1543 silc_idcache_add(server->local_list->clients, client->nickname,
1544 client_id, client, FALSE);
1546 /* Notify our router about new client on the SILC network */
1547 if (!server->standalone)
1548 silc_server_send_new_id(server, (SilcSocketConnection)
1549 server->router->connection,
1550 server->server_type == SILC_ROUTER ? TRUE : FALSE,
1551 client->id, SILC_ID_CLIENT, id_len);
1553 /* Send the new client ID to the client. */
1554 id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
1555 reply = silc_buffer_alloc(2 + 2 + id_len);
1556 silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
1557 silc_buffer_format(reply,
1558 SILC_STR_UI_SHORT(SILC_ID_CLIENT),
1559 SILC_STR_UI_SHORT(id_len),
1560 SILC_STR_UI_XNSTRING(id_string, id_len),
1562 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0,
1563 reply->data, reply->len, FALSE);
1564 silc_free(id_string);
1565 silc_buffer_free(reply);
1567 /* Send some nice info to the client */
1568 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1569 ("Welcome to the SILC Network %s",
1571 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1572 ("Your host is %s, running version %s",
1573 server->config->server_info->server_name,
1575 if (server->server_type == SILC_ROUTER) {
1576 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1577 ("There are %d clients on %d servers in SILC "
1578 "Network", server->stat.clients,
1579 server->stat.servers + 1));
1580 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1581 ("There are %d clients on %d server in our cell",
1582 server->stat.cell_clients,
1583 server->stat.cell_servers + 1));
1584 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1585 ("I have %d clients, %d channels, %d servers and "
1587 server->stat.my_clients,
1588 server->stat.my_channels,
1589 server->stat.my_servers,
1590 server->stat.my_routers));
1591 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1592 ("%d server operators and %d router operators "
1594 server->stat.my_server_ops,
1595 server->stat.my_router_ops));
1597 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1598 ("I have %d clients and %d channels formed",
1599 server->stat.my_clients,
1600 server->stat.my_channels));
1601 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1602 ("%d operators online",
1603 server->stat.my_server_ops));
1605 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1606 ("Your connection is secured with %s cipher, "
1607 "key length %d bits",
1608 idata->send_key->cipher->name,
1609 idata->send_key->cipher->key_len));
1610 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1611 ("Your current nickname is %s",
1615 silc_server_send_motd(server, sock);
1620 /* Create new server. This processes received New Server packet and
1621 saves the received Server ID. The server is our locally connected
1622 server thus we save all the information and save it to local list.
1623 This funtion can be used by both normal server and router server.
1624 If normal server uses this it means that its router has connected
1625 to the server. If router uses this it means that one of the cell's
1626 servers is connected to the router. */
1628 SilcServerEntry silc_server_new_server(SilcServer server,
1629 SilcSocketConnection sock,
1630 SilcPacketContext *packet)
1632 SilcBuffer buffer = packet->buffer;
1633 SilcServerEntry new_server, server_entry;
1634 SilcServerID *server_id;
1635 SilcIDListData idata;
1636 unsigned char *server_name, *id_string;
1637 uint16 id_len, name_len;
1641 SILC_LOG_DEBUG(("Creating new server"));
1643 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
1644 sock->type != SILC_SOCKET_TYPE_ROUTER)
1647 /* Take server entry */
1648 new_server = (SilcServerEntry)sock->user_data;
1649 idata = (SilcIDListData)new_server;
1651 /* Remove the old cache entry */
1652 if (!silc_idcache_del_by_context(server->local_list->servers, new_server)) {
1653 silc_idcache_del_by_context(server->global_list->servers, new_server);
1657 /* Parse the incoming packet */
1658 ret = silc_buffer_unformat(buffer,
1659 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
1660 SILC_STR_UI16_NSTRING_ALLOC(&server_name,
1665 silc_free(id_string);
1667 silc_free(server_name);
1671 if (id_len > buffer->len) {
1672 silc_free(id_string);
1673 silc_free(server_name);
1678 server_name[255] = '\0';
1681 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
1683 silc_free(id_string);
1684 silc_free(server_name);
1687 silc_free(id_string);
1689 /* Check that we do not have this ID already */
1690 server_entry = silc_idlist_find_server_by_id(server->local_list,
1691 server_id, TRUE, NULL);
1693 silc_idcache_del_by_context(server->local_list->servers, server_entry);
1695 server_entry = silc_idlist_find_server_by_id(server->global_list,
1696 server_id, TRUE, NULL);
1698 silc_idcache_del_by_context(server->global_list->servers, server_entry);
1701 /* Update server entry */
1702 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
1703 new_server->server_name = server_name;
1704 new_server->id = server_id;
1706 SILC_LOG_DEBUG(("New server id(%s)",
1707 silc_id_render(server_id, SILC_ID_SERVER)));
1709 /* Add again the entry to the ID cache. */
1710 silc_idcache_add(local ? server->local_list->servers :
1711 server->global_list->servers, server_name, server_id,
1714 /* Distribute the information about new server in the SILC network
1715 to our router. If we are normal server we won't send anything
1716 since this connection must be our router connection. */
1717 if (server->server_type == SILC_ROUTER && !server->standalone &&
1718 server->router->connection != sock)
1719 silc_server_send_new_id(server, server->router->connection,
1720 TRUE, new_server->id, SILC_ID_SERVER,
1721 silc_id_get_len(server_id, SILC_ID_SERVER));
1723 if (server->server_type == SILC_ROUTER)
1724 server->stat.cell_servers++;
1726 /* Check whether this router connection has been replaced by an
1727 backup router. If it has been then we'll disable the server and will
1728 ignore everything it will send until the backup router resuming
1729 protocol has been completed. */
1730 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
1731 silc_server_backup_replaced_get(server, server_id, NULL)) {
1732 /* Send packet to the server indicating that it cannot use this
1733 connection as it has been replaced by backup router. */
1734 SilcBuffer packet = silc_buffer_alloc(2);
1735 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
1736 silc_buffer_format(packet,
1737 SILC_STR_UI_CHAR(SILC_SERVER_BACKUP_REPLACED),
1738 SILC_STR_UI_CHAR(0),
1740 silc_server_packet_send(server, sock,
1741 SILC_PACKET_RESUME_ROUTER, 0,
1742 packet->data, packet->len, TRUE);
1743 silc_buffer_free(packet);
1745 /* Mark the router disabled. The data sent earlier will go but nothing
1746 after this does not go to this connection. */
1747 idata->status |= SILC_IDLIST_STATUS_DISABLED;
1749 /* If it is router announce our stuff to it. */
1750 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
1751 server->server_type == SILC_ROUTER) {
1752 silc_server_announce_servers(server, FALSE, 0, sock);
1753 silc_server_announce_clients(server, 0, sock);
1754 silc_server_announce_channels(server, 0, sock);
1761 /* Processes incoming New ID packet. New ID Payload is used to distribute
1762 information about newly registered clients and servers. */
1764 static void silc_server_new_id_real(SilcServer server,
1765 SilcSocketConnection sock,
1766 SilcPacketContext *packet,
1769 SilcBuffer buffer = packet->buffer;
1771 SilcServerEntry router, server_entry;
1772 SilcSocketConnection router_sock;
1777 SILC_LOG_DEBUG(("Processing new ID"));
1779 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1780 server->server_type == SILC_SERVER ||
1781 packet->src_id_type != SILC_ID_SERVER)
1784 idp = silc_id_payload_parse(buffer);
1788 id_type = silc_id_payload_get_type(idp);
1790 /* Normal server cannot have other normal server connections */
1791 server_entry = (SilcServerEntry)sock->user_data;
1792 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER &&
1793 server_entry->server_type == SILC_SERVER)
1796 id = silc_id_payload_get_id(idp);
1800 /* If the packet is coming from server then use the sender as the
1801 origin of the the packet. If it came from router then check the real
1802 sender of the packet and use that as the origin. */
1803 if (sock->type == SILC_SOCKET_TYPE_SERVER) {
1804 id_list = server->local_list;
1806 router = sock->user_data;
1808 /* If the sender is backup router and ID is server (and we are not
1809 backup router) then switch the entry to global list. */
1810 if (server_entry->server_type == SILC_BACKUP_ROUTER &&
1811 id_type == SILC_ID_SERVER &&
1812 server->id_entry->server_type != SILC_BACKUP_ROUTER) {
1813 id_list = server->global_list;
1814 router_sock = server->router ? server->router->connection : sock;
1817 void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1818 packet->src_id_type);
1819 router = silc_idlist_find_server_by_id(server->global_list,
1820 sender_id, TRUE, NULL);
1822 router = silc_idlist_find_server_by_id(server->local_list,
1823 sender_id, TRUE, NULL);
1824 silc_free(sender_id);
1828 id_list = server->global_list;
1832 case SILC_ID_CLIENT:
1834 SilcClientEntry entry;
1836 /* Check that we do not have this client already */
1837 entry = silc_idlist_find_client_by_id(server->global_list,
1838 id, server->server_type,
1841 entry = silc_idlist_find_client_by_id(server->local_list,
1842 id, server->server_type,
1845 SILC_LOG_DEBUG(("Ignoring client that we already have"));
1849 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
1850 silc_id_render(id, SILC_ID_CLIENT),
1851 sock->type == SILC_SOCKET_TYPE_SERVER ?
1852 "Server" : "Router", sock->hostname));
1854 /* As a router we keep information of all global information in our
1855 global list. Cell wide information however is kept in the local
1857 entry = silc_idlist_add_client(id_list, NULL, NULL, NULL,
1860 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
1862 /* Inform the sender that the ID is not usable */
1863 silc_server_send_notify_signoff(server, sock, FALSE, id, NULL);
1866 entry->nickname = NULL;
1867 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
1869 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1870 server->stat.cell_clients++;
1871 server->stat.clients++;
1875 case SILC_ID_SERVER:
1877 SilcServerEntry entry;
1879 /* If the ID is mine, ignore it. */
1880 if (SILC_ID_SERVER_COMPARE(id, server->id)) {
1881 SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
1885 /* If the ID is the sender's ID, ignore it (we have it already) */
1886 if (SILC_ID_SERVER_COMPARE(id, router->id)) {
1887 SILC_LOG_DEBUG(("Ignoring sender's own ID"));
1891 /* Check that we do not have this server already */
1892 entry = silc_idlist_find_server_by_id(server->global_list,
1893 id, server->server_type,
1896 entry = silc_idlist_find_server_by_id(server->local_list,
1897 id, server->server_type,
1900 SILC_LOG_DEBUG(("Ignoring server that we already have"));
1904 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
1905 silc_id_render(id, SILC_ID_SERVER),
1906 sock->type == SILC_SOCKET_TYPE_SERVER ?
1907 "Server" : "Router", sock->hostname));
1909 /* As a router we keep information of all global information in our
1910 global list. Cell wide information however is kept in the local
1912 entry = silc_idlist_add_server(id_list, NULL, 0, id, router,
1915 SILC_LOG_ERROR(("Could not add new server to the ID Cache"));
1918 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
1920 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1921 server->stat.cell_servers++;
1922 server->stat.servers++;
1926 case SILC_ID_CHANNEL:
1927 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
1936 /* If the sender of this packet is server and we are router we need to
1937 broadcast this packet to other routers in the network. */
1938 if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
1939 sock->type == SILC_SOCKET_TYPE_SERVER &&
1940 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1941 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
1942 silc_server_packet_send(server, server->router->connection,
1944 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1945 buffer->data, buffer->len, FALSE);
1946 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
1947 packet->type, packet->flags,
1948 packet->buffer->data, packet->buffer->len,
1953 silc_id_payload_free(idp);
1957 /* Processes incoming New ID packet. New ID Payload is used to distribute
1958 information about newly registered clients and servers. */
1960 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
1961 SilcPacketContext *packet)
1963 silc_server_new_id_real(server, sock, packet, TRUE);
1966 /* Receoved New Id List packet, list of New ID payloads inside one
1967 packet. Process the New ID payloads one by one. */
1969 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
1970 SilcPacketContext *packet)
1972 SilcPacketContext *new_id;
1976 SILC_LOG_DEBUG(("Processing New ID List"));
1978 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1979 packet->src_id_type != SILC_ID_SERVER)
1982 /* If the sender of this packet is server and we are router we need to
1983 broadcast this packet to other routers in the network. Broadcast
1984 this list packet instead of multiple New ID packets. */
1985 if (!server->standalone && server->server_type == SILC_ROUTER &&
1986 sock->type == SILC_SOCKET_TYPE_SERVER &&
1987 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1988 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
1989 silc_server_packet_send(server, server->router->connection,
1991 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1992 packet->buffer->data, packet->buffer->len, FALSE);
1993 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
1994 packet->type, packet->flags,
1995 packet->buffer->data, packet->buffer->len,
1999 /* Make copy of the original packet context, except for the actual
2000 data buffer, which we will here now fetch from the original buffer. */
2001 new_id = silc_packet_context_alloc();
2002 new_id->type = SILC_PACKET_NEW_ID;
2003 new_id->flags = packet->flags;
2004 new_id->src_id = packet->src_id;
2005 new_id->src_id_len = packet->src_id_len;
2006 new_id->src_id_type = packet->src_id_type;
2007 new_id->dst_id = packet->dst_id;
2008 new_id->dst_id_len = packet->dst_id_len;
2009 new_id->dst_id_type = packet->dst_id_type;
2011 idp = silc_buffer_alloc(256);
2012 new_id->buffer = idp;
2014 while (packet->buffer->len) {
2015 SILC_GET16_MSB(id_len, packet->buffer->data + 2);
2016 if ((id_len > packet->buffer->len) ||
2017 (id_len > idp->truelen))
2020 silc_buffer_pull_tail(idp, 4 + id_len);
2021 silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
2023 /* Process the New ID */
2024 silc_server_new_id_real(server, sock, new_id, FALSE);
2026 silc_buffer_push_tail(idp, 4 + id_len);
2027 silc_buffer_pull(packet->buffer, 4 + id_len);
2030 silc_buffer_free(idp);
2034 /* Received New Channel packet. Information about new channels in the
2035 network are distributed using this packet. Save the information about
2036 the new channel. This usually comes from router but also normal server
2037 can send this to notify channels it has when it connects to us. */
2039 void silc_server_new_channel(SilcServer server,
2040 SilcSocketConnection sock,
2041 SilcPacketContext *packet)
2043 SilcChannelPayload payload;
2044 SilcChannelID *channel_id;
2050 SilcServerEntry server_entry;
2051 SilcChannelEntry channel;
2053 SILC_LOG_DEBUG(("Processing New Channel"));
2055 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2056 packet->src_id_type != SILC_ID_SERVER ||
2057 server->server_type == SILC_SERVER)
2060 /* Parse the channel payload */
2061 payload = silc_channel_payload_parse(packet->buffer);
2065 /* Get the channel ID */
2066 channel_id = silc_channel_get_id_parse(payload);
2068 silc_channel_payload_free(payload);
2072 channel_name = silc_channel_get_name(payload, &name_len);
2074 channel_name[255] = '\0';
2076 id = silc_channel_get_id(payload, &id_len);
2078 server_entry = (SilcServerEntry)sock->user_data;
2080 if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
2081 /* Add the channel to global list as it is coming from router. It
2082 cannot be our own channel as it is coming from router. */
2084 /* Check that we don't already have this channel */
2085 channel = silc_idlist_find_channel_by_name(server->local_list,
2086 channel_name, NULL);
2088 channel = silc_idlist_find_channel_by_name(server->global_list,
2089 channel_name, NULL);
2091 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
2092 silc_id_render(channel_id, SILC_ID_CHANNEL),
2095 silc_idlist_add_channel(server->global_list, strdup(channel_name),
2096 0, channel_id, sock->user_data, NULL, NULL);
2097 server->stat.channels++;
2100 /* The channel is coming from our server, thus it is in our cell
2101 we will add it to our local list. */
2104 SILC_LOG_DEBUG(("Channel id(%s) from [Server] %s",
2105 silc_id_render(channel_id, SILC_ID_CHANNEL),
2108 /* Check that we don't already have this channel */
2109 channel = silc_idlist_find_channel_by_name(server->local_list,
2110 channel_name, NULL);
2112 channel = silc_idlist_find_channel_by_name(server->global_list,
2113 channel_name, NULL);
2115 /* If the channel does not exist, then create it. This creates a new
2116 key to the channel as well that we will send to the server. */
2118 /* The protocol says that the Channel ID's IP address must be based
2119 on the router's IP address. Check whether the ID is based in our
2120 IP and if it is not then create a new ID and enforce the server
2121 to switch the ID. */
2122 if (server_entry->server_type != SILC_BACKUP_ROUTER &&
2123 !SILC_ID_COMPARE(channel_id, server->id, server->id->ip.data_len)) {
2125 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2127 if (silc_id_create_channel_id(server, server->id, server->rng, &tmp)) {
2128 silc_server_send_notify_channel_change(server, sock, FALSE,
2130 silc_free(channel_id);
2135 /* Create the channel with the provided Channel ID */
2136 channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
2140 silc_channel_payload_free(payload);
2141 silc_free(channel_id);
2145 /* Get the mode and set it to the channel */
2146 channel->mode = silc_channel_get_mode(payload);
2148 /* Send the new channel key to the server */
2149 chk = silc_channel_key_payload_encode(id_len, id,
2150 strlen(channel->channel_key->
2152 channel->channel_key->cipher->name,
2153 channel->key_len / 8,
2155 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
2156 chk->data, chk->len, FALSE);
2157 silc_buffer_free(chk);
2160 /* The channel exist by that name, check whether the ID's match.
2161 If they don't then we'll force the server to use the ID we have.
2162 We also create a new key for the channel. */
2163 SilcBuffer users = NULL, users_modes = NULL;
2166 channel->id = silc_id_dup(channel_id, SILC_ID_CHANNEL);
2168 if (!SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
2169 /* They don't match, send CHANNEL_CHANGE notify to the server to
2170 force the ID change. */
2171 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2172 silc_server_send_notify_channel_change(server, sock, FALSE,
2173 channel_id, channel->id);
2176 /* If the mode is different from what we have then enforce the
2178 mode = silc_channel_get_mode(payload);
2179 if (channel->mode != mode) {
2180 SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
2181 silc_server_send_notify_cmode(server, sock, FALSE, channel,
2182 channel->mode, server->id,
2184 channel->cipher, channel->hmac_name);
2187 /* Create new key for the channel and send it to the server and
2188 everybody else possibly on the channel. */
2190 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
2191 if (!silc_server_create_channel_key(server, channel, 0))
2194 /* Send to the channel */
2195 silc_server_send_channel_key(server, sock, channel, FALSE);
2196 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2197 id_len = SILC_ID_CHANNEL_LEN;
2199 /* Send to the server */
2200 chk = silc_channel_key_payload_encode(id_len, id,
2201 strlen(channel->channel_key->
2203 channel->channel_key->
2205 channel->key_len / 8,
2207 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
2208 chk->data, chk->len, FALSE);
2209 silc_buffer_free(chk);
2213 silc_free(channel_id);
2215 /* Since the channel is coming from server and we also know about it
2216 then send the JOIN notify to the server so that it see's our
2217 users on the channel "joining" the channel. */
2218 silc_server_announce_get_channel_users(server, channel, &users,
2221 silc_buffer_push(users, users->data - users->head);
2222 silc_server_packet_send(server, sock,
2223 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2224 users->data, users->len, FALSE);
2225 silc_buffer_free(users);
2228 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
2229 silc_server_packet_send_dest(server, sock,
2230 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2231 channel->id, SILC_ID_CHANNEL,
2233 users_modes->len, FALSE);
2234 silc_buffer_free(users_modes);
2239 silc_channel_payload_free(payload);
2242 /* Received New Channel List packet, list of New Channel List payloads inside
2243 one packet. Process the New Channel payloads one by one. */
2245 void silc_server_new_channel_list(SilcServer server,
2246 SilcSocketConnection sock,
2247 SilcPacketContext *packet)
2249 SilcPacketContext *new;
2253 SILC_LOG_DEBUG(("Processing New Channel List"));
2255 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2256 packet->src_id_type != SILC_ID_SERVER ||
2257 server->server_type == SILC_SERVER)
2260 /* If the sender of this packet is server and we are router we need to
2261 broadcast this packet to other routers in the network. Broadcast
2262 this list packet instead of multiple New Channel packets. */
2263 if (!server->standalone && server->server_type == SILC_ROUTER &&
2264 sock->type == SILC_SOCKET_TYPE_SERVER &&
2265 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2266 SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
2267 silc_server_packet_send(server, server->router->connection,
2269 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2270 packet->buffer->data, packet->buffer->len, FALSE);
2271 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
2272 packet->type, packet->flags,
2273 packet->buffer->data, packet->buffer->len,
2277 /* Make copy of the original packet context, except for the actual
2278 data buffer, which we will here now fetch from the original buffer. */
2279 new = silc_packet_context_alloc();
2280 new->type = SILC_PACKET_NEW_CHANNEL;
2281 new->flags = packet->flags;
2282 new->src_id = packet->src_id;
2283 new->src_id_len = packet->src_id_len;
2284 new->src_id_type = packet->src_id_type;
2285 new->dst_id = packet->dst_id;
2286 new->dst_id_len = packet->dst_id_len;
2287 new->dst_id_type = packet->dst_id_type;
2289 buffer = silc_buffer_alloc(512);
2290 new->buffer = buffer;
2292 while (packet->buffer->len) {
2293 SILC_GET16_MSB(len1, packet->buffer->data);
2294 if ((len1 > packet->buffer->len) ||
2295 (len1 > buffer->truelen))
2298 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
2299 if ((len2 > packet->buffer->len) ||
2300 (len2 > buffer->truelen))
2303 silc_buffer_pull_tail(buffer, 8 + len1 + len2);
2304 silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
2306 /* Process the New Channel */
2307 silc_server_new_channel(server, sock, new);
2309 silc_buffer_push_tail(buffer, 8 + len1 + len2);
2310 silc_buffer_pull(packet->buffer, 8 + len1 + len2);
2313 silc_buffer_free(buffer);
2317 /* Received key agreement packet. This packet is never for us. It is to
2318 the client in the packet's destination ID. Sending of this sort of packet
2319 equals sending private message, ie. it is sent point to point from
2320 one client to another. */
2322 void silc_server_key_agreement(SilcServer server,
2323 SilcSocketConnection sock,
2324 SilcPacketContext *packet)
2326 SilcSocketConnection dst_sock;
2327 SilcIDListData idata;
2329 SILC_LOG_DEBUG(("Start"));
2331 if (packet->src_id_type != SILC_ID_CLIENT ||
2332 packet->dst_id_type != SILC_ID_CLIENT)
2335 if (!packet->dst_id)
2338 /* Get the route to the client */
2339 dst_sock = silc_server_get_client_route(server, packet->dst_id,
2340 packet->dst_id_len, NULL, &idata);
2344 /* Relay the packet */
2345 silc_server_relay_packet(server, dst_sock, idata->send_key,
2346 idata->hmac_send, packet, FALSE);
2349 /* Received connection auth request packet that is used during connection
2350 phase to resolve the mandatory authentication method. This packet can
2351 actually be received at anytime but usually it is used only during
2352 the connection authentication phase. Now, protocol says that this packet
2353 can come from client or server, however, we support only this coming
2354 from client and expect that server always knows what authentication
2357 void silc_server_connection_auth_request(SilcServer server,
2358 SilcSocketConnection sock,
2359 SilcPacketContext *packet)
2361 SilcServerConfigSectionClientConnection *client = NULL;
2364 SilcAuthMethod auth_meth;
2366 SILC_LOG_DEBUG(("Start"));
2368 if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT)
2371 /* Parse the payload */
2372 ret = silc_buffer_unformat(packet->buffer,
2373 SILC_STR_UI_SHORT(&conn_type),
2374 SILC_STR_UI_SHORT(NULL),
2379 if (conn_type != SILC_SOCKET_TYPE_CLIENT)
2382 /* Get the authentication method for the client */
2383 auth_meth = SILC_AUTH_NONE;
2384 port = server->sockets[server->sock]->port; /* Listenning port */
2385 client = silc_server_config_find_client_conn(server->config,
2389 client = silc_server_config_find_client_conn(server->config,
2393 auth_meth = client->auth_meth;
2395 /* Send it back to the client */
2396 silc_server_send_connection_auth_request(server, sock,
2401 /* Received REKEY packet. The sender of the packet wants to regenerate
2402 its session keys. This starts the REKEY protocol. */
2404 void silc_server_rekey(SilcServer server,
2405 SilcSocketConnection sock,
2406 SilcPacketContext *packet)
2408 SilcProtocol protocol;
2409 SilcServerRekeyInternalContext *proto_ctx;
2410 SilcIDListData idata = (SilcIDListData)sock->user_data;
2412 SILC_LOG_DEBUG(("Start"));
2414 /* Allocate internal protocol context. This is sent as context
2416 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
2417 proto_ctx->server = (void *)server;
2418 proto_ctx->sock = sock;
2419 proto_ctx->responder = TRUE;
2420 proto_ctx->pfs = idata->rekey->pfs;
2422 /* Perform rekey protocol. Will call the final callback after the
2423 protocol is over. */
2424 silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
2425 &protocol, proto_ctx, silc_server_rekey_final);
2426 sock->protocol = protocol;
2428 if (proto_ctx->pfs == FALSE)
2429 /* Run the protocol */
2430 silc_protocol_execute(protocol, server->schedule, 0, 0);