5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2001 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
21 * Server packet routines to handle received packets.
25 #include "serverincludes.h"
26 #include "server_internal.h"
28 extern char *server_version;
30 /* Received notify packet. Server can receive notify packets from router.
31 Server then relays the notify messages to clients if needed. */
33 void silc_server_notify(SilcServer server,
34 SilcSocketConnection sock,
35 SilcPacketContext *packet)
37 SilcNotifyPayload payload;
39 SilcArgumentPayload args;
40 SilcChannelID *channel_id, *channel_id2;
41 SilcClientID *client_id, *client_id2;
42 SilcServerID *server_id;
43 SilcChannelEntry channel;
44 SilcClientEntry client;
45 SilcServerEntry server_entry;
46 SilcChannelClientEntry chl;
47 SilcIDCacheEntry cache;
52 SILC_LOG_DEBUG(("Start"));
54 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
55 packet->src_id_type != SILC_ID_SERVER)
61 /* If the packet is destined directly to a client then relay the packet
62 before processing it. */
63 if (packet->dst_id_type == SILC_ID_CLIENT) {
65 SilcSocketConnection dst_sock;
67 /* Get the route to the client */
68 dst_sock = silc_server_get_client_route(server, packet->dst_id,
69 packet->dst_id_len, NULL, &idata);
71 /* Relay the packet */
72 silc_server_relay_packet(server, dst_sock, idata->send_key,
73 idata->hmac_receive, packet, TRUE);
76 /* If we are router and this packet is not already broadcast packet
77 we will broadcast it. The sending socket really cannot be router or
78 the router is buggy. If this packet is coming from router then it must
79 have the broadcast flag set already and we won't do anything. */
80 if (!server->standalone && server->server_type == SILC_ROUTER &&
81 sock->type == SILC_SOCKET_TYPE_SERVER &&
82 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
83 SILC_LOG_DEBUG(("Broadcasting received Notify packet"));
84 silc_server_packet_send(server, server->router->connection, packet->type,
85 packet->flags | SILC_PACKET_FLAG_BROADCAST,
86 packet->buffer->data, packet->buffer->len, FALSE);
89 payload = silc_notify_payload_parse(packet->buffer);
93 type = silc_notify_get_type(payload);
94 args = silc_notify_get_args(payload);
99 case SILC_NOTIFY_TYPE_JOIN:
101 * Distribute the notify to local clients on the channel
103 SILC_LOG_DEBUG(("JOIN notify"));
106 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
109 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
113 /* Get channel entry */
114 channel = silc_idlist_find_channel_by_id(server->global_list,
117 channel = silc_idlist_find_channel_by_id(server->local_list,
120 silc_free(channel_id);
124 silc_free(channel_id);
127 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
130 client_id = silc_id_payload_parse_id(tmp, tmp_len);
134 /* Send to channel */
135 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
136 FALSE, packet->buffer->data,
137 packet->buffer->len, FALSE);
139 /* If the the client is not in local list we check global list (ie. the
140 channel will be global channel) and if it does not exist then create
141 entry for the client. */
142 client = silc_idlist_find_client_by_id(server->global_list,
145 client = silc_idlist_find_client_by_id(server->local_list,
148 /* If router did not find the client the it is bogus */
149 if (server->server_type == SILC_ROUTER)
153 silc_idlist_add_client(server->global_list, NULL, 0, NULL, NULL,
154 silc_id_dup(client_id, SILC_ID_CLIENT),
155 sock->user_data, NULL);
157 silc_free(client_id);
161 client->data.registered = TRUE;
165 /* Do not add client to channel if it is there already */
166 if (silc_server_client_on_channel(client, channel))
169 if (server->server_type == SILC_SERVER &&
170 sock->type == SILC_SOCKET_TYPE_ROUTER)
171 /* The channel is global now */
172 channel->global_users = TRUE;
174 /* JOIN the global client to the channel (local clients (if router
175 created the channel) is joined in the pending JOIN command). */
176 chl = silc_calloc(1, sizeof(*chl));
177 chl->client = client;
178 chl->channel = channel;
179 silc_list_add(channel->user_list, chl);
180 silc_list_add(client->channels, chl);
181 silc_free(client_id);
185 case SILC_NOTIFY_TYPE_LEAVE:
187 * Distribute the notify to local clients on the channel
189 SILC_LOG_DEBUG(("LEAVE notify"));
191 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
192 packet->dst_id_type);
196 /* Get channel entry */
197 channel = silc_idlist_find_channel_by_id(server->global_list,
200 channel = silc_idlist_find_channel_by_id(server->local_list,
203 silc_free(channel_id);
209 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
211 silc_free(channel_id);
214 client_id = silc_id_payload_parse_id(tmp, tmp_len);
216 silc_free(channel_id);
220 /* Send to channel */
221 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
222 FALSE, packet->buffer->data,
223 packet->buffer->len, FALSE);
225 /* Get client entry */
226 client = silc_idlist_find_client_by_id(server->global_list,
229 client = silc_idlist_find_client_by_id(server->local_list,
232 silc_free(client_id);
233 silc_free(channel_id);
237 silc_free(client_id);
239 /* Remove the user from channel */
240 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
243 case SILC_NOTIFY_TYPE_SIGNOFF:
245 * Distribute the notify to local clients on the channel
247 SILC_LOG_DEBUG(("SIGNOFF notify"));
250 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
253 client_id = silc_id_payload_parse_id(tmp, tmp_len);
257 /* Get client entry */
258 client = silc_idlist_find_client_by_id(server->global_list,
261 client = silc_idlist_find_client_by_id(server->local_list,
264 silc_free(client_id);
268 silc_free(client_id);
270 /* Get signoff message */
271 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
275 /* Remove the client from all channels. */
276 silc_server_remove_from_channels(server, NULL, client, TRUE, tmp, FALSE);
278 client->data.registered = FALSE;
279 cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
282 case SILC_NOTIFY_TYPE_TOPIC_SET:
284 * Distribute the notify to local clients on the channel
287 SILC_LOG_DEBUG(("TOPIC SET notify"));
289 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
290 packet->dst_id_type);
294 /* Get channel entry */
295 channel = silc_idlist_find_channel_by_id(server->global_list,
298 channel = silc_idlist_find_channel_by_id(server->local_list,
301 silc_free(channel_id);
307 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
309 silc_free(channel_id);
314 silc_free(channel->topic);
315 channel->topic = silc_calloc(tmp_len, sizeof(*channel->topic));
316 memcpy(channel->topic, tmp, tmp_len);
318 /* Send the same notify to the channel */
319 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
320 FALSE, packet->buffer->data,
321 packet->buffer->len, FALSE);
322 silc_free(channel_id);
325 case SILC_NOTIFY_TYPE_NICK_CHANGE:
328 * Distribute the notify to local clients on the channel
330 unsigned char *id, *id2;
332 SILC_LOG_DEBUG(("NICK CHANGE notify"));
334 /* Get old client ID */
335 id = silc_argument_get_arg_type(args, 1, &tmp_len);
338 client_id = silc_id_payload_parse_id(id, tmp_len);
342 /* Get new client ID */
343 id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
346 client_id2 = silc_id_payload_parse_id(id2, tmp_len);
350 SILC_LOG_DEBUG(("Old Client ID id(%s)",
351 silc_id_render(client_id, SILC_ID_CLIENT)));
352 SILC_LOG_DEBUG(("New Client ID id(%s)",
353 silc_id_render(client_id2, SILC_ID_CLIENT)));
355 /* Replace the Client ID */
356 client = silc_idlist_replace_client_id(server->global_list, client_id,
359 client = silc_idlist_replace_client_id(server->local_list, client_id,
363 /* The nickname is not valid anymore, set it NULL. This causes that
364 the nickname will be queried if someone wants to know it. */
365 if (client->nickname)
366 silc_free(client->nickname);
367 client->nickname = NULL;
369 /* Send the NICK_CHANGE notify type to local clients on the channels
370 this client is joined to. */
371 silc_server_send_notify_on_channels(server, NULL, client,
372 SILC_NOTIFY_TYPE_NICK_CHANGE, 2,
377 silc_free(client_id);
379 silc_free(client_id2);
383 case SILC_NOTIFY_TYPE_CMODE_CHANGE:
385 * Distribute the notify to local clients on the channel
388 SILC_LOG_DEBUG(("CMODE CHANGE notify"));
390 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
391 packet->dst_id_type);
395 /* Get channel entry */
396 channel = silc_idlist_find_channel_by_id(server->global_list,
399 channel = silc_idlist_find_channel_by_id(server->local_list,
402 silc_free(channel_id);
407 /* Send the same notify to the channel */
408 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
409 FALSE, packet->buffer->data,
410 packet->buffer->len, FALSE);
413 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
415 silc_free(channel_id);
419 SILC_GET32_MSB(mode, tmp);
421 /* If the channel had private keys set and the mode was removed then
422 we must re-generate and re-distribute a new channel key */
423 if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY &&
424 !(mode & SILC_CHANNEL_MODE_PRIVKEY)) {
425 /* Re-generate channel key */
426 silc_server_create_channel_key(server, channel, 0);
428 /* Send the channel key. This sends it to our local clients and if
429 we are normal server to our router as well. */
430 silc_server_send_channel_key(server, NULL, channel,
431 server->server_type == SILC_ROUTER ?
432 FALSE : !server->standalone);
436 channel->mode = mode;
437 silc_free(channel_id);
440 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
442 unsigned char hash[32];
445 silc_hmac_free(channel->hmac);
446 if (!silc_hmac_alloc(tmp, NULL, &channel->hmac))
449 /* Set the HMAC key out of current channel key. The client must do
451 silc_hash_make(channel->hmac->hash, channel->key, channel->key_len / 8,
453 silc_hmac_set_key(channel->hmac, hash,
454 silc_hash_len(channel->hmac->hash));
455 memset(hash, 0, sizeof(hash));
460 case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
462 * Distribute the notify to local clients on the channel
465 SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
467 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
468 packet->dst_id_type);
472 /* Get channel entry */
473 channel = silc_idlist_find_channel_by_id(server->global_list,
476 channel = silc_idlist_find_channel_by_id(server->local_list,
479 silc_free(channel_id);
485 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
487 silc_free(channel_id);
491 SILC_GET32_MSB(mode, tmp);
493 /* Get target client */
494 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
497 client_id = silc_id_payload_parse_id(tmp, tmp_len);
501 /* Get client entry */
502 client = silc_idlist_find_client_by_id(server->global_list,
505 client = silc_idlist_find_client_by_id(server->local_list,
508 silc_free(client_id);
512 silc_free(client_id);
514 /* Get entry to the channel user list */
515 silc_list_start(channel->user_list);
516 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
517 SilcChannelClientEntry chl2 = NULL;
519 /* If the mode is channel founder and we already find a client
520 to have that mode on the channel we will enforce the sender
521 to change the channel founder mode away. There can be only one
522 channel founder on the channel. */
523 if (server->server_type == SILC_ROUTER &&
524 mode & SILC_CHANNEL_UMODE_CHANFO &&
525 chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
526 silc_server_send_notify_cumode(server, sock, FALSE, channel,
527 (mode & (~SILC_CHANNEL_UMODE_CHANFO)),
528 server->id, SILC_ID_SERVER,
530 client->id, SILC_ID_CLIENT_LEN);
531 silc_free(channel_id);
533 /* Change the mode back if we changed it */
535 chl2->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
539 if (chl->client == client) {
540 /* Change the mode */
542 if (!(mode & SILC_CHANNEL_UMODE_CHANFO))
549 /* Send the same notify to the channel */
550 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
551 FALSE, packet->buffer->data,
552 packet->buffer->len, FALSE);
553 silc_free(channel_id);
556 case SILC_NOTIFY_TYPE_INVITE:
558 if (packet->dst_id_type == SILC_ID_CLIENT)
561 SILC_LOG_DEBUG(("INVITE notify"));
564 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
567 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
571 /* Get channel entry */
572 channel = silc_idlist_find_channel_by_id(server->global_list,
575 channel = silc_idlist_find_channel_by_id(server->local_list,
578 silc_free(channel_id);
582 silc_free(channel_id);
584 /* Get the added invite */
585 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
587 if (!channel->invite_list)
588 channel->invite_list = silc_calloc(tmp_len + 2,
589 sizeof(*channel->invite_list));
591 channel->invite_list = silc_realloc(channel->invite_list,
592 sizeof(*channel->invite_list) *
594 strlen(channel->invite_list) +
596 if (tmp[tmp_len - 1] == ',')
597 tmp[tmp_len - 1] = '\0';
599 strncat(channel->invite_list, tmp, tmp_len);
600 strncat(channel->invite_list, ",", 1);
603 /* Get the deleted invite */
604 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
605 if (tmp && channel->invite_list) {
606 char *start, *end, *n;
608 if (!strncmp(channel->invite_list, tmp,
609 strlen(channel->invite_list) - 1)) {
610 silc_free(channel->invite_list);
611 channel->invite_list = NULL;
613 start = strstr(channel->invite_list, tmp);
614 if (start && strlen(start) >= tmp_len) {
615 end = start + tmp_len;
616 n = silc_calloc(strlen(channel->invite_list) - tmp_len, sizeof(*n));
617 strncat(n, channel->invite_list, start - channel->invite_list);
618 strncat(n, end + 1, ((channel->invite_list +
619 strlen(channel->invite_list)) - end) - 1);
620 silc_free(channel->invite_list);
621 channel->invite_list = n;
628 case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
630 * Distribute to the local clients on the channel and change the
634 SILC_LOG_DEBUG(("CHANNEL CHANGE"));
636 if (sock->type != SILC_SOCKET_TYPE_ROUTER)
639 /* Get the old Channel ID */
640 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
643 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
647 /* Get the channel entry */
648 channel = silc_idlist_find_channel_by_id(server->global_list,
651 channel = silc_idlist_find_channel_by_id(server->local_list,
654 silc_free(channel_id);
659 /* Send the notify to the channel */
660 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
661 FALSE, packet->buffer->data,
662 packet->buffer->len, FALSE);
664 /* Get the new Channel ID */
665 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
668 channel_id2 = silc_id_payload_parse_id(tmp, tmp_len);
672 SILC_LOG_DEBUG(("Old Channel ID id(%s)",
673 silc_id_render(channel_id, SILC_ID_CHANNEL)));
674 SILC_LOG_DEBUG(("New Channel ID id(%s)",
675 silc_id_render(channel_id2, SILC_ID_CHANNEL)));
677 /* Replace the Channel ID */
678 if (!silc_idlist_replace_channel_id(server->global_list, channel_id,
680 if (!silc_idlist_replace_channel_id(server->local_list, channel_id,
682 silc_free(channel_id2);
687 SilcBuffer users = NULL, users_modes = NULL;
689 /* Re-announce our clients on the channel as the ID has changed now */
690 silc_server_announce_get_channel_users(server, channel, &users,
693 silc_buffer_push(users, users->data - users->head);
694 silc_server_packet_send(server, sock,
695 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
696 users->data, users->len, FALSE);
697 silc_buffer_free(users);
700 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
701 silc_server_packet_send(server, sock,
702 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
703 users_modes->data, users_modes->len, FALSE);
704 silc_buffer_free(users_modes);
708 silc_free(channel_id);
712 case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
714 * Remove the server entry and all clients that this server owns.
717 SILC_LOG_DEBUG(("SERVER SIGNOFF notify"));
720 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
723 server_id = silc_id_payload_parse_id(tmp, tmp_len);
727 /* Get server entry */
728 server_entry = silc_idlist_find_server_by_id(server->global_list,
731 server_entry = silc_idlist_find_server_by_id(server->local_list,
734 silc_free(server_id);
738 silc_free(server_id);
740 /* Free all client entries that this server owns as they will
741 become invalid now as well. */
742 silc_server_remove_clients_by_server(server, server_entry, TRUE);
744 /* Remove the server entry */
745 if (!silc_idlist_del_server(server->global_list, server_entry))
746 silc_idlist_del_server(server->local_list, server_entry);
748 /* XXX update statistics */
752 case SILC_NOTIFY_TYPE_KICKED:
754 * Distribute the notify to local clients on the channel
757 SILC_LOG_DEBUG(("KICKED notify"));
759 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
760 packet->dst_id_type);
764 /* Get channel entry */
765 channel = silc_idlist_find_channel_by_id(server->global_list,
768 channel = silc_idlist_find_channel_by_id(server->local_list,
771 silc_free(channel_id);
775 silc_free(channel_id);
778 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
781 client_id = silc_id_payload_parse_id(tmp, tmp_len);
785 /* Send to channel */
786 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
787 FALSE, packet->buffer->data,
788 packet->buffer->len, FALSE);
790 /* If the the client is not in local list we check global list */
791 client = silc_idlist_find_client_by_id(server->global_list,
794 client = silc_idlist_find_client_by_id(server->local_list,
797 silc_free(client_id);
802 /* Remove the client from channel */
803 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
807 case SILC_NOTIFY_TYPE_KILLED:
810 * Distribute the notify to local clients on channels
815 SILC_LOG_DEBUG(("KILLED notify"));
818 id = silc_argument_get_arg_type(args, 1, &id_len);
821 client_id = silc_id_payload_parse_id(id, id_len);
825 /* If the the client is not in local list we check global list */
826 client = silc_idlist_find_client_by_id(server->global_list,
829 client = silc_idlist_find_client_by_id(server->local_list,
832 silc_free(client_id);
836 silc_free(client_id);
838 /* If the client is one of ours, then close the connection to the
839 client now. This removes the client from all channels as well. */
840 if (packet->dst_id_type == SILC_ID_CLIENT && client->data.registered &&
841 client->connection) {
842 sock = client->connection;
843 silc_server_free_client_data(server, NULL, client, FALSE, NULL);
844 silc_server_close_connection(server, sock);
849 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
853 /* Send the notify to local clients on the channels except to the
854 client who is killed. */
855 silc_server_send_notify_on_channels(server, client, client,
856 SILC_NOTIFY_TYPE_KILLED,
861 /* Remove the client from all channels */
862 silc_server_remove_from_channels(server, NULL, client, FALSE, NULL,
868 case SILC_NOTIFY_TYPE_UMODE_CHANGE:
870 * Save the mode of the client.
873 SILC_LOG_DEBUG(("UMODE_CHANGE notify"));
876 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
879 client_id = silc_id_payload_parse_id(tmp, tmp_len);
883 /* Get client entry */
884 client = silc_idlist_find_client_by_id(server->global_list,
887 client = silc_idlist_find_client_by_id(server->local_list,
890 silc_free(client_id);
894 silc_free(client_id);
897 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
902 SILC_GET32_MSB(client->mode, tmp);
906 case SILC_NOTIFY_TYPE_BAN:
911 SILC_LOG_DEBUG(("BAN notify"));
914 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
917 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
921 /* Get channel entry */
922 channel = silc_idlist_find_channel_by_id(server->global_list,
925 channel = silc_idlist_find_channel_by_id(server->local_list,
928 silc_free(channel_id);
932 silc_free(channel_id);
934 /* Get the new ban and add it to the ban list */
935 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
937 if (!channel->ban_list)
938 channel->ban_list = silc_calloc(tmp_len + 2,
939 sizeof(*channel->ban_list));
941 channel->ban_list = silc_realloc(channel->ban_list,
942 sizeof(*channel->ban_list) *
944 strlen(channel->ban_list) + 2));
945 strncat(channel->ban_list, tmp, tmp_len);
946 strncat(channel->ban_list, ",", 1);
949 /* Get the ban to be removed and remove it from the list */
950 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
951 if (tmp && channel->ban_list) {
952 char *start, *end, *n;
954 if (!strcmp(channel->ban_list, tmp)) {
955 silc_free(channel->ban_list);
956 channel->ban_list = NULL;
958 start = strstr(channel->ban_list, tmp);
959 if (start && strlen(start) >= tmp_len) {
960 end = start + tmp_len;
961 n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
962 strncat(n, channel->ban_list, start - channel->ban_list);
963 strncat(n, end + 1, ((channel->ban_list +
964 strlen(channel->ban_list)) - end) - 1);
965 silc_free(channel->ban_list);
966 channel->ban_list = n;
973 /* Ignore rest of the notify types for now */
974 case SILC_NOTIFY_TYPE_NONE:
975 case SILC_NOTIFY_TYPE_MOTD:
982 silc_notify_payload_free(payload);
985 void silc_server_notify_list(SilcServer server,
986 SilcSocketConnection sock,
987 SilcPacketContext *packet)
989 SilcPacketContext *new;
993 SILC_LOG_DEBUG(("Processing Notify List"));
995 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
996 packet->src_id_type != SILC_ID_SERVER)
999 /* Make copy of the original packet context, except for the actual
1000 data buffer, which we will here now fetch from the original buffer. */
1001 new = silc_packet_context_alloc();
1002 new->type = SILC_PACKET_NOTIFY;
1003 new->flags = packet->flags;
1004 new->src_id = packet->src_id;
1005 new->src_id_len = packet->src_id_len;
1006 new->src_id_type = packet->src_id_type;
1007 new->dst_id = packet->dst_id;
1008 new->dst_id_len = packet->dst_id_len;
1009 new->dst_id_type = packet->dst_id_type;
1011 buffer = silc_buffer_alloc(1024);
1012 new->buffer = buffer;
1014 while (packet->buffer->len) {
1015 SILC_GET16_MSB(len, packet->buffer->data + 2);
1016 if (len > packet->buffer->len)
1019 if (len > buffer->truelen) {
1020 silc_buffer_free(buffer);
1021 buffer = silc_buffer_alloc(1024 + len);
1024 silc_buffer_pull_tail(buffer, len);
1025 silc_buffer_put(buffer, packet->buffer->data, len);
1027 /* Process the Notify */
1028 silc_server_notify(server, sock, new);
1030 silc_buffer_push_tail(buffer, len);
1031 silc_buffer_pull(packet->buffer, len);
1034 silc_buffer_free(buffer);
1038 /* Received private message. This resolves the destination of the message
1039 and sends the packet. This is used by both server and router. If the
1040 destination is our locally connected client this sends the packet to
1041 the client. This may also send the message for further routing if
1042 the destination is not in our server (or router). */
1044 void silc_server_private_message(SilcServer server,
1045 SilcSocketConnection sock,
1046 SilcPacketContext *packet)
1048 SilcSocketConnection dst_sock;
1049 SilcIDListData idata;
1051 SILC_LOG_DEBUG(("Start"));
1053 if (packet->src_id_type != SILC_ID_CLIENT ||
1054 packet->dst_id_type != SILC_ID_CLIENT)
1057 if (!packet->dst_id)
1060 /* Get the route to the client */
1061 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1062 packet->dst_id_len, NULL, &idata);
1066 /* Send the private message */
1067 silc_server_send_private_message(server, dst_sock, idata->send_key,
1068 idata->hmac_send, packet);
1071 /* Received private message key packet.. This packet is never for us. It is to
1072 the client in the packet's destination ID. Sending of this sort of packet
1073 equals sending private message, ie. it is sent point to point from
1074 one client to another. */
1076 void silc_server_private_message_key(SilcServer server,
1077 SilcSocketConnection sock,
1078 SilcPacketContext *packet)
1080 SilcSocketConnection dst_sock;
1081 SilcIDListData idata;
1083 SILC_LOG_DEBUG(("Start"));
1085 if (packet->src_id_type != SILC_ID_CLIENT ||
1086 packet->dst_id_type != SILC_ID_CLIENT)
1089 if (!packet->dst_id)
1092 /* Get the route to the client */
1093 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1094 packet->dst_id_len, NULL, &idata);
1098 /* Relay the packet */
1099 silc_server_relay_packet(server, dst_sock, idata->send_key,
1100 idata->hmac_send, packet, FALSE);
1103 /* Processes incoming command reply packet. The command reply packet may
1104 be destined to one of our clients or it may directly for us. We will
1105 call the command reply routine after processing the packet. */
1107 void silc_server_command_reply(SilcServer server,
1108 SilcSocketConnection sock,
1109 SilcPacketContext *packet)
1111 SilcBuffer buffer = packet->buffer;
1112 SilcClientEntry client = NULL;
1113 SilcSocketConnection dst_sock;
1114 SilcIDListData idata;
1115 SilcClientID *id = NULL;
1117 SILC_LOG_DEBUG(("Start"));
1119 /* Source must be server or router */
1120 if (packet->src_id_type != SILC_ID_SERVER &&
1121 sock->type != SILC_SOCKET_TYPE_ROUTER)
1124 if (packet->dst_id_type == SILC_ID_CHANNEL)
1127 if (packet->dst_id_type == SILC_ID_CLIENT) {
1128 /* Destination must be one of ours */
1129 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
1132 client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
1134 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
1140 if (packet->dst_id_type == SILC_ID_SERVER) {
1141 /* For now this must be for us */
1142 if (SILC_ID_SERVER_COMPARE(packet->dst_id, server->id_string)) {
1143 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
1148 /* Execute command reply locally for the command */
1149 silc_server_command_reply_process(server, sock, buffer);
1151 if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
1152 /* Relay the packet to the client */
1154 dst_sock = (SilcSocketConnection)client->connection;
1155 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
1156 + packet->dst_id_len + packet->padlen);
1158 silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
1159 silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
1161 idata = (SilcIDListData)client;
1163 /* Encrypt packet */
1164 silc_packet_encrypt(idata->send_key, idata->hmac_send, dst_sock->outbuf,
1167 /* Send the packet */
1168 silc_server_packet_send_real(server, dst_sock, TRUE);
1174 /* Process received channel message. The message can be originated from
1175 client or server. */
1177 void silc_server_channel_message(SilcServer server,
1178 SilcSocketConnection sock,
1179 SilcPacketContext *packet)
1181 SilcChannelEntry channel = NULL;
1182 SilcChannelClientEntry chl;
1183 SilcChannelID *id = NULL;
1184 void *sender = NULL;
1185 void *sender_entry = NULL;
1187 SILC_LOG_DEBUG(("Processing channel message"));
1190 if (packet->dst_id_type != SILC_ID_CHANNEL) {
1191 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1195 /* Find channel entry */
1196 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
1199 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
1201 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
1203 SILC_LOG_DEBUG(("Could not find channel"));
1208 /* See that this client is on the channel. If the message is coming
1209 from router we won't do the check as the message is from client that
1210 we don't know about. Also, if the original sender is not client
1211 (as it can be server as well) we don't do the check. */
1212 sender = silc_id_str2id(packet->src_id, packet->src_id_len,
1213 packet->src_id_type);
1216 if (packet->src_id_type == SILC_ID_CLIENT) {
1217 silc_list_start(channel->user_list);
1218 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
1219 if (chl->client && !SILC_ID_CLIENT_COMPARE(chl->client->id, sender)) {
1220 sender_entry = chl->client;
1224 if (chl == SILC_LIST_END) {
1225 SILC_LOG_DEBUG(("Client not on channel"));
1230 /* Distribute the packet to our local clients. This will send the
1231 packet for further routing as well, if needed. */
1232 silc_server_packet_relay_to_channel(server, sock, channel, sender,
1233 packet->src_id_type, sender_entry,
1234 packet->buffer->data,
1235 packet->buffer->len, FALSE);
1244 /* Received channel key packet. We distribute the key to all of our locally
1245 connected clients on the channel. */
1247 void silc_server_channel_key(SilcServer server,
1248 SilcSocketConnection sock,
1249 SilcPacketContext *packet)
1251 SilcBuffer buffer = packet->buffer;
1252 SilcChannelEntry channel;
1254 if (packet->src_id_type != SILC_ID_SERVER ||
1255 (server->server_type == SILC_ROUTER &&
1256 sock->type == SILC_SOCKET_TYPE_ROUTER))
1259 /* Save the channel key */
1260 channel = silc_server_save_channel_key(server, buffer, NULL);
1264 /* Distribute the key to everybody who is on the channel. If we are router
1265 we will also send it to locally connected servers. */
1266 silc_server_send_channel_key(server, sock, channel, FALSE);
1269 /* Received New Client packet and processes it. Creates Client ID for the
1270 client. Client becomes registered after calling this functions. */
1272 SilcClientEntry silc_server_new_client(SilcServer server,
1273 SilcSocketConnection sock,
1274 SilcPacketContext *packet)
1276 SilcBuffer buffer = packet->buffer;
1277 SilcClientEntry client;
1278 SilcIDCacheEntry cache;
1279 SilcClientID *client_id;
1281 SilcIDListData idata;
1282 char *username = NULL, *realname = NULL, *id_string;
1285 SILC_LOG_DEBUG(("Creating new client"));
1287 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
1290 /* Take client entry */
1291 client = (SilcClientEntry)sock->user_data;
1292 idata = (SilcIDListData)client;
1294 /* Fetch the old client cache entry so that we can update it. */
1295 if (!silc_idcache_find_by_context(server->local_list->clients,
1296 sock->user_data, &cache)) {
1297 SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
1298 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1303 /* Parse incoming packet */
1304 ret = silc_buffer_unformat(buffer,
1305 SILC_STR_UI16_STRING_ALLOC(&username),
1306 SILC_STR_UI16_STRING_ALLOC(&realname),
1310 silc_free(username);
1312 silc_free(realname);
1313 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1314 "Incomplete client information");
1319 silc_free(username);
1321 silc_free(realname);
1322 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1323 "Incomplete client information");
1327 /* Create Client ID */
1328 silc_id_create_client_id(server->id, server->rng, server->md5hash,
1329 username, &client_id);
1331 if (strlen(username) > 128)
1332 username[127] = '\0';
1334 /* Update client entry */
1335 idata->registered = TRUE;
1336 client->nickname = strdup(username);
1337 client->username = username;
1338 client->userinfo = realname ? realname : strdup(" ");
1339 client->id = client_id;
1341 /* Update the cache entry */
1342 cache->id = (void *)client_id;
1343 cache->type = SILC_ID_CLIENT;
1344 cache->data = username;
1345 cache->data_len = strlen(username);
1346 silc_idcache_sort_by_data(server->local_list->clients);
1348 /* Notify our router about new client on the SILC network */
1349 if (!server->standalone)
1350 silc_server_send_new_id(server, (SilcSocketConnection)
1351 server->router->connection,
1352 server->server_type == SILC_ROUTER ? TRUE : FALSE,
1353 client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
1355 /* Send the new client ID to the client. */
1356 id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
1357 reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
1358 silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
1359 silc_buffer_format(reply,
1360 SILC_STR_UI_SHORT(SILC_ID_CLIENT),
1361 SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
1362 SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
1364 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0,
1365 reply->data, reply->len, FALSE);
1366 silc_free(id_string);
1367 silc_buffer_free(reply);
1369 /* Send some nice info to the client */
1370 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1371 ("Welcome to the SILC Network %s@%s",
1372 username, sock->hostname));
1373 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1374 ("Your host is %s, running version %s",
1375 server->config->server_info->server_name,
1377 if (server->server_type == SILC_ROUTER) {
1378 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1379 ("There are %d clients on %d servers in SILC "
1380 "Network", server->stat.clients,
1381 server->stat.servers + 1));
1382 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1383 ("There are %d clients on %d server in our cell",
1384 server->stat.cell_clients,
1385 server->stat.cell_servers + 1));
1386 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1387 ("I have %d clients, %d channels, %d servers and "
1389 server->stat.my_clients,
1390 server->stat.my_channels,
1391 server->stat.my_servers,
1392 server->stat.my_routers));
1393 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1394 ("%d server operators and %d router operators "
1396 server->stat.my_server_ops,
1397 server->stat.my_router_ops));
1399 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1400 ("I have %d clients and %d channels formed",
1401 server->stat.my_clients,
1402 server->stat.my_channels));
1403 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1404 ("%d operators online",
1405 server->stat.my_server_ops));
1407 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1408 ("Your connection is secured with %s cipher, "
1409 "key length %d bits",
1410 idata->send_key->cipher->name,
1411 idata->send_key->cipher->key_len));
1412 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1413 ("Your current nickname is %s",
1417 silc_server_send_motd(server, sock);
1422 /* Create new server. This processes received New Server packet and
1423 saves the received Server ID. The server is our locally connected
1424 server thus we save all the information and save it to local list.
1425 This funtion can be used by both normal server and router server.
1426 If normal server uses this it means that its router has connected
1427 to the server. If router uses this it means that one of the cell's
1428 servers is connected to the router. */
1430 SilcServerEntry silc_server_new_server(SilcServer server,
1431 SilcSocketConnection sock,
1432 SilcPacketContext *packet)
1434 SilcBuffer buffer = packet->buffer;
1435 SilcServerEntry new_server;
1436 SilcIDCacheEntry cache;
1437 SilcServerID *server_id;
1438 SilcIDListData idata;
1439 unsigned char *server_name, *id_string;
1440 uint16 id_len, name_len;
1443 SILC_LOG_DEBUG(("Creating new server"));
1445 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
1446 sock->type != SILC_SOCKET_TYPE_ROUTER)
1449 /* Take server entry */
1450 new_server = (SilcServerEntry)sock->user_data;
1451 idata = (SilcIDListData)new_server;
1453 /* Fetch the old server cache entry so that we can update it. */
1454 if (!silc_idcache_find_by_context(server->local_list->servers,
1455 sock->user_data, &cache)) {
1456 SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
1460 /* Parse the incoming packet */
1461 ret = silc_buffer_unformat(buffer,
1462 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
1463 SILC_STR_UI16_NSTRING_ALLOC(&server_name,
1468 silc_free(id_string);
1470 silc_free(server_name);
1474 if (id_len > buffer->len) {
1475 silc_free(id_string);
1476 silc_free(server_name);
1481 server_name[255] = '\0';
1484 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
1486 silc_free(id_string);
1487 silc_free(server_name);
1490 silc_free(id_string);
1492 /* Update client entry */
1493 idata->registered = TRUE;
1494 new_server->server_name = server_name;
1495 new_server->id = server_id;
1497 /* Update the cache entry */
1498 cache->id = (void *)server_id;
1499 cache->type = SILC_ID_SERVER;
1500 cache->data = server_name;
1501 cache->data_len = strlen(server_name);
1502 silc_idcache_sort_by_data(server->local_list->servers);
1504 /* Distribute the information about new server in the SILC network
1505 to our router. If we are normal server we won't send anything
1506 since this connection must be our router connection. */
1507 if (server->server_type == SILC_ROUTER && !server->standalone &&
1508 server->router->connection != sock)
1509 silc_server_send_new_id(server, server->router->connection,
1510 TRUE, new_server->id, SILC_ID_SERVER,
1511 SILC_ID_SERVER_LEN);
1513 if (server->server_type == SILC_ROUTER)
1514 server->stat.cell_servers++;
1519 /* Processes incoming New ID packet. New ID Payload is used to distribute
1520 information about newly registered clients and servers. */
1522 static void silc_server_new_id_real(SilcServer server,
1523 SilcSocketConnection sock,
1524 SilcPacketContext *packet,
1527 SilcBuffer buffer = packet->buffer;
1529 SilcServerEntry router;
1530 SilcSocketConnection router_sock;
1533 unsigned char *hash = NULL;
1536 SILC_LOG_DEBUG(("Processing new ID"));
1538 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1539 server->server_type == SILC_SERVER ||
1540 packet->src_id_type != SILC_ID_SERVER)
1543 idp = silc_id_payload_parse(buffer);
1547 id_type = silc_id_payload_get_type(idp);
1549 /* Normal server cannot have other normal server connections */
1550 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
1553 id = silc_id_payload_get_id(idp);
1557 /* If the sender of this packet is server and we are router we need to
1558 broadcast this packet to other routers in the network. */
1559 if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
1560 sock->type == SILC_SOCKET_TYPE_SERVER &&
1561 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1562 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
1563 silc_server_packet_send(server, server->router->connection,
1565 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1566 buffer->data, buffer->len, FALSE);
1569 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1570 id_list = server->local_list;
1572 id_list = server->global_list;
1574 /* If the packet is coming from server then use the sender as the
1575 origin of the the packet. If it came from router then check the real
1576 sender of the packet and use that as the origin. */
1577 if (sock->type == SILC_SOCKET_TYPE_SERVER) {
1579 router = sock->user_data;
1581 void *sender_id = silc_id_str2id(packet->src_id, packet->src_id_len,
1582 packet->src_id_type);
1583 router = silc_idlist_find_server_by_id(server->global_list,
1586 router = silc_idlist_find_server_by_id(server->local_list,
1588 silc_free(sender_id);
1595 case SILC_ID_CLIENT:
1597 SilcClientEntry entry;
1599 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
1600 silc_id_render(id, SILC_ID_CLIENT),
1601 sock->type == SILC_SOCKET_TYPE_SERVER ?
1602 "Server" : "Router", sock->hostname));
1604 /* As a router we keep information of all global information in our
1605 global list. Cell wide information however is kept in the local
1606 list. The client is put to global list and we will take the hash
1607 value of the Client ID and save it to the ID Cache system for fast
1608 searching in the future. */
1609 hash = silc_calloc(sizeof(((SilcClientID *)id)->hash),
1610 sizeof(unsigned char));
1611 memcpy(hash, ((SilcClientID *)id)->hash,
1612 sizeof(((SilcClientID *)id)->hash));
1613 entry = silc_idlist_add_client(id_list, hash,
1614 sizeof(((SilcClientID *)id)->hash),
1615 NULL, NULL, id, router, NULL);
1616 entry->nickname = NULL;
1617 entry->data.registered = TRUE;
1619 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1620 server->stat.cell_clients++;
1621 server->stat.clients++;
1625 case SILC_ID_SERVER:
1626 /* If the ID is mine, ignore it. */
1627 if (!SILC_ID_SERVER_COMPARE(id, server->id)) {
1628 SILC_LOG_DEBUG(("Ignoring my own ID as new ID"));
1632 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
1633 silc_id_render(id, SILC_ID_SERVER),
1634 sock->type == SILC_SOCKET_TYPE_SERVER ?
1635 "Server" : "Router", sock->hostname));
1637 /* As a router we keep information of all global information in our global
1638 list. Cell wide information however is kept in the local list. */
1639 silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
1641 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1642 server->stat.cell_servers++;
1643 server->stat.servers++;
1646 case SILC_ID_CHANNEL:
1647 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
1655 silc_id_payload_free(idp);
1659 /* Processes incoming New ID packet. New ID Payload is used to distribute
1660 information about newly registered clients and servers. */
1662 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
1663 SilcPacketContext *packet)
1665 silc_server_new_id_real(server, sock, packet, TRUE);
1668 /* Receoved New Id List packet, list of New ID payloads inside one
1669 packet. Process the New ID payloads one by one. */
1671 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
1672 SilcPacketContext *packet)
1674 SilcPacketContext *new_id;
1678 SILC_LOG_DEBUG(("Processing New ID List"));
1680 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1681 packet->src_id_type != SILC_ID_SERVER)
1684 /* If the sender of this packet is server and we are router we need to
1685 broadcast this packet to other routers in the network. Broadcast
1686 this list packet instead of multiple New ID packets. */
1687 if (!server->standalone && server->server_type == SILC_ROUTER &&
1688 sock->type == SILC_SOCKET_TYPE_SERVER &&
1689 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1690 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
1691 silc_server_packet_send(server, server->router->connection,
1693 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1694 packet->buffer->data, packet->buffer->len, FALSE);
1697 /* Make copy of the original packet context, except for the actual
1698 data buffer, which we will here now fetch from the original buffer. */
1699 new_id = silc_packet_context_alloc();
1700 new_id->type = SILC_PACKET_NEW_ID;
1701 new_id->flags = packet->flags;
1702 new_id->src_id = packet->src_id;
1703 new_id->src_id_len = packet->src_id_len;
1704 new_id->src_id_type = packet->src_id_type;
1705 new_id->dst_id = packet->dst_id;
1706 new_id->dst_id_len = packet->dst_id_len;
1707 new_id->dst_id_type = packet->dst_id_type;
1709 idp = silc_buffer_alloc(256);
1710 new_id->buffer = idp;
1712 while (packet->buffer->len) {
1713 SILC_GET16_MSB(id_len, packet->buffer->data + 2);
1714 if ((id_len > packet->buffer->len) ||
1715 (id_len > idp->truelen))
1718 silc_buffer_pull_tail(idp, 4 + id_len);
1719 silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
1721 /* Process the New ID */
1722 silc_server_new_id_real(server, sock, new_id, FALSE);
1724 silc_buffer_push_tail(idp, 4 + id_len);
1725 silc_buffer_pull(packet->buffer, 4 + id_len);
1728 silc_buffer_free(idp);
1732 /* Received New Channel packet. Information about new channels in the
1733 network are distributed using this packet. Save the information about
1734 the new channel. This usually comes from router but also normal server
1735 can send this to notify channels it has when it connects to us. */
1737 void silc_server_new_channel(SilcServer server,
1738 SilcSocketConnection sock,
1739 SilcPacketContext *packet)
1741 SilcChannelPayload payload;
1742 SilcChannelID *channel_id;
1749 SILC_LOG_DEBUG(("Processing New Channel"));
1751 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1752 packet->src_id_type != SILC_ID_SERVER ||
1753 server->server_type == SILC_SERVER)
1756 /* Parse the channel payload */
1757 payload = silc_channel_payload_parse(packet->buffer);
1761 /* Get the channel ID */
1762 channel_id = silc_channel_get_id_parse(payload);
1764 silc_channel_payload_free(payload);
1768 channel_name = silc_channel_get_name(payload, &name_len);
1770 channel_name[255] = '\0';
1772 id = silc_channel_get_id(payload, &id_len);
1774 if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
1775 /* Add the server to global list as it is coming from router. It
1776 cannot be our own channel as it is coming from router. */
1778 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
1779 silc_id_render(channel_id, SILC_ID_CHANNEL),
1782 silc_idlist_add_channel(server->global_list, strdup(channel_name),
1783 0, channel_id, server->router->connection,
1786 server->stat.channels++;
1788 /* The channel is coming from our server, thus it is in our cell
1789 we will add it to our local list. */
1790 SilcChannelEntry channel;
1793 SILC_LOG_DEBUG(("New channel id(%s) from [Server] %s",
1794 silc_id_render(channel_id, SILC_ID_CHANNEL),
1797 /* Check that we don't already have this channel */
1798 channel = silc_idlist_find_channel_by_name(server->local_list,
1799 channel_name, NULL);
1801 channel = silc_idlist_find_channel_by_name(server->global_list,
1802 channel_name, NULL);
1804 /* If the channel does not exist, then create it. We create the channel
1805 with the channel ID provided by the server. This creates a new
1806 key to the channel as well that we will send to the server. */
1808 channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
1812 silc_channel_payload_free(payload);
1813 silc_free(channel_id);
1817 /* Send the new channel key to the server */
1818 chk = silc_channel_key_payload_encode(id_len, id,
1819 strlen(channel->channel_key->
1821 channel->channel_key->cipher->name,
1822 channel->key_len / 8,
1824 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
1825 chk->data, chk->len, FALSE);
1826 silc_buffer_free(chk);
1829 /* The channel exist by that name, check whether the ID's match.
1830 If they don't then we'll force the server to use the ID we have.
1831 We also create a new key for the channel. */
1832 SilcBuffer users = NULL, users_modes = NULL;
1835 channel_id = silc_id_dup(channel_id, SILC_ID_CHANNEL);
1837 if (SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
1838 /* They don't match, send CHANNEL_CHANGE notify to the server to
1839 force the ID change. */
1840 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
1841 silc_server_send_notify_channel_change(server, sock, FALSE,
1844 SILC_ID_CHANNEL_LEN);
1847 /* If the mode is different from what we have then enforce the
1849 mode = silc_channel_get_mode(payload);
1850 if (channel->mode != mode) {
1851 SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
1852 silc_server_send_notify_cmode(server, sock, FALSE, channel,
1853 channel->mode, server->id,
1854 SILC_ID_SERVER, SILC_ID_SERVER_LEN,
1855 channel->cipher, channel->hmac_name);
1858 /* Create new key for the channel and send it to the server and
1859 everybody else possibly on the channel. */
1861 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
1862 silc_server_create_channel_key(server, channel, 0);
1864 /* Send to the channel */
1865 silc_server_send_channel_key(server, sock, channel, FALSE);
1866 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
1867 id_len = SILC_ID_CHANNEL_LEN;
1869 /* Send to the server */
1870 chk = silc_channel_key_payload_encode(id_len, id,
1871 strlen(channel->channel_key->
1873 channel->channel_key->
1875 channel->key_len / 8,
1877 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
1878 chk->data, chk->len, FALSE);
1879 silc_buffer_free(chk);
1883 silc_free(channel_id);
1885 /* Since the channel is coming from server and we also know about it
1886 then send the JOIN notify to the server so that it see's our
1887 users on the channel "joining" the channel. */
1888 silc_server_announce_get_channel_users(server, channel, &users,
1891 silc_buffer_push(users, users->data - users->head);
1892 silc_server_packet_send(server, sock,
1893 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1894 users->data, users->len, FALSE);
1895 silc_buffer_free(users);
1898 silc_buffer_push(users_modes, users_modes->data - users_modes->head);
1899 silc_server_packet_send(server, sock,
1900 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1901 users_modes->data, users_modes->len, FALSE);
1902 silc_buffer_free(users_modes);
1907 silc_channel_payload_free(payload);
1910 /* Received New Channel List packet, list of New Channel List payloads inside
1911 one packet. Process the New Channel payloads one by one. */
1913 void silc_server_new_channel_list(SilcServer server,
1914 SilcSocketConnection sock,
1915 SilcPacketContext *packet)
1917 SilcPacketContext *new;
1921 SILC_LOG_DEBUG(("Processing New Channel List"));
1923 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1924 packet->src_id_type != SILC_ID_SERVER ||
1925 server->server_type == SILC_SERVER)
1928 /* If the sender of this packet is server and we are router we need to
1929 broadcast this packet to other routers in the network. Broadcast
1930 this list packet instead of multiple New Channel packets. */
1931 if (!server->standalone && server->server_type == SILC_ROUTER &&
1932 sock->type == SILC_SOCKET_TYPE_SERVER &&
1933 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1934 SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
1935 silc_server_packet_send(server, server->router->connection,
1937 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1938 packet->buffer->data, packet->buffer->len, FALSE);
1941 /* Make copy of the original packet context, except for the actual
1942 data buffer, which we will here now fetch from the original buffer. */
1943 new = silc_packet_context_alloc();
1944 new->type = SILC_PACKET_NEW_CHANNEL;
1945 new->flags = packet->flags;
1946 new->src_id = packet->src_id;
1947 new->src_id_len = packet->src_id_len;
1948 new->src_id_type = packet->src_id_type;
1949 new->dst_id = packet->dst_id;
1950 new->dst_id_len = packet->dst_id_len;
1951 new->dst_id_type = packet->dst_id_type;
1953 buffer = silc_buffer_alloc(512);
1954 new->buffer = buffer;
1956 while (packet->buffer->len) {
1957 SILC_GET16_MSB(len1, packet->buffer->data);
1958 if ((len1 > packet->buffer->len) ||
1959 (len1 > buffer->truelen))
1962 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
1963 if ((len2 > packet->buffer->len) ||
1964 (len2 > buffer->truelen))
1967 silc_buffer_pull_tail(buffer, 8 + len1 + len2);
1968 silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
1970 /* Process the New Channel */
1971 silc_server_new_channel(server, sock, new);
1973 silc_buffer_push_tail(buffer, 8 + len1 + len2);
1974 silc_buffer_pull(packet->buffer, 8 + len1 + len2);
1977 silc_buffer_free(buffer);
1981 /* Received key agreement packet. This packet is never for us. It is to
1982 the client in the packet's destination ID. Sending of this sort of packet
1983 equals sending private message, ie. it is sent point to point from
1984 one client to another. */
1986 void silc_server_key_agreement(SilcServer server,
1987 SilcSocketConnection sock,
1988 SilcPacketContext *packet)
1990 SilcSocketConnection dst_sock;
1991 SilcIDListData idata;
1993 SILC_LOG_DEBUG(("Start"));
1995 if (packet->src_id_type != SILC_ID_CLIENT ||
1996 packet->dst_id_type != SILC_ID_CLIENT)
1999 if (!packet->dst_id)
2002 /* Get the route to the client */
2003 dst_sock = silc_server_get_client_route(server, packet->dst_id,
2004 packet->dst_id_len, NULL, &idata);
2008 /* Relay the packet */
2009 silc_server_relay_packet(server, dst_sock, idata->send_key,
2010 idata->hmac_send, packet, FALSE);
2013 /* Received connection auth request packet that is used during connection
2014 phase to resolve the mandatory authentication method. This packet can
2015 actually be received at anytime but usually it is used only during
2016 the connection authentication phase. Now, protocol says that this packet
2017 can come from client or server, however, we support only this coming
2018 from client and expect that server's always knows what authentication
2021 void silc_server_connection_auth_request(SilcServer server,
2022 SilcSocketConnection sock,
2023 SilcPacketContext *packet)
2025 SilcServerConfigSectionClientConnection *client = NULL;
2028 SilcAuthMethod auth_meth;
2030 SILC_LOG_DEBUG(("Start"));
2032 if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT)
2035 /* Parse the payload */
2036 ret = silc_buffer_unformat(packet->buffer,
2037 SILC_STR_UI_SHORT(&conn_type),
2038 SILC_STR_UI_SHORT(NULL),
2043 if (conn_type != SILC_SOCKET_TYPE_CLIENT)
2046 /* Get the authentication method for the client */
2047 auth_meth = SILC_AUTH_NONE;
2048 client = silc_server_config_find_client_conn(server->config,
2052 client = silc_server_config_find_client_conn(server->config,
2056 auth_meth = client->auth_meth;
2058 /* Send it back to the client */
2059 silc_server_send_connection_auth_request(server, sock,
2064 /* Received REKEY packet. The sender of the packet wants to regenerate
2065 its session keys. This starts the REKEY protocol. */
2067 void silc_server_rekey(SilcServer server,
2068 SilcSocketConnection sock,
2069 SilcPacketContext *packet)
2071 SilcProtocol protocol;
2072 SilcServerRekeyInternalContext *proto_ctx;
2073 SilcIDListData idata = (SilcIDListData)sock->user_data;
2075 SILC_LOG_DEBUG(("Start"));
2077 /* Allocate internal protocol context. This is sent as context
2079 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
2080 proto_ctx->server = (void *)server;
2081 proto_ctx->sock = sock;
2082 proto_ctx->responder = TRUE;
2083 proto_ctx->pfs = idata->rekey->pfs;
2085 /* Perform rekey protocol. Will call the final callback after the
2086 protocol is over. */
2087 silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
2088 &protocol, proto_ctx, silc_server_rekey_final);
2089 sock->protocol = protocol;
2091 if (proto_ctx->pfs == FALSE)
2092 /* Run the protocol */
2093 protocol->execute(server->timeout_queue, 0, protocol, sock->sock, 0, 0);