X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=apps%2Fsilcd%2Fcommand.c;h=9ceb7caaf403e11568a81a0eaffc75e3bdf69b07;hb=2407b5a8d55101dcc4cccb098888e0e21f6f299c;hp=cb487e23880534f81c4212f61c830107fb8efe8c;hpb=bd2c9343055303a5517a33401f57a0414639a953;p=silc.git diff --git a/apps/silcd/command.c b/apps/silcd/command.c index cb487e23..9ceb7caa 100644 --- a/apps/silcd/command.c +++ b/apps/silcd/command.c @@ -131,7 +131,6 @@ static int silc_server_is_registered(SilcServer server, silc_server_command_send_status_reply(cmd, command, SILC_STATUS_ERR_NOT_REGISTERED); - silc_server_command_free(cmd); return FALSE; } @@ -149,6 +148,11 @@ SILC_TASK_CALLBACK(silc_server_command_process_timeout) 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); @@ -159,6 +163,8 @@ SILC_TASK_CALLBACK(silc_server_command_process_timeout) timeout->ctx, timeout->cmd->cmd)) timeout->cmd->cb(timeout->ctx, NULL); + else + silc_server_command_free(timeout->ctx); silc_free(timeout); } @@ -233,15 +239,12 @@ void silc_server_command_process(SilcServer server, 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; } @@ -251,6 +254,8 @@ void silc_server_command_process(SilcServer server, 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 */ @@ -498,6 +503,8 @@ silc_server_command_whois_parse(SilcServerCommandContext cmd, (*client_id)[0] = silc_id_payload_parse_id(tmp, len); 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; @@ -515,6 +522,9 @@ silc_server_command_whois_parse(SilcServerCommandContext cmd, 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)++; @@ -556,6 +566,8 @@ silc_server_command_whois_check(SilcServerCommandContext cmd, int i, k; bool no_res = TRUE; + SILC_LOG_DEBUG(("Start")); + for (i = 0; i < clients_count; i++) { entry = clients[i]; if (!entry) @@ -1054,7 +1066,6 @@ silc_server_command_whowas_check(SilcServerCommandContext cmd, silc_server_command_whowas, silc_server_command_dup(cmd)); cmd->pending = TRUE; - silc_command_set_ident(cmd->payload, old_ident); silc_buffer_free(tmpbuf); @@ -1188,7 +1199,6 @@ silc_server_command_whowas_process(SilcServerCommandContext cmd) silc_server_command_whowas, silc_server_command_dup(cmd)); cmd->pending = TRUE; - silc_command_set_ident(cmd->payload, old_ident); silc_buffer_free(tmpbuf); @@ -2327,7 +2337,7 @@ SILC_SERVER_CMD_FUNC(topic) idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT); /* Send notify about topic change to all clients on the channel */ - silc_server_send_notify_to_channel(server, NULL, channel, TRUE, + silc_server_send_notify_to_channel(server, NULL, channel, FALSE, SILC_NOTIFY_TYPE_TOPIC_SET, 2, idp->data, idp->len, channel->topic, strlen(channel->topic)); @@ -2424,6 +2434,7 @@ SILC_SERVER_CMD_FUNC(invite) tmp = silc_argument_get_arg_type(cmd->args, 2, &len); if (tmp) { char invite[512]; + bool resolve; dest_id = silc_id_payload_parse_id(tmp, len); if (!dest_id) { @@ -2433,11 +2444,12 @@ SILC_SERVER_CMD_FUNC(invite) } /* Get the client entry */ - dest = silc_server_get_client_resolve(server, dest_id); + dest = silc_server_get_client_resolve(server, dest_id, &resolve); if (!dest) { - if (server->server_type != SILC_SERVER) { - silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE, - SILC_STATUS_ERR_NO_SUCH_CLIENT_ID); + if (server->server_type != SILC_SERVER || !resolve) { + silc_server_command_send_status_reply( + cmd, SILC_COMMAND_INVITE, + SILC_STATUS_ERR_NO_SUCH_CLIENT_ID); goto out; } @@ -2650,6 +2662,7 @@ SILC_SERVER_CMD_FUNC(kill) SilcClientID *client_id; unsigned char *tmp, *comment; uint32 tmp_len, tmp_len2; + bool local; SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_KILL, cmd, 1, 2); @@ -2687,9 +2700,11 @@ SILC_SERVER_CMD_FUNC(kill) /* 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); @@ -2743,9 +2758,17 @@ SILC_SERVER_CMD_FUNC(kill) 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: @@ -2976,6 +2999,7 @@ static void silc_server_command_join_channel(SilcServer server, uint16 ident = silc_command_get_ident(cmd->payload); char check[512], check2[512]; bool founder = FALSE; + bool resolve; SILC_LOG_DEBUG(("Start")); @@ -2986,11 +3010,18 @@ static void silc_server_command_join_channel(SilcServer server, if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT) { client = (SilcClientEntry)sock->user_data; } else { - client = silc_server_get_client_resolve(server, client_id); + client = silc_server_get_client_resolve(server, client_id, &resolve); if (!client) { if (cmd->pending) goto out; + if (!resolve) { + silc_server_command_send_status_reply( + cmd, SILC_COMMAND_JOIN, + SILC_STATUS_ERR_NOT_ENOUGH_PARAMS); + goto out; + } + /* The client info is being resolved. Reprocess this packet after receiving the reply to the query. */ silc_server_command_pending(server, SILC_COMMAND_WHOIS, @@ -3311,16 +3342,8 @@ SILC_SERVER_CMD_FUNC(join) channel_name, NULL); if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT) { - /* If this is coming from client the Client ID in the command packet must - be same as the client's ID. */ - if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT) { - SilcClientEntry entry = (SilcClientEntry)cmd->sock->user_data; - if (!SILC_ID_CLIENT_COMPARE(entry->id, client_id)) { - silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN, - SILC_STATUS_ERR_NOT_ENOUGH_PARAMS); - goto out; - } - } + SilcClientEntry entry = (SilcClientEntry)cmd->sock->user_data; + client_id = silc_id_dup(entry->id, SILC_ID_CLIENT); if (!channel || channel->disabled) { /* Channel not found */ @@ -3331,8 +3354,9 @@ SILC_SERVER_CMD_FUNC(join) 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); goto out; } @@ -3372,6 +3396,7 @@ SILC_SERVER_CMD_FUNC(join) silc_server_command_join, silc_server_command_dup(cmd)); cmd->pending = TRUE; + silc_command_set_ident(cmd->payload, old_ident); goto out; } @@ -3435,10 +3460,12 @@ SILC_SERVER_CMD_FUNC(join) 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) + if (silc_command_get(reply->payload) == SILC_COMMAND_WHOIS && + !silc_hash_table_count(channel->user_list)) created = TRUE; } @@ -3631,9 +3658,14 @@ SILC_SERVER_CMD_FUNC(umode) 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) { @@ -3644,9 +3676,14 @@ SILC_SERVER_CMD_FUNC(umode) 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) { @@ -3829,22 +3866,22 @@ SILC_SERVER_CMD_FUNC(cmode) /* 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; @@ -4243,9 +4280,9 @@ SILC_SERVER_CMD_FUNC(cumode) /* If the target client is founder, no one else can change their mode but themselves. */ - if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && chl->client != target_client) { + if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && client != target_client) { silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE, - SILC_STATUS_ERR_NOT_YOU); + SILC_STATUS_ERR_NO_CHANNEL_PRIV); goto out; } @@ -4504,7 +4541,7 @@ SILC_SERVER_CMD_FUNC(kick) silc_server_send_notify_kicked(server, server->router->connection, server->server_type == SILC_ROUTER ? TRUE : FALSE, channel, - target_client->id, comment); + target_client->id, client->id, comment); if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) { /* Re-generate channel key */ @@ -4581,6 +4618,12 @@ SILC_SERVER_CMD_FUNC(oper) /* 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, @@ -4659,6 +4702,12 @@ SILC_SERVER_CMD_FUNC(silcoper) /* 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, @@ -4781,7 +4830,11 @@ SILC_SERVER_CMD_FUNC(ban) } /* 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)) { @@ -4842,7 +4895,7 @@ SILC_SERVER_CMD_FUNC(ban) 2, id, id_len, 3, channel->ban_list, channel->ban_list ? - strlen(channel->ban_list) - 1 : 0); + strlen(channel->ban_list) : 0); silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0, packet->data, packet->len, FALSE); @@ -5194,6 +5247,7 @@ SILC_SERVER_CMD_FUNC(getkey) uint32 tmp_len, pklen; SilcBuffer pk = NULL; SilcIdType id_type; + SilcPublicKey public_key; SILC_LOG_DEBUG(("Start")); @@ -5262,11 +5316,12 @@ SILC_SERVER_CMD_FUNC(getkey) /* The client is locally connected, just get the public key and send it back. If they key does not exist then do not send it, send just OK reply */ - if (!client->data.public_key) { + public_key = client->data.public_key; + if (!public_key) { pkdata = NULL; pklen = 0; } else { - tmp = silc_pkcs_public_key_encode(client->data.public_key, &tmp_len); + 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, @@ -5312,7 +5367,6 @@ SILC_SERVER_CMD_FUNC(getkey) 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; @@ -5325,12 +5379,14 @@ SILC_SERVER_CMD_FUNC(getkey) } /* If they key does not exist then do not send it, send just OK reply */ - if (!server_entry->data.public_key) { + 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(server_entry->data.public_key, - &tmp_len); + 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,