static void
silc_server_command_send_status_reply(SilcServerCommandContext cmd,
SilcCommand command,
- SilcStatus status);
+ SilcStatus status,
+ SilcStatus error);
static void
silc_server_command_send_status_data(SilcServerCommandContext cmd,
SilcCommand command,
SilcStatus status,
+ SilcStatus error,
SilcUInt32 arg_type,
const unsigned char *arg,
SilcUInt32 arg_len);
It also checks that the requested command includes correct amount
of arguments. */
-#define SILC_SERVER_COMMAND_CHECK(command, context, min, max) \
-do { \
- SilcUInt32 _argc; \
- \
- SILC_LOG_DEBUG(("Start")); \
- \
- if (silc_server_command_pending_error_check(cmd, context2, command)) { \
- silc_server_command_free(cmd); \
- return; \
- } \
- \
- _argc = silc_argument_get_arg_num(cmd->args); \
- if (_argc < min) { \
- silc_server_command_send_status_reply(cmd, command, \
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS); \
- silc_server_command_free(cmd); \
- return; \
- } \
- if (_argc > max) { \
- silc_server_command_send_status_reply(cmd, command, \
- SILC_STATUS_ERR_TOO_MANY_PARAMS); \
- silc_server_command_free(cmd); \
- return; \
- } \
+#define SILC_SERVER_COMMAND_CHECK(command, context, min, max) \
+do { \
+ SilcUInt32 _argc; \
+ \
+ SILC_LOG_DEBUG(("Start")); \
+ \
+ if (silc_server_command_pending_error_check(cmd, context2, command)) { \
+ silc_server_command_free(cmd); \
+ return; \
+ } \
+ \
+ _argc = silc_argument_get_arg_num(cmd->args); \
+ if (_argc < min) { \
+ silc_server_command_send_status_reply(cmd, command, \
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, \
+ 0); \
+ silc_server_command_free(cmd); \
+ return; \
+ } \
+ if (_argc > max) { \
+ silc_server_command_send_status_reply(cmd, command, \
+ SILC_STATUS_ERR_TOO_MANY_PARAMS, \
+ 0); \
+ silc_server_command_free(cmd); \
+ return; \
+ } \
} while(0)
/* Returns TRUE if the connection is registered. Unregistered connections
return TRUE;
silc_server_command_send_status_reply(cmd, command,
- SILC_STATUS_ERR_NOT_REGISTERED);
+ SILC_STATUS_ERR_NOT_REGISTERED, 0);
return FALSE;
}
SilcServerCommand *cmd;
SilcCommand command;
+ SILC_LOG_DEBUG(("Start"));
+
/* Allocate command context. This must be free'd by the
command routine receiving it. */
ctx = silc_server_command_alloc();
packet->buffer->len);
if (!ctx->payload) {
SILC_LOG_ERROR(("Bad command payload, packet dropped"));
- silc_buffer_free(packet->buffer);
silc_packet_context_free(packet);
silc_socket_free(ctx->sock);
silc_free(ctx);
if (!cmd || !cmd->cb) {
silc_server_command_send_status_reply(ctx, command,
- SILC_STATUS_ERR_UNKNOWN_COMMAND);
+ SILC_STATUS_ERR_UNKNOWN_COMMAND, 0);
silc_server_command_free(ctx);
return;
}
client->fast_command++;
fast = FALSE;
} else {
- client->fast_command = ((client->fast_command - 1) <= 0 ? 0 :
- client->fast_command--);
+ if (client->fast_command - 2 <= 0)
+ client->fast_command = 0;
+ else
+ client->fast_command -= 2;
fast = TRUE;
}
if (!fast && ((cmd->flags & SILC_CF_LAG_STRICT) ||
(client->fast_command > 5 && cmd->flags & SILC_CF_LAG)))
silc_schedule_task_add(server->schedule, sock->sock,
- silc_server_command_process_timeout,
- (void *)timeout,
- 2 - (time(NULL) - client->last_command), 0,
- SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
+ silc_server_command_process_timeout, timeout,
+ (client->fast_command < 3 ? 0 :
+ 2 - (time(NULL) - client->last_command)),
+ (client->fast_command < 3 ? 200000 : 0),
+ SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
else
silc_schedule_task_add(server->schedule, sock->sock,
- silc_server_command_process_timeout,
- (void *)timeout, 0, 1,
- SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
+ silc_server_command_process_timeout, timeout,
+ 0, 1, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
return;
}
static void
silc_server_command_send_status_reply(SilcServerCommandContext cmd,
SilcCommand command,
- SilcStatus status)
+ SilcStatus status,
+ SilcStatus error)
{
SilcBuffer buffer;
SILC_LOG_DEBUG(("Sending command status %d", status));
buffer =
- silc_command_reply_payload_encode_va(command, status, 0,
+ silc_command_reply_payload_encode_va(command, status, error,
silc_command_get_ident(cmd->payload),
0);
silc_server_packet_send(cmd->server, cmd->sock,
silc_server_command_send_status_data(SilcServerCommandContext cmd,
SilcCommand command,
SilcStatus status,
+ SilcStatus error,
SilcUInt32 arg_type,
const unsigned char *arg,
SilcUInt32 arg_len)
******************************************************************************/
+typedef struct {
+ void *id;
+ SilcIdType id_type;
+ SilcUInt32 index;
+ SilcStatus error;
+} *ResolveError;
+
+#define ADD_ERROR(errptr, errptr_count, _id, _id_type, _index, _status) \
+do { \
+ errptr = silc_realloc(errptr, sizeof(*errptr) * (errptr_count + 1)); \
+ if (!errptr) \
+ return FALSE; \
+ errptr[errptr_count].id = _id; \
+ errptr[errptr_count].id_type = _id_type; \
+ errptr[errptr_count].index = _index; \
+ errptr[errptr_count].error = _status; \
+ errptr_count++; \
+} while(0)
+
static int
silc_server_command_whois_parse(SilcServerCommandContext cmd,
SilcClientID ***client_id,
char **nickname,
char **server_name,
int *count,
- SilcCommand command)
+ ResolveError *error_client,
+ SilcUInt32 *error_client_count)
{
unsigned char *tmp;
SilcUInt32 len;
SilcUInt32 argc = silc_argument_get_arg_num(cmd->args);
+ void *id;
int i, k;
/* If client ID is in the command it must be used instead of nickname */
- tmp = silc_argument_get_arg_type(cmd->args, 3, &len);
+ tmp = silc_argument_get_arg_type(cmd->args, 4, &len);
if (!tmp) {
/* No ID, get the nickname@server string and parse it. */
tmp = silc_argument_get_arg_type(cmd->args, 1, NULL);
if (tmp) {
silc_parse_userfqdn(tmp, nickname, server_name);
} else {
- silc_server_command_send_status_reply(cmd, command,
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_WHOIS,
+ SILC_STATUS_ERR_BAD_NICKNAME, 0);
return FALSE;
}
} else {
- /* Command includes ID, we must use that. Also check whether the command
- has more than one ID set - take them all. */
-
- *client_id = silc_calloc(1, sizeof(**client_id));
- (*client_id)[0] = silc_id_payload_parse_id(tmp, len, NULL);
- if ((*client_id)[0] == NULL) {
- silc_free(*client_id);
- silc_server_command_send_status_reply(cmd, command,
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
- return FALSE;
- }
- *client_id_count = 1;
-
- /* Take all ID's from the command packet */
- if (argc > 1) {
- for (k = 1, i = 1; i < argc; i++) {
- tmp = silc_argument_get_arg_type(cmd->args, i + 3, &len);
- if (tmp) {
- *client_id = silc_realloc(*client_id, sizeof(**client_id) *
- (*client_id_count + 1));
- (*client_id)[k] = silc_id_payload_parse_id(tmp, len, NULL);
- if ((*client_id)[k] == NULL) {
- /* Cleanup all and fail */
- for (i = 0; i < *client_id_count; i++)
- silc_free((*client_id)[i]);
- silc_free(*client_id);
- silc_server_command_send_status_reply(
- cmd, command,
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
- return FALSE;
- }
- (*client_id_count)++;
- k++;
- }
+ /* Command includes ID, we must use that. Take all ID's from the
+ command packet */
+ for (k = 0, i = 0; i < argc; i++) {
+ tmp = silc_argument_get_arg_type(cmd->args, i + 4, &len);
+ if (!tmp)
+ continue;
+ id = silc_id_payload_parse_id(tmp, len, NULL);
+ if (id) {
+ *client_id = silc_realloc(*client_id, sizeof(**client_id) *
+ (*client_id_count + 1));
+ (*client_id)[k] = id;
+ (*client_id_count)++;
+ k++;
+ } else {
+ ADD_ERROR((*error_client), (*error_client_count), NULL, 0, i + 4,
+ SILC_STATUS_ERR_BAD_CLIENT_ID);
}
}
}
/* Get the max count of reply messages allowed */
tmp = silc_argument_get_arg_type(cmd->args, 2, NULL);
- if (tmp) {
+ if (tmp)
SILC_GET32_MSB(*count, tmp);
- } else {
+ else
*count = 0;
- }
return TRUE;
}
sizeof(**r->res_argv));
memcpy(r->res_argv[r->res_argc], idp->data, idp->len);
r->res_argv_lens[r->res_argc] = idp->len;
- r->res_argv_types[r->res_argc] = r->res_argc + 3;
+ r->res_argv_types[r->res_argc] = r->res_argc + 4;
r->res_argc++;
silc_buffer_free(idp);
static void
silc_server_command_whois_send_reply(SilcServerCommandContext cmd,
SilcClientEntry *clients,
- SilcUInt32 clients_count,
- int count,
- const char *nickname,
+ SilcUInt32 clients_count,
+ ResolveError errors,
+ SilcUInt32 errors_count,
+ int count, const char *nickname,
SilcClientID **client_ids)
{
SilcServer server = cmd->server;
char *tmp;
- int i, k, len, valid_count;
+ int i, k, valid_count = clients_count;
+ SilcUInt32 len;
SilcBuffer packet, idp, channels, umode_list = NULL;
SilcClientEntry entry;
SilcStatus status;
unsigned char *fingerprint;
SilcSocketConnection hsock;
- /* Process only valid clients and ignore those that are not registered. */
- valid_count = 0;
- for (i = 0; i < clients_count; i++) {
- if (clients[i]->data.status & SILC_IDLIST_STATUS_REGISTERED)
- valid_count++;
- else
- clients[i] = NULL;
- }
+ if (nickname) {
+ /* Process only valid clients and ignore those that are not registered.
+ This is checked with nickname only because when resolved client IDs
+ we check that they are registered earlier. */
+ valid_count = 0;
+ for (i = 0; i < clients_count; i++)
+ if (clients[i]->data.status & SILC_IDLIST_STATUS_REGISTERED)
+ valid_count++;
+ else
+ clients[i] = NULL;
- if (!valid_count) {
- /* No valid clients found, send error reply */
- if (nickname) {
+ if (!valid_count) {
silc_server_command_send_status_data(cmd, SILC_COMMAND_WHOIS,
- SILC_STATUS_ERR_NO_SUCH_NICK,
+ SILC_STATUS_ERR_NO_SUCH_NICK, 0,
3, nickname, strlen(nickname));
- } else if (client_ids && client_ids[0]) {
- SilcBuffer idp = silc_id_payload_encode(client_ids[0], SILC_ID_CLIENT);
- silc_server_command_send_status_data(cmd, SILC_COMMAND_WHOIS,
- SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
- 2, idp->data, idp->len);
- silc_buffer_free(idp);
+ return;
}
- return;
}
/* Start processing found clients. */
+ status = SILC_STATUS_OK;
if (valid_count > 1)
status = SILC_STATUS_LIST_START;
- else
- status = SILC_STATUS_OK;
for (i = 0, k = 0; i < clients_count; i++) {
entry = clients[i];
if (k >= 1)
status = SILC_STATUS_LIST_ITEM;
- if (valid_count > 1 && k == valid_count - 1)
+ if (valid_count > 1 && k == valid_count - 1 && !errors_count)
status = SILC_STATUS_LIST_END;
if (count && k - 1 == count)
status = SILC_STATUS_LIST_END;
fingerprint = NULL;
SILC_PUT32_MSB(entry->mode, mode);
-
- if (entry->connection) {
+ if (entry->connection)
SILC_PUT32_MSB((time(NULL) - entry->data.last_receive), idle);
- }
packet =
silc_command_reply_payload_encode_va(SILC_COMMAND_WHOIS,
umode_list = NULL;
}
+ if (status == SILC_STATUS_LIST_END)
+ break;
+ k++;
+ }
+
+ /* Send error replies */
+ if (status == SILC_STATUS_OK && errors_count > 1)
+ status = SILC_STATUS_LIST_START;
+
+ idp = NULL;
+ for (i = 0, k = 0; i < errors_count; i++) {
+ if (errors[i].id) {
+ idp = silc_id_payload_encode(errors[i].id, SILC_ID_CLIENT);
+ tmp = idp->data;
+ len = idp->len;
+ } else {
+ tmp = silc_argument_get_arg_type(cmd->args, errors[i].index, &len);
+ }
+
+ if (k >= 1)
+ status = SILC_STATUS_LIST_ITEM;
+ if (errors_count > 1 && k == errors_count - 1)
+ status = SILC_STATUS_LIST_END;
+ if (count && k - 1 == count)
+ status = SILC_STATUS_LIST_END;
+
+ /* Send error */
+ silc_server_command_send_status_data(cmd, SILC_COMMAND_WHOIS,
+ (status == SILC_STATUS_OK ?
+ errors[i].error : status),
+ (status == SILC_STATUS_OK ?
+ 0 : errors[i].error),
+ 2, tmp, len);
+ silc_buffer_free(idp);
+ idp = NULL;
+
+ if (status == SILC_STATUS_LIST_END)
+ break;
k++;
}
}
int count = 0;
SilcClientEntry *clients = NULL, entry;
SilcClientID **client_id = NULL;
- SilcUInt32 client_id_count = 0, clients_count = 0;
+ SilcUInt32 client_id_count = 0, clients_count = 0, error_client_count = 0;
+ ResolveError error_client = NULL;
int i, ret = 0;
bool check_global = FALSE;
/* Parse the whois request */
if (!silc_server_command_whois_parse(cmd, &client_id, &client_id_count,
&nick, &server_name, &count,
- SILC_COMMAND_WHOIS))
+ &error_client, &error_client_count))
return 0;
/* Send the WHOIS request to the router only if it included nickname.
ret = -1;
goto out;
}
+
+ ADD_ERROR(error_client, error_client_count, client_id[i],
+ SILC_ID_CLIENT, 0, SILC_STATUS_ERR_NO_SUCH_CLIENT_ID);
}
}
- } else {
+ } else if (nick) {
/* Find by nickname */
if (!silc_idlist_get_clients_by_hash(server->local_list,
nick, server->md5hash,
}
}
- if (!clients) {
+ if (!clients && (client_id_count || nick)) {
/* If we are normal server and did not send the request first to router
do it now, since we do not have the information. */
if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT &&
}
/* Such client(s) really does not exist in the SILC network. */
- if (!client_id_count) {
+ if (!client_id_count)
silc_server_command_send_status_data(cmd, SILC_COMMAND_WHOIS,
- SILC_STATUS_ERR_NO_SUCH_NICK,
+ SILC_STATUS_ERR_NO_SUCH_NICK, 0,
3, nick, strlen(nick));
- } else {
- SilcBuffer idp = silc_id_payload_encode(client_id[0], SILC_ID_CLIENT);
- silc_server_command_send_status_data(cmd, SILC_COMMAND_WHOIS,
- SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
- 2, idp->data, idp->len);
- silc_buffer_free(idp);
- }
+ else
+ silc_server_command_whois_send_reply(cmd, NULL, 0,
+ error_client, error_client_count,
+ 0, NULL, NULL);
goto out;
}
/* Send the command reply */
silc_server_command_whois_send_reply(cmd, clients, clients_count,
+ error_client, error_client_count,
count, nick, client_id);
out:
silc_free(client_id);
}
silc_free(clients);
+ silc_free(error_client);
silc_free(nick);
silc_free(server_name);
tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
if (!tmp) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_WHOWAS,
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
+ 0);
return FALSE;
}
/* Get the max count of reply messages allowed */
tmp = silc_argument_get_arg_type(cmd->args, 2, NULL);
- if (tmp) {
+ if (tmp)
SILC_GET32_MSB(*count, tmp);
- } else {
+ else
*count = 0;
- }
return TRUE;
}
if (!valid_count) {
/* No valid entries found at all, just send error */
- unsigned char *tmp;
-
tmp = silc_argument_get_arg_type(cmd->args, 1, NULL);
- if (tmp)
- silc_server_command_send_status_data(cmd, SILC_COMMAND_WHOWAS,
- SILC_STATUS_ERR_NO_SUCH_NICK,
- 3, tmp, strlen(tmp));
+ silc_server_command_send_status_data(cmd, SILC_COMMAND_WHOWAS,
+ SILC_STATUS_ERR_NO_SUCH_NICK, 0,
+ 3, tmp, tmp ? strlen(tmp) : 0);
return;
}
status = SILC_STATUS_LIST_END;
if (count && k - 1 == count)
status = SILC_STATUS_LIST_END;
- if (count && k - 1 > count)
- break;
/* Send WHOWAS reply */
idp = silc_id_payload_encode(entry->id, SILC_ID_CLIENT);
silc_buffer_free(packet);
silc_buffer_free(idp);
+ if (status == SILC_STATUS_LIST_END)
+ break;
k++;
}
}
if (!clients) {
/* Such a client really does not exist in the SILC network. */
silc_server_command_send_status_data(cmd, SILC_COMMAND_WHOWAS,
- SILC_STATUS_ERR_NO_SUCH_NICK,
+ SILC_STATUS_ERR_NO_SUCH_NICK, 0,
3, nick, strlen(nick));
goto out;
}
SilcUInt32 *servers_count,
SilcChannelEntry **channels,
SilcUInt32 *channels_count,
- SilcUInt32 *count)
+ SilcUInt32 *count,
+ ResolveError *error_id,
+ SilcUInt32 *error_id_count)
{
SilcServer server = cmd->server;
unsigned char *tmp;
bool check_global = FALSE;
void *entry;
int i;
- bool error = FALSE;
if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT)
check_global = TRUE;
if (!(*clients)) {
/* the nickname does not exist, send error reply */
silc_server_command_send_status_data(cmd, SILC_COMMAND_IDENTIFY,
- SILC_STATUS_ERR_NO_SUCH_NICK,
+ SILC_STATUS_ERR_NO_SUCH_NICK, 0,
3, tmp, strlen(tmp));
return 0;
}
/* the server does not exist, send error reply */
silc_server_command_send_status_data(cmd, SILC_COMMAND_IDENTIFY,
SILC_STATUS_ERR_NO_SUCH_SERVER,
- 3, tmp, strlen(tmp));
+ 0, 3, tmp, strlen(tmp));
return 0;
}
}
/* The channel does not exist, send error reply */
silc_server_command_send_status_data(cmd, SILC_COMMAND_IDENTIFY,
SILC_STATUS_ERR_NO_SUCH_CHANNEL,
- 3, tmp, strlen(tmp));
+ 0, 3, tmp, strlen(tmp));
return 0;
}
}
if (!(*clients) && !(*servers) && !(*channels)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_IDENTIFY,
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
+ 0);
return 0;
}
} else {
continue;
idp = silc_id_payload_parse(tmp, len);
- if (!idp) {
- silc_free(*clients);
- silc_free(*servers);
- silc_free(*channels);
- silc_server_command_send_status_reply(
- cmd, SILC_COMMAND_IDENTIFY,
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
- return 0;
- }
+ if (!idp)
+ ADD_ERROR((*error_id), (*error_id_count), NULL, 0, i + 5,
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
id = silc_id_payload_get_id(idp);
-
switch (silc_id_payload_get_type(idp)) {
case SILC_ID_CLIENT:
- entry = (void *)silc_idlist_find_client_by_id(server->local_list,
- id, TRUE, NULL);
+ entry = silc_idlist_find_client_by_id(server->local_list,
+ id, TRUE, NULL);
if (!entry && check_global)
- entry = (void *)silc_idlist_find_client_by_id(server->global_list,
- id, TRUE, NULL);
+ entry = silc_idlist_find_client_by_id(server->global_list,
+ id, TRUE, NULL);
if (entry) {
*clients = silc_realloc(*clients, sizeof(**clients) *
(*clients_count + 1));
silc_free(*clients);
silc_free(*servers);
silc_free(*channels);
+ silc_free(*error_id);
return -1;
- } else {
- silc_server_command_send_status_data(
- cmd, SILC_COMMAND_IDENTIFY,
- SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
- 2, tmp, len);
- error = TRUE;
}
+
+ ADD_ERROR((*error_id), (*error_id_count), NULL, 0, i + 5,
+ SILC_STATUS_ERR_NO_SUCH_CLIENT_ID);
}
break;
case SILC_ID_SERVER:
- entry = (void *)silc_idlist_find_server_by_id(server->local_list,
- id, TRUE, NULL);
+ entry = silc_idlist_find_server_by_id(server->local_list,
+ id, TRUE, NULL);
if (!entry && check_global)
- entry = (void *)silc_idlist_find_server_by_id(server->global_list,
- id, TRUE, NULL);
+ entry = silc_idlist_find_server_by_id(server->global_list,
+ id, TRUE, NULL);
if (entry) {
*servers = silc_realloc(*servers, sizeof(**servers) *
(*servers_count + 1));
silc_free(*clients);
silc_free(*servers);
silc_free(*channels);
+ silc_free(*error_id);
return -1;
- } else {
- silc_server_command_send_status_data(
- cmd, SILC_COMMAND_IDENTIFY,
- SILC_STATUS_ERR_NO_SUCH_SERVER_ID,
- 2, tmp, len);
- error = TRUE;
}
+
+ ADD_ERROR((*error_id), (*error_id_count), NULL, 0, i + 5,
+ SILC_STATUS_ERR_NO_SUCH_SERVER_ID);
}
break;
case SILC_ID_CHANNEL:
- entry = (void *)silc_idlist_find_channel_by_id(server->local_list,
- id, NULL);
+ entry = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
if (!entry && check_global)
- entry = (void *)silc_idlist_find_channel_by_id(server->global_list,
- id, NULL);
+ entry = silc_idlist_find_channel_by_id(server->global_list, id,
+ NULL);
if (entry) {
*channels = silc_realloc(*channels, sizeof(**channels) *
(*channels_count + 1));
silc_free(*clients);
silc_free(*servers);
silc_free(*channels);
+ silc_free(*error_id);
return -1;
- } else {
- silc_server_command_send_status_data(
- cmd, SILC_COMMAND_IDENTIFY,
- SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID,
- 2, tmp, len);
- error = TRUE;
}
+
+ ADD_ERROR((*error_id), (*error_id_count), NULL, 0, i + 5,
+ SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID);
}
break;
}
}
}
- if (error) {
- silc_free(*clients);
- silc_free(*servers);
- silc_free(*channels);
- return FALSE;
- }
-
/* Get the max count of reply messages allowed */
tmp = silc_argument_get_arg_type(cmd->args, 4, NULL);
- if (tmp) {
+ if (tmp)
SILC_GET32_MSB(*count, tmp);
- } else {
+ else
*count = 0;
- }
return 1;
}
sizeof(**r->res_argv));
memcpy(r->res_argv[r->res_argc], idp->data, idp->len);
r->res_argv_lens[r->res_argc] = idp->len;
- r->res_argv_types[r->res_argc] = r->res_argc + 3;
+ r->res_argv_types[r->res_argc] = r->res_argc + 4;
r->res_argc++;
silc_buffer_free(idp);
SilcUInt32 servers_count,
SilcChannelEntry *channels,
SilcUInt32 channels_count,
+ ResolveError errors,
+ SilcUInt32 errors_count,
int count)
{
SilcServer server = cmd->server;
- int i, k, len, valid_count;
+ int i, k, valid_count;
+ SilcUInt32 len;
SilcBuffer packet, idp;
SilcStatus status;
SilcUInt16 ident = silc_command_get_ident(cmd->payload);
char nh[256], uh[256];
SilcSocketConnection hsock;
+ unsigned char *tmp;
status = SILC_STATUS_OK;
if (clients) {
SilcClientEntry entry;
+ valid_count = clients_count;
+
+ if (silc_argument_get_arg_type(cmd->args, 1, NULL)) {
+ /* Process only valid clients and ignore those that are not registered.
+ This is checked with nickname only because when resolved client IDs
+ we check that they are registered earlier. */
+ valid_count = 0;
+ for (i = 0; i < clients_count; i++) {
+ if (clients[i]->data.status & SILC_IDLIST_STATUS_REGISTERED)
+ valid_count++;
+ else
+ clients[i] = NULL;
+ }
- /* Process only valid entries. */
- valid_count = 0;
- for (i = 0; i < clients_count; i++) {
- if (clients[i]->data.status & SILC_IDLIST_STATUS_REGISTERED)
- valid_count++;
- else
- clients[i] = NULL;
- }
-
- if (!valid_count) {
- /* No valid entries found at all, just send error */
- unsigned char *tmp;
-
- tmp = silc_argument_get_arg_type(cmd->args, 1, NULL);
- if (tmp) {
+ if (!valid_count) {
+ /* No valid entries found at all, just send error */
+ tmp = silc_argument_get_arg_type(cmd->args, 1, NULL);
silc_server_command_send_status_data(cmd, SILC_COMMAND_IDENTIFY,
- SILC_STATUS_ERR_NO_SUCH_NICK,
- 3, tmp, strlen(tmp));
- } else {
- tmp = silc_argument_get_arg_type(cmd->args, 5, (SilcUInt32 *)&len);
- silc_server_command_send_status_data(cmd, SILC_COMMAND_IDENTIFY,
- SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
- 2, tmp, len);
+ SILC_STATUS_ERR_NO_SUCH_NICK, 0,
+ 3, tmp, tmp ? strlen(tmp) : 0);
+ return;
}
- return;
}
/* Process all valid client entries and send command replies */
if (k >= 1)
status = SILC_STATUS_LIST_ITEM;
if (valid_count > 1 && k == valid_count - 1
- && !servers_count && !channels_count)
+ && !servers_count && !channels_count && !errors_count)
status = SILC_STATUS_LIST_END;
if (count && k - 1 == count)
status = SILC_STATUS_LIST_END;
- if (count && k - 1 > count)
- break;
/* Send IDENTIFY reply */
silc_buffer_free(packet);
silc_buffer_free(idp);
+ if (status == SILC_STATUS_LIST_END)
+ break;
k++;
}
}
if (k >= 1)
status = SILC_STATUS_LIST_ITEM;
- if (servers_count > 1 && k == servers_count - 1 && !channels_count)
+ if (servers_count > 1 && k == servers_count - 1 && !channels_count &&
+ !errors_count)
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_SERVER);
silc_buffer_free(packet);
silc_buffer_free(idp);
+ if (status == SILC_STATUS_LIST_END)
+ break;
k++;
}
}
if (k >= 1)
status = SILC_STATUS_LIST_ITEM;
- if (channels_count > 1 && k == channels_count - 1)
+ if (channels_count > 1 && k == channels_count - 1 && !errors_count)
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_CHANNEL);
silc_buffer_free(packet);
silc_buffer_free(idp);
+ if (status == SILC_STATUS_LIST_END)
+ break;
+ k++;
+ }
+ }
+
+ /* Send error replies */
+ if (errors) {
+ if (status == SILC_STATUS_OK && errors_count > 1)
+ status = SILC_STATUS_LIST_START;
+
+ idp = NULL;
+ for (i = 0, k = 0; i < errors_count; i++) {
+ if (errors[i].id) {
+ idp = silc_id_payload_encode(errors[i].id, SILC_ID_CLIENT);
+ tmp = idp->data;
+ len = idp->len;
+ } else {
+ tmp = silc_argument_get_arg_type(cmd->args, errors[i].index, &len);
+ }
+
+ if (k >= 1)
+ status = SILC_STATUS_LIST_ITEM;
+ if (errors_count > 1 && k == errors_count - 1)
+ status = SILC_STATUS_LIST_END;
+ if (count && k - 1 == count)
+ status = SILC_STATUS_LIST_END;
+
+ /* Send error */
+ silc_server_command_send_status_data(cmd, SILC_COMMAND_IDENTIFY,
+ (status == SILC_STATUS_OK ?
+ errors[i].error : status),
+ (status == SILC_STATUS_OK ?
+ 0 : errors[i].error),
+ 2, tmp, len);
+ silc_buffer_free(idp);
+ idp = NULL;
+
+ if (status == SILC_STATUS_LIST_END)
+ break;
k++;
}
}
SilcServerEntry *servers = NULL;
SilcChannelEntry *channels = NULL;
SilcUInt32 clients_count = 0, servers_count = 0, channels_count = 0;
+ SilcUInt32 errors_count = 0;
+ ResolveError errors = NULL;
/* Parse the IDENTIFY request */
ret = silc_server_command_identify_parse(cmd,
&clients, &clients_count,
&servers, &servers_count,
&channels, &channels_count,
- &count);
+ &count, &errors, &errors_count);
if (ret < 1)
return ret;
ret = 0;
/* Check that all mandatory fields are present and request those data
from the server who owns the client if necessary. */
- if (clients && !silc_server_command_identify_check_client(cmd, clients,
- clients_count)) {
+ if (!silc_server_command_identify_check_client(cmd, clients,
+ clients_count)) {
ret = -1;
goto out;
}
clients, clients_count,
servers, servers_count,
channels, channels_count,
+ errors, errors_count,
count);
out:
silc_free(clients);
silc_free(servers);
silc_free(channels);
+ silc_free(errors);
return ret;
}
nick[128] = '\0';
if (silc_server_name_bad_chars(nick, nick_len) == TRUE) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_NICK,
- SILC_STATUS_ERR_BAD_NICKNAME);
+ SILC_STATUS_ERR_BAD_NICKNAME, 0);
goto out;
}
nickfail++;
if (nickfail > 9) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_NICK,
- SILC_STATUS_ERR_BAD_NICKNAME);
+ SILC_STATUS_ERR_BAD_NICKNAME, 0);
goto out;
}
snprintf(&nick[strlen(nick) - 1], 1, "%d", nickfail);
send_reply:
/* Send the new Client ID as reply command back to client */
packet = silc_command_reply_payload_encode_va(SILC_COMMAND_NICK,
- SILC_STATUS_OK, 0, ident, 1,
- 2, nidp->data, nidp->len);
+ SILC_STATUS_OK, 0, ident, 2,
+ 2, nidp->data, nidp->len,
+ 3, nick, strlen(nick));
silc_server_packet_send(cmd->server, cmd->sock, SILC_PACKET_COMMAND_REPLY,
0, packet->data, packet->len, FALSE);
channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
if (!channel_id) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_LIST,
- SILC_STATUS_ERR_NO_CHANNEL_ID);
+ SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
goto out;
}
}
tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
if (!tmp) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_TOPIC,
- SILC_STATUS_ERR_NO_CHANNEL_ID);
+ SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
goto out;
}
channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
if (!channel_id) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_TOPIC,
- SILC_STATUS_ERR_NO_CHANNEL_ID);
+ SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
goto out;
}
channel_id, NULL);
if (!channel) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_TOPIC,
- SILC_STATUS_ERR_NO_SUCH_CHANNEL);
+ SILC_STATUS_ERR_NO_SUCH_CHANNEL,
+ 0);
goto out;
}
}
tmp = silc_argument_get_arg_type(cmd->args, 2, NULL);
if (!tmp) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_TOPIC,
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
+ 0);
goto out;
}
if (strlen(tmp) > 256) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_TOPIC,
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
+ 0);
goto out;
}
/* See whether the client is on channel and has rights to change topic */
if (!silc_server_client_on_channel(client, channel, &chl)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_TOPIC,
- SILC_STATUS_ERR_NOT_ON_CHANNEL);
+ SILC_STATUS_ERR_NOT_ON_CHANNEL,
+ 0);
goto out;
}
!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
!(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_TOPIC,
- SILC_STATUS_ERR_NO_CHANNEL_PRIV);
+ SILC_STATUS_ERR_NO_CHANNEL_PRIV,
+ 0);
goto out;
}
tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
if (!tmp) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
- SILC_STATUS_ERR_NO_CHANNEL_ID);
+ SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
goto out;
}
channel_id = silc_id_payload_parse_id(tmp, len, NULL);
if (!channel_id) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
- SILC_STATUS_ERR_NO_CHANNEL_ID);
+ SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
goto out;
}
channel_id, NULL);
if (!channel) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
- SILC_STATUS_ERR_NO_SUCH_CHANNEL);
+ SILC_STATUS_ERR_NO_SUCH_CHANNEL,
+ 0);
goto out;
}
}
sender = (SilcClientEntry)sock->user_data;
if (!silc_server_client_on_channel(sender, channel, &chl)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
- SILC_STATUS_ERR_NOT_ON_CHANNEL);
+ SILC_STATUS_ERR_NOT_ON_CHANNEL, 0);
goto out;
}
!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
!(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
- SILC_STATUS_ERR_NO_CHANNEL_PRIV);
+ SILC_STATUS_ERR_NO_CHANNEL_PRIV,
+ 0);
goto out;
}
dest_id = silc_id_payload_parse_id(tmp, len, NULL);
if (!dest_id) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
- SILC_STATUS_ERR_NO_CLIENT_ID);
+ SILC_STATUS_ERR_NO_CLIENT_ID, 0);
goto out;
}
if (server->server_type != SILC_SERVER || !resolve) {
silc_server_command_send_status_reply(
cmd, SILC_COMMAND_INVITE,
- SILC_STATUS_ERR_NO_SUCH_CLIENT_ID);
+ SILC_STATUS_ERR_NO_SUCH_CLIENT_ID, 0);
goto out;
}
/* Check whether the requested client is already on the channel. */
if (silc_server_client_on_channel(dest, channel, NULL)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
- SILC_STATUS_ERR_USER_ON_CHANNEL);
+ SILC_STATUS_ERR_USER_ON_CHANNEL,
+ 0);
goto out;
}
&idata, NULL);
if (!dest_sock) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
- SILC_STATUS_ERR_NO_SUCH_CLIENT_ID);
+ SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
+ 0);
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);
+ 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);
+ SILC_STATUS_ERR_NO_ROUTER_PRIV, 0);
goto out;
}
tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
if (!tmp) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
+ 0);
goto out;
}
client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
if (!client_id) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
- SILC_STATUS_ERR_NO_SUCH_CLIENT_ID);
+ SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
+ 0);
goto out;
}
local = FALSE;
if (!remote_client) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
- SILC_STATUS_ERR_NO_SUCH_CLIENT_ID);
+ SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
+ 0);
goto out;
}
}
/* Send reply to the sender */
silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
- SILC_STATUS_OK);
+ SILC_STATUS_OK, 0);
/* Check if anyone is watching this nickname */
if (server->server_type == SILC_ROUTER)
server_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
if (!server_id) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_INFO,
- SILC_STATUS_ERR_NO_SERVER_ID);
+ SILC_STATUS_ERR_NO_SERVER_ID, 0);
goto out;
}
}
server_id, TRUE, NULL);
if (!entry && server->server_type != SILC_SERVER) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_INFO,
- SILC_STATUS_ERR_NO_SUCH_SERVER);
+ SILC_STATUS_ERR_NO_SUCH_SERVER,
+ 0);
goto out;
}
}
if (!entry) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_INFO,
- SILC_STATUS_ERR_NO_SUCH_SERVER);
+ SILC_STATUS_ERR_NO_SUCH_SERVER, 0);
goto out;
}
tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
if (!tmp) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_PING,
- SILC_STATUS_ERR_NO_SERVER_ID);
+ SILC_STATUS_ERR_NO_SERVER_ID, 0);
goto out;
}
id = silc_id_str2id(tmp, len, SILC_ID_SERVER);
if (SILC_ID_SERVER_COMPARE(id, server->id)) {
/* Send our reply */
silc_server_command_send_status_reply(cmd, SILC_COMMAND_PING,
- SILC_STATUS_OK);
+ SILC_STATUS_OK, 0);
} else {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_PING,
- SILC_STATUS_ERR_NO_SUCH_SERVER);
+ SILC_STATUS_ERR_NO_SUCH_SERVER, 0);
goto out;
}
tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
if (!tmp) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_INFO,
- SILC_STATUS_ERR_NO_SERVER_ID);
+ SILC_STATUS_ERR_NO_SERVER_ID, 0);
goto out;
}
server_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
/* 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_STATUS_ERR_NO_SUCH_SERVER);
+ SILC_STATUS_ERR_NO_SUCH_SERVER, 0);
silc_free(server_id);
goto out;
}
char check[512], check2[512];
bool founder = FALSE;
bool resolve;
+ unsigned char *fkey = NULL;
+ SilcUInt32 fkey_len = 0;
SILC_LOG_DEBUG(("Start"));
if (!resolve) {
silc_server_command_send_status_reply(
cmd, SILC_COMMAND_JOIN,
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
goto out;
}
if (channel->founder_key && idata->public_key &&
silc_pkcs_public_key_compare(channel->founder_key,
idata->public_key)) {
- void *auth_data = (channel->founder_method == SILC_AUTH_PASSWORD ?
- (void *)channel->founder_passwd :
- (void *)channel->founder_key);
- SilcUInt32 auth_data_len =
- (channel->founder_method == SILC_AUTH_PASSWORD ?
- channel->founder_passwd_len : 0);
-
/* Check whether the client is to become founder */
- if (silc_auth_verify_data(auth, auth_len, channel->founder_method,
- auth_data, auth_data_len,
- idata->hash, client->id, SILC_ID_CLIENT)) {
+ if (silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
+ channel->founder_key, 0, server->sha1hash,
+ client->id, SILC_ID_CLIENT)) {
umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
founder = TRUE;
}
(!silc_string_match(channel->invite_list, check) &&
!silc_string_match(channel->invite_list, check2))) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
- SILC_STATUS_ERR_NOT_INVITED);
+ SILC_STATUS_ERR_NOT_INVITED, 0);
goto out;
}
}
silc_string_match(channel->ban_list, check2)) {
silc_server_command_send_status_reply(
cmd, SILC_COMMAND_JOIN,
- SILC_STATUS_ERR_BANNED_FROM_CHANNEL);
+ SILC_STATUS_ERR_BANNED_FROM_CHANNEL, 0);
goto out;
}
}
if (silc_hash_table_count(channel->user_list) + 1 >
channel->user_limit) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
- SILC_STATUS_ERR_CHANNEL_IS_FULL);
+ SILC_STATUS_ERR_CHANNEL_IS_FULL,
+ 0);
goto out;
}
}
if (!passphrase || !channel->passphrase ||
memcmp(passphrase, channel->passphrase, strlen(channel->passphrase))) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
- SILC_STATUS_ERR_BAD_PASSWORD);
+ SILC_STATUS_ERR_BAD_PASSWORD, 0);
goto out;
}
}
/* Check whether the client already is on the channel */
if (silc_server_client_on_channel(client, channel, NULL)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
- SILC_STATUS_ERR_USER_ON_CHANNEL);
+ SILC_STATUS_ERR_USER_ON_CHANNEL, 0);
goto out;
}
silc_hash_table_add(channel->user_list, client, chl);
silc_hash_table_add(client->channels, channel, chl);
channel->user_count++;
+ channel->disabled = FALSE;
/* Get users on the channel */
silc_server_get_users_on_channel(server, channel, &user_list, &mode_list,
silc_free(tmp);
}
+ if (channel->founder_key)
+ fkey = silc_pkcs_public_key_encode(channel->founder_key, &fkey_len);
+
reply =
silc_command_reply_payload_encode_va(SILC_COMMAND_JOIN,
- SILC_STATUS_OK, 0, ident, 13,
+ SILC_STATUS_OK, 0, ident, 14,
2, channel->channel_name,
strlen(channel->channel_name),
3, chidp->data, chidp->len,
12, tmp3, 4,
13, user_list->data, user_list->len,
14, mode_list->data,
- mode_list->len);
+ mode_list->len,
+ 15, fkey, fkey_len);
/* Send command reply */
silc_server_packet_send(server, sock, SILC_PACKET_COMMAND_REPLY, 0,
/* Distribute the channel key to all backup routers. */
silc_server_backup_send(server, NULL, SILC_PACKET_CHANNEL_KEY, 0,
keyp->data, keyp->len, FALSE, TRUE);
- }
- /* If client became founder by providing correct founder auth data
- notify the mode change to the channel. */
- if (founder) {
- SILC_PUT32_MSB(chl->mode, mode);
- silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
- SILC_NOTIFY_TYPE_CUMODE_CHANGE, 3,
- clidp->data, clidp->len,
- mode, 4, clidp->data, clidp->len);
+ /* If client became founder by providing correct founder auth data
+ notify the mode change to the channel. */
+ if (founder) {
+ SILC_PUT32_MSB(chl->mode, mode);
+ silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
+ SILC_NOTIFY_TYPE_CUMODE_CHANGE, 4,
+ clidp->data, clidp->len,
+ mode, 4, clidp->data, clidp->len,
+ fkey, fkey_len);
- /* Set CUMODE notify type to network */
- if (!server->standalone)
- silc_server_send_notify_cumode(server, server->router->connection,
- server->server_type == SILC_ROUTER ?
- TRUE : FALSE, channel,
- chl->mode, client->id, SILC_ID_CLIENT,
- client->id);
+ /* Set CUMODE notify type to network */
+ if (!server->standalone)
+ silc_server_send_notify_cumode(server, server->router->connection,
+ server->server_type == SILC_ROUTER ?
+ TRUE : FALSE, channel,
+ chl->mode, client->id, SILC_ID_CLIENT,
+ client->id, channel->founder_key);
+ }
}
silc_buffer_free(reply);
silc_buffer_free(keyp);
silc_buffer_free(user_list);
silc_buffer_free(mode_list);
+ silc_free(fkey);
out:
silc_free(passphrase);
tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
if (!tmp) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
+ 0);
goto out;
}
channel_name = tmp;
if (silc_server_name_bad_chars(channel_name, tmp_len) == TRUE) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
- SILC_STATUS_ERR_BAD_CHANNEL);
+ SILC_STATUS_ERR_BAD_CHANNEL, 0);
goto out;
}
tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
if (!tmp) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
+ 0);
goto out;
}
client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
if (!client_id) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
+ 0);
goto out;
}
SilcClientEntry entry = (SilcClientEntry)cmd->sock->user_data;
client_id = silc_id_dup(entry->id, SILC_ID_CLIENT);
- if (!channel || channel->disabled) {
+ if (!channel ||
+ (channel->disabled && server->server_type != SILC_ROUTER)) {
/* Channel not found */
/* If we are standalone server we don't have a router, we just create
if (!channel) {
silc_server_command_send_status_reply(
cmd, SILC_COMMAND_JOIN,
- SILC_STATUS_ERR_UNKNOWN_ALGORITHM);
+ SILC_STATUS_ERR_UNKNOWN_ALGORITHM,
+ 0);
goto out;
}
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);
+ silc_server_command_send_status_reply(
+ cmd, SILC_COMMAND_JOIN,
+ SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0);
goto out;
}
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);
+ silc_server_command_send_status_reply(
+ cmd, SILC_COMMAND_JOIN,
+ SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0);
goto out;
}
}
if (silc_command_get(reply->payload) == SILC_COMMAND_WHOIS &&
- !silc_hash_table_count(channel->user_list))
+ !channel->disabled && !silc_hash_table_count(channel->user_list))
created = TRUE;
}
/* If the channel does not have global users and is also empty the client
will be the channel founder and operator. */
- if (!channel->global_users && !silc_hash_table_count(channel->user_list))
+ if (!channel->disabled &&
+ !channel->global_users && !silc_hash_table_count(channel->user_list))
umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
/* Join to the channel */
dest_server = silc_argument_get_arg_type(cmd->args, 1, NULL);
if (!dest_server) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_MOTD,
- SILC_STATUS_ERR_NO_SUCH_SERVER);
+ SILC_STATUS_ERR_NO_SUCH_SERVER, 0);
goto out;
}
if (!entry) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_INFO,
- SILC_STATUS_ERR_NO_SUCH_SERVER);
+ SILC_STATUS_ERR_NO_SUCH_SERVER, 0);
goto out;
}
/* Check that mode changing is allowed. */
if (!silc_server_check_umode_rights(server, client, mask)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_UMODE,
- SILC_STATUS_ERR_PERM_DENIED);
+ SILC_STATUS_ERR_PERM_DENIED, 0);
goto out;
}
if (mask & SILC_UMODE_ANONYMOUS) {
if (!(client->mode & SILC_UMODE_ANONYMOUS)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_UMODE,
- SILC_STATUS_ERR_PERM_DENIED);
+ SILC_STATUS_ERR_PERM_DENIED, 0);
goto out;
}
} else {
if (client->mode & SILC_UMODE_ANONYMOUS) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_UMODE,
- SILC_STATUS_ERR_PERM_DENIED);
+ SILC_STATUS_ERR_PERM_DENIED, 0);
goto out;
}
}
SilcUInt32 mode_mask = 0, tmp_len, tmp_len2;
SilcUInt16 ident = silc_command_get_ident(cmd->payload);
bool set_mask = FALSE;
+ SilcPublicKey founder_key = NULL;
+ unsigned char *fkey = NULL;
+ SilcUInt32 fkey_len = 0;
SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_CMODE, cmd, 1, 7);
tmp_id = silc_argument_get_arg_type(cmd->args, 1, &tmp_len2);
if (!tmp_id) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
- SILC_STATUS_ERR_NO_CHANNEL_ID);
+ SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
goto out;
}
channel_id = silc_id_payload_parse_id(tmp_id, tmp_len2, NULL);
if (!channel_id) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
- SILC_STATUS_ERR_NO_CHANNEL_ID);
+ SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
goto out;
}
channel_id, NULL);
if (!channel) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
- SILC_STATUS_ERR_NO_SUCH_CHANNEL);
+ SILC_STATUS_ERR_NO_SUCH_CHANNEL,
+ 0);
goto out;
}
}
/* Check whether this client is on the channel */
if (!silc_server_client_on_channel(client, channel, &chl)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
- SILC_STATUS_ERR_NOT_ON_CHANNEL);
+ SILC_STATUS_ERR_NOT_ON_CHANNEL, 0);
goto out;
}
cmd, SILC_COMMAND_CMODE,
(!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) ?
SILC_STATUS_ERR_NO_CHANNEL_PRIV :
- SILC_STATUS_ERR_NO_CHANNEL_FOPRIV));
+ SILC_STATUS_ERR_NO_CHANNEL_FOPRIV), 0);
goto out;
}
if (!tmp) {
if (!(channel->mode & SILC_CHANNEL_MODE_ULIMIT)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
goto out;
}
} else {
tmp = silc_argument_get_arg_type(cmd->args, 4, NULL);
if (!tmp) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
goto out;
}
cipher = silc_argument_get_arg_type(cmd->args, 5, NULL);
if (!cipher) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
goto out;
}
/* Delete old cipher and allocate the new one */
if (!silc_cipher_alloc(cipher, &newkey)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
- SILC_STATUS_ERR_UNKNOWN_ALGORITHM);
+ SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0);
goto out;
}
/* Delete old cipher and allocate default one */
if (!silc_cipher_alloc(cipher ? cipher : SILC_DEFAULT_CIPHER, &newkey)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
- SILC_STATUS_ERR_UNKNOWN_ALGORITHM);
+ SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0);
goto out;
}
hmac = silc_argument_get_arg_type(cmd->args, 6, NULL);
if (!hmac) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
goto out;
}
/* Delete old hmac and allocate the new one */
if (!silc_hmac_alloc(hmac, NULL, &newhmac)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
- SILC_STATUS_ERR_UNKNOWN_ALGORITHM);
+ SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0);
goto out;
}
silc_hmac_free(channel->hmac);
if (!silc_hmac_alloc(hmac ? hmac : SILC_DEFAULT_HMAC, NULL, &newhmac)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
- SILC_STATUS_ERR_UNKNOWN_ALGORITHM);
+ SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0);
goto out;
}
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);
+ silc_server_command_send_status_reply(
+ cmd, SILC_COMMAND_CMODE,
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0);
goto out;
}
- auth = silc_auth_payload_parse(tmp, tmp_len);
- if (!auth) {
+ /* 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)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ SILC_STATUS_ERR_AUTH_FAILED,
+ 0);
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_memdup(tmp, tmp_len);
- channel->founder_passwd_len = tmp_len;
- } else {
- /* Verify the payload before setting the mode */
- if (!silc_auth_verify(auth, channel->founder_method,
- channel->founder_key, 0, idata->hash,
- client->id, SILC_ID_CLIENT)) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
- SILC_STATUS_ERR_AUTH_FAILED);
- goto out;
- }
- }
+ 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;
+ }
- silc_auth_payload_free(auth);
+ 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);
+ goto out;
+ }
}
}
} else {
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;
- }
+ channel->founder_key = NULL;
}
}
}
/* Send CMODE_CHANGE notify. */
cidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
- SILC_NOTIFY_TYPE_CMODE_CHANGE, 5,
+ SILC_NOTIFY_TYPE_CMODE_CHANGE, 6,
cidp->data, cidp->len,
tmp_mask, 4,
cipher, cipher ? strlen(cipher) : 0,
hmac, hmac ? strlen(hmac) : 0,
passphrase, passphrase ?
- strlen(passphrase) : 0);
+ strlen(passphrase) : 0,
+ fkey, fkey_len);
/* Set CMODE notify type to network */
if (!server->standalone)
server->server_type == SILC_ROUTER ?
TRUE : FALSE, channel,
mode_mask, client->id, SILC_ID_CLIENT,
- cipher, hmac, passphrase);
+ cipher, hmac, passphrase, founder_key);
/* Send command reply to sender */
packet = silc_command_reply_payload_encode_va(SILC_COMMAND_CMODE,
silc_buffer_free(cidp);
out:
+ silc_free(fkey);
silc_free(channel_id);
silc_server_command_free(cmd);
}
SilcUInt32 target_mask, sender_mask = 0, tmp_len, tmp_ch_len;
int notify = FALSE;
SilcUInt16 ident = silc_command_get_ident(cmd->payload);
+ SilcPublicKey founder_key = NULL;
+ unsigned char *fkey = NULL;
+ SilcUInt32 fkey_len = 0;
SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_CUMODE, cmd, 3, 4);
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);
+ SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
goto out;
}
channel_id = silc_id_payload_parse_id(tmp_ch_id, tmp_ch_len, NULL);
if (!channel_id) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
- SILC_STATUS_ERR_NO_CHANNEL_ID);
+ SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
goto out;
}
channel_id, NULL);
if (!channel) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
- SILC_STATUS_ERR_NO_SUCH_CHANNEL);
+ SILC_STATUS_ERR_NO_SUCH_CHANNEL,
+ 0);
goto out;
}
}
/* Check whether sender is on the channel */
if (!silc_server_client_on_channel(client, channel, &chl)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
- SILC_STATUS_ERR_NOT_ON_CHANNEL);
+ SILC_STATUS_ERR_NOT_ON_CHANNEL, 0);
goto out;
}
sender_mask = chl->mode;
tmp_mask = silc_argument_get_arg_type(cmd->args, 2, NULL);
if (!tmp_mask) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
+ 0);
goto out;
}
SILC_GET32_MSB(target_mask, tmp_mask);
tmp_id = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
if (!tmp_id) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
- SILC_STATUS_ERR_NO_CLIENT_ID);
+ SILC_STATUS_ERR_NO_CLIENT_ID, 0);
goto out;
}
client_id = silc_id_payload_parse_id(tmp_id, tmp_len, NULL);
if (!client_id) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
- SILC_STATUS_ERR_NO_CLIENT_ID);
+ SILC_STATUS_ERR_NO_CLIENT_ID, 0);
goto out;
}
!(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_NO_CHANNEL_PRIV);
+ SILC_STATUS_ERR_NO_CHANNEL_PRIV, 0);
goto out;
}
if (target_client != client) {
if (!silc_server_client_on_channel(target_client, channel, &chl)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
- SILC_STATUS_ERR_USER_NOT_ON_CHANNEL);
+ SILC_STATUS_ERR_USER_NOT_ON_CHANNEL, 0);
goto out;
}
}
but themselves. */
if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && client != target_client) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
- SILC_STATUS_ERR_NO_CHANNEL_FOPRIV);
+ SILC_STATUS_ERR_NO_CHANNEL_FOPRIV,
+ 0);
goto out;
}
if (target_mask & SILC_CHANNEL_UMODE_CHANFO) {
if (target_client != client) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
- SILC_STATUS_ERR_NOT_YOU);
+ SILC_STATUS_ERR_NOT_YOU, 0);
goto out;
}
if (!(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
/* The client tries to claim the founder rights. */
unsigned char *tmp_auth;
- SilcUInt32 tmp_auth_len, auth_len;
- void *auth;
-
+ SilcUInt32 tmp_auth_len;
+ SilcChannelClientEntry chl2;
+ SilcHashTableList htl;
+
if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) ||
!channel->founder_key || !idata->public_key ||
!silc_pkcs_public_key_compare(channel->founder_key,
idata->public_key)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
- SILC_STATUS_ERR_NOT_YOU);
+ SILC_STATUS_ERR_AUTH_FAILED, 0);
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);
+ SILC_STATUS_ERR_AUTH_FAILED, 0);
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)) {
+ /* Verify the authentication payload */
+ if (!silc_auth_verify_data(tmp_auth, tmp_auth_len, SILC_AUTH_PUBLIC_KEY,
+ channel->founder_key, 0, server->sha1hash,
+ client->id, SILC_ID_CLIENT)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
- SILC_STATUS_ERR_AUTH_FAILED);
+ SILC_STATUS_ERR_AUTH_FAILED, 0);
goto out;
}
-
- sender_mask = chl->mode |= SILC_CHANNEL_UMODE_CHANFO;
+
notify = TRUE;
+ 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_CUMODE,
+ SILC_STATUS_ERR_AUTH_FAILED, 0);
+ goto out;
+ }
+
+ /* There cannot be anyone else as founder on the channel now. This
+ client is definitely the founder due to this authentication */
+ silc_hash_table_list(channel->user_list, &htl);
+ while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
+ if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
+ chl2->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
+ silc_server_force_cumode_change(server, NULL, channel, chl2,
+ chl2->mode);
+ break;
+ }
+ silc_hash_table_list_reset(&htl);
+
+ sender_mask = chl->mode |= SILC_CHANNEL_UMODE_CHANFO;
}
} else {
if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
notify = TRUE;
} else {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
- SILC_STATUS_ERR_NOT_YOU);
+ SILC_STATUS_ERR_NOT_YOU, 0);
goto out;
}
}
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;
if (target_mask & SILC_CHANNEL_UMODE_BLOCK_MESSAGES) {
if (target_client != client) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
- SILC_STATUS_ERR_NOT_YOU);
+ SILC_STATUS_ERR_NOT_YOU, 0);
goto out;
}
if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES) {
if (target_client != client) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
- SILC_STATUS_ERR_NOT_YOU);
+ SILC_STATUS_ERR_NOT_YOU, 0);
goto out;
}
if (target_mask & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS) {
if (target_client != client) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
- SILC_STATUS_ERR_NOT_YOU);
+ SILC_STATUS_ERR_NOT_YOU, 0);
goto out;
}
if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS) {
if (target_client != client) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
- SILC_STATUS_ERR_NOT_YOU);
+ SILC_STATUS_ERR_NOT_YOU, 0);
goto out;
}
if (target_mask & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS) {
if (target_client != client) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
- SILC_STATUS_ERR_NOT_YOU);
+ SILC_STATUS_ERR_NOT_YOU, 0);
goto out;
}
if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS) {
if (target_client != client) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
- SILC_STATUS_ERR_NOT_YOU);
+ SILC_STATUS_ERR_NOT_YOU, 0);
goto out;
}
}
}
+ if (target_mask & SILC_CHANNEL_UMODE_QUIET) {
+ if (!(chl->mode & SILC_CHANNEL_UMODE_QUIET)) {
+ if (client == target_client) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+ SILC_STATUS_ERR_PERM_DENIED, 0);
+ goto out;
+ }
+ chl->mode |= SILC_CHANNEL_UMODE_QUIET;
+ notify = TRUE;
+ }
+ } else {
+ if (chl->mode & SILC_CHANNEL_UMODE_QUIET) {
+ if (client == target_client) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+ SILC_STATUS_ERR_PERM_DENIED, 0);
+ goto out;
+ }
+ chl->mode &= ~SILC_CHANNEL_UMODE_QUIET;
+ 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) {
silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
- SILC_NOTIFY_TYPE_CUMODE_CHANGE, 3,
+ SILC_NOTIFY_TYPE_CUMODE_CHANGE, 4,
idp->data, idp->len,
tmp_mask, 4,
- tmp_id, tmp_len);
+ tmp_id, tmp_len,
+ fkey, fkey_len);
/* Set CUMODE notify type to network */
if (!server->standalone)
TRUE : FALSE, channel,
target_mask, client->id,
SILC_ID_CLIENT,
- target_client->id);
+ target_client->id, founder_key);
}
/* Send command reply to sender */
silc_buffer_free(idp);
out:
+ silc_free(fkey);
silc_server_command_free(cmd);
}
tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
if (!tmp) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
- SILC_STATUS_ERR_NO_CHANNEL_ID);
+ SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
goto out;
}
channel_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
if (!channel_id) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
- SILC_STATUS_ERR_NO_CHANNEL_ID);
+ SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
goto out;
}
channel_id, NULL);
if (!channel) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
- SILC_STATUS_ERR_NO_SUCH_CHANNEL);
+ SILC_STATUS_ERR_NO_SUCH_CHANNEL,
+ 0);
goto out;
}
}
/* Check whether sender is on the channel */
if (!silc_server_client_on_channel(client, channel, &chl)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
- SILC_STATUS_ERR_NOT_ON_CHANNEL);
+ SILC_STATUS_ERR_NOT_ON_CHANNEL, 0);
goto out;
}
if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
!(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
- SILC_STATUS_ERR_NO_CHANNEL_PRIV);
+ SILC_STATUS_ERR_NO_CHANNEL_PRIV, 0);
goto out;
}
target_idp = silc_argument_get_arg_type(cmd->args, 2, &target_idp_len);
if (!target_idp) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
- SILC_STATUS_ERR_NO_CLIENT_ID);
+ SILC_STATUS_ERR_NO_CLIENT_ID, 0);
goto out;
}
client_id = silc_id_payload_parse_id(target_idp, target_idp_len, NULL);
if (!client_id) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
- SILC_STATUS_ERR_NO_CLIENT_ID);
+ SILC_STATUS_ERR_NO_CLIENT_ID, 0);
goto out;
}
/* Check whether target client is on the channel */
if (!silc_server_client_on_channel(target_client, channel, &chl)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
- SILC_STATUS_ERR_USER_NOT_ON_CHANNEL);
+ SILC_STATUS_ERR_USER_NOT_ON_CHANNEL,
+ 0);
goto out;
}
cannot be kicked from the channel. */
if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
- SILC_STATUS_ERR_NO_CHANNEL_FOPRIV);
+ SILC_STATUS_ERR_NO_CHANNEL_FOPRIV,
+ 0);
goto out;
}
/* Send command reply to sender */
silc_server_command_send_status_reply(cmd, SILC_COMMAND_KICK,
- SILC_STATUS_OK);
+ SILC_STATUS_OK, 0);
/* Send KICKED notify to local clients on the channel */
idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
username = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
if (!username) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
+ 0);
goto out;
}
username, client->nickname);
if (!admin) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
- SILC_STATUS_ERR_AUTH_FAILED);
+ SILC_STATUS_ERR_AUTH_FAILED,
+ 0);
goto out;
}
}
auth = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
if (!auth) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
+ 0);
goto out;
}
if (!result) {
/* Authentication failed */
silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
- SILC_STATUS_ERR_AUTH_FAILED);
+ SILC_STATUS_ERR_AUTH_FAILED,
+ 0);
goto out;
}
/* Send reply to the sender */
silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
- SILC_STATUS_OK);
+ SILC_STATUS_OK, 0);
out:
silc_server_command_free(cmd);
SILC_TASK_CALLBACK(silc_server_command_detach_timeout)
{
QuitInternal q = (QuitInternal)context;
- SilcClientEntry client = (SilcClientEntry)q->sock;
+ SilcClientID *client_id = (SilcClientID *)q->sock;
+ SilcClientEntry client;
SILC_LOG_DEBUG(("Start"));
- if (client->mode & SILC_UMODE_DETACHED)
+ client = silc_idlist_find_client_by_id(q->server->local_list, client_id,
+ FALSE, NULL);
+
+ if (client && client->mode & SILC_UMODE_DETACHED)
silc_server_free_client_data(q->server, NULL, client, TRUE,
"Detach timeout");
+
+ silc_free(client_id);
silc_free(q);
}
if (server->config->detach_disabled) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_DETACH,
- SILC_STATUS_ERR_UNKNOWN_COMMAND);
+ SILC_STATUS_ERR_UNKNOWN_COMMAND, 0);
goto out;
}
/* Send the user mode notify to notify that client is detached */
client->mode |= SILC_UMODE_DETACHED;
client->data.status &= ~SILC_IDLIST_STATUS_RESUMED;
+ client->last_command = 0;
+ client->fast_command = 0;
if (!server->standalone)
silc_server_send_notify_umode(server, server->router->connection,
server->server_type == SILC_SERVER ?
if (server->config->detach_timeout) {
q = silc_calloc(1, sizeof(*q));
q->server = server;
- q->sock = (void *)client;
+ q->sock = silc_id_dup(client->id, SILC_ID_CLIENT);
silc_schedule_task_add(server->schedule, 0,
silc_server_command_detach_timeout,
q, server->config->detach_timeout * 60,
/* Send reply to the sender */
silc_server_command_send_status_reply(cmd, SILC_COMMAND_DETACH,
- SILC_STATUS_OK);
+ SILC_STATUS_OK, 0);
out:
silc_server_command_free(cmd);
SilcServerCommandReplyContext reply = context2;
SilcStatus status;
silc_command_get_status(reply->payload, &status, NULL);
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH, status);
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH, status,
+ 0);
}
goto out;
tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
if (!tmp) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
+ 0);
goto out;
}
client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
if (!client_id) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
- SILC_STATUS_ERR_NO_SUCH_CLIENT_ID);
+ SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
+ 0);
goto out;
}
client_id, TRUE, NULL);
if (!client) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
- SILC_STATUS_ERR_NO_SUCH_CLIENT_ID);
+ SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
+ 0);
goto out;
}
del_nick = silc_argument_get_arg_type(cmd->args, 3, &del_nick_len);
if (!add_nick && !del_nick) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
+ 0);
goto out;
}
if (add_nick) {
if (silc_server_name_bad_chars(add_nick, strlen(add_nick)) == TRUE) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
- SILC_STATUS_ERR_BAD_NICKNAME);
+ SILC_STATUS_ERR_BAD_NICKNAME, 0);
goto out;
}
client, NULL)) {
/* Nickname is alredy being watched for this client */
silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
- SILC_STATUS_ERR_NICKNAME_IN_USE);
+ SILC_STATUS_ERR_NICKNAME_IN_USE,
+ 0);
goto out;
}
if (del_nick) {
if (silc_server_name_bad_chars(del_nick, strlen(del_nick)) == TRUE) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
- SILC_STATUS_ERR_BAD_NICKNAME);
+ SILC_STATUS_ERR_BAD_NICKNAME, 0);
goto out;
}
client, (void **)&tmp)) {
/* Nickname is alredy being watched for this client */
silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
- SILC_STATUS_ERR_NO_SUCH_NICK);
+ SILC_STATUS_ERR_NO_SUCH_NICK, 0);
goto out;
}
silc_free(tmp);
}
+ /* Distribute the watch list to backup routers too */
+ if (server->backup) {
+ SilcBuffer tmpbuf;
+ silc_command_set_ident(cmd->payload, ++server->cmd_ident);
+ tmpbuf = silc_command_payload_encode_payload(cmd->payload);
+ silc_server_backup_send(server, NULL, SILC_PACKET_COMMAND,
+ cmd->packet->flags, tmpbuf->data, tmpbuf->len,
+ FALSE, TRUE);
+ silc_buffer_free(tmpbuf);
+ }
+
silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
- SILC_STATUS_OK);
+ SILC_STATUS_OK, 0);
out:
silc_free(client_id);
if (server->server_type != SILC_ROUTER) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
- SILC_STATUS_ERR_AUTH_FAILED);
+ SILC_STATUS_ERR_AUTH_FAILED, 0);
goto out;
}
username = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
if (!username) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
+ 0);
goto out;
}
username, client->nickname);
if (!admin) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
- SILC_STATUS_ERR_AUTH_FAILED);
+ SILC_STATUS_ERR_AUTH_FAILED, 0);
goto out;
}
}
auth = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
if (!auth) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
+ 0);
goto out;
}
if (!result) {
/* Authentication failed */
silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
- SILC_STATUS_ERR_AUTH_FAILED);
+ SILC_STATUS_ERR_AUTH_FAILED, 0);
goto out;
}
/* Send reply to the sender */
silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
- SILC_STATUS_OK);
+ SILC_STATUS_OK, 0);
out:
silc_server_command_free(cmd);
channel_id = silc_id_payload_parse_id(id, id_len, NULL);
if (!channel_id) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
- SILC_STATUS_ERR_NO_CHANNEL_ID);
+ SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
goto out;
}
}
channel_id, NULL);
if (!channel) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
- SILC_STATUS_ERR_NO_SUCH_CHANNEL);
+ SILC_STATUS_ERR_NO_SUCH_CHANNEL,
+ 0);
goto out;
}
}
/* Check whether this client is on the channel */
if (!silc_server_client_on_channel(client, channel, &chl)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
- SILC_STATUS_ERR_NOT_ON_CHANNEL);
+ SILC_STATUS_ERR_NOT_ON_CHANNEL, 0);
goto out;
}
/* The client must be at least channel operator. */
if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
- SILC_STATUS_ERR_NO_CHANNEL_PRIV);
+ SILC_STATUS_ERR_NO_CHANNEL_PRIV, 0);
goto out;
}
tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
if (!tmp) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_LEAVE,
- SILC_STATUS_ERR_NO_CHANNEL_ID);
+ SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
goto out;
}
id = silc_id_payload_parse_id(tmp, len, NULL);
if (!id) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_LEAVE,
- SILC_STATUS_ERR_NO_CHANNEL_ID);
+ SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
goto out;
}
channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
if (!channel) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_LEAVE,
- SILC_STATUS_ERR_NO_SUCH_CHANNEL);
+ SILC_STATUS_ERR_NO_SUCH_CHANNEL,
+ 0);
goto out;
}
}
/* Check whether this client is on the channel */
if (!silc_server_client_on_channel(id_entry, channel, NULL)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_LEAVE,
- SILC_STATUS_ERR_NOT_ON_CHANNEL);
+ SILC_STATUS_ERR_NOT_ON_CHANNEL, 0);
goto out;
}
TRUE : FALSE, channel, id_entry->id);
silc_server_command_send_status_data(cmd, SILC_COMMAND_LEAVE,
- SILC_STATUS_OK, 2, tmp, len);
+ SILC_STATUS_OK, 0, 2, tmp, len);
/* Remove client from channel */
if (!silc_server_remove_from_one_channel(server, sock, channel, id_entry,
if (!channel_id && !channel_name) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_USERS,
- SILC_STATUS_ERR_NO_CHANNEL_ID);
+ SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
goto out;
}
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);
+ SILC_STATUS_ERR_NO_CHANNEL_ID, 0);
goto out;
}
}
channel = silc_idlist_find_channel_by_name(server->local_list,
channel_name, NULL);
- if (!channel || channel->disabled || !channel->users_resolved) {
+ if (!channel || (!server->standalone && (channel->disabled ||
+ !channel->users_resolved))) {
if (server->server_type != SILC_ROUTER && !server->standalone &&
!cmd->pending) {
SilcBuffer tmpbuf;
if (!channel) {
/* Channel really does not exist */
silc_server_command_send_status_reply(cmd, SILC_COMMAND_USERS,
- SILC_STATUS_ERR_NO_SUCH_CHANNEL);
+ SILC_STATUS_ERR_NO_SUCH_CHANNEL,
+ 0);
goto out;
}
}
&& !silc_server_client_on_channel(cmd->sock->user_data, channel,
NULL)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_USERS,
- SILC_STATUS_ERR_NOT_ON_CHANNEL);
+ SILC_STATUS_ERR_NOT_ON_CHANNEL, 0);
goto out;
}
}
/* Get the users list */
- silc_server_get_users_on_channel(server, channel, &client_id_list,
- &client_mode_list, &list_count);
+ if (!silc_server_get_users_on_channel(server, channel, &client_id_list,
+ &client_mode_list, &list_count)) {
+ list_count = 0;
+ client_id_list = NULL;
+ client_mode_list = NULL;
+ }
/* List count */
SILC_PUT32_MSB(list_count, lc);
SILC_STATUS_OK, 0, ident, 4,
2, idp->data, idp->len,
3, lc, 4,
- 4, client_id_list->data,
- client_id_list->len,
- 5, client_mode_list->data,
- client_mode_list->len);
+ 4, client_id_list ?
+ client_id_list->data : NULL,
+ client_id_list ?
+ client_id_list->len : 0,
+ 5, client_mode_list ?
+ client_mode_list->data : NULL,
+ client_mode_list ?
+ client_mode_list->len : 0);
silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
packet->data, packet->len, FALSE);
silc_buffer_free(idp);
silc_buffer_free(packet);
- silc_buffer_free(client_id_list);
- silc_buffer_free(client_mode_list);
+ if (client_id_list)
+ silc_buffer_free(client_id_list);
+ if (client_mode_list)
+ silc_buffer_free(client_mode_list);
silc_free(id);
out:
tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
if (!tmp) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_GETKEY,
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
+ 0);
goto out;
}
idp = silc_id_payload_parse(tmp, tmp_len);
if (!idp) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_GETKEY,
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
+ 0);
goto out;
}
if (!client) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_GETKEY,
- SILC_STATUS_ERR_NO_SUCH_CLIENT_ID);
+ SILC_STATUS_ERR_NO_SUCH_CLIENT_ID,
+ 0);
goto out;
}
if (!server_entry) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_GETKEY,
- SILC_STATUS_ERR_NO_SUCH_SERVER_ID);
+ SILC_STATUS_ERR_NO_SUCH_SERVER_ID,
+ 0);
goto out;
}
if (!(client->mode & SILC_UMODE_SERVER_OPERATOR) &&
!(client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CONNECT,
- SILC_STATUS_ERR_NO_SERVER_PRIV);
+ SILC_STATUS_ERR_NO_SERVER_PRIV, 0);
goto out;
}
if (server->server_type == SILC_ROUTER &&
client->mode & SILC_UMODE_SERVER_OPERATOR) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CONNECT,
- SILC_STATUS_ERR_NO_ROUTER_PRIV);
+ SILC_STATUS_ERR_NO_ROUTER_PRIV, 0);
goto out;
}
host = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
if (!host) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CONNECT,
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
+ 0);
goto out;
}
/* Send reply to the sender */
silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CONNECT,
- SILC_STATUS_OK);
+ SILC_STATUS_OK, 0);
out:
silc_server_command_free(cmd);
if (!(client->mode & SILC_UMODE_SERVER_OPERATOR) &&
!(client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
- SILC_STATUS_ERR_NO_SERVER_PRIV);
+ SILC_STATUS_ERR_NO_SERVER_PRIV,
+ 0);
goto out;
}
name = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
if (!name) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
+ 0);
goto out;
}
name, port, FALSE, NULL);
if (!server_entry) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
- SILC_STATUS_ERR_NO_SERVER_ID);
+ SILC_STATUS_ERR_NO_SERVER_ID, 0);
goto out;
}
/* Send reply to the sender */
silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CLOSE,
- SILC_STATUS_OK);
+ SILC_STATUS_OK, 0);
/* Close the connection to the server */
sock = (SilcSocketConnection)server_entry->connection;
if (!(client->mode & SILC_UMODE_SERVER_OPERATOR) &&
!(client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_SHUTDOWN,
- SILC_STATUS_ERR_NO_SERVER_PRIV);
+ SILC_STATUS_ERR_NO_SERVER_PRIV,
+ 0);
goto out;
}
/* Send reply to the sender */
silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_SHUTDOWN,
- SILC_STATUS_OK);
+ SILC_STATUS_OK, 0);
/* Then, gracefully, or not, bring the server down. */
silc_server_stop(server);