Skip to content

Commit 1a74f8f

Browse files
Update security environment variables (#617)
Signed-off-by: ruffsl <[email protected]> Co-authored-by: Mikael Arguedas <[email protected]>
1 parent b714f41 commit 1a74f8f

File tree

3 files changed

+88
-63
lines changed

3 files changed

+88
-63
lines changed

rcl/include/rcl/security.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@ extern "C"
2727
#include "rcl/visibility_control.h"
2828
#include "rmw/security_options.h"
2929

30-
#ifndef ROS_SECURITY_DIRECTORY_OVERRIDE
31-
# define ROS_SECURITY_DIRECTORY_OVERRIDE "ROS_SECURITY_DIRECTORY_OVERRIDE"
30+
#ifndef ROS_SECURITY_ENCLAVE_OVERRIDE
31+
# define ROS_SECURITY_ENCLAVE_OVERRIDE "ROS_SECURITY_ENCLAVE_OVERRIDE"
3232
#endif
3333

34-
#ifndef ROS_SECURITY_ROOT_DIRECTORY_VAR_NAME
35-
# define ROS_SECURITY_ROOT_DIRECTORY_VAR_NAME "ROS_SECURITY_ROOT_DIRECTORY"
34+
#ifndef ROS_SECURITY_KEYSTORE_VAR_NAME
35+
# define ROS_SECURITY_KEYSTORE_VAR_NAME "ROS_SECURITY_KEYSTORE"
3636
#endif
3737

3838
#ifndef ROS_SECURITY_STRATEGY_VAR_NAME
@@ -96,21 +96,21 @@ rcl_get_enforcement_policy(rmw_security_enforcement_policy_t * policy);
9696
/**
9797
* Return the security directory associated with the enclave name.
9898
*
99-
* The value of the environment variable `ROS_SECURITY_ROOT_DIRECTORY` is used as a root.
99+
* The value of the environment variable `ROS_SECURITY_KEYSTORE` is used as a root.
100100
* The specific directory to be used, is found from that root using the `name` passed.
101101
* E.g. for a context named "/a/b/c" and root "/r", the secure root path will be
102102
* "/r/a/b/c", where the delimiter "/" is native for target file system (e.g. "\\" for _WIN32).
103103
*
104-
* However, this expansion can be overridden by setting the secure directory override environment
105-
* (`ROS_SECURITY_DIRECTORY_OVERRIDE`) variable, allowing users to explicitly specify the exact secure
106-
* root directory to be utilized.
104+
* However, this expansion can be overridden by setting the secure enclave override environment
105+
* (`ROS_SECURITY_ENCLAVE_OVERRIDE`) variable, allowing users to explicitly specify the exact enclave
106+
* `name` to be utilized.
107107
* Such an override is useful for applications where the enclave is non-deterministic
108108
* before runtime, or when testing and using additional tools that may not otherwise be easily
109109
* provisioned.
110110
*
111111
* \param[in] name validated name (a single token)
112112
* \param[in] allocator the allocator to use for allocation
113-
* \returns Machine specific (absolute) secure root path or NULL on failure.
113+
* \returns Machine specific (absolute) enclave directory path or NULL on failure.
114114
* Returned pointer must be deallocated by the caller of this function
115115
*/
116116
RCL_PUBLIC

rcl/src/rcl/security.c

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -106,13 +106,13 @@ rcl_get_enforcement_policy(rmw_security_enforcement_policy_t * policy)
106106

107107
char * exact_match_lookup(
108108
const char * name,
109-
const char * ros_secure_root_env,
109+
const char * ros_secure_keystore_env,
110110
const rcl_allocator_t * allocator)
111111
{
112112
// Perform an exact match for the enclave name in directory <root dir>.
113113
char * secure_root = NULL;
114114
char * enclaves_dir = NULL;
115-
enclaves_dir = rcutils_join_path(ros_secure_root_env, "enclaves", *allocator);
115+
enclaves_dir = rcutils_join_path(ros_secure_keystore_env, "enclaves", *allocator);
116116
// "/" case when root namespace is explicitly passed in
117117
if (0 == strcmp(name, "/")) {
118118
secure_root = enclaves_dir;
@@ -132,58 +132,74 @@ char * rcl_get_secure_root(
132132
const char * name,
133133
const rcl_allocator_t * allocator)
134134
{
135-
bool ros_secure_directory_override = true;
135+
bool ros_secure_enclave_override = true;
136136

137137
// find out if either of the configuration environment variables are set
138138
const char * env_buf = NULL;
139139
if (NULL == name) {
140140
return NULL;
141141
}
142-
143-
if (rcutils_get_env(ROS_SECURITY_DIRECTORY_OVERRIDE, &env_buf)) {
142+
const char * get_env_error_str = NULL;
143+
// check if enclave override environment variable is empty
144+
get_env_error_str = rcutils_get_env(ROS_SECURITY_ENCLAVE_OVERRIDE, &env_buf);
145+
if (NULL != get_env_error_str) {
146+
RCUTILS_LOG_ERROR("rcutils_get_env failed: %s\n", get_env_error_str);
144147
return NULL;
145148
}
146149
if (!env_buf) {
147150
return NULL;
148151
}
149152
if (0 == strcmp("", env_buf)) {
150-
// check root directory if override directory environment variable is empty
151-
if (rcutils_get_env(ROS_SECURITY_ROOT_DIRECTORY_VAR_NAME, &env_buf)) {
152-
return NULL;
153-
}
154-
if (!env_buf) {
155-
return NULL;
156-
}
157-
if (0 == strcmp("", env_buf)) {
158-
return NULL; // environment variable was empty
159-
}
160-
ros_secure_directory_override = false;
153+
ros_secure_enclave_override = false;
161154
}
155+
char * ros_secure_enclave_override_env = rcutils_strdup(env_buf, *allocator);
162156

163-
// found a usable environment variable, copy into our memory before overwriting with next lookup
164-
char * ros_secure_root_env = rcutils_strdup(env_buf, *allocator);
157+
// check if keystore environment variable is empty
158+
get_env_error_str = rcutils_get_env(ROS_SECURITY_KEYSTORE_VAR_NAME, &env_buf);
159+
if (NULL != get_env_error_str) {
160+
RCUTILS_LOG_ERROR("rcutils_get_env failed: %s\n", get_env_error_str);
161+
allocator->deallocate(ros_secure_enclave_override_env, allocator->state);
162+
return NULL;
163+
}
164+
if (!env_buf) {
165+
allocator->deallocate(ros_secure_enclave_override_env, allocator->state);
166+
return NULL;
167+
}
168+
if (0 == strcmp("", env_buf)) {
169+
allocator->deallocate(ros_secure_enclave_override_env, allocator->state);
170+
return NULL; // environment variable was empty
171+
}
172+
char * ros_secure_keystore_env = rcutils_strdup(env_buf, *allocator);
165173

174+
// given usable environment variables, overwrite with next lookup
166175
char * secure_root = NULL;
167-
if (ros_secure_directory_override) {
168-
secure_root = rcutils_strdup(ros_secure_root_env, *allocator);
176+
if (ros_secure_enclave_override) {
177+
secure_root = exact_match_lookup(
178+
ros_secure_enclave_override_env,
179+
ros_secure_keystore_env,
180+
allocator);
169181
} else {
170-
secure_root = exact_match_lookup(name, ros_secure_root_env, allocator);
182+
secure_root = exact_match_lookup(
183+
name,
184+
ros_secure_keystore_env,
185+
allocator);
171186
}
172187

173188
if (NULL == secure_root || !rcutils_is_directory(secure_root)) {
174189
// Check secure_root is not NULL before checking directory
175190
if (NULL == secure_root) {
176191
RCL_SET_ERROR_MSG_WITH_FORMAT_STRING(
177192
"SECURITY ERROR: unable to find a folder matching the name '%s' in '%s'. ",
178-
name, ros_secure_root_env);
193+
name, ros_secure_keystore_env);
179194
} else {
180195
RCL_SET_ERROR_MSG_WITH_FORMAT_STRING(
181196
"SECURITY ERROR: directory '%s' does not exist.", secure_root);
182197
}
183-
allocator->deallocate(ros_secure_root_env, allocator->state);
198+
allocator->deallocate(ros_secure_enclave_override_env, allocator->state);
199+
allocator->deallocate(ros_secure_keystore_env, allocator->state);
184200
allocator->deallocate(secure_root, allocator->state);
185201
return NULL;
186202
}
187-
allocator->deallocate(ros_secure_root_env, allocator->state);
203+
allocator->deallocate(ros_secure_keystore_env, allocator->state);
188204
return secure_root;
189205
}

rcl/test/rcl/test_security.cpp

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,10 @@
3838
# define PATH_SEPARATOR "\\"
3939
#endif
4040

41-
#define TEST_ENCLAVE_MULTIPLE_TOKENS \
42-
"/group1" PATH_SEPARATOR TEST_ENCLAVE
41+
#define TEST_ENCLAVE_MULTIPLE_TOKENS_ABSOLUTE \
42+
"/group1" TEST_ENCLAVE_ABSOLUTE
43+
#define TEST_ENCLAVE_MULTIPLE_TOKENS_DIR \
44+
"group1" PATH_SEPARATOR TEST_ENCLAVE
4345

4446
char g_envstring[512] = {0};
4547

@@ -74,8 +76,8 @@ class TestGetSecureRoot : public ::testing::Test
7476
rcl_reset_error();
7577

7678
// Always make sure the variable we set is unset at the beginning of a test
77-
unsetenv_wrapper(ROS_SECURITY_ROOT_DIRECTORY_VAR_NAME);
78-
unsetenv_wrapper(ROS_SECURITY_DIRECTORY_OVERRIDE);
79+
unsetenv_wrapper(ROS_SECURITY_KEYSTORE_VAR_NAME);
80+
unsetenv_wrapper(ROS_SECURITY_ENCLAVE_OVERRIDE);
7981
unsetenv_wrapper(ROS_SECURITY_STRATEGY_VAR_NAME);
8082
unsetenv_wrapper(ROS_SECURITY_ENABLE_VAR_NAME);
8183
allocator = rcl_get_default_allocator();
@@ -104,7 +106,7 @@ class TestGetSecureRoot : public ::testing::Test
104106
{
105107
base_lookup_dir_fqn = rcutils_join_path(
106108
resource_dir, resource_dir_name, allocator);
107-
std::string putenv_input = ROS_SECURITY_ROOT_DIRECTORY_VAR_NAME "=";
109+
std::string putenv_input = ROS_SECURITY_KEYSTORE_VAR_NAME "=";
108110
putenv_input += base_lookup_dir_fqn;
109111
memcpy(
110112
g_envstring, putenv_input.c_str(),
@@ -124,7 +126,7 @@ TEST_F(TestGetSecureRoot, failureScenarios) {
124126
(char *) NULL);
125127
rcl_reset_error();
126128

127-
putenv_wrapper(ROS_SECURITY_ROOT_DIRECTORY_VAR_NAME "=" TEST_RESOURCES_DIRECTORY);
129+
putenv_wrapper(ROS_SECURITY_KEYSTORE_VAR_NAME "=" TEST_RESOURCES_DIRECTORY);
128130

129131
/* Security directory is set, but there's no matching directory */
130132
/// Wrong enclave
@@ -136,7 +138,7 @@ TEST_F(TestGetSecureRoot, failureScenarios) {
136138

137139
TEST_F(TestGetSecureRoot, successScenarios_local_root_enclave) {
138140
putenv_wrapper(
139-
ROS_SECURITY_ROOT_DIRECTORY_VAR_NAME "="
141+
ROS_SECURITY_KEYSTORE_VAR_NAME "="
140142
TEST_RESOURCES_DIRECTORY TEST_SECURITY_DIRECTORY_RESOURCES_DIR_NAME);
141143

142144
secure_root = rcl_get_secure_root("/", &allocator);
@@ -148,7 +150,7 @@ TEST_F(TestGetSecureRoot, successScenarios_local_root_enclave) {
148150

149151
TEST_F(TestGetSecureRoot, successScenarios_local_exactMatch) {
150152
putenv_wrapper(
151-
ROS_SECURITY_ROOT_DIRECTORY_VAR_NAME "="
153+
ROS_SECURITY_KEYSTORE_VAR_NAME "="
152154
TEST_RESOURCES_DIRECTORY TEST_SECURITY_DIRECTORY_RESOURCES_DIR_NAME);
153155

154156
secure_root = rcl_get_secure_root(TEST_ENCLAVE_ABSOLUTE, &allocator);
@@ -161,42 +163,43 @@ TEST_F(TestGetSecureRoot, successScenarios_local_exactMatch) {
161163

162164
TEST_F(TestGetSecureRoot, successScenarios_local_exactMatch_multipleTokensName) {
163165
putenv_wrapper(
164-
ROS_SECURITY_ROOT_DIRECTORY_VAR_NAME "="
166+
ROS_SECURITY_KEYSTORE_VAR_NAME "="
165167
TEST_RESOURCES_DIRECTORY TEST_SECURITY_DIRECTORY_RESOURCES_DIR_NAME);
166168

167169
secure_root = rcl_get_secure_root(
168-
TEST_ENCLAVE_MULTIPLE_TOKENS, &allocator);
170+
TEST_ENCLAVE_MULTIPLE_TOKENS_ABSOLUTE, &allocator);
169171
ASSERT_NE(nullptr, secure_root);
170172
std::string secure_root_str(secure_root);
171173
ASSERT_STREQ(
172174
TEST_ENCLAVE,
173175
secure_root_str.substr(secure_root_str.size() - strlen(TEST_ENCLAVE)).c_str());
174176
}
175177

176-
TEST_F(TestGetSecureRoot, nodeSecurityDirectoryOverride_validDirectory) {
177-
/* Specify a valid directory */
178-
putenv_wrapper(ROS_SECURITY_DIRECTORY_OVERRIDE "=" TEST_RESOURCES_DIRECTORY);
178+
TEST_F(TestGetSecureRoot, nodeSecurityEnclaveOverride_validEnclave) {
179+
putenv_wrapper(
180+
ROS_SECURITY_KEYSTORE_VAR_NAME "="
181+
TEST_RESOURCES_DIRECTORY TEST_SECURITY_DIRECTORY_RESOURCES_DIR_NAME);
182+
183+
/* Specify a valid enclave */
184+
putenv_wrapper(ROS_SECURITY_ENCLAVE_OVERRIDE "=" TEST_ENCLAVE_ABSOLUTE);
179185
root_path = rcl_get_secure_root(
180186
"name shouldn't matter", &allocator);
181-
ASSERT_STREQ(root_path, TEST_RESOURCES_DIRECTORY);
187+
ASSERT_STREQ(
188+
TEST_RESOURCES_DIRECTORY TEST_SECURITY_DIRECTORY_RESOURCES_DIR_NAME
189+
PATH_SEPARATOR "enclaves" PATH_SEPARATOR TEST_ENCLAVE,
190+
root_path);
182191
}
183192

184-
TEST_F(
185-
TestGetSecureRoot,
186-
nodeSecurityDirectoryOverride_validDirectory_overrideRootDirectoryAttempt) {
187-
/* Setting root dir has no effect */
188-
putenv_wrapper(ROS_SECURITY_DIRECTORY_OVERRIDE "=" TEST_RESOURCES_DIRECTORY);
189-
root_path = rcl_get_secure_root("name shouldn't matter", &allocator);
190-
putenv_wrapper(ROS_SECURITY_ROOT_DIRECTORY_VAR_NAME "=" TEST_RESOURCES_DIRECTORY);
191-
ASSERT_STREQ(root_path, TEST_RESOURCES_DIRECTORY);
192-
}
193+
TEST_F(TestGetSecureRoot, nodeSecurityEnclaveOverride_invalidEnclave) {
194+
putenv_wrapper(
195+
ROS_SECURITY_KEYSTORE_VAR_NAME "="
196+
TEST_RESOURCES_DIRECTORY TEST_SECURITY_DIRECTORY_RESOURCES_DIR_NAME);
193197

194-
TEST_F(TestGetSecureRoot, nodeSecurityDirectoryOverride_invalidDirectory) {
195198
/* The override provided should exist. Providing correct node/namespace/root dir won't help
196199
* if the node override is invalid. */
197200
putenv_wrapper(
198-
ROS_SECURITY_DIRECTORY_OVERRIDE
199-
"=TheresN_oWayThi_sDirectory_Exists_hence_this_should_fail");
201+
ROS_SECURITY_ENCLAVE_OVERRIDE
202+
"=TheresN_oWayThi_sEnclave_Exists_hence_this_should_fail");
200203
EXPECT_EQ(
201204
rcl_get_secure_root(TEST_ENCLAVE_ABSOLUTE, &allocator),
202205
(char *) NULL);
@@ -215,20 +218,26 @@ TEST_F(TestGetSecureRoot, test_get_security_options) {
215218

216219
putenv_wrapper(ROS_SECURITY_ENABLE_VAR_NAME "=true");
217220
putenv_wrapper(ROS_SECURITY_STRATEGY_VAR_NAME "=Enforce");
221+
putenv_wrapper(
222+
ROS_SECURITY_KEYSTORE_VAR_NAME "="
223+
TEST_RESOURCES_DIRECTORY TEST_SECURITY_DIRECTORY_RESOURCES_DIR_NAME);
218224

219225
putenv_wrapper(
220-
ROS_SECURITY_DIRECTORY_OVERRIDE "=" TEST_RESOURCES_DIRECTORY);
226+
ROS_SECURITY_ENCLAVE_OVERRIDE "=" TEST_ENCLAVE_MULTIPLE_TOKENS_ABSOLUTE);
221227
ret = rcl_get_security_options_from_environment(
222228
"doesn't matter at all", &allocator, &options);
223229
ASSERT_EQ(RMW_RET_OK, ret) << rmw_get_error_string().str;
224230
EXPECT_EQ(RMW_SECURITY_ENFORCEMENT_ENFORCE, options.enforce_security);
225-
EXPECT_STREQ(TEST_RESOURCES_DIRECTORY, options.security_root_path);
231+
EXPECT_STREQ(
232+
TEST_RESOURCES_DIRECTORY TEST_SECURITY_DIRECTORY_RESOURCES_DIR_NAME
233+
PATH_SEPARATOR "enclaves" PATH_SEPARATOR TEST_ENCLAVE_MULTIPLE_TOKENS_DIR,
234+
options.security_root_path);
226235
EXPECT_EQ(RMW_RET_OK, rmw_security_options_fini(&options, &allocator));
227236

228237
options = rmw_get_zero_initialized_security_options();
229-
unsetenv_wrapper(ROS_SECURITY_DIRECTORY_OVERRIDE);
238+
unsetenv_wrapper(ROS_SECURITY_ENCLAVE_OVERRIDE);
230239
putenv_wrapper(
231-
ROS_SECURITY_ROOT_DIRECTORY_VAR_NAME "="
240+
ROS_SECURITY_KEYSTORE_VAR_NAME "="
232241
TEST_RESOURCES_DIRECTORY TEST_SECURITY_DIRECTORY_RESOURCES_DIR_NAME);
233242
ret = rcl_get_security_options_from_environment(
234243
TEST_ENCLAVE_ABSOLUTE, &allocator, &options);

0 commit comments

Comments
 (0)