X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcclient%2Fclient_connect.c;h=de87143f047ff3f9dc6be0eb51df4c66b2743fd9;hb=52e57c880aba9c5e89f59d962eb9af75670b76e0;hp=06215fb8c47f1c7f2d93ae08fbc892bdc799c36f;hpb=8a6279964422ae932dcf5af1a32616cfcbde5a19;p=silc.git diff --git a/lib/silcclient/client_connect.c b/lib/silcclient/client_connect.c index 06215fb8..de87143f 100644 --- a/lib/silcclient/client_connect.c +++ b/lib/silcclient/client_connect.c @@ -79,8 +79,7 @@ static void silc_client_connect_callback(SilcNetStatus status, if (status != SILC_NET_OK) { /* Notify application of failure */ SILC_LOG_DEBUG(("Connecting failed")); - conn->callback(client, conn, SILC_CLIENT_CONN_ERROR, 0, - NULL, conn->callback_context); + conn->internal->status = SILC_CLIENT_CONN_ERROR; silc_fsm_next(fsm, silc_client_st_connect_error); SILC_FSM_CALL_CONTINUE(fsm); return; @@ -88,7 +87,7 @@ static void silc_client_connect_callback(SilcNetStatus status, /* Connection created successfully */ SILC_LOG_DEBUG(("Connected")); - conn->stream = (void *)stream; + conn->internal->user_stream = stream; SILC_FSM_CALL_CONTINUE(fsm); } @@ -96,7 +95,7 @@ static void silc_client_connect_callback(SilcNetStatus status, static void silc_client_ke_verify_key_cb(SilcBool success, void *context) { - VerifyKeyContext verify = (VerifyKeyContext)context; + SilcVerifyKeyContext verify = context; SILC_LOG_DEBUG(("Start")); @@ -119,7 +118,7 @@ static void silc_client_ke_verify_key(SilcSKE ske, SilcFSMThread fsm = context; SilcClientConnection conn = silc_fsm_get_context(fsm); SilcClient client = conn->client; - VerifyKeyContext verify; + SilcVerifyKeyContext verify; /* If we provided repository for SKE and we got here the key was not found from the repository. */ @@ -176,10 +175,11 @@ static void silc_client_ke_completion(SilcSKE ske, conn->remote_host, silc_ske_map_status(status)); + conn->internal->status = SILC_CLIENT_CONN_ERROR_KE; silc_ske_free_rekey_material(rekey); silc_fsm_next(fsm, silc_client_st_connect_error); - SILC_FSM_CALL_CONTINUE(fsm); + SILC_FSM_CALL_CONTINUE_SYNC(fsm); return; } @@ -197,13 +197,11 @@ static void silc_client_ke_completion(SilcSKE ske, "Error during key exchange with %s: cannot use keys", conn->remote_host); - conn->callback(client, conn, SILC_CLIENT_CONN_ERROR_KE, 0, NULL, - conn->callback_context); - + conn->internal->status = SILC_CLIENT_CONN_ERROR_KE; silc_ske_free_rekey_material(rekey); silc_fsm_next(fsm, silc_client_st_connect_error); - SILC_FSM_CALL_CONTINUE(fsm); + SILC_FSM_CALL_CONTINUE_SYNC(fsm); return; } @@ -220,13 +218,11 @@ static void silc_client_ke_completion(SilcSKE ske, "Error during key exchange with %s: cannot use keys", conn->remote_host); - conn->callback(client, conn, SILC_CLIENT_CONN_ERROR_KE, 0, NULL, - conn->callback_context); - + conn->internal->status = SILC_CLIENT_CONN_ERROR_KE; silc_ske_free_rekey_material(rekey); silc_fsm_next(fsm, silc_client_st_connect_error); - SILC_FSM_CALL_CONTINUE(fsm); + SILC_FSM_CALL_CONTINUE_SYNC(fsm); return; } @@ -235,7 +231,7 @@ static void silc_client_ke_completion(SilcSKE ske, SILC_LOG_DEBUG(("Key Exchange completed")); /* Key exchange done */ - SILC_FSM_CALL_CONTINUE(fsm); + SILC_FSM_CALL_CONTINUE_SYNC(fsm); } /* Rekey protocol completion callback */ @@ -263,6 +259,8 @@ static void silc_client_rekey_completion(SilcSKE ske, conn->remote_host, silc_ske_map_status(status)); + silc_ske_free(conn->internal->ske); + conn->internal->ske = NULL; silc_fsm_finish(fsm); return; } @@ -270,7 +268,10 @@ static void silc_client_rekey_completion(SilcSKE ske, silc_ske_free_rekey_material(conn->internal->rekey); conn->internal->rekey = rekey; - SILC_LOG_DEBUG(("Rekey completed")); + silc_ske_free(conn->internal->ske); + conn->internal->ske = NULL; + + SILC_LOG_DEBUG(("Rekey completed conn %p", conn)); /* Rekey done */ silc_fsm_finish(fsm); @@ -279,14 +280,18 @@ static void silc_client_rekey_completion(SilcSKE ske, /* Callback called by application to return authentication data */ static void silc_client_connect_auth_method(SilcAuthMethod auth_meth, - void *auth, SilcUInt32 auth_len, + const void *auth, + SilcUInt32 auth_len, void *context) { SilcFSMThread fsm = context; SilcClientConnection conn = silc_fsm_get_context(fsm); conn->internal->params.auth_method = auth_meth; - conn->internal->params.auth = auth; + if (auth_meth == SILC_AUTH_PASSWORD) + conn->internal->params.auth = silc_memdup(auth, auth_len); + else + conn->internal->params.auth = (void *)auth; conn->internal->params.auth_len = auth_len; SILC_FSM_CALL_CONTINUE(fsm); @@ -311,12 +316,12 @@ static void silc_client_connect_auth_completion(SilcConnAuth connauth, client, conn, SILC_CLIENT_MESSAGE_ERROR, "Authentication failed"); - conn->callback(client, conn, SILC_CLIENT_CONN_ERROR_AUTH, 0, NULL, - conn->callback_context); + conn->internal->status = SILC_CLIENT_CONN_ERROR_AUTH; + conn->internal->error = SILC_STATUS_ERR_AUTH_FAILED; silc_fsm_next(fsm, silc_client_st_connect_error); } - SILC_FSM_CALL_CONTINUE(fsm); + SILC_FSM_CALL_CONTINUE_SYNC(fsm); } /********************** CONNECTION_AUTH_REQUEST packet **********************/ @@ -332,7 +337,7 @@ SILC_FSM_STATE(silc_client_connect_auth_request) if (!conn->internal->auth_request) { silc_packet_free(packet); - SILC_FSM_FINISH; + return SILC_FSM_FINISH; } /* Parse the payload */ @@ -352,7 +357,7 @@ SILC_FSM_STATE(silc_client_connect_auth_request) /* Continue authentication */ silc_fsm_continue_sync(&conn->internal->event_thread); - SILC_FSM_FINISH; + return SILC_FSM_FINISH; } /*************************** Connect remote host ****************************/ @@ -362,12 +367,11 @@ SILC_FSM_STATE(silc_client_connect_auth_request) SILC_TASK_CALLBACK(silc_client_connect_timeout) { SilcClientConnection conn = context; - SilcClient client = conn->client; SILC_LOG_DEBUG(("Connection timeout")); - conn->callback(client, conn, SILC_CLIENT_CONN_ERROR_TIMEOUT, 0, NULL, - conn->callback_context); + conn->internal->status = SILC_CLIENT_CONN_ERROR_TIMEOUT; + conn->internal->error = SILC_STATUS_ERR_TIMEDOUT; silc_fsm_next(&conn->internal->event_thread, silc_client_st_connect_error); silc_fsm_continue_sync(&conn->internal->event_thread); @@ -378,7 +382,6 @@ SILC_TASK_CALLBACK(silc_client_connect_timeout) SILC_FSM_STATE(silc_client_st_connect) { SilcClientConnection conn = fsm_context; - SilcClient client = conn->client; SILC_LOG_DEBUG(("Connecting to %s:%d", conn->remote_host, conn->remote_port)); @@ -398,10 +401,9 @@ SILC_FSM_STATE(silc_client_st_connect) if (!conn->internal->params.local_ip) { /** IP address not given */ SILC_LOG_ERROR(("Local UDP IP address not specified")); - conn->callback(client, conn, SILC_CLIENT_CONN_ERROR, 0, NULL, - conn->callback_context); + conn->internal->status = SILC_CLIENT_CONN_ERROR; silc_fsm_next(fsm, silc_client_st_connect_error); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; } /* Connect (UDP) */ @@ -435,27 +437,26 @@ SILC_FSM_STATE(silc_client_st_connect_set_stream) if (conn->internal->disconnected) { /** Disconnected */ silc_fsm_next(fsm, silc_client_st_connect_error); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; } /* Create packet stream */ conn->stream = silc_packet_stream_create(client->internal->packet_engine, conn->internal->schedule, - (SilcStream)conn->stream); + conn->internal->user_stream); if (!conn->stream) { /** Cannot create packet stream */ SILC_LOG_DEBUG(("Could not create packet stream")); - conn->callback(client, conn, SILC_CLIENT_CONN_ERROR, 0, NULL, - conn->callback_context); + conn->internal->status = SILC_CLIENT_CONN_ERROR; silc_fsm_next(fsm, silc_client_st_connect_error); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; } silc_packet_set_context(conn->stream, conn); /** Start key exchange */ silc_fsm_next(fsm, silc_client_st_connect_key_exchange); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; } /* Starts key exchange protocol with remote host */ @@ -465,6 +466,7 @@ SILC_FSM_STATE(silc_client_st_connect_key_exchange) SilcClientConnection conn = fsm_context; SilcClient client = conn->client; SilcSKEParamsStruct params; + SilcClientID cid; SILC_LOG_DEBUG(("Starting key exchange protocol")); @@ -475,10 +477,9 @@ SILC_FSM_STATE(silc_client_st_connect_key_exchange) conn->public_key, conn->private_key, fsm); if (!conn->internal->ske) { /** Out of memory */ - conn->callback(client, conn, SILC_CLIENT_CONN_ERROR_KE, 0, NULL, - conn->callback_context); + conn->internal->status = SILC_CLIENT_CONN_ERROR_KE; silc_fsm_next(fsm, silc_client_st_connect_error); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; } /* Set SKE callbacks */ @@ -487,6 +488,7 @@ SILC_FSM_STATE(silc_client_st_connect_key_exchange) /* Set up key exchange parameters */ params.version = client->internal->silc_client_version; + params.timeout_secs = conn->internal->params.timeout_secs; params.flags = SILC_SKE_SP_FLAG_MUTUAL; if (conn->internal->params.pfs) params.flags |= SILC_SKE_SP_FLAG_PFS; @@ -505,6 +507,12 @@ SILC_FSM_STATE(silc_client_st_connect_key_exchange) /** Run key exchange (TCP) */ silc_fsm_next(fsm, silc_client_st_connect_auth_resolve); + /* Old server version requires empty Client ID in packets. Remove this + backwards support somepoint after 1.1 server is released. */ + memset(&cid, 0, sizeof(cid)); + cid.ip.data_len = 4; + silc_packet_set_ids(conn->stream, SILC_ID_CLIENT, &cid, 0, NULL); + SILC_FSM_CALL(conn->internal->op = silc_ske_initiator(conn->internal->ske, conn->stream, ¶ms, NULL)); @@ -516,7 +524,6 @@ SILC_FSM_STATE(silc_client_st_connect_key_exchange) SILC_FSM_STATE(silc_client_st_connect_setup_udp) { SilcClientConnection conn = fsm_context; - SilcClient client = conn->client; SilcStream stream, old; SilcSKESecurityProperties prop; @@ -525,7 +532,7 @@ SILC_FSM_STATE(silc_client_st_connect_setup_udp) if (conn->internal->disconnected) { /** Disconnected */ silc_fsm_next(fsm, silc_client_st_connect_error); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; } /* Create new UDP stream */ @@ -536,10 +543,9 @@ SILC_FSM_STATE(silc_client_st_connect_setup_udp) conn->internal->schedule); if (!stream) { /** Cannot create UDP stream */ - conn->callback(client, conn, SILC_CLIENT_CONN_ERROR, 0, NULL, - conn->callback_context); + conn->internal->status = SILC_CLIENT_CONN_ERROR; silc_fsm_next(fsm, silc_client_st_connect_error); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; } /* Set the new stream to packet stream */ @@ -553,10 +559,10 @@ SILC_FSM_STATE(silc_client_st_connect_setup_udp) /** Start authentication */ silc_fsm_next(fsm, silc_client_st_connect_auth_resolve); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; } -/* Resolved authentication method to be used in authentication protocol */ +/* Resolve authentication method to be used in authentication protocol */ SILC_FSM_STATE(silc_client_st_connect_auth_resolve) { @@ -567,14 +573,14 @@ SILC_FSM_STATE(silc_client_st_connect_auth_resolve) if (conn->internal->disconnected) { /** Disconnected */ silc_fsm_next(fsm, silc_client_st_connect_error); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; } /* If authentication method and data is set, use them */ if (conn->internal->params.auth_set) { /** Got authentication data */ silc_fsm_next(fsm, silc_client_st_connect_auth_start); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; } /* Send connection authentication request packet */ @@ -588,7 +594,7 @@ SILC_FSM_STATE(silc_client_st_connect_auth_resolve) conn->internal->auth_request = TRUE; conn->internal->params.auth_method = SILC_AUTH_NONE; silc_fsm_next_later(fsm, silc_client_st_connect_auth_data, 2, 0); - SILC_FSM_WAIT; + return SILC_FSM_WAIT; } /* Get authentication data to be used in authentication protocol */ @@ -603,7 +609,7 @@ SILC_FSM_STATE(silc_client_st_connect_auth_data) if (conn->internal->disconnected) { /** Disconnected */ silc_fsm_next(fsm, silc_client_st_connect_error); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; } conn->internal->auth_request = FALSE; @@ -623,7 +629,6 @@ SILC_FSM_STATE(silc_client_st_connect_auth_data) SILC_FSM_STATE(silc_client_st_connect_auth_start) { SilcClientConnection conn = fsm_context; - SilcClient client = conn->client; SilcConnAuth connauth; SILC_LOG_DEBUG(("Starting connection authentication protocol")); @@ -631,7 +636,7 @@ SILC_FSM_STATE(silc_client_st_connect_auth_start) if (conn->internal->disconnected) { /** Disconnected */ silc_fsm_next(fsm, silc_client_st_connect_error); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; } /* We always use the same key for connection authentication and SKE */ @@ -644,10 +649,10 @@ SILC_FSM_STATE(silc_client_st_connect_auth_start) conn->internal->params.rekey_secs); if (!connauth) { /** Out of memory */ - conn->callback(client, conn, SILC_CLIENT_CONN_ERROR_AUTH, 0, NULL, - conn->callback_context); + conn->internal->status = SILC_CLIENT_CONN_ERROR_AUTH; + conn->internal->error = SILC_STATUS_ERR_AUTH_FAILED; silc_fsm_next(fsm, silc_client_st_connect_error); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; } /** Start connection authentication */ @@ -668,21 +673,33 @@ SILC_FSM_STATE(silc_client_st_connected) SilcClientConnection conn = fsm_context; SilcClient client = conn->client; + /* Get SILC protocol version remote supports */ + silc_ske_parse_version(conn->internal->ske, &conn->internal->remote_version, + NULL, NULL, NULL, NULL); + silc_ske_free(conn->internal->ske); conn->internal->ske = NULL; + if (!conn->internal->params.auth_set && + conn->internal->params.auth_method == SILC_AUTH_PASSWORD && + conn->internal->params.auth) { + silc_free(conn->internal->params.auth); + conn->internal->params.auth = NULL; + } + if (conn->internal->disconnected) { /** Disconnected */ silc_fsm_next(fsm, silc_client_st_connect_error); - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; } SILC_LOG_DEBUG(("Connection established")); /* Install rekey timer */ - silc_schedule_task_add_timeout(conn->internal->schedule, - silc_client_rekey_timer, conn, - conn->internal->params.rekey_secs, 0); + if (conn->type != SILC_CONN_CLIENT) + silc_schedule_task_add_timeout(conn->internal->schedule, + silc_client_rekey_timer, conn, + conn->internal->params.rekey_secs, 0); /* If we connected to server, now register to network. */ if (conn->type == SILC_CONN_SERVER && @@ -698,7 +715,7 @@ SILC_FSM_STATE(silc_client_st_connected) silc_fsm_next(fsm, silc_client_st_register); } - SILC_FSM_CONTINUE; + return SILC_FSM_CONTINUE; } silc_schedule_task_del_by_all(conn->internal->schedule, 0, @@ -708,7 +725,10 @@ SILC_FSM_STATE(silc_client_st_connected) conn->callback(client, conn, SILC_CLIENT_CONN_SUCCESS, 0, NULL, conn->callback_context); - SILC_FSM_FINISH; + silc_async_free(conn->internal->cop); + conn->internal->cop = NULL; + + return SILC_FSM_FINISH; } /* Error during connecting */ @@ -731,7 +751,7 @@ SILC_FSM_STATE(silc_client_st_connect_error) silc_schedule_task_del_by_all(conn->internal->schedule, 0, silc_client_connect_timeout, conn); - SILC_FSM_FINISH; + return SILC_FSM_FINISH; } /****************************** Connect rekey *******************************/ @@ -743,9 +763,11 @@ SILC_TASK_CALLBACK(silc_client_rekey_timer) SilcClientConnection conn = context; /* Signal to start rekey */ - conn->internal->rekey_responder = FALSE; - conn->internal->rekeying = TRUE; - SILC_FSM_EVENT_SIGNAL(&conn->internal->wait_event); + if (!silc_fsm_is_started(&conn->internal->event_thread)) { + conn->internal->rekey_responder = FALSE; + conn->internal->rekeying = TRUE; + SILC_FSM_EVENT_SIGNAL(&conn->internal->wait_event); + } /* Reinstall rekey timer */ silc_schedule_task_add_timeout(conn->internal->schedule, @@ -760,18 +782,17 @@ SILC_FSM_STATE(silc_client_st_rekey) SilcClientConnection conn = fsm_context; SilcClient client = conn->client; - SILC_LOG_DEBUG(("Rekey")); + SILC_LOG_DEBUG(("Rekey conn %p", conn)); if (conn->internal->disconnected) - SILC_FSM_FINISH; + return SILC_FSM_FINISH; /* Allocate SKE */ conn->internal->ske = - silc_ske_alloc(client->rng, conn->internal->schedule, - conn->internal->params.repository, - conn->public_key, conn->private_key, fsm); + silc_ske_alloc(client->rng, conn->internal->schedule, NULL, + conn->public_key, NULL, fsm); if (!conn->internal->ske) - SILC_FSM_FINISH; + return SILC_FSM_FINISH; /* Set SKE callbacks */ silc_ske_set_callbacks(conn->internal->ske, NULL, @@ -787,5 +808,6 @@ SILC_FSM_STATE(silc_client_st_rekey) SILC_FSM_CALL(conn->internal->op = silc_ske_rekey_responder( conn->internal->ske, conn->stream, - conn->internal->rekey)); + conn->internal->rekey, + NULL)); }