X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=apps%2Fsilcd%2Fcommand.c;h=02ec6d1d6aefaf07681f48562db78c15108bf5f7;hb=a818c5b5411bbc4436d1c5f011236985c96bb787;hp=ab4d5cd080fe314c0c196812457e87c0df64a13b;hpb=da1c3bc287b33b27277030d0bd7b9bf0753228be;p=silc.git diff --git a/apps/silcd/command.c b/apps/silcd/command.c index ab4d5cd0..02ec6d1d 100644 --- a/apps/silcd/command.c +++ b/apps/silcd/command.c @@ -34,9 +34,9 @@ static void silc_server_command_send_status_data(SilcServerCommandContext cmd, SilcCommand command, SilcCommandStatus status, - uint32 arg_type, + SilcUInt32 arg_type, const unsigned char *arg, - uint32 arg_len); + SilcUInt32 arg_len); static bool silc_server_command_pending_error_check(SilcServerCommandContext cmd, SilcServerCommandReplyContext cmdr, @@ -89,7 +89,7 @@ SilcServerCommand silc_command_list[] = of arguments. */ #define SILC_SERVER_COMMAND_CHECK(command, context, min, max) \ do { \ - uint32 _argc; \ + SilcUInt32 _argc; \ \ SILC_LOG_DEBUG(("Start")); \ \ @@ -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 */ @@ -303,7 +308,7 @@ silc_server_command_dup(SilcServerCommandContext ctx) bool silc_server_command_pending(SilcServer server, SilcCommand reply_cmd, - uint16 ident, + SilcUInt16 ident, SilcCommandCb callback, void *context) { @@ -333,7 +338,7 @@ bool silc_server_command_pending(SilcServer server, void silc_server_command_pending_del(SilcServer server, SilcCommand reply_cmd, - uint16 ident) + SilcUInt16 ident) { SilcServerCommandPending *r; @@ -353,8 +358,8 @@ SilcServerCommandPendingCallbacks silc_server_command_pending_check(SilcServer server, SilcServerCommandReplyContext ctx, SilcCommand command, - uint16 ident, - uint32 *callbacks_count) + SilcUInt16 ident, + SilcUInt32 *callbacks_count) { SilcServerCommandPending *r; SilcServerCommandPendingCallbacks callbacks = NULL; @@ -404,9 +409,9 @@ static void silc_server_command_send_status_data(SilcServerCommandContext cmd, SilcCommand command, SilcCommandStatus status, - uint32 arg_type, + SilcUInt32 arg_type, const unsigned char *arg, - uint32 arg_len) + SilcUInt32 arg_len) { SilcBuffer buffer; @@ -467,15 +472,15 @@ silc_server_command_pending_error_check(SilcServerCommandContext cmd, static int silc_server_command_whois_parse(SilcServerCommandContext cmd, SilcClientID ***client_id, - uint32 *client_id_count, + SilcUInt32 *client_id_count, char **nickname, char **server_name, int *count, SilcCommand command) { unsigned char *tmp; - uint32 len; - uint32 argc = silc_argument_get_arg_num(cmd->args); + SilcUInt32 len; + SilcUInt32 argc = silc_argument_get_arg_num(cmd->args); int i, k; /* If client ID is in the command it must be used instead of nickname */ @@ -542,25 +547,27 @@ silc_server_command_whois_parse(SilcServerCommandContext cmd, /* Resolve context used by both WHOIS and IDENTIFY commands */ typedef struct { SilcServerEntry router; - uint16 ident; + SilcUInt16 ident; unsigned char **res_argv; - uint32 *res_argv_lens; - uint32 *res_argv_types; - uint32 res_argc; + SilcUInt32 *res_argv_lens; + SilcUInt32 *res_argv_types; + SilcUInt32 res_argc; } *SilcServerResolveContext; static bool silc_server_command_whois_check(SilcServerCommandContext cmd, SilcClientEntry *clients, - uint32 clients_count) + SilcUInt32 clients_count) { SilcServer server = cmd->server; SilcClientEntry entry; SilcServerResolveContext resolve = NULL, r = NULL; - uint32 resolve_count = 0; + SilcUInt32 resolve_count = 0; int i, k; bool no_res = TRUE; + SILC_LOG_DEBUG(("Start")); + for (i = 0; i < clients_count; i++) { entry = clients[i]; if (!entry) @@ -689,7 +696,7 @@ silc_server_command_whois_check(SilcServerCommandContext cmd, static void silc_server_command_whois_send_reply(SilcServerCommandContext cmd, SilcClientEntry *clients, - uint32 clients_count, + SilcUInt32 clients_count, int count, const char *nickname, SilcClientID **client_ids) @@ -700,7 +707,7 @@ silc_server_command_whois_send_reply(SilcServerCommandContext cmd, SilcBuffer packet, idp, channels; SilcClientEntry entry; SilcCommandStatus status; - uint16 ident = silc_command_get_ident(cmd->payload); + SilcUInt16 ident = silc_command_get_ident(cmd->payload); char nh[256], uh[256]; unsigned char idle[4], mode[4]; unsigned char *fingerprint; @@ -823,7 +830,7 @@ silc_server_command_whois_send_router(SilcServerCommandContext cmd) { SilcServer server = cmd->server; SilcBuffer tmpbuf; - uint16 old_ident; + SilcUInt16 old_ident; old_ident = silc_command_get_ident(cmd->payload); silc_command_set_ident(cmd->payload, ++server->cmd_ident); @@ -853,7 +860,7 @@ silc_server_command_whois_process(SilcServerCommandContext cmd) int count = 0; SilcClientEntry *clients = NULL, entry; SilcClientID **client_id = NULL; - uint32 client_id_count = 0, clients_count = 0; + SilcUInt32 client_id_count = 0, clients_count = 0; int i, ret = 0; bool check_global = FALSE; @@ -1003,7 +1010,7 @@ silc_server_command_whowas_parse(SilcServerCommandContext cmd, int *count) { unsigned char *tmp; - uint32 len; + SilcUInt32 len; tmp = silc_argument_get_arg_type(cmd->args, 1, &len); if (!tmp) { @@ -1028,7 +1035,7 @@ silc_server_command_whowas_parse(SilcServerCommandContext cmd, static char silc_server_command_whowas_check(SilcServerCommandContext cmd, SilcClientEntry *clients, - uint32 clients_count) + SilcUInt32 clients_count) { SilcServer server = cmd->server; int i; @@ -1039,7 +1046,7 @@ silc_server_command_whowas_check(SilcServerCommandContext cmd, if (!entry->nickname || !entry->username) { SilcBuffer tmpbuf; - uint16 old_ident; + SilcUInt16 old_ident; if (!entry->router) continue; @@ -1059,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); @@ -1073,40 +1079,57 @@ silc_server_command_whowas_check(SilcServerCommandContext cmd, static void silc_server_command_whowas_send_reply(SilcServerCommandContext cmd, SilcClientEntry *clients, - uint32 clients_count) + SilcUInt32 clients_count) { 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; + SilcUInt16 ident = silc_command_get_ident(cmd->payload); 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); @@ -1147,13 +1170,9 @@ silc_server_command_whowas_send_reply(SilcServerCommandContext cmd, 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 @@ -1163,7 +1182,7 @@ silc_server_command_whowas_process(SilcServerCommandContext cmd) char *nick = NULL, *server_name = NULL; int count = 0; SilcClientEntry *clients = NULL; - uint32 clients_count = 0; + SilcUInt32 clients_count = 0; int ret = 0; bool check_global = FALSE; @@ -1175,7 +1194,7 @@ silc_server_command_whowas_process(SilcServerCommandContext cmd) server->server_type == SILC_SERVER && !cmd->pending && !server->standalone) { SilcBuffer tmpbuf; - uint16 old_ident; + SilcUInt16 old_ident; old_ident = silc_command_get_ident(cmd->payload); silc_command_set_ident(cmd->payload, ++server->cmd_ident); @@ -1193,7 +1212,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); @@ -1278,7 +1296,7 @@ silc_server_command_identify_send_router(SilcServerCommandContext cmd) { SilcServer server = cmd->server; SilcBuffer tmpbuf; - uint16 old_ident; + SilcUInt16 old_ident; old_ident = silc_command_get_ident(cmd->payload); silc_command_set_ident(cmd->payload, ++server->cmd_ident); @@ -1303,17 +1321,17 @@ silc_server_command_identify_send_router(SilcServerCommandContext cmd) static int silc_server_command_identify_parse(SilcServerCommandContext cmd, SilcClientEntry **clients, - uint32 *clients_count, + SilcUInt32 *clients_count, SilcServerEntry **servers, - uint32 *servers_count, + SilcUInt32 *servers_count, SilcChannelEntry **channels, - uint32 *channels_count, - uint32 *count) + SilcUInt32 *channels_count, + SilcUInt32 *count) { SilcServer server = cmd->server; unsigned char *tmp; - uint32 len; - uint32 argc = silc_argument_get_arg_num(cmd->args); + SilcUInt32 len; + SilcUInt32 argc = silc_argument_get_arg_num(cmd->args); SilcIDPayload idp; bool check_global = FALSE; void *entry; @@ -1575,12 +1593,12 @@ silc_server_command_identify_parse(SilcServerCommandContext cmd, static bool silc_server_command_identify_check_client(SilcServerCommandContext cmd, SilcClientEntry *clients, - uint32 clients_count) + SilcUInt32 clients_count) { SilcServer server = cmd->server; SilcClientEntry entry; SilcServerResolveContext resolve = NULL, r = NULL; - uint32 resolve_count = 0; + SilcUInt32 resolve_count = 0; int i, k; bool no_res = TRUE; @@ -1712,18 +1730,18 @@ silc_server_command_identify_check_client(SilcServerCommandContext cmd, static void silc_server_command_identify_send_reply(SilcServerCommandContext cmd, SilcClientEntry *clients, - uint32 clients_count, + SilcUInt32 clients_count, SilcServerEntry *servers, - uint32 servers_count, + SilcUInt32 servers_count, SilcChannelEntry *channels, - uint32 channels_count, + SilcUInt32 channels_count, int count) { SilcServer server = cmd->server; int i, k, len, valid_count; SilcBuffer packet, idp; SilcCommandStatus status; - uint16 ident = silc_command_get_ident(cmd->payload); + SilcUInt16 ident = silc_command_get_ident(cmd->payload); char nh[256], uh[256]; SilcSocketConnection hsock; @@ -1751,7 +1769,7 @@ silc_server_command_identify_send_reply(SilcServerCommandContext cmd, SILC_STATUS_ERR_NO_SUCH_NICK, 3, tmp, strlen(tmp)); } else { - tmp = silc_argument_get_arg_type(cmd->args, 5, (uint32 *)&len); + 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); @@ -1906,12 +1924,12 @@ silc_server_command_identify_send_reply(SilcServerCommandContext cmd, static int silc_server_command_identify_process(SilcServerCommandContext cmd) { - uint32 count = 0; + SilcUInt32 count = 0; int ret = 0; SilcClientEntry *clients = NULL; SilcServerEntry *servers = NULL; SilcChannelEntry *channels = NULL; - uint32 clients_count = 0, servers_count = 0, channels_count = 0; + SilcUInt32 clients_count = 0, servers_count = 0, channels_count = 0; /* Parse the IDENTIFY request */ ret = silc_server_command_identify_parse(cmd, @@ -1967,9 +1985,9 @@ SILC_SERVER_CMD_FUNC(nick) SilcServer server = cmd->server; SilcBuffer packet, nidp, oidp = NULL; SilcClientID *new_id; - uint32 nick_len; + SilcUInt32 nick_len; char *nick; - uint16 ident = silc_command_get_ident(cmd->payload); + SilcUInt16 ident = silc_command_get_ident(cmd->payload); int nickfail = 0; if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT) @@ -2059,18 +2077,18 @@ SILC_SERVER_CMD_FUNC(nick) static void silc_server_command_list_send_reply(SilcServerCommandContext cmd, SilcChannelEntry *lch, - uint32 lch_count, + SilcUInt32 lch_count, SilcChannelEntry *gch, - uint32 gch_count) + SilcUInt32 gch_count) { int i, k; SilcBuffer packet, idp; SilcChannelEntry entry; SilcCommandStatus status; - uint16 ident = silc_command_get_ident(cmd->payload); + SilcUInt16 ident = silc_command_get_ident(cmd->payload); char *topic; unsigned char usercount[4]; - uint32 users; + SilcUInt32 users; int valid_lcount = 0, valid_rcount = 0; for (i = 0; i < lch_count; i++) { @@ -2147,7 +2165,7 @@ silc_server_command_list_send_reply(SilcServerCommandContext cmd, memset(usercount, 0, sizeof(usercount)); } else { topic = entry->topic; - users = silc_hash_table_count(entry->user_list); + users = entry->user_count; SILC_PUT32_MSB(users, usercount); } @@ -2178,9 +2196,9 @@ SILC_SERVER_CMD_FUNC(list) SilcServer server = cmd->server; SilcChannelID *channel_id = NULL; unsigned char *tmp; - uint32 tmp_len; + SilcUInt32 tmp_len; SilcChannelEntry *lchannels = NULL, *gchannels = NULL; - uint32 lch_count = 0, gch_count = 0; + SilcUInt32 lch_count = 0, gch_count = 0; SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_LIST, cmd, 0, 1); @@ -2189,7 +2207,7 @@ SILC_SERVER_CMD_FUNC(list) if (!cmd->pending && server->server_type == SILC_SERVER && !server->standalone) { SilcBuffer tmpbuf; - uint16 old_ident; + SilcUInt16 old_ident; old_ident = silc_command_get_ident(cmd->payload); silc_command_set_ident(cmd->payload, ++server->cmd_ident); @@ -2252,8 +2270,8 @@ SILC_SERVER_CMD_FUNC(topic) SilcChannelClientEntry chl; SilcBuffer packet, idp; unsigned char *tmp; - uint32 argc, tmp_len; - uint16 ident = silc_command_get_ident(cmd->payload); + SilcUInt32 argc, tmp_len; + SilcUInt16 ident = silc_command_get_ident(cmd->payload); SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_TOPIC, cmd, 1, 2); @@ -2374,8 +2392,8 @@ SILC_SERVER_CMD_FUNC(invite) SilcIDListData idata; SilcBuffer idp, idp2, packet; unsigned char *tmp, *add, *del; - uint32 len; - uint16 ident = silc_command_get_ident(cmd->payload); + SilcUInt32 len; + SilcUInt16 ident = silc_command_get_ident(cmd->payload); SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_INVITE, cmd, 1, 4); @@ -2619,7 +2637,7 @@ SILC_SERVER_CMD_FUNC(quit) SilcSocketConnection sock = cmd->sock; QuitInternal q; unsigned char *tmp = NULL; - uint32 len = 0; + SilcUInt32 len = 0; SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_QUIT, cmd, 0, 1); @@ -2656,7 +2674,7 @@ SILC_SERVER_CMD_FUNC(kill) SilcClientEntry remote_client; SilcClientID *client_id; unsigned char *tmp, *comment; - uint32 tmp_len, tmp_len2; + SilcUInt32 tmp_len, tmp_len2; bool local; SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_KILL, cmd, 1, 2); @@ -2780,9 +2798,9 @@ SILC_SERVER_CMD_FUNC(info) SilcServer server = cmd->server; SilcBuffer packet, idp; unsigned char *tmp; - uint32 tmp_len; + SilcUInt32 tmp_len; char *dest_server, *server_info = NULL, *server_name; - uint16 ident = silc_command_get_ident(cmd->payload); + SilcUInt16 ident = silc_command_get_ident(cmd->payload); SilcServerEntry entry = NULL; SilcServerID *server_id = NULL; @@ -2831,10 +2849,10 @@ SILC_SERVER_CMD_FUNC(info) 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; @@ -2853,7 +2871,7 @@ SILC_SERVER_CMD_FUNC(info) server->server_type != SILC_SERVER && entry && !entry->server_info) { /* Send to the server */ SilcBuffer tmpbuf; - uint16 old_ident; + SilcUInt16 old_ident; old_ident = silc_command_get_ident(cmd->payload); silc_command_set_ident(cmd->payload, ++server->cmd_ident); @@ -2877,7 +2895,7 @@ SILC_SERVER_CMD_FUNC(info) if (!entry && !cmd->pending && !server->standalone) { /* Send to the primary router */ SilcBuffer tmpbuf; - uint16 old_ident; + SilcUInt16 old_ident; old_ident = silc_command_get_ident(cmd->payload); silc_command_set_ident(cmd->payload, ++server->cmd_ident); @@ -2938,7 +2956,7 @@ SILC_SERVER_CMD_FUNC(ping) SilcServerCommandContext cmd = (SilcServerCommandContext)context; SilcServer server = cmd->server; SilcServerID *id; - uint32 len; + SilcUInt32 len; unsigned char *tmp; SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_INFO, cmd, 1, 2); @@ -2980,18 +2998,18 @@ static void silc_server_command_join_channel(SilcServer server, SilcClientID *client_id, bool created, bool create_key, - uint32 umode, + SilcUInt32 umode, const unsigned char *auth, - uint32 auth_len) + SilcUInt32 auth_len) { SilcSocketConnection sock = cmd->sock; unsigned char *tmp; - uint32 tmp_len, user_count; + SilcUInt32 tmp_len, user_count; unsigned char *passphrase = NULL, mode[4], tmp2[4], tmp3[4]; SilcClientEntry client; SilcChannelClientEntry chl; SilcBuffer reply, chidp, clidp, keyp = NULL, user_list, mode_list; - uint16 ident = silc_command_get_ident(cmd->payload); + SilcUInt16 ident = silc_command_get_ident(cmd->payload); char check[512], check2[512]; bool founder = FALSE; bool resolve; @@ -3044,7 +3062,7 @@ static void silc_server_command_join_channel(SilcServer server, void *auth_data = (channel->founder_method == SILC_AUTH_PASSWORD ? (void *)channel->founder_passwd : (void *)channel->founder_key); - uint32 auth_data_len = (channel->founder_method == SILC_AUTH_PASSWORD ? + SilcUInt32 auth_data_len = (channel->founder_method == SILC_AUTH_PASSWORD ? channel->founder_passwd_len : 0); /* Check whether the client is to become founder */ @@ -3123,10 +3141,8 @@ static void silc_server_command_join_channel(SilcServer server, if (channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) { /* Get passphrase */ tmp = silc_argument_get_arg_type(cmd->args, 3, &tmp_len); - if (tmp) { - passphrase = silc_calloc(tmp_len, sizeof(*passphrase)); - memcpy(passphrase, tmp, tmp_len); - } + if (tmp) + passphrase = silc_memdup(tmp, tmp_len); if (!passphrase || !channel->passphrase || memcmp(passphrase, channel->passphrase, strlen(channel->passphrase))) { @@ -3169,6 +3185,7 @@ static void silc_server_command_join_channel(SilcServer server, chl->channel = channel; silc_hash_table_add(channel->user_list, client, chl); silc_hash_table_add(client->channels, channel, chl); + channel->user_count++; /* Get users on the channel */ silc_server_get_users_on_channel(server, channel, &user_list, &mode_list, @@ -3247,24 +3264,24 @@ static void silc_server_command_join_channel(SilcServer server, /* 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); @@ -3286,10 +3303,10 @@ SILC_SERVER_CMD_FUNC(join) SilcServerCommandContext cmd = (SilcServerCommandContext)context; SilcServer server = cmd->server; unsigned char *auth; - uint32 tmp_len, auth_len; + SilcUInt32 tmp_len, auth_len; char *tmp, *channel_name = NULL, *cipher, *hmac; SilcChannelEntry channel; - uint32 umode = 0; + SilcUInt32 umode = 0; bool created = FALSE, create_key = TRUE; SilcClientID *client_id; @@ -3367,7 +3384,7 @@ SILC_SERVER_CMD_FUNC(join) or joins the client to it). */ if (server->server_type != SILC_ROUTER) { SilcBuffer tmpbuf; - uint16 old_ident; + SilcUInt16 old_ident; /* If this is pending command callback then we've resolved it and it didn't work, return since we've notified the @@ -3391,6 +3408,8 @@ 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); + silc_buffer_free(tmpbuf); goto out; } @@ -3454,7 +3473,8 @@ 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 && @@ -3487,8 +3507,8 @@ SILC_SERVER_CMD_FUNC(motd) SilcServer server = cmd->server; SilcBuffer packet, idp; char *motd, *dest_server; - uint32 motd_len; - uint16 ident = silc_command_get_ident(cmd->payload); + SilcUInt32 motd_len; + SilcUInt16 ident = silc_command_get_ident(cmd->payload); SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_MOTD, cmd, 1, 1); @@ -3505,10 +3525,10 @@ SILC_SERVER_CMD_FUNC(motd) 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; @@ -3543,7 +3563,7 @@ SILC_SERVER_CMD_FUNC(motd) entry && !entry->motd) { /* Send to the server */ SilcBuffer tmpbuf; - uint16 old_ident; + SilcUInt16 old_ident; old_ident = silc_command_get_ident(cmd->payload); silc_command_set_ident(cmd->payload, ++server->cmd_ident); @@ -3567,7 +3587,7 @@ SILC_SERVER_CMD_FUNC(motd) if (!entry && !cmd->pending && !server->standalone) { /* Send to the primary router */ SilcBuffer tmpbuf; - uint16 old_ident; + SilcUInt16 old_ident; old_ident = silc_command_get_ident(cmd->payload); silc_command_set_ident(cmd->payload, ++server->cmd_ident); @@ -3622,8 +3642,8 @@ SILC_SERVER_CMD_FUNC(umode) SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data; SilcBuffer packet; unsigned char *tmp_mask; - uint32 mask; - uint16 ident = silc_command_get_ident(cmd->payload); + SilcUInt32 mask; + SilcUInt16 ident = silc_command_get_ident(cmd->payload); if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT) goto out; @@ -3709,7 +3729,7 @@ SILC_SERVER_CMD_FUNC(umode) int silc_server_check_cmode_rights(SilcChannelEntry channel, SilcChannelClientEntry client, - uint32 mode) + SilcUInt32 mode) { int is_op = client->mode & SILC_CHANNEL_UMODE_CHANOP; int is_fo = client->mode & SILC_CHANNEL_UMODE_CHANFO; @@ -3787,8 +3807,8 @@ SILC_SERVER_CMD_FUNC(cmode) SilcBuffer packet, cidp; unsigned char *tmp, *tmp_id, *tmp_mask; char *cipher = NULL, *hmac = NULL, *passphrase = NULL; - uint32 mode_mask, tmp_len, tmp_len2; - uint16 ident = silc_command_get_ident(cmd->payload); + SilcUInt32 mode_mask, tmp_len, tmp_len2; + SilcUInt16 ident = silc_command_get_ident(cmd->payload); SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_CMODE, cmd, 2, 7); @@ -3859,25 +3879,25 @@ 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; + SilcUInt32 user_limit; /* Get user limit */ tmp = silc_argument_get_arg_type(cmd->args, 3, NULL); @@ -4087,9 +4107,7 @@ SILC_SERVER_CMD_FUNC(cmode) if (channel->founder_method == SILC_AUTH_PASSWORD) { tmp = silc_auth_get_data(auth, &tmp_len); - channel->founder_passwd = - silc_calloc(tmp_len + 1, sizeof(*channel->founder_passwd)); - memcpy(channel->founder_passwd, tmp, tmp_len); + channel->founder_passwd = silc_memdup(tmp, tmp_len); channel->founder_passwd_len = tmp_len; } else { /* Verify the payload before setting the mode */ @@ -4171,9 +4189,9 @@ SILC_SERVER_CMD_FUNC(cumode) SilcChannelClientEntry chl; SilcBuffer packet, idp; unsigned char *tmp_id, *tmp_ch_id, *tmp_mask; - uint32 target_mask, sender_mask = 0, tmp_len, tmp_ch_len; + SilcUInt32 target_mask, sender_mask = 0, tmp_len, tmp_ch_len; int notify = FALSE; - uint16 ident = silc_command_get_ident(cmd->payload); + SilcUInt16 ident = silc_command_get_ident(cmd->payload); SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_CUMODE, cmd, 3, 4); @@ -4283,7 +4301,7 @@ SILC_SERVER_CMD_FUNC(cumode) if (!(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) { /* The client tries to claim the founder rights. */ unsigned char *tmp_auth; - uint32 tmp_auth_len, auth_len; + SilcUInt32 tmp_auth_len, auth_len; void *auth; if (target_client != client) { @@ -4418,7 +4436,7 @@ SILC_SERVER_CMD_FUNC(kick) SilcChannelEntry channel; SilcChannelClientEntry chl; SilcBuffer idp; - uint32 tmp_len, target_idp_len; + SilcUInt32 tmp_len, target_idp_len; unsigned char *tmp, *comment, *target_idp; SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_LEAVE, cmd, 1, 3); @@ -4561,9 +4579,10 @@ SILC_SERVER_CMD_FUNC(oper) SilcServer server = cmd->server; SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data; unsigned char *username, *auth; - uint32 tmp_len; - SilcServerConfigSectionAdminConnection *admin; + SilcUInt32 tmp_len; + SilcServerConfigAdmin *admin; SilcIDListData idata = (SilcIDListData)client; + bool result = FALSE; SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_OPER, cmd, 1, 2); @@ -4579,10 +4598,10 @@ SILC_SERVER_CMD_FUNC(oper) } /* 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, @@ -4599,10 +4618,18 @@ SILC_SERVER_CMD_FUNC(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; @@ -4639,9 +4666,10 @@ SILC_SERVER_CMD_FUNC(silcoper) SilcServer server = cmd->server; SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data; unsigned char *username, *auth; - uint32 tmp_len; - SilcServerConfigSectionAdminConnection *admin; + SilcUInt32 tmp_len; + SilcServerConfigAdmin *admin; SilcIDListData idata = (SilcIDListData)client; + bool result = FALSE; SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_SILCOPER, cmd, 1, 2); @@ -4663,10 +4691,10 @@ SILC_SERVER_CMD_FUNC(silcoper) } /* 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, @@ -4683,11 +4711,19 @@ SILC_SERVER_CMD_FUNC(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; } @@ -4723,8 +4759,8 @@ SILC_SERVER_CMD_FUNC(connect) SilcServer server = cmd->server; SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data; unsigned char *tmp, *host; - uint32 tmp_len; - uint32 port = SILC_PORT; + SilcUInt32 tmp_len; + SilcUInt32 port = SILC_PORT; SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_CONNECT, cmd, 1, 2); @@ -4782,8 +4818,8 @@ SILC_SERVER_CMD_FUNC(ban) SilcChannelClientEntry chl; SilcChannelID *channel_id = NULL; unsigned char *id, *add, *del; - uint32 id_len, tmp_len; - uint16 ident = silc_command_get_ident(cmd->payload); + SilcUInt32 id_len, tmp_len; + SilcUInt16 ident = silc_command_get_ident(cmd->payload); if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT) goto out; @@ -4888,7 +4924,7 @@ SILC_SERVER_CMD_FUNC(ban) 2, id, id_len, 3, channel->ban_list, channel->ban_list ? - strlen(channel->ban_list) : 0); + strlen(channel->ban_list) -1 : 0); silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0, packet->data, packet->len, FALSE); @@ -4909,9 +4945,9 @@ SILC_SERVER_CMD_FUNC(close) SilcServerEntry server_entry; SilcSocketConnection sock; unsigned char *tmp; - uint32 tmp_len; + SilcUInt32 tmp_len; unsigned char *name; - uint32 port = SILC_PORT; + SilcUInt32 port = SILC_PORT; SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_CLOSE, cmd, 1, 2); @@ -5014,7 +5050,7 @@ SILC_SERVER_CMD_FUNC(leave) SilcClientEntry id_entry = (SilcClientEntry)cmd->sock->user_data; SilcChannelID *id = NULL; SilcChannelEntry channel; - uint32 len; + SilcUInt32 len; unsigned char *tmp; SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_LEAVE, cmd, 1, 2); @@ -5095,12 +5131,12 @@ SILC_SERVER_CMD_FUNC(users) SilcChannelID *id = NULL; SilcBuffer packet, idp; unsigned char *channel_id; - uint32 channel_id_len; + SilcUInt32 channel_id_len; SilcBuffer client_id_list; SilcBuffer client_mode_list; unsigned char lc[4]; - uint32 list_count = 0; - uint16 ident = silc_command_get_ident(cmd->payload); + SilcUInt32 list_count = 0; + SilcUInt16 ident = silc_command_get_ident(cmd->payload); char *channel_name; SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_USERS, cmd, 1, 2); @@ -5235,9 +5271,9 @@ SILC_SERVER_CMD_FUNC(getkey) SilcClientID *client_id = NULL; SilcServerID *server_id = NULL; SilcIDPayload idp = NULL; - uint16 ident = silc_command_get_ident(cmd->payload); + SilcUInt16 ident = silc_command_get_ident(cmd->payload); unsigned char *tmp, *pkdata; - uint32 tmp_len, pklen; + SilcUInt32 tmp_len, pklen; SilcBuffer pk = NULL; SilcIdType id_type; SilcPublicKey public_key; @@ -5273,7 +5309,7 @@ SILC_SERVER_CMD_FUNC(getkey) (client && !client->connection && !cmd->pending) || (client && !client->data.public_key && !cmd->pending)) { SilcBuffer tmpbuf; - uint16 old_ident; + SilcUInt16 old_ident; SilcSocketConnection dest_sock; dest_sock = silc_server_get_client_route(server, NULL, 0, @@ -5344,7 +5380,7 @@ SILC_SERVER_CMD_FUNC(getkey) (server_entry && !server_entry->data.public_key && !cmd->pending && !server->standalone))) { SilcBuffer tmpbuf; - uint16 old_ident; + SilcUInt16 old_ident; old_ident = silc_command_get_ident(cmd->payload); silc_command_set_ident(cmd->payload, ++server->cmd_ident); @@ -5360,7 +5396,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;