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;
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 /* Update server entry */
1674 idata->status |= SILC_IDLIST_STATUS_REGISTERED;
1675 new_server->server_name = server_name;
1676 new_server->id = server_id;
1678 /* Add again the entry to the ID cache. */
1679 silc_idcache_add(server->local_list->servers, server_name, server_id,
1682 /* Distribute the information about new server in the SILC network
1683 to our router. If we are normal server we won't send anything
1684 since this connection must be our router connection. */
1685 if (server->server_type == SILC_ROUTER && !server->standalone &&
1686 server->router->connection != sock)
1687 silc_server_send_new_id(server, server->router->connection,
1688 TRUE, new_server->id, SILC_ID_SERVER,
1689 silc_id_get_len(server_id, SILC_ID_SERVER));
1691 if (server->server_type == SILC_ROUTER)
1692 server->stat.cell_servers++;
1694 /* Check whether this router connection has been replaced by an
1695 backup router. If it has been then we'll disable the server and will
1696 ignore everything it will send until the backup router resuming
1697 protocol has been completed. */
1698 if (sock->type == SILC_SOCKET_TYPE_ROUTER &&
1699 silc_server_backup_replaced_get(server, server_id, NULL)) {
1700 /* Send packet to the server indicating that it cannot use this
1701 connection as it has been replaced by backup router. */
1702 SilcBuffer packet = silc_buffer_alloc(2);
1703 silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
1704 silc_buffer_format(packet,
1705 SILC_STR_UI_CHAR(SILC_SERVER_BACKUP_REPLACED),
1706 SILC_STR_UI_CHAR(0),
1708 silc_server_packet_send(server, sock,
1709 SILC_PACKET_RESUME_ROUTER, 0,
1710 packet->data, packet->len, TRUE);
1711 silc_buffer_free(packet);
1713 /* Mark the server disabled. The data sent earlier will go but nothing
1714 after this does not go to this connection. */
1715 idata->status |= SILC_IDLIST_STATUS_DISABLED;
1721 /* Processes incoming New ID packet. New ID Payload is used to distribute
1722 information about newly registered clients and servers. */
1724 static void silc_server_new_id_real(SilcServer server,
1725 SilcSocketConnection sock,
1726 SilcPacketContext *packet,
1729 SilcBuffer buffer = packet->buffer;
1731 SilcServerEntry router;
1732 SilcSocketConnection router_sock;
1737 SILC_LOG_DEBUG(("Processing new ID"));
1739 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1740 server->server_type == SILC_SERVER ||
1741 packet->src_id_type != SILC_ID_SERVER)
1744 idp = silc_id_payload_parse(buffer);
1748 id_type = silc_id_payload_get_type(idp);
1750 /* Normal server cannot have other normal server connections */
1751 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
1754 id = silc_id_payload_get_id(idp);
1758 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1759 id_list = server->local_list;
1761 id_list = server->global_list;
1763 /* If the packet is coming from server then use the sender as the
1764 origin of the the packet. If it came from router then check the real
1765 sender of the packet and use that as the origin. */
1766 if (sock->type == SILC_SOCKET_TYPE_SERVER) {
1768 router = sock->user_data;
1770 void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1771 packet->src_id_type);
1772 router = silc_idlist_find_server_by_id(server->global_list,
1773 sender_id, TRUE, NULL);
1775 router = silc_idlist_find_server_by_id(server->local_list,
1776 sender_id, TRUE, NULL);
1777 silc_free(sender_id);
1784 case SILC_ID_CLIENT:
1786 SilcClientEntry entry;
1788 /* Check that we do not have this client already */
1789 entry = silc_idlist_find_client_by_id(server->global_list,
1790 id, server->server_type,
1793 entry = silc_idlist_find_client_by_id(server->local_list,
1794 id, server->server_type,
1797 SILC_LOG_DEBUG(("Ignoring client that we already have"));
1801 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
1802 silc_id_render(id, SILC_ID_CLIENT),
1803 sock->type == SILC_SOCKET_TYPE_SERVER ?
1804 "Server" : "Router", sock->hostname));
1806 /* As a router we keep information of all global information in our
1807 global list. Cell wide information however is kept in the local
1809 entry = silc_idlist_add_client(id_list, NULL, NULL, NULL,
1812 SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
1814 /* Inform the sender that the ID is not usable */
1815 silc_server_send_notify_signoff(server, sock, FALSE, id, NULL);
1818 entry->nickname = NULL;
1819 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
1821 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1822 server->stat.cell_clients++;
1823 server->stat.clients++;
1827 case SILC_ID_SERVER:
1829 SilcServerEntry entry;
1831 /* If the ID is mine, ignore it. */
1832 if (SILC_ID_SERVER_COMPARE(id, server->id)) {
1833 SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
1837 /* If the ID is the sender's ID, ignore it (we have it already) */
1838 if (SILC_ID_SERVER_COMPARE(id, router->id)) {
1839 SILC_LOG_DEBUG(("Ignoring sender's own ID"));
1843 /* Check that we do not have this server already */
1844 entry = silc_idlist_find_server_by_id(server->global_list,
1845 id, server->server_type,
1848 entry = silc_idlist_find_server_by_id(server->local_list,
1849 id, server->server_type,
1852 SILC_LOG_DEBUG(("Ignoring server that we already have"));
1856 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
1857 silc_id_render(id, SILC_ID_SERVER),
1858 sock->type == SILC_SOCKET_TYPE_SERVER ?
1859 "Server" : "Router", sock->hostname));
1861 /* As a router we keep information of all global information in our
1862 global list. Cell wide information however is kept in the local
1864 entry = silc_idlist_add_server(id_list, NULL, 0, id, router,
1867 SILC_LOG_ERROR(("Could not add new server to the ID Cache"));
1870 entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
1872 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1873 server->stat.cell_servers++;
1874 server->stat.servers++;
1878 case SILC_ID_CHANNEL:
1879 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
1888 /* If the sender of this packet is server and we are router we need to
1889 broadcast this packet to other routers in the network. */
1890 if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
1891 sock->type == SILC_SOCKET_TYPE_SERVER &&
1892 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1893 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
1894 silc_server_packet_send(server, server->router->connection,
1896 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1897 buffer->data, buffer->len, FALSE);
1898 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
1899 packet->type, packet->flags,
1900 packet->buffer->data, packet->buffer->len,
1905 silc_id_payload_free(idp);
1909 /* Processes incoming New ID packet. New ID Payload is used to distribute
1910 information about newly registered clients and servers. */
1912 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
1913 SilcPacketContext *packet)
1915 silc_server_new_id_real(server, sock, packet, TRUE);
1918 /* Receoved New Id List packet, list of New ID payloads inside one
1919 packet. Process the New ID payloads one by one. */
1921 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
1922 SilcPacketContext *packet)
1924 SilcPacketContext *new_id;
1928 SILC_LOG_DEBUG(("Processing New ID List"));
1930 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1931 packet->src_id_type != SILC_ID_SERVER)
1934 /* If the sender of this packet is server and we are router we need to
1935 broadcast this packet to other routers in the network. Broadcast
1936 this list packet instead of multiple New ID packets. */
1937 if (!server->standalone && server->server_type == SILC_ROUTER &&
1938 sock->type == SILC_SOCKET_TYPE_SERVER &&
1939 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1940 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
1941 silc_server_packet_send(server, server->router->connection,
1943 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1944 packet->buffer->data, packet->buffer->len, FALSE);
1945 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
1946 packet->type, packet->flags,
1947 packet->buffer->data, packet->buffer->len,
1951 /* Make copy of the original packet context, except for the actual
1952 data buffer, which we will here now fetch from the original buffer. */
1953 new_id = silc_packet_context_alloc();
1954 new_id->type = SILC_PACKET_NEW_ID;
1955 new_id->flags = packet->flags;
1956 new_id->src_id = packet->src_id;
1957 new_id->src_id_len = packet->src_id_len;
1958 new_id->src_id_type = packet->src_id_type;
1959 new_id->dst_id = packet->dst_id;
1960 new_id->dst_id_len = packet->dst_id_len;
1961 new_id->dst_id_type = packet->dst_id_type;
1963 idp = silc_buffer_alloc(256);
1964 new_id->buffer = idp;
1966 while (packet->buffer->len) {
1967 SILC_GET16_MSB(id_len, packet->buffer->data + 2);
1968 if ((id_len > packet->buffer->len) ||
1969 (id_len > idp->truelen))
1972 silc_buffer_pull_tail(idp, 4 + id_len);
1973 silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
1975 /* Process the New ID */
1976 silc_server_new_id_real(server, sock, new_id, FALSE);
1978 silc_buffer_push_tail(idp, 4 + id_len);
1979 silc_buffer_pull(packet->buffer, 4 + id_len);
1982 silc_buffer_free(idp);
1986 /* Received New Channel packet. Information about new channels in the
1987 network are distributed using this packet. Save the information about
1988 the new channel. This usually comes from router but also normal server
1989 can send this to notify channels it has when it connects to us. */
1991 void silc_server_new_channel(SilcServer server,
1992 SilcSocketConnection sock,
1993 SilcPacketContext *packet)
1995 SilcChannelPayload payload;
1996 SilcChannelID *channel_id;
2002 SilcServerEntry server_entry;
2003 SilcChannelEntry channel;
2005 SILC_LOG_DEBUG(("Processing New Channel"));
2007 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2008 packet->src_id_type != SILC_ID_SERVER ||
2009 server->server_type == SILC_SERVER)
2012 /* Parse the channel payload */
2013 payload = silc_channel_payload_parse(packet->buffer);
2017 /* Get the channel ID */
2018 channel_id = silc_channel_get_id_parse(payload);
2020 silc_channel_payload_free(payload);
2024 channel_name = silc_channel_get_name(payload, &name_len);
2026 channel_name[255] = '\0';
2028 id = silc_channel_get_id(payload, &id_len);
2030 server_entry = (SilcServerEntry)sock->user_data;
2032 if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
2033 /* Add the channel to global list as it is coming from router. It
2034 cannot be our own channel as it is coming from router. */
2036 /* Check that we don't already have this channel */
2037 channel = silc_idlist_find_channel_by_name(server->local_list,
2038 channel_name, NULL);
2040 channel = silc_idlist_find_channel_by_name(server->global_list,
2041 channel_name, NULL);
2043 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
2044 silc_id_render(channel_id, SILC_ID_CHANNEL),
2047 silc_idlist_add_channel(server->global_list, strdup(channel_name),
2048 0, channel_id, sock->user_data, NULL, NULL);
2049 server->stat.channels++;
2052 /* The channel is coming from our server, thus it is in our cell
2053 we will add it to our local list. */
2056 SILC_LOG_DEBUG(("Channel id(%s) from [Server] %s",
2057 silc_id_render(channel_id, SILC_ID_CHANNEL),
2060 /* Check that we don't already have this channel */
2061 channel = silc_idlist_find_channel_by_name(server->local_list,
2062 channel_name, NULL);
2064 channel = silc_idlist_find_channel_by_name(server->global_list,
2065 channel_name, NULL);
2067 /* If the channel does not exist, then create it. This creates a new
2068 key to the channel as well that we will send to the server. */
2070 /* The protocol says that the Channel ID's IP address must be based
2071 on the router's IP address. Check whether the ID is based in our
2072 IP and if it is not then create a new ID and enforce the server
2073 to switch the ID. */
2074 if (server_entry->server_type != SILC_BACKUP_ROUTER &&
2075 !SILC_ID_COMPARE(channel_id, server->id, server->id->ip.data_len)) {
2077 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2079 if (silc_id_create_channel_id(server, server->id, server->rng, &tmp)) {
2080 silc_server_send_notify_channel_change(server, sock, FALSE,
2082 silc_free(channel_id);
2087 /* Create the channel with the provided Channel ID */
2088 channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
2092 silc_channel_payload_free(payload);
2093 silc_free(channel_id);
2097 /* Get the mode and set it to the channel */
2098 channel->mode = silc_channel_get_mode(payload);
2100 /* Send the new channel key to the server */
2101 chk = silc_channel_key_payload_encode(id_len, id,
2102 strlen(channel->channel_key->
2104 channel->channel_key->cipher->name,
2105 channel->key_len / 8,
2107 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
2108 chk->data, chk->len, FALSE);
2109 silc_buffer_free(chk);
2112 /* The channel exist by that name, check whether the ID's match.
2113 If they don't then we'll force the server to use the ID we have.
2114 We also create a new key for the channel. */
2115 SilcBuffer users = NULL, users_modes = NULL;
2118 channel->id = silc_id_dup(channel_id, SILC_ID_CHANNEL);
2120 if (!SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
2121 /* They don't match, send CHANNEL_CHANGE notify to the server to
2122 force the ID change. */
2123 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
2124 silc_server_send_notify_channel_change(server, sock, FALSE,
2125 channel_id, channel->id);
2128 /* If the mode is different from what we have then enforce the
2130 mode = silc_channel_get_mode(payload);
2131 if (channel->mode != mode) {
2132 SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
2133 silc_server_send_notify_cmode(server, sock, FALSE, channel,
2134 channel->mode, server->id,
2136 channel->cipher, channel->hmac_name);
2139 /* Create new key for the channel and send it to the server and
2140 everybody else possibly on the channel. */
2142 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
2143 if (!silc_server_create_channel_key(server, channel, 0))
2146 /* Send to the channel */
2147 silc_server_send_channel_key(server, sock, channel, FALSE);
2148 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
2149 id_len = SILC_ID_CHANNEL_LEN;
2151 /* Send to the server */
2152 chk = silc_channel_key_payload_encode(id_len, id,
2153 strlen(channel->channel_key->
2155 channel->channel_key->
2157 channel->key_len / 8,
2159 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
2160 chk->data, chk->len, FALSE);
2161 silc_buffer_free(chk);
2165 silc_free(channel_id);
2167 /* Since the channel is coming from server and we also know about it
2168 then send the JOIN notify to the server so that it see's our
2169 users on the channel "joining" the channel. */
2170 silc_server_announce_get_channel_users(server, channel, &users,
2173 silc_buffer_push(users, users->data - users->head);
2174 silc_server_packet_send(server, sock,
2175 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2176 users->data, users->len, FALSE);
2177 silc_buffer_free(users);
2180 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
2181 silc_server_packet_send_dest(server, sock,
2182 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
2183 channel->id, SILC_ID_CHANNEL,
2185 users_modes->len, FALSE);
2186 silc_buffer_free(users_modes);
2191 silc_channel_payload_free(payload);
2194 /* Received New Channel List packet, list of New Channel List payloads inside
2195 one packet. Process the New Channel payloads one by one. */
2197 void silc_server_new_channel_list(SilcServer server,
2198 SilcSocketConnection sock,
2199 SilcPacketContext *packet)
2201 SilcPacketContext *new;
2205 SILC_LOG_DEBUG(("Processing New Channel List"));
2207 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
2208 packet->src_id_type != SILC_ID_SERVER ||
2209 server->server_type == SILC_SERVER)
2212 /* If the sender of this packet is server and we are router we need to
2213 broadcast this packet to other routers in the network. Broadcast
2214 this list packet instead of multiple New Channel packets. */
2215 if (!server->standalone && server->server_type == SILC_ROUTER &&
2216 sock->type == SILC_SOCKET_TYPE_SERVER &&
2217 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
2218 SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
2219 silc_server_packet_send(server, server->router->connection,
2221 packet->flags | SILC_PACKET_FLAG_BROADCAST,
2222 packet->buffer->data, packet->buffer->len, FALSE);
2223 silc_server_backup_send(server, (SilcServerEntry)sock->user_data,
2224 packet->type, packet->flags,
2225 packet->buffer->data, packet->buffer->len,
2229 /* Make copy of the original packet context, except for the actual
2230 data buffer, which we will here now fetch from the original buffer. */
2231 new = silc_packet_context_alloc();
2232 new->type = SILC_PACKET_NEW_CHANNEL;
2233 new->flags = packet->flags;
2234 new->src_id = packet->src_id;
2235 new->src_id_len = packet->src_id_len;
2236 new->src_id_type = packet->src_id_type;
2237 new->dst_id = packet->dst_id;
2238 new->dst_id_len = packet->dst_id_len;
2239 new->dst_id_type = packet->dst_id_type;
2241 buffer = silc_buffer_alloc(512);
2242 new->buffer = buffer;
2244 while (packet->buffer->len) {
2245 SILC_GET16_MSB(len1, packet->buffer->data);
2246 if ((len1 > packet->buffer->len) ||
2247 (len1 > buffer->truelen))
2250 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
2251 if ((len2 > packet->buffer->len) ||
2252 (len2 > buffer->truelen))
2255 silc_buffer_pull_tail(buffer, 8 + len1 + len2);
2256 silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
2258 /* Process the New Channel */
2259 silc_server_new_channel(server, sock, new);
2261 silc_buffer_push_tail(buffer, 8 + len1 + len2);
2262 silc_buffer_pull(packet->buffer, 8 + len1 + len2);
2265 silc_buffer_free(buffer);
2269 /* Received key agreement packet. This packet is never for us. It is to
2270 the client in the packet's destination ID. Sending of this sort of packet
2271 equals sending private message, ie. it is sent point to point from
2272 one client to another. */
2274 void silc_server_key_agreement(SilcServer server,
2275 SilcSocketConnection sock,
2276 SilcPacketContext *packet)
2278 SilcSocketConnection dst_sock;
2279 SilcIDListData idata;
2281 SILC_LOG_DEBUG(("Start"));
2283 if (packet->src_id_type != SILC_ID_CLIENT ||
2284 packet->dst_id_type != SILC_ID_CLIENT)
2287 if (!packet->dst_id)
2290 /* Get the route to the client */
2291 dst_sock = silc_server_get_client_route(server, packet->dst_id,
2292 packet->dst_id_len, NULL, &idata);
2296 /* Relay the packet */
2297 silc_server_relay_packet(server, dst_sock, idata->send_key,
2298 idata->hmac_send, packet, FALSE);
2301 /* Received connection auth request packet that is used during connection
2302 phase to resolve the mandatory authentication method. This packet can
2303 actually be received at anytime but usually it is used only during
2304 the connection authentication phase. Now, protocol says that this packet
2305 can come from client or server, however, we support only this coming
2306 from client and expect that server always knows what authentication
2309 void silc_server_connection_auth_request(SilcServer server,
2310 SilcSocketConnection sock,
2311 SilcPacketContext *packet)
2313 SilcServerConfigSectionClientConnection *client = NULL;
2316 SilcAuthMethod auth_meth;
2318 SILC_LOG_DEBUG(("Start"));
2320 if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT)
2323 /* Parse the payload */
2324 ret = silc_buffer_unformat(packet->buffer,
2325 SILC_STR_UI_SHORT(&conn_type),
2326 SILC_STR_UI_SHORT(NULL),
2331 if (conn_type != SILC_SOCKET_TYPE_CLIENT)
2334 /* Get the authentication method for the client */
2335 auth_meth = SILC_AUTH_NONE;
2336 port = server->sockets[server->sock]->port; /* Listenning port */
2337 client = silc_server_config_find_client_conn(server->config,
2341 client = silc_server_config_find_client_conn(server->config,
2345 auth_meth = client->auth_meth;
2347 /* Send it back to the client */
2348 silc_server_send_connection_auth_request(server, sock,
2353 /* Received REKEY packet. The sender of the packet wants to regenerate
2354 its session keys. This starts the REKEY protocol. */
2356 void silc_server_rekey(SilcServer server,
2357 SilcSocketConnection sock,
2358 SilcPacketContext *packet)
2360 SilcProtocol protocol;
2361 SilcServerRekeyInternalContext *proto_ctx;
2362 SilcIDListData idata = (SilcIDListData)sock->user_data;
2364 SILC_LOG_DEBUG(("Start"));
2366 /* Allocate internal protocol context. This is sent as context
2368 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
2369 proto_ctx->server = (void *)server;
2370 proto_ctx->sock = sock;
2371 proto_ctx->responder = TRUE;
2372 proto_ctx->pfs = idata->rekey->pfs;
2374 /* Perform rekey protocol. Will call the final callback after the
2375 protocol is over. */
2376 silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
2377 &protocol, proto_ctx, silc_server_rekey_final);
2378 sock->protocol = protocol;
2380 if (proto_ctx->pfs == FALSE)
2381 /* Run the protocol */
2382 silc_protocol_execute(protocol, server->schedule, 0, 0);