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;
1281 SILC_LOG_DEBUG(("Processing channel message"));
1284 if (packet->dst_id_type != SILC_ID_CHANNEL) {
1285 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1289 /* Find channel entry */
1290 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
1293 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
1295 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
1297 SILC_LOG_DEBUG(("Could not find channel"));
1302 /* See that this client is on the channel. If the original sender is
1303 not client (as it can be server as well) we don't do the check. */
1304 sender = silc_id_str2id(packet->src_id, packet->src_id_len,
1305 packet->src_id_type);
1308 if (packet->src_id_type == SILC_ID_CLIENT) {
1309 sender_entry = silc_idlist_find_client_by_id(server->local_list,
1310 sender, TRUE, NULL);
1312 sender_entry = silc_idlist_find_client_by_id(server->global_list,
1313 sender, TRUE, NULL);
1314 if (!sender_entry || !silc_server_client_on_channel(sender_entry,
1316 SILC_LOG_DEBUG(("Client not on channel"));
1321 /* Distribute the packet to our local clients. This will send the
1322 packet for further routing as well, if needed. */
1323 silc_server_packet_relay_to_channel(server, sock, channel, sender,
1324 packet->src_id_type, sender_entry,
1325 packet->buffer->data,
1326 packet->buffer->len, FALSE);
1335 /* Received channel key packet. We distribute the key to all of our locally
1336 connected clients on the channel. */
1338 void silc_server_channel_key(SilcServer server,
1339 SilcSocketConnection sock,
1340 SilcPacketContext *packet)
1342 SilcBuffer buffer = packet->buffer;
1343 SilcChannelEntry channel;
1345 if (packet->src_id_type != SILC_ID_SERVER ||
1346 (server->server_type == SILC_ROUTER &&
1347 sock->type == SILC_SOCKET_TYPE_ROUTER))
1350 /* Save the channel key */
1351 channel = silc_server_save_channel_key(server, buffer, NULL);
1355 /* Distribute the key to everybody who is on the channel. If we are router
1356 we will also send it to locally connected servers. */
1357 silc_server_send_channel_key(server, sock, channel, FALSE);
1359 if (server->server_type != SILC_BACKUP_ROUTER) {
1360 /* Distribute to local cell backup routers. */
1361 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
1362 SILC_PACKET_CHANNEL_KEY, 0,
1363 buffer->data, buffer->len, FALSE, TRUE);
1367 /* Received New Client packet and processes it. Creates Client ID for the
1368 client. Client becomes registered after calling this functions. */
1370 SilcClientEntry silc_server_new_client(SilcServer server,
1371 SilcSocketConnection sock,
1372 SilcPacketContext *packet)
1374 SilcBuffer buffer = packet->buffer;
1375 SilcClientEntry client;
1376 SilcClientID *client_id;
1378 SilcIDListData idata;
1379 char *username = NULL, *realname = NULL, *id_string;
1382 char *hostname, *nickname;
1385 SILC_LOG_DEBUG(("Creating new client"));
1387 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
1390 /* Take client entry */
1391 client = (SilcClientEntry)sock->user_data;
1392 idata = (SilcIDListData)client;
1394 /* Remove the old cache entry */
1395 if (!silc_idcache_del_by_context(server->local_list->clients, client)) {
1396 SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
1397 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1402 /* Parse incoming packet */
1403 ret = silc_buffer_unformat(buffer,
1404 SILC_STR_UI16_STRING_ALLOC(&username),
1405 SILC_STR_UI16_STRING_ALLOC(&realname),
1409 silc_free(username);
1411 silc_free(realname);
1412 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1413 "Incomplete client information");
1418 silc_free(username);
1420 silc_free(realname);
1421 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1422 "Incomplete client information");
1426 if (strlen(username) > 128)
1427 username[127] = '\0';
1429 nickname = strdup(username);
1431 /* Make sanity checks for the hostname of the client. If the hostname
1432 is provided in the `username' check that it is the same than the
1433 resolved hostname, or if not resolved the hostname that appears in
1434 the client's public key. If the hostname is not present then put
1435 it from the resolved name or from the public key. */
1436 if (strchr(username, '@')) {
1437 SilcPublicKeyIdentifier pident;
1438 int tlen = strcspn(username, "@");
1439 char *phostname = NULL;
1441 hostname = silc_calloc((strlen(username) - tlen) + 1, sizeof(char));
1442 memcpy(hostname, username + tlen + 1, strlen(username) - tlen - 1);
1444 if (strcmp(sock->hostname, sock->ip) &&
1445 strcmp(sock->hostname, hostname)) {
1446 silc_free(username);
1447 silc_free(hostname);
1449 silc_free(realname);
1450 silc_server_disconnect_remote(server, sock,
1451 "Server closed connection: "
1452 "Incomplete client information");
1456 pident = silc_pkcs_decode_identifier(client->data.public_key->identifier);
1458 phostname = strdup(pident->host);
1459 silc_pkcs_free_identifier(pident);
1462 if (!strcmp(sock->hostname, sock->ip) &&
1463 phostname && strcmp(phostname, hostname)) {
1464 silc_free(username);
1465 silc_free(hostname);
1467 silc_free(phostname);
1469 silc_free(realname);
1470 silc_server_disconnect_remote(server, sock,
1471 "Server closed connection: "
1472 "Incomplete client information");
1477 silc_free(phostname);
1479 /* The hostname is not present, add it. */
1481 /* XXX For now we cannot take the host name from the public key since
1482 they are not trusted or we cannot verify them as trusted. Just take
1483 what the resolved name or address is. */
1485 if (strcmp(sock->hostname, sock->ip)) {
1487 newusername = silc_calloc(strlen(username) +
1488 strlen(sock->hostname) + 2,
1489 sizeof(*newusername));
1490 strncat(newusername, username, strlen(username));
1491 strncat(newusername, "@", 1);
1492 strncat(newusername, sock->hostname, strlen(sock->hostname));
1493 silc_free(username);
1494 username = newusername;
1497 SilcPublicKeyIdentifier pident =
1498 silc_pkcs_decode_identifier(client->data.public_key->identifier);
1501 newusername = silc_calloc(strlen(username) +
1502 strlen(pident->host) + 2,
1503 sizeof(*newusername));
1504 strncat(newusername, username, strlen(username));
1505 strncat(newusername, "@", 1);
1506 strncat(newusername, pident->host, strlen(pident->host));
1507 silc_free(username);
1508 username = newusername;
1509 silc_pkcs_free_identifier(pident);
1515 /* Create Client ID */
1516 while (!silc_id_create_client_id(server, server->id, server->rng,
1517 server->md5hash, nickname, &client_id)) {
1519 snprintf(&nickname[strlen(nickname) - 1], 1, "%d", nickfail);
1522 /* Update client entry */
1523 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
1524 client->nickname = nickname;
1525 client->username = username;
1526 client->userinfo = realname ? realname : strdup(" ");
1527 client->id = client_id;
1528 id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
1530 /* Add the client again to the ID cache */
1531 silc_idcache_add(server->local_list->clients, client->nickname,
1532 client_id, client, FALSE);
1534 /* Notify our router about new client on the SILC network */
1535 if (!server->standalone)
1536 silc_server_send_new_id(server, (SilcSocketConnection)
1537 server->router->connection,
1538 server->server_type == SILC_ROUTER ? TRUE : FALSE,
1539 client->id, SILC_ID_CLIENT, id_len);
1541 /* Send the new client ID to the client. */
1542 id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
1543 reply = silc_buffer_alloc(2 + 2 + id_len);
1544 silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
1545 silc_buffer_format(reply,
1546 SILC_STR_UI_SHORT(SILC_ID_CLIENT),
1547 SILC_STR_UI_SHORT(id_len),
1548 SILC_STR_UI_XNSTRING(id_string, id_len),
1550 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0,
1551 reply->data, reply->len, FALSE);
1552 silc_free(id_string);
1553 silc_buffer_free(reply);
1555 /* Send some nice info to the client */
1556 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1557 ("Welcome to the SILC Network %s",
1559 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1560 ("Your host is %s, running version %s",
1561 server->config->server_info->server_name,
1563 if (server->server_type == SILC_ROUTER) {
1564 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1565 ("There are %d clients on %d servers in SILC "
1566 "Network", server->stat.clients,
1567 server->stat.servers + 1));
1568 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1569 ("There are %d clients on %d server in our cell",
1570 server->stat.cell_clients,
1571 server->stat.cell_servers + 1));
1572 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1573 ("I have %d clients, %d channels, %d servers and "
1575 server->stat.my_clients,
1576 server->stat.my_channels,
1577 server->stat.my_servers,
1578 server->stat.my_routers));
1579 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1580 ("%d server operators and %d router operators "
1582 server->stat.my_server_ops,
1583 server->stat.my_router_ops));
1585 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1586 ("I have %d clients and %d channels formed",
1587 server->stat.my_clients,
1588 server->stat.my_channels));
1589 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1590 ("%d operators online",
1591 server->stat.my_server_ops));
1593 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1594 ("Your connection is secured with %s cipher, "
1595 "key length %d bits",
1596 idata->send_key->cipher->name,
1597 idata->send_key->cipher->key_len));
1598 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1599 ("Your current nickname is %s",
1603 silc_server_send_motd(server, sock);
1608 /* Create new server. This processes received New Server packet and
1609 saves the received Server ID. The server is our locally connected
1610 server thus we save all the information and save it to local list.
1611 This funtion can be used by both normal server and router server.
1612 If normal server uses this it means that its router has connected
1613 to the server. If router uses this it means that one of the cell's
1614 servers is connected to the router. */
1616 SilcServerEntry silc_server_new_server(SilcServer server,
1617 SilcSocketConnection sock,
1618 SilcPacketContext *packet)
1620 SilcBuffer buffer = packet->buffer;
1621 SilcServerEntry new_server, server_entry;
1622 SilcServerID *server_id;
1623 SilcIDListData idata;
1624 unsigned char *server_name, *id_string;
1625 uint16 id_len, name_len;
1628 SILC_LOG_DEBUG(("Creating new server"));
1630 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
1631 sock->type != SILC_SOCKET_TYPE_ROUTER)
1634 /* Take server entry */
1635 new_server = (SilcServerEntry)sock->user_data;
1636 idata = (SilcIDListData)new_server;
1638 /* Remove the old cache entry */
1639 silc_idcache_del_by_context(server->local_list->servers, new_server);
1641 /* Parse the incoming packet */
1642 ret = silc_buffer_unformat(buffer,
1643 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
1644 SILC_STR_UI16_NSTRING_ALLOC(&server_name,
1649 silc_free(id_string);
1651 silc_free(server_name);
1655 if (id_len > buffer->len) {
1656 silc_free(id_string);
1657 silc_free(server_name);
1662 server_name[255] = '\0';
1665 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
1667 silc_free(id_string);
1668 silc_free(server_name);
1671 silc_free(id_string);
1673 /* Check that we do not have this ID already */
1674 server_entry = silc_idlist_find_server_by_id(server->local_list,
1675 server_id, TRUE, NULL);
1677 silc_idcache_del_by_context(server->local_list->servers, server_entry);
1679 server_entry = silc_idlist_find_server_by_id(server->global_list,
1680 server_id, TRUE, NULL);
1682 silc_idcache_del_by_context(server->global_list->servers, server_entry);
1685 /* Update server entry */
1686 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
1687 new_server->server_name = server_name;
1688 new_server->id = server_id;
1690 SILC_LOG_DEBUG(("New server id(%s)",
1691 silc_id_render(server_id, SILC_ID_SERVER)));
1693 /* Add again the entry to the ID cache. */
1694 silc_idcache_add(server->local_list->servers, server_name, server_id,
1697 /* Distribute the information about new server in the SILC network
1698 to our router. If we are normal server we won't send anything
1699 since this connection must be our router connection. */
1700 if (server->server_type == SILC_ROUTER && !server->standalone &&
1701 server->router->connection != sock)
1702 silc_server_send_new_id(server, server->router->connection,
1703 TRUE, new_server->id, SILC_ID_SERVER,
1704 silc_id_get_len(server_id, SILC_ID_SERVER));
1706 if (server->server_type == SILC_ROUTER)
1707 server->stat.cell_servers++;
1709 /* Check whether this router connection has been replaced by an
1710 backup router. If it has been then we'll disable the server and will
1711 ignore everything it will send until the backup router resuming
1712 protocol has been completed. */
1713 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
1714 silc_server_backup_replaced_get(server, server_id, NULL)) {
1715 /* Send packet to the server indicating that it cannot use this
1716 connection as it has been replaced by backup router. */
1717 SilcBuffer packet = silc_buffer_alloc(2);
1718 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
1719 silc_buffer_format(packet,
1720 SILC_STR_UI_CHAR(SILC_SERVER_BACKUP_REPLACED),
1721 SILC_STR_UI_CHAR(0),
1723 silc_server_packet_send(server, sock,
1724 SILC_PACKET_RESUME_ROUTER, 0,
1725 packet->data, packet->len, TRUE);
1726 silc_buffer_free(packet);
1728 /* Mark the router disabled. The data sent earlier will go but nothing
1729 after this does not go to this connection. */
1730 idata->status |= SILC_IDLIST_STATUS_DISABLED;
1736 /* Processes incoming New ID packet. New ID Payload is used to distribute
1737 information about newly registered clients and servers. */
1739 static void silc_server_new_id_real(SilcServer server,
1740 SilcSocketConnection sock,
1741 SilcPacketContext *packet,
1744 SilcBuffer buffer = packet->buffer;
1746 SilcServerEntry router;
1747 SilcSocketConnection router_sock;
1752 SILC_LOG_DEBUG(("Processing new ID"));
1754 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1755 server->server_type == SILC_SERVER ||
1756 packet->src_id_type != SILC_ID_SERVER)
1759 idp = silc_id_payload_parse(buffer);
1763 id_type = silc_id_payload_get_type(idp);
1765 /* Normal server cannot have other normal server connections */
1766 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
1769 id = silc_id_payload_get_id(idp);
1773 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1774 id_list = server->local_list;
1776 id_list = server->global_list;
1778 /* If the packet is coming from server then use the sender as the
1779 origin of the the packet. If it came from router then check the real
1780 sender of the packet and use that as the origin. */
1781 if (sock->type == SILC_SOCKET_TYPE_SERVER) {
1783 router = sock->user_data;
1785 void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1786 packet->src_id_type);
1787 router = silc_idlist_find_server_by_id(server->global_list,
1788 sender_id, TRUE, NULL);
1790 router = silc_idlist_find_server_by_id(server->local_list,
1791 sender_id, TRUE, NULL);
1792 silc_free(sender_id);
1799 case SILC_ID_CLIENT:
1801 SilcClientEntry entry;
1803 /* Check that we do not have this client already */
1804 entry = silc_idlist_find_client_by_id(server->global_list,
1805 id, server->server_type,
1808 entry = silc_idlist_find_client_by_id(server->local_list,
1809 id, server->server_type,
1812 SILC_LOG_DEBUG(("Ignoring client that we already have"));
1816 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
1817 silc_id_render(id, SILC_ID_CLIENT),
1818 sock->type == SILC_SOCKET_TYPE_SERVER ?
1819 "Server" : "Router", sock->hostname));
1821 /* As a router we keep information of all global information in our
1822 global list. Cell wide information however is kept in the local
1824 entry = silc_idlist_add_client(id_list, NULL, NULL, NULL,
1827 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
1829 /* Inform the sender that the ID is not usable */
1830 silc_server_send_notify_signoff(server, sock, FALSE, id, NULL);
1833 entry->nickname = NULL;
1834 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
1836 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1837 server->stat.cell_clients++;
1838 server->stat.clients++;
1842 case SILC_ID_SERVER:
1844 SilcServerEntry entry;
1846 /* If the ID is mine, ignore it. */
1847 if (SILC_ID_SERVER_COMPARE(id, server->id)) {
1848 SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
1852 /* If the ID is the sender's ID, ignore it (we have it already) */
1853 if (SILC_ID_SERVER_COMPARE(id, router->id)) {
1854 SILC_LOG_DEBUG(("Ignoring sender's own ID"));
1858 /* Check that we do not have this server already */
1859 entry = silc_idlist_find_server_by_id(server->global_list,
1860 id, server->server_type,
1863 entry = silc_idlist_find_server_by_id(server->local_list,
1864 id, server->server_type,
1867 SILC_LOG_DEBUG(("Ignoring server that we already have"));
1871 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
1872 silc_id_render(id, SILC_ID_SERVER),
1873 sock->type == SILC_SOCKET_TYPE_SERVER ?
1874 "Server" : "Router", sock->hostname));
1876 /* As a router we keep information of all global information in our
1877 global list. Cell wide information however is kept in the local
1879 entry = silc_idlist_add_server(id_list, NULL, 0, id, router,
1882 SILC_LOG_ERROR(("Could not add new server to the ID Cache"));
1885 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
1887 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1888 server->stat.cell_servers++;
1889 server->stat.servers++;
1893 case SILC_ID_CHANNEL:
1894 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
1903 /* If the sender of this packet is server and we are router we need to
1904 broadcast this packet to other routers in the network. */
1905 if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
1906 sock->type == SILC_SOCKET_TYPE_SERVER &&
1907 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1908 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
1909 silc_server_packet_send(server, server->router->connection,
1911 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1912 buffer->data, buffer->len, FALSE);
1913 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
1914 packet->type, packet->flags,
1915 packet->buffer->data, packet->buffer->len,
1920 silc_id_payload_free(idp);
1924 /* Processes incoming New ID packet. New ID Payload is used to distribute
1925 information about newly registered clients and servers. */
1927 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
1928 SilcPacketContext *packet)
1930 silc_server_new_id_real(server, sock, packet, TRUE);
1933 /* Receoved New Id List packet, list of New ID payloads inside one
1934 packet. Process the New ID payloads one by one. */
1936 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
1937 SilcPacketContext *packet)
1939 SilcPacketContext *new_id;
1943 SILC_LOG_DEBUG(("Processing New ID List"));
1945 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1946 packet->src_id_type != SILC_ID_SERVER)
1949 /* If the sender of this packet is server and we are router we need to
1950 broadcast this packet to other routers in the network. Broadcast
1951 this list packet instead of multiple New ID packets. */
1952 if (!server->standalone && server->server_type == SILC_ROUTER &&
1953 sock->type == SILC_SOCKET_TYPE_SERVER &&
1954 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1955 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
1956 silc_server_packet_send(server, server->router->connection,
1958 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1959 packet->buffer->data, packet->buffer->len, FALSE);
1960 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
1961 packet->type, packet->flags,
1962 packet->buffer->data, packet->buffer->len,
1966 /* Make copy of the original packet context, except for the actual
1967 data buffer, which we will here now fetch from the original buffer. */
1968 new_id = silc_packet_context_alloc();
1969 new_id->type = SILC_PACKET_NEW_ID;
1970 new_id->flags = packet->flags;
1971 new_id->src_id = packet->src_id;
1972 new_id->src_id_len = packet->src_id_len;
1973 new_id->src_id_type = packet->src_id_type;
1974 new_id->dst_id = packet->dst_id;
1975 new_id->dst_id_len = packet->dst_id_len;
1976 new_id->dst_id_type = packet->dst_id_type;
1978 idp = silc_buffer_alloc(256);
1979 new_id->buffer = idp;
1981 while (packet->buffer->len) {
1982 SILC_GET16_MSB(id_len, packet->buffer->data + 2);
1983 if ((id_len > packet->buffer->len) ||
1984 (id_len > idp->truelen))
1987 silc_buffer_pull_tail(idp, 4 + id_len);
1988 silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
1990 /* Process the New ID */
1991 silc_server_new_id_real(server, sock, new_id, FALSE);
1993 silc_buffer_push_tail(idp, 4 + id_len);
1994 silc_buffer_pull(packet->buffer, 4 + id_len);
1997 silc_buffer_free(idp);
2001 /* Received New Channel packet. Information about new channels in the
2002 network are distributed using this packet. Save the information about
2003 the new channel. This usually comes from router but also normal server
2004 can send this to notify channels it has when it connects to us. */
2006 void silc_server_new_channel(SilcServer server,
2007 SilcSocketConnection sock,
2008 SilcPacketContext *packet)
2010 SilcChannelPayload payload;
2011 SilcChannelID *channel_id;
2017 SilcServerEntry server_entry;
2018 SilcChannelEntry channel;
2020 SILC_LOG_DEBUG(("Processing New Channel"));
2022 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2023 packet->src_id_type != SILC_ID_SERVER ||
2024 server->server_type == SILC_SERVER)
2027 /* Parse the channel payload */
2028 payload = silc_channel_payload_parse(packet->buffer);
2032 /* Get the channel ID */
2033 channel_id = silc_channel_get_id_parse(payload);
2035 silc_channel_payload_free(payload);
2039 channel_name = silc_channel_get_name(payload, &name_len);
2041 channel_name[255] = '\0';
2043 id = silc_channel_get_id(payload, &id_len);
2045 server_entry = (SilcServerEntry)sock->user_data;
2047 if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
2048 /* Add the channel to global list as it is coming from router. It
2049 cannot be our own channel as it is coming from router. */
2051 /* Check that we don't already have this channel */
2052 channel = silc_idlist_find_channel_by_name(server->local_list,
2053 channel_name, NULL);
2055 channel = silc_idlist_find_channel_by_name(server->global_list,
2056 channel_name, NULL);
2058 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
2059 silc_id_render(channel_id, SILC_ID_CHANNEL),
2062 silc_idlist_add_channel(server->global_list, strdup(channel_name),
2063 0, channel_id, sock->user_data, NULL, NULL);
2064 server->stat.channels++;
2067 /* The channel is coming from our server, thus it is in our cell
2068 we will add it to our local list. */
2071 SILC_LOG_DEBUG(("Channel id(%s) from [Server] %s",
2072 silc_id_render(channel_id, SILC_ID_CHANNEL),
2075 /* Check that we don't already have this channel */
2076 channel = silc_idlist_find_channel_by_name(server->local_list,
2077 channel_name, NULL);
2079 channel = silc_idlist_find_channel_by_name(server->global_list,
2080 channel_name, NULL);
2082 /* If the channel does not exist, then create it. This creates a new
2083 key to the channel as well that we will send to the server. */
2085 /* The protocol says that the Channel ID's IP address must be based
2086 on the router's IP address. Check whether the ID is based in our
2087 IP and if it is not then create a new ID and enforce the server
2088 to switch the ID. */
2089 if (server_entry->server_type != SILC_BACKUP_ROUTER &&
2090 !SILC_ID_COMPARE(channel_id, server->id, server->id->ip.data_len)) {
2092 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2094 if (silc_id_create_channel_id(server, server->id, server->rng, &tmp)) {
2095 silc_server_send_notify_channel_change(server, sock, FALSE,
2097 silc_free(channel_id);
2102 /* Create the channel with the provided Channel ID */
2103 channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
2107 silc_channel_payload_free(payload);
2108 silc_free(channel_id);
2112 /* Get the mode and set it to the channel */
2113 channel->mode = silc_channel_get_mode(payload);
2115 /* Send the new channel key to the server */
2116 chk = silc_channel_key_payload_encode(id_len, id,
2117 strlen(channel->channel_key->
2119 channel->channel_key->cipher->name,
2120 channel->key_len / 8,
2122 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
2123 chk->data, chk->len, FALSE);
2124 silc_buffer_free(chk);
2127 /* The channel exist by that name, check whether the ID's match.
2128 If they don't then we'll force the server to use the ID we have.
2129 We also create a new key for the channel. */
2130 SilcBuffer users = NULL, users_modes = NULL;
2133 channel->id = silc_id_dup(channel_id, SILC_ID_CHANNEL);
2135 if (!SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
2136 /* They don't match, send CHANNEL_CHANGE notify to the server to
2137 force the ID change. */
2138 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2139 silc_server_send_notify_channel_change(server, sock, FALSE,
2140 channel_id, channel->id);
2143 /* If the mode is different from what we have then enforce the
2145 mode = silc_channel_get_mode(payload);
2146 if (channel->mode != mode) {
2147 SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
2148 silc_server_send_notify_cmode(server, sock, FALSE, channel,
2149 channel->mode, server->id,
2151 channel->cipher, channel->hmac_name);
2154 /* Create new key for the channel and send it to the server and
2155 everybody else possibly on the channel. */
2157 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
2158 if (!silc_server_create_channel_key(server, channel, 0))
2161 /* Send to the channel */
2162 silc_server_send_channel_key(server, sock, channel, FALSE);
2163 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2164 id_len = SILC_ID_CHANNEL_LEN;
2166 /* Send to the server */
2167 chk = silc_channel_key_payload_encode(id_len, id,
2168 strlen(channel->channel_key->
2170 channel->channel_key->
2172 channel->key_len / 8,
2174 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
2175 chk->data, chk->len, FALSE);
2176 silc_buffer_free(chk);
2180 silc_free(channel_id);
2182 /* Since the channel is coming from server and we also know about it
2183 then send the JOIN notify to the server so that it see's our
2184 users on the channel "joining" the channel. */
2185 silc_server_announce_get_channel_users(server, channel, &users,
2188 silc_buffer_push(users, users->data - users->head);
2189 silc_server_packet_send(server, sock,
2190 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2191 users->data, users->len, FALSE);
2192 silc_buffer_free(users);
2195 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
2196 silc_server_packet_send_dest(server, sock,
2197 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2198 channel->id, SILC_ID_CHANNEL,
2200 users_modes->len, FALSE);
2201 silc_buffer_free(users_modes);
2206 silc_channel_payload_free(payload);
2209 /* Received New Channel List packet, list of New Channel List payloads inside
2210 one packet. Process the New Channel payloads one by one. */
2212 void silc_server_new_channel_list(SilcServer server,
2213 SilcSocketConnection sock,
2214 SilcPacketContext *packet)
2216 SilcPacketContext *new;
2220 SILC_LOG_DEBUG(("Processing New Channel List"));
2222 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2223 packet->src_id_type != SILC_ID_SERVER ||
2224 server->server_type == SILC_SERVER)
2227 /* If the sender of this packet is server and we are router we need to
2228 broadcast this packet to other routers in the network. Broadcast
2229 this list packet instead of multiple New Channel packets. */
2230 if (!server->standalone && server->server_type == SILC_ROUTER &&
2231 sock->type == SILC_SOCKET_TYPE_SERVER &&
2232 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2233 SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
2234 silc_server_packet_send(server, server->router->connection,
2236 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2237 packet->buffer->data, packet->buffer->len, FALSE);
2238 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
2239 packet->type, packet->flags,
2240 packet->buffer->data, packet->buffer->len,
2244 /* Make copy of the original packet context, except for the actual
2245 data buffer, which we will here now fetch from the original buffer. */
2246 new = silc_packet_context_alloc();
2247 new->type = SILC_PACKET_NEW_CHANNEL;
2248 new->flags = packet->flags;
2249 new->src_id = packet->src_id;
2250 new->src_id_len = packet->src_id_len;
2251 new->src_id_type = packet->src_id_type;
2252 new->dst_id = packet->dst_id;
2253 new->dst_id_len = packet->dst_id_len;
2254 new->dst_id_type = packet->dst_id_type;
2256 buffer = silc_buffer_alloc(512);
2257 new->buffer = buffer;
2259 while (packet->buffer->len) {
2260 SILC_GET16_MSB(len1, packet->buffer->data);
2261 if ((len1 > packet->buffer->len) ||
2262 (len1 > buffer->truelen))
2265 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
2266 if ((len2 > packet->buffer->len) ||
2267 (len2 > buffer->truelen))
2270 silc_buffer_pull_tail(buffer, 8 + len1 + len2);
2271 silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
2273 /* Process the New Channel */
2274 silc_server_new_channel(server, sock, new);
2276 silc_buffer_push_tail(buffer, 8 + len1 + len2);
2277 silc_buffer_pull(packet->buffer, 8 + len1 + len2);
2280 silc_buffer_free(buffer);
2284 /* Received key agreement packet. This packet is never for us. It is to
2285 the client in the packet's destination ID. Sending of this sort of packet
2286 equals sending private message, ie. it is sent point to point from
2287 one client to another. */
2289 void silc_server_key_agreement(SilcServer server,
2290 SilcSocketConnection sock,
2291 SilcPacketContext *packet)
2293 SilcSocketConnection dst_sock;
2294 SilcIDListData idata;
2296 SILC_LOG_DEBUG(("Start"));
2298 if (packet->src_id_type != SILC_ID_CLIENT ||
2299 packet->dst_id_type != SILC_ID_CLIENT)
2302 if (!packet->dst_id)
2305 /* Get the route to the client */
2306 dst_sock = silc_server_get_client_route(server, packet->dst_id,
2307 packet->dst_id_len, NULL, &idata);
2311 /* Relay the packet */
2312 silc_server_relay_packet(server, dst_sock, idata->send_key,
2313 idata->hmac_send, packet, FALSE);
2316 /* Received connection auth request packet that is used during connection
2317 phase to resolve the mandatory authentication method. This packet can
2318 actually be received at anytime but usually it is used only during
2319 the connection authentication phase. Now, protocol says that this packet
2320 can come from client or server, however, we support only this coming
2321 from client and expect that server always knows what authentication
2324 void silc_server_connection_auth_request(SilcServer server,
2325 SilcSocketConnection sock,
2326 SilcPacketContext *packet)
2328 SilcServerConfigSectionClientConnection *client = NULL;
2331 SilcAuthMethod auth_meth;
2333 SILC_LOG_DEBUG(("Start"));
2335 if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT)
2338 /* Parse the payload */
2339 ret = silc_buffer_unformat(packet->buffer,
2340 SILC_STR_UI_SHORT(&conn_type),
2341 SILC_STR_UI_SHORT(NULL),
2346 if (conn_type != SILC_SOCKET_TYPE_CLIENT)
2349 /* Get the authentication method for the client */
2350 auth_meth = SILC_AUTH_NONE;
2351 port = server->sockets[server->sock]->port; /* Listenning port */
2352 client = silc_server_config_find_client_conn(server->config,
2356 client = silc_server_config_find_client_conn(server->config,
2360 auth_meth = client->auth_meth;
2362 /* Send it back to the client */
2363 silc_server_send_connection_auth_request(server, sock,
2368 /* Received REKEY packet. The sender of the packet wants to regenerate
2369 its session keys. This starts the REKEY protocol. */
2371 void silc_server_rekey(SilcServer server,
2372 SilcSocketConnection sock,
2373 SilcPacketContext *packet)
2375 SilcProtocol protocol;
2376 SilcServerRekeyInternalContext *proto_ctx;
2377 SilcIDListData idata = (SilcIDListData)sock->user_data;
2379 SILC_LOG_DEBUG(("Start"));
2381 /* Allocate internal protocol context. This is sent as context
2383 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
2384 proto_ctx->server = (void *)server;
2385 proto_ctx->sock = sock;
2386 proto_ctx->responder = TRUE;
2387 proto_ctx->pfs = idata->rekey->pfs;
2389 /* Perform rekey protocol. Will call the final callback after the
2390 protocol is over. */
2391 silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
2392 &protocol, proto_ctx, silc_server_rekey_final);
2393 sock->protocol = protocol;
2395 if (proto_ctx->pfs == FALSE)
2396 /* Run the protocol */
2397 silc_protocol_execute(protocol, server->schedule, 0, 0);