/* Check nickname */
nick = silc_argument_get_arg_type(cmd->args, 1, &nick_len);
+ if (!nick) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_NICK,
+ SILC_STATUS_ERR_BAD_NICKNAME, 0);
+ goto out;
+ }
if (nick_len > 128)
nick[128] = '\0';
if (silc_server_name_bad_chars(nick, nick_len) == TRUE) {
SilcChannelEntry channel;
SilcChannelID *channel_id = NULL;
SilcIDListData idata;
- SilcBuffer idp, idp2, packet;
- unsigned char *tmp, *add, *del;
- SilcUInt32 len;
- SilcUInt16 ident = silc_command_get_ident(cmd->payload);
+ SilcArgumentPayload args;
+ SilcHashTableList htl;
+ SilcBuffer packet, list, tmp2;
+ unsigned char *tmp;
+ SilcUInt32 len, type;
+ SilcUInt16 argc = 0, ident = silc_command_get_ident(cmd->payload);
SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_INVITE, cmd, 1, 4);
/* Get destination client ID */
tmp = silc_argument_get_arg_type(cmd->args, 2, &len);
if (tmp) {
- char invite[512];
bool resolve;
dest_id = silc_id_payload_parse_id(tmp, len, NULL);
/* Get the client entry */
dest = silc_server_query_client(server, dest_id, FALSE, &resolve);
if (!dest) {
- if (server->server_type != SILC_SERVER || !resolve) {
+ if (server->server_type != SILC_SERVER || !resolve || cmd->pending) {
silc_server_command_send_status_reply(
cmd, SILC_COMMAND_INVITE,
SILC_STATUS_ERR_NO_SUCH_CLIENT_ID, 0);
goto out;
}
- memset(invite, 0, sizeof(invite));
- silc_strncat(invite, sizeof(invite),
- dest->nickname, strlen(dest->nickname));
- silc_strncat(invite, sizeof(invite), "!", 1);
- silc_strncat(invite, sizeof(invite),
- dest->username, strlen(dest->username));
- if (!strchr(dest->username, '@')) {
- silc_strncat(invite, sizeof(invite), "@", 1);
- silc_strncat(invite, sizeof(invite), cmd->sock->hostname,
- strlen(cmd->sock->hostname));
- }
+ /* Add the client to the invite list */
- len = strlen(invite);
+ /* Allocate hash table for invite list if it doesn't exist yet */
if (!channel->invite_list)
- channel->invite_list = silc_calloc(len + 2,
- sizeof(*channel->invite_list));
- else
- channel->invite_list = silc_realloc(channel->invite_list,
- sizeof(*channel->invite_list) *
- (len +
- strlen(channel->invite_list) + 2));
- strncat(channel->invite_list, invite, len);
- strncat(channel->invite_list, ",", 1);
+ channel->invite_list = silc_hash_table_alloc(0, silc_hash_ptr,
+ NULL, NULL, NULL,
+ NULL, NULL, TRUE);
+
+ /* Check if the ID is in the list already */
+ silc_hash_table_list(channel->invite_list, &htl);
+ while (silc_hash_table_get(&htl, (void **)&type, (void **)&tmp2)) {
+ if (type == 3 && !memcmp(tmp2->data, tmp, len)) {
+ tmp = NULL;
+ break;
+ }
+ }
+ silc_hash_table_list_reset(&htl);
+
+ /* Add new Client ID to invite list */
+ if (tmp) {
+ list = silc_buffer_alloc_size(len);
+ silc_buffer_put(list, tmp, len);
+ silc_hash_table_add(channel->invite_list, (void *)3, list);
+ }
if (!(dest->mode & SILC_UMODE_BLOCK_INVITE)) {
/* Send notify to the client that is invited to the channel */
+ SilcBuffer idp, idp2;
idp = silc_id_payload_encode(channel_id, SILC_ID_CHANNEL);
idp2 = silc_id_payload_encode(sender->id, SILC_ID_CLIENT);
silc_server_send_notify_dest(server, dest_sock, FALSE, dest_id,
}
}
- /* Add the client to the invite list of the channel */
- add = silc_argument_get_arg_type(cmd->args, 3, &len);
- if (add) {
- if (!channel->invite_list)
- channel->invite_list = silc_calloc(len + 2,
- sizeof(*channel->invite_list));
- else
- channel->invite_list = silc_realloc(channel->invite_list,
- sizeof(*channel->invite_list) *
- (len +
- strlen(channel->invite_list) + 2));
- if (add[len - 1] == ',')
- add[len - 1] = '\0';
-
- strncat(channel->invite_list, add, len);
- strncat(channel->invite_list, ",", 1);
- }
-
- /* Get the invite to be removed and remove it from the list */
- del = silc_argument_get_arg_type(cmd->args, 4, &len);
- if (del && channel->invite_list) {
- char *start, *end, *n;
+ /* Get the invite information */
+ tmp = silc_argument_get_arg_type(cmd->args, 4, &len);
+ if (tmp) {
+ /* Parse the arguments to see they are constructed correctly */
+ SILC_GET16_MSB(argc, tmp);
+ args = silc_argument_payload_parse(tmp + 2, len - 2, argc);
+ if (!args) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
+ 0);
+ goto out;
+ }
- if (!strncmp(channel->invite_list, del,
- strlen(channel->invite_list) - 1)) {
- silc_free(channel->invite_list);
- channel->invite_list = NULL;
- } else {
- start = strstr(channel->invite_list, del);
- if (start && strlen(start) >= len) {
- end = start + len;
- n = silc_calloc(strlen(channel->invite_list) - len, sizeof(*n));
- strncat(n, channel->invite_list, start - channel->invite_list);
- strncat(n, end + 1, ((channel->invite_list +
- strlen(channel->invite_list)) - end) - 1);
- silc_free(channel->invite_list);
- channel->invite_list = n;
+ /* Get the type of action */
+ tmp = silc_argument_get_arg_type(cmd->args, 3, &len);
+ if (tmp && len == 1) {
+ if (tmp[0] == 0x00) {
+ /* Allocate hash table for invite list if it doesn't exist yet */
+ if (!channel->invite_list)
+ channel->invite_list = silc_hash_table_alloc(0, silc_hash_ptr,
+ NULL, NULL, NULL,
+ NULL, NULL, TRUE);
+
+ /* Check for resource limit */
+ if (silc_hash_table_count(channel->invite_list) > 64) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
+ SILC_STATUS_ERR_RESOURCE_LIMIT,
+ 0);
+ goto out;
+ }
}
+
+ /* Now add or delete the information. */
+ silc_server_inviteban_process(server, channel->invite_list,
+ (SilcUInt8)tmp[0], args);
}
+ silc_argument_payload_free(args);
+ }
+
+ /* Encode invite list */
+ list = NULL;
+ if (channel->invite_list) {
+ list = silc_buffer_alloc_size(2);
+ silc_buffer_format(list,
+ SILC_STR_UI_SHORT(silc_hash_table_count(
+ channel->invite_list)),
+ SILC_STR_END);
+ silc_hash_table_list(channel->invite_list, &htl);
+ while (silc_hash_table_get(&htl, (void **)&type, (void **)&tmp2)) {
+ if (type == 1)
+ list = silc_argument_payload_encode_one(list, (char *)tmp2,
+ strlen((char *)tmp2), type);
+ else
+ list = silc_argument_payload_encode_one(list, tmp2->data, tmp2->len,
+ type);
+ }
+ silc_hash_table_list_reset(&htl);
}
/* Send notify to the primary router */
- silc_server_send_notify_invite(server, SILC_PRIMARY_ROUTE(server),
- SILC_BROADCAST(server), channel,
- sender->id, add, del);
+ silc_server_send_notify_invite(
+ server, SILC_PRIMARY_ROUTE(server),
+ SILC_BROADCAST(server), channel, sender->id,
+ silc_argument_get_arg_type(cmd->args, 3, NULL),
+ list);
/* Send command reply */
tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
-
- packet =
- silc_command_reply_payload_encode_va(SILC_COMMAND_INVITE,
- SILC_STATUS_OK, 0, ident, 2,
- 2, tmp, len,
- 3, channel->invite_list,
- channel->invite_list ?
- strlen(channel->invite_list) : 0);
+ packet = silc_command_reply_payload_encode_va(SILC_COMMAND_INVITE,
+ SILC_STATUS_OK, 0, ident, 2,
+ 2, tmp, len,
+ 3, list ? list->data : NULL,
+ list ? list->len : 0);
silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
packet->data, packet->len, FALSE);
silc_buffer_free(packet);
+ silc_buffer_free(list);
out:
silc_free(dest_id);
SilcServer server = cmd->server;
SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
SilcClientEntry remote_client;
- SilcClientID *client_id;
- unsigned char *tmp, *comment;
- SilcUInt32 tmp_len, tmp_len2;
- bool local;
+ SilcClientID *client_id = NULL;
+ unsigned char *tmp, *comment, *auth;
+ SilcUInt32 tmp_len, tmp_len2, auth_len;
- SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_KILL, cmd, 1, 2);
+ SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_KILL, cmd, 1, 3);
if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
goto out;
- /* KILL command works only on router */
- if (server->server_type != SILC_ROUTER) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
- SILC_STATUS_ERR_NO_ROUTER_PRIV, 0);
- goto out;
- }
+ /* Get authentication payload if present */
+ auth = silc_argument_get_arg_type(cmd->args, 3, &auth_len);
- /* Check whether client has the permissions. */
- if (!(client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
- SILC_STATUS_ERR_NO_ROUTER_PRIV, 0);
- goto out;
+ if (!auth) {
+ /* Router operator killing */
+
+ /* KILL command works only on router */
+ if (server->server_type != SILC_ROUTER) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
+ SILC_STATUS_ERR_NO_ROUTER_PRIV, 0);
+ goto out;
+ }
+
+ /* Check whether client has the permissions. */
+ if (!(client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
+ SILC_STATUS_ERR_NO_ROUTER_PRIV, 0);
+ goto out;
+ }
}
/* Get the client ID */
/* Get the client entry */
remote_client = silc_idlist_find_client_by_id(server->local_list,
client_id, TRUE, NULL);
- local = TRUE;
if (!remote_client) {
remote_client = silc_idlist_find_client_by_id(server->global_list,
client_id, TRUE, NULL);
- local = FALSE;
if (!remote_client) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
/* Get comment */
comment = silc_argument_get_arg_type(cmd->args, 2, &tmp_len2);
- if (tmp_len2 > 128)
+ if (comment && tmp_len2 > 128) {
tmp_len2 = 128;
+ comment[127] = '\0';
+ }
- /* Send reply to the sender */
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
- SILC_STATUS_OK, 0);
+ /* If authentication data is provided then verify that killing is
+ actually allowed */
+ if (auth && auth_len) {
+ SilcSocketConnection sock;
- /* Check if anyone is watching this nickname */
- if (server->server_type == SILC_ROUTER)
- silc_server_check_watcher_list(server, client, NULL,
- SILC_NOTIFY_TYPE_KILLED);
+ if (!SILC_IS_LOCAL(remote_client) || !remote_client->data.public_key) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
+ SILC_STATUS_ERR_OPERATION_ALLOWED,
+ 0);
+ goto out;
+ }
- /* Now do the killing */
- silc_server_kill_client(server, remote_client, comment, client->id,
- SILC_ID_CLIENT);
+ /* Verify the signature */
+ if (!silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
+ remote_client->data.public_key, 0,
+ server->sha1hash, remote_client->id,
+ SILC_ID_CLIENT)) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
+ SILC_STATUS_ERR_AUTH_FAILED,
+ 0);
+ goto out;
+ }
+
+ /* Send reply to the sender */
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
+ SILC_STATUS_OK, 0);
+
+ /* Do normal signoff for the destination client */
+ sock = remote_client->connection;
+ silc_server_free_client_data(server, NULL, remote_client, TRUE,
+ comment ? comment :
+ (unsigned char *)"Killed");
+ if (sock)
+ silc_server_close_connection(server, sock);
+ } else {
+ /* Router operator killing */
+
+ /* Send reply to the sender */
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
+ SILC_STATUS_OK, 0);
+
+ /* Check if anyone is watching this nickname */
+ if (server->server_type == SILC_ROUTER)
+ silc_server_check_watcher_list(server, client, NULL,
+ SILC_NOTIFY_TYPE_KILLED);
+
+ /* Now do the killing */
+ silc_server_kill_client(server, remote_client, comment, client->id,
+ SILC_ID_CLIENT);
+ }
out:
+ silc_free(client_id);
silc_server_command_free(cmd);
}
{
SilcServerCommandContext cmd = (SilcServerCommandContext)context;
SilcServer server = cmd->server;
- SilcServerID *id;
- SilcUInt32 len;
+ SilcUInt32 tmp_len;
unsigned char *tmp;
+ SilcServerID *server_id = NULL;
- SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_INFO, cmd, 1, 2);
+ SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_PING, cmd, 1, 1);
/* Get Server ID */
- tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
+ tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
if (!tmp) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_PING,
SILC_STATUS_ERR_NO_SERVER_ID, 0);
goto out;
}
- id = silc_id_str2id(tmp, len, SILC_ID_SERVER);
- if (!id)
+ server_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
+ if (!server_id)
goto out;
- if (SILC_ID_SERVER_COMPARE(id, server->id)) {
+ if (SILC_ID_SERVER_COMPARE(server_id, server->id)) {
/* Send our reply */
silc_server_command_send_status_reply(cmd, SILC_COMMAND_PING,
SILC_STATUS_OK, 0);
goto out;
}
- silc_free(id);
-
out:
+ silc_free(server_id);
silc_server_command_free(cmd);
}
/* Get Server ID */
tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
if (!tmp) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_INFO,
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_PING,
SILC_STATUS_ERR_NO_SERVER_ID, 0);
goto out;
}
/* The ID must be ours */
if (!SILC_ID_SERVER_COMPARE(server->id, server_id)) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_INFO,
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_PING,
SILC_STATUS_ERR_NO_SUCH_SERVER, 0);
silc_free(server_id);
goto out;
unsigned char *passphrase = NULL, mode[4], tmp2[4], tmp3[4];
SilcClientEntry client;
SilcChannelClientEntry chl;
- SilcBuffer reply, chidp, clidp, keyp = NULL, user_list, mode_list;
+ SilcBuffer reply, chidp, clidp, keyp = NULL;
+ SilcBuffer user_list, mode_list, invite_list, ban_list;
SilcUInt16 ident = silc_command_get_ident(cmd->payload);
char check[512], check2[512];
bool founder = FALSE;
bool resolve;
- unsigned char *fkey = NULL;
- SilcUInt32 fkey_len = 0;
+ SilcBuffer fkey = NULL;
const char *cipher;
SILC_LOG_DEBUG(("Joining client to channel"));
client = silc_server_query_client(server, client_id, FALSE,
&resolve);
if (!client) {
- if (cmd->pending)
- goto out;
-
- if (!resolve) {
+ if (!resolve || cmd->pending) {
silc_server_command_send_status_reply(
cmd, SILC_COMMAND_JOIN,
SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
/* Check invite list if channel is invite-only channel */
if (channel->mode & SILC_CHANNEL_MODE_INVITE) {
if (!channel->invite_list ||
- (!silc_string_match(channel->invite_list, check) &&
- !silc_string_match(channel->invite_list, check2))) {
+ (!silc_server_inviteban_match(server, channel->invite_list,
+ 3, client->id) &&
+ !silc_server_inviteban_match(server, channel->invite_list,
+ 2, client->data.public_key) &&
+ !silc_server_inviteban_match(server, channel->invite_list,
+ 1, check) &&
+ !silc_server_inviteban_match(server, channel->invite_list,
+ 1, check2))) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
SILC_STATUS_ERR_NOT_INVITED, 0);
goto out;
username and/or hostname is in the ban list the access to the
channel is denied. */
if (channel->ban_list) {
- if (silc_string_match(channel->ban_list, check) ||
- silc_string_match(channel->ban_list, check2)) {
+ if (silc_server_inviteban_match(server, channel->invite_list,
+ 3, client->id) ||
+ silc_server_inviteban_match(server, channel->invite_list,
+ 2, client->data.public_key) ||
+ !silc_server_inviteban_match(server, channel->invite_list,
+ 1, check) ||
+ !silc_server_inviteban_match(server, channel->invite_list,
+ 1, check2)) {
silc_server_command_send_status_reply(
cmd, SILC_COMMAND_JOIN,
SILC_STATUS_ERR_BANNED_FROM_CHANNEL, 0);
}
if (channel->founder_key)
- fkey = silc_pkcs_public_key_encode(channel->founder_key, &fkey_len);
+ fkey = silc_pkcs_public_key_payload_encode(channel->founder_key);
+
+ /* Encode invite list */
+ invite_list = NULL;
+ if (channel->invite_list) {
+ SilcHashTableList htl;
+
+ invite_list = silc_buffer_alloc_size(2);
+ silc_buffer_format(invite_list,
+ SILC_STR_UI_SHORT(silc_hash_table_count(
+ channel->invite_list)),
+ SILC_STR_END);
+
+ silc_hash_table_list(channel->invite_list, &htl);
+ while (silc_hash_table_get(&htl, (void **)&tmp_len, (void **)&reply)) {
+ if (tmp_len == 1)
+ invite_list = silc_argument_payload_encode_one(invite_list,
+ (char *)reply,
+ strlen((char *)reply),
+ tmp_len);
+ else
+ invite_list = silc_argument_payload_encode_one(invite_list,
+ reply->data,
+ reply->len, tmp_len);
+ }
+ silc_hash_table_list_reset(&htl);
+ }
+
+ /* Encode ban list */
+ ban_list = NULL;
+ if (channel->ban_list) {
+ SilcHashTableList htl;
+
+ ban_list = silc_buffer_alloc_size(2);
+ silc_buffer_format(ban_list,
+ SILC_STR_UI_SHORT(silc_hash_table_count(
+ channel->ban_list)),
+ SILC_STR_END);
+
+ silc_hash_table_list(channel->ban_list, &htl);
+ while (silc_hash_table_get(&htl, (void **)&tmp_len, (void **)&reply)) {
+ if (tmp_len == 1)
+ ban_list = silc_argument_payload_encode_one(ban_list,
+ (char *)reply,
+ strlen((char *)reply),
+ tmp_len);
+ else
+ ban_list = silc_argument_payload_encode_one(ban_list,
+ reply->data,
+ reply->len, tmp_len);
+ }
+ silc_hash_table_list_reset(&htl);
+ }
reply =
silc_command_reply_payload_encode_va(SILC_COMMAND_JOIN,
6, tmp2, 4,
7, keyp ? keyp->data : NULL,
keyp ? keyp->len : 0,
- 8, channel->ban_list,
- channel->ban_list ?
- strlen(channel->ban_list) : 0,
- 9, channel->invite_list,
- channel->invite_list ?
- strlen(channel->invite_list) : 0,
+ 8, ban_list ? ban_list->data : NULL,
+ ban_list ? ban_list->len : 0,
+ 9, invite_list ? invite_list->data :
+ NULL,
+ invite_list ? invite_list->len : 0,
10, channel->topic,
channel->topic ?
strlen(channel->topic) : 0,
13, user_list->data, user_list->len,
14, mode_list->data,
mode_list->len,
- 15, fkey, fkey_len);
+ 15, fkey ? fkey->data : NULL,
+ fkey ? fkey->len : 0);
/* Send command reply */
silc_server_packet_send(server, sock, SILC_PACKET_COMMAND_REPLY, 0,
SILC_NOTIFY_TYPE_CUMODE_CHANGE, 4,
clidp->data, clidp->len,
mode, 4, clidp->data, clidp->len,
- fkey, fkey_len);
+ fkey ? fkey->data : NULL,
+ fkey ? fkey->len : 0);
}
}
silc_buffer_free(keyp);
silc_buffer_free(user_list);
silc_buffer_free(mode_list);
- silc_free(fkey);
+ silc_buffer_free(fkey);
+ silc_buffer_free(invite_list);
+ silc_buffer_free(ban_list);
out:
silc_free(passphrase);
SilcUInt16 ident = silc_command_get_ident(cmd->payload);
bool set_mask = FALSE;
SilcPublicKey founder_key = NULL;
- unsigned char *fkey = NULL;
- SilcUInt32 fkey_len = 0;
+ SilcBuffer fkey = NULL;
if (!client) {
silc_server_command_free(cmd);
return;
}
- SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_CMODE, cmd, 1, 7);
+ SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_CMODE, cmd, 1, 8);
/* 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 */
- 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, 0);
- goto out;
- }
-
- /* Verify the payload before setting the mode */
- if (!silc_auth_verify_data(tmp, tmp_len, SILC_AUTH_PUBLIC_KEY,
- idata->public_key, 0, server->sha1hash,
- client->id, SILC_ID_CLIENT)) {
+ /* Check if the founder public key was received */
+ founder_key = idata->public_key;
+ tmp = silc_argument_get_arg_type(cmd->args, 8, &tmp_len);
+ if (tmp) {
+ if (!silc_pkcs_public_key_payload_decode(tmp, tmp_len, &founder_key)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
SILC_STATUS_ERR_AUTH_FAILED,
0);
goto out;
}
+ }
- /* Save the public key */
- channel->founder_key = silc_pkcs_public_key_copy(idata->public_key);
- if (!channel->founder_key) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
- SILC_STATUS_ERR_AUTH_FAILED,
- 0);
- goto out;
- }
+ /* Set the founder authentication */
+ 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, 0);
+ goto out;
+ }
- founder_key = channel->founder_key;
- fkey = silc_pkcs_public_key_encode(founder_key, &fkey_len);
- if (!fkey) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
- SILC_STATUS_ERR_AUTH_FAILED,
- 0);
- silc_pkcs_public_key_free(channel->founder_key);
- channel->founder_key = NULL;
- goto out;
- }
+ /* Verify the payload before setting the mode */
+ if (!silc_auth_verify_data(tmp, tmp_len, SILC_AUTH_PUBLIC_KEY,
+ founder_key, 0, server->sha1hash,
+ client->id, SILC_ID_CLIENT)) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
+ SILC_STATUS_ERR_AUTH_FAILED,
+ 0);
+ goto out;
+ }
+
+ /* Save the public key */
+ if (channel->founder_key)
+ silc_pkcs_public_key_free(channel->founder_key);
+ if (silc_argument_get_arg_type(cmd->args, 8, NULL))
+ channel->founder_key = founder_key;
+ else
+ channel->founder_key = silc_pkcs_public_key_copy(founder_key);
+ if (!channel->founder_key) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
+ SILC_STATUS_ERR_AUTH_FAILED,
+ 0);
+ goto out;
+ }
+
+ fkey = silc_pkcs_public_key_payload_encode(channel->founder_key);
+ if (!fkey) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
+ SILC_STATUS_ERR_AUTH_FAILED,
+ 0);
+ silc_pkcs_public_key_free(channel->founder_key);
+ channel->founder_key = NULL;
+ goto out;
}
}
} else {
hmac, hmac ? strlen(hmac) : 0,
passphrase, passphrase ?
strlen(passphrase) : 0,
- fkey, fkey_len);
+ fkey ? fkey->data : NULL,
+ fkey ? fkey->len : 0);
/* Set CMODE notify type to network */
silc_server_send_notify_cmode(server, SILC_PRIMARY_ROUTE(server),
/* Send command reply to sender */
packet = silc_command_reply_payload_encode_va(SILC_COMMAND_CMODE,
- SILC_STATUS_OK, 0, ident, 2,
+ SILC_STATUS_OK, 0, ident, 3,
2, tmp_id, tmp_len2,
- 3, tmp_mask, 4);
+ 3, tmp_mask, 4,
+ 4, fkey ? fkey->data : NULL,
+ fkey ? fkey->len : 0);
silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
packet->data, packet->len, FALSE);
out:
channel->mode = old_mask;
- silc_free(fkey);
+ silc_buffer_free(fkey);
silc_free(channel_id);
silc_server_command_free(cmd);
}
int notify = FALSE;
SilcUInt16 ident = silc_command_get_ident(cmd->payload);
SilcPublicKey founder_key = NULL;
- unsigned char *fkey = NULL;
- SilcUInt32 fkey_len = 0;
+ SilcBuffer fkey = NULL;
if (!client)
goto out;
notify = TRUE;
founder_key = channel->founder_key;
- fkey = silc_pkcs_public_key_encode(founder_key, &fkey_len);
+ fkey = silc_pkcs_public_key_payload_encode(founder_key);
if (!fkey) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
SILC_STATUS_ERR_AUTH_FAILED, 0);
idp->data, idp->len,
tmp_mask, 4,
tmp_id, tmp_len,
- fkey, fkey_len);
+ fkey ? fkey->data : NULL,
+ fkey ? fkey->len : 0);
/* Set CUMODE notify type to network */
silc_server_send_notify_cumode(server, SILC_PRIMARY_ROUTE(server),
out:
silc_free(channel_id);
silc_free(client_id);
- silc_free(fkey);
+ silc_buffer_free(fkey);
silc_server_command_free(cmd);
}
if (server->config->detach_disabled) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_DETACH,
- SILC_STATUS_ERR_UNKNOWN_COMMAND, 0);
+ SILC_STATUS_ERR_OPERATION_ALLOWED,
+ 0);
goto out;
}
SilcServerCommandContext cmd = (SilcServerCommandContext)context;
SilcServer server = cmd->server;
SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
- SilcBuffer packet;
+ SilcBuffer packet, list, tmp2;
SilcChannelEntry channel;
SilcChannelClientEntry chl;
SilcChannelID *channel_id = NULL;
- unsigned char *id, *add, *del;
- SilcUInt32 id_len, tmp_len;
- SilcUInt16 ident = silc_command_get_ident(cmd->payload);
+ unsigned char *id, *tmp;
+ SilcUInt32 id_len, len;
+ SilcArgumentPayload args;
+ SilcHashTableList htl;
+ SilcUInt32 type;
+ SilcUInt16 argc = 0, ident = silc_command_get_ident(cmd->payload);
if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
goto out;
goto out;
}
- /* Get the new ban and add it to the ban list */
- add = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
- if (add) {
- if (!channel->ban_list)
- channel->ban_list = silc_calloc(tmp_len + 2, sizeof(*channel->ban_list));
- else
- channel->ban_list = silc_realloc(channel->ban_list,
- sizeof(*channel->ban_list) *
- (tmp_len +
- strlen(channel->ban_list) + 2));
- if (add[tmp_len - 1] == ',')
- add[tmp_len - 1] = '\0';
-
- strncat(channel->ban_list, add, tmp_len);
- strncat(channel->ban_list, ",", 1);
- }
-
- /* Get the ban to be removed and remove it from the list */
- del = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
- if (del && channel->ban_list) {
- char *start, *end, *n;
+ /* Get the ban information */
+ tmp = silc_argument_get_arg_type(cmd->args, 3, &len);
+ if (tmp) {
+ /* Parse the arguments to see they are constructed correctly */
+ SILC_GET16_MSB(argc, tmp);
+ args = silc_argument_payload_parse(tmp + 2, len - 2, argc);
+ if (!args) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
+ 0);
+ goto out;
+ }
- if (!strncmp(channel->ban_list, del, strlen(channel->ban_list) - 1)) {
- silc_free(channel->ban_list);
- channel->ban_list = NULL;
- } else {
- start = strstr(channel->ban_list, del);
- if (start && strlen(start) >= tmp_len) {
- end = start + tmp_len;
- n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
- strncat(n, channel->ban_list, start - channel->ban_list);
- strncat(n, end + 1, ((channel->ban_list + strlen(channel->ban_list)) -
- end) - 1);
- silc_free(channel->ban_list);
- channel->ban_list = n;
+ /* Get the type of action */
+ tmp = silc_argument_get_arg_type(cmd->args, 3, &len);
+ if (tmp && len == 1) {
+ if (tmp[0] == 0x00) {
+ /* Allocate hash table for ban list if it doesn't exist yet */
+ if (!channel->ban_list)
+ channel->ban_list = silc_hash_table_alloc(0, silc_hash_ptr,
+ NULL, NULL, NULL,
+ NULL, NULL, TRUE);
+
+ /* Check for resource limit */
+ if (silc_hash_table_count(channel->ban_list) > 64) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
+ SILC_STATUS_ERR_RESOURCE_LIMIT,
+ 0);
+ goto out;
+ }
}
+
+ /* Now add or delete the information. */
+ silc_server_inviteban_process(server, channel->ban_list,
+ (SilcUInt8)tmp[0], args);
}
+ silc_argument_payload_free(args);
+ }
+
+ /* Encode ban list */
+ list = NULL;
+ if (channel->ban_list) {
+ list = silc_buffer_alloc_size(2);
+ silc_buffer_format(list,
+ SILC_STR_UI_SHORT(silc_hash_table_count(
+ channel->ban_list)),
+ SILC_STR_END);
+ silc_hash_table_list(channel->ban_list, &htl);
+ while (silc_hash_table_get(&htl, (void **)&type, (void **)&tmp2)) {
+ if (type == 1)
+ list = silc_argument_payload_encode_one(list, (char *)tmp2,
+ strlen((char *)tmp2), type);
+ else
+ list = silc_argument_payload_encode_one(list, tmp2->data, tmp2->len,
+ type);
+ }
+ silc_hash_table_list_reset(&htl);
}
/* Send the BAN notify type to our primary router. */
- if (add || del)
+ if (list)
silc_server_send_notify_ban(server, SILC_PRIMARY_ROUTE(server),
- SILC_BROADCAST(server), channel, add, del);
+ SILC_BROADCAST(server), channel,
+ silc_argument_get_arg_type(cmd->args, 2, NULL),
+ list);
/* Send the reply back to the client */
packet =
silc_command_reply_payload_encode_va(SILC_COMMAND_BAN,
SILC_STATUS_OK, 0, ident, 2,
2, id, id_len,
- 3, channel->ban_list,
- channel->ban_list ?
- strlen(channel->ban_list) -1 : 0);
+ 3, list ? list->data : NULL,
+ list ? list->len : 0);
silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
packet->data, packet->len, FALSE);
silc_buffer_free(packet);
+ silc_buffer_free(list);
out:
silc_free(channel_id);
id = silc_id_payload_parse_id(channel_id, channel_id_len, NULL);
if (!id) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_USERS,
- SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
+ SILC_STATUS_ERR_BAD_CHANNEL_ID, 0);
goto out;
}
}
SilcServerID *server_id = NULL;
SilcIDPayload idp = NULL;
SilcUInt16 ident = silc_command_get_ident(cmd->payload);
- unsigned char *tmp, *pkdata;
- SilcUInt32 tmp_len, pklen;
+ unsigned char *tmp;
+ SilcUInt32 tmp_len;
SilcBuffer pk = NULL;
SilcIdType id_type;
SilcPublicKey public_key;
send it back. If they key does not exist then do not send it,
send just OK reply */
public_key = client->data.public_key;
- if (!public_key) {
- pkdata = NULL;
- pklen = 0;
- } else {
- tmp = silc_pkcs_public_key_encode(public_key, &tmp_len);
- pk = silc_buffer_alloc(4 + tmp_len);
- silc_buffer_pull_tail(pk, SILC_BUFFER_END(pk));
- silc_buffer_format(pk,
- SILC_STR_UI_SHORT(tmp_len),
- SILC_STR_UI_SHORT(SILC_SKE_PK_TYPE_SILC),
- SILC_STR_UI_XNSTRING(tmp, tmp_len),
- SILC_STR_END);
- silc_free(tmp);
- pkdata = pk->data;
- pklen = pk->len;
- }
+ if (public_key)
+ pk = silc_pkcs_public_key_payload_encode(public_key);
} else if (id_type == SILC_ID_SERVER) {
server_id = silc_id_payload_get_id(idp);
public_key = (!server_entry->data.public_key ?
(server_entry == server->id_entry ? server->public_key :
NULL) : server_entry->data.public_key);
- if (!public_key) {
- pkdata = NULL;
- pklen = 0;
- } else {
- tmp = silc_pkcs_public_key_encode(public_key, &tmp_len);
- pk = silc_buffer_alloc(4 + tmp_len);
- silc_buffer_pull_tail(pk, SILC_BUFFER_END(pk));
- silc_buffer_format(pk,
- SILC_STR_UI_SHORT(tmp_len),
- SILC_STR_UI_SHORT(SILC_SKE_PK_TYPE_SILC),
- SILC_STR_UI_XNSTRING(tmp, tmp_len),
- SILC_STR_END);
- silc_free(tmp);
- pkdata = pk->data;
- pklen = pk->len;
- }
+ if (public_key)
+ pk = silc_pkcs_public_key_payload_encode(public_key);
} else {
goto out;
}
tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
packet = silc_command_reply_payload_encode_va(SILC_COMMAND_GETKEY,
- SILC_STATUS_OK, 0, ident,
- pkdata ? 2 : 1,
+ SILC_STATUS_OK, 0, ident, 2,
2, tmp, tmp_len,
- 3, pkdata, pklen);
+ 3, pk ? pk->data : NULL,
+ pk ? pk->len : 0);
silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
packet->data, packet->len, FALSE);
silc_buffer_free(packet);
- if (pk)
- silc_buffer_free(pk);
-
out:
if (idp)
silc_id_payload_free(idp);
+ silc_buffer_free(pk);
silc_free(client_id);
silc_free(server_id);
silc_server_command_free(cmd);