Do TPM measurements only if there is a TPMRA workitem
This commit is contained in:
@@ -33,8 +33,11 @@
|
||||
#include <pts/pts.h>
|
||||
#include <pts/pts_database.h>
|
||||
#include <pts/pts_creds.h>
|
||||
#include <pts/components/ita/ita_comp_func_name.h>
|
||||
|
||||
#include <tcg/tcg_attr.h>
|
||||
#include <tcg/pts/tcg_pts_attr_meas_algo.h>
|
||||
#include <tcg/pts/tcg_pts_attr_proto_caps.h>
|
||||
#include <tcg/pts/tcg_pts_attr_req_file_meas.h>
|
||||
#include <tcg/pts/tcg_pts_attr_req_file_meta.h>
|
||||
|
||||
@@ -289,6 +292,7 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
|
||||
imv_state_t *state;
|
||||
imv_session_t *session;
|
||||
imv_attestation_state_t *attestation_state;
|
||||
imv_attestation_handshake_state_t handshake_state;
|
||||
TNC_IMVID imv_id;
|
||||
TNC_Result result = TNC_RESULT_SUCCESS;
|
||||
pts_t *pts;
|
||||
@@ -300,6 +304,7 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
|
||||
}
|
||||
attestation_state = (imv_attestation_state_t*)state;
|
||||
pts = attestation_state->get_pts(attestation_state);
|
||||
handshake_state = attestation_state->get_handshake_state(attestation_state);
|
||||
platform_info = pts->get_platform_info(pts);
|
||||
session = state->get_session(state);
|
||||
imv_id = this->agent->get_id(this->agent);
|
||||
@@ -340,6 +345,26 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
|
||||
out_msg = imv_msg_create(this->agent, state, id, imv_id, TNC_IMCID_ANY,
|
||||
msg_types[0]);
|
||||
|
||||
if (handshake_state == IMV_ATTESTATION_STATE_INIT)
|
||||
{
|
||||
pa_tnc_attr_t *attr;
|
||||
pts_proto_caps_flag_t flags;
|
||||
|
||||
/* Send Request Protocol Capabilities attribute */
|
||||
flags = pts->get_proto_caps(pts);
|
||||
attr = tcg_pts_attr_proto_caps_create(flags, TRUE);
|
||||
attr->set_noskip_flag(attr, TRUE);
|
||||
out_msg->add_attribute(out_msg, attr);
|
||||
|
||||
/* Send Measurement Algorithms attribute */
|
||||
attr = tcg_pts_attr_meas_algo_create(this->supported_algorithms, FALSE);
|
||||
attr->set_noskip_flag(attr, TRUE);
|
||||
out_msg->add_attribute(out_msg, attr);
|
||||
|
||||
attestation_state->set_handshake_state(attestation_state,
|
||||
IMV_ATTESTATION_STATE_DISCOVERY);
|
||||
}
|
||||
|
||||
if (platform_info && session &&
|
||||
(state->get_action_flags(state) & IMV_ATTESTATION_FLAG_ALGO) &&
|
||||
!(state->get_action_flags(state) & IMV_ATTESTATION_FLAG_FILE_MEAS))
|
||||
@@ -352,6 +377,9 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
|
||||
char *pathname;
|
||||
enumerator_t *enumerator;
|
||||
|
||||
attestation_state->set_handshake_state(attestation_state,
|
||||
IMV_ATTESTATION_STATE_END);
|
||||
|
||||
enumerator = session->create_workitem_enumerator(session);
|
||||
if (enumerator)
|
||||
{
|
||||
@@ -376,6 +404,8 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
|
||||
break;
|
||||
case IMV_WORKITEM_TPM_ATTEST:
|
||||
{
|
||||
pts_component_t *comp;
|
||||
pts_comp_func_name_t *comp_name;
|
||||
TNC_IMV_Action_Recommendation rec;
|
||||
TNC_IMV_Evaluation_Result eval;
|
||||
bool no_d_flag, no_t_flag;
|
||||
@@ -397,7 +427,45 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
|
||||
state->update_recommendation(state, rec, eval);
|
||||
imcv_db->finalize_workitem(imcv_db, workitem);
|
||||
workitem->destroy(workitem);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* do TPM BIOS measurements */
|
||||
if (strchr(workitem->get_arg_str(workitem), 'B'))
|
||||
{
|
||||
comp_name = pts_comp_func_name_create(PEN_ITA,
|
||||
PTS_ITA_COMP_FUNC_NAME_IMA,
|
||||
PTS_ITA_QUALIFIER_FLAG_KERNEL |
|
||||
PTS_ITA_QUALIFIER_TYPE_TRUSTED);
|
||||
comp = attestation_state->create_component(
|
||||
attestation_state, comp_name,
|
||||
0, this->pts_db);
|
||||
if (!comp)
|
||||
{
|
||||
comp_name->log(comp_name, "unregistered ");
|
||||
comp_name->destroy(comp_name);
|
||||
}
|
||||
}
|
||||
|
||||
/* do TPM IMA measurements */
|
||||
if (strchr(workitem->get_arg_str(workitem), 'I'))
|
||||
{
|
||||
comp_name = pts_comp_func_name_create(PEN_ITA,
|
||||
PTS_ITA_COMP_FUNC_NAME_IMA,
|
||||
PTS_ITA_QUALIFIER_FLAG_KERNEL |
|
||||
PTS_ITA_QUALIFIER_TYPE_OS);
|
||||
comp = attestation_state->create_component(
|
||||
attestation_state, comp_name,
|
||||
0, this->pts_db);
|
||||
if (!comp)
|
||||
{
|
||||
comp_name->log(comp_name, "unregistered ");
|
||||
comp_name->destroy(comp_name);
|
||||
}
|
||||
}
|
||||
|
||||
attestation_state->set_handshake_state(attestation_state,
|
||||
IMV_ATTESTATION_STATE_NONCE_REQ);
|
||||
continue;
|
||||
}
|
||||
default:
|
||||
@@ -467,8 +535,8 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
|
||||
}
|
||||
|
||||
/* check the IMV state for the next PA-TNC attributes to send */
|
||||
if (!imv_attestation_build(out_msg, state, this->supported_algorithms,
|
||||
this->supported_dh_groups, this->pts_db))
|
||||
if (!imv_attestation_build(out_msg, state, this->supported_dh_groups,
|
||||
this->pts_db))
|
||||
{
|
||||
state->set_recommendation(state,
|
||||
TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
|
||||
* Copyright (C) 2011-2012 Sansar Choinyambuu
|
||||
* Copyright (C) 2011-2014 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -16,8 +17,6 @@
|
||||
#include "imv_attestation_build.h"
|
||||
#include "imv_attestation_state.h"
|
||||
|
||||
#include <tcg/pts/tcg_pts_attr_proto_caps.h>
|
||||
#include <tcg/pts/tcg_pts_attr_meas_algo.h>
|
||||
#include <tcg/pts/tcg_pts_attr_dh_nonce_params_req.h>
|
||||
#include <tcg/pts/tcg_pts_attr_dh_nonce_finish.h>
|
||||
#include <tcg/pts/tcg_pts_attr_get_tpm_version_info.h>
|
||||
@@ -27,9 +26,7 @@
|
||||
|
||||
#include <utils/debug.h>
|
||||
|
||||
bool imv_attestation_build(imv_msg_t *out_msg,
|
||||
imv_state_t *state,
|
||||
pts_meas_algorithms_t supported_algorithms,
|
||||
bool imv_attestation_build(imv_msg_t *out_msg, imv_state_t *state,
|
||||
pts_dh_group_t supported_dh_groups,
|
||||
pts_database_t *pts_db)
|
||||
{
|
||||
@@ -42,60 +39,8 @@ bool imv_attestation_build(imv_msg_t *out_msg,
|
||||
handshake_state = attestation_state->get_handshake_state(attestation_state);
|
||||
pts = attestation_state->get_pts(attestation_state);
|
||||
|
||||
/**
|
||||
* Received a response form the Attestation IMC so we can proceeed
|
||||
*/
|
||||
if (handshake_state == IMV_ATTESTATION_STATE_DISCOVERY &&
|
||||
(state->get_action_flags(state) & IMV_ATTESTATION_FLAG_ALGO))
|
||||
{
|
||||
handshake_state = IMV_ATTESTATION_STATE_NONCE_REQ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip DH Nonce Parameters Request attribute when
|
||||
* DH Nonce Exchange is not selected by PTS-IMC side
|
||||
*/
|
||||
if (handshake_state == IMV_ATTESTATION_STATE_NONCE_REQ &&
|
||||
!(pts->get_proto_caps(pts) & PTS_PROTO_CAPS_D))
|
||||
{
|
||||
DBG2(DBG_IMV, "PTS-IMC does not support DH Nonce negotiation");
|
||||
handshake_state = IMV_ATTESTATION_STATE_TPM_INIT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip TPM Version Info and AIK attributes when
|
||||
* no TPM is available on the PTS-IMC side
|
||||
*/
|
||||
if (handshake_state == IMV_ATTESTATION_STATE_TPM_INIT &&
|
||||
!(pts->get_proto_caps(pts) & PTS_PROTO_CAPS_T))
|
||||
{
|
||||
DBG2(DBG_IMV, "PTS-IMC made no TPM available");
|
||||
handshake_state = IMV_ATTESTATION_STATE_END;
|
||||
}
|
||||
|
||||
switch (handshake_state)
|
||||
{
|
||||
case IMV_ATTESTATION_STATE_INIT:
|
||||
{
|
||||
pts_proto_caps_flag_t flags;
|
||||
|
||||
/* Send Request Protocol Capabilities attribute */
|
||||
flags = pts->get_proto_caps(pts);
|
||||
attr = tcg_pts_attr_proto_caps_create(flags, TRUE);
|
||||
attr->set_noskip_flag(attr, TRUE);
|
||||
out_msg->add_attribute(out_msg, attr);
|
||||
|
||||
/* Send Measurement Algorithms attribute */
|
||||
attr = tcg_pts_attr_meas_algo_create(supported_algorithms, FALSE);
|
||||
attr->set_noskip_flag(attr, TRUE);
|
||||
out_msg->add_attribute(out_msg, attr);
|
||||
|
||||
attestation_state->set_handshake_state(attestation_state,
|
||||
IMV_ATTESTATION_STATE_DISCOVERY);
|
||||
break;
|
||||
}
|
||||
case IMV_ATTESTATION_STATE_DISCOVERY:
|
||||
break;
|
||||
case IMV_ATTESTATION_STATE_NONCE_REQ:
|
||||
{
|
||||
int min_nonce_len;
|
||||
@@ -117,16 +62,13 @@ bool imv_attestation_build(imv_msg_t *out_msg,
|
||||
pts_meas_algorithms_t selected_algorithm;
|
||||
chunk_t initiator_value, initiator_nonce;
|
||||
|
||||
if ((pts->get_proto_caps(pts) & PTS_PROTO_CAPS_D))
|
||||
{
|
||||
/* Send DH nonce finish attribute */
|
||||
selected_algorithm = pts->get_meas_algorithm(pts);
|
||||
pts->get_my_public_value(pts, &initiator_value, &initiator_nonce);
|
||||
attr = tcg_pts_attr_dh_nonce_finish_create(selected_algorithm,
|
||||
/* Send DH nonce finish attribute */
|
||||
selected_algorithm = pts->get_meas_algorithm(pts);
|
||||
pts->get_my_public_value(pts, &initiator_value, &initiator_nonce);
|
||||
attr = tcg_pts_attr_dh_nonce_finish_create(selected_algorithm,
|
||||
initiator_value, initiator_nonce);
|
||||
attr->set_noskip_flag(attr, TRUE);
|
||||
out_msg->add_attribute(out_msg, attr);
|
||||
}
|
||||
attr->set_noskip_flag(attr, TRUE);
|
||||
out_msg->add_attribute(out_msg, attr);
|
||||
|
||||
/* Send Get TPM Version attribute */
|
||||
attr = tcg_pts_attr_get_tpm_version_info_create();
|
||||
@@ -146,24 +88,16 @@ bool imv_attestation_build(imv_msg_t *out_msg,
|
||||
{
|
||||
tcg_pts_attr_req_func_comp_evid_t *attr_cast;
|
||||
enumerator_t *enumerator;
|
||||
pts_component_t *comp;
|
||||
pts_comp_func_name_t *comp_name;
|
||||
pts_comp_func_name_t *name;
|
||||
chunk_t keyid;
|
||||
int kid, vid, name, qualifier;
|
||||
int kid;
|
||||
u_int8_t flags;
|
||||
u_int32_t depth;
|
||||
bool first = TRUE, first_component = TRUE;
|
||||
bool first_component = TRUE;
|
||||
|
||||
attestation_state->set_handshake_state(attestation_state,
|
||||
IMV_ATTESTATION_STATE_END);
|
||||
|
||||
if (!(pts->get_proto_caps(pts) & PTS_PROTO_CAPS_T) ||
|
||||
!(pts->get_proto_caps(pts) & PTS_PROTO_CAPS_D))
|
||||
{
|
||||
DBG2(DBG_IMV, "PTS-IMC made no TPM available - "
|
||||
"skipping Component Measurements");
|
||||
break;
|
||||
}
|
||||
if (!pts->get_aik_keyid(pts, &keyid))
|
||||
{
|
||||
DBG1(DBG_IMV, "retrieval of AIK keyid failed");
|
||||
@@ -178,41 +112,22 @@ bool imv_attestation_build(imv_msg_t *out_msg,
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
enumerator = pts_db->create_comp_evid_enumerator(pts_db, kid);
|
||||
if (!enumerator)
|
||||
enumerator = attestation_state->create_component_enumerator(
|
||||
attestation_state);
|
||||
while (enumerator->enumerate(enumerator, &flags, &depth, &name))
|
||||
{
|
||||
break;
|
||||
}
|
||||
while (enumerator->enumerate(enumerator, &vid, &name,
|
||||
&qualifier, &depth))
|
||||
{
|
||||
if (first)
|
||||
{
|
||||
DBG2(DBG_IMV, "evidence request by");
|
||||
first = FALSE;
|
||||
}
|
||||
comp_name = pts_comp_func_name_create(vid, name, qualifier);
|
||||
comp_name->log(comp_name, " ");
|
||||
|
||||
comp = attestation_state->create_component(attestation_state,
|
||||
comp_name, depth, pts_db);
|
||||
if (!comp)
|
||||
{
|
||||
DBG2(DBG_IMV, " not registered or duplicate"
|
||||
" - removed from request");
|
||||
comp_name->destroy(comp_name);
|
||||
continue;
|
||||
}
|
||||
if (first_component)
|
||||
{
|
||||
attr = tcg_pts_attr_req_func_comp_evid_create();
|
||||
attr->set_noskip_flag(attr, TRUE);
|
||||
first_component = FALSE;
|
||||
DBG2(DBG_IMV, "evidence request by");
|
||||
}
|
||||
flags = comp->get_evidence_flags(comp);
|
||||
name->log(name, " ");
|
||||
|
||||
/* TODO check flags against negotiated_caps */
|
||||
attr_cast = (tcg_pts_attr_req_func_comp_evid_t *)attr;
|
||||
attr_cast->add_component(attr_cast, flags, depth, comp_name);
|
||||
attr_cast->add_component(attr_cast, flags, depth, name);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
@@ -238,9 +153,7 @@ bool imv_attestation_build(imv_msg_t *out_msg,
|
||||
IMV_ATTESTATION_STATE_END);
|
||||
}
|
||||
break;
|
||||
case IMV_ATTESTATION_STATE_END:
|
||||
attestation_state->set_handshake_state(attestation_state,
|
||||
IMV_ATTESTATION_STATE_END);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
@@ -35,14 +35,11 @@
|
||||
*
|
||||
* @param out_msg outbound PA-TNC message to be built
|
||||
* @param state state of a given connection
|
||||
* @param supported_algorithms supported PTS measurement algorithms
|
||||
* @param supported_dh_groups supported DH groups
|
||||
* @param pts_db PTS configuration database
|
||||
* @return TRUE if successful
|
||||
*/
|
||||
bool imv_attestation_build(imv_msg_t *out_msg,
|
||||
imv_state_t *state,
|
||||
pts_meas_algorithms_t supported_algorithms,
|
||||
bool imv_attestation_build(imv_msg_t *out_msg, imv_state_t *state,
|
||||
pts_dh_group_t supported_dh_groups,
|
||||
pts_database_t *pts_db);
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2011-2013 Sansar Choinyambuu, Andreas Steffen
|
||||
* Copyright (C) 2011-2012 Sansar Choinyambuu
|
||||
* Copyright (C) 2011-2014 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -381,9 +382,6 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg,
|
||||
status = comp->verify(comp, name->get_qualifier(name), pts, evidence);
|
||||
if (status == VERIFY_ERROR || status == FAILED)
|
||||
{
|
||||
state->update_recommendation(state,
|
||||
TNC_IMV_ACTION_RECOMMENDATION_ISOLATE,
|
||||
TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR);
|
||||
attestation_state->set_measurement_error(attestation_state,
|
||||
IMV_ATTESTATION_ERROR_COMP_EVID_FAIL);
|
||||
name->log(name, " measurement mismatch for ");
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2011-2012 Sansar Choinyambuu
|
||||
* Copyright (C) 2011-2013 Andreas Steffen
|
||||
* Copyright (C) 2011-2014 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -127,7 +127,7 @@ struct private_imv_attestation_state_t {
|
||||
*/
|
||||
struct func_comp_t {
|
||||
pts_component_t *comp;
|
||||
u_int8_t qualifier;
|
||||
pts_comp_func_name_t* name;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -136,6 +136,7 @@ struct func_comp_t {
|
||||
static void free_func_comp(func_comp_t *this)
|
||||
{
|
||||
this->comp->destroy(this->comp);
|
||||
this->name->destroy(this->name);
|
||||
free(this);
|
||||
}
|
||||
|
||||
@@ -396,13 +397,13 @@ METHOD(imv_attestation_state_t, create_component, pts_component_t*,
|
||||
|
||||
if (found)
|
||||
{
|
||||
if (name->get_qualifier(name) == entry->qualifier)
|
||||
if (name->equals(name, entry->name))
|
||||
{
|
||||
/* duplicate entry */
|
||||
return NULL;
|
||||
}
|
||||
new_entry = malloc_thing(func_comp_t);
|
||||
new_entry->qualifier = name->get_qualifier(name);
|
||||
new_entry->name = name->clone(name);
|
||||
new_entry->comp = entry->comp->get_ref(entry->comp);
|
||||
this->components->insert_last(this->components, new_entry);
|
||||
return entry->comp;
|
||||
@@ -416,13 +417,41 @@ METHOD(imv_attestation_state_t, create_component, pts_component_t*,
|
||||
return NULL;
|
||||
}
|
||||
new_entry = malloc_thing(func_comp_t);
|
||||
new_entry->qualifier = name->get_qualifier(name);
|
||||
new_entry->name = name->clone(name);
|
||||
new_entry->comp = component;
|
||||
this->components->insert_last(this->components, new_entry);
|
||||
return component;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enumerate file measurement entries
|
||||
*/
|
||||
static bool entry_filter(void *null, func_comp_t **entry, u_int8_t *flags,
|
||||
void *i2, u_int32_t *depth,
|
||||
void *i3, pts_comp_func_name_t **comp_name)
|
||||
{
|
||||
pts_component_t *comp;
|
||||
pts_comp_func_name_t *name;
|
||||
|
||||
comp = (*entry)->comp;
|
||||
name = (*entry)->name;
|
||||
|
||||
*flags = comp->get_evidence_flags(comp);
|
||||
*depth = comp->get_depth(comp);
|
||||
*comp_name = name;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(imv_attestation_state_t, create_component_enumerator, enumerator_t*,
|
||||
private_imv_attestation_state_t *this)
|
||||
{
|
||||
return enumerator_create_filter(
|
||||
this->components->create_enumerator(this->components),
|
||||
(void*)entry_filter, NULL, NULL);
|
||||
}
|
||||
|
||||
METHOD(imv_attestation_state_t, get_component, pts_component_t*,
|
||||
private_imv_attestation_state_t *this, pts_comp_func_name_t *name)
|
||||
{
|
||||
@@ -433,8 +462,7 @@ METHOD(imv_attestation_state_t, get_component, pts_component_t*,
|
||||
enumerator = this->components->create_enumerator(this->components);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (name->equals(name, entry->comp->get_comp_func_name(entry->comp)) &&
|
||||
name->get_qualifier(name) == entry->qualifier)
|
||||
if (name->equals(name, entry->name))
|
||||
{
|
||||
found = entry->comp;
|
||||
break;
|
||||
@@ -464,7 +492,8 @@ METHOD(imv_attestation_state_t, finalize_components, void,
|
||||
while (this->components->remove_last(this->components,
|
||||
(void**)&entry) == SUCCESS)
|
||||
{
|
||||
if (!entry->comp->finalize(entry->comp, entry->qualifier))
|
||||
if (!entry->comp->finalize(entry->comp,
|
||||
entry->name->get_qualifier(entry->name)))
|
||||
{
|
||||
set_measurement_error(this, IMV_ATTESTATION_ERROR_COMP_EVID_PEND);
|
||||
}
|
||||
@@ -512,6 +541,7 @@ imv_state_t *imv_attestation_state_create(TNC_ConnectionID connection_id)
|
||||
.set_handshake_state = _set_handshake_state,
|
||||
.get_pts = _get_pts,
|
||||
.create_component = _create_component,
|
||||
.create_component_enumerator = _create_component_enumerator,
|
||||
.get_component = _get_component,
|
||||
.finalize_components = _finalize_components,
|
||||
.components_finalized = _components_finalized,
|
||||
|
||||
@@ -116,6 +116,13 @@ struct imv_attestation_state_t {
|
||||
u_int32_t depth,
|
||||
pts_database_t *pts_db);
|
||||
|
||||
/**
|
||||
* Enumerate over all Functional Components
|
||||
*
|
||||
* @return Functional Component enumerator
|
||||
*/
|
||||
enumerator_t* (*create_component_enumerator)(imv_attestation_state_t *this);
|
||||
|
||||
/**
|
||||
* Get a Functional Component with a given name
|
||||
*
|
||||
|
||||
@@ -286,7 +286,7 @@ METHOD(tcg_pts_attr_req_func_comp_evid_t, add_component, void,
|
||||
entry = malloc_thing(entry_t);
|
||||
entry->flags = flags;
|
||||
entry->depth = depth;
|
||||
entry->name = name;
|
||||
entry->name = name->clone(name);
|
||||
this->list->insert_last(this->list, entry);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user