From 75a2d69f7d56b8298e80f9a4546f22ddf138be39 Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Fri, 1 Nov 2002 09:33:09 +0000 Subject: [PATCH] Moved the SilcClient and SilcClientConnection to the public silcclient.h and cleaned up the structures a bit. --- CHANGES | 6 ++ TODO-1.0 | 17 --- lib/silcclient/client.c | 179 ++++++++++++++++--------------- lib/silcclient/client.h | 171 +++-------------------------- lib/silcclient/client_attrs.c | 34 +++--- lib/silcclient/client_channel.c | 6 +- lib/silcclient/client_ftp.c | 70 ++++++------ lib/silcclient/client_internal.h | 67 ++++++++++++ lib/silcclient/client_notify.c | 9 +- lib/silcclient/client_prvmsg.c | 33 +++--- lib/silcclient/client_resume.c | 6 +- lib/silcclient/command.c | 57 +++++----- lib/silcclient/command_reply.c | 27 ++--- lib/silcclient/idlist.c | 57 +++++----- lib/silcclient/protocol.c | 107 +++++++++--------- lib/silcclient/silcclient.h | 137 ++++++++++++++++++++--- 16 files changed, 522 insertions(+), 461 deletions(-) diff --git a/CHANGES b/CHANGES index e0ef1234..a525afe3 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ +Fri Nov 1 10:30:26 CET 2002 Pekka Riikonen + + * Moved the SilcClient and SilcClientConnection from client.h + to the public lib/silcclient/silcclient.h. Changed the + structures a bit. + Thu Oct 31 22:44:07 EET 2002 Pekka Riikonen * If version string in silc_clinet_alloc is NULL the library diff --git a/TODO-1.0 b/TODO-1.0 index 1f821fde..a1957118 100644 --- a/TODO-1.0 +++ b/TODO-1.0 @@ -164,20 +164,3 @@ least could be done. o Check whether we can fully comply with RFC 2779. - -TODO in SILC Protocol -===================== - - o Inviting and banning by public key should be made possible. To be - included in protocol version 1.2. - - o UTF-8 support/requirement for nicknames & channel names. UTF-8 support - in terminals and OS's are so hazy that this matter is left for - consideration in next version of the protocol (1.2). For good UTF-8 - reference and tutorial see: http://www.cl.cam.ac.uk/~mgk25/unicode.html. - What should CLI application do if it receives nickname that it cannot - display without messing up the terminal? If UTF-8 is mandatory in - SILC then SILC clients cannot be allowed to start on terminals that do - not support UTF-8 (which renders 98% of users unable to use CLI SILC - app without hacking their environment). See also site - http://gratrix.net/unicode/ diff --git a/lib/silcclient/client.c b/lib/silcclient/client.c index 23033e75..e08ddffa 100644 --- a/lib/silcclient/client.c +++ b/lib/silcclient/client.c @@ -207,24 +207,26 @@ silc_client_add_connection(SilcClient client, SILC_LOG_DEBUG(("Adding new connection to %s:%d", hostname, port)); conn = silc_calloc(1, sizeof(*conn)); + conn->internal = silc_calloc(1, sizeof(*conn->internal)); /* Initialize ID caches */ - conn->client_cache = silc_idcache_alloc(0, SILC_ID_CLIENT, - silc_client_entry_destructor); - conn->channel_cache = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL); - conn->server_cache = silc_idcache_alloc(0, SILC_ID_SERVER, NULL); conn->client = client; conn->remote_host = strdup(hostname); conn->remote_port = port; conn->context = context; - conn->pending_commands = silc_dlist_init(); - conn->ftp_sessions = silc_dlist_init(); + conn->internal->client_cache = + silc_idcache_alloc(0, SILC_ID_CLIENT, silc_client_entry_destructor); + conn->internal->channel_cache = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL); + conn->internal->server_cache = silc_idcache_alloc(0, SILC_ID_SERVER, NULL); + conn->internal->pending_commands = silc_dlist_init(); + conn->internal->ftp_sessions = silc_dlist_init(); if (params) { if (params->detach_data) - conn->params.detach_data = silc_memdup(params->detach_data, - params->detach_data_len); - conn->params.detach_data_len = params->detach_data_len; + conn->internal->params.detach_data = + silc_memdup(params->detach_data, + params->detach_data_len); + conn->internal->params.detach_data_len = params->detach_data_len; } /* Add the connection to connections table */ @@ -252,14 +254,15 @@ void silc_client_del_connection(SilcClient client, SilcClientConnection conn) for (i = 0; i < client->internal->conns_count; i++) if (client->internal->conns[i] == conn) { - silc_idcache_free(conn->client_cache); - silc_idcache_free(conn->channel_cache); - silc_idcache_free(conn->server_cache); - if (conn->pending_commands) - silc_dlist_uninit(conn->pending_commands); + silc_idcache_free(conn->internal->client_cache); + silc_idcache_free(conn->internal->channel_cache); + silc_idcache_free(conn->internal->server_cache); + if (conn->internal->pending_commands) + silc_dlist_uninit(conn->internal->pending_commands); silc_free(conn->remote_host); - if (conn->ftp_sessions) - silc_dlist_uninit(conn->ftp_sessions); + if (conn->internal->ftp_sessions) + silc_dlist_uninit(conn->internal->ftp_sessions); + silc_free(conn->internal); silc_free(conn); client->internal->conns[i] = NULL; @@ -702,7 +705,7 @@ SILC_TASK_CALLBACK(silc_client_connect_to_server_final) goto err; } - if (conn->params.detach_data) { + if (conn->internal->params.detach_data) { /* Send RESUME_CLIENT packet to the server, which is used to resume old detached session back. */ SilcBuffer auth; @@ -722,7 +725,8 @@ SILC_TASK_CALLBACK(silc_client_connect_to_server_final) /* Generate authentication data that server will verify */ auth = silc_auth_public_key_auth_generate(client->public_key, client->private_key, - client->rng, conn->hash, + client->rng, + conn->internal->hash, old_client_id, SILC_ID_CLIENT); if (!auth) { silc_free(old_client_id); @@ -774,11 +778,11 @@ SILC_TASK_CALLBACK(silc_client_connect_to_server_final) conn->remote_id_data_len = silc_id_get_len(ctx->dest_id, SILC_ID_SERVER); /* Register re-key timeout */ - conn->rekey->timeout = client->internal->params->rekey_secs; - conn->rekey->context = (void *)client; + conn->internal->rekey->timeout = client->internal->params->rekey_secs; + conn->internal->rekey->context = (void *)client; silc_schedule_task_add(client->schedule, conn->sock->sock, silc_client_rekey_callback, - (void *)conn->sock, conn->rekey->timeout, 0, + (void *)conn->sock, conn->internal->rekey->timeout, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL); silc_protocol_free(protocol); @@ -919,8 +923,9 @@ SILC_TASK_CALLBACK_GLOBAL(silc_client_packet_process) /* Process the packet. This will call the parser that will then decrypt and parse the packet. */ if (sock->type != SILC_SOCKET_TYPE_UNKNOWN) - silc_packet_receive_process(sock, FALSE, conn->receive_key, - conn->hmac_receive, conn->psn_receive, + silc_packet_receive_process(sock, FALSE, conn->internal->receive_key, + conn->internal->hmac_receive, + conn->internal->psn_receive, silc_client_packet_parse, client); else silc_packet_receive_process(sock, FALSE, NULL, NULL, 0, @@ -940,14 +945,14 @@ static bool silc_client_packet_parse(SilcPacketParserContext *parser_context, SilcPacketContext *packet = parser_context->packet; SilcPacketType ret; - if (conn && conn->hmac_receive && conn->sock == sock) - conn->psn_receive = parser_context->packet->sequence + 1; + if (conn && conn->internal->hmac_receive && conn->sock == sock) + conn->internal->psn_receive = parser_context->packet->sequence + 1; /* Parse the packet immediately */ if (parser_context->normal) - ret = silc_packet_parse(packet, conn->receive_key); + ret = silc_packet_parse(packet, conn->internal->receive_key); else - ret = silc_packet_parse_special(packet, conn->receive_key); + ret = silc_packet_parse_special(packet, conn->internal->receive_key); if (ret == SILC_PACKET_NONE) { silc_packet_context_free(packet); @@ -970,11 +975,12 @@ static bool silc_client_packet_parse(SilcPacketParserContext *parser_context, silc_free(parser_context); /* Reprocess the buffer since we'll return FALSE. This is because - the `conn->receive_key' might have become valid by processing + the `conn->internal->receive_key' might have become valid by processing the previous packet */ if (sock->type != SILC_SOCKET_TYPE_UNKNOWN) - silc_packet_receive_process(sock, FALSE, conn->receive_key, - conn->hmac_receive, conn->psn_receive, + silc_packet_receive_process(sock, FALSE, conn->internal->receive_key, + conn->internal->hmac_receive, + conn->internal->psn_receive, silc_client_packet_parse, client); else silc_packet_receive_process(sock, FALSE, NULL, NULL, 0, @@ -1306,11 +1312,11 @@ void silc_client_packet_send(SilcClient client, /* Get data used in the packet sending, keys and stuff */ if ((!cipher || !hmac || !dst_id) && sock->user_data) { - if (!cipher && ((SilcClientConnection)sock->user_data)->send_key) - cipher = ((SilcClientConnection)sock->user_data)->send_key; + if (!cipher && ((SilcClientConnection)sock->user_data)->internal->send_key) + cipher = ((SilcClientConnection)sock->user_data)->internal->send_key; - if (!hmac && ((SilcClientConnection)sock->user_data)->hmac_send) - hmac = ((SilcClientConnection)sock->user_data)->hmac_send; + if (!hmac && ((SilcClientConnection)sock->user_data)->internal->hmac_send) + hmac = ((SilcClientConnection)sock->user_data)->internal->hmac_send; if (!dst_id && ((SilcClientConnection)sock->user_data)->remote_id) { dst_id = ((SilcClientConnection)sock->user_data)->remote_id; @@ -1318,7 +1324,7 @@ void silc_client_packet_send(SilcClient client, } if (hmac) - sequence = ((SilcClientConnection)sock->user_data)->psn_send++; + sequence = ((SilcClientConnection)sock->user_data)->internal->psn_send++; } block_len = cipher ? silc_cipher_get_block_len(cipher) : 0; @@ -1443,7 +1449,7 @@ void silc_client_close_connection_real(SilcClient client, SilcClientCommandPending *r; bool ret; - if (silc_idcache_get_all(conn->client_cache, &list)) { + if (silc_idcache_get_all(conn->internal->client_cache, &list)) { ret = silc_idcache_list_first(list, &entry); while (ret) { silc_client_del_client(client, conn, entry->context); @@ -1452,7 +1458,7 @@ void silc_client_close_connection_real(SilcClient client, silc_idcache_list_free(list); } - if (silc_idcache_get_all(conn->channel_cache, &list)) { + if (silc_idcache_get_all(conn->internal->channel_cache, &list)) { ret = silc_idcache_list_first(list, &entry); while (ret) { silc_client_del_channel(client, conn, entry->context); @@ -1461,7 +1467,7 @@ void silc_client_close_connection_real(SilcClient client, silc_idcache_list_free(list); } - if (silc_idcache_get_all(conn->server_cache, &list)) { + if (silc_idcache_get_all(conn->internal->server_cache, &list)) { ret = silc_idcache_list_first(list, &entry); while (ret) { silc_client_del_server(client, conn, entry->context); @@ -1471,12 +1477,12 @@ void silc_client_close_connection_real(SilcClient client, } /* Clear ID caches */ - if (conn->client_cache) - silc_idcache_free(conn->client_cache); - if (conn->channel_cache) - silc_idcache_free(conn->channel_cache); - if (conn->server_cache) - silc_idcache_free(conn->server_cache); + if (conn->internal->client_cache) + silc_idcache_free(conn->internal->client_cache); + if (conn->internal->channel_cache) + silc_idcache_free(conn->internal->channel_cache); + if (conn->internal->server_cache) + silc_idcache_free(conn->internal->server_cache); /* Free data (my ID is freed in above silc_client_del_client). conn->nickname is freed when freeing the local_entry->nickname. */ @@ -1484,30 +1490,31 @@ void silc_client_close_connection_real(SilcClient client, silc_free(conn->remote_host); if (conn->local_id_data) silc_free(conn->local_id_data); - if (conn->send_key) - silc_cipher_free(conn->send_key); - if (conn->receive_key) - silc_cipher_free(conn->receive_key); - if (conn->hmac_send) - silc_hmac_free(conn->hmac_send); - if (conn->hmac_receive) - silc_hmac_free(conn->hmac_receive); - if (conn->rekey) - silc_free(conn->rekey); - - if (conn->active_session) { + if (conn->internal->send_key) + silc_cipher_free(conn->internal->send_key); + if (conn->internal->receive_key) + silc_cipher_free(conn->internal->receive_key); + if (conn->internal->hmac_send) + silc_hmac_free(conn->internal->hmac_send); + if (conn->internal->hmac_receive) + silc_hmac_free(conn->internal->hmac_receive); + if (conn->internal->rekey) + silc_free(conn->internal->rekey); + + if (conn->internal->active_session) { sock->user_data = NULL; - silc_client_ftp_session_free(conn->active_session); - conn->active_session = NULL; + silc_client_ftp_session_free(conn->internal->active_session); + conn->internal->active_session = NULL; } silc_client_ftp_free_sessions(client, conn); - silc_dlist_start(conn->pending_commands); - while ((r = silc_dlist_get(conn->pending_commands)) != SILC_LIST_END) - silc_dlist_del(conn->pending_commands, r); - if (conn->pending_commands) - silc_dlist_uninit(conn->pending_commands); + silc_dlist_start(conn->internal->pending_commands); + while ((r = silc_dlist_get(conn->internal->pending_commands)) + != SILC_LIST_END) + silc_dlist_del(conn->internal->pending_commands, r); + if (conn->internal->pending_commands) + silc_dlist_uninit(conn->internal->pending_commands); memset(conn, 0, sizeof(*conn)); silc_client_del_connection(client, conn); @@ -1657,7 +1664,8 @@ void silc_client_receive_new_id(SilcClient client, return; } - silc_idcache_del_by_context(conn->client_cache, conn->local_entry); + silc_idcache_del_by_context(conn->internal->client_cache, + conn->local_entry); silc_free(conn->local_id); } @@ -1687,7 +1695,8 @@ void silc_client_receive_new_id(SilcClient client, TRUE); /* Put it to the ID cache */ - silc_idcache_add(conn->client_cache, strdup(conn->nickname), conn->local_id, + silc_idcache_add(conn->internal->client_cache, + strdup(conn->nickname), conn->local_id, (void *)conn->local_entry, 0, NULL); if (connecting) { @@ -1703,7 +1712,7 @@ void silc_client_receive_new_id(SilcClient client, conn->cmd_ident, 1, 5, sidp->data, sidp->len); silc_buffer_free(sidp); - if (!conn->params.detach_data) { + if (!conn->internal->params.detach_data) { /* Send NICK command if the nickname was set by the application (and is not same as the username). Send this with little timeout. */ if (client->nickname && strcmp(client->nickname, client->username)) @@ -1806,7 +1815,7 @@ SILC_TASK_CALLBACK(silc_client_rekey_callback) { SilcSocketConnection sock = (SilcSocketConnection)context; SilcClientConnection conn = (SilcClientConnection)sock->user_data; - SilcClient client = (SilcClient)conn->rekey->context; + SilcClient client = (SilcClient)conn->internal->rekey->context; SilcProtocol protocol; SilcClientRekeyInternalContext *proto_ctx; @@ -1818,7 +1827,7 @@ SILC_TASK_CALLBACK(silc_client_rekey_callback) proto_ctx->client = (void *)client; proto_ctx->sock = silc_socket_dup(sock); proto_ctx->responder = FALSE; - proto_ctx->pfs = conn->rekey->pfs; + proto_ctx->pfs = conn->internal->rekey->pfs; /* Perform rekey protocol. Will call the final callback after the protocol is over. */ @@ -1832,7 +1841,7 @@ SILC_TASK_CALLBACK(silc_client_rekey_callback) /* Re-register re-key timeout */ silc_schedule_task_add(client->schedule, sock->sock, silc_client_rekey_callback, - context, conn->rekey->timeout, 0, + context, conn->internal->rekey->timeout, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL); } @@ -1893,7 +1902,7 @@ void silc_client_connection_auth_request(SilcClient client, int ret; /* If we haven't send our request then ignore this one. */ - if (!conn->connauth) + if (!conn->internal->connauth) return; /* Parse the payload */ @@ -1906,14 +1915,14 @@ void silc_client_connection_auth_request(SilcClient client, /* Call the request callback to notify application for received authentication method information. */ - if (conn->connauth->callback) - (*conn->connauth->callback)(client, conn, auth_meth, - conn->connauth->context); + if (conn->internal->connauth->callback) + (*conn->internal->connauth->callback)(client, conn, auth_meth, + conn->internal->connauth->context); - silc_schedule_task_del(client->schedule, conn->connauth->timeout); + silc_schedule_task_del(client->schedule, conn->internal->connauth->timeout); - silc_free(conn->connauth); - conn->connauth = NULL; + silc_free(conn->internal->connauth); + conn->internal->connauth = NULL; } /* Timeout task callback called if the server does not reply to our @@ -1924,16 +1933,16 @@ SILC_TASK_CALLBACK(silc_client_request_authentication_method_timeout) SilcClientConnection conn = (SilcClientConnection)context; SilcClient client = conn->client; - if (!conn->connauth) + if (!conn->internal->connauth) return; /* Call the request callback to notify application */ - if (conn->connauth->callback) - (*conn->connauth->callback)(client, conn, SILC_AUTH_NONE, - conn->connauth->context); + if (conn->internal->connauth->callback) + (*conn->internal->connauth->callback)(client, conn, SILC_AUTH_NONE, + conn->internal->connauth->context); - silc_free(conn->connauth); - conn->connauth = NULL; + silc_free(conn->internal->connauth); + conn->internal->connauth = NULL; } /* This function can be used to request the current authentication method @@ -1957,10 +1966,10 @@ silc_client_request_authentication_method(SilcClient client, connauth->callback = callback; connauth->context = context; - if (conn->connauth) - silc_free(conn->connauth); + if (conn->internal->connauth) + silc_free(conn->internal->connauth); - conn->connauth = connauth; + conn->internal->connauth = connauth; /* Assemble the request packet and send it to the server */ packet = silc_buffer_alloc(4); diff --git a/lib/silcclient/client.h b/lib/silcclient/client.h index 6b9965be..0fc86888 100644 --- a/lib/silcclient/client.h +++ b/lib/silcclient/client.h @@ -21,159 +21,22 @@ #define CLIENT_H /* Forward declarations */ +typedef struct SilcClientStruct *SilcClient; +typedef struct SilcClientConnectionStruct *SilcClientConnection; +typedef struct SilcClientPingStruct SilcClientPing; +typedef struct SilcClientAwayStruct SilcClientAway; +typedef struct SilcClientKeyAgreementStruct *SilcClientKeyAgreement; +typedef struct SilcClientFtpSessionStruct *SilcClientFtpSession; +typedef struct SilcClientEntryStruct *SilcClientEntry; +typedef struct SilcChannelEntryStruct *SilcChannelEntry; +typedef struct SilcServerEntryStruct *SilcServerEntry; +typedef struct SilcClientCommandStruct *SilcClientCommand; +typedef struct SilcClientCommandContextStruct *SilcClientCommandContext; +typedef struct SilcClientCommandReplyContextStruct + *SilcClientCommandReplyContext; +typedef struct SilcChannelUserStruct *SilcChannelUser; typedef struct SilcClientInternalStruct *SilcClientInternal; - -/* Generic rekey context for connections */ -typedef struct { - /* Current sending encryption key, provided for re-key. The `pfs' - is TRUE if the Perfect Forward Secrecy is performed in re-key. */ - unsigned char *send_enc_key; - SilcUInt32 enc_key_len; - int ske_group; - bool pfs; - SilcUInt32 timeout; - void *context; -} *SilcClientRekey; - -/* Context to hold the connection authentication request callbacks that - will be called when the server has replied back to our request about - current authentication method in the session. */ -typedef struct { - SilcConnectionAuthRequest callback; - void *context; - SilcTask timeout; -} *SilcClientConnAuthRequest; - -/* Connection structure used in client to associate all the important - connection specific data to this structure. */ -struct SilcClientConnectionStruct { - /* - * Local data - */ - char *nickname; - - /* Local client ID for this connection */ - SilcClientID *local_id; - - /* Decoded local ID so that the above defined ID would not have - to be decoded for every packet. */ - unsigned char *local_id_data; - SilcUInt32 local_id_data_len; - - /* Own client entry. */ - SilcClientEntry local_entry; - - /* - * Remote data - */ - char *remote_host; - int remote_port; - int remote_type; - char *remote_info; - - /* Remote server ID for this connection */ - SilcServerID *remote_id; - - /* Decoded remote ID so that the above defined ID would not have - to be decoded for every packet. */ - unsigned char *remote_id_data; - SilcUInt32 remote_id_data_len; - - /* - * Common data - */ - /* Keys and stuff negotiated in the SKE protocol */ - SilcCipher send_key; - SilcCipher receive_key; - SilcHmac hmac_send; - SilcHmac hmac_receive; - SilcHash hash; - SilcUInt32 psn_send; - SilcUInt32 psn_receive; - - /* Client ID and Channel ID cache. Messages transmitted in SILC network - are done using different unique ID's. These are the cache for - thoses ID's used in the communication. */ - SilcIDCache client_cache; - SilcIDCache channel_cache; - SilcIDCache server_cache; - - /* Current channel on window. All channels are saved (allocated) into - the cache entries. */ - SilcChannelEntry current_channel; - - /* Socket connection object for this connection (window). This - object will have a back-pointer to this window object for fast - referencing (sock->user_data). */ - SilcSocketConnection sock; - - /* Pending command queue for this connection */ - SilcDList pending_commands; - - /* Current command identifier, 0 not used */ - SilcUInt16 cmd_ident; - - /* Requested pings. */ - SilcClientPing *ping; - SilcUInt32 ping_count; - - /* Set away message */ - SilcClientAway *away; - - /* Re-key context */ - SilcClientRekey rekey; - - /* Authentication request context. */ - SilcClientConnAuthRequest connauth; - - /* File transmission sessions */ - SilcDList ftp_sessions; - SilcUInt32 next_session_id; - SilcClientFtpSession active_session; - - /* Requested Attributes */ - SilcHashTable attrs; - - /* Pointer back to the SilcClient. This object is passed to the application - and the actual client object is accesible through this pointer. */ - SilcClient client; - - /* Connection parameters */ - SilcClientConnectionParams params; - - /* User data context. Library does not touch this. */ - void *context; -}; - -/* Main client structure. */ -struct SilcClientStruct { - char *username; /* Username, must be set by application */ - char *nickname; /* Nickname, may be set by application */ - char *hostname; /* hostname, must be set by application */ - char *realname; /* Real name, must be set be application */ - - SilcPublicKey public_key; /* Public key of user, set by application */ - SilcPrivateKey private_key; /* Private key of user, set by application */ - SilcPKCS pkcs; /* PKCS allocated by application */ - - SilcSchedule schedule; /* Scheduler, automatically allocated by - the client library. */ - - /* Random Number Generator. Application should use this as its primary - random number generator. */ - SilcRng rng; - - /* Application specific user data pointer. Client library does not - touch this. This the context sent as argument to silc_client_alloc. */ - void *application; - - /* Generic hash context for application usage */ - SilcHash md5hash; - SilcHash sha1hash; - - /* Internal data for client library. Application cannot access this - data at all. */ - SilcClientInternal internal; -}; - +typedef struct SilcClientConnectionInternalStruct + *SilcClientConnectionInternal; + #endif diff --git a/lib/silcclient/client_attrs.c b/lib/silcclient/client_attrs.c index 4a28d9e8..b244979f 100644 --- a/lib/silcclient/client_attrs.c +++ b/lib/silcclient/client_attrs.c @@ -88,7 +88,7 @@ SilcBuffer silc_client_attributes_process(SilcClient client, /* If nothing is set by application assume that we don't want to use attributes, ignore the request. */ - if (!conn->attrs) + if (!conn->internal->attrs) return NULL; /* Always put our public key. */ @@ -112,7 +112,8 @@ SilcBuffer silc_client_attributes_process(SilcClient client, if (attribute == SILC_ATTRIBUTE_USER_DIGITAL_SIGNATURE) continue; - silc_hash_table_find_foreach(conn->attrs, (void *)(SilcUInt32)attribute, + silc_hash_table_find_foreach(conn->internal->attrs, + (void *)(SilcUInt32)attribute, silc_client_attributes_process_foreach, &f); } @@ -156,11 +157,13 @@ SilcAttributePayload silc_client_attribute_add(SilcClient client, if (!attr) return NULL; - if (!conn->attrs) - conn->attrs = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL, - NULL, silc_client_attribute_destruct, - NULL, TRUE); - silc_hash_table_add(conn->attrs, (void *)(SilcUInt32)attribute, attr); + if (!conn->internal->attrs) + conn->internal->attrs = + silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL, + NULL, silc_client_attribute_destruct, + NULL, TRUE); + silc_hash_table_add(conn->internal->attrs, + (void *)(SilcUInt32)attribute, attr); return attr; } @@ -173,7 +176,7 @@ static void silc_client_attribute_del_foreach(void *key, void *context, if (!attr) return; attribute = silc_attribute_get_attribute(attr); - silc_hash_table_del_by_context(conn->attrs, + silc_hash_table_del_by_context(conn->internal->attrs, (void *)(SilcUInt32)attribute, attr); } @@ -186,15 +189,16 @@ bool silc_client_attribute_del(SilcClient client, { bool ret; - if (!conn->attrs) + if (!conn->internal->attrs) return FALSE; if (attr) { attribute = silc_attribute_get_attribute(attr); - ret = silc_hash_table_del_by_context(conn->attrs, + ret = silc_hash_table_del_by_context(conn->internal->attrs, (void *)(SilcUInt32)attribute, attr); } else if (attribute) { - silc_hash_table_find_foreach(conn->attrs, (void *)(SilcUInt32)attribute, + silc_hash_table_find_foreach(conn->internal->attrs, + (void *)(SilcUInt32)attribute, silc_client_attribute_del_foreach, conn); ret = TRUE; } else{ @@ -202,9 +206,9 @@ bool silc_client_attribute_del(SilcClient client, } if (ret) - if (!silc_hash_table_count(conn->attrs)) { - silc_hash_table_free(conn->attrs); - conn->attrs = NULL; + if (!silc_hash_table_count(conn->internal->attrs)) { + silc_hash_table_free(conn->internal->attrs); + conn->internal->attrs = NULL; } return ret; @@ -215,7 +219,7 @@ bool silc_client_attribute_del(SilcClient client, const SilcHashTable silc_client_attributes_get(SilcClient client, SilcClientConnection conn) { - return (const SilcHashTable)conn->attrs; + return (const SilcHashTable)conn->internal->attrs; } /* Construct a Requested Attributes buffer. If the `attribute' is zero (0) diff --git a/lib/silcclient/client_channel.c b/lib/silcclient/client_channel.c index f72d4def..c678ab58 100644 --- a/lib/silcclient/client_channel.c +++ b/lib/silcclient/client_channel.c @@ -122,8 +122,8 @@ void silc_client_send_channel_message(SilcClient client, client->rng); /* Get data used in packet header encryption, keys and stuff. */ - cipher = conn->send_key; - hmac = conn->hmac_send; + cipher = conn->internal->send_key; + hmac = conn->internal->hmac_send; id_string = silc_id_id2str(channel->id, SILC_ID_CHANNEL); /* Set the packet context pointers. The destination ID is always @@ -157,7 +157,7 @@ void silc_client_send_channel_message(SilcClient client, /* Encrypt the header and padding of the packet. This is encrypted with normal session key shared with our server. */ - silc_packet_encrypt(cipher, hmac, conn->psn_send++, + silc_packet_encrypt(cipher, hmac, conn->internal->psn_send++, (SilcBuffer)&packet, SILC_PACKET_HEADER_LEN + packetdata.src_id_len + packetdata.dst_id_len + packetdata.padlen); diff --git a/lib/silcclient/client_ftp.c b/lib/silcclient/client_ftp.c index 5d981a23..7d26a810 100644 --- a/lib/silcclient/client_ftp.c +++ b/lib/silcclient/client_ftp.c @@ -511,7 +511,7 @@ SILC_TASK_CALLBACK(silc_client_ftp_key_agreement_final) } /* Set this as active session */ - conn->active_session = session; + conn->internal->active_session = session; out: silc_ske_free_key_material(ctx->keymat); @@ -685,15 +685,16 @@ SILC_TASK_CALLBACK(silc_client_ftp_process_key_agreement) void silc_client_ftp_free_sessions(SilcClient client, SilcClientConnection conn) { - if (conn->ftp_sessions) { + if (conn->internal->ftp_sessions) { SilcClientFtpSession session; - silc_dlist_start(conn->ftp_sessions); - while ((session = silc_dlist_get(conn->ftp_sessions)) != SILC_LIST_END) { + silc_dlist_start(conn->internal->ftp_sessions); + while ((session = silc_dlist_get(conn->internal->ftp_sessions)) + != SILC_LIST_END) { if (session->sock) session->sock->user_data = NULL; silc_client_ftp_session_free(session); } - silc_dlist_del(conn->ftp_sessions, session); + silc_dlist_del(conn->internal->ftp_sessions, session); } } @@ -704,12 +705,13 @@ void silc_client_ftp_session_free_client(SilcClientConnection conn, { SilcClientFtpSession session; - if (!conn->ftp_sessions) + if (!conn->internal->ftp_sessions) return; /* Get the session */ - silc_dlist_start(conn->ftp_sessions); - while ((session = silc_dlist_get(conn->ftp_sessions)) != SILC_LIST_END) { + silc_dlist_start(conn->internal->ftp_sessions); + while ((session = silc_dlist_get(conn->internal->ftp_sessions)) + != SILC_LIST_END) { if (session->client_entry == client_entry) { if (session->sock) session->sock->user_data = NULL; @@ -726,11 +728,11 @@ void silc_client_ftp_session_free(SilcClientFtpSession session) SILC_LOG_DEBUG(("Free session")); - if (session->conn && session->conn->ftp_sessions) - silc_dlist_del(session->conn->ftp_sessions, session); + if (session->conn && session->conn->internal->ftp_sessions) + silc_dlist_del(session->conn->internal->ftp_sessions, session); - if (session->conn && session->conn->active_session == session) - session->conn->active_session = NULL; + if (session->conn && session->conn->internal->active_session == session) + session->conn->internal->active_session = NULL; if (session->sftp) { if (session->server) @@ -759,8 +761,8 @@ void silc_client_ftp_session_free(SilcClientFtpSession session) if (session->sock->user_data) { conn = (SilcClientConnection)session->sock->user_data; - if (conn->active_session == session) - conn->active_session = NULL; + if (conn->internal->active_session == session) + conn->internal->active_session = NULL; silc_client_close_connection_real(session->client, session->sock, conn); } else { @@ -803,8 +805,9 @@ silc_client_file_send(SilcClient client, SILC_LOG_DEBUG(("Start")); /* Check for existing session for `filepath'. */ - silc_dlist_start(conn->ftp_sessions); - while ((session = silc_dlist_get(conn->ftp_sessions)) != SILC_LIST_END) { + silc_dlist_start(conn->internal->ftp_sessions); + while ((session = silc_dlist_get(conn->internal->ftp_sessions)) + != SILC_LIST_END) { if (session->filepath && !strcmp(session->filepath, filepath) && session->client_entry == client_entry) return SILC_CLIENT_FILE_ALREADY_STARTED; @@ -818,7 +821,7 @@ silc_client_file_send(SilcClient client, /* Add new session */ session = silc_calloc(1, sizeof(*session)); - session->session_id = ++conn->next_session_id; + session->session_id = ++conn->internal->next_session_id; session->client = client; session->conn = conn; session->client_entry = client_entry; @@ -826,7 +829,7 @@ silc_client_file_send(SilcClient client, session->monitor_context = monitor_context; session->filepath = strdup(filepath); session->server = TRUE; - silc_dlist_add(conn->ftp_sessions, session); + silc_dlist_add(conn->internal->ftp_sessions, session); path = silc_calloc(strlen(filepath) + 9, sizeof(*path)); silc_strncat(path, strlen(filepath) + 9, "file://", 7); @@ -910,8 +913,9 @@ silc_client_file_receive(SilcClient client, SILC_LOG_DEBUG(("Start, Session ID: %d", session_id)); /* Get the session */ - silc_dlist_start(conn->ftp_sessions); - while ((session = silc_dlist_get(conn->ftp_sessions)) != SILC_LIST_END) { + silc_dlist_start(conn->internal->ftp_sessions); + while ((session = silc_dlist_get(conn->internal->ftp_sessions)) + != SILC_LIST_END) { if (session->session_id == session_id) { break; } @@ -992,8 +996,9 @@ SilcClientFileError silc_client_file_close(SilcClient client, SILC_LOG_DEBUG(("Start, Session ID: %d", session_id)); /* Get the session */ - silc_dlist_start(conn->ftp_sessions); - while ((session = silc_dlist_get(conn->ftp_sessions)) != SILC_LIST_END) { + silc_dlist_start(conn->internal->ftp_sessions); + while ((session = silc_dlist_get(conn->internal->ftp_sessions)) + != SILC_LIST_END) { if (session->session_id == session_id) { break; } @@ -1034,8 +1039,9 @@ static void silc_client_ftp_resolve_cb(SilcClient client, client_entry = clients[0]; - silc_dlist_start(conn->ftp_sessions); - while ((session = silc_dlist_get(conn->ftp_sessions)) != SILC_LIST_END) { + silc_dlist_start(conn->internal->ftp_sessions); + while ((session = silc_dlist_get(conn->internal->ftp_sessions)) + != SILC_LIST_END) { if (session->client_entry == client_entry && !session->server) break; } @@ -1059,11 +1065,11 @@ static void silc_client_ftp_resolve_cb(SilcClient client, /* Add new session */ session = silc_calloc(1, sizeof(*session)); - session->session_id = ++conn->next_session_id; + session->session_id = ++conn->internal->next_session_id; session->client = client; session->conn = conn; session->client_entry = client_entry; - silc_dlist_add(conn->ftp_sessions, session); + silc_dlist_add(conn->internal->ftp_sessions, session); /* Let the application know */ client->internal->ops->ftp(client, conn, client_entry, @@ -1126,14 +1132,14 @@ void silc_client_ftp(SilcClient client, /* If we have active FTP session then give the packet directly to the protocol processor. */ - if (conn->active_session) { + if (conn->internal->active_session) { /* Give it to the SFTP */ - if (conn->active_session->server) - silc_sftp_server_receive_process(conn->active_session->sftp, sock, - packet); + if (conn->internal->active_session->server) + silc_sftp_server_receive_process(conn->internal->active_session->sftp, + sock, packet); else - silc_sftp_client_receive_process(conn->active_session->sftp, sock, - packet); + silc_sftp_client_receive_process(conn->internal->active_session->sftp, + sock, packet); } else { /* We don't have active session, resolve the remote client information and then try to find the correct session. */ diff --git a/lib/silcclient/client_internal.h b/lib/silcclient/client_internal.h index 8d4c4f21..d3de6db3 100644 --- a/lib/silcclient/client_internal.h +++ b/lib/silcclient/client_internal.h @@ -20,6 +20,27 @@ #ifndef CLIENT_INTERNAL_H #define CLIENT_INTERNAL_H +/* Context to hold the connection authentication request callbacks that + will be called when the server has replied back to our request about + current authentication method in the session. */ +typedef struct { + SilcConnectionAuthRequest callback; + void *context; + SilcTask timeout; +} *SilcClientConnAuthRequest; + +/* Generic rekey context for connections */ +typedef struct { + /* Current sending encryption key, provided for re-key. The `pfs' + is TRUE if the Perfect Forward Secrecy is performed in re-key. */ + unsigned char *send_enc_key; + SilcUInt32 enc_key_len; + int ske_group; + bool pfs; + SilcUInt32 timeout; + void *context; +} *SilcClientRekey; + /* Internal context for connection process. This is needed as we doing asynchronous connecting. */ typedef struct { @@ -82,6 +103,52 @@ struct SilcClientInternalStruct { char *silc_client_version; }; +/* Internal context for conn->internal in SilcClientConnection. */ +struct SilcClientConnectionInternalStruct { + /* Keys and stuff negotiated in the SKE protocol */ + SilcCipher send_key; + SilcCipher receive_key; + SilcHmac hmac_send; + SilcHmac hmac_receive; + SilcHash hash; + SilcUInt32 psn_send; + SilcUInt32 psn_receive; + + /* Client ID and Channel ID cache. Messages transmitted in SILC network + are done using different unique ID's. These are the cache for + thoses ID's used in the communication. */ + SilcIDCache client_cache; + SilcIDCache channel_cache; + SilcIDCache server_cache; + + /* Pending command queue for this connection */ + SilcDList pending_commands; + + /* Requested pings. */ + SilcClientPing *ping; + SilcUInt32 ping_count; + + /* Set away message */ + SilcClientAway *away; + + /* Re-key context */ + SilcClientRekey rekey; + + /* Authentication request context. */ + SilcClientConnAuthRequest connauth; + + /* File transmission sessions */ + SilcDList ftp_sessions; + SilcUInt32 next_session_id; + SilcClientFtpSession active_session; + + /* Requested Attributes */ + SilcHashTable attrs; + + /* Connection parameters */ + SilcClientConnectionParams params; +}; + /* Session resuming callback */ typedef void (*SilcClientResumeSessionCallback)(SilcClient client, SilcClientConnection conn, diff --git a/lib/silcclient/client_notify.c b/lib/silcclient/client_notify.c index 9c7b0bde..4517aab1 100644 --- a/lib/silcclient/client_notify.c +++ b/lib/silcclient/client_notify.c @@ -428,7 +428,7 @@ void silc_client_notify_by_server(SilcClient client, silc_client_remove_from_channels(client, conn, client_entry); /* Remove from cache */ - silc_idcache_del_by_context(conn->client_cache, client_entry); + silc_idcache_del_by_context(conn->internal->client_cache, client_entry); /* Get signoff message */ tmp = silc_argument_get_arg_type(args, 2, &tmp_len); @@ -615,10 +615,11 @@ void silc_client_notify_by_server(SilcClient client, if (tmp_nick && !strcmp(tmp, tmp_nick)) { /* Nickname didn't change. Update only the ID */ - silc_idcache_del_by_context(conn->client_cache, client_entry); + silc_idcache_del_by_context(conn->internal->client_cache, + client_entry); silc_free(client_entry->id); client_entry->id = silc_id_dup(client_id, SILC_ID_CLIENT); - silc_idcache_add(conn->client_cache, strdup(tmp), + silc_idcache_add(conn->internal->client_cache, strdup(tmp), client_entry->id, client_entry, 0, NULL); /* Notify application */ @@ -673,7 +674,7 @@ void silc_client_notify_by_server(SilcClient client, } /* Remove the old from cache */ - silc_idcache_del_by_context(conn->client_cache, client_entry); + silc_idcache_del_by_context(conn->internal->client_cache, client_entry); /* Replace old ID entry with new one on all channels. */ silc_client_replace_from_channels(client, conn, client_entry, diff --git a/lib/silcclient/client_prvmsg.c b/lib/silcclient/client_prvmsg.c index 7c251d81..4a4fc6b4 100644 --- a/lib/silcclient/client_prvmsg.c +++ b/lib/silcclient/client_prvmsg.c @@ -71,8 +71,8 @@ void silc_client_send_private_message(SilcClient client, /* We have private message specific key */ /* Get data used in the encryption */ - cipher = conn->send_key; - hmac = conn->hmac_send; + cipher = conn->internal->send_key; + hmac = conn->internal->hmac_send; block_len = silc_cipher_get_block_len(cipher); /* Set the packet context pointers. */ @@ -103,7 +103,7 @@ void silc_client_send_private_message(SilcClient client, } /* Encrypt the header and padding of the packet. */ - silc_packet_encrypt(cipher, hmac, conn->psn_send++, + silc_packet_encrypt(cipher, hmac, conn->internal->psn_send++, (SilcBuffer)&packet, SILC_PACKET_HEADER_LEN + packetdata.src_id_len + packetdata.dst_id_len + packetdata.padlen); @@ -202,7 +202,8 @@ void silc_client_private_message(SilcClient client, /* See if we are away (gone). If we are away we will reply to the sender with the set away message. */ - if (conn->away && conn->away->away && !(flags & SILC_MESSAGE_FLAG_NOREPLY)) { + if (conn->internal->away && conn->internal->away->away && + !(flags & SILC_MESSAGE_FLAG_NOREPLY)) { /* If it's me, ignore */ if (SILC_ID_CLIENT_COMPARE(remote_id, conn->local_id)) goto out; @@ -211,8 +212,8 @@ void silc_client_private_message(SilcClient client, silc_client_send_private_message(client, conn, remote_client, SILC_MESSAGE_FLAG_AUTOREPLY | SILC_MESSAGE_FLAG_NOREPLY, - conn->away->away, - strlen(conn->away->away), TRUE); + conn->internal->away->away, + strlen(conn->internal->away->away), TRUE); } out: @@ -534,7 +535,7 @@ silc_client_list_private_message_keys(SilcClient client, SilcIDCacheList list; SilcClientEntry entry; - if (!silc_idcache_get_all(conn->client_cache, &list)) + if (!silc_idcache_get_all(conn->internal->client_cache, &list)) return NULL; if (!silc_idcache_list_count(list)) { @@ -587,17 +588,17 @@ void silc_client_set_away_message(SilcClient client, SilcClientConnection conn, char *message) { - if (!message && conn->away) { - silc_free(conn->away->away); - silc_free(conn->away); - conn->away = NULL; + if (!message && conn->internal->away) { + silc_free(conn->internal->away->away); + silc_free(conn->internal->away); + conn->internal->away = NULL; } if (message) { - if (!conn->away) - conn->away = silc_calloc(1, sizeof(*conn->away)); - if (conn->away->away) - silc_free(conn->away->away); - conn->away->away = strdup(message); + if (!conn->internal->away) + conn->internal->away = silc_calloc(1, sizeof(*conn->internal->away)); + if (conn->internal->away->away) + silc_free(conn->internal->away->away); + conn->internal->away->away = strdup(message); } } diff --git a/lib/silcclient/client_resume.c b/lib/silcclient/client_resume.c index 72abe19d..5f1cced0 100644 --- a/lib/silcclient/client_resume.c +++ b/lib/silcclient/client_resume.c @@ -114,8 +114,8 @@ bool silc_client_process_detach_data(SilcClient client, SILC_LOG_DEBUG(("Start")); silc_free(conn->nickname); - silc_buffer_set(&detach, conn->params.detach_data, - conn->params.detach_data_len); + silc_buffer_set(&detach, conn->internal->params.detach_data, + conn->internal->params.detach_data_len); SILC_LOG_HEXDUMP(("Detach data"), detach.data, detach.len); @@ -264,7 +264,7 @@ void silc_client_resume_session(SilcClient client, /* Second, send IDENTIFY command of all channels we know about. These are the channels we've joined to according our detachment data. */ - if (silc_idcache_get_all(conn->channel_cache, &list)) { + if (silc_idcache_get_all(conn->internal->channel_cache, &list)) { unsigned char **res_argv = NULL; SilcUInt32 *res_argv_lens = NULL, *res_argv_types = NULL, res_argc = 0; diff --git a/lib/silcclient/command.c b/lib/silcclient/command.c index f033dc25..f1be2aab 100644 --- a/lib/silcclient/command.c +++ b/lib/silcclient/command.c @@ -108,7 +108,7 @@ void silc_client_command_pending(SilcClientConnection conn, reply->ident = ident; reply->context = context; reply->callback = callback; - silc_dlist_add(conn->pending_commands, reply); + silc_dlist_add(conn->internal->pending_commands, reply); } /* Deletes pending command by reply command type. */ @@ -119,15 +119,16 @@ void silc_client_command_pending_del(SilcClientConnection conn, { SilcClientCommandPending *r; - if (!conn->pending_commands) + if (!conn->internal->pending_commands) return; - silc_dlist_start(conn->pending_commands); - while ((r = silc_dlist_get(conn->pending_commands)) != SILC_LIST_END) { + silc_dlist_start(conn->internal->pending_commands); + while ((r = silc_dlist_get(conn->internal->pending_commands)) + != SILC_LIST_END) { if ((r->reply_cmd == reply_cmd || (r->reply_cmd == SILC_COMMAND_NONE && r->reply_check)) && r->ident == ident) { - silc_dlist_del(conn->pending_commands, r); + silc_dlist_del(conn->internal->pending_commands, r); silc_free(r); } } @@ -147,8 +148,9 @@ silc_client_command_pending_check(SilcClientConnection conn, SilcClientCommandPendingCallbacks callbacks = NULL; int i = 0; - silc_dlist_start(conn->pending_commands); - while ((r = silc_dlist_get(conn->pending_commands)) != SILC_LIST_END) { + silc_dlist_start(conn->internal->pending_commands); + while ((r = silc_dlist_get(conn->internal->pending_commands)) + != SILC_LIST_END) { if ((r->reply_cmd == command || r->reply_cmd == SILC_COMMAND_NONE) && r->ident == ident) { callbacks = silc_realloc(callbacks, sizeof(*callbacks) * (i + 1)); @@ -438,7 +440,8 @@ SILC_CLIENT_CMD_FUNC(list) name = cmd->argv[1]; /* Get the Channel ID of the channel */ - if (silc_idcache_find_by_name_one(conn->channel_cache, name, &id_cache)) { + if (silc_idcache_find_by_name_one(conn->internal->channel_cache, + name, &id_cache)) { channel = (SilcChannelEntry)id_cache->context; idp = silc_id_payload_encode(id_cache->id, SILC_ID_CHANNEL); } @@ -507,7 +510,8 @@ SILC_CLIENT_CMD_FUNC(topic) } /* Get the Channel ID of the channel */ - if (!silc_idcache_find_by_name_one(conn->channel_cache, name, &id_cache)) { + if (!silc_idcache_find_by_name_one(conn->internal->channel_cache, + name, &id_cache)) { COMMAND_ERROR(SILC_STATUS_ERR_NOT_ON_CHANNEL); goto out; } @@ -949,21 +953,23 @@ SILC_CLIENT_CMD_FUNC(ping) } /* Start counting time */ - for (i = 0; i < conn->ping_count; i++) { - if (conn->ping[i].dest_id == NULL) { - conn->ping[i].start_time = time(NULL); - conn->ping[i].dest_id = id; - conn->ping[i].dest_name = strdup(conn->remote_host); + for (i = 0; i < conn->internal->ping_count; i++) { + if (conn->internal->ping[i].dest_id == NULL) { + conn->internal->ping[i].start_time = time(NULL); + conn->internal->ping[i].dest_id = id; + conn->internal->ping[i].dest_name = strdup(conn->remote_host); break; } } - if (i >= conn->ping_count) { - i = conn->ping_count; - conn->ping = silc_realloc(conn->ping, sizeof(*conn->ping) * (i + 1)); - conn->ping[i].start_time = time(NULL); - conn->ping[i].dest_id = id; - conn->ping[i].dest_name = strdup(conn->remote_host); - conn->ping_count++; + if (i >= conn->internal->ping_count) { + i = conn->internal->ping_count; + conn->internal->ping = + silc_realloc(conn->internal->ping, + sizeof(*conn->internal->ping) * (i + 1)); + conn->internal->ping[i].start_time = time(NULL); + conn->internal->ping[i].dest_id = id; + conn->internal->ping[i].dest_name = strdup(conn->remote_host); + conn->internal->ping_count++; } /* Notify application */ @@ -1699,7 +1705,8 @@ SILC_CLIENT_CMD_FUNC(kick) } /* Get the Channel ID of the channel */ - if (!silc_idcache_find_by_name_one(conn->channel_cache, name, &id_cache)) { + if (!silc_idcache_find_by_name_one(conn->internal->channel_cache, + name, &id_cache)) { COMMAND_ERROR(SILC_STATUS_ERR_NOT_ON_CHANNEL); goto out; } @@ -1760,7 +1767,8 @@ static void silc_client_command_oper_send(unsigned char *data, /* Encode the public key authentication payload */ auth = silc_auth_public_key_auth_generate(cmd->client->public_key, cmd->client->private_key, - cmd->client->rng, conn->hash, + cmd->client->rng, + conn->internal->hash, conn->local_id, SILC_ID_CLIENT); } else { @@ -1830,7 +1838,8 @@ static void silc_client_command_silcoper_send(unsigned char *data, /* Encode the public key authentication payload */ auth = silc_auth_public_key_auth_generate(cmd->client->public_key, cmd->client->private_key, - cmd->client->rng, conn->hash, + cmd->client->rng, + conn->internal->hash, conn->local_id, SILC_ID_CLIENT); } else { diff --git a/lib/silcclient/command_reply.c b/lib/silcclient/command_reply.c index 49e7dcd9..a3284016 100644 --- a/lib/silcclient/command_reply.c +++ b/lib/silcclient/command_reply.c @@ -570,13 +570,14 @@ SILC_CLIENT_CMD_REPLY_FUNC(nick) /* Take the new nickname too */ tmp = silc_argument_get_arg_type(cmd->args, 3, &len); if (tmp) { - silc_idcache_del_by_context(conn->client_cache, conn->local_entry); + silc_idcache_del_by_context(conn->internal->client_cache, + conn->local_entry); if (conn->nickname) silc_free(conn->nickname); conn->nickname = strdup(tmp); conn->local_entry->nickname = conn->nickname; silc_client_nickname_format(cmd->client, conn, conn->local_entry); - silc_idcache_add(conn->client_cache, strdup(tmp), + silc_idcache_add(conn->internal->client_cache, strdup(tmp), conn->local_entry->id, conn->local_entry, 0, NULL); } @@ -891,26 +892,26 @@ SILC_CLIENT_CMD_REPLY_FUNC(ping) curtime = time(NULL); id = silc_id_str2id(cmd->packet->src_id, cmd->packet->src_id_len, cmd->packet->src_id_type); - if (!id || !conn->ping) { + if (!id || !conn->internal->ping) { COMMAND_REPLY_ERROR; goto out; } - for (i = 0; i < conn->ping_count; i++) { - if (!conn->ping[i].dest_id) + for (i = 0; i < conn->internal->ping_count; i++) { + if (!conn->internal->ping[i].dest_id) continue; - if (SILC_ID_SERVER_COMPARE(conn->ping[i].dest_id, id)) { - diff = curtime - conn->ping[i].start_time; + if (SILC_ID_SERVER_COMPARE(conn->internal->ping[i].dest_id, id)) { + diff = curtime - conn->internal->ping[i].start_time; SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_INFO, "Ping reply from %s: %d second%s", - conn->ping[i].dest_name, diff, + conn->internal->ping[i].dest_name, diff, diff == 1 ? "" : "s"); - conn->ping[i].start_time = 0; - silc_free(conn->ping[i].dest_id); - conn->ping[i].dest_id = NULL; - silc_free(conn->ping[i].dest_name); - conn->ping[i].dest_name = NULL; + conn->internal->ping[i].start_time = 0; + silc_free(conn->internal->ping[i].dest_id); + conn->internal->ping[i].dest_id = NULL; + silc_free(conn->internal->ping[i].dest_name); + conn->internal->ping[i].dest_name = NULL; break; } } diff --git a/lib/silcclient/idlist.c b/lib/silcclient/idlist.c index 85d28203..2e4c3707 100644 --- a/lib/silcclient/idlist.c +++ b/lib/silcclient/idlist.c @@ -50,7 +50,8 @@ SilcClientEntry *silc_client_get_clients_local(SilcClient client, bool found = FALSE; /* Find ID from cache */ - if (!silc_idcache_find_by_name(conn->client_cache, (char *)nickname, &list)) + if (!silc_idcache_find_by_name(conn->internal->client_cache, + (char *)nickname, &list)) return NULL; if (!silc_idcache_list_count(list)) { @@ -219,8 +220,8 @@ SilcClientEntry silc_idlist_get_client(SilcClient client, SILC_LOG_DEBUG(("Start")); /* Find ID from cache */ - if (!silc_idcache_find_by_name(conn->client_cache, (char *)nickname, - &list)) { + if (!silc_idcache_find_by_name(conn->internal->client_cache, + (char *)nickname, &list)) { identify: if (query) { @@ -325,7 +326,7 @@ SILC_CLIENT_CMD_FUNC(get_clients_list_callback) } /* Get the client entry */ - if (silc_idcache_find_by_id_one_ext(i->conn->client_cache, + if (silc_idcache_find_by_id_one_ext(i->conn->internal->client_cache, (void *)client_id, NULL, NULL, silc_hash_client_id_compare, NULL, @@ -401,8 +402,8 @@ void silc_client_get_clients_by_list(SilcClient client, /* Check if we have this client cached already. */ ret = - silc_idcache_find_by_id_one_ext(conn->client_cache, (void *)client_id, - NULL, NULL, + silc_idcache_find_by_id_one_ext(conn->internal->client_cache, + (void *)client_id, NULL, NULL, silc_hash_client_id_compare, NULL, &id_cache); @@ -503,8 +504,8 @@ SilcClientEntry silc_client_get_client_by_id(SilcClient client, silc_id_render(client_id, SILC_ID_CLIENT))); /* Find ID from cache */ - if (!silc_idcache_find_by_id_one_ext(conn->client_cache, (void *)client_id, - NULL, NULL, + if (!silc_idcache_find_by_id_one_ext(conn->internal->client_cache, + (void *)client_id, NULL, NULL, silc_hash_client_id_compare, NULL, &id_cache)) return NULL; @@ -622,7 +623,7 @@ silc_client_add_client(SilcClient client, SilcClientConnection conn, silc_client_nickname_format(client, conn, client_entry); /* Add client to cache, the non-formatted nickname is saved to cache */ - if (!silc_idcache_add(conn->client_cache, nick, client_entry->id, + if (!silc_idcache_add(conn->internal->client_cache, nick, client_entry->id, (void *)client_entry, 0, NULL)) { silc_free(client_entry->nickname); silc_free(client_entry->username); @@ -669,8 +670,8 @@ void silc_client_update_client(SilcClient client, if (nick) { /* Remove the old cache entry and create a new one */ - silc_idcache_del_by_context(conn->client_cache, client_entry); - silc_idcache_add(conn->client_cache, nick, client_entry->id, + silc_idcache_del_by_context(conn->internal->client_cache, client_entry); + silc_idcache_add(conn->internal->client_cache, nick, client_entry->id, client_entry, 0, NULL); } } @@ -707,7 +708,8 @@ void silc_client_del_client_entry(SilcClient client, bool silc_client_del_client(SilcClient client, SilcClientConnection conn, SilcClientEntry client_entry) { - bool ret = silc_idcache_del_by_context(conn->client_cache, client_entry); + bool ret = silc_idcache_del_by_context(conn->internal->client_cache, + client_entry); /* Remove from channels */ silc_client_remove_from_channels(client, conn, client_entry); @@ -738,7 +740,7 @@ SilcChannelEntry silc_client_add_channel(SilcClient client, NULL, NULL, NULL, TRUE); /* Put it to the ID cache */ - if (!silc_idcache_add(conn->channel_cache, channel->channel_name, + if (!silc_idcache_add(conn->internal->channel_cache, channel->channel_name, (void *)channel->id, (void *)channel, 0, NULL)) { silc_free(channel->channel_name); silc_hash_table_free(channel->user_list); @@ -770,7 +772,8 @@ static void silc_client_del_channel_foreach(void *key, void *context, bool silc_client_del_channel(SilcClient client, SilcClientConnection conn, SilcChannelEntry channel) { - bool ret = silc_idcache_del_by_context(conn->channel_cache, channel); + bool ret = silc_idcache_del_by_context(conn->internal->channel_cache, + channel); SILC_LOG_DEBUG(("Start")); @@ -815,10 +818,11 @@ bool silc_client_replace_channel_id(SilcClient client, SILC_LOG_DEBUG(("New Channel ID id(%s)", silc_id_render(new_id, SILC_ID_CHANNEL))); - silc_idcache_del_by_id(conn->channel_cache, channel->id); + silc_idcache_del_by_id(conn->internal->channel_cache, channel->id); silc_free(channel->id); channel->id = new_id; - return silc_idcache_add(conn->channel_cache, channel->channel_name, + return silc_idcache_add(conn->internal->channel_cache, + channel->channel_name, (void *)channel->id, (void *)channel, 0, NULL); } @@ -836,7 +840,7 @@ SilcChannelEntry silc_client_get_channel(SilcClient client, SILC_LOG_DEBUG(("Start")); - if (!silc_idcache_find_by_name_one(conn->channel_cache, channel, + if (!silc_idcache_find_by_name_one(conn->internal->channel_cache, channel, &id_cache)) return NULL; @@ -860,7 +864,7 @@ SilcChannelEntry silc_client_get_channel_by_id(SilcClient client, SILC_LOG_DEBUG(("Start")); - if (!silc_idcache_find_by_id_one(conn->channel_cache, channel_id, + if (!silc_idcache_find_by_id_one(conn->internal->channel_cache, channel_id, &id_cache)) return NULL; @@ -946,8 +950,8 @@ SilcServerEntry silc_client_get_server(SilcClient client, SILC_LOG_DEBUG(("Start")); - if (!silc_idcache_find_by_name_one(conn->server_cache, server_name, - &id_cache)) + if (!silc_idcache_find_by_name_one(conn->internal->server_cache, + server_name, &id_cache)) return NULL; entry = (SilcServerEntry)id_cache->context; @@ -966,8 +970,8 @@ SilcServerEntry silc_client_get_server_by_id(SilcClient client, SILC_LOG_DEBUG(("Start")); - if (!silc_idcache_find_by_id_one(conn->server_cache, (void *)server_id, - &id_cache)) + if (!silc_idcache_find_by_id_one(conn->internal->server_cache, + (void *)server_id, &id_cache)) return NULL; entry = (SilcServerEntry)id_cache->context; @@ -998,7 +1002,8 @@ SilcServerEntry silc_client_add_server(SilcClient client, server_entry->server_info = strdup(server_info); /* Add server to cache */ - if (!silc_idcache_add(conn->server_cache, server_entry->server_name, + if (!silc_idcache_add(conn->internal->server_cache, + server_entry->server_name, server_entry->server_id, server_entry, 0, NULL)) { silc_free(server_entry->server_id); silc_free(server_entry->server_name); @@ -1015,7 +1020,7 @@ SilcServerEntry silc_client_add_server(SilcClient client, bool silc_client_del_server(SilcClient client, SilcClientConnection conn, SilcServerEntry server) { - bool ret = silc_idcache_del_by_context(conn->server_cache, server); + bool ret = silc_idcache_del_by_context(conn->internal->server_cache, server); silc_free(server->server_name); silc_free(server->server_info); silc_free(server->server_id); @@ -1036,10 +1041,10 @@ void silc_client_update_server(SilcClient client, if (server_name && (!server_entry->server_name || strcmp(server_entry->server_name, server_name))) { - silc_idcache_del_by_context(conn->server_cache, server_entry); + silc_idcache_del_by_context(conn->internal->server_cache, server_entry); silc_free(server_entry->server_name); server_entry->server_name = strdup(server_name); - silc_idcache_add(conn->server_cache, server_entry->server_name, + silc_idcache_add(conn->internal->server_cache, server_entry->server_name, server_entry->server_id, server_entry, 0, NULL); } diff --git a/lib/silcclient/protocol.c b/lib/silcclient/protocol.c index 122ffdfc..fb834aa0 100644 --- a/lib/silcclient/protocol.c +++ b/lib/silcclient/protocol.c @@ -122,47 +122,49 @@ void silc_client_protocol_ke_set_keys(SilcSKE ske, SILC_LOG_DEBUG(("Setting new keys into use")); /* Allocate cipher to be used in the communication */ - silc_cipher_alloc((char *)cname, &conn->send_key); - silc_cipher_alloc((char *)cname, &conn->receive_key); - silc_hmac_alloc((char *)silc_hmac_get_name(hmac), NULL, &conn->hmac_send); - silc_hmac_alloc((char *)silc_hmac_get_name(hmac), NULL, &conn->hmac_receive); + silc_cipher_alloc((char *)cname, &conn->internal->send_key); + silc_cipher_alloc((char *)cname, &conn->internal->receive_key); + silc_hmac_alloc((char *)silc_hmac_get_name(hmac), NULL, + &conn->internal->hmac_send); + silc_hmac_alloc((char *)silc_hmac_get_name(hmac), NULL, + &conn->internal->hmac_receive); if (is_responder == TRUE) { - silc_cipher_set_key(conn->send_key, keymat->receive_enc_key, + silc_cipher_set_key(conn->internal->send_key, keymat->receive_enc_key, keymat->enc_key_len); - silc_cipher_set_iv(conn->send_key, keymat->receive_iv); - silc_cipher_set_key(conn->receive_key, keymat->send_enc_key, + silc_cipher_set_iv(conn->internal->send_key, keymat->receive_iv); + silc_cipher_set_key(conn->internal->receive_key, keymat->send_enc_key, keymat->enc_key_len); - silc_cipher_set_iv(conn->receive_key, keymat->send_iv); - silc_hmac_set_key(conn->hmac_send, keymat->receive_hmac_key, + silc_cipher_set_iv(conn->internal->receive_key, keymat->send_iv); + silc_hmac_set_key(conn->internal->hmac_send, keymat->receive_hmac_key, keymat->hmac_key_len); - silc_hmac_set_key(conn->hmac_receive, keymat->send_hmac_key, + silc_hmac_set_key(conn->internal->hmac_receive, keymat->send_hmac_key, keymat->hmac_key_len); } else { - silc_cipher_set_key(conn->send_key, keymat->send_enc_key, + silc_cipher_set_key(conn->internal->send_key, keymat->send_enc_key, keymat->enc_key_len); - silc_cipher_set_iv(conn->send_key, keymat->send_iv); - silc_cipher_set_key(conn->receive_key, keymat->receive_enc_key, + silc_cipher_set_iv(conn->internal->send_key, keymat->send_iv); + silc_cipher_set_key(conn->internal->receive_key, keymat->receive_enc_key, keymat->enc_key_len); - silc_cipher_set_iv(conn->receive_key, keymat->receive_iv); - silc_hmac_set_key(conn->hmac_send, keymat->send_hmac_key, + silc_cipher_set_iv(conn->internal->receive_key, keymat->receive_iv); + silc_hmac_set_key(conn->internal->hmac_send, keymat->send_hmac_key, keymat->hmac_key_len); - silc_hmac_set_key(conn->hmac_receive, keymat->receive_hmac_key, + silc_hmac_set_key(conn->internal->hmac_receive, keymat->receive_hmac_key, keymat->hmac_key_len); } /* Rekey stuff */ - conn->rekey = silc_calloc(1, sizeof(*conn->rekey)); - conn->rekey->send_enc_key = silc_memdup(keymat->send_enc_key, - keymat->enc_key_len / 8); - conn->rekey->enc_key_len = keymat->enc_key_len / 8; + conn->internal->rekey = silc_calloc(1, sizeof(*conn->internal->rekey)); + conn->internal->rekey->send_enc_key = silc_memdup(keymat->send_enc_key, + keymat->enc_key_len / 8); + conn->internal->rekey->enc_key_len = keymat->enc_key_len / 8; if (ske->start_payload->flags & SILC_SKE_SP_FLAG_PFS) - conn->rekey->pfs = TRUE; - conn->rekey->ske_group = silc_ske_group_get_number(group); + conn->internal->rekey->pfs = TRUE; + conn->internal->rekey->ske_group = silc_ske_group_get_number(group); /* Save the HASH function */ - silc_hash_alloc(silc_hash_get_name(hash), &conn->hash); + silc_hash_alloc(silc_hash_get_name(hash), &conn->internal->hash); } /* Checks the version string of the server. */ @@ -744,41 +746,42 @@ silc_client_protocol_rekey_validate(SilcClient client, if (ctx->responder == TRUE) { if (send) { - silc_cipher_set_key(conn->send_key, keymat->receive_enc_key, + silc_cipher_set_key(conn->internal->send_key, keymat->receive_enc_key, keymat->enc_key_len); - silc_cipher_set_iv(conn->send_key, keymat->receive_iv); - silc_hmac_set_key(conn->hmac_send, keymat->receive_hmac_key, + silc_cipher_set_iv(conn->internal->send_key, keymat->receive_iv); + silc_hmac_set_key(conn->internal->hmac_send, keymat->receive_hmac_key, keymat->hmac_key_len); } else { - silc_cipher_set_key(conn->receive_key, keymat->send_enc_key, + silc_cipher_set_key(conn->internal->receive_key, keymat->send_enc_key, keymat->enc_key_len); - silc_cipher_set_iv(conn->receive_key, keymat->send_iv); - silc_hmac_set_key(conn->hmac_receive, keymat->send_hmac_key, + silc_cipher_set_iv(conn->internal->receive_key, keymat->send_iv); + silc_hmac_set_key(conn->internal->hmac_receive, keymat->send_hmac_key, keymat->hmac_key_len); } } else { if (send) { - silc_cipher_set_key(conn->send_key, keymat->send_enc_key, + silc_cipher_set_key(conn->internal->send_key, keymat->send_enc_key, keymat->enc_key_len); - silc_cipher_set_iv(conn->send_key, keymat->send_iv); - silc_hmac_set_key(conn->hmac_send, keymat->send_hmac_key, + silc_cipher_set_iv(conn->internal->send_key, keymat->send_iv); + silc_hmac_set_key(conn->internal->hmac_send, keymat->send_hmac_key, keymat->hmac_key_len); } else { - silc_cipher_set_key(conn->receive_key, keymat->receive_enc_key, - keymat->enc_key_len); - silc_cipher_set_iv(conn->receive_key, keymat->receive_iv); - silc_hmac_set_key(conn->hmac_receive, keymat->receive_hmac_key, - keymat->hmac_key_len); + silc_cipher_set_key(conn->internal->receive_key, + keymat->receive_enc_key, keymat->enc_key_len); + silc_cipher_set_iv(conn->internal->receive_key, keymat->receive_iv); + silc_hmac_set_key(conn->internal->hmac_receive, + keymat->receive_hmac_key, keymat->hmac_key_len); } } /* Save the current sending encryption key */ if (!send) { - memset(conn->rekey->send_enc_key, 0, conn->rekey->enc_key_len); - silc_free(conn->rekey->send_enc_key); - conn->rekey->send_enc_key = silc_memdup(keymat->send_enc_key, - keymat->enc_key_len / 8); - conn->rekey->enc_key_len = keymat->enc_key_len / 8; + memset(conn->internal->rekey->send_enc_key, 0, + conn->internal->rekey->enc_key_len); + silc_free(conn->internal->rekey->send_enc_key); + conn->internal->rekey->send_enc_key = silc_memdup(keymat->send_enc_key, + keymat->enc_key_len / 8); + conn->internal->rekey->enc_key_len = keymat->enc_key_len / 8; } } @@ -792,18 +795,18 @@ silc_client_protocol_rekey_generate(SilcClient client, { SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data; SilcSKEKeyMaterial *keymat; - SilcUInt32 key_len = silc_cipher_get_key_len(conn->send_key); - SilcUInt32 hash_len = silc_hash_len(conn->hash); + SilcUInt32 key_len = silc_cipher_get_key_len(conn->internal->send_key); + SilcUInt32 hash_len = silc_hash_len(conn->internal->hash); SILC_LOG_DEBUG(("Generating new %s session keys (no PFS)", send ? "sending" : "receiving")); /* Generate the new key */ keymat = silc_calloc(1, sizeof(*keymat)); - silc_ske_process_key_material_data(conn->rekey->send_enc_key, - conn->rekey->enc_key_len, + silc_ske_process_key_material_data(conn->internal->rekey->send_enc_key, + conn->internal->rekey->enc_key_len, 16, key_len, hash_len, - conn->hash, keymat); + conn->internal->hash, keymat); /* Set the keys into use */ silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send); @@ -821,8 +824,8 @@ silc_client_protocol_rekey_generate_pfs(SilcClient client, { SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data; SilcSKEKeyMaterial *keymat; - SilcUInt32 key_len = silc_cipher_get_key_len(conn->send_key); - SilcUInt32 hash_len = silc_hash_len(conn->hash); + SilcUInt32 key_len = silc_cipher_get_key_len(conn->internal->send_key); + SilcUInt32 hash_len = silc_hash_len(conn->internal->hash); unsigned char *tmpbuf; SilcUInt32 klen; @@ -835,7 +838,7 @@ silc_client_protocol_rekey_generate_pfs(SilcClient client, /* Generate the new key */ keymat = silc_calloc(1, sizeof(*keymat)); silc_ske_process_key_material_data(tmpbuf, klen, 16, key_len, hash_len, - conn->hash, keymat); + conn->internal->hash, keymat); /* Set the keys into use */ silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send); @@ -908,7 +911,7 @@ SILC_TASK_CALLBACK(silc_client_protocol_rekey) ctx->ske = silc_ske_alloc(client->rng, client); ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop)); - silc_ske_group_get_by_number(conn->rekey->ske_group, + silc_ske_group_get_by_number(conn->internal->rekey->ske_group, &ctx->ske->prop->group); silc_ske_set_callbacks(ctx->ske, @@ -964,7 +967,7 @@ SILC_TASK_CALLBACK(silc_client_protocol_rekey) */ ctx->ske = silc_ske_alloc(client->rng, client); ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop)); - silc_ske_group_get_by_number(conn->rekey->ske_group, + silc_ske_group_get_by_number(conn->internal->rekey->ske_group, &ctx->ske->prop->group); silc_ske_set_callbacks(ctx->ske, diff --git a/lib/silcclient/silcclient.h b/lib/silcclient/silcclient.h index 92a24dfa..43c1bee9 100644 --- a/lib/silcclient/silcclient.h +++ b/lib/silcclient/silcclient.h @@ -54,24 +54,129 @@ extern "C" { #endif -/* Forward declarations */ -typedef struct SilcClientStruct *SilcClient; -typedef struct SilcClientConnectionStruct *SilcClientConnection; -typedef struct SilcClientPingStruct SilcClientPing; -typedef struct SilcClientAwayStruct SilcClientAway; -typedef struct SilcClientKeyAgreementStruct *SilcClientKeyAgreement; -typedef struct SilcClientFtpSessionStruct *SilcClientFtpSession; -typedef struct SilcClientEntryStruct *SilcClientEntry; -typedef struct SilcChannelEntryStruct *SilcChannelEntry; -typedef struct SilcServerEntryStruct *SilcServerEntry; -typedef struct SilcClientCommandStruct *SilcClientCommand; -typedef struct SilcClientCommandContextStruct *SilcClientCommandContext; -typedef struct SilcClientCommandReplyContextStruct - *SilcClientCommandReplyContext; -typedef struct SilcChannelUserStruct *SilcChannelUser; +#include "client.h" /* General definitions */ +/****s* silcclient/SilcClientAPI/SilcClient + * + * NAME + * + * typedef struct SilcClientStruct { ... } *SilcClient + * + * DESCRIPTION + * + * This is the actual SILC Client structure which represents one + * SILC Client. It is allocated with the silc_client_alloc function + * and given as argument to all SILC Client Library functions. It + * is initialized with silc_client_init function, and freed with + * silc_client_free function. + * + * SOURCE + */ +struct SilcClientStruct { + /* + * The following fields are set by application + */ + char *nickname; /* Nickname, MAY be set by application */ + char *username; /* Username, MUST be set by application */ + char *hostname; /* hostname, MUST be set by application */ + char *realname; /* Real name, MUST be set be application */ + + SilcPublicKey public_key; /* Public key of user, set by application */ + SilcPrivateKey private_key; /* Private key of user, set by application */ + SilcPKCS pkcs; /* PKCS allocated by application */ + + /* + * The following fields are set by the library + */ + + /* Scheduler, set by library. Application may use this pointer. */ + SilcSchedule schedule; + + /* Random Number Generator. Application should use this as its primary + random number generator. */ + SilcRng rng; + + /* Application specific user data pointer. Client library does not + touch this. This the context sent as argument to silc_client_alloc. + Application can use it freely. */ + void *application; + + /* Generic hash context for application usage */ + SilcHash md5hash; + SilcHash sha1hash; + + /* Internal data for client library. Application cannot access this + data at all. */ + SilcClientInternal internal; +}; +/***/ + +/****s* silcclient/SilcClientAPI/SilcClientConnection + * + * NAME + * + * typedef struct SilcClientConnectionStruct { ... } + * *SilcClientConnection + * + * DESCRIPTION + * + * This structure represents a connection. When connection is created + * to server this is context is returned to the application in the + * "connected" client operation. It includes all the important + * data for the session, such as nickname, local and remote IDs, and + * other information. + * + * SOURCE + */ +struct SilcClientConnectionStruct { + /* + * Local data + */ + char *nickname; /* Current nickname */ + SilcClientEntry local_entry; /* Own Client Entry */ + SilcClientID *local_id; /* Current Client ID */ + unsigned char *local_id_data; /* Current Client ID decoded */ + SilcUInt32 local_id_data_len; + + /* + * Remote data + */ + char *remote_host; /* Remote host name */ + int remote_port; /* Remote port */ + SilcServerID *remote_id; /* Remote Server ID */ + unsigned char *remote_id_data; /* Remote Server ID decoded */ + SilcUInt32 remote_id_data_len; + + /* + * Common data + */ + + /* User data context. Library does not touch this. Application may + freely set and use this pointer for its needs. */ + void *context; + + /* Pointer back to the SilcClient. Application may use this. */ + SilcClient client; + + /* Current channel. Application may use and set this pointer if needed. */ + SilcChannelEntry current_channel; + + /* Socket connection object for this connection. Application may + use this if needed. The sock->user_data is back pointer to this + structure. */ + SilcSocketConnection sock; + + /* Current command identifier, 0 not used */ + SilcUInt16 cmd_ident; + + /* Internal data for client library. Application cannot access this + data at all. */ + SilcClientConnectionInternal internal; +}; +/***/ + /****d* silcclient/SilcClientAPI/SilcKeyAgreementStatus * * NAME @@ -1938,7 +2043,6 @@ void silc_client_set_away_message(SilcClient client, SilcClientConnection conn, char *message); - /****f* silcclient/SilcClientAPI/SilcConnectionAuthRequest * * SYNOPSIS @@ -2329,7 +2433,6 @@ void silc_client_packet_send(SilcClient client, SilcUInt32 data_len, bool force_send); -#include "client.h" #include "command.h" #include "command_reply.h" #include "idlist.h" -- 2.24.0