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 if (chl->client == client) {
518 /* Change the mode */
523 /* Send the same notify to the channel */
524 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
525 FALSE, packet->buffer->data,
526 packet->buffer->len, FALSE);
527 silc_free(channel_id);
530 case SILC_NOTIFY_TYPE_INVITE:
532 if (packet->dst_id_type == SILC_ID_CLIENT)
535 SILC_LOG_DEBUG(("INVITE notify"));
538 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
541 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
545 /* Get channel entry */
546 channel = silc_idlist_find_channel_by_id(server->global_list,
549 channel = silc_idlist_find_channel_by_id(server->local_list,
552 silc_free(channel_id);
556 silc_free(channel_id);
558 /* Get the added invite */
559 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
561 if (!channel->invite_list)
562 channel->invite_list = silc_calloc(tmp_len + 2,
563 sizeof(*channel->invite_list));
565 channel->invite_list = silc_realloc(channel->invite_list,
566 sizeof(*channel->invite_list) *
568 strlen(channel->invite_list) +
570 if (tmp[tmp_len - 1] == ',')
571 tmp[tmp_len - 1] = '\0';
573 strncat(channel->invite_list, tmp, tmp_len);
574 strncat(channel->invite_list, ",", 1);
577 /* Get the deleted invite */
578 tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
579 if (tmp && channel->invite_list) {
580 char *start, *end, *n;
582 if (!strncmp(channel->invite_list, tmp,
583 strlen(channel->invite_list) - 1)) {
584 silc_free(channel->invite_list);
585 channel->invite_list = NULL;
587 start = strstr(channel->invite_list, tmp);
588 if (start && strlen(start) >= tmp_len) {
589 end = start + tmp_len;
590 n = silc_calloc(strlen(channel->invite_list) - tmp_len, sizeof(*n));
591 strncat(n, channel->invite_list, start - channel->invite_list);
592 strncat(n, end + 1, ((channel->invite_list +
593 strlen(channel->invite_list)) - end) - 1);
594 silc_free(channel->invite_list);
595 channel->invite_list = n;
602 case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
604 * Distribute to the local clients on the channel and change the
608 SILC_LOG_DEBUG(("CHANNEL CHANGE"));
610 if (sock->type != SILC_SOCKET_TYPE_ROUTER)
613 /* Get the old Channel ID */
614 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
617 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
621 /* Get the channel entry */
622 channel = silc_idlist_find_channel_by_id(server->global_list,
625 channel = silc_idlist_find_channel_by_id(server->local_list,
628 silc_free(channel_id);
633 /* Send the notify to the channel */
634 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
635 FALSE, packet->buffer->data,
636 packet->buffer->len, FALSE);
638 /* Get the new Channel ID */
639 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
642 channel_id2 = silc_id_payload_parse_id(tmp, tmp_len);
646 SILC_LOG_DEBUG(("Old Channel ID id(%s)",
647 silc_id_render(channel_id, SILC_ID_CHANNEL)));
648 SILC_LOG_DEBUG(("New Channel ID id(%s)",
649 silc_id_render(channel_id2, SILC_ID_CHANNEL)));
651 /* Replace the Channel ID */
652 if (!silc_idlist_replace_channel_id(server->global_list, channel_id,
654 if (!silc_idlist_replace_channel_id(server->local_list, channel_id,
656 silc_free(channel_id2);
661 SilcBuffer users = NULL;
663 /* Re-announce our clients on the channel as the ID has changed now */
664 silc_server_announce_get_channel_users(server, channel, &users);
666 silc_buffer_push(users, users->data - users->head);
667 silc_server_packet_send(server, sock,
668 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
669 users->data, users->len, FALSE);
670 silc_buffer_free(users);
674 silc_free(channel_id);
678 case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
680 * Remove the server entry and all clients that this server owns.
683 SILC_LOG_DEBUG(("SERVER SIGNOFF notify"));
686 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
689 server_id = silc_id_payload_parse_id(tmp, tmp_len);
693 /* Get server entry */
694 server_entry = silc_idlist_find_server_by_id(server->global_list,
697 server_entry = silc_idlist_find_server_by_id(server->local_list,
700 silc_free(server_id);
704 silc_free(server_id);
706 /* Free all client entries that this server owns as they will
707 become invalid now as well. */
708 silc_server_remove_clients_by_server(server, server_entry, TRUE);
710 /* Remove the server entry */
711 if (!silc_idlist_del_server(server->global_list, server_entry))
712 silc_idlist_del_server(server->local_list, server_entry);
714 /* XXX update statistics */
718 case SILC_NOTIFY_TYPE_KICKED:
720 * Distribute the notify to local clients on the channel
723 SILC_LOG_DEBUG(("KICKED notify"));
725 channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
726 packet->dst_id_type);
730 /* Get channel entry */
731 channel = silc_idlist_find_channel_by_id(server->global_list,
734 channel = silc_idlist_find_channel_by_id(server->local_list,
737 silc_free(channel_id);
741 silc_free(channel_id);
744 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
747 client_id = silc_id_payload_parse_id(tmp, tmp_len);
751 /* Send to channel */
752 silc_server_packet_send_to_channel(server, sock, channel, packet->type,
753 FALSE, packet->buffer->data,
754 packet->buffer->len, FALSE);
756 /* If the the client is not in local list we check global list */
757 client = silc_idlist_find_client_by_id(server->global_list,
760 client = silc_idlist_find_client_by_id(server->local_list,
763 silc_free(client_id);
768 /* Remove the client from channel */
769 silc_server_remove_from_one_channel(server, sock, channel, client, FALSE);
773 case SILC_NOTIFY_TYPE_KILLED:
776 * Distribute the notify to local clients on channels
781 SILC_LOG_DEBUG(("KILLED notify"));
784 id = silc_argument_get_arg_type(args, 1, &id_len);
787 client_id = silc_id_payload_parse_id(id, id_len);
791 /* If the the client is not in local list we check global list */
792 client = silc_idlist_find_client_by_id(server->global_list,
795 client = silc_idlist_find_client_by_id(server->local_list,
798 silc_free(client_id);
802 silc_free(client_id);
804 /* If the client is one of ours, then close the connection to the
805 client now. This removes the client from all channels as well. */
806 if (packet->dst_id_type == SILC_ID_CLIENT && client->data.registered &&
807 client->connection) {
808 sock = client->connection;
809 silc_server_free_client_data(server, NULL, client, FALSE, NULL);
810 silc_server_close_connection(server, sock);
815 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
819 /* Send the notify to local clients on the channels except to the
820 client who is killed. */
821 silc_server_send_notify_on_channels(server, client, client,
822 SILC_NOTIFY_TYPE_KILLED,
827 /* Remove the client from all channels */
828 silc_server_remove_from_channels(server, NULL, client, FALSE, NULL,
834 case SILC_NOTIFY_TYPE_UMODE_CHANGE:
836 * Save the mode of the client.
839 SILC_LOG_DEBUG(("UMODE_CHANGE notify"));
842 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
845 client_id = silc_id_payload_parse_id(tmp, tmp_len);
849 /* Get client entry */
850 client = silc_idlist_find_client_by_id(server->global_list,
853 client = silc_idlist_find_client_by_id(server->local_list,
856 silc_free(client_id);
860 silc_free(client_id);
863 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
868 SILC_GET32_MSB(client->mode, tmp);
872 case SILC_NOTIFY_TYPE_BAN:
877 SILC_LOG_DEBUG(("BAN notify"));
880 tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
883 channel_id = silc_id_payload_parse_id(tmp, tmp_len);
887 /* Get channel entry */
888 channel = silc_idlist_find_channel_by_id(server->global_list,
891 channel = silc_idlist_find_channel_by_id(server->local_list,
894 silc_free(channel_id);
898 silc_free(channel_id);
900 /* Get the new ban and add it to the ban list */
901 tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
903 if (!channel->ban_list)
904 channel->ban_list = silc_calloc(tmp_len + 2,
905 sizeof(*channel->ban_list));
907 channel->ban_list = silc_realloc(channel->ban_list,
908 sizeof(*channel->ban_list) *
910 strlen(channel->ban_list) + 2));
911 strncat(channel->ban_list, tmp, tmp_len);
912 strncat(channel->ban_list, ",", 1);
915 /* Get the ban to be removed and remove it from the list */
916 tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
917 if (tmp && channel->ban_list) {
918 char *start, *end, *n;
920 if (!strcmp(channel->ban_list, tmp)) {
921 silc_free(channel->ban_list);
922 channel->ban_list = NULL;
924 start = strstr(channel->ban_list, tmp);
925 if (start && strlen(start) >= tmp_len) {
926 end = start + tmp_len;
927 n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
928 strncat(n, channel->ban_list, start - channel->ban_list);
929 strncat(n, end + 1, ((channel->ban_list +
930 strlen(channel->ban_list)) - end) - 1);
931 silc_free(channel->ban_list);
932 channel->ban_list = n;
939 /* Ignore rest of the notify types for now */
940 case SILC_NOTIFY_TYPE_NONE:
941 case SILC_NOTIFY_TYPE_MOTD:
948 silc_notify_payload_free(payload);
951 void silc_server_notify_list(SilcServer server,
952 SilcSocketConnection sock,
953 SilcPacketContext *packet)
955 SilcPacketContext *new;
959 SILC_LOG_DEBUG(("Processing New Notify List"));
961 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
962 packet->src_id_type != SILC_ID_SERVER)
965 /* Make copy of the original packet context, except for the actual
966 data buffer, which we will here now fetch from the original buffer. */
967 new = silc_packet_context_alloc();
968 new->type = SILC_PACKET_NOTIFY;
969 new->flags = packet->flags;
970 new->src_id = packet->src_id;
971 new->src_id_len = packet->src_id_len;
972 new->src_id_type = packet->src_id_type;
973 new->dst_id = packet->dst_id;
974 new->dst_id_len = packet->dst_id_len;
975 new->dst_id_type = packet->dst_id_type;
977 buffer = silc_buffer_alloc(1024);
978 new->buffer = buffer;
980 while (packet->buffer->len) {
981 SILC_GET16_MSB(len, packet->buffer->data + 2);
982 if (len > packet->buffer->len)
985 if (len > buffer->truelen) {
986 silc_buffer_free(buffer);
987 buffer = silc_buffer_alloc(1024 + len);
990 silc_buffer_pull_tail(buffer, len);
991 silc_buffer_put(buffer, packet->buffer->data, len);
993 /* Process the Notify */
994 silc_server_notify(server, sock, new);
996 silc_buffer_push_tail(buffer, len);
997 silc_buffer_pull(packet->buffer, len);
1000 silc_buffer_free(buffer);
1004 /* Received private message. This resolves the destination of the message
1005 and sends the packet. This is used by both server and router. If the
1006 destination is our locally connected client this sends the packet to
1007 the client. This may also send the message for further routing if
1008 the destination is not in our server (or router). */
1010 void silc_server_private_message(SilcServer server,
1011 SilcSocketConnection sock,
1012 SilcPacketContext *packet)
1014 SilcSocketConnection dst_sock;
1015 SilcIDListData idata;
1017 SILC_LOG_DEBUG(("Start"));
1019 if (packet->src_id_type != SILC_ID_CLIENT ||
1020 packet->dst_id_type != SILC_ID_CLIENT)
1023 if (!packet->dst_id)
1026 /* Get the route to the client */
1027 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1028 packet->dst_id_len, NULL, &idata);
1032 /* Send the private message */
1033 silc_server_send_private_message(server, dst_sock, idata->send_key,
1034 idata->hmac_send, packet);
1037 /* Received private message key packet.. This packet is never for us. It is to
1038 the client in the packet's destination ID. Sending of this sort of packet
1039 equals sending private message, ie. it is sent point to point from
1040 one client to another. */
1042 void silc_server_private_message_key(SilcServer server,
1043 SilcSocketConnection sock,
1044 SilcPacketContext *packet)
1046 SilcSocketConnection dst_sock;
1047 SilcIDListData idata;
1049 SILC_LOG_DEBUG(("Start"));
1051 if (packet->src_id_type != SILC_ID_CLIENT ||
1052 packet->dst_id_type != SILC_ID_CLIENT)
1055 if (!packet->dst_id)
1058 /* Get the route to the client */
1059 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1060 packet->dst_id_len, NULL, &idata);
1064 /* Relay the packet */
1065 silc_server_relay_packet(server, dst_sock, idata->send_key,
1066 idata->hmac_send, packet, FALSE);
1069 /* Processes incoming command reply packet. The command reply packet may
1070 be destined to one of our clients or it may directly for us. We will
1071 call the command reply routine after processing the packet. */
1073 void silc_server_command_reply(SilcServer server,
1074 SilcSocketConnection sock,
1075 SilcPacketContext *packet)
1077 SilcBuffer buffer = packet->buffer;
1078 SilcClientEntry client = NULL;
1079 SilcSocketConnection dst_sock;
1080 SilcIDListData idata;
1081 SilcClientID *id = NULL;
1083 SILC_LOG_DEBUG(("Start"));
1085 /* Source must be server or router */
1086 if (packet->src_id_type != SILC_ID_SERVER &&
1087 sock->type != SILC_SOCKET_TYPE_ROUTER)
1090 if (packet->dst_id_type == SILC_ID_CHANNEL)
1093 if (packet->dst_id_type == SILC_ID_CLIENT) {
1094 /* Destination must be one of ours */
1095 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
1098 client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
1100 SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
1106 if (packet->dst_id_type == SILC_ID_SERVER) {
1107 /* For now this must be for us */
1108 if (SILC_ID_SERVER_COMPARE(packet->dst_id, server->id_string)) {
1109 SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
1114 /* Execute command reply locally for the command */
1115 silc_server_command_reply_process(server, sock, buffer);
1117 if (packet->dst_id_type == SILC_ID_CLIENT && client && id) {
1118 /* Relay the packet to the client */
1120 dst_sock = (SilcSocketConnection)client->connection;
1121 silc_buffer_push(buffer, SILC_PACKET_HEADER_LEN + packet->src_id_len
1122 + packet->dst_id_len + packet->padlen);
1124 silc_packet_send_prepare(dst_sock, 0, 0, buffer->len);
1125 silc_buffer_put(dst_sock->outbuf, buffer->data, buffer->len);
1127 idata = (SilcIDListData)client;
1129 /* Encrypt packet */
1130 silc_packet_encrypt(idata->send_key, idata->hmac_send, dst_sock->outbuf,
1133 /* Send the packet */
1134 silc_server_packet_send_real(server, dst_sock, TRUE);
1140 /* Process received channel message. The message can be originated from
1141 client or server. */
1143 void silc_server_channel_message(SilcServer server,
1144 SilcSocketConnection sock,
1145 SilcPacketContext *packet)
1147 SilcChannelEntry channel = NULL;
1148 SilcChannelClientEntry chl;
1149 SilcChannelID *id = NULL;
1150 void *sender = NULL;
1152 SILC_LOG_DEBUG(("Processing channel message"));
1155 if (packet->dst_id_type != SILC_ID_CHANNEL) {
1156 SILC_LOG_DEBUG(("Received bad message for channel, dropped"));
1160 /* Find channel entry */
1161 id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
1164 channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
1166 channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
1168 SILC_LOG_DEBUG(("Could not find channel"));
1173 /* See that this client is on the channel. If the message is coming
1174 from router we won't do the check as the message is from client that
1175 we don't know about. Also, if the original sender is not client
1176 (as it can be server as well) we don't do the check. */
1177 sender = silc_id_str2id(packet->src_id, packet->src_id_len,
1178 packet->src_id_type);
1181 if (sock->type != SILC_SOCKET_TYPE_ROUTER &&
1182 packet->src_id_type == SILC_ID_CLIENT) {
1183 silc_list_start(channel->user_list);
1184 while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
1185 if (chl->client && !SILC_ID_CLIENT_COMPARE(chl->client->id, sender))
1188 if (chl == SILC_LIST_END) {
1189 SILC_LOG_DEBUG(("Client not on channel"));
1194 /* If we are router and the packet came from router and private key
1195 has not been set for the channel then we must encrypt the packet
1196 as it was decrypted with the session key shared between us and the
1197 router which sent it. This is so, because cells does not share the
1199 if (server->server_type == SILC_ROUTER &&
1200 sock->type == SILC_SOCKET_TYPE_ROUTER &&
1201 !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
1204 uint16 data_len, flags;
1206 iv_len = silc_cipher_get_block_len(channel->channel_key);
1207 if (channel->iv[0] == '\0')
1208 for (i = 0; i < iv_len; i++) channel->iv[i] =
1209 silc_rng_get_byte(server->rng);
1211 silc_hash_make(server->md5hash, channel->iv, iv_len, channel->iv);
1213 /* Encode new payload. This encrypts it also. */
1214 SILC_GET16_MSB(flags, packet->buffer->data);
1215 SILC_GET16_MSB(data_len, packet->buffer->data + 2);
1216 chp = silc_channel_message_payload_encode(flags, data_len,
1217 packet->buffer->data + 4,
1218 iv_len, channel->iv,
1219 channel->channel_key,
1221 silc_buffer_put(packet->buffer, chp->data, chp->len);
1222 silc_buffer_free(chp);
1225 /* Distribute the packet to our local clients. This will send the
1226 packet for further routing as well, if needed. */
1227 silc_server_packet_relay_to_channel(server, sock, channel, sender,
1228 packet->src_id_type,
1229 packet->buffer->data,
1230 packet->buffer->len, FALSE);
1239 /* Received channel key packet. We distribute the key to all of our locally
1240 connected clients on the channel. */
1242 void silc_server_channel_key(SilcServer server,
1243 SilcSocketConnection sock,
1244 SilcPacketContext *packet)
1246 SilcBuffer buffer = packet->buffer;
1247 SilcChannelEntry channel;
1249 if (packet->src_id_type != SILC_ID_SERVER ||
1250 (server->server_type == SILC_ROUTER &&
1251 sock->type == SILC_SOCKET_TYPE_ROUTER))
1254 /* Save the channel key */
1255 channel = silc_server_save_channel_key(server, buffer, NULL);
1259 /* Distribute the key to everybody who is on the channel. If we are router
1260 we will also send it to locally connected servers. */
1261 silc_server_send_channel_key(server, sock, channel, FALSE);
1264 /* Received New Client packet and processes it. Creates Client ID for the
1265 client. Client becomes registered after calling this functions. */
1267 SilcClientEntry silc_server_new_client(SilcServer server,
1268 SilcSocketConnection sock,
1269 SilcPacketContext *packet)
1271 SilcBuffer buffer = packet->buffer;
1272 SilcClientEntry client;
1273 SilcIDCacheEntry cache;
1274 SilcClientID *client_id;
1276 SilcIDListData idata;
1277 char *username = NULL, *realname = NULL, *id_string;
1280 SILC_LOG_DEBUG(("Creating new client"));
1282 if (sock->type != SILC_SOCKET_TYPE_CLIENT)
1285 /* Take client entry */
1286 client = (SilcClientEntry)sock->user_data;
1287 idata = (SilcIDListData)client;
1289 /* Fetch the old client cache entry so that we can update it. */
1290 if (!silc_idcache_find_by_context(server->local_list->clients,
1291 sock->user_data, &cache)) {
1292 SILC_LOG_ERROR(("Lost client's cache entry - bad thing"));
1293 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1298 /* Parse incoming packet */
1299 ret = silc_buffer_unformat(buffer,
1300 SILC_STR_UI16_STRING_ALLOC(&username),
1301 SILC_STR_UI16_STRING_ALLOC(&realname),
1305 silc_free(username);
1307 silc_free(realname);
1308 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1309 "Incomplete client information");
1314 silc_free(username);
1316 silc_free(realname);
1317 silc_server_disconnect_remote(server, sock, "Server closed connection: "
1318 "Incomplete client information");
1322 /* Create Client ID */
1323 silc_id_create_client_id(server->id, server->rng, server->md5hash,
1324 username, &client_id);
1326 if (strlen(username) > 128)
1327 username[127] = '\0';
1329 /* Update client entry */
1330 idata->registered = TRUE;
1331 client->nickname = strdup(username);
1332 client->username = username;
1333 client->userinfo = realname ? realname : strdup(" ");
1334 client->id = client_id;
1336 /* Update the cache entry */
1337 cache->id = (void *)client_id;
1338 cache->type = SILC_ID_CLIENT;
1339 cache->data = username;
1340 cache->data_len = strlen(username);
1341 silc_idcache_sort_by_data(server->local_list->clients);
1343 /* Notify our router about new client on the SILC network */
1344 if (!server->standalone)
1345 silc_server_send_new_id(server, (SilcSocketConnection)
1346 server->router->connection,
1347 server->server_type == SILC_ROUTER ? TRUE : FALSE,
1348 client->id, SILC_ID_CLIENT, SILC_ID_CLIENT_LEN);
1350 /* Send the new client ID to the client. */
1351 id_string = silc_id_id2str(client->id, SILC_ID_CLIENT);
1352 reply = silc_buffer_alloc(2 + 2 + SILC_ID_CLIENT_LEN);
1353 silc_buffer_pull_tail(reply, SILC_BUFFER_END(reply));
1354 silc_buffer_format(reply,
1355 SILC_STR_UI_SHORT(SILC_ID_CLIENT),
1356 SILC_STR_UI_SHORT(SILC_ID_CLIENT_LEN),
1357 SILC_STR_UI_XNSTRING(id_string, SILC_ID_CLIENT_LEN),
1359 silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, 0,
1360 reply->data, reply->len, FALSE);
1361 silc_free(id_string);
1362 silc_buffer_free(reply);
1364 /* Send some nice info to the client */
1365 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1366 ("Welcome to the SILC Network %s@%s",
1367 username, sock->hostname));
1368 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1369 ("Your host is %s, running version %s",
1370 server->config->server_info->server_name,
1372 if (server->server_type == SILC_ROUTER) {
1373 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1374 ("There are %d clients on %d servers in SILC "
1375 "Network", server->stat.clients,
1376 server->stat.servers + 1));
1377 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1378 ("There are %d clients on %d server in our cell",
1379 server->stat.cell_clients,
1380 server->stat.cell_servers + 1));
1381 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1382 ("I have %d clients, %d channels, %d servers and "
1384 server->stat.my_clients,
1385 server->stat.my_channels,
1386 server->stat.my_servers,
1387 server->stat.my_routers));
1388 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1389 ("%d server operators and %d router operators "
1391 server->stat.my_server_ops,
1392 server->stat.my_router_ops));
1394 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1395 ("I have %d clients and %d channels formed",
1396 server->stat.my_clients,
1397 server->stat.my_channels));
1398 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1399 ("%d operators online",
1400 server->stat.my_server_ops));
1402 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1403 ("Your connection is secured with %s cipher, "
1404 "key length %d bits",
1405 idata->send_key->cipher->name,
1406 idata->send_key->cipher->key_len));
1407 SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
1408 ("Your current nickname is %s",
1412 silc_server_send_motd(server, sock);
1417 /* Create new server. This processes received New Server packet and
1418 saves the received Server ID. The server is our locally connected
1419 server thus we save all the information and save it to local list.
1420 This funtion can be used by both normal server and router server.
1421 If normal server uses this it means that its router has connected
1422 to the server. If router uses this it means that one of the cell's
1423 servers is connected to the router. */
1425 SilcServerEntry silc_server_new_server(SilcServer server,
1426 SilcSocketConnection sock,
1427 SilcPacketContext *packet)
1429 SilcBuffer buffer = packet->buffer;
1430 SilcServerEntry new_server;
1431 SilcIDCacheEntry cache;
1432 SilcServerID *server_id;
1433 SilcIDListData idata;
1434 unsigned char *server_name, *id_string;
1435 uint16 id_len, name_len;
1438 SILC_LOG_DEBUG(("Creating new server"));
1440 if (sock->type != SILC_SOCKET_TYPE_SERVER &&
1441 sock->type != SILC_SOCKET_TYPE_ROUTER)
1444 /* Take server entry */
1445 new_server = (SilcServerEntry)sock->user_data;
1446 idata = (SilcIDListData)new_server;
1448 /* Fetch the old server cache entry so that we can update it. */
1449 if (!silc_idcache_find_by_context(server->local_list->servers,
1450 sock->user_data, &cache)) {
1451 SILC_LOG_ERROR(("Lost server's cache entry - bad thing"));
1455 /* Parse the incoming packet */
1456 ret = silc_buffer_unformat(buffer,
1457 SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
1458 SILC_STR_UI16_NSTRING_ALLOC(&server_name,
1463 silc_free(id_string);
1465 silc_free(server_name);
1469 if (id_len > buffer->len) {
1470 silc_free(id_string);
1471 silc_free(server_name);
1476 server_name[255] = '\0';
1479 server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
1481 silc_free(id_string);
1482 silc_free(server_name);
1485 silc_free(id_string);
1487 /* Update client entry */
1488 idata->registered = TRUE;
1489 new_server->server_name = server_name;
1490 new_server->id = server_id;
1492 /* Update the cache entry */
1493 cache->id = (void *)server_id;
1494 cache->type = SILC_ID_SERVER;
1495 cache->data = server_name;
1496 cache->data_len = strlen(server_name);
1497 silc_idcache_sort_by_data(server->local_list->servers);
1499 /* Distribute the information about new server in the SILC network
1500 to our router. If we are normal server we won't send anything
1501 since this connection must be our router connection. */
1502 if (server->server_type == SILC_ROUTER && !server->standalone &&
1503 server->router->connection != sock)
1504 silc_server_send_new_id(server, server->router->connection,
1505 TRUE, new_server->id, SILC_ID_SERVER,
1506 SILC_ID_SERVER_LEN);
1508 if (server->server_type == SILC_ROUTER)
1509 server->stat.cell_servers++;
1514 /* Processes incoming New ID packet. New ID Payload is used to distribute
1515 information about newly registered clients and servers. */
1517 static void silc_server_new_id_real(SilcServer server,
1518 SilcSocketConnection sock,
1519 SilcPacketContext *packet,
1522 SilcBuffer buffer = packet->buffer;
1524 SilcServerEntry router;
1525 SilcSocketConnection router_sock;
1528 unsigned char *hash = NULL;
1531 SILC_LOG_DEBUG(("Processing new ID"));
1533 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1534 server->server_type == SILC_SERVER ||
1535 packet->src_id_type != SILC_ID_SERVER)
1538 idp = silc_id_payload_parse(buffer);
1542 id_type = silc_id_payload_get_type(idp);
1544 /* Normal server cannot have other normal server connections */
1545 if (id_type == SILC_ID_SERVER && sock->type == SILC_SOCKET_TYPE_SERVER)
1548 id = silc_id_payload_get_id(idp);
1552 /* If the sender of this packet is server and we are router we need to
1553 broadcast this packet to other routers in the network. */
1554 if (broadcast && !server->standalone && server->server_type == SILC_ROUTER &&
1555 sock->type == SILC_SOCKET_TYPE_SERVER &&
1556 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1557 SILC_LOG_DEBUG(("Broadcasting received New ID packet"));
1558 silc_server_packet_send(server, server->router->connection,
1560 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1561 buffer->data, buffer->len, FALSE);
1564 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1565 id_list = server->local_list;
1567 id_list = server->global_list;
1570 router = sock->user_data;
1573 case SILC_ID_CLIENT:
1575 SilcClientEntry entry;
1577 SILC_LOG_DEBUG(("New client id(%s) from [%s] %s",
1578 silc_id_render(id, SILC_ID_CLIENT),
1579 sock->type == SILC_SOCKET_TYPE_SERVER ?
1580 "Server" : "Router", sock->hostname));
1582 /* As a router we keep information of all global information in our
1583 global list. Cell wide information however is kept in the local
1584 list. The client is put to global list and we will take the hash
1585 value of the Client ID and save it to the ID Cache system for fast
1586 searching in the future. */
1587 hash = silc_calloc(sizeof(((SilcClientID *)id)->hash),
1588 sizeof(unsigned char));
1589 memcpy(hash, ((SilcClientID *)id)->hash,
1590 sizeof(((SilcClientID *)id)->hash));
1591 entry = silc_idlist_add_client(id_list, hash,
1592 sizeof(((SilcClientID *)id)->hash),
1593 NULL, NULL, id, router, NULL);
1594 entry->nickname = NULL;
1595 entry->data.registered = TRUE;
1597 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1598 server->stat.cell_clients++;
1599 server->stat.clients++;
1603 case SILC_ID_SERVER:
1604 SILC_LOG_DEBUG(("New server id(%s) from [%s] %s",
1605 silc_id_render(id, SILC_ID_SERVER),
1606 sock->type == SILC_SOCKET_TYPE_SERVER ?
1607 "Server" : "Router", sock->hostname));
1609 /* As a router we keep information of all global information in our global
1610 list. Cell wide information however is kept in the local list. */
1611 silc_idlist_add_server(id_list, NULL, 0, id, router, router_sock);
1613 if (sock->type == SILC_SOCKET_TYPE_SERVER)
1614 server->stat.cell_servers++;
1615 server->stat.servers++;
1618 case SILC_ID_CHANNEL:
1619 SILC_LOG_ERROR(("Channel cannot be registered with NEW_ID packet"));
1627 silc_id_payload_free(idp);
1631 /* Processes incoming New ID packet. New ID Payload is used to distribute
1632 information about newly registered clients and servers. */
1634 void silc_server_new_id(SilcServer server, SilcSocketConnection sock,
1635 SilcPacketContext *packet)
1637 silc_server_new_id_real(server, sock, packet, TRUE);
1640 /* Receoved New Id List packet, list of New ID payloads inside one
1641 packet. Process the New ID payloads one by one. */
1643 void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
1644 SilcPacketContext *packet)
1646 SilcPacketContext *new_id;
1650 SILC_LOG_DEBUG(("Processing New ID List"));
1652 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1653 packet->src_id_type != SILC_ID_SERVER)
1656 /* If the sender of this packet is server and we are router we need to
1657 broadcast this packet to other routers in the network. Broadcast
1658 this list packet instead of multiple New ID packets. */
1659 if (!server->standalone && server->server_type == SILC_ROUTER &&
1660 sock->type == SILC_SOCKET_TYPE_SERVER &&
1661 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1662 SILC_LOG_DEBUG(("Broadcasting received New ID List packet"));
1663 silc_server_packet_send(server, server->router->connection,
1665 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1666 packet->buffer->data, packet->buffer->len, FALSE);
1669 /* Make copy of the original packet context, except for the actual
1670 data buffer, which we will here now fetch from the original buffer. */
1671 new_id = silc_packet_context_alloc();
1672 new_id->type = SILC_PACKET_NEW_ID;
1673 new_id->flags = packet->flags;
1674 new_id->src_id = packet->src_id;
1675 new_id->src_id_len = packet->src_id_len;
1676 new_id->src_id_type = packet->src_id_type;
1677 new_id->dst_id = packet->dst_id;
1678 new_id->dst_id_len = packet->dst_id_len;
1679 new_id->dst_id_type = packet->dst_id_type;
1681 idp = silc_buffer_alloc(256);
1682 new_id->buffer = idp;
1684 while (packet->buffer->len) {
1685 SILC_GET16_MSB(id_len, packet->buffer->data + 2);
1686 if ((id_len > packet->buffer->len) ||
1687 (id_len > idp->truelen))
1690 silc_buffer_pull_tail(idp, 4 + id_len);
1691 silc_buffer_put(idp, packet->buffer->data, 4 + id_len);
1693 /* Process the New ID */
1694 silc_server_new_id_real(server, sock, new_id, FALSE);
1696 silc_buffer_push_tail(idp, 4 + id_len);
1697 silc_buffer_pull(packet->buffer, 4 + id_len);
1700 silc_buffer_free(idp);
1704 /* Received New Channel packet. Information about new channels in the
1705 network are distributed using this packet. Save the information about
1706 the new channel. This usually comes from router but also normal server
1707 can send this to notify channels it has when it connects to us. */
1709 void silc_server_new_channel(SilcServer server,
1710 SilcSocketConnection sock,
1711 SilcPacketContext *packet)
1713 SilcChannelPayload payload;
1714 SilcChannelID *channel_id;
1721 SILC_LOG_DEBUG(("Processing New Channel"));
1723 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1724 packet->src_id_type != SILC_ID_SERVER ||
1725 server->server_type == SILC_SERVER)
1728 /* Parse the channel payload */
1729 payload = silc_channel_payload_parse(packet->buffer);
1733 /* Get the channel ID */
1734 channel_id = silc_channel_get_id_parse(payload);
1736 silc_channel_payload_free(payload);
1740 channel_name = silc_channel_get_name(payload, &name_len);
1742 channel_name[255] = '\0';
1744 id = silc_channel_get_id(payload, &id_len);
1746 if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
1747 /* Add the server to global list as it is coming from router. It
1748 cannot be our own channel as it is coming from router. */
1750 SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
1751 silc_id_render(channel_id, SILC_ID_CHANNEL),
1754 silc_idlist_add_channel(server->global_list, strdup(channel_name),
1755 0, channel_id, server->router->connection,
1758 server->stat.channels++;
1760 /* The channel is coming from our server, thus it is in our cell
1761 we will add it to our local list. */
1762 SilcChannelEntry channel;
1765 SILC_LOG_DEBUG(("New channel id(%s) from [Server] %s",
1766 silc_id_render(channel_id, SILC_ID_CHANNEL),
1769 /* Check that we don't already have this channel */
1770 channel = silc_idlist_find_channel_by_name(server->local_list,
1771 channel_name, NULL);
1773 channel = silc_idlist_find_channel_by_name(server->global_list,
1774 channel_name, NULL);
1776 /* If the channel does not exist, then create it. We create the channel
1777 with the channel ID provided by the server. This creates a new
1778 key to the channel as well that we will send to the server. */
1780 channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
1784 silc_channel_payload_free(payload);
1785 silc_free(channel_id);
1789 /* Send the new channel key to the server */
1790 chk = silc_channel_key_payload_encode(id_len, id,
1791 strlen(channel->channel_key->
1793 channel->channel_key->cipher->name,
1794 channel->key_len / 8,
1796 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
1797 chk->data, chk->len, FALSE);
1798 silc_buffer_free(chk);
1801 /* The channel exist by that name, check whether the ID's match.
1802 If they don't then we'll force the server to use the ID we have.
1803 We also create a new key for the channel. */
1804 SilcBuffer users = NULL;
1807 channel_id = silc_id_dup(channel_id, SILC_ID_CHANNEL);
1809 if (SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) {
1810 /* They don't match, send CHANNEL_CHANGE notify to the server to
1811 force the ID change. */
1812 SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
1813 silc_server_send_notify_channel_change(server, sock, FALSE,
1816 SILC_ID_CHANNEL_LEN);
1819 /* If the mode is different from what we have then enforce the
1821 mode = silc_channel_get_mode(payload);
1822 if (channel->mode != mode) {
1823 SILC_LOG_DEBUG(("Forcing the server to change channel mode"));
1824 silc_server_send_notify_cmode(server, sock, FALSE, channel,
1825 channel->mode, server->id,
1826 SILC_ID_SERVER, SILC_ID_SERVER_LEN,
1827 channel->cipher, channel->hmac_name);
1830 /* Create new key for the channel and send it to the server and
1831 everybody else possibly on the channel. */
1833 if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
1834 silc_server_create_channel_key(server, channel, 0);
1836 /* Send to the channel */
1837 silc_server_send_channel_key(server, sock, channel, FALSE);
1838 id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
1839 id_len = SILC_ID_CHANNEL_LEN;
1841 /* Send to the server */
1842 chk = silc_channel_key_payload_encode(id_len, id,
1843 strlen(channel->channel_key->
1845 channel->channel_key->
1847 channel->key_len / 8,
1849 silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0,
1850 chk->data, chk->len, FALSE);
1851 silc_buffer_free(chk);
1855 silc_free(channel_id);
1857 /* Since the channel is coming from server and we also know about it
1858 then send the JOIN notify to the server so that it see's our
1859 users on the channel "joining" the channel. */
1860 silc_server_announce_get_channel_users(server, channel, &users);
1862 silc_buffer_push(users, users->data - users->head);
1863 silc_server_packet_send(server, sock,
1864 SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
1865 users->data, users->len, FALSE);
1866 silc_buffer_free(users);
1871 silc_channel_payload_free(payload);
1874 /* Received New Channel List packet, list of New Channel List payloads inside
1875 one packet. Process the New Channel payloads one by one. */
1877 void silc_server_new_channel_list(SilcServer server,
1878 SilcSocketConnection sock,
1879 SilcPacketContext *packet)
1881 SilcPacketContext *new;
1885 SILC_LOG_DEBUG(("Processing New Channel List"));
1887 if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
1888 packet->src_id_type != SILC_ID_SERVER ||
1889 server->server_type == SILC_SERVER)
1892 /* If the sender of this packet is server and we are router we need to
1893 broadcast this packet to other routers in the network. Broadcast
1894 this list packet instead of multiple New Channel packets. */
1895 if (!server->standalone && server->server_type == SILC_ROUTER &&
1896 sock->type == SILC_SOCKET_TYPE_SERVER &&
1897 !(packet->flags & SILC_PACKET_FLAG_BROADCAST)) {
1898 SILC_LOG_DEBUG(("Broadcasting received New Channel List packet"));
1899 silc_server_packet_send(server, server->router->connection,
1901 packet->flags | SILC_PACKET_FLAG_BROADCAST,
1902 packet->buffer->data, packet->buffer->len, FALSE);
1905 /* Make copy of the original packet context, except for the actual
1906 data buffer, which we will here now fetch from the original buffer. */
1907 new = silc_packet_context_alloc();
1908 new->type = SILC_PACKET_NEW_CHANNEL;
1909 new->flags = packet->flags;
1910 new->src_id = packet->src_id;
1911 new->src_id_len = packet->src_id_len;
1912 new->src_id_type = packet->src_id_type;
1913 new->dst_id = packet->dst_id;
1914 new->dst_id_len = packet->dst_id_len;
1915 new->dst_id_type = packet->dst_id_type;
1917 buffer = silc_buffer_alloc(512);
1918 new->buffer = buffer;
1920 while (packet->buffer->len) {
1921 SILC_GET16_MSB(len1, packet->buffer->data);
1922 if ((len1 > packet->buffer->len) ||
1923 (len1 > buffer->truelen))
1926 SILC_GET16_MSB(len2, packet->buffer->data + 2 + len1);
1927 if ((len2 > packet->buffer->len) ||
1928 (len2 > buffer->truelen))
1931 silc_buffer_pull_tail(buffer, 8 + len1 + len2);
1932 silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
1934 /* Process the New Channel */
1935 silc_server_new_channel(server, sock, new);
1937 silc_buffer_push_tail(buffer, 8 + len1 + len2);
1938 silc_buffer_pull(packet->buffer, 8 + len1 + len2);
1941 silc_buffer_free(buffer);
1945 /* Received key agreement packet. This packet is never for us. It is to
1946 the client in the packet's destination ID. Sending of this sort of packet
1947 equals sending private message, ie. it is sent point to point from
1948 one client to another. */
1950 void silc_server_key_agreement(SilcServer server,
1951 SilcSocketConnection sock,
1952 SilcPacketContext *packet)
1954 SilcSocketConnection dst_sock;
1955 SilcIDListData idata;
1957 SILC_LOG_DEBUG(("Start"));
1959 if (packet->src_id_type != SILC_ID_CLIENT ||
1960 packet->dst_id_type != SILC_ID_CLIENT)
1963 if (!packet->dst_id)
1966 /* Get the route to the client */
1967 dst_sock = silc_server_get_client_route(server, packet->dst_id,
1968 packet->dst_id_len, NULL, &idata);
1972 /* Relay the packet */
1973 silc_server_relay_packet(server, dst_sock, idata->send_key,
1974 idata->hmac_send, packet, FALSE);
1977 /* Received connection auth request packet that is used during connection
1978 phase to resolve the mandatory authentication method. This packet can
1979 actually be received at anytime but usually it is used only during
1980 the connection authentication phase. Now, protocol says that this packet
1981 can come from client or server, however, we support only this coming
1982 from client and expect that server's always knows what authentication
1985 void silc_server_connection_auth_request(SilcServer server,
1986 SilcSocketConnection sock,
1987 SilcPacketContext *packet)
1989 SilcServerConfigSectionClientConnection *client = NULL;
1992 SilcAuthMethod auth_meth;
1994 SILC_LOG_DEBUG(("Start"));
1996 if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT)
1999 /* Parse the payload */
2000 ret = silc_buffer_unformat(packet->buffer,
2001 SILC_STR_UI_SHORT(&conn_type),
2002 SILC_STR_UI_SHORT(NULL),
2007 if (conn_type != SILC_SOCKET_TYPE_CLIENT)
2010 /* Get the authentication method for the client */
2011 auth_meth = SILC_AUTH_NONE;
2012 client = silc_server_config_find_client_conn(server->config,
2016 client = silc_server_config_find_client_conn(server->config,
2020 auth_meth = client->auth_meth;
2022 /* Send it back to the client */
2023 silc_server_send_connection_auth_request(server, sock,
2028 /* Received REKEY packet. The sender of the packet wants to regenerate
2029 its session keys. This starts the REKEY protocol. */
2031 void silc_server_rekey(SilcServer server,
2032 SilcSocketConnection sock,
2033 SilcPacketContext *packet)
2035 SilcProtocol protocol;
2036 SilcServerRekeyInternalContext *proto_ctx;
2037 SilcIDListData idata = (SilcIDListData)sock->user_data;
2039 SILC_LOG_DEBUG(("Start"));
2041 /* Allocate internal protocol context. This is sent as context
2043 proto_ctx = silc_calloc(1, sizeof(*proto_ctx));
2044 proto_ctx->server = (void *)server;
2045 proto_ctx->sock = sock;
2046 proto_ctx->responder = TRUE;
2047 proto_ctx->pfs = idata->rekey->pfs;
2049 /* Perform rekey protocol. Will call the final callback after the
2050 protocol is over. */
2051 silc_protocol_alloc(SILC_PROTOCOL_SERVER_REKEY,
2052 &protocol, proto_ctx, silc_server_rekey_final);
2053 sock->protocol = protocol;
2055 if (proto_ctx->pfs == FALSE)
2056 /* Run the protocol */
2057 protocol->execute(server->timeout_queue, 0, protocol, sock->sock, 0, 0);