X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=blobdiff_plain;f=apps%2Fsilcd%2Fcommand_reply.c;h=a72e6c206a8ccdef7d0f727f6fe7ec6fbbd94fba;hp=c524111bd2389923bebafc479f4152a6692f90a7;hb=382d15d447b7a95390decfa783836ae4fe255b3d;hpb=ed3133837d3466b1d9eb15278677d82971bbd35f diff --git a/apps/silcd/command_reply.c b/apps/silcd/command_reply.c index c524111b..a72e6c20 100644 --- a/apps/silcd/command_reply.c +++ b/apps/silcd/command_reply.c @@ -24,13 +24,18 @@ #include "command_reply.h" /* All functions that call the COMMAND_CHECK_STATUS macros must have - out: goto label. */ - -#define COMMAND_CHECK_STATUS \ -do { \ - SILC_LOG_DEBUG(("Start")); \ - if (!silc_command_get_status(cmd->payload, &status, &error)) \ - goto out; \ + out: and err: goto labels. */ + +#define COMMAND_CHECK_STATUS \ +do { \ + SILC_LOG_DEBUG(("Start")); \ + if (!silc_command_get_status(cmd->payload, &status, &error)) { \ + if (SILC_STATUS_IS_ERROR(status)) \ + goto out; \ + if (status == SILC_STATUS_LIST_END) \ + goto out; \ + goto err; \ + } \ } while(0) /* Server command reply list. Not all commands have reply function as @@ -47,6 +52,7 @@ SilcServerCommandReply silc_command_reply_list[] = SILC_SERVER_CMD_REPLY(users, USERS), SILC_SERVER_CMD_REPLY(getkey, GETKEY), SILC_SERVER_CMD_REPLY(list, LIST), + SILC_SERVER_CMD_REPLY(watch, WATCH), { NULL, 0 }, }; @@ -61,7 +67,6 @@ void silc_server_command_reply_process(SilcServer server, SilcServerCommandReplyContext ctx; SilcCommandPayload payload; SilcCommand command; - SilcUInt16 ident; SILC_LOG_DEBUG(("Start")); @@ -80,16 +85,22 @@ void silc_server_command_reply_process(SilcServer server, ctx->sock = silc_socket_dup(sock); ctx->payload = payload; ctx->args = silc_command_get_args(ctx->payload); - ident = silc_command_get_ident(ctx->payload); + ctx->ident = silc_command_get_ident(ctx->payload); + command = silc_command_get(ctx->payload); + + /* Client is not allowed to send reply to all commands */ + if (sock->type == SILC_SOCKET_TYPE_CLIENT && + command != SILC_COMMAND_WHOIS) { + silc_server_command_reply_free(ctx); + return; + } /* Check for pending commands and mark to be exeucted */ ctx->callbacks = - silc_server_command_pending_check(server, ctx, - silc_command_get(ctx->payload), - ident, &ctx->callbacks_count); + silc_server_command_pending_check(server, command, + ctx->ident, &ctx->callbacks_count); /* Execute command reply */ - command = silc_command_get(ctx->payload); for (cmd = silc_command_reply_list; cmd->cb; cmd++) if (cmd->cmd == command) break; @@ -115,21 +126,53 @@ void silc_server_command_reply_free(SilcServerCommandReplyContext cmd) } } +static void +silc_server_command_process_error(SilcServerCommandReplyContext cmd, + SilcStatus error) +{ + SilcServer server = cmd->server; + + /* If we received notify for invalid ID we'll remove the ID if we + have it cached. */ + if (error == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID && + cmd->sock->type == SILC_SOCKET_TYPE_ROUTER) { + SilcClientEntry client; + SilcUInt32 tmp_len; + unsigned char *tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len); + if (tmp) { + SilcClientID *client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL); + if (client_id) { + SILC_LOG_DEBUG(("Received invalid client ID notification, deleting " + "the entry from cache")); + client = silc_idlist_find_client_by_id(server->global_list, + client_id, FALSE, NULL); + if (client) { + silc_server_remove_from_channels(server, NULL, client, TRUE, + NULL, TRUE, FALSE); + silc_idlist_del_data(client); + silc_idlist_del_client(server->global_list, client); + } + silc_free(client_id); + } + } + } +} + /* Caches the received WHOIS information. */ static char silc_server_command_reply_whois_save(SilcServerCommandReplyContext cmd) { SilcServer server = cmd->server; - unsigned char *tmp, *id_data; + unsigned char *tmp, *id_data, *umodes; char *nickname, *username, *realname, *servername = NULL; unsigned char *fingerprint; SilcClientID *client_id; SilcClientEntry client; + SilcIDCacheEntry cache = NULL; char global = FALSE; char *nick; - SilcUInt32 mode = 0, len, id_len, flen; - int expire = 0; + SilcUInt32 mode = 0, len, len2, id_len, flen; id_data = silc_argument_get_arg_type(cmd->args, 2, &id_len); nickname = silc_argument_get_arg_type(cmd->args, 3, &len); @@ -173,8 +216,7 @@ silc_server_command_reply_whois_save(SilcServerCommandReplyContext cmd) client = silc_idlist_add_client(server->global_list, nick, strdup(username), strdup(realname), client_id, - cmd->sock->user_data, NULL, - time(NULL) + 300); + cmd->sock->user_data, NULL, 0); if (!client) { SILC_LOG_ERROR(("Could not add new client to the ID Cache")); return FALSE; @@ -210,22 +252,72 @@ silc_server_command_reply_whois_save(SilcServerCommandReplyContext cmd) client->data.status |= SILC_IDLIST_STATUS_RESOLVED; client->data.status &= ~SILC_IDLIST_STATUS_RESOLVING; - /* If client is global and is not on any channel then add that we'll - expire the entry after a while. */ - if (global && !silc_hash_table_count(client->channels) && - server->server_type == SILC_SERVER) - expire = time(NULL) + 300; - /* Create new cache entry */ silc_idcache_add(global ? server->global_list->clients : server->local_list->clients, nick, client->id, - client, expire, NULL); + client, 0, NULL); silc_free(client_id); } + /* Save channel list if it was sent to us */ + if (server->server_type == SILC_SERVER) { + tmp = silc_argument_get_arg_type(cmd->args, 6, &len); + umodes = silc_argument_get_arg_type(cmd->args, 10, &len2); + if (tmp && umodes) { + SilcBufferStruct channels_buf, umodes_buf; + silc_buffer_set(&channels_buf, tmp, len); + silc_buffer_set(&umodes_buf, umodes, len2); + silc_server_save_user_channels(server, cmd->sock, client, &channels_buf, + &umodes_buf); + } else { + silc_server_save_user_channels(server, cmd->sock, client, NULL, NULL); + } + + /* If client is global and is not on any channel then add that we'll + expire the entry after a while. */ + if (global) { + silc_idlist_find_client_by_id(server->global_list, client->id, + FALSE, &cache); + if (!silc_hash_table_count(client->channels)) + cache->expire = time(NULL) + 300; + else + cache->expire = 0; + } + } + if (fingerprint && flen == sizeof(client->data.fingerprint)) memcpy(client->data.fingerprint, fingerprint, flen); + /* Take Requested Attributes if set. */ + tmp = silc_argument_get_arg_type(cmd->args, 11, &len); + if (tmp) { + silc_free(client->attrs); + client->attrs = silc_memdup(tmp, len); + client->attrs_len = len; + } + + return TRUE; +} + +/* Handle requested attributes reply in WHOIS from client */ + +static char +silc_server_command_reply_whois_save_client(SilcServerCommandReplyContext cmd) +{ + unsigned char *tmp; + SilcUInt32 len; + SilcClientEntry client = cmd->sock->user_data; + + /* Take Requested Attributes if set. */ + tmp = silc_argument_get_arg_type(cmd->args, 11, &len); + if (tmp && client) { + silc_free(client->attrs); + client->attrs = silc_memdup(tmp, len); + client->attrs_len = len; + } + + client->data.status &= ~SILC_IDLIST_STATUS_RESOLVING; + return TRUE; } @@ -238,13 +330,17 @@ silc_server_command_reply_whois_save(SilcServerCommandReplyContext cmd) SILC_SERVER_CMD_REPLY_FUNC(whois) { SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context; - SilcServer server = cmd->server; - SilcCommandStatus status, error; + SilcStatus status, error; COMMAND_CHECK_STATUS; - if (!silc_server_command_reply_whois_save(cmd)) - goto out; + if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT) { + if (!silc_server_command_reply_whois_save(cmd)) + goto out; + } else { + if (!silc_server_command_reply_whois_save_client(cmd)) + goto out; + } /* Pending callbacks are not executed if this was an list entry */ if (status != SILC_STATUS_OK && @@ -254,32 +350,14 @@ SILC_SERVER_CMD_REPLY_FUNC(whois) } out: - /* If we received notify for invalid ID we'll remove the ID if we - have it cached. */ - if (error == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID && - cmd->sock->type == SILC_SOCKET_TYPE_ROUTER) { - SilcClientEntry client; - SilcUInt32 tmp_len; - unsigned char *tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len); - if (tmp) { - SilcClientID *client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL); - if (client_id) { - SILC_LOG_DEBUG(("Received invalid client ID notification, deleting " - "the entry from cache")); - client = silc_idlist_find_client_by_id(server->global_list, - client_id, FALSE, NULL); - if (client) { - silc_server_remove_from_channels(server, NULL, client, TRUE, - NULL, TRUE); - silc_idlist_del_client(server->global_list, client); - } - silc_free(client_id); - } - } - } - + silc_server_command_process_error(cmd, error); SILC_SERVER_PENDING_EXEC(cmd, SILC_COMMAND_WHOIS); silc_server_command_reply_free(cmd); + return; + + err: + silc_server_command_process_error(cmd, error); + silc_server_command_reply_free(cmd); } /* Caches the received WHOWAS information for a short period of time. */ @@ -341,6 +419,8 @@ silc_server_command_reply_whowas_save(SilcServerCommandReplyContext cmd) return FALSE; } + client->data.status |= SILC_IDLIST_STATUS_RESOLVED; + client->data.status &= ~SILC_IDLIST_STATUS_RESOLVING; client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED; client->servername = servername; } else { @@ -351,10 +431,13 @@ silc_server_command_reply_whowas_save(SilcServerCommandReplyContext cmd) silc_free(client->nickname); silc_free(client->username); + silc_free(client->servername); client->nickname = nick; client->username = strdup(username); client->servername = servername; + client->data.status |= SILC_IDLIST_STATUS_RESOLVED; + client->data.status &= ~SILC_IDLIST_STATUS_RESOLVING; /* Remove the old cache entry and create a new one */ silc_idcache_del_by_context(global ? server->global_list->clients : @@ -364,6 +447,17 @@ silc_server_command_reply_whowas_save(SilcServerCommandReplyContext cmd) client, 0, NULL); } + /* If client is global and is not on any channel then add that we'll + expire the entry after a while. */ + if (global) { + silc_idlist_find_client_by_id(server->global_list, client->id, + FALSE, &cache); + if (!silc_hash_table_count(client->channels)) + cache->expire = SILC_ID_CACHE_EXPIRE_DEF; + else + cache->expire = 0; + } + silc_free(client_id); return TRUE; @@ -375,7 +469,7 @@ silc_server_command_reply_whowas_save(SilcServerCommandReplyContext cmd) SILC_SERVER_CMD_REPLY_FUNC(whowas) { SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context; - SilcCommandStatus status, error; + SilcStatus status, error; COMMAND_CHECK_STATUS; @@ -390,8 +484,14 @@ SILC_SERVER_CMD_REPLY_FUNC(whowas) } out: + silc_server_command_process_error(cmd, error); SILC_SERVER_PENDING_EXEC(cmd, SILC_COMMAND_WHOWAS); silc_server_command_reply_free(cmd); + return; + + err: + silc_server_command_process_error(cmd, error); + silc_server_command_reply_free(cmd); } /* Caches the received IDENTIFY information. */ @@ -457,8 +557,8 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd) global. */ client = silc_idlist_add_client(server->global_list, nick, info ? strdup(info) : NULL, NULL, - client_id, cmd->sock->user_data, NULL, - time(NULL) + 300); + client_id, cmd->sock->user_data, + NULL, time(NULL) + 300); if (!client) { SILC_LOG_ERROR(("Could not add new client to the ID Cache")); goto error; @@ -492,18 +592,24 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd) client->data.status &= ~SILC_IDLIST_STATUS_RESOLVING; if (name) { - /* If client is global and is not on any channel then add that we'll - expire the entry after a while. */ - if (global && !silc_hash_table_count(client->channels) && - server->server_type == SILC_SERVER) - expire = time(NULL) + 300; - /* Add new cache entry */ silc_idcache_add(global ? server->global_list->clients : server->local_list->clients, nick, client->id, client, expire, NULL); } + /* If client is global and is not on any channel then add that we'll + expire the entry after a while. */ + if (global && server->server_type == SILC_SERVER) { + SilcIDCacheEntry cache = NULL; + silc_idlist_find_client_by_id(server->global_list, client->id, + FALSE, &cache); + if (!silc_hash_table_count(client->channels)) + cache->expire = time(NULL) + 300; + else + cache->expire = 0; + } + silc_free(client_id); } @@ -533,7 +639,8 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd) /* We don't have that server anywhere, add it. */ server_entry = silc_idlist_add_server(server->global_list, strdup(name), 0, - server_id, NULL, NULL); + server_id, server->router, + SILC_PRIMARY_ROUTE(server)); if (!server_entry) { silc_free(server_id); goto error; @@ -568,7 +675,7 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd) if (server->server_type != SILC_SERVER) goto error; - /* We don't have that server anywhere, add it. */ + /* We don't have that channel anywhere, add it. */ channel = silc_idlist_add_channel(server->global_list, strdup(name), SILC_CHANNEL_MODE_NONE, channel_id, server->router, NULL, NULL, 0); @@ -599,8 +706,7 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd) SILC_SERVER_CMD_REPLY_FUNC(identify) { SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context; - SilcServer server = cmd->server; - SilcCommandStatus status, error; + SilcStatus status, error; COMMAND_CHECK_STATUS; @@ -615,32 +721,14 @@ SILC_SERVER_CMD_REPLY_FUNC(identify) } out: - /* If we received notify for invalid ID we'll remove the ID if we - have it cached. */ - if (error == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID && - cmd->sock->type == SILC_SOCKET_TYPE_ROUTER) { - SilcClientEntry client; - SilcUInt32 tmp_len; - unsigned char *tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len); - if (tmp) { - SilcClientID *client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL); - if (client_id) { - SILC_LOG_DEBUG(("Received invalid client ID notification, deleting " - "the entry from cache")); - client = silc_idlist_find_client_by_id(server->global_list, - client_id, FALSE, NULL); - if (client) { - silc_server_remove_from_channels(server, NULL, client, TRUE, - NULL, TRUE); - silc_idlist_del_client(server->global_list, client); - } - silc_free(client_id); - } - } - } - + silc_server_command_process_error(cmd, error); SILC_SERVER_PENDING_EXEC(cmd, SILC_COMMAND_IDENTIFY); silc_server_command_reply_free(cmd); + return; + + err: + silc_server_command_process_error(cmd, error); + silc_server_command_reply_free(cmd); } /* Received reply fro INFO command. Cache the server and its information */ @@ -649,7 +737,7 @@ SILC_SERVER_CMD_REPLY_FUNC(info) { SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context; SilcServer server = cmd->server; - SilcCommandStatus status, error; + SilcStatus status, error; SilcServerEntry entry; SilcServerID *server_id; SilcUInt32 tmp_len; @@ -679,7 +767,8 @@ SILC_SERVER_CMD_REPLY_FUNC(info) /* Add the server to global list */ server_id = silc_id_dup(server_id, SILC_ID_SERVER); entry = silc_idlist_add_server(server->global_list, name, 0, - server_id, NULL, NULL); + server_id, cmd->sock->user_data, + cmd->sock); if (!entry) { silc_free(server_id); goto out; @@ -697,6 +786,7 @@ SILC_SERVER_CMD_REPLY_FUNC(info) out: SILC_SERVER_PENDING_EXEC(cmd, SILC_COMMAND_INFO); + err: silc_server_command_reply_free(cmd); } @@ -706,7 +796,7 @@ SILC_SERVER_CMD_REPLY_FUNC(motd) { SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context; SilcServer server = cmd->server; - SilcCommandStatus status, error; + SilcStatus status, error; SilcServerEntry entry = NULL; SilcServerID *server_id; SilcUInt32 tmp_len; @@ -740,6 +830,7 @@ SILC_SERVER_CMD_REPLY_FUNC(motd) out: SILC_SERVER_PENDING_EXEC(cmd, SILC_COMMAND_MOTD); + err: silc_server_command_reply_free(cmd); if (entry) @@ -755,7 +846,7 @@ SILC_SERVER_CMD_REPLY_FUNC(join) SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context; SilcServer server = cmd->server; SilcIDCacheEntry cache = NULL; - SilcCommandStatus status, error; + SilcStatus status, error; SilcChannelID *id; SilcClientID *client_id = NULL; SilcChannelEntry entry; @@ -765,6 +856,7 @@ SILC_SERVER_CMD_REPLY_FUNC(join) char *channel_name, *tmp; SilcUInt32 mode, created; SilcBuffer keyp = NULL, client_id_list = NULL, client_mode_list = NULL; + SilcPublicKey founder_key = NULL; COMMAND_CHECK_STATUS; @@ -844,6 +936,11 @@ SILC_SERVER_CMD_REPLY_FUNC(join) silc_buffer_pull_tail(client_mode_list, len); silc_buffer_put(client_mode_list, tmp, len); + /* Get founder key */ + tmp = silc_argument_get_arg_type(cmd->args, 15, &len); + if (tmp) + silc_pkcs_public_key_payload_decode(tmp, len, &founder_key); + /* See whether we already have the channel. */ entry = silc_idlist_find_channel_by_name(server->local_list, channel_name, &cache); @@ -869,7 +966,9 @@ SILC_SERVER_CMD_REPLY_FUNC(join) silc_free(id); goto out; } + hmac = NULL; server->stat.my_channels++; + server->stat.channels++; } else { /* The entry exists. */ @@ -883,28 +982,64 @@ SILC_SERVER_CMD_REPLY_FUNC(join) them in the entry */ if (!(mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) && entry->founder_key) { silc_pkcs_public_key_free(entry->founder_key); - silc_free(entry->founder_passwd); - entry->founder_passwd = NULL; + entry->founder_key = NULL; } } - if (entry->hmac_name && hmac) { + if (founder_key) { + if (entry->founder_key) + silc_pkcs_public_key_free(entry->founder_key); + entry->founder_key = founder_key; + founder_key = NULL; + } + + if (entry->hmac_name && (hmac || (!hmac && entry->hmac))) { silc_free(entry->hmac_name); - entry->hmac_name = strdup(silc_hmac_get_name(hmac)); + entry->hmac_name = strdup(silc_hmac_get_name(hmac ? hmac : entry->hmac)); } /* Get the ban list */ tmp = silc_argument_get_arg_type(cmd->args, 8, &len); - if (tmp) { - silc_free(entry->ban_list); - entry->ban_list = silc_memdup(tmp, len); + if (tmp && len > 2) { + SilcArgumentPayload iargs; + SilcUInt16 iargc; + SILC_GET16_MSB(iargc, tmp); + iargs = silc_argument_payload_parse(tmp + 2, len - 2, iargc); + if (iargs) { + /* Delete old ban list */ + if (entry->ban_list) + silc_hash_table_free(entry->ban_list); + entry->ban_list = + silc_hash_table_alloc(0, silc_hash_ptr, + NULL, NULL, NULL, + silc_server_inviteban_destruct, entry, TRUE); + + /* Add new ban list */ + silc_server_inviteban_process(server, entry->ban_list, 0, iargs); + silc_argument_payload_free(iargs); + } } /* Get the invite list */ tmp = silc_argument_get_arg_type(cmd->args, 9, &len); - if (tmp) { - silc_free(entry->invite_list); - entry->invite_list = silc_memdup(tmp, len); + if (tmp && len > 2) { + SilcArgumentPayload iargs; + SilcUInt16 iargc; + SILC_GET16_MSB(iargc, tmp); + iargs = silc_argument_payload_parse(tmp + 2, len - 2, iargc); + if (iargs) { + /* Delete old invite list */ + if (entry->invite_list) + silc_hash_table_free(entry->invite_list); + entry->invite_list = + silc_hash_table_alloc(0, silc_hash_ptr, + NULL, NULL, NULL, + silc_server_inviteban_destruct, entry, TRUE); + + /* Add new invite list */ + silc_server_inviteban_process(server, entry->invite_list, 0, iargs); + silc_argument_payload_free(iargs); + } } /* Get the topic */ @@ -939,12 +1074,17 @@ SILC_SERVER_CMD_REPLY_FUNC(join) silc_server_save_users_on_channel(server, cmd->sock, entry, client_id, client_id_list, client_mode_list, list_count); + entry->users_resolved = TRUE; out: SILC_SERVER_PENDING_EXEC(cmd, SILC_COMMAND_JOIN); + err: + if (hmac) + silc_hmac_free(hmac); silc_free(client_id); silc_server_command_reply_free(cmd); + silc_pkcs_public_key_free(founder_key); if (client_id_list) silc_buffer_free(client_id_list); if (client_mode_list) @@ -957,7 +1097,7 @@ SILC_SERVER_CMD_REPLY_FUNC(stats) { SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context; SilcServer server = cmd->server; - SilcCommandStatus status, error; + SilcStatus status, error; unsigned char *tmp; SilcUInt32 tmp_len; SilcBufferStruct buf; @@ -966,7 +1106,7 @@ SILC_SERVER_CMD_REPLY_FUNC(stats) /* Get statistics structure */ tmp = silc_argument_get_arg_type(cmd->args, 3, &tmp_len); - if (server->server_type == SILC_SERVER && tmp) { + if (server->server_type != SILC_ROUTER && tmp) { silc_buffer_set(&buf, tmp, tmp_len); silc_buffer_unformat(&buf, SILC_STR_UI_INT(NULL), @@ -989,13 +1129,15 @@ SILC_SERVER_CMD_REPLY_FUNC(stats) out: SILC_SERVER_PENDING_EXEC(cmd, SILC_COMMAND_STATS); + err: + silc_server_command_reply_free(cmd); } SILC_SERVER_CMD_REPLY_FUNC(users) { SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context; SilcServer server = cmd->server; - SilcCommandStatus status, error; + SilcStatus status, error; SilcChannelEntry channel; SilcChannelID *channel_id = NULL; SilcBuffer client_id_list; @@ -1027,7 +1169,7 @@ SILC_SERVER_CMD_REPLY_FUNC(users) goto out; idp = silc_id_payload_encode(channel_id, SILC_ID_CHANNEL); - silc_server_send_command(server, server->router->connection, + silc_server_send_command(server, SILC_PRIMARY_ROUTE(server), SILC_COMMAND_IDENTIFY, ++server->cmd_ident, 1, 5, idp->data, idp->len); silc_buffer_free(idp); @@ -1071,12 +1213,16 @@ SILC_SERVER_CMD_REPLY_FUNC(users) client_id_list, client_mode_list, list_count); + channel->global_users = silc_server_channel_has_global(channel); + channel->users_resolved = TRUE; + silc_buffer_free(client_id_list); silc_buffer_free(client_mode_list); out: SILC_SERVER_PENDING_EXEC(cmd, SILC_COMMAND_USERS); silc_free(channel_id); + err: silc_server_command_reply_free(cmd); } @@ -1084,15 +1230,13 @@ SILC_SERVER_CMD_REPLY_FUNC(getkey) { SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context; SilcServer server = cmd->server; - SilcCommandStatus status, error; + SilcStatus status, error; SilcClientEntry client = NULL; SilcServerEntry server_entry = NULL; SilcClientID *client_id = NULL; SilcServerID *server_id = NULL; - SilcSKEPKType type; - unsigned char *tmp, *pk; + unsigned char *tmp; SilcUInt32 len; - SilcUInt16 pk_len; SilcIDPayload idp = NULL; SilcIdType id_type; SilcPublicKey public_key = NULL; @@ -1111,16 +1255,8 @@ SILC_SERVER_CMD_REPLY_FUNC(getkey) if (!tmp) goto out; - /* Decode the public key */ - - SILC_GET16_MSB(pk_len, tmp); - SILC_GET16_MSB(type, tmp + 2); - pk = tmp + 4; - - if (type != SILC_SKE_PK_TYPE_SILC) - goto out; - - if (!silc_pkcs_public_key_decode(pk, pk_len, &public_key)) + /* Decode the public key payload */ + if (!silc_pkcs_public_key_payload_decode(tmp, len, &public_key)) goto out; id_type = silc_id_payload_get_type(idp); @@ -1164,6 +1300,7 @@ SILC_SERVER_CMD_REPLY_FUNC(getkey) silc_free(server_id); if (public_key) silc_pkcs_public_key_free(public_key); + err: silc_server_command_reply_free(cmd); } @@ -1171,7 +1308,7 @@ SILC_SERVER_CMD_REPLY_FUNC(list) { SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context; SilcServer server = cmd->server; - SilcCommandStatus status, error; + SilcStatus status, error; SilcChannelID *channel_id = NULL; SilcChannelEntry channel; SilcIDCacheEntry cache; @@ -1241,5 +1378,19 @@ SILC_SERVER_CMD_REPLY_FUNC(list) out: SILC_SERVER_PENDING_EXEC(cmd, SILC_COMMAND_LIST); silc_free(channel_id); + err: + silc_server_command_reply_free(cmd); +} + +SILC_SERVER_CMD_REPLY_FUNC(watch) +{ + SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context; + SilcStatus status, error; + + COMMAND_CHECK_STATUS; + + out: + SILC_SERVER_PENDING_EXEC(cmd, SILC_COMMAND_WATCH); + err: silc_server_command_reply_free(cmd); }