silc_server_command_send_status_reply(cmd, command,
SILC_STATUS_ERR_NOT_REGISTERED);
- silc_server_command_free(cmd);
return FALSE;
}
SilcServerCommandTimeout timeout = (SilcServerCommandTimeout)context;
SilcClientEntry client = (SilcClientEntry)timeout->ctx->sock->user_data;
+ if (!client) {
+ silc_server_command_free(timeout->ctx);
+ silc_free(timeout);
+ }
+
/* Update access time */
client->last_command = time(NULL);
timeout->ctx,
timeout->cmd->cmd))
timeout->cmd->cb(timeout->ctx, NULL);
+ else
+ silc_server_command_free(timeout->ctx);
silc_free(timeout);
}
silc_server_command_process_timeout,
(void *)timeout,
2 - (time(NULL) - client->last_command), 0,
- SILC_TASK_TIMEOUT,
- SILC_TASK_PRI_NORMAL);
+ 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);
+ (void *)timeout, 0, 1,
+ SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
return;
}
cmd->cb(ctx, NULL);
else if (silc_server_is_registered(server, sock, ctx, cmd->cmd))
cmd->cb(ctx, NULL);
+ else
+ silc_server_command_free(ctx);
}
/* Allocate Command Context */
int i, k;
bool no_res = TRUE;
+ SILC_LOG_DEBUG(("Start"));
+
for (i = 0; i < clients_count; i++) {
entry = clients[i];
if (!entry)
silc_server_command_whowas,
silc_server_command_dup(cmd));
cmd->pending = TRUE;
-
silc_command_set_ident(cmd->payload, old_ident);
silc_buffer_free(tmpbuf);
{
SilcServer server = cmd->server;
char *tmp;
- int i, count = 0, len;
+ int i, k, count = 0, len;
SilcBuffer packet, idp;
SilcClientEntry entry = NULL;
SilcCommandStatus status;
uint16 ident = silc_command_get_ident(cmd->payload);
- char found = FALSE;
char nh[256], uh[256];
+ int valid_count;
status = SILC_STATUS_OK;
- if (clients_count > 1)
- status = SILC_STATUS_LIST_START;
+ /* Process only entries that are not registered anymore. */
+ valid_count = 0;
for (i = 0; i < clients_count; i++) {
- entry = clients[i];
+ if (clients[i]->data.status & SILC_IDLIST_STATUS_REGISTERED)
+ clients[i] = NULL;
+ else
+ valid_count++;
+ }
- /* We will take only clients that are not valid anymore. They are the
- ones that are not registered anymore but still have a ID. They
- have disconnected us, and thus valid for WHOWAS. */
- if (entry->data.status & SILC_IDLIST_STATUS_REGISTERED || !entry->id)
- continue;
+ 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));
+ return;
+ }
- if (count && i - 1 == count)
- break;
+ if (valid_count > 1)
+ status = SILC_STATUS_LIST_START;
- found = TRUE;
+ for (i = 0, k = 0; i < clients_count; i++) {
+ entry = clients[i];
+ if (!entry)
+ continue;
- if (clients_count > 2)
+ if (k >= 1)
status = SILC_STATUS_LIST_ITEM;
- if (clients_count > 1 && i == clients_count - 1)
+ if (valid_count > 1 && k == valid_count - 1)
+ 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 (found == FALSE && entry)
- silc_server_command_send_status_data(cmd, SILC_COMMAND_WHOWAS,
- SILC_STATUS_ERR_NO_SUCH_NICK,
- 3, entry->nickname,
- strlen(entry->nickname));
+ k++;
+ }
}
static int
silc_server_command_whowas,
silc_server_command_dup(cmd));
cmd->pending = TRUE;
-
silc_command_set_ident(cmd->payload, old_ident);
silc_buffer_free(tmpbuf);
SilcClientID *client_id;
unsigned char *tmp, *comment;
uint32 tmp_len, tmp_len2;
+ bool local;
SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_KILL, cmd, 1, 2);
/* 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);
silc_server_free_client_data(server, sock, remote_client, FALSE, NULL);
silc_server_close_connection(server, sock);
} else {
+ /* Update statistics */
+ if (remote_client->connection)
+ server->stat.my_clients--;
+ if (server->server_type == SILC_ROUTER)
+ server->stat.cell_clients--;
+ SILC_OPER_STATS_UPDATE(remote_client, server, SILC_UMODE_SERVER_OPERATOR);
+ SILC_OPER_STATS_UPDATE(remote_client, router, SILC_UMODE_ROUTER_OPERATOR);
+
/* Remove remote client */
- if (!silc_idlist_del_client(server->global_list, remote_client))
- silc_idlist_del_client(server->local_list, remote_client);
+ silc_idlist_del_client(local ? server->local_list :
+ server->global_list, remote_client);
}
out:
memset(info_string, 0, sizeof(info_string));
snprintf(info_string, sizeof(info_string),
"location: %s server: %s admin: %s <%s>",
- server->config->admin_info->location,
- server->config->admin_info->server_type,
- server->config->admin_info->admin_name,
- server->config->admin_info->admin_email);
+ server->config->server_info->location,
+ server->config->server_info->server_type,
+ server->config->server_info->admin,
+ server->config->server_info->email);
server_info = info_string;
entry = server->id_entry;
/* 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, 3,
+ clidp->data, clidp->len,
+ mode, 4, clidp->data, clidp->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);
}
silc_buffer_free(reply);
silc_server_command_join,
silc_server_command_dup(cmd));
cmd->pending = TRUE;
+ silc_command_set_ident(cmd->payload, old_ident);
+ silc_buffer_free(tmpbuf);
goto out;
}
if (silc_command_get(reply->payload) == SILC_COMMAND_JOIN) {
tmp = silc_argument_get_arg_type(reply->args, 6, NULL);
SILC_GET32_MSB(created, tmp);
- create_key = FALSE; /* Router returned the key already */
+ if (silc_argument_get_arg_type(reply->args, 7, NULL))
+ create_key = FALSE; /* Router returned the key already */
}
if (silc_command_get(reply->payload) == SILC_COMMAND_WHOIS &&
idp = silc_id_payload_encode(server->id_entry->id, SILC_ID_SERVER);
- if (server->config && server->config->motd &&
- server->config->motd->motd_file) {
+ if (server->config && server->config->server_info &&
+ server->config->server_info->motd_file) {
/* Send motd */
- motd = silc_file_readfile(server->config->motd->motd_file, &motd_len);
+ motd = silc_file_readfile(server->config->server_info->motd_file, &motd_len);
if (!motd)
goto out;
goto out;
}
} else {
- if (client->mode & SILC_UMODE_SERVER_OPERATOR)
- /* Remove the server operator rights */
+ /* Remove the server operator rights */
+ if (client->mode & SILC_UMODE_SERVER_OPERATOR) {
client->mode &= ~SILC_UMODE_SERVER_OPERATOR;
+ if (client->connection)
+ server->stat.my_server_ops--;
+ if (server->server_type == SILC_ROUTER)
+ server->stat.server_ops--;
+ }
}
if (mask & SILC_UMODE_ROUTER_OPERATOR) {
goto out;
}
} else {
- if (client->mode & SILC_UMODE_ROUTER_OPERATOR)
- /* Remove the router operator rights */
+ /* Remove the router operator rights */
+ if (client->mode & SILC_UMODE_ROUTER_OPERATOR) {
client->mode &= ~SILC_UMODE_ROUTER_OPERATOR;
+ if (client->connection)
+ server->stat.my_router_ops--;
+ if (server->server_type == SILC_ROUTER)
+ server->stat.router_ops--;
+ }
}
if (mask & SILC_UMODE_GONE) {
/* The mode is removed and we need to generate and distribute
new channel key. Clients are not using private channel keys
anymore after this. */
-
+
/* Re-generate channel key */
if (!silc_server_create_channel_key(server, channel, 0))
goto out;
-
+
/* Send the channel key. This sends it to our local clients and if
we are normal server to our router as well. */
silc_server_send_channel_key(server, NULL, channel,
server->server_type == SILC_ROUTER ?
FALSE : !server->standalone);
-
+
cipher = channel->channel_key->cipher->name;
hmac = (char *)silc_hmac_get_name(channel->hmac);
}
}
-
+
if (mode_mask & SILC_CHANNEL_MODE_ULIMIT) {
/* User limit is set on channel */
uint32 user_limit;
SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
unsigned char *username, *auth;
uint32 tmp_len;
- SilcServerConfigSectionAdminConnection *admin;
+ SilcServerConfigAdmin *admin;
SilcIDListData idata = (SilcIDListData)client;
+ bool result = FALSE;
SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_OPER, cmd, 1, 2);
}
/* Get the admin configuration */
- admin = silc_server_config_find_admin(server->config, cmd->sock->ip,
+ admin = silc_server_config_find_admin(server, cmd->sock->ip,
username, client->nickname);
if (!admin) {
- admin = silc_server_config_find_admin(server->config, cmd->sock->hostname,
+ admin = silc_server_config_find_admin(server, cmd->sock->hostname,
username, client->nickname);
if (!admin) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
goto out;
}
- /* Verify the authentication data */
- if (!silc_auth_verify_data(auth, tmp_len, admin->auth_meth,
- admin->auth_data, admin->auth_data_len,
- idata->hash, client->id, SILC_ID_CLIENT)) {
+ /* Verify the authentication data. If both passphrase and public key
+ is set then try both of them. */
+ if (admin->passphrase)
+ result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PASSWORD,
+ admin->passphrase, admin->passphrase_len,
+ idata->hash, client->id, SILC_ID_CLIENT);
+ if (!result && admin->publickey)
+ result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PUBLIC_KEY,
+ admin->publickey, 0,
+ idata->hash, client->id, SILC_ID_CLIENT);
+ if (!result) {
+ /* Authentication failed */
silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
SILC_STATUS_ERR_AUTH_FAILED);
goto out;
/* Client is now server operator */
client->mode |= SILC_UMODE_SERVER_OPERATOR;
+ /* Update statistics */
+ if (client->connection)
+ server->stat.my_server_ops++;
+ if (server->server_type == SILC_ROUTER)
+ server->stat.server_ops++;
+
/* Send UMODE change to primary router */
if (!server->standalone)
silc_server_send_notify_umode(server, server->router->connection, TRUE,
SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
unsigned char *username, *auth;
uint32 tmp_len;
- SilcServerConfigSectionAdminConnection *admin;
+ SilcServerConfigAdmin *admin;
SilcIDListData idata = (SilcIDListData)client;
+ bool result = FALSE;
SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_SILCOPER, cmd, 1, 2);
}
/* Get the admin configuration */
- admin = silc_server_config_find_admin(server->config, cmd->sock->ip,
+ admin = silc_server_config_find_admin(server, cmd->sock->ip,
username, client->nickname);
if (!admin) {
- admin = silc_server_config_find_admin(server->config, cmd->sock->hostname,
+ admin = silc_server_config_find_admin(server, cmd->sock->hostname,
username, client->nickname);
if (!admin) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
goto out;
}
- /* Verify the authentication data */
- if (!silc_auth_verify_data(auth, tmp_len, admin->auth_meth,
- admin->auth_data, admin->auth_data_len,
- idata->hash, client->id, SILC_ID_CLIENT)) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
+ /* Verify the authentication data. If both passphrase and public key
+ is set then try both of them. */
+ if (admin->passphrase)
+ result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PASSWORD,
+ admin->passphrase, admin->passphrase_len,
+ idata->hash, client->id, SILC_ID_CLIENT);
+ if (!result && admin->publickey)
+ result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PUBLIC_KEY,
+ admin->publickey, 0,
+ idata->hash, client->id, SILC_ID_CLIENT);
+ if (!result) {
+ /* Authentication failed */
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
SILC_STATUS_ERR_AUTH_FAILED);
goto out;
}
/* Client is now router operator */
client->mode |= SILC_UMODE_ROUTER_OPERATOR;
+ /* Update statistics */
+ if (client->connection)
+ server->stat.my_router_ops++;
+ if (server->server_type == SILC_ROUTER)
+ server->stat.router_ops++;
+
/* Send UMODE change to primary router */
if (!server->standalone)
silc_server_send_notify_umode(server, server->router->connection, TRUE,
}
/* Get entry to the channel user list */
- silc_hash_table_find(channel->user_list, client, NULL, (void *)&chl);
+ if (!silc_hash_table_find(channel->user_list, client, NULL, (void *)&chl)) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
+ SILC_STATUS_ERR_NOT_ON_CHANNEL);
+ goto out;
+ }
/* The client must be at least channel operator. */
if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP)) {
2, id, id_len,
3, channel->ban_list,
channel->ban_list ?
- strlen(channel->ban_list) - 1 : 0);
+ strlen(channel->ban_list) -1 : 0);
silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
packet->data, packet->len, FALSE);
silc_server_command_getkey,
silc_server_command_dup(cmd));
cmd->pending = TRUE;
-
silc_command_set_ident(cmd->payload, old_ident);
silc_buffer_free(tmpbuf);
goto out;