}
}
-static void
+void
silc_client_command_reply_whois_save(SilcClientCommandReplyContext cmd,
SilcStatus status,
bool notify)
SilcUInt32 argc, mode = 0, len, list_count;
char *topic, *tmp, *channel_name = NULL, *hmac;
SilcBuffer keyp = NULL, client_id_list = NULL, client_mode_list = NULL;
- SilcPublicKey founder_key = NULL;
SilcBufferStruct chpklist;
int i;
}
conn->current_channel = channel;
+ channel->mode = mode;
/* Get hmac */
hmac = silc_argument_get_arg_type(cmd->args, 11, NULL);
/* 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);
+ if (tmp) {
+ if (channel->founder_key)
+ silc_pkcs_public_key_free(channel->founder_key);
+ channel->founder_key = NULL;
+ silc_pkcs_public_key_payload_decode(tmp, len, &channel->founder_key);
+ }
/* Get channel public key list */
tmp = silc_argument_get_arg_type(cmd->args, 16, &len);
COMMAND_REPLY((SILC_ARGS, channel_name, channel, mode, 0,
keyp ? keyp->head : NULL, NULL,
NULL, topic, hmac, list_count, client_id_list,
- client_mode_list, founder_key, tmp ? &chpklist : NULL));
+ client_mode_list, channel->founder_key,
+ tmp ? &chpklist : NULL));
out:
SILC_CLIENT_PENDING_EXEC(cmd, SILC_COMMAND_JOIN);
silc_client_command_reply_free(cmd);
- if (founder_key)
- silc_pkcs_public_key_free(founder_key);
silc_buffer_free(keyp);
silc_buffer_free(client_id_list);
silc_buffer_free(client_mode_list);
silc_hash_make(cmd->client->sha1hash, tmp + 4, len - 4,
client_entry->fingerprint);
}
+ if (!client_entry->public_key) {
+ client_entry->public_key = public_key;
+ public_key = NULL;
+ }
/* Notify application */
- COMMAND_REPLY((SILC_ARGS, id_type, client_entry, public_key));
+ COMMAND_REPLY((SILC_ARGS, id_type, client_entry,
+ client_entry->public_key));
} else if (id_type == SILC_ID_SERVER) {
/* Received server's public key */
server_id = silc_id_payload_get_id(idp);
SilcGetClientCallback completion;
void *context;
char *nickname;
- char *server;
+ SilcClientEntry *clients;
+ SilcUInt32 clients_count;
} *GetClientInternal;
+/* Completion for IDENTIFY */
+
SILC_CLIENT_CMD_FUNC(get_client_callback)
{
GetClientInternal i = (GetClientInternal)context;
}
silc_free(i->nickname);
- silc_free(i->server);
silc_free(i);
}
+/* Completion for WHOIS */
+
+SILC_CLIENT_CMD_FUNC(get_client_callback_wc)
+{
+ GetClientInternal i = (GetClientInternal)context;
+ SilcClientCommandReplyContext cmd = context2;
+ SilcClientID *client_id = NULL;
+ SilcClientEntry client_entry = NULL;
+ unsigned char *id_data;
+ SilcUInt32 len;
+
+ /* Get the client entry just returned from server */
+ id_data = silc_argument_get_arg_type(cmd->args, 2, &len);
+ if (id_data)
+ client_id = silc_id_payload_parse_id(id_data, len, NULL);
+ if (client_id)
+ client_entry = silc_client_get_client_by_id(i->client,
+ i->conn, client_id);
+ if (!client_entry) {
+ if (!SILC_STATUS_IS_ERROR(cmd->status) &&
+ cmd->status != SILC_STATUS_OK &&
+ cmd->status != SILC_STATUS_LIST_END) {
+ silc_free(client_id);
+ return;
+ }
+
+ i->completion(i->client, i->conn, i->clients, i->clients_count,
+ i->context);
+ silc_free(client_id);
+ silc_free(i->clients);
+ silc_free(i->nickname);
+ silc_free(i);
+ return;
+ }
+
+ /* Save the client */
+ i->clients = silc_realloc(i->clients,
+ (sizeof(*i->clients) * (i->clients_count + 1)));
+ i->clients[i->clients_count] = client_entry;
+ i->clients_count++;
+
+ /* Return if more data is expected */
+ if (cmd->status != SILC_STATUS_OK &&
+ cmd->status != SILC_STATUS_LIST_END) {
+ silc_free(client_id);
+ return;
+ }
+
+ i->completion(i->client, i->conn, i->clients, i->clients_count,
+ i->context);
+
+ silc_free(client_id);
+ silc_free(i->clients);
+ silc_free(i->nickname);
+ silc_free(i);
+}
+
+/* Our own WHOIS reply processor. */
+
+SILC_CLIENT_CMD_FUNC(get_client_callback_w)
+{
+ SilcClientCommandReplyContext cmd = (SilcClientCommandReplyContext)context;
+ SilcClientConnection conn = (SilcClientConnection)cmd->sock->user_data;
+
+ SILC_LOG_DEBUG(("Start"));
+
+ if (!silc_command_get_status(cmd->payload, NULL, NULL)) {
+ if (SILC_STATUS_IS_ERROR(cmd->status))
+ goto out;
+ if (cmd->status == SILC_STATUS_LIST_END)
+ goto out;
+ goto err;
+ }
+
+ /* Save WHOIS info */
+ silc_client_command_reply_whois_save(cmd, cmd->status, FALSE);
+
+ /* Call pending completion for each reply */
+ if (cmd->status != SILC_STATUS_OK &&
+ cmd->status != SILC_STATUS_LIST_END) {
+ if (cmd->callbacks[0].callback)
+ (*cmd->callbacks[0].callback)(cmd->callbacks[0].context, cmd);
+ silc_client_command_reply_free(cmd);
+ return;
+ }
+
+ out:
+ SILC_CLIENT_PENDING_EXEC(cmd, SILC_COMMAND_WHOIS);
+
+ err:
+ /* If we received notify for invalid ID we'll remove the ID if we
+ have it cached. */
+ if (cmd->error == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) {
+ SilcClientEntry client_entry;
+ SilcUInt32 tmp_len;
+ unsigned char *tmp =
+ silc_argument_get_arg_type(silc_command_get_args(cmd->payload),
+ 2, &tmp_len);
+ if (tmp) {
+ SilcClientID *client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
+ if (client_id) {
+ client_entry = silc_client_get_client_by_id(cmd->client, conn,
+ client_id);
+ if (client_entry)
+ silc_client_del_client(cmd->client, conn, client_entry);
+ silc_free(client_id);
+ }
+ }
+ }
+
+ /* Unregister this command reply */
+ silc_client_command_unregister(cmd->client, SILC_COMMAND_WHOIS,
+ NULL, silc_client_command_reply_whois_i,
+ cmd->ident);
+ silc_client_command_reply_free(cmd);
+}
+
/* Finds client entry or entries by the `nickname' and `server'. The
completion callback will be called when the client entries has been found.
{
GetClientInternal i;
int len;
- char *userhost;
+ char *userhost = NULL;
assert(client && conn);
- if (!nickname)
+ if (!nickname && !attributes)
return;
i = silc_calloc(1, sizeof(*i));
i->client = client;
i->conn = conn;
- i->nickname = strdup(nickname);
- i->server = server ? strdup(server) : NULL;
+ i->nickname = nickname ? strdup(nickname) : NULL;
i->completion = completion;
i->context = context;
silc_strncat(userhost, len, nickname, strlen(nickname));
silc_strncat(userhost, len, "@", 1);
silc_strncat(userhost, len, server, strlen(server));
- } else {
+ } else if (nickname) {
userhost = silc_memdup(nickname, strlen(nickname));
}
silc_client_command_send(client, conn, SILC_COMMAND_IDENTIFY,
conn->cmd_ident, 1, 1, userhost,
strlen(userhost));
+
+ /* Add pending callback */
+ silc_client_command_pending(conn, command, conn->cmd_ident,
+ silc_client_command_get_client_callback,
+ (void *)i);
} else {
silc_client_command_register(client, command, NULL, NULL,
- silc_client_command_reply_whois_i, 0,
+ silc_client_command_get_client_callback_w, 0,
++conn->cmd_ident);
/* Send the command */
silc_client_command_send(client, conn, command, conn->cmd_ident, 2,
- 1, userhost, strlen(userhost),
+ 1, userhost, userhost ? strlen(userhost) : 0,
3, attributes ? attributes->data : NULL,
attributes ? attributes->len : 0);
- }
- /* Add pending callback */
- silc_client_command_pending(conn, command, conn->cmd_ident,
- silc_client_command_get_client_callback,
- (void *)i);
+ /* Add pending callback */
+ silc_client_command_pending(conn, command, conn->cmd_ident,
+ silc_client_command_get_client_callback_wc,
+ (void *)i);
+ }
silc_free(userhost);
}
silc_free(client_entry->server);
silc_free(client_entry->id);
silc_free(client_entry->fingerprint);
+ if (client_entry->public_key)
+ silc_pkcs_public_key_free(client_entry->public_key);
silc_hash_table_free(client_entry->channels);
if (client_entry->send_key)
silc_cipher_free(client_entry->send_key);
silc_free(channel->channel_name);
silc_free(channel->topic);
silc_free(channel->id);
+ if (channel->founder_key)
+ silc_pkcs_public_key_free(channel->founder_key);
silc_free(channel->key);
if (channel->channel_key)
silc_cipher_free(channel->channel_key);