+Wed Feb 21 14:17:04 EET 2001 Pekka Riikonen <priikone@poseidon.pspt.fi>
+
+ * Implemented CMODE_CHANGE, CUMODE_CHANGE and TOPIC_SET notify
+ types in the server's silcd/packet_receive.c.
+
+ * Implemented CMODE and CUMODE to work in router environment.
+
+ * Fixed minor encoding and decoding buglet from the
+ lib/silccore/silcmode.c.
+
Wed Feb 21 12:44:00 EET 2001 Mika Boström <bostik@lut.fi>
* Changed all SilcConfigServer* and silc_config_server* to
/* See whether has rights to change topic */
silc_list_start(channel->user_list);
- while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
- if (chl->client == client) {
- if (chl->mode == SILC_CHANNEL_UMODE_NONE) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_TOPIC,
- SILC_STATUS_ERR_NO_CHANNEL_PRIV);
- goto out;
- } else {
- break;
- }
+ while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END)
+ if (chl->client == client)
+ break;
+
+ if (chl->mode == SILC_CHANNEL_UMODE_NONE) {
+ if (channel->mode & SILC_CHANNEL_MODE_TOPIC) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_TOPIC,
+ SILC_STATUS_ERR_NO_CHANNEL_PRIV);
+ goto out;
}
}
SILC_NOTIFY_TYPE_CMODE_CHANGE, 2,
cidp->data, cidp->len,
tmp_mask, tmp_len);
- silc_free(cidp);
+
+ /* Set SET_MODE packet to network */
+ if (!server->standalone)
+ silc_server_send_set_mode(server, server->router->connection,
+ server->server_type == SILC_ROUTER ?
+ TRUE : FALSE, SILC_MODE_TYPE_CHANNEL,
+ mode_mask, 2,
+ tmp_id, tmp_len2,
+ cidp->data, cidp->len);
/* Send command reply to sender */
packet = silc_command_reply_payload_encode_va(SILC_COMMAND_CMODE,
silc_buffer_free(packet);
silc_free(channel_id);
+ silc_free(cidp);
out:
silc_server_command_free(cmd);
SilcClientEntry target_client;
SilcChannelClientEntry chl;
SilcBuffer packet, idp;
- unsigned char *tmp_id, *tmp_mask;
- unsigned int target_mask, sender_mask, tmp_len;
+ unsigned char *tmp_id, *tmp_ch_id, *tmp_mask;
+ unsigned int target_mask, sender_mask, tmp_len, tmp_ch_len;
int notify = FALSE;
SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_CUMODE, cmd, 3, 3);
/* Get Channel ID */
- tmp_id = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
- if (!tmp_id) {
+ tmp_ch_id = silc_argument_get_arg_type(cmd->args, 1, &tmp_ch_len);
+ if (!tmp_ch_id) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
SILC_STATUS_ERR_NO_CHANNEL_ID);
goto out;
}
- channel_id = silc_id_payload_parse_id(tmp_id, tmp_len);
+ channel_id = silc_id_payload_parse_id(tmp_ch_id, tmp_ch_len);
if (!channel_id) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
SILC_STATUS_ERR_NO_CHANNEL_ID);
target_client = silc_idlist_find_client_by_id(server->local_list,
client_id, NULL);
if (!target_client) {
- /* XXX If target client is not one of mine send to primary route */
+ target_client = silc_idlist_find_client_by_id(server->global_list,
+ client_id, NULL);
}
/* Check whether target client is on the channel */
}
}
+ idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
+
/* Send notify to channel, notify only if mode was actually changed. */
if (notify) {
- idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
silc_server_send_notify_to_channel(server, NULL, channel, TRUE,
SILC_NOTIFY_TYPE_CUMODE_CHANGE, 3,
idp->data, idp->len,
- tmp_mask, 4, tmp_id, tmp_len);
- silc_buffer_free(idp);
+ tmp_mask, 4,
+ tmp_id, tmp_len);
}
+ /* Set SET_MODE packet to network */
+ if (!server->standalone)
+ silc_server_send_set_mode(server, server->router->connection,
+ server->server_type == SILC_ROUTER ?
+ TRUE : FALSE, SILC_MODE_TYPE_UCHANNEL,
+ target_mask, 3,
+ tmp_ch_id, tmp_ch_len,
+ idp->data, idp->len,
+ tmp_id, tmp_len);
+
/* Send command reply to sender */
packet = silc_command_reply_payload_encode_va(SILC_COMMAND_CUMODE,
SILC_STATUS_OK, 0, 2,
silc_buffer_free(packet);
silc_free(channel_id);
silc_free(client_id);
+ silc_buffer_free(idp);
out:
silc_server_command_free(cmd);
SilcClientID *client_id, *client_id2;
SilcChannelEntry channel;
SilcClientEntry client;
+ SilcChannelClientEntry chl;
+ unsigned int mode;
unsigned char *tmp;
unsigned int tmp_len;
silc_idlist_del_client(server->global_list, client);
break;
+ case SILC_NOTIFY_TYPE_TOPIC_SET:
+ /*
+ * Distribute the notify to local clients on the channel
+ */
+
+ SILC_LOG_DEBUG(("TOPIC SET notify"));
+
+ channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
+ packet->dst_id_type);
+ if (!channel_id)
+ goto out;
+
+ /* Get channel entry */
+ channel = silc_idlist_find_channel_by_id(server->local_list,
+ channel_id, NULL);
+ if (!channel) {
+ channel = silc_idlist_find_channel_by_id(server->global_list,
+ channel_id, NULL);
+ if (!channel) {
+ silc_free(channel_id);
+ goto out;
+ }
+ }
+
+ /* Get the topic */
+ tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
+ if (!tmp) {
+ silc_free(channel_id);
+ goto out;
+ }
+
+ if (channel->topic)
+ silc_free(channel->topic);
+ channel->topic = silc_calloc(tmp_len, sizeof(*channel->topic));
+ memcpy(channel->topic, tmp, tmp_len);
+
+ /* Send the same notify to the channel */
+ silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
+ FALSE, packet->buffer->data,
+ packet->buffer->len, FALSE);
+ silc_free(channel_id);
+ break;
+
case SILC_NOTIFY_TYPE_NICK_CHANGE:
{
/*
silc_free(client_id2);
break;
}
- case SILC_NOTIFY_TYPE_TOPIC_SET:
- /*
- * Distribute the notify to local clients on the channel
- */
- SILC_LOG_DEBUG(("TOPIC SET notify (not-impl XXX)"));
- break;
case SILC_NOTIFY_TYPE_CMODE_CHANGE:
/*
* Distribute the notify to local clients on the channel
*/
- SILC_LOG_DEBUG(("CMODE CHANGE notify (not-impl XXX)"));
+
+ SILC_LOG_DEBUG(("CMODE CHANGE notify"));
+
+ channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
+ packet->dst_id_type);
+ if (!channel_id)
+ goto out;
+
+ /* Get channel entry */
+ channel = silc_idlist_find_channel_by_id(server->local_list,
+ channel_id, NULL);
+ if (!channel) {
+ channel = silc_idlist_find_channel_by_id(server->global_list,
+ channel_id, NULL);
+ if (!channel) {
+ silc_free(channel_id);
+ goto out;
+ }
+ }
+
+ /* Send the same notify to the channel */
+ silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
+ FALSE, packet->buffer->data,
+ packet->buffer->len, FALSE);
+
+ /* Get the mode */
+ tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
+ if (!tmp) {
+ silc_free(channel_id);
+ goto out;
+ }
+
+ SILC_GET32_MSB(mode, tmp);
+
+ /* Change mode */
+ channel->mode = mode;
+ silc_free(channel_id);
break;
case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
/*
* Distribute the notify to local clients on the channel
*/
- SILC_LOG_DEBUG(("CUMODE CHANGE notify (not-impl XXX)"));
+
+ SILC_LOG_DEBUG(("CUMODE CHANGE notify"));
+
+ channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
+ packet->dst_id_type);
+ if (!channel_id)
+ goto out;
+
+ /* Get channel entry */
+ channel = silc_idlist_find_channel_by_id(server->local_list,
+ channel_id, NULL);
+ if (!channel) {
+ channel = silc_idlist_find_channel_by_id(server->global_list,
+ channel_id, NULL);
+ if (!channel) {
+ silc_free(channel_id);
+ goto out;
+ }
+ }
+
+ /* Get the mode */
+ tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
+ if (!tmp) {
+ silc_free(channel_id);
+ goto out;
+ }
+
+ SILC_GET32_MSB(mode, tmp);
+
+ /* Get target client */
+ tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
+ if (!tmp)
+ goto out;
+ client_id = silc_id_payload_parse_id(tmp, tmp_len);
+ if (!client_id)
+ goto out;
+
+ /* Get client entry */
+ client = silc_idlist_find_client_by_id(server->global_list,
+ client_id, NULL);
+ if (!client) {
+ client = silc_idlist_find_client_by_id(server->local_list,
+ client_id, NULL);
+ if (!client) {
+ silc_free(client_id);
+ goto out;
+ }
+ }
+ silc_free(client_id);
+
+ /* Get entry to the channel user list */
+ silc_list_start(channel->user_list);
+ while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END)
+ if (chl->client == client) {
+ /* Change the mode */
+ chl->mode = mode;
+ break;
+ }
+
+ /* Send the same notify to the channel */
+ silc_server_packet_send_to_channel(server, NULL, channel, packet->type,
+ FALSE, packet->buffer->data,
+ packet->buffer->len, FALSE);
+ silc_free(channel_id);
+ break;
+
+ case SILC_NOTIFY_TYPE_INVITE:
+ SILC_LOG_DEBUG(("INVITE notify (not-impl XXX)"));
break;
/* Ignore rest notify types for now */
case SILC_NOTIFY_TYPE_NONE:
- case SILC_NOTIFY_TYPE_INVITE:
case SILC_NOTIFY_TYPE_MOTD:
+ break;
default:
break;
}
/* Send CUMODE_CHANGE notify to local channel */
silc_server_send_notify_to_channel(server, sock, channel, FALSE,
- SILC_NOTIFY_TYPE_CUMODE_CHANGE, 2,
+ SILC_NOTIFY_TYPE_CUMODE_CHANGE, 3,
tmp, tmp_len,
mode, sizeof(mode),
tmp2, tmp_len2);
out:
if (channel_id)
silc_free(channel_id);
- if (args)
- silc_argument_payload_free(args);
if (payload)
silc_set_mode_payload_free(payload);
}
SILC_ID_CLIENT, &id_cache))
return NULL;
+ SILC_LOG_DEBUG(("Found"));
+
return (SilcClientEntry)id_cache->context;
}
return FALSE;
}
- /* Verify the authencation data */
+ /* Verify the authentication data */
if (!silc_pkcs_verify_with_hash(pkcs, hash, payload->auth_data,
payload->auth_len, tmp, tmp_len)) {
goto err;
if (new->argc) {
- silc_buffer_pull(buffer, 5);
+ silc_buffer_pull(buffer, 9);
new->args = silc_argument_payload_parse(buffer, new->argc);
- silc_buffer_push(buffer, 5);
+ silc_buffer_push(buffer, 9);
}
return new;
silc_free(argv_types);
}
- len += 5;
+ len += 9;
buffer = silc_buffer_alloc(len);
silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer));
silc_buffer_format(buffer,
SILC_STR_UI_SHORT(mode_type),
SILC_STR_UI_SHORT(len),
SILC_STR_UI_INT(mode_mask),
- SILC_STR_UI_CHAR(argc),
+ SILC_STR_UI_CHAR((unsigned char)argc),
SILC_STR_END);
if (argc) {
- silc_buffer_pull(buffer, 5);
+ silc_buffer_pull(buffer, 9);
silc_buffer_format(buffer,
SILC_STR_UI_XNSTRING(args->data, args->len),
SILC_STR_END);
- silc_buffer_push(buffer, 5);
+ silc_buffer_push(buffer, 9);
silc_buffer_free(args);
}