X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=blobdiff_plain;f=lib%2Fsilcclient%2Fclient.c;h=745cb698b52daf343e7233769ab7df0f770f7c00;hp=d8f7dbdea3f6e7633bc04e99fda198fd0db8ebdf;hb=382d15d447b7a95390decfa783836ae4fe255b3d;hpb=9b47b4cbecca281ab183fa2cf4c590848c0ce9cc diff --git a/lib/silcclient/client.c b/lib/silcclient/client.c index d8f7dbde..745cb698 100644 --- a/lib/silcclient/client.c +++ b/lib/silcclient/client.c @@ -26,7 +26,6 @@ SILC_TASK_CALLBACK(silc_client_connect_to_server_start); SILC_TASK_CALLBACK(silc_client_connect_to_server_second); SILC_TASK_CALLBACK(silc_client_connect_to_server_final); -SILC_TASK_CALLBACK(silc_client_rekey_callback); SILC_TASK_CALLBACK(silc_client_rekey_final); static bool silc_client_packet_parse(SilcPacketParserContext *parser_context, @@ -47,7 +46,7 @@ void silc_client_resolve_auth_method(bool success, SilcClient silc_client_alloc(SilcClientOperations *ops, SilcClientParams *params, void *application, - const char *silc_version) + const char *version_string) { SilcClient new_client; @@ -58,7 +57,9 @@ SilcClient silc_client_alloc(SilcClientOperations *ops, new_client->internal->ops = ops; new_client->internal->params = silc_calloc(1, sizeof(*new_client->internal->params)); - new_client->internal->silc_client_version = strdup(silc_version); + if (!version_string) + version_string = silc_version_string; + new_client->internal->silc_client_version = strdup(version_string); if (params) memcpy(new_client->internal->params, params, sizeof(*params)); @@ -87,6 +88,16 @@ void silc_client_free(SilcClient client) if (client->rng) silc_rng_free(client->rng); + silc_cipher_unregister_all(); + silc_pkcs_unregister_all(); + silc_hash_unregister_all(); + silc_hmac_unregister_all(); + + silc_hash_free(client->md5hash); + silc_hash_free(client->sha1hash); + silc_hmac_free(client->internal->md5hmac); + silc_hmac_free(client->internal->sha1hmac); + silc_cipher_free(client->internal->none_cipher); silc_free(client->internal->params); silc_free(client->internal->silc_client_version); silc_free(client->internal); @@ -98,10 +109,23 @@ void silc_client_free(SilcClient client) the client ready to be run. One must call silc_client_run to run the client. Returns FALSE if error occured, TRUE otherwise. */ -int silc_client_init(SilcClient client) +bool silc_client_init(SilcClient client) { SILC_LOG_DEBUG(("Initializing client")); + assert(client); + assert(client->username); + assert(client->hostname); + assert(client->realname); + + /* Initialize the crypto library. If application has done this already + this has no effect. Also, we will not be overriding something + application might have registered earlier. */ + silc_cipher_register_default(); + silc_pkcs_register_default(); + silc_hash_register_default(); + silc_hmac_register_default(); + /* Initialize hash functions for client to use */ silc_hash_alloc("md5", &client->md5hash); silc_hash_alloc("sha1", &client->sha1hash); @@ -153,6 +177,11 @@ void silc_client_run(SilcClient client) { SILC_LOG_DEBUG(("Running client")); + assert(client); + assert(client->pkcs); + assert(client->public_key); + assert(client->private_key); + /* Start the scheduler, the heart of the SILC client. When this returns the program will be terminated. */ silc_schedule(client->schedule); @@ -197,24 +226,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 */ @@ -241,15 +272,79 @@ void silc_client_del_connection(SilcClient client, SilcClientConnection conn) for (i = 0; i < client->internal->conns_count; i++) if (client->internal->conns[i] == conn) { + /* Free all cache entries */ + SilcIDCacheList list; + SilcIDCacheEntry entry; + SilcClientCommandPending *r; + bool ret; + + 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); + ret = silc_idcache_list_next(list, &entry); + } + silc_idcache_list_free(list); + } - 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); + 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); + ret = silc_idcache_list_next(list, &entry); + } + silc_idcache_list_free(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); + ret = silc_idcache_list_next(list, &entry); + } + silc_idcache_list_free(list); + } + + /* Clear ID caches */ + 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. */ silc_free(conn->remote_host); - if (conn->ftp_sessions) - silc_dlist_uninit(conn->ftp_sessions); + silc_free(conn->local_id_data); + 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); + silc_free(conn->internal->rekey); + + if (conn->internal->active_session) { + conn->sock->user_data = NULL; + silc_client_ftp_session_free(conn->internal->active_session); + conn->internal->active_session = NULL; + } + + silc_client_ftp_free_sessions(client, conn); + + if (conn->internal->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); + silc_dlist_uninit(conn->internal->pending_commands); + } + + silc_free(conn->internal); + memset(conn, 0, sizeof(*conn)); silc_free(conn); client->internal->conns[i] = NULL; @@ -341,7 +436,7 @@ silc_client_connect_to_server_internal(SilcClientInternalConnectContext *ctx) case then this function is not used at all. When the connecting is done the `connect' client operation is called. */ -int silc_client_connect_to_server(SilcClient client, +bool silc_client_connect_to_server(SilcClient client, SilcClientConnectionParams *params, int port, char *host, void *context) { @@ -363,7 +458,7 @@ int silc_client_connect_to_server(SilcClient client, ctx->client = client; ctx->conn = conn; ctx->host = strdup(host); - ctx->port = port; + ctx->port = port ? port : 706; ctx->tries = 0; /* Do the actual connecting process */ @@ -416,7 +511,7 @@ static void silc_client_start_key_exchange_cb(SilcSocketConnection sock, client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR, "Error: Could not start key exchange protocol"); silc_net_close_connection(conn->sock->sock); - client->internal->ops->connect(client, conn, SILC_CLIENT_CONN_ERROR); + client->internal->ops->connected(client, conn, SILC_CLIENT_CONN_ERROR); return; } conn->sock->protocol = protocol; @@ -445,6 +540,10 @@ void silc_client_start_key_exchange(SilcClient client, SilcClientConnection conn, int fd) { + assert(client->pkcs); + assert(client->public_key); + assert(client->private_key); + /* Allocate new socket connection object */ silc_socket_alloc(fd, SILC_SOCKET_TYPE_SERVER, (void *)conn, &conn->sock); @@ -471,8 +570,8 @@ SILC_TASK_CALLBACK(silc_client_connect_failure) (SilcClientKEInternalContext *)context; SilcClient client = (SilcClient)ctx->client; - client->internal->ops->connect(client, ctx->sock->user_data, - SILC_CLIENT_CONN_ERROR); + client->internal->ops->connected(client, ctx->sock->user_data, + SILC_CLIENT_CONN_ERROR); if (ctx->packet) silc_packet_context_free(ctx->packet); silc_free(ctx); @@ -487,8 +586,8 @@ SILC_TASK_CALLBACK(silc_client_connect_failure_auth) (SilcClientConnAuthInternalContext *)context; SilcClient client = (SilcClient)ctx->client; - client->internal->ops->connect(client, ctx->sock->user_data, - SILC_CLIENT_CONN_ERROR); + client->internal->ops->connected(client, ctx->sock->user_data, + SILC_CLIENT_CONN_ERROR); silc_free(ctx); } @@ -536,7 +635,7 @@ SILC_TASK_CALLBACK(silc_client_connect_to_server_start) silc_free(ctx); /* Notify application of failure */ - client->internal->ops->connect(client, conn, SILC_CLIENT_CONN_ERROR); + client->internal->ops->connected(client, conn, SILC_CLIENT_CONN_ERROR); silc_client_del_connection(client, conn); } return; @@ -692,7 +791,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; @@ -712,7 +811,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); @@ -764,11 +864,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); @@ -799,7 +899,7 @@ SILC_TASK_CALLBACK(silc_client_connect_to_server_final) is used directly only in special cases. Normal cases should use silc_server_packet_send. Returns < 0 on error. */ -int silc_client_packet_send_real(SilcClient client, +bool silc_client_packet_send_real(SilcClient client, SilcSocketConnection sock, bool force_send) { @@ -894,14 +994,14 @@ SILC_TASK_CALLBACK_GLOBAL(silc_client_packet_process) close the connection */ if (SILC_IS_DISCONNECTING(sock)) { if (sock == conn->sock && sock->type != SILC_SOCKET_TYPE_CLIENT) - client->internal->ops->disconnect(client, conn, 0, NULL); + client->internal->ops->disconnected(client, conn, 0, NULL); silc_client_close_connection_real(client, sock, conn); return; } SILC_LOG_DEBUG(("EOF from connection %d", sock->sock)); if (sock == conn->sock && sock->type != SILC_SOCKET_TYPE_CLIENT) - client->internal->ops->disconnect(client, conn, 0, NULL); + client->internal->ops->disconnected(client, conn, 0, NULL); silc_client_close_connection_real(client, sock, conn); return; } @@ -909,8 +1009,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, @@ -930,14 +1031,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); @@ -960,11 +1061,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, @@ -1282,7 +1384,7 @@ void silc_client_packet_send(SilcClient client, SilcHmac hmac, unsigned char *data, SilcUInt32 data_len, - int force_send) + bool force_send) { SilcPacketContext packetdata; const SilcBufferStruct packet; @@ -1296,11 +1398,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; @@ -1308,7 +1410,13 @@ void silc_client_packet_send(SilcClient client, } if (hmac) - sequence = ((SilcClientConnection)sock->user_data)->psn_send++; + sequence = ((SilcClientConnection)sock->user_data)->internal->psn_send++; + + /* Check for mandatory rekey */ + if (sequence == SILC_CLIENT_REKEY_THRESHOLD) + silc_schedule_task_add(client->schedule, sock->sock, + silc_client_rekey_callback, sock, 0, 1, + SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL); } block_len = cipher ? silc_cipher_get_block_len(cipher) : 0; @@ -1341,7 +1449,10 @@ void silc_client_packet_send(SilcClient client, packetdata.dst_id_len)); packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN + packetdata.src_id_len + packetdata.dst_id_len; - packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen, block_len); + if (type == SILC_PACKET_CONNECTION_AUTH) + SILC_PACKET_PADLEN_MAX(packetdata.truelen, block_len, packetdata.padlen); + else + SILC_PACKET_PADLEN(packetdata.truelen, block_len, packetdata.padlen); /* Create the outgoing packet */ if (!silc_packet_assemble(&packetdata, client->rng, cipher, hmac, sock, @@ -1362,6 +1473,25 @@ void silc_client_packet_send(SilcClient client, silc_client_packet_send_real(client, sock, force_send); } +/* Packet sending routine for application. This is the only routine that + is provided for application to send SILC packets. */ + +bool silc_client_send_packet(SilcClient client, + SilcClientConnection conn, + SilcPacketType type, + const unsigned char *data, + SilcUInt32 data_len) +{ + + assert(client); + if (!conn) + return FALSE; + + silc_client_packet_send(client, conn->sock, type, NULL, 0, NULL, NULL, + (unsigned char *)data, data_len, TRUE); + return TRUE; +} + void silc_client_packet_queue_purge(SilcClient client, SilcSocketConnection sock) { @@ -1416,7 +1546,7 @@ void silc_client_close_connection_real(SilcClient client, sock->protocol->state = SILC_PROTOCOL_STATE_ERROR; silc_protocol_execute_final(sock->protocol, client->schedule); /* The application will recall this function with these protocols - (the ops->connect client operation). */ + (the ops->connected client operation). */ return; } else { sock->protocol->state = SILC_PROTOCOL_STATE_ERROR; @@ -1426,82 +1556,8 @@ void silc_client_close_connection_real(SilcClient client, } /* Free everything */ - if (del && sock->user_data) { - /* Free all cache entries */ - SilcIDCacheList list; - SilcIDCacheEntry entry; - SilcClientCommandPending *r; - bool ret; - - if (silc_idcache_get_all(conn->client_cache, &list)) { - ret = silc_idcache_list_first(list, &entry); - while (ret) { - silc_client_del_client(client, conn, entry->context); - ret = silc_idcache_list_next(list, &entry); - } - silc_idcache_list_free(list); - } - - if (silc_idcache_get_all(conn->channel_cache, &list)) { - ret = silc_idcache_list_first(list, &entry); - while (ret) { - silc_client_del_channel(client, conn, entry->context); - ret = silc_idcache_list_next(list, &entry); - } - silc_idcache_list_free(list); - } - - if (silc_idcache_get_all(conn->server_cache, &list)) { - ret = silc_idcache_list_first(list, &entry); - while (ret) { - silc_client_del_server(client, conn, entry->context); - ret = silc_idcache_list_next(list, &entry); - } - silc_idcache_list_free(list); - } - - /* 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); - - /* Free data (my ID is freed in above silc_client_del_client). - conn->nickname is freed when freeing the local_entry->nickname. */ - if (conn->remote_host) - 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) { - sock->user_data = NULL; - silc_client_ftp_session_free(conn->active_session); - conn->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); - - memset(conn, 0, sizeof(*conn)); + if (del && sock->user_data) silc_client_del_connection(client, conn); - } silc_socket_free(sock); } @@ -1555,7 +1611,7 @@ void silc_client_disconnected_by_server(SilcClient client, conn = (SilcClientConnection)sock->user_data; if (sock == conn->sock && sock->type != SILC_SOCKET_TYPE_CLIENT) - client->internal->ops->disconnect(client, conn, status, message); + client->internal->ops->disconnected(client, conn, status, message); silc_free(message); @@ -1589,10 +1645,10 @@ SILC_TASK_CALLBACK(silc_client_send_auto_nick) { SilcClientConnection conn = (SilcClientConnection)context; SilcClient client = conn->client; - - silc_client_command_send(client, conn, SILC_COMMAND_NICK, - ++conn->cmd_ident, 1, 1, - client->nickname, strlen(client->nickname)); + if (client) + silc_client_command_send(client, conn, SILC_COMMAND_NICK, + ++conn->cmd_ident, 1, 1, + client->nickname, strlen(client->nickname)); } /* Client session resuming callback. If the session was resumed @@ -1608,9 +1664,9 @@ static void silc_client_resume_session_cb(SilcClient client, SilcBuffer sidp; /* Notify application that connection is created to server */ - client->internal->ops->connect(client, conn, success ? - SILC_CLIENT_CONN_SUCCESS_RESUME : - SILC_CLIENT_CONN_ERROR); + client->internal->ops->connected(client, conn, success ? + SILC_CLIENT_CONN_SUCCESS_RESUME : + SILC_CLIENT_CONN_ERROR); if (success) { /* Issue INFO command to fetch the real server name and server @@ -1647,7 +1703,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); } @@ -1677,7 +1734,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) { @@ -1693,7 +1751,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)) @@ -1703,7 +1761,7 @@ void silc_client_receive_new_id(SilcClient client, /* Notify application of successful connection. We do it here now that we've received the Client ID and are allowed to send traffic. */ - client->internal->ops->connect(client, conn, SILC_CLIENT_CONN_SUCCESS); + client->internal->ops->connected(client, conn, SILC_CLIENT_CONN_SUCCESS); /* Issue INFO command to fetch the real server name and server information and other stuff. */ @@ -1792,11 +1850,11 @@ void silc_client_process_failure(SilcClient client, /* A timeout callback for the re-key. We will be the initiator of the re-key protocol. */ -SILC_TASK_CALLBACK(silc_client_rekey_callback) +SILC_TASK_CALLBACK_GLOBAL(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; @@ -1808,7 +1866,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. */ @@ -1822,7 +1880,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); } @@ -1883,7 +1941,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 */ @@ -1896,14 +1954,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 @@ -1914,16 +1972,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 @@ -1943,14 +2001,15 @@ silc_client_request_authentication_method(SilcClient client, SilcClientConnAuthRequest connauth; SilcBuffer packet; + assert(client && conn); connauth = silc_calloc(1, sizeof(*connauth)); 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);