/* If we are normal server, send the command to router, since we
want to know all channels in the network. */
- if (!cmd->pending && server->server_type == SILC_SERVER &&
+ if (!cmd->pending && server->server_type != SILC_ROUTER &&
!server->standalone) {
SilcBuffer tmpbuf;
SilcUInt16 old_ident;
/* 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);
/* Send command reply */
tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
- if (add || del)
- 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);
- else
- packet =
- silc_command_reply_payload_encode_va(SILC_COMMAND_INVITE,
- SILC_STATUS_OK, 0, ident, 1,
- 2, tmp, 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);
silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
packet->data, packet->len, FALSE);
silc_buffer_free(packet);
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;
+ }
+
+ /* 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;
+ }
- /* Now do the killing */
- silc_server_kill_client(server, remote_client, comment, client->id,
- SILC_ID_CLIENT);
+ /* 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;
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);
goto out;
}
+ if (auth && auth_len && !client->data.public_key) {
+ if (cmd->pending == 2)
+ goto out;
+
+ /* We must retrieve the detached client's public key by sending
+ GETKEY command. Reprocess this packet after receiving the key */
+ clidp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
+ silc_server_send_command(server, cmd->sock,
+ SILC_COMMAND_GETKEY, ++server->cmd_ident,
+ 1, 1, clidp->data, clidp->len);
+ silc_buffer_free(clidp);
+ silc_server_command_pending(server, SILC_COMMAND_GETKEY,
+ server->cmd_ident,
+ silc_server_command_join,
+ silc_server_command_dup(cmd));
+ cmd->pending = 2;
+ goto out;
+ }
+
cmd->pending = FALSE;
}
if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
tmp = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
+ cipher = silc_cipher_get_name(channel->channel_key);
keyp = silc_channel_key_payload_encode(silc_id_get_len(channel->id,
SILC_ID_CHANNEL),
tmp,
- strlen(channel->channel_key->
- cipher->name),
- channel->channel_key->cipher->name,
+ strlen(cipher), cipher,
channel->key_len / 8, channel->key);
silc_free(tmp);
}
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);
reply =
silc_command_reply_payload_encode_va(SILC_COMMAND_JOIN,
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);
out:
silc_free(passphrase);
}
if (!entry) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_INFO,
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_MOTD,
SILC_STATUS_ERR_NO_SUCH_SERVER, 0);
goto out;
}
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);
silc_server_send_channel_key(server, NULL, channel,
server->server_type == SILC_ROUTER ?
FALSE : !server->standalone);
-
- cipher = channel->channel_key->cipher->name;
+
+ cipher = (char *)silc_cipher_get_name(channel->channel_key);
hmac = (char *)silc_hmac_get_name(channel->hmac);
}
}
}
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_CMODE,
SILC_STATUS_ERR_AUTH_FAILED,
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),
out:
channel->mode = old_mask;
- silc_free(fkey);
+ silc_buffer_free(fkey);
silc_free(channel_id);
silc_server_command_free(cmd);
}
SilcServer server = cmd->server;
SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
SilcIDListData idata = (SilcIDListData)client;
- SilcChannelID *channel_id;
- SilcClientID *client_id;
+ SilcChannelID *channel_id = NULL;
+ SilcClientID *client_id = NULL;
SilcChannelEntry channel;
SilcClientEntry target_client;
SilcChannelClientEntry chl;
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),
packet->data, packet->len, FALSE);
silc_buffer_free(packet);
- silc_free(channel_id);
- silc_free(client_id);
silc_buffer_free(idp);
out:
- silc_free(fkey);
+ silc_free(channel_id);
+ silc_free(client_id);
+ silc_buffer_free(fkey);
silc_server_command_free(cmd);
}
silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
SILC_STATUS_ERR_AUTH_FAILED,
0);
- SILC_LOG_INFO(("OPER authentication failed for username '%s' by"
+ SILC_LOG_INFO(("OPER authentication failed for username '%s' by "
"nickname '%s' from %s", username,
client->nickname, cmd->sock->hostname));
goto out;
SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_WATCH, cmd, 1, 3);
- if (server->server_type == SILC_SERVER && !server->standalone) {
+ if (server->server_type != SILC_ROUTER && !server->standalone) {
if (!cmd->pending) {
/* Send the command to router */
SilcBuffer tmpbuf;
SilcUInt16 old_ident;
+ SILC_LOG_DEBUG(("Forwarding WATCH to router"));
+
old_ident = silc_command_get_ident(cmd->payload);
silc_command_set_ident(cmd->payload, ++server->cmd_ident);
tmpbuf = silc_command_payload_encode_payload(cmd->payload);
/* Received reply from router, just send same data to the client. */
SilcServerCommandReplyContext reply = context2;
SilcStatus status;
+
+ SILC_LOG_DEBUG(("Received reply to WATCH from router"));
silc_command_get_status(reply->payload, &status, NULL);
silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH, status,
0);
if (!admin) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
SILC_STATUS_ERR_AUTH_FAILED, 0);
- SILC_LOG_INFO(("SILCOPER authentication failed for username '%s' by"
+ SILC_LOG_INFO(("SILCOPER authentication failed for username '%s' by "
"nickname '%s' from %s", username,
client->nickname, cmd->sock->hostname));
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);
goto out;
}
- if (server->server_type == SILC_ROUTER &&
+ if (server->server_type == SILC_ROUTER && !server->backup_router &&
client->mode & SILC_UMODE_SERVER_OPERATOR) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_PRIV_CONNECT,
SILC_STATUS_ERR_NO_ROUTER_PRIV, 0);