X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=blobdiff_plain;f=lib%2Fsilcclient%2Fclient_register.c;h=efbeaa24d9cae4534d01d65ad53e221b9ec83fb7;hp=a2380c80b5eee189fb7b59666d4804a2bdd92be0;hb=HEAD;hpb=af6a141a3e8147538523665c54ccb58389c032ae diff --git a/lib/silcclient/client_register.c b/lib/silcclient/client_register.c index a2380c80..efbeaa24 100644 --- a/lib/silcclient/client_register.c +++ b/lib/silcclient/client_register.c @@ -28,7 +28,10 @@ typedef struct { SilcClient client; SilcClientConnection conn; SilcBufferStruct detach; + SilcBuffer auth; char *nickname; + unsigned char *id; + SilcUInt32 id_len; SilcUInt32 channel_count; } *SilcClientResumeSession; @@ -68,6 +71,23 @@ silc_client_resume_command_callback(SilcClient client, va_end(ap); } +/* Resume authentication data generation callback */ + +static void silc_client_resume_auth_generated(const SilcBuffer data, + void *context) +{ + SilcClientConnection conn = context; + SilcClientResumeSession resume = + silc_fsm_get_state_context(&conn->internal->event_thread); + + if (!data) + silc_fsm_next(&conn->internal->event_thread, silc_client_st_resume_error); + else + resume->auth = silc_buffer_copy(data); + + SILC_FSM_CALL_CONTINUE_SYNC(&conn->internal->event_thread); +} + /****************************** NEW_ID packet *******************************/ @@ -78,6 +98,7 @@ SILC_FSM_STATE(silc_client_new_id) SilcClientConnection conn = fsm_context; SilcClient client = conn->client; SilcPacket packet = state_context; + char *nick; SilcID id; if (conn->local_id) @@ -92,9 +113,15 @@ SILC_FSM_STATE(silc_client_new_id) SILC_LOG_DEBUG(("New ID %s", silc_id_render(&id.u.client_id, SILC_ID_CLIENT))); + /* From SILC protocol version 1.3, nickname is in NEW_CLIENT packet */ + if (conn->internal->remote_version >= 13) + nick = (conn->internal->params.nickname ? + conn->internal->params.nickname : client->username); + else + nick = client->username; + /* Create local client entry */ - conn->local_entry = silc_client_add_client(client, conn, - client->username, + conn->local_entry = silc_client_add_client(client, conn, nick, client->username, client->realname, &id.u.client_id, 0); @@ -236,6 +263,8 @@ SILC_FSM_STATE(silc_client_st_register_complete) conn->internal->registering = FALSE; silc_schedule_task_del_by_all(conn->internal->schedule, 0, silc_client_connect_timeout, conn); + silc_async_free(conn->internal->cop); + conn->internal->cop = NULL; return SILC_FSM_FINISH; } @@ -270,7 +299,6 @@ SILC_FSM_STATE(silc_client_st_resume) SilcClientConnection conn = fsm_context; SilcClient client = conn->client; SilcClientResumeSession resume; - SilcBuffer auth; unsigned char *id; SilcUInt16 id_len; SilcClientID client_id; @@ -314,25 +342,34 @@ SILC_FSM_STATE(silc_client_st_resume) silc_fsm_next(fsm, silc_client_st_resume_error); return SILC_FSM_CONTINUE; } + resume->id = id; + resume->id_len = id_len; /* Generate authentication data that server will verify */ - auth = silc_auth_public_key_auth_generate(conn->public_key, - conn->private_key, - client->rng, - conn->internal->hash, - &client_id, SILC_ID_CLIENT); - if (!auth) { - /** Out of memory */ - silc_fsm_next(fsm, silc_client_st_resume_error); - return SILC_FSM_CONTINUE; - } + silc_fsm_next(fsm, silc_client_st_resume_send); + SILC_FSM_CALL(silc_auth_public_key_auth_generate( + conn->public_key, conn->private_key, + client->rng, conn->internal->hash, + &client_id, SILC_ID_CLIENT, + silc_client_resume_auth_generated, conn)); + /* NOT REACHED */ +} + +/* Send RESUME_CLIENT packet */ + +SILC_FSM_STATE(silc_client_st_resume_send) +{ + SilcClientConnection conn = fsm_context; + SilcClientResumeSession resume = state_context; + + SILC_LOG_DEBUG(("Send RESUME_CLIENT packet")); /* Send RESUME_CLIENT packet to resume to network */ if (!silc_packet_send_va(conn->stream, SILC_PACKET_RESUME_CLIENT, 0, - SILC_STR_UI_SHORT(id_len), - SILC_STR_DATA(id, id_len), - SILC_STR_DATA(silc_buffer_data(auth), - silc_buffer_len(auth)), + SILC_STR_UI_SHORT(resume->id_len), + SILC_STR_DATA(resume->id, resume->id_len), + SILC_STR_DATA(silc_buffer_data(resume->auth), + silc_buffer_len(resume->auth)), SILC_STR_END)) { /** Error sending packet */ SILC_LOG_DEBUG(("Error sending packet")); @@ -416,6 +453,8 @@ SILC_FSM_STATE(silc_client_st_resume_resolve_channels) channel = silc_client_get_channel_by_id(client, conn, &channel_id); if (!channel) silc_client_add_channel(client, conn, name, 0, &channel_id); + else + silc_client_unref_channel(client, conn, channel); res_argv = silc_realloc(res_argv, sizeof(*res_argv) * (res_argc + 1)); res_argv_lens = silc_realloc(res_argv_lens, sizeof(*res_argv_lens) * @@ -552,25 +591,26 @@ SILC_FSM_STATE(silc_client_st_resume_completed) &conn->local_entry->id); /* Call JOIN command replies for all joined channel */ - silc_idcache_get_all(conn->internal->channel_cache, &channels); - silc_list_start(channels); - while ((entry = silc_list_get(channels))) { - SilcHashTableList htl; - const char *cipher, *hmac; - - channel = entry->context; - cipher = (channel->internal.send_key ? - silc_cipher_get_name(channel->internal.send_key) : NULL); - hmac = (channel->internal.hmac ? - silc_hmac_get_name(channel->internal.hmac) : NULL); - silc_hash_table_list(channel->user_list, &htl); - silc_client_resume_command_callback(client, conn, SILC_COMMAND_JOIN, - channel->channel_name, channel, - channel->mode, &htl, channel->topic, - cipher, hmac, channel->founder_key, - channel->channel_pubkeys, - channel->user_limit); - silc_hash_table_list_reset(&htl); + if (silc_idcache_get_all(conn->internal->channel_cache, &channels)) { + silc_list_start(channels); + while ((entry = silc_list_get(channels))) { + SilcHashTableList htl; + const char *cipher, *hmac; + + channel = entry->context; + cipher = (channel->internal.send_key ? + silc_cipher_get_name(channel->internal.send_key) : NULL); + hmac = (channel->internal.hmac ? + silc_hmac_get_name(channel->internal.hmac) : NULL); + silc_hash_table_list(channel->user_list, &htl); + silc_client_resume_command_callback(client, conn, SILC_COMMAND_JOIN, + channel->channel_name, channel, + channel->mode, &htl, channel->topic, + cipher, hmac, channel->founder_key, + channel->channel_pubkeys, + channel->user_limit); + silc_hash_table_list_reset(&htl); + } } conn->internal->registering = FALSE; @@ -578,6 +618,8 @@ SILC_FSM_STATE(silc_client_st_resume_completed) silc_client_connect_timeout, conn); silc_free(resume->nickname); silc_free(resume); + silc_async_free(conn->internal->cop); + conn->internal->cop = NULL; return SILC_FSM_FINISH; }