static void
silc_server_command_whois_send_reply(SilcServerCommandContext cmd,
SilcClientEntry *clients,
- unsigned int clients_count)
+ unsigned int clients_count,
+ int count)
{
SilcServer server = cmd->server;
char *tmp;
- int i, count = 0, len;
+ int i, k, len;
SilcBuffer packet, idp, channels;
SilcClientEntry entry;
SilcCommandStatus status;
unsigned char idle[4], mode[4];
SilcSocketConnection hsock;
+ len = 0;
+ for (i = 0; i < clients_count; i++)
+ if (clients[i]->data.registered)
+ len++;
+
status = SILC_STATUS_OK;
- if (clients_count > 1)
+ if (len > 1)
status = SILC_STATUS_LIST_START;
- for (i = 0; i < clients_count; i++) {
+ for (i = 0, k = 0; i < clients_count; i++) {
entry = clients[i];
if (entry->data.registered == FALSE) {
continue;
}
- if (count && i - 1 == count)
- break;
-
- if (i >= 1)
+ if (k >= 1)
status = SILC_STATUS_LIST_ITEM;
- if (clients_count > 1 && i == clients_count - 1)
+ if (clients_count > 1 && k == clients_count - 1)
+ status = SILC_STATUS_LIST_END;
+
+ if (count && k - 1 == count)
status = SILC_STATUS_LIST_END;
+ if (count && k - 1 > count)
+ break;
+
/* Sanity check, however these should never fail. However, as
this sanity check has been added here they have failed. */
if (!entry->nickname || !entry->username || !entry->userinfo)
silc_buffer_free(idp);
if (channels)
silc_buffer_free(channels);
+
+ k++;
}
}
}
/* Send the command reply to the client */
- silc_server_command_whois_send_reply(cmd, clients, clients_count);
+ silc_server_command_whois_send_reply(cmd, clients, clients_count,
+ count);
out:
if (client_id_count) {
}
/* Send the command reply to the client */
- silc_server_command_whois_send_reply(cmd, clients, clients_count);
+ silc_server_command_whois_send_reply(cmd, clients, clients_count,
+ count);
out:
if (client_id_count) {
static void
silc_server_command_identify_send_reply(SilcServerCommandContext cmd,
SilcClientEntry *clients,
- unsigned int clients_count)
+ unsigned int clients_count,
+ int count)
{
SilcServer server = cmd->server;
char *tmp;
- int i, count = 0, len;
+ int i, k, len;
SilcBuffer packet, idp;
SilcClientEntry entry;
SilcCommandStatus status;
char nh[256], uh[256];
SilcSocketConnection hsock;
+ len = 0;
+ for (i = 0; i < clients_count; i++)
+ if (clients[i]->data.registered)
+ len++;
+
status = SILC_STATUS_OK;
- if (clients_count > 1)
+ if (len > 1)
status = SILC_STATUS_LIST_START;
- for (i = 0; i < clients_count; i++) {
+ for (i = 0, k = 0; i < clients_count; i++) {
entry = clients[i];
if (entry->data.registered == FALSE) {
continue;
}
- if (count && i - 1 == count)
- break;
-
- if (i >= 1)
+ if (k >= 1)
status = SILC_STATUS_LIST_ITEM;
- if (clients_count > 1 && i == clients_count - 1)
+ if (clients_count > 1 && k == clients_count - 1)
status = SILC_STATUS_LIST_END;
+ if (count && k - 1 == count)
+ status = SILC_STATUS_LIST_END;
+
+ if (count && k - 1 > count)
+ break;
+
/* Send IDENTIFY reply */
idp = silc_id_payload_encode(entry->id, SILC_ID_CLIENT);
tmp = silc_argument_get_first_arg(cmd->args, NULL);
silc_buffer_free(packet);
silc_buffer_free(idp);
+
+ k++;
}
}
}
}
} else {
- clients = silc_idlist_get_clients_by_nickname(server->local_list,
- nick, server_name,
- &clients_count);
+ clients = silc_idlist_get_clients_by_hash(server->local_list,
+ nick, server->md5hash,
+ &clients_count);
if (!clients)
- clients = silc_idlist_get_clients_by_hash(server->local_list,
- nick, server->md5hash,
- &clients_count);
+ clients = silc_idlist_get_clients_by_nickname(server->local_list,
+ nick, server_name,
+ &clients_count);
}
/* Check global list as well */
}
}
} else {
- clients = silc_idlist_get_clients_by_nickname(server->global_list,
- nick, server_name,
- &clients_count);
+ clients = silc_idlist_get_clients_by_hash(server->global_list,
+ nick, server->md5hash,
+ &clients_count);
if (!clients)
- clients = silc_idlist_get_clients_by_hash(server->global_list,
- nick, server->md5hash,
- &clients_count);
+ clients = silc_idlist_get_clients_by_nickname(server->global_list,
+ nick, server_name,
+ &clients_count);
}
}
}
/* Send the command reply to the client */
- silc_server_command_identify_send_reply(cmd, clients, clients_count);
+ silc_server_command_identify_send_reply(cmd, clients, clients_count,
+ count);
out:
if (client_id_count) {
}
}
} else {
- clients = silc_idlist_get_clients_by_nickname(server->local_list,
- nick, server_name,
- &clients_count);
+ clients = silc_idlist_get_clients_by_hash(server->local_list,
+ nick, server->md5hash,
+ &clients_count);
if (!clients)
- clients = silc_idlist_get_clients_by_hash(server->local_list,
- nick, server->md5hash,
- &clients_count);
+ clients = silc_idlist_get_clients_by_nickname(server->local_list,
+ nick, server_name,
+ &clients_count);
}
/* If we are router we will check our global list as well. */
}
}
} else {
- clients = silc_idlist_get_clients_by_nickname(server->global_list,
- nick, server_name,
- &clients_count);
+ clients = silc_idlist_get_clients_by_hash(server->global_list,
+ nick, server->md5hash,
+ &clients_count);
if (!clients)
- clients = silc_idlist_get_clients_by_hash(server->global_list,
- nick, server->md5hash,
- &clients_count);
+ clients = silc_idlist_get_clients_by_nickname(server->global_list,
+ nick, server_name,
+ &clients_count);
}
}
}
/* Send the command reply */
- silc_server_command_identify_send_reply(cmd, clients, clients_count);
+ silc_server_command_identify_send_reply(cmd, clients, clients_count, count);
out:
if (client_id_count) {
SilcServerCommandContext cmd = (SilcServerCommandContext)context;
SilcServer server = cmd->server;
SilcBuffer packet, idp;
+ unsigned char *tmp;
+ unsigned int tmp_len;
char *dest_server, *server_info = NULL, *server_name;
unsigned short ident = silc_command_get_ident(cmd->payload);
SilcServerEntry entry = NULL;
+ SilcServerID *server_id = NULL;
- SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_INFO, cmd, 1, 1);
+ SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_INFO, cmd, 0, 2);
/* Get server name */
dest_server = silc_argument_get_arg_type(cmd->args, 1, NULL);
- if (!dest_server) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_INFO,
- SILC_STATUS_ERR_NO_SUCH_SERVER);
- goto out;
+
+ /* Get Server ID */
+ tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
+ if (tmp) {
+ server_id = silc_id_payload_parse_id(tmp, tmp_len);
+ if (!server_id) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_INFO,
+ SILC_STATUS_ERR_NO_SERVER_ID);
+ goto out;
+ }
}
- if (!strncasecmp(dest_server, server->server_name, strlen(dest_server))) {
+ if (server_id) {
+ /* Check whether we have this server cached */
+ entry = silc_idlist_find_server_by_id(server->local_list,
+ server_id, NULL);
+ if (!entry) {
+ entry = silc_idlist_find_server_by_id(server->global_list,
+ server_id, NULL);
+ if (!entry && server->server_type == SILC_ROUTER) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_INFO,
+ SILC_STATUS_ERR_NO_SUCH_SERVER);
+ goto out;
+ }
+ }
+ }
+
+ if ((!dest_server && !server_id) ||
+ (dest_server && !cmd->pending &&
+ !strncasecmp(dest_server, server->server_name, strlen(dest_server)))) {
/* Send our reply */
char info_string[256];
entry = server->id_entry;
} else {
/* Check whether we have this server cached */
- entry = silc_idlist_find_server_by_name(server->global_list,
- dest_server, NULL);
- if (!entry) {
- entry = silc_idlist_find_server_by_name(server->local_list,
+ if (!entry && dest_server) {
+ entry = silc_idlist_find_server_by_name(server->global_list,
dest_server, NULL);
+ if (!entry) {
+ entry = silc_idlist_find_server_by_name(server->local_list,
+ dest_server, NULL);
+ }
}
- if (server->server_type == SILC_ROUTER && entry && !entry->server_info) {
+ if (!cmd->pending &&
+ server->server_type == SILC_ROUTER && entry && !entry->server_info) {
/* Send to the server */
SilcBuffer tmpbuf;
unsigned short old_ident;
}
}
+ if (server_id)
+ silc_free(server_id);
+
if (!entry) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_INFO,
SILC_STATUS_ERR_NO_SUCH_SERVER);
idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
if (!server_info)
server_info = entry->server_info;
- server_name = dest_server;
+ server_name = entry->server_name;
/* Send the reply */
packet = silc_command_reply_payload_encode_va(SILC_COMMAND_INFO,
unsigned char *passphrase = NULL, mode[4], tmp2[4], tmp3[4];
SilcClientEntry client;
SilcChannelClientEntry chl;
- SilcBuffer reply, chidp, clidp, keyp, user_list, mode_list;
+ SilcBuffer reply, chidp, clidp, keyp = NULL, user_list, mode_list;
unsigned short ident = silc_command_get_ident(cmd->payload);
char check[512];
/* Send the channel key. This is broadcasted to the channel but is not
sent to the client who is joining to the channel. */
- silc_server_send_channel_key(server, NULL, channel,
- server->server_type == SILC_ROUTER ?
- FALSE : !server->standalone);
+ if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY))
+ silc_server_send_channel_key(server, NULL, channel,
+ server->server_type == SILC_ROUTER ?
+ FALSE : !server->standalone);
/* Join the client to the channel by adding it to channel's user list.
Add also the channel to client entry's channels list for fast cross-
SILC_PUT32_MSB(channel->mode, mode);
SILC_PUT32_MSB(created, tmp2);
SILC_PUT32_MSB(user_count, tmp3);
- tmp = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
- keyp = silc_channel_key_payload_encode(SILC_ID_CHANNEL_LEN, tmp,
- strlen(channel->channel_key->
- cipher->name),
- channel->channel_key->cipher->name,
- channel->key_len / 8, channel->key);
- silc_free(tmp);
+
+ if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
+ tmp = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
+ keyp = silc_channel_key_payload_encode(SILC_ID_CHANNEL_LEN, tmp,
+ strlen(channel->channel_key->
+ cipher->name),
+ channel->channel_key->cipher->name,
+ channel->key_len / 8, channel->key);
+ silc_free(tmp);
+ }
+
reply =
silc_command_reply_payload_encode_va(SILC_COMMAND_JOIN,
SILC_STATUS_OK, ident, 13,
4, clidp->data, clidp->len,
5, mode, 4,
6, tmp2, 4,
- 7, keyp->data, keyp->len,
+ 7, keyp ? keyp->data : NULL,
+ keyp ? keyp->len : 0,
8, channel->ban_list,
channel->ban_list ?
strlen(channel->ban_list) : 0,
}
}
- if (!channel) {
+ if (!channel || !channel->id) {
/* Channel not found */
/* If we are standalone server we don't have a router, we just create
if (server->standalone) {
channel = silc_server_create_new_channel(server, server->id, cipher,
hmac, channel_name, TRUE);
+ if (!channel) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
+ SILC_STATUS_ERR_UNKNOWN_ALGORITHM);
+ goto out;
+ }
+
umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
created = TRUE;
/* Channel really does not exist, create it */
channel = silc_server_create_new_channel(server, server->id, cipher,
hmac, channel_name, TRUE);
+ if (!channel) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
+ SILC_STATUS_ERR_UNKNOWN_ALGORITHM);
+ goto out;
+ }
+
umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
created = TRUE;
}
/* Channel really does not exist, create it */
channel = silc_server_create_new_channel(server, server->id, cipher,
hmac, channel_name, TRUE);
+ if (!channel) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
+ SILC_STATUS_ERR_UNKNOWN_ALGORITHM);
+ goto out;
+ }
+
umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
created = TRUE;
}
*/
if (mask & SILC_UMODE_SERVER_OPERATOR) {
- /* Cannot operator mode */
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_UMODE,
- SILC_STATUS_ERR_PERM_DENIED);
- goto out;
+ if (!(client->mode & SILC_UMODE_SERVER_OPERATOR)) {
+ /* Cannot operator mode */
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_UMODE,
+ SILC_STATUS_ERR_PERM_DENIED);
+ goto out;
+ }
} else {
if (client->mode & SILC_UMODE_SERVER_OPERATOR)
/* Remove the server operator rights */
}
if (mask & SILC_UMODE_ROUTER_OPERATOR) {
- /* Cannot operator mode */
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_UMODE,
- SILC_STATUS_ERR_PERM_DENIED);
- goto out;
+ if (!(client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
+ /* Cannot operator mode */
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_UMODE,
+ SILC_STATUS_ERR_PERM_DENIED);
+ goto out;
+ }
} else {
if (client->mode & SILC_UMODE_ROUTER_OPERATOR)
/* Remove the router operator rights */
client->mode &= ~SILC_UMODE_ROUTER_OPERATOR;
}
+ if (mask & SILC_UMODE_GONE) {
+ client->mode |= SILC_UMODE_GONE;
+ } else {
+ if (client->mode & SILC_UMODE_GONE)
+ /* Remove the gone status */
+ client->mode &= ~SILC_UMODE_GONE;
+ }
+
/* Send UMODE change to primary router */
if (!server->standalone)
silc_server_send_notify_umode(server, server->router->connection, TRUE,
}
}
+ if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
+ if (is_op && !is_fo)
+ return FALSE;
+ } else {
+ if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
+ if (is_op && !is_fo)
+ return FALSE;
+ }
+ }
+
return TRUE;
}
SilcServerCommandContext cmd = (SilcServerCommandContext)context;
SilcServer server = cmd->server;
SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
+ SilcIDListData idata = (SilcIDListData)client;
SilcChannelID *channel_id;
SilcChannelEntry channel;
SilcChannelClientEntry chl;
SilcBuffer packet, cidp;
unsigned char *tmp, *tmp_id, *tmp_mask;
char *cipher = NULL, *hmac = NULL;
- unsigned int argc, mode_mask, tmp_len, tmp_len2;
+ unsigned int mode_mask, tmp_len, tmp_len2;
unsigned short ident = silc_command_get_ident(cmd->payload);
- SILC_LOG_DEBUG(("Start"));
-
- argc = silc_argument_get_arg_num(cmd->args);
- if (argc < 2) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
- goto out;
- }
- if (argc > 8) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
- SILC_STATUS_ERR_TOO_MANY_PARAMS);
- goto out;
- }
+ SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_CMODE, cmd, 2, 7);
/* Get Channel ID */
tmp_id = silc_argument_get_arg_type(cmd->args, 1, &tmp_len2);
}
}
+ if (mode_mask & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
+ if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
+ if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
+ /* Set the founder authentication */
+ SilcAuthPayload auth;
+
+ tmp = silc_argument_get_arg_type(cmd->args, 7, &tmp_len);
+ if (!tmp) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ goto out;
+ }
+
+ auth = silc_auth_payload_parse(tmp, tmp_len);
+ if (!auth) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ goto out;
+ }
+
+ /* Save the public key */
+ tmp = silc_pkcs_public_key_encode(idata->public_key, &tmp_len);
+ silc_pkcs_public_key_decode(tmp, tmp_len, &channel->founder_key);
+ silc_free(tmp);
+
+ channel->founder_method = silc_auth_get_method(auth);
+
+ if (channel->founder_method == SILC_AUTH_PASSWORD) {
+ tmp = silc_auth_get_data(auth, &tmp_len);
+ channel->founder_passwd =
+ silc_calloc(tmp_len + 1, sizeof(*channel->founder_passwd));
+ memcpy(channel->founder_passwd, tmp, tmp_len);
+ channel->founder_passwd_len = tmp_len;
+ }
+
+ silc_auth_payload_free(auth);
+ }
+ }
+ } else {
+ if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
+ if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
+ if (channel->founder_key)
+ silc_pkcs_public_key_free(channel->founder_key);
+ if (channel->founder_passwd) {
+ silc_free(channel->founder_passwd);
+ channel->founder_passwd = NULL;
+ }
+ }
+ }
+ }
+
/* Finally, set the mode */
channel->mode = mode_mask;
silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
SILC_NOTIFY_TYPE_CMODE_CHANGE, 4,
cidp->data, cidp->len,
- tmp_mask, tmp_len,
+ tmp_mask, 4,
cipher, cipher ? strlen(cipher) : 0,
hmac, hmac ? strlen(hmac) : 0);
silc_server_send_notify_cmode(server, server->router->connection,
server->server_type == SILC_ROUTER ?
TRUE : FALSE, channel,
- mode_mask, client->id, SILC_ID_CLIENT_LEN,
+ mode_mask, client->id, SILC_ID_CLIENT,
+ SILC_ID_CLIENT_LEN,
cipher, hmac);
/* Send command reply to sender */
SilcServerCommandContext cmd = (SilcServerCommandContext)context;
SilcServer server = cmd->server;
SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
+ SilcIDListData idata = (SilcIDListData)client;
SilcChannelID *channel_id;
SilcClientID *client_id;
SilcChannelEntry channel;
SilcChannelClientEntry chl;
SilcBuffer packet, idp;
unsigned char *tmp_id, *tmp_ch_id, *tmp_mask;
- unsigned int target_mask, sender_mask, tmp_len, tmp_ch_len;
+ unsigned int target_mask, sender_mask = 0, tmp_len, tmp_ch_len;
int notify = FALSE;
unsigned short ident = silc_command_get_ident(cmd->payload);
- SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_CUMODE, cmd, 3, 3);
+ SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_CUMODE, cmd, 3, 4);
/* Get Channel ID */
tmp_ch_id = silc_argument_get_arg_type(cmd->args, 1, &tmp_ch_len);
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_CHANFO) &&
- !(chl->mode & SILC_CHANNEL_UMODE_CHANOP)) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
- SILC_STATUS_ERR_NO_CHANNEL_PRIV);
- goto out;
- }
-
sender_mask = chl->mode;
break;
}
client_id, NULL);
}
- /* Check whether target client is on the channel */
- if (!silc_server_client_on_channel(target_client, channel)) {
+ if (target_client != client &&
+ !(sender_mask & SILC_CHANNEL_UMODE_CHANFO) &&
+ !(sender_mask & SILC_CHANNEL_UMODE_CHANOP)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
- SILC_STATUS_ERR_USER_NOT_ON_CHANNEL);
+ SILC_STATUS_ERR_NO_CHANNEL_PRIV);
goto out;
}
- /* 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 == target_client)
- break;
+ /* Check whether target client is on the channel */
+ if (target_client != client) {
+ if (!silc_server_client_on_channel(target_client, channel)) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+ SILC_STATUS_ERR_USER_NOT_ON_CHANNEL);
+ goto out;
+ }
+
+ /* 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 == target_client)
+ break;
+ }
/*
* Change the mode
}
if (target_mask & SILC_CHANNEL_UMODE_CHANFO) {
- /* Cannot promote anyone to channel founder */
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
- SILC_STATUS_ERR_NOT_YOU);
- goto out;
+ /* The client tries to claim the founder rights. */
+ unsigned char *tmp_auth;
+ unsigned int tmp_auth_len, auth_len;
+ void *auth;
+
+ if (target_client != client) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+ SILC_STATUS_ERR_NOT_YOU);
+ goto out;
+ }
+
+ if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) ||
+ !channel->founder_key) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+ SILC_STATUS_ERR_NOT_YOU);
+ goto out;
+ }
+
+ tmp_auth = silc_argument_get_arg_type(cmd->args, 4, &tmp_auth_len);
+ if (!tmp_auth) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ goto out;
+ }
+
+ auth = (channel->founder_method == SILC_AUTH_PASSWORD ?
+ (void *)channel->founder_passwd : (void *)channel->founder_key);
+ auth_len = (channel->founder_method == SILC_AUTH_PASSWORD ?
+ channel->founder_passwd_len : 0);
+
+ if (!silc_auth_verify_data(tmp_auth, tmp_auth_len,
+ channel->founder_method, auth, auth_len,
+ idata->hash, client->id, SILC_ID_CLIENT)) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+ SILC_STATUS_ERR_AUTH_FAILED);
+ goto out;
+ }
+
+ chl->mode |= SILC_CHANNEL_UMODE_CHANFO;
+ notify = TRUE;
} else {
if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
if (target_client == client) {
if (target_mask & SILC_CHANNEL_UMODE_CHANOP) {
/* Promote to operator */
if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP)) {
+ if (!(sender_mask & SILC_CHANNEL_UMODE_CHANOP) &&
+ !(sender_mask & SILC_CHANNEL_UMODE_CHANFO)) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+ SILC_STATUS_ERR_NO_CHANNEL_PRIV);
+ goto out;
+ }
+
chl->mode |= SILC_CHANNEL_UMODE_CHANOP;
notify = TRUE;
}
} else {
if (chl->mode & SILC_CHANNEL_UMODE_CHANOP) {
+ if (!(sender_mask & SILC_CHANNEL_UMODE_CHANOP) &&
+ !(sender_mask & SILC_CHANNEL_UMODE_CHANFO)) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+ SILC_STATUS_ERR_NO_CHANNEL_PRIV);
+ goto out;
+ }
+
/* Demote to normal user */
chl->mode &= ~SILC_CHANNEL_UMODE_CHANOP;
notify = TRUE;
}
idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
+ tmp_id = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
/* Send notify to channel, notify only if mode was actually changed. */
if (notify) {
target_client->id, SILC_ID_CLIENT_LEN,
comment);
- /* Re-generate channel key */
- silc_server_create_channel_key(server, channel, 0);
-
- /* Send the channel key to the channel. The key of course is not sent
- to the client who was kicked off the channel. */
- silc_server_send_channel_key(server, target_client->connection, channel,
- server->server_type == SILC_ROUTER ?
- FALSE : !server->standalone);
+ if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
+ /* Re-generate channel key */
+ silc_server_create_channel_key(server, channel, 0);
+
+ /* Send the channel key to the channel. The key of course is not sent
+ to the client who was kicked off the channel. */
+ silc_server_send_channel_key(server, target_client->connection, channel,
+ server->server_type == SILC_ROUTER ?
+ FALSE : !server->standalone);
+ }
out:
silc_server_command_free(cmd);
SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_SILCOPER, cmd, 1, 2);
+ if (server->server_type == SILC_SERVER)
+ goto out;
+
if (!client || cmd->sock->type != SILC_SOCKET_TYPE_CLIENT)
goto out;
SILC_SERVER_CMD_FUNC(restart)
{
+ SilcServerCommandContext cmd = (SilcServerCommandContext)context;
+
+ silc_server_command_free(cmd);
}
/* Server side command of CLOSE. Closes connection to a specified server. */
SilcClientEntry id_entry = (SilcClientEntry)cmd->sock->user_data;
SilcChannelID *id;
SilcChannelEntry channel;
- SilcBuffer packet;
- unsigned int i, len;
+ unsigned int len;
unsigned char *tmp;
SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_LEAVE, cmd, 1, 2);
TRUE : FALSE, channel, id_entry->id,
SILC_ID_CLIENT_LEN);
- /* Remove client from channel */
- i = silc_server_remove_from_one_channel(server, sock, channel, id_entry,
- TRUE);
silc_server_command_send_status_reply(cmd, SILC_COMMAND_LEAVE,
SILC_STATUS_OK);
- /* If the channel does not exist anymore we won't send anything */
- if (!i)
+ /* Remove client from channel */
+ if (!silc_server_remove_from_one_channel(server, sock, channel, id_entry,
+ TRUE))
+ /* If the channel does not exist anymore we won't send anything */
goto out;
- /* Re-generate channel key */
- silc_server_create_channel_key(server, channel, 0);
-
- /* Encode channel key payload to be distributed on the channel */
- packet =
- silc_channel_key_payload_encode(len, tmp,
- strlen(channel->channel_key->cipher->name),
- channel->channel_key->cipher->name,
- channel->key_len / 8, channel->key);
-
- /* If we are normal server then we will send it to our router. If we
- are router we will send it to all local servers that has clients on
- the channel */
- if (server->server_type == SILC_SERVER) {
- if (!server->standalone)
- silc_server_packet_send(server,
- cmd->server->router->connection,
- SILC_PACKET_CHANNEL_KEY, 0, packet->data,
- packet->len, FALSE);
- } else {
+ if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
+ /* Re-generate channel key */
+ silc_server_create_channel_key(server, channel, 0);
+ /* Send the channel key */
+ silc_server_send_channel_key(server, NULL, channel,
+ server->server_type == SILC_ROUTER ?
+ FALSE : !server->standalone);
}
- /* Send to locally connected clients on the channel */
- silc_server_packet_send_local_channel(server, channel,
- SILC_PACKET_CHANNEL_KEY, 0,
- packet->data, packet->len, FALSE);
-
- silc_buffer_free(packet);
silc_free(id);
out: