and in protocol.c. This file implements the client-to-client key
agreement as defined by the SILC protocol. */
-#include "clientlibincludes.h"
+#include "silcincludes.h"
+#include "silcclient.h"
#include "client_internal.h"
SILC_TASK_CALLBACK(silc_client_key_agreement_final);
sock = silc_net_accept_connection(ke->fd);
if (sock < 0) {
- client->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
- "Could not accept key agreement connection: ",
- strerror(errno));
+ client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
+ "Could not accept key agreement connection: ",
+ strerror(errno));
ke->client_entry->ke = NULL;
ke->completion(ke->client, ke->conn, ke->client_entry,
SILC_KEY_AGREEMENT_ERROR, NULL, ke->context);
/* Perform name and address lookups for the remote host. */
silc_net_check_host_by_sock(sock, &newsocket->hostname, &newsocket->ip);
if (!newsocket->hostname && !newsocket->ip) {
- client->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
- "Could not resolve the remote IP or hostname");
+ client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
+ "Could not resolve the remote IP or hostname");
ke->client_entry->ke = NULL;
ke->completion(ke->client, ke->conn, ke->client_entry,
SILC_KEY_AGREEMENT_ERROR, NULL, ke->context);
void silc_client_send_key_agreement(SilcClient client,
SilcClientConnection conn,
SilcClientEntry client_entry,
- char *hostname,
+ const char *hostname,
+ const char *bindhost,
int port,
- uint32 timeout_secs,
+ SilcUInt32 timeout_secs,
SilcKeyAgreementCallback completion,
void *context)
{
SilcClientKeyAgreement ke = NULL;
SilcBuffer buffer;
- assert(client_entry);
+ if (!client_entry)
+ return;
+
+ if (client_entry->ke) {
+ completion(client, conn, client_entry, SILC_KEY_AGREEMENT_ALREADY_STARTED,
+ NULL, context);
+ return;
+ }
- if (client_entry->ke)
+ if (client_entry == conn->local_entry) {
+ completion(client, conn, client_entry, SILC_KEY_AGREEMENT_SELF_DENIED,
+ NULL, context);
return;
+ }
- /* Create the listener if hostname and port was provided */
+ /* Create the listener if hostname and port was provided.
+ * also, use bindhost if it was specified.
+ */
+
if (hostname) {
ke = silc_calloc(1, sizeof(*ke));
- ke->fd = silc_net_create_server(port, hostname);
+
+ if (bindhost)
+ ke->fd = silc_net_create_server(port, bindhost);
+ else
+ ke->fd = silc_net_create_server(port, hostname);
if (ke->fd < 0) {
- client->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
- "Cannot create listener on %s on port %d: %s",
- hostname, port, strerror(errno));
+ client->internal->ops->say(
+ client, conn, SILC_CLIENT_MESSAGE_ERROR,
+ "Cannot create listener on %s on port %d: %s",
+ (bindhost) ? bindhost:hostname, port, strerror(errno));
completion(client, conn, client_entry, SILC_KEY_AGREEMENT_FAILURE,
NULL, context);
silc_free(ke);
silc_client_packet_send(client, sock, SILC_PACKET_KEY_AGREEMENT,
client_entry->id, SILC_ID_CLIENT, NULL, NULL,
buffer->data, buffer->len, FALSE);
- silc_free(buffer);
+ silc_buffer_free(buffer);
}
static int
int sock;
/* Create connection to server asynchronously */
- sock = silc_net_create_connection_async(ctx->port, ctx->host);
+ sock = silc_net_create_connection_async(NULL, ctx->port, ctx->host);
if (sock < 0)
return -1;
if (opt != 0) {
if (ctx->tries < 2) {
/* Connection failed but lets try again */
- client->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
- "Could not connect to client %s: %s",
- ctx->host, strerror(opt));
- client->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
- "Connecting to port %d of client %s resumed",
- ctx->port, ctx->host);
+ client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
+ "Could not connect to client %s: %s",
+ ctx->host, strerror(opt));
+ client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
+ "Connecting to port %d of client %s resumed",
+ ctx->port, ctx->host);
/* Unregister old connection try */
silc_schedule_unset_listen_fd(client->schedule, fd);
ctx->tries++;
} else {
/* Connection failed and we won't try anymore */
- client->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
- "Could not connect to client %s: %s",
- ctx->host, strerror(opt));
+ client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
+ "Could not connect to client %s: %s",
+ ctx->host, strerror(opt));
silc_schedule_unset_listen_fd(client->schedule, fd);
silc_net_close_connection(fd);
silc_schedule_task_del(client->schedule, ctx->task);
SILC_LOG_DEBUG(("Start"));
- assert(client_entry && hostname && port);
+ if (!client_entry)
+ return;
+
+ if (!hostname || !port) {
+ completion(client, conn, client_entry, SILC_KEY_AGREEMENT_FAILURE,
+ NULL, context);
+ return;
+ }
+
+ if (client_entry == conn->local_entry) {
+ completion(client, conn, client_entry, SILC_KEY_AGREEMENT_SELF_DENIED,
+ NULL, context);
+ return;
+ }
ke = silc_calloc(1, sizeof(*ke));
ke->client = client;
SILC_LOG_DEBUG(("Start"));
- assert(client_entry);
+ if (!client_entry)
+ return;
+
+ if (client_entry == conn->local_entry) {
+ completion(client, conn, client_entry, SILC_KEY_AGREEMENT_SELF_DENIED,
+ NULL, context);
+ return;
+ }
ke = silc_calloc(1, sizeof(*ke));
ke->client = client;
SilcClientConnection conn,
SilcClientEntry client_entry)
{
- assert(client_entry);
+ if (!client_entry)
+ return;
if (client_entry->ke) {
+ SilcClientKeyAgreement ke;
+
if (client_entry->ke->sock) {
silc_client_del_socket(client_entry->ke->client, client_entry->ke->sock);
silc_socket_free(client_entry->ke->sock);
}
- client_entry->ke = NULL;
silc_schedule_task_del_by_fd(client->schedule, client_entry->ke->fd);
if (client_entry->ke->timeout)
silc_schedule_task_del(client->schedule,
- client_entry->ke->timeout);
- silc_free(client_entry->ke);
+ client_entry->ke->timeout);
+ ke = client_entry->ke;
+ client_entry->ke = NULL;
+ ke->completion(client, conn, client_entry,
+ SILC_KEY_AGREEMENT_ABORTED, NULL, ke->context);
+ silc_free(ke);
}
}
silc_client_key_agreement_resolve_cb(SilcClient client,
SilcClientConnection conn,
SilcClientEntry *clients,
- uint32 clients_count,
+ SilcUInt32 clients_count,
void *context)
{
SilcPacketContext *packet = (SilcPacketContext *)context;
goto out;
/* Parse the key agreement payload */
- payload = silc_key_agreement_payload_parse(packet->buffer);
+ payload = silc_key_agreement_payload_parse(packet->buffer->data,
+ packet->buffer->len);
if (!payload)
goto out;
/* Call the key_agreement client operation */
- ret = client->ops->key_agreement(client, conn, clients[0],
+ ret = client->internal->ops->key_agreement(
+ client, conn, clients[0],
silc_key_agreement_get_hostname(payload),
silc_key_agreement_get_port(payload),
&completion, &completion_context);
return;
silc_client_get_client_by_id_resolve(client, sock->user_data, remote_id,
+ NULL,
silc_client_key_agreement_resolve_cb,
silc_packet_context_dup(packet));
silc_free(remote_id);