From b95444f37a4b624ab2ff0ac52c4ee606f10bc6e4 Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Sat, 30 Sep 2000 06:05:30 +0000 Subject: [PATCH] Added new function silc_client_start_key_exchange and changed that code uses that function now. Patch by cras. Updated README file to explain the usage of the function. --- lib/silcclient/README | 27 ++++++++++ lib/silcclient/client.c | 108 ++++++++++++++++++++++------------------ lib/silcclient/client.h | 3 ++ 3 files changed, 90 insertions(+), 48 deletions(-) diff --git a/lib/silcclient/README b/lib/silcclient/README index 60af009c..bfa8a0bb 100644 --- a/lib/silcclient/README +++ b/lib/silcclient/README @@ -113,3 +113,30 @@ Application specific context can be saved to the SilcClientConnection object which then can be retrieved in the application, thus perhaps associate the connection with what ever object in the application (window or something else). + + +Using Own Connecting +==================== + +Application might not want to use silc_client_connect_to_server function +if it wants to perform its own connecting for some reason. In this case +application must call function silc_client_start_key_exchange after it +has created the connection by itself. This function starts key exhange +protocol between the client and server and the library takes care of +everything after that. + +After connection has been created application must call: + + SilcClientConnection conn; + + /* Add new connection to client library */ + conn = silc_client_add_connection(client, context); + conn->remote_host = hostname; + conn->remote_port = port; + + /* Start key exchange and let the library handle everything + after this point on. */ + silc_client_start_key_exchange(client, conn, sock); + +These calls are performed only and only if application did not call +silc_client_connect_to_server function. diff --git a/lib/silcclient/client.c b/lib/silcclient/client.c index f4a2b795..ad273bdc 100644 --- a/lib/silcclient/client.c +++ b/lib/silcclient/client.c @@ -243,6 +243,65 @@ int silc_client_connect_to_server(SilcClient client, int port, return sock; } +/* Start SILC Key Exchange (SKE) protocol to negotiate shared secret + key material between client and server. This function can be called + directly if application is performing its own connecting and does not + use the connecting provided by this library. */ + +int silc_client_start_key_exchange(SilcClient client, + SilcClientConnection conn, + int fd) +{ + SilcProtocol protocol; + SilcClientKEInternalContext *proto_ctx; + void *context; + + /* Allocate new socket connection object */ + silc_socket_alloc(fd, SILC_SOCKET_TYPE_SERVER, (void *)conn, &conn->sock); + if (conn->sock == NULL) { + client->ops->say(client, conn, + "Error: Could not allocate connection socket"); + return FALSE; + } + + conn->nickname = strdup(client->username); + conn->sock->hostname = conn->remote_host; + conn->sock->port = conn->remote_port; + + /* Allocate internal Key Exchange context. This is sent to the + protocol as context. */ + proto_ctx = silc_calloc(1, sizeof(*proto_ctx)); + proto_ctx->client = (void *)client; + proto_ctx->sock = conn->sock; + proto_ctx->rng = client->rng; + proto_ctx->responder = FALSE; + + /* Perform key exchange protocol. silc_client_connect_to_server_final + will be called after the protocol is finished. */ + silc_protocol_alloc(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE, + &protocol, (void *)proto_ctx, + silc_client_connect_to_server_second); + if (!protocol) { + client->ops->say(client, conn, + "Error: Could not start authentication protocol"); + return FALSE; + } + conn->sock->protocol = protocol; + + /* Register the connection for network input and output. This sets + that scheduler will listen for incoming packets for this connection + and sets that outgoing packets may be sent to this connection as well. + However, this doesn't set the scheduler for outgoing traffic, it will + be set separately by calling SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT, + later when outgoing data is available. */ + context = (void *)client; + SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(fd); + + /* Execute the protocol */ + protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0); + return TRUE; +} + /* Start of the connection to the remote server. This is called after succesful TCP/IP connection has been established to the remote host. */ @@ -252,8 +311,6 @@ SILC_TASK_CALLBACK(silc_client_connect_to_server_start) (SilcClientInternalConnectContext *)context; SilcClient client = ctx->client; SilcClientConnection conn = ctx->conn; - SilcProtocol protocol; - SilcClientKEInternalContext *proto_ctx; int opt, opt_len = sizeof(opt); SILC_LOG_DEBUG(("Start")); @@ -297,52 +354,10 @@ SILC_TASK_CALLBACK(silc_client_connect_to_server_start) silc_task_unregister(client->io_queue, ctx->task); silc_free(ctx); - /* Allocate new socket connection object */ - silc_socket_alloc(fd, SILC_SOCKET_TYPE_SERVER, (void *)conn, &conn->sock); - if (conn->sock == NULL) { - client->ops->say(client, conn, - "Error: Could not allocate connection socket"); + if (!silc_client_start_key_exchange(client, conn, fd)) { silc_net_close_connection(fd); client->ops->connect(client, conn, FALSE); - return; } - - conn->nickname = strdup(client->username); - conn->sock->hostname = conn->remote_host; - conn->sock->port = conn->remote_port; - - /* Allocate internal Key Exchange context. This is sent to the - protocol as context. */ - proto_ctx = silc_calloc(1, sizeof(*proto_ctx)); - proto_ctx->client = (void *)client; - proto_ctx->sock = conn->sock; - proto_ctx->rng = client->rng; - proto_ctx->responder = FALSE; - - /* Perform key exchange protocol. silc_client_connect_to_server_final - will be called after the protocol is finished. */ - silc_protocol_alloc(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE, - &protocol, (void *)proto_ctx, - silc_client_connect_to_server_second); - if (!protocol) { - client->ops->say(client, conn, - "Error: Could not start authentication protocol"); - client->ops->connect(client, conn, FALSE); - return; - } - conn->sock->protocol = protocol; - - /* Register the connection for network input and output. This sets - that scheduler will listen for incoming packets for this connection - and sets that outgoing packets may be sent to this connection as well. - However, this doesn't set the scheduler for outgoing traffic, it will - be set separately by calling SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT, - later when outgoing data is available. */ - context = (void *)client; - SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(fd); - - /* Execute the protocol */ - protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0); } /* Second part of the connecting to the server. This executed @@ -474,9 +489,6 @@ SILC_TASK_CALLBACK(silc_client_connect_to_server_final) conn->remote_id_data = silc_id_id2str(ctx->dest_id, SILC_ID_SERVER); conn->remote_id_data_len = SILC_ID_SERVER_LEN; - client->ops->say(client, conn, "Connected to port %d of host %s", - conn->remote_port, conn->remote_host); - /* Notify application of successful connection */ client->ops->connect(client, conn, TRUE); diff --git a/lib/silcclient/client.h b/lib/silcclient/client.h index 8caffe81..a9dce2aa 100644 --- a/lib/silcclient/client.h +++ b/lib/silcclient/client.h @@ -226,6 +226,9 @@ SilcClientConnection silc_client_add_connection(SilcClient client, void *context); int silc_client_connect_to_server(SilcClient client, int port, char *host, void *context); +int silc_client_start_key_exchange(SilcClient client, + SilcClientConnection conn, + int fd); void silc_client_packet_send(SilcClient client, SilcSocketConnection sock, SilcPacketType type, -- 2.24.0