summaryrefslogtreecommitdiff
path: root/implementation/configuration/src/configuration_impl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'implementation/configuration/src/configuration_impl.cpp')
-rw-r--r--implementation/configuration/src/configuration_impl.cpp1521
1 files changed, 1339 insertions, 182 deletions
diff --git a/implementation/configuration/src/configuration_impl.cpp b/implementation/configuration/src/configuration_impl.cpp
index ccf3883..b574841 100644
--- a/implementation/configuration/src/configuration_impl.cpp
+++ b/implementation/configuration/src/configuration_impl.cpp
@@ -64,15 +64,18 @@ configuration_impl::configuration_impl()
max_configured_message_size_(0),
max_local_message_size_(0),
max_reliable_message_size_(0),
- buffer_shrink_threshold_(0),
+ buffer_shrink_threshold_(VSOMEIP_DEFAULT_BUFFER_SHRINK_THRESHOLD),
trace_(std::make_shared<trace>()),
watchdog_(std::make_shared<watchdog>()),
log_version_(true),
log_version_interval_(10),
permissions_shm_(VSOMEIP_DEFAULT_SHM_PERMISSION),
- umask_(VSOMEIP_DEFAULT_UMASK_LOCAL_ENDPOINTS),
+ permissions_uds_(VSOMEIP_DEFAULT_UDS_PERMISSIONS),
policy_enabled_(false),
check_credentials_(false),
+ check_routing_credentials_(false),
+ allow_remote_clients_(true),
+ check_whitelist_(false),
network_("vsomeip"),
e2e_enabled_(false),
log_memory_(false),
@@ -80,8 +83,15 @@ configuration_impl::configuration_impl()
log_status_(false),
log_status_interval_(0),
endpoint_queue_limit_external_(QUEUE_SIZE_UNLIMITED),
- endpoint_queue_limit_local_(QUEUE_SIZE_UNLIMITED) {
+ endpoint_queue_limit_local_(QUEUE_SIZE_UNLIMITED),
+ tcp_restart_aborts_max_(VSOMEIP_MAX_TCP_RESTART_ABORTS),
+ tcp_connect_time_max_(VSOMEIP_MAX_TCP_CONNECT_TIME),
+ has_issued_methods_warning_(false),
+ has_issued_clients_warning_(false),
+ udp_receive_buffer_size_(VSOMEIP_DEFAULT_UDP_RCV_BUFFER_SIZE),
+ shutdown_timeout_(VSOMEIP_DEFAULT_SHUTDOWN_TIMEOUT) {
unicast_ = unicast_.from_string(VSOMEIP_UNICAST_ADDRESS);
+ netmask_ = netmask_.from_string(VSOMEIP_NETMASK);
for (auto i = 0; i < ET_MAX; i++)
is_configured_[i] = false;
}
@@ -97,14 +107,21 @@ configuration_impl::configuration_impl(const configuration_impl &_other)
max_reliable_message_size_(_other.max_reliable_message_size_),
buffer_shrink_threshold_(_other.buffer_shrink_threshold_),
permissions_shm_(VSOMEIP_DEFAULT_SHM_PERMISSION),
- umask_(VSOMEIP_DEFAULT_UMASK_LOCAL_ENDPOINTS),
+ permissions_uds_(VSOMEIP_DEFAULT_UDS_PERMISSIONS),
endpoint_queue_limit_external_(_other.endpoint_queue_limit_external_),
- endpoint_queue_limit_local_(_other.endpoint_queue_limit_local_) {
+ endpoint_queue_limit_local_(_other.endpoint_queue_limit_local_),
+ tcp_restart_aborts_max_(_other.tcp_restart_aborts_max_),
+ tcp_connect_time_max_(_other.tcp_connect_time_max_),
+ udp_receive_buffer_size_(_other.udp_receive_buffer_size_),
+ shutdown_timeout_(_other.shutdown_timeout_) {
applications_.insert(_other.applications_.begin(), _other.applications_.end());
+ client_identifiers_ = _other.client_identifiers_;
services_.insert(_other.services_.begin(), _other.services_.end());
+ clients_ = _other.clients_;
unicast_ = _other.unicast_;
+ netmask_ = _other.netmask_;
diagnosis_ = _other.diagnosis_;
diagnosis_mask_ = _other.diagnosis_mask_;
@@ -132,26 +149,48 @@ configuration_impl::configuration_impl(const configuration_impl &_other)
sd_offer_debounce_time_ = _other.sd_offer_debounce_time_;
trace_ = std::make_shared<trace>(*_other.trace_.get());
+ supported_selective_addresses = _other.supported_selective_addresses;
watchdog_ = std::make_shared<watchdog>(*_other.watchdog_.get());
+ internal_service_ranges_ = _other.internal_service_ranges_;
log_version_ = _other.log_version_;
log_version_interval_ = _other.log_version_interval_;
magic_cookies_.insert(_other.magic_cookies_.begin(), _other.magic_cookies_.end());
+ message_sizes_ = _other.message_sizes_;
for (auto i = 0; i < ET_MAX; i++)
is_configured_[i] = _other.is_configured_[i];
+ policies_ = _other.policies_;
+ any_client_policies_ = _other.any_client_policies_;
+ ids_ = _other.ids_;
policy_enabled_ = _other.policy_enabled_;
check_credentials_ = _other.check_credentials_;
+ check_routing_credentials_ = _other.check_routing_credentials_;
+ allow_remote_clients_ = _other.allow_remote_clients_;
+ check_whitelist_ = _other.check_whitelist_;
+
network_ = _other.network_;
+ configuration_path_ = _other.configuration_path_;
+
e2e_enabled_ = _other.e2e_enabled_;
+ e2e_configuration_ = _other.e2e_configuration_;
log_memory_ = _other.log_memory_;
log_memory_interval_ = _other.log_memory_interval_;
log_status_ = _other.log_status_;
log_status_interval_ = _other.log_status_interval_;
+ ttl_factors_offers_ = _other.ttl_factors_offers_;
+ ttl_factors_subscriptions_ = _other.ttl_factors_subscriptions_;
+
debounces_ = _other.debounces_;
+ endpoint_queue_limits_ = _other.endpoint_queue_limits_;
+
+ offer_acceptance_required_ips_ = _other.offer_acceptance_required_ips_;
+
+ has_issued_methods_warning_ = _other.has_issued_methods_warning_;
+ has_issued_clients_warning_ = _other.has_issued_clients_warning_;
}
configuration_impl::~configuration_impl() {
@@ -195,14 +234,14 @@ bool configuration_impl::load(const std::string &_name) {
}
if (its_folder != "") {
its_input.insert(its_folder);
- }
-
- // Add debug configuration folder/file on top of already set input
- const char* its_debug_env = getenv(VSOMEIP_ENV_DEBUG_CONFIGURATION);
- if (nullptr != its_debug_env) {
- its_input.insert(its_debug_env);
- } else {
- its_input.insert(VSOMEIP_DEBUG_CONFIGURATION_FOLDER);
+#ifndef _WIN32
+ // load security configuration files from UID_GID sub folder if existing
+ std::stringstream its_security_config_folder;
+ its_security_config_folder << its_folder << "/" << getuid() << "_" << getgid();
+ if (utility::is_folder(its_security_config_folder.str())) {
+ its_input.insert(its_security_config_folder.str());
+ }
+#endif
}
// Determine standard configuration file
@@ -271,6 +310,101 @@ bool configuration_impl::load(const std::string &_name) {
return is_loaded_;
}
+bool configuration_impl::remote_offer_info_add(service_t _service,
+ instance_t _instance,
+ std::uint16_t _port,
+ bool _reliable,
+ bool _magic_cookies_enabled) {
+ bool ret = false;
+ if (!is_loaded_) {
+ VSOMEIP_ERROR << __func__ << " shall only be called after normal"
+ "configuration has been parsed";
+ } else {
+ std::shared_ptr<service> its_service(std::make_shared<service>());
+ its_service->service_ = _service;
+ its_service->instance_ = _instance;
+ its_service->reliable_ = its_service->unreliable_ = ILLEGAL_PORT;
+ _reliable ?
+ its_service->reliable_ = _port :
+ its_service->unreliable_ = _port;
+ its_service->unicast_address_ = "local";
+ its_service->multicast_address_ = "";
+ its_service->multicast_port_ = ILLEGAL_PORT;
+ its_service->protocol_ = "someip";
+
+ {
+ std::lock_guard<std::mutex> its_lock(services_mutex_);
+ bool updated(false);
+ auto found_service = services_.find(its_service->service_);
+ if (found_service != services_.end()) {
+ auto found_instance = found_service->second.find(its_service->instance_);
+ if (found_instance != found_service->second.end()) {
+ VSOMEIP_INFO << "Updating remote configuration for service ["
+ << std::hex << std::setw(4) << std::setfill('0')
+ << its_service->service_ << "." << its_service->instance_ << "]";
+ if (_reliable) {
+ found_instance->second->reliable_ = its_service->reliable_;
+ } else {
+ found_instance->second->unreliable_ = its_service->unreliable_;
+ }
+ updated = true;
+ }
+ }
+ if (!updated) {
+ services_[_service][_instance] = its_service;
+ VSOMEIP_INFO << "Added new remote configuration for service ["
+ << std::hex << std::setw(4) << std::setfill('0')
+ << its_service->service_ << "."
+ << std::hex << std::setw(4) << std::setfill('0')
+ << its_service->instance_ << "]";
+ }
+ if (_magic_cookies_enabled) {
+ magic_cookies_[its_service->unicast_address_].insert(its_service->reliable_);
+ }
+ }
+ ret = true;
+ }
+ return ret;
+}
+
+bool configuration_impl::remote_offer_info_remove(service_t _service,
+ instance_t _instance,
+ std::uint16_t _port,
+ bool _reliable,
+ bool _magic_cookies_enabled,
+ bool* _still_offered_remote) {
+ (void)_port;
+ (void)_magic_cookies_enabled;
+ bool ret = false;
+ if (!is_loaded_) {
+ VSOMEIP_ERROR << __func__ << " shall only be called after normal"
+ "configuration has been parsed";
+ } else {
+ std::lock_guard<std::mutex> its_lock(services_mutex_);
+ auto found_service = services_.find(_service);
+ if (found_service != services_.end()) {
+ auto found_instance = found_service->second.find(_instance);
+ if (found_instance != found_service->second.end()) {
+ VSOMEIP_INFO << "Removing remote configuration for service ["
+ << std::hex << std::setw(4) << std::setfill('0')
+ << _service << "." << _instance << "]";
+ if (_reliable) {
+ found_instance->second->reliable_ = ILLEGAL_PORT;
+ // TODO delete from magic_cookies_map without overwriting
+ // configurations from other services offered on the same port
+ } else {
+ found_instance->second->unreliable_ = ILLEGAL_PORT;
+ }
+ *_still_offered_remote = (
+ found_instance->second->unreliable_ != ILLEGAL_PORT ||
+ found_instance->second->reliable_ != ILLEGAL_PORT);
+ ret = true;
+ }
+ }
+ }
+ return ret;
+}
+
void configuration_impl::read_data(const std::set<std::string> &_input,
std::vector<element> &_elements, std::set<std::string> &_failed,
bool _mandatory_only) {
@@ -339,17 +473,23 @@ bool configuration_impl::load_data(const std::vector<element> &_elements,
has_applications = load_applications(e) || has_applications;
load_network(e);
load_diagnosis_address(e);
+ load_shutdown_timeout(e);
load_payload_sizes(e);
load_endpoint_queue_sizes(e);
+ load_tcp_restart_settings(e);
load_permissions(e);
load_policies(e);
load_tracing(e);
+ load_udp_receive_buffer_size(e);
+ load_security_update_whitelist(e);
+ load_routing_credentials(e);
}
}
if (_load_optional) {
for (auto e : _elements) {
load_unicast_address(e);
+ load_netmask(e);
load_service_discovery(e);
load_services(e);
load_internal_services(e);
@@ -358,6 +498,7 @@ bool configuration_impl::load_data(const std::vector<element> &_elements,
load_selective_broadcasts_support(e);
load_e2e(e);
load_debounce(e);
+ load_offer_acceptance_required(e);
}
}
@@ -476,6 +617,51 @@ bool configuration_impl::load_routing(const element &_element) {
return true;
}
+bool configuration_impl::load_routing_credentials(const element &_element) {
+ try {
+ auto its_routing_cred = _element.tree_.get_child("routing-credentials");
+ if (is_configured_[ET_ROUTING_CREDENTIALS]) {
+ VSOMEIP_WARNING << "vSomeIP Security: Multiple definitions of routing-credentials."
+ << " Ignoring definition from " << _element.name_;
+ } else {
+ for (auto i = its_routing_cred.begin();
+ i != its_routing_cred.end();
+ ++i) {
+ std::string its_key(i->first);
+ std::string its_value(i->second.data());
+ std::stringstream its_converter;
+ if (its_key == "uid") {
+ uint32_t its_uid(0);
+ if (its_value.find("0x") == 0) {
+ its_converter << std::hex << its_value;
+ } else {
+ its_converter << std::dec << its_value;
+ }
+ its_converter >> its_uid;
+ std::lock_guard<std::mutex> its_lock(routing_credentials_mutex_);
+ std::get<0>(routing_credentials_) = its_uid;
+ } else if (its_key == "gid") {
+ uint32_t its_gid(0);
+ if (its_value.find("0x") == 0) {
+ its_converter << std::hex << its_value;
+ } else {
+ its_converter << std::dec << its_value;
+ }
+ its_converter >> its_gid;
+ std::lock_guard<std::mutex> its_lock(routing_credentials_mutex_);
+ std::get<1>(routing_credentials_) = its_gid;
+ }
+ }
+ check_routing_credentials_ = true;
+ is_configured_[ET_ROUTING_CREDENTIALS] = true;
+ }
+ } catch (...) {
+ return false;
+ }
+ return true;
+}
+
+
bool configuration_impl::load_applications(const element &_element) {
try {
std::stringstream its_converter;
@@ -500,6 +686,7 @@ void configuration_impl::load_application_data(
std::size_t its_io_thread_count(VSOMEIP_IO_THREAD_COUNT);
std::size_t its_request_debounce_time(VSOMEIP_REQUEST_DEBOUNCE_TIME);
std::map<plugin_type_e, std::set<std::string>> plugins;
+ int its_io_thread_nice_level(VSOMEIP_IO_THREAD_NICE_LEVEL);
for (auto i = _tree.begin(); i != _tree.end(); ++i) {
std::string its_key(i->first);
std::string its_value(i->second.data());
@@ -529,6 +716,9 @@ void configuration_impl::load_application_data(
VSOMEIP_WARNING << "Max. number of threads per application is 255";
its_io_thread_count = 255;
}
+ } else if (its_key == "io_thread_nice") {
+ its_converter << std::dec << its_value;
+ its_converter >> its_io_thread_nice_level;
} else if (its_key == "request_debounce_time") {
its_converter << std::dec << its_value;
its_converter >> its_request_debounce_time;
@@ -552,13 +742,13 @@ void configuration_impl::load_application_data(
if (its_inner_key == "application_plugin") {
#ifndef _WIN32
library += ".";
- library += (VSOMEIP_APPLICATION_PLUGIN_VERSION + '0');
+ library += std::to_string(std::uint32_t(VSOMEIP_APPLICATION_PLUGIN_VERSION));
#endif
plugins[plugin_type_e::APPLICATION_PLUGIN].insert(library);
} else if (its_inner_key == "configuration_plugin") {
#ifndef _WIN32
library += ".";
- library += (VSOMEIP_PRE_CONFIGURATION_PLUGIN_VERSION + '0');
+ library += std::to_string(std::uint32_t(VSOMEIP_PRE_CONFIGURATION_PLUGIN_VERSION));
#endif
plugins[plugin_type_e::PRE_CONFIGURATION_PLUGIN].insert(library);
} else {
@@ -586,7 +776,7 @@ void configuration_impl::load_application_data(
applications_[its_name]
= std::make_tuple(its_id, its_max_dispatchers,
its_max_dispatch_time, its_io_thread_count,
- its_request_debounce_time, plugins);
+ its_request_debounce_time, plugins, its_io_thread_nice_level);
} else {
VSOMEIP_WARNING << "Multiple configurations for application "
<< its_name << ". Ignoring a configuration from "
@@ -672,56 +862,137 @@ void configuration_impl::load_trace_filters(
void configuration_impl::load_trace_filter(
const boost::property_tree::ptree &_tree) {
- std::shared_ptr<trace_filter_rule> its_filter_rule = std::make_shared<trace_filter_rule>();
- for(auto i = _tree.begin(); i != _tree.end(); ++i) {
+ std::shared_ptr<trace_filter> its_filter = std::make_shared<trace_filter>();
+ bool has_channel(false);
+ for (auto i = _tree.begin(); i != _tree.end(); ++i) {
std::string its_key = i->first;
- std::string its_value = i->second.data();
- if(its_key == "channel") {
- its_filter_rule->channel_ = its_value;
+ if (its_key == "channel") {
+ std::string its_value;
+ if (i->second.size() == 0) {
+ its_value = i->second.data();
+ its_filter->channels_.push_back(its_value);
+ } else {
+ for (auto j = i->second.begin(); j != i->second.end(); ++j) {
+ its_filter->channels_.push_back(j->second.data());
+ }
+ }
+ has_channel = true;
} else if(its_key == "type") {
- its_filter_rule->type_ = its_value;
+ std::string its_value = i->second.data();
+ its_filter->is_positive_ = (its_value == "positive");
} else {
- load_trace_filter_expressions(i->second, its_key, its_filter_rule);
+ load_trace_filter_expressions(i->second, its_key, its_filter);
}
}
- trace_->filter_rules_.push_back(its_filter_rule);
+
+ if (!has_channel) {
+ its_filter->channels_.push_back("TC"); // default
+ }
+
+ if (!its_filter->is_range_ || its_filter->matches_.size() == 2) {
+ trace_->filters_.push_back(its_filter);
+ }
}
void configuration_impl::load_trace_filter_expressions(
const boost::property_tree::ptree &_tree,
std::string &_criteria,
- std::shared_ptr<trace_filter_rule> &_filter_rule) {
- for(auto i = _tree.begin(); i != _tree.end(); ++i) {
- std::string its_value = i->second.data();
- std::stringstream its_converter;
-
- if(_criteria == "services") {
- service_t its_id = NO_TRACE_FILTER_EXPRESSION;
- if (its_value.size() > 1 && its_value[0] == '0' && its_value[1] == 'x') {
- its_converter << std::hex << its_value;
- } else {
- its_converter << std::dec << its_value;
- }
- its_converter >> its_id;
- _filter_rule->services_.push_back(its_id);
- } else if(_criteria == "methods") {
- method_t its_id = NO_TRACE_FILTER_EXPRESSION;
- if (its_value.size() > 1 && its_value[0] == '0' && its_value[1] == 'x') {
- its_converter << std::hex << its_value;
+ std::shared_ptr<trace_filter> &_filter) {
+ if (_criteria == "services") {
+ for (auto i = _tree.begin(); i != _tree.end(); ++i) {
+ vsomeip::trace::match_t its_match;
+ load_trace_filter_match(i->second, its_match);
+ _filter->matches_.push_back(its_match);
+ }
+ } else if (_criteria == "methods") {
+ if (!has_issued_methods_warning_) {
+ VSOMEIP_WARNING << "\"method\" entry in filter configuration has no effect!";
+ has_issued_methods_warning_ = true;
+ }
+ } else if (_criteria == "clients") {
+ if (!has_issued_clients_warning_) {
+ VSOMEIP_WARNING << "\"clients\" entry in filter configuration has no effect!";
+ has_issued_clients_warning_ = true;
+ }
+ } else if (_criteria == "matches") {
+ for (auto i = _tree.begin(); i != _tree.end(); ++i) {
+ vsomeip::trace::match_t its_match;
+ load_trace_filter_match(i->second, its_match);
+ if (i->first == "from") {
+ _filter->is_range_ = true;
+ _filter->matches_.insert(_filter->matches_.begin(), its_match);
} else {
- its_converter << std::dec << its_value;
+ if (i->first == "to") _filter->is_range_ = true;
+ _filter->matches_.push_back(its_match);
}
- its_converter >> its_id;
- _filter_rule->methods_.push_back(its_id);
- } else if(_criteria == "clients") {
- client_t its_id = NO_TRACE_FILTER_EXPRESSION;
- if (its_value.size() > 1 && its_value[0] == '0' && its_value[1] == 'x') {
- its_converter << std::hex << its_value;
- } else {
- its_converter << std::dec << its_value;
+ }
+ }
+}
+
+void configuration_impl::load_trace_filter_match(
+ const boost::property_tree::ptree &_data,
+ vsomeip::trace::match_t &_match) {
+ std::stringstream its_converter;
+
+ if (_data.size() == 0) {
+ std::string its_value(_data.data());
+ service_t its_service(ANY_SERVICE);
+ if (its_value.find("0x") == 0) {
+ its_converter << std::hex << its_value;
+ } else {
+ its_converter << std::dec << its_value;
+ }
+ its_converter >> its_service;
+
+ std::get<0>(_match) = its_service;
+ std::get<1>(_match) = ANY_INSTANCE;
+ std::get<2>(_match) = ANY_METHOD;
+ } else {
+ std::get<0>(_match) = ANY_SERVICE;
+ std::get<1>(_match) = ANY_INSTANCE;
+ std::get<2>(_match) = ANY_METHOD;
+
+ for (auto i = _data.begin(); i != _data.end(); ++i) {
+ std::string its_value;
+
+ its_converter.str("");
+ its_converter.clear();
+
+ try {
+ its_value = i->second.data();
+ if (its_value == "any") its_value = "0xffff";
+
+ if (i->first == "service") {
+ service_t its_service(ANY_SERVICE);
+ if (its_value.find("0x") == 0) {
+ its_converter << std::hex << its_value;
+ } else {
+ its_converter << std::dec << its_value;
+ }
+ its_converter >> its_service;
+ std::get<0>(_match) = its_service;
+ } else if (i->first == "instance") {
+ instance_t its_instance(ANY_INSTANCE);
+ if (its_value.find("0x") == 0) {
+ its_converter << std::hex << its_value;
+ } else {
+ its_converter << std::dec << its_value;
+ }
+ its_converter >> its_instance;
+ std::get<1>(_match) = its_instance;
+ } else if (i->first == "method") {
+ method_t its_method(ANY_METHOD);
+ if (its_value.find("0x") == 0) {
+ its_converter << std::hex << its_value;
+ } else {
+ its_converter << std::dec << its_value;
+ }
+ its_converter >> its_method;
+ std::get<2>(_match) = its_method;
+ }
+ } catch (...) {
+ // Intentionally left empty
}
- its_converter >> its_id;
- _filter_rule->clients_.push_back(its_id);
}
}
}
@@ -741,6 +1012,21 @@ void configuration_impl::load_unicast_address(const element &_element) {
}
}
+void configuration_impl::load_netmask(const element &_element) {
+ try {
+ std::string its_value = _element.tree_.get<std::string>("netmask");
+ if (is_configured_[ET_NETMASK]) {
+ VSOMEIP_WARNING << "Multiple definitions for netmask."
+ "Ignoring definition from " << _element.name_;
+ } else {
+ netmask_ = netmask_.from_string(its_value);
+ is_configured_[ET_NETMASK] = true;
+ }
+ } catch (...) {
+ // intentionally left empty!
+ }
+}
+
void configuration_impl::load_network(const element &_element) {
try {
std::string its_value(_element.tree_.get<std::string>("network"));
@@ -793,6 +1079,31 @@ void configuration_impl::load_diagnosis_address(const element &_element) {
}
}
+void configuration_impl::load_shutdown_timeout(const element &_element) {
+ const std::string shutdown_timeout("shutdown_timeout");
+ try {
+ if (_element.tree_.get_child_optional(shutdown_timeout)) {
+ std::string its_value = _element.tree_.get<std::string>("shutdown_timeout");
+ if (is_configured_[ET_SHUTDOWN_TIMEOUT]) {
+ VSOMEIP_WARNING << "Multiple definitions for shutdown_timeout."
+ "Ignoring definition from " << _element.name_;
+ } else {
+ std::stringstream its_converter;
+
+ if (its_value.size() > 1 && its_value[0] == '0' && its_value[1] == 'x') {
+ its_converter << std::hex << its_value;
+ } else {
+ its_converter << std::dec << its_value;
+ }
+ its_converter >> shutdown_timeout_;
+ is_configured_[ET_SHUTDOWN_TIMEOUT] = true;
+ }
+ }
+ } catch (...) {
+ // intentionally left empty
+ }
+}
+
void configuration_impl::load_service_discovery(
const element &_element) {
try {
@@ -978,6 +1289,7 @@ void configuration_impl::load_delays(
}
void configuration_impl::load_services(const element &_element) {
+ std::lock_guard<std::mutex> its_lock(services_mutex_);
try {
auto its_services = _element.tree_.get_child("services");
for (auto i = its_services.begin(); i != its_services.end(); ++i)
@@ -1587,10 +1899,10 @@ void configuration_impl::load_permissions(const element &_element) {
std::string its_value(i->second.data());
its_converter << std::oct << its_value;
its_converter >> permissions_shm_;
- } else if (its_key == "umask") {
+ } else if (its_key == "permissions-uds") {
std::string its_value(i->second.data());
its_converter << std::oct << its_value;
- its_converter >> umask_;
+ its_converter >> permissions_uds_;
}
}
@@ -1636,8 +1948,13 @@ void configuration_impl::load_policies(const element &_element) {
} else {
check_credentials_ = false;
}
- }
- if (its_security->first == "policies") {
+ } else if (its_security->first == "allow_remote_clients") {
+ if (its_security->second.data() == "true") {
+ allow_remote_clients_ = true;
+ } else {
+ allow_remote_clients_ = false;
+ }
+ } else if (its_security->first == "policies") {
for (auto its_policy = its_security->second.begin();
its_policy != its_security->second.end(); ++its_policy) {
load_policy(its_policy->second);
@@ -1676,16 +1993,19 @@ void configuration_impl::load_policy(const boost::property_tree::ptree &_tree) {
if (firstClient < lastClient && lastClient != ANY_CLIENT) {
uint32_t overrides(0);
for (client_t c = firstClient; c <= lastClient; ++c) {
- if (policies_.find(c) != policies_.end()) {
+ if (find_client_id_policy(c)) {
overrides++;
}
- policies_[c] = policy;
}
if (overrides) {
- VSOMEIP_INFO << std::hex << "Security configuration: "
- << "Client range 0x" << firstClient
- << " - 0x" << lastClient << " overrides policy of "
- << std::dec << overrides << " clients";
+ VSOMEIP_WARNING << std::hex << "Security configuration: "
+ << "for client range 0x" << firstClient
+ << " - 0x" << lastClient
+ << " will be ignored as it would override an already existing policy of "
+ << std::dec << overrides << " clients!";
+ } else {
+ std::lock_guard<std::mutex> its_lock(policies_mutex_);
+ policies_[std::make_pair(firstClient, lastClient)] = policy;
}
has_been_inserted = true;
} else {
@@ -1699,47 +2019,63 @@ void configuration_impl::load_policy(const boost::property_tree::ptree &_tree) {
its_converter << std::hex << value;
its_converter >> client;
if (client != 0x0) {
- if (policies_.find(client) != policies_.end()) {
- VSOMEIP_INFO << std::hex << "Security configuration: "
- << "Overriding policy for client 0x" << client << ".";
+ if (find_client_id_policy(client)) {
+ VSOMEIP_WARNING << std::hex << "Security configuration for client "
+ << client
+ << " will be ignored as it would overwrite an already existing policy!";
+ } else {
+ std::lock_guard<std::mutex> its_lock(policies_mutex_);
+ policies_[std::make_pair(client, client)] = policy;
}
- policies_[client] = policy;
has_been_inserted= true;
}
}
} else if (i->first == "credentials") {
std::pair<uint32_t, uint32_t> its_uid_range, its_gid_range;
+ ranges_t its_uid_ranges, its_gid_ranges;
+
bool has_uid(false), has_gid(false);
+ bool has_uid_range(false), has_gid_range(false);
for (auto n = i->second.begin();
n != i->second.end(); ++n) {
std::string its_key(n->first);
std::string its_value(n->second.data());
if (its_key == "uid") {
- if (its_value != "any") {
- uint32_t its_uid;
- std::stringstream its_converter;
- its_converter << std::dec << its_value;
- its_converter >> its_uid;
- std::get<0>(its_uid_range) = its_uid;
- std::get<1>(its_uid_range) = its_uid;
+ if(n->second.data().empty()) {
+ load_ranges(n->second, its_uid_ranges);
+ has_uid_range = true;
} else {
- std::get<0>(its_uid_range) = 0;
- std::get<1>(its_uid_range) = 0xFFFFFFFF;
+ if (its_value != "any") {
+ uint32_t its_uid;
+ std::stringstream its_converter;
+ its_converter << std::dec << its_value;
+ its_converter >> its_uid;
+ std::get<0>(its_uid_range) = its_uid;
+ std::get<1>(its_uid_range) = its_uid;
+ } else {
+ std::get<0>(its_uid_range) = 0;
+ std::get<1>(its_uid_range) = 0xFFFFFFFF;
+ }
+ has_uid = true;
}
- has_uid = true;
} else if (its_key == "gid") {
- if (its_value != "any") {
- uint32_t its_gid;
- std::stringstream its_converter;
- its_converter << std::dec << its_value;
- its_converter >> its_gid;
- std::get<0>(its_gid_range) = its_gid;
- std::get<1>(its_gid_range) = its_gid;
+ if(n->second.data().empty()) {
+ load_ranges(n->second, its_gid_ranges);
+ has_gid_range = true;
} else {
- std::get<0>(its_gid_range) = 0;
- std::get<1>(its_gid_range) = 0xFFFFFFFF;
+ if (its_value != "any") {
+ uint32_t its_gid;
+ std::stringstream its_converter;
+ its_converter << std::dec << its_value;
+ its_converter >> its_gid;
+ std::get<0>(its_gid_range) = its_gid;
+ std::get<1>(its_gid_range) = its_gid;
+ } else {
+ std::get<0>(its_gid_range) = 0;
+ std::get<1>(its_gid_range) = 0xFFFFFFFF;
+ }
+ has_gid = true;
}
- has_gid = true;
} else if (its_key == "allow" || its_key == "deny") {
policy->allow_who_ = (its_key == "allow");
load_credential(n->second, policy->ids_);
@@ -1755,10 +2091,13 @@ void configuration_impl::load_policy(const boost::property_tree::ptree &_tree) {
policy->allow_who_ = true;
policy->ids_.insert(std::make_pair(its_uids, its_gids));
}
-
+ if (has_uid_range && has_gid_range) {
+ policy->allow_who_ = true;
+ policy->ids_.insert(std::make_pair(its_uid_ranges, its_gid_ranges));
+ }
} else if (i->first == "allow") {
if (allow_deny_set) {
- VSOMEIP_WARNING << "Security configuration: \"allow\" tag overrides "
+ VSOMEIP_WARNING << "vSomeIP Security: Security configuration: \"allow\" tag overrides "
<< "already set \"deny\" tag. "
<< "Either \"deny\" or \"allow\" is allowed.";
}
@@ -1769,49 +2108,98 @@ void configuration_impl::load_policy(const boost::property_tree::ptree &_tree) {
for (auto n = l->second.begin(); n != l->second.end(); ++n) {
service_t service = 0x0;
instance_t instance = 0x0;
+ ids_t its_instance_method_ranges;
for (auto k = n->second.begin(); k != n->second.end(); ++k) {
std::stringstream its_converter;
if (k->first == "service") {
std::string value = k->second.data();
its_converter << std::hex << value;
its_converter >> service;
- } else if (k->first == "instance") {
+ } else if (k->first == "instance") { // legacy definition for instances
+ ranges_t its_instance_ranges;
+ ranges_t its_method_ranges;
std::string value = k->second.data();
- its_converter << std::hex << value;
- its_converter >> instance;
+ if (value != "any") {
+ its_converter << std::hex << value;
+ its_converter >> instance;
+ if (instance != 0x0) {
+ its_instance_ranges.insert(std::make_pair(instance, instance));
+ its_method_ranges.insert(std::make_pair(0x01, 0xFFFF));
+ }
+ } else {
+ its_instance_ranges.insert(std::make_pair(0x01, 0xFFFF));
+ its_method_ranges.insert(std::make_pair(0x01, 0xFFFF));
+ }
+ its_instance_method_ranges.insert(std::make_pair(its_instance_ranges, its_method_ranges));
+ } else if (k->first == "instances") { // new instances definition
+ for (auto p = k->second.begin(); p != k->second.end(); ++p) {
+ ranges_t its_instance_ranges;
+ ranges_t its_method_ranges;
+ for (auto m = p->second.begin(); m != p->second.end(); ++m) {
+ if (m->first == "ids") {
+ load_instance_ranges(m->second, its_instance_ranges);
+ } else if (m->first == "methods") {
+ load_instance_ranges(m->second, its_method_ranges);
+ }
+ if (!its_instance_ranges.empty() && !its_method_ranges.empty()) {
+ its_instance_method_ranges.insert(std::make_pair(its_instance_ranges, its_method_ranges));
+ }
+ }
+ }
+ if (its_instance_method_ranges.empty()) {
+ ranges_t its_legacy_instance_ranges;
+ ranges_t its_legacy_method_ranges;
+ its_legacy_method_ranges.insert(std::make_pair(0x01, 0xFFFF));
+ // try to only load instance ranges with any method to be allowed
+ load_instance_ranges(k->second, its_legacy_instance_ranges);
+ if (!its_legacy_instance_ranges.empty() && !its_legacy_method_ranges.empty()) {
+ its_instance_method_ranges.insert(std::make_pair(its_legacy_instance_ranges,
+ its_legacy_method_ranges));
+ }
+ }
}
}
- if (service != 0x0 && instance != 0x0) {
+ if (service != 0x0 && !its_instance_method_ranges.empty()) {
policy->services_.insert(
- std::make_pair(service, instance));
+ std::make_pair(service, its_instance_method_ranges));
}
}
} else if (l->first == "offers") {
for (auto n = l->second.begin(); n != l->second.end(); ++n) {
service_t service = 0x0;
instance_t instance = 0x0;
+ ranges_t its_instance_ranges;
for (auto k = n->second.begin(); k != n->second.end(); ++k) {
std::stringstream its_converter;
if (k->first == "service") {
std::string value = k->second.data();
its_converter << std::hex << value;
its_converter >> service;
- } else if (k->first == "instance") {
+ } else if (k->first == "instance") { // legacy definition for instances
std::string value = k->second.data();
- its_converter << std::hex << value;
- its_converter >> instance;
+ if (value != "any") {
+ its_converter << std::hex << value;
+ its_converter >> instance;
+ if (instance != 0x0) {
+ its_instance_ranges.insert(std::make_pair(instance, instance));
+ }
+ } else {
+ its_instance_ranges.insert(std::make_pair(0x01, 0xFFFF));
+ }
+ } else if (k->first == "instances") { // new instances definition
+ load_instance_ranges(k->second, its_instance_ranges);
}
}
- if (service != 0x0 && instance != 0x0) {
+ if (service != 0x0 && !its_instance_ranges.empty()) {
policy->offers_.insert(
- std::make_pair(service, instance));
+ std::make_pair(service, its_instance_ranges));
}
}
}
}
} else if (i->first == "deny") {
if (allow_deny_set) {
- VSOMEIP_WARNING << "Security configuration: \"deny\" tag overrides "
+ VSOMEIP_WARNING << "vSomeIP Security: Security configuration: \"deny\" tag overrides "
<< "already set \"allow\" tag. "
<< "Either \"deny\" or \"allow\" is allowed.";
}
@@ -1822,21 +2210,60 @@ void configuration_impl::load_policy(const boost::property_tree::ptree &_tree) {
for (auto n = l->second.begin(); n != l->second.end(); ++n) {
service_t service = 0x0;
instance_t instance = 0x0;
+ ids_t its_instance_method_ranges;
for (auto k = n->second.begin(); k != n->second.end(); ++k) {
std::stringstream its_converter;
if (k->first == "service") {
std::string value = k->second.data();
its_converter << std::hex << value;
its_converter >> service;
- } else if (k->first == "instance") {
+ } else if (k->first == "instance") { // legacy definition for instances
+ ranges_t its_instance_ranges;
+ ranges_t its_method_ranges;
std::string value = k->second.data();
- its_converter << std::hex << value;
- its_converter >> instance;
+ if (value != "any") {
+ its_converter << std::hex << value;
+ its_converter >> instance;
+ if (instance != 0x0) {
+ its_instance_ranges.insert(std::make_pair(instance, instance));
+ its_method_ranges.insert(std::make_pair(0x01, 0xFFFF));
+ }
+ } else {
+ its_instance_ranges.insert(std::make_pair(0x01, 0xFFFF));
+ its_method_ranges.insert(std::make_pair(0x01, 0xFFFF));
+ }
+ its_instance_method_ranges.insert(std::make_pair(its_instance_ranges, its_method_ranges));
+ } else if (k->first == "instances") { // new instances definition
+ for (auto p = k->second.begin(); p != k->second.end(); ++p) {
+ ranges_t its_instance_ranges;
+ ranges_t its_method_ranges;
+ for (auto m = p->second.begin(); m != p->second.end(); ++m) {
+ if (m->first == "ids") {
+ load_instance_ranges(m->second, its_instance_ranges);
+ } else if (m->first == "methods") {
+ load_instance_ranges(m->second, its_method_ranges);
+ }
+ if (!its_instance_ranges.empty() && !its_method_ranges.empty()) {
+ its_instance_method_ranges.insert(std::make_pair(its_instance_ranges, its_method_ranges));
+ }
+ }
+ }
+ if (its_instance_method_ranges.empty()) {
+ ranges_t its_legacy_instance_ranges;
+ ranges_t its_legacy_method_ranges;
+ its_legacy_method_ranges.insert(std::make_pair(0x01, 0xFFFF));
+ // try to only load instance ranges with any method to be allowed
+ load_instance_ranges(k->second, its_legacy_instance_ranges);
+ if (!its_legacy_instance_ranges.empty() && !its_legacy_method_ranges.empty()) {
+ its_instance_method_ranges.insert(std::make_pair(its_legacy_instance_ranges,
+ its_legacy_method_ranges));
+ }
+ }
}
}
- if (service != 0x0 && instance != 0x0) {
+ if (service != 0x0 && !its_instance_method_ranges.empty()) {
policy->services_.insert(
- std::make_pair(service, instance));
+ std::make_pair(service, its_instance_method_ranges));
}
}
}
@@ -1844,21 +2271,31 @@ void configuration_impl::load_policy(const boost::property_tree::ptree &_tree) {
for (auto n = l->second.begin(); n != l->second.end(); ++n) {
service_t service = 0x0;
instance_t instance = 0x0;
+ ranges_t its_instance_ranges;
for (auto k = n->second.begin(); k != n->second.end(); ++k) {
std::stringstream its_converter;
if (k->first == "service") {
std::string value = k->second.data();
its_converter << std::hex << value;
its_converter >> service;
- } else if (k->first == "instance") {
+ } else if (k->first == "instance") { // legacy definition for instances
std::string value = k->second.data();
- its_converter << std::hex << value;
- its_converter >> instance;
+ if (value != "any") {
+ its_converter << std::hex << value;
+ its_converter >> instance;
+ if (instance != 0x0) {
+ its_instance_ranges.insert(std::make_pair(instance, instance));
+ }
+ } else {
+ its_instance_ranges.insert(std::make_pair(0x01, 0xFFFF));
+ }
+ } else if (k->first == "instances") { // new instances definition
+ load_instance_ranges(k->second, its_instance_ranges);
}
}
- if (service != 0x0 && instance != 0x0) {
+ if (service != 0x0 && !its_instance_ranges.empty()) {
policy->offers_.insert(
- std::make_pair(service, instance));
+ std::make_pair(service, its_instance_ranges));
}
}
}
@@ -1867,6 +2304,7 @@ void configuration_impl::load_policy(const boost::property_tree::ptree &_tree) {
}
if (!has_been_inserted) {
+ std::lock_guard<std::mutex> its_lock(any_client_policies_mutex_);
any_client_policies_.push_back(policy);
}
}
@@ -1882,7 +2320,7 @@ void configuration_impl::load_credential(
} else if (its_key == "gid") {
load_ranges(j->second, its_gid_ranges);
} else {
- VSOMEIP_WARNING << "Security configuration: "
+ VSOMEIP_WARNING << "vSomeIP Security: Security configuration: "
<< "Malformed credential (contains illegal key \""
<< its_key << "\"";
}
@@ -1892,6 +2330,41 @@ void configuration_impl::load_credential(
}
}
+void configuration_impl::load_security_update_whitelist(const element &_element) {
+#ifdef _WIN32
+ return;
+#endif
+ try {
+ auto optional = _element.tree_.get_child_optional("security-update-whitelist");
+ if (!optional) {
+ return;
+ }
+ auto found_whitelist = _element.tree_.get_child("security-update-whitelist");
+ for (auto its_whitelist = found_whitelist.begin();
+ its_whitelist != found_whitelist.end(); ++its_whitelist) {
+
+ if (its_whitelist->first == "uids") {
+ {
+ std::lock_guard<std::mutex> its_lock(uid_whitelist_mutex_);
+ load_ranges(its_whitelist->second, uid_whitelist_);
+ }
+ } else if (its_whitelist->first == "services") {
+ {
+ std::lock_guard<std::mutex> its_lock(service_interface_whitelist_mutex_);
+ load_service_ranges(its_whitelist->second, service_interface_whitelist_);
+ }
+ } else if (its_whitelist->first == "check-whitelist") {
+ if (its_whitelist->second.data() == "true") {
+ check_whitelist_ = true;
+ } else {
+ check_whitelist_ = false;
+ }
+ }
+ }
+ } catch (...) {
+ }
+}
+
void configuration_impl::load_ranges(
const boost::property_tree::ptree &_tree, ranges_t &_range) {
ranges_t its_ranges;
@@ -1902,7 +2375,6 @@ void configuration_impl::load_ranges(
std::stringstream its_converter;
its_converter << std::dec << its_data.data();
its_converter >> its_id;
-
its_ranges.insert(std::make_pair(its_id, its_id));
} else {
uint32_t its_first, its_last;
@@ -1929,7 +2401,7 @@ void configuration_impl::load_ranges(
}
has_last = true;
} else {
- VSOMEIP_WARNING << "Security configuration: "
+ VSOMEIP_WARNING << "vSomeIP Security: Security configuration: "
<< " Malformed range. Contains illegal key ("
<< its_key << ")";
}
@@ -1944,6 +2416,128 @@ void configuration_impl::load_ranges(
_range = its_ranges;
}
+void configuration_impl::load_instance_ranges(
+ const boost::property_tree::ptree &_tree, ranges_t &_range) {
+ ranges_t its_ranges;
+ std::string key(_tree.data());
+ if (key == "any") {
+ its_ranges.insert(std::make_pair(0x01, 0xFFFF));
+ _range = its_ranges;
+ return;
+ }
+ for (auto i = _tree.begin(); i != _tree.end(); ++i) {
+ auto its_data = i->second;
+ if (!its_data.data().empty()) {
+ uint32_t its_id = 0x0;
+ std::stringstream its_converter;
+ its_converter << std::hex << its_data.data();
+ its_converter >> its_id;
+ if (its_id != 0x0) {
+ its_ranges.insert(std::make_pair(its_id, its_id));
+ }
+ } else {
+ uint32_t its_first, its_last;
+ bool has_first(false), has_last(false);
+ for (auto j = its_data.begin(); j != its_data.end(); ++j) {
+ std::string its_key(j->first);
+ std::string its_value(j->second.data());
+ if (its_key == "first") {
+ if (its_value == "max") {
+ its_first = 0xFFFF;
+ } else {
+ std::stringstream its_converter;
+ its_converter << std::hex << j->second.data();
+ its_converter >> its_first;
+ }
+ has_first = true;
+ } else if (its_key == "last") {
+ if (its_value == "max") {
+ its_last = 0xFFFF;
+ } else {
+ std::stringstream its_converter;
+ its_converter << std::hex << j->second.data();
+ its_converter >> its_last;
+ }
+ has_last = true;
+ } else {
+ VSOMEIP_WARNING << "vSomeIP Security: Security configuration: "
+ << " Malformed range. Contains illegal key ("
+ << its_key << ")";
+ }
+ }
+
+ if (has_first && has_last) {
+ if( its_last > its_first) {
+ its_ranges.insert(std::make_pair(its_first, its_last));
+ }
+ }
+ }
+ }
+
+ _range = its_ranges;
+}
+
+void configuration_impl::load_service_ranges(
+ const boost::property_tree::ptree &_tree, std::set<std::pair<service_t, service_t>> &_ranges) {
+ std::set<std::pair<service_t, service_t>> its_ranges;
+ std::string key(_tree.data());
+ if (key == "any") {
+ its_ranges.insert(std::make_pair(0x01, 0xFFFF));
+ _ranges = its_ranges;
+ return;
+ }
+ for (auto i = _tree.begin(); i != _tree.end(); ++i) {
+ auto its_data = i->second;
+ if (!its_data.data().empty()) {
+ service_t its_id = 0x0;
+ std::stringstream its_converter;
+ its_converter << std::hex << its_data.data();
+ its_converter >> its_id;
+ if (its_id != 0x0) {
+ its_ranges.insert(std::make_pair(its_id, its_id));
+ }
+ } else {
+ service_t its_first, its_last;
+ bool has_first(false), has_last(false);
+ for (auto j = its_data.begin(); j != its_data.end(); ++j) {
+ std::string its_key(j->first);
+ std::string its_value(j->second.data());
+ if (its_key == "first") {
+ if (its_value == "max") {
+ its_first = 0xFFFF;
+ } else {
+ std::stringstream its_converter;
+ its_converter << std::hex << j->second.data();
+ its_converter >> its_first;
+ }
+ has_first = true;
+ } else if (its_key == "last") {
+ if (its_value == "max") {
+ its_last = 0xFFFF;
+ } else {
+ std::stringstream its_converter;
+ its_converter << std::hex << j->second.data();
+ its_converter >> its_last;
+ }
+ has_last = true;
+ } else {
+ VSOMEIP_WARNING << "vSomeIP Security: Security interface whitelist configuration: "
+ << " Malformed range. Contains illegal key ("
+ << its_key << ")";
+ }
+ }
+
+ if (has_first && has_last) {
+ if( its_last >= its_first) {
+ its_ranges.insert(std::make_pair(its_first, its_last));
+ }
+ }
+ }
+ }
+
+ _ranges = its_ranges;
+}
+
///////////////////////////////////////////////////////////////////////////////
// Internal helper
///////////////////////////////////////////////////////////////////////////////
@@ -1994,6 +2588,10 @@ const boost::asio::ip::address & configuration_impl::get_unicast_address() const
return unicast_;
}
+const boost::asio::ip::address& configuration_impl::get_netmask() const {
+ return netmask_;
+}
+
unsigned short configuration_impl::get_diagnosis_address() const {
return diagnosis_;
}
@@ -2046,8 +2644,9 @@ std::string configuration_impl::get_unicast_address(service_t _service,
uint16_t configuration_impl::get_reliable_port(service_t _service,
instance_t _instance) const {
+ std::lock_guard<std::mutex> its_lock(services_mutex_);
uint16_t its_reliable(ILLEGAL_PORT);
- auto its_service = find_service(_service, _instance);
+ auto its_service = find_service_unlocked(_service, _instance);
if (its_service)
its_reliable = its_service->reliable_;
@@ -2056,8 +2655,9 @@ uint16_t configuration_impl::get_reliable_port(service_t _service,
uint16_t configuration_impl::get_unreliable_port(service_t _service,
instance_t _instance) const {
+ std::lock_guard<std::mutex> its_lock(services_mutex_);
uint16_t its_unreliable = ILLEGAL_PORT;
- auto its_service = find_service(_service, _instance);
+ auto its_service = find_service_unlocked(_service, _instance);
if (its_service)
its_unreliable = its_service->unreliable_;
@@ -2174,6 +2774,17 @@ std::size_t configuration_impl::get_io_thread_count(const std::string &_name) co
return its_io_thread_count;
}
+int configuration_impl::get_io_thread_nice_level(const std::string &_name) const {
+ int its_io_thread_nice_level = VSOMEIP_IO_THREAD_NICE_LEVEL;
+
+ auto found_application = applications_.find(_name);
+ if (found_application != applications_.end()) {
+ its_io_thread_nice_level = std::get<6>(found_application->second);
+ }
+
+ return its_io_thread_nice_level;
+}
+
std::size_t configuration_impl::get_max_dispatchers(
const std::string &_name) const {
std::size_t its_max_dispatchers = VSOMEIP_MAX_DISPATCHERS;
@@ -2200,6 +2811,7 @@ std::size_t configuration_impl::get_max_dispatch_time(
std::set<std::pair<service_t, instance_t> >
configuration_impl::get_remote_services() const {
+ std::lock_guard<std::mutex> its_lock(services_mutex_);
std::set<std::pair<service_t, instance_t> > its_remote_services;
for (auto i : services_) {
for (auto j : i.second) {
@@ -2335,8 +2947,9 @@ bool configuration_impl::find_port(uint16_t &_port, uint16_t _remote, bool _reli
bool configuration_impl::is_event_reliable(service_t _service,
instance_t _instance, event_t _event) const {
+ std::lock_guard<std::mutex> its_lock(services_mutex_);
bool is_reliable(false);
- auto its_service = find_service(_service, _instance);
+ auto its_service = find_service_unlocked(_service, _instance);
if (its_service) {
auto its_event = its_service->events_.find(_event);
if (its_event != its_service->events_.end()) {
@@ -2353,6 +2966,12 @@ bool configuration_impl::is_event_reliable(service_t _service,
std::shared_ptr<service> configuration_impl::find_service(service_t _service,
instance_t _instance) const {
+ std::lock_guard<std::mutex> its_lock(services_mutex_);
+ return find_service_unlocked(_service, _instance);
+}
+
+std::shared_ptr<service> configuration_impl::find_service_unlocked(service_t _service,
+ instance_t _instance) const {
std::shared_ptr<service> its_service;
auto find_service = services_.find(_service);
if (find_service != services_.end()) {
@@ -2517,8 +3136,8 @@ uint32_t configuration_impl::get_watchdog_timeout() const {
uint32_t configuration_impl::get_allowed_missing_pongs() const {
return watchdog_->missing_pongs_allowed_;
}
-std::uint32_t configuration_impl::get_umask() const {
- return umask_;
+std::uint32_t configuration_impl::get_permissions_uds() const {
+ return permissions_uds_;
}
std::uint32_t configuration_impl::get_permissions_shm() const {
@@ -2529,24 +3148,25 @@ bool configuration_impl::is_security_enabled() const {
return policy_enabled_;
}
+bool configuration_impl::is_audit_mode_enabled() const {
+ return check_credentials_;
+}
+
bool configuration_impl::check_credentials(client_t _client, uint32_t _uid,
uint32_t _gid) {
if (!policy_enabled_) {
return true;
}
- // store the client -> (uid, gid) mapping
- ids_[_client] = std::make_pair(_uid, _gid);
-
std::vector<std::shared_ptr<policy> > its_policies;
bool has_id(false);
- auto its_client = policies_.find(_client);
-
- // Use client specific policy if it does exist
- if (its_client != policies_.end())
- its_policies.push_back(its_client->second);
- else
+ auto found_policy = find_client_id_policy(_client);
+ if (found_policy) {
+ its_policies.push_back(found_policy);
+ } else {
+ std::lock_guard<std::mutex> its_lock(any_client_policies_mutex_);
its_policies = any_client_policies_;
+ }
for (const auto &p : its_policies) {
for (auto its_credential : p->ids_) {
@@ -2571,21 +3191,38 @@ bool configuration_impl::check_credentials(client_t _client, uint32_t _uid,
}
if ((has_id && p->allow_who_) || (!has_id && !p->allow_who_)) {
+ if (!store_client_to_uid_gid_mapping(_client,_uid, _gid)) {
+ std::string security_mode_text = "!";
+ if (!check_credentials_) {
+ security_mode_text = " but will be allowed due to audit mode is active!";
+ }
+
+ VSOMEIP_INFO << "vSomeIP Security: Client 0x" << std::hex << _client
+ << " with UID/GID=" << std::dec << _uid << "/" << _gid
+ << " : Check credentials failed as existing credentials would be overwritten"
+ << security_mode_text;
+
+ return !check_credentials_;
+ }
+ store_uid_gid_to_client_mapping(_uid, _gid, _client);
return true;
}
}
+ std::string security_mode_text = " ~> Skip!";
if (!check_credentials_) {
- VSOMEIP_INFO << "vSomeIP Security: Check credentials failed for client 0x"
- << std::hex << _client << " with UID/GID=" << std::dec << _uid
- << "/" << _gid << " but will be allowed due to audit mode is active!";
+ security_mode_text = " but will be allowed due to audit mode is active!";
}
+ VSOMEIP_INFO << "vSomeIP Security: Client 0x" << std::hex << _client
+ << " with UID/GID=" << std::dec << _uid << "/" << _gid
+ << " : Check credentials failed" << security_mode_text;
+
return !check_credentials_;
}
bool configuration_impl::is_client_allowed(client_t _client, service_t _service,
- instance_t _instance) const {
+ instance_t _instance, method_t _method, bool _is_request_service) const {
if (!policy_enabled_) {
return true;
}
@@ -2593,35 +3230,39 @@ bool configuration_impl::is_client_allowed(client_t _client, service_t _service,
uint32_t its_uid(0xffffffff), its_gid(0xffffffff);
bool must_apply(true);
std::vector<std::shared_ptr<policy> > its_policies;
- auto its_client = policies_.find(_client);
-
- // Use client specific policy if it does exist
- if (its_client != policies_.end())
- its_policies.push_back(its_client->second);
+ auto found_policy = find_client_id_policy(_client);
+ if (found_policy)
+ its_policies.push_back(found_policy);
else {
must_apply = false;
- its_policies = any_client_policies_;
+ {
+ std::lock_guard<std::mutex> its_lock(any_client_policies_mutex_);
+ its_policies = any_client_policies_;
+ }
+ std::lock_guard<std::mutex> its_lock(ids_mutex_);
auto found_id = ids_.find(_client);
if (found_id != ids_.end()) {
its_uid = found_id->second.first;
its_gid = found_id->second.second;
} else {
+ std::string security_mode_text = " ~> Skip!";
if (!check_credentials_) {
- VSOMEIP_INFO << "vSomeIP Security: Cannot determine uid/gid for"
- "client 0x" << std::hex << _client
- << ". Therefore it isn't allowed to communicate to service/instance "
- << _service << "/" << _instance
- << " but will be allowed due to audit mode is active!";
+ security_mode_text = " but will be allowed due to audit mode is active!";
}
+ VSOMEIP_INFO << "vSomeIP Security: Client 0x" << std::hex << _client
+ << " : Cannot determine uid/gid. Therefore it isn't allowed to communicate to service/instance "
+ << _service << "/" << _instance
+ << security_mode_text;
+
return !check_credentials_;
}
}
for (const auto &p : its_policies) {
- bool has_uid(false), has_gid(false);
+ bool has_uid(false), has_gid(false), has_service(false), has_instance_id(false), has_method_id(false);
if (must_apply) {
- has_uid = has_gid = p->allow_what_;
+ has_uid = has_gid = p->allow_who_;
} else {
for (auto its_credential : p->ids_) {
has_uid = has_gid = false;
@@ -2643,21 +3284,68 @@ bool configuration_impl::is_client_allowed(client_t _client, service_t _service,
}
}
- auto its_service = p->services_.find(std::make_pair(_service, _instance));
- if (has_uid && has_gid && p->allow_what_ && its_service != p->services_.end()) {
- return true;
- } else if (!has_uid && !has_gid && !p->allow_what_ && its_service == p->services_.end()) {
- return true;
+ for (auto its_offer : p->services_) {
+ if (std::get<0>(its_offer) == _service) {
+ for (auto its_ids : std::get<1>(its_offer)) {
+ has_service = has_instance_id = has_method_id = false;
+ for (auto its_instance_range : std::get<0>(its_ids)) {
+ if (std::get<0>(its_instance_range) <= _instance && _instance <= std::get<1>(its_instance_range)) {
+ has_instance_id = true;
+ break;
+ }
+ }
+ if (!_is_request_service) {
+ for (auto its_method_range : std::get<1>(its_ids)) {
+ if (std::get<0>(its_method_range) <= _method && _method <= std::get<1>(its_method_range)) {
+ has_method_id = true;
+ break;
+ }
+ }
+ } else {
+ // handle VSOMEIP_REQUEST_SERVICE
+ has_method_id = true;
+ }
+
+ if (has_instance_id && has_method_id) {
+ has_service = true;
+ break;
+ }
+ }
+ if (has_service)
+ break;
+ }
+ }
+
+ if ((has_uid && has_gid && p->allow_who_) || ((!has_uid || !has_gid) && !p->allow_who_)) {
+ if (p->allow_what_) {
+ // allow policy
+ if (has_service) {
+ return true;
+ }
+ } else {
+ // deny policy
+ // allow client if the service / instance / !ANY_METHOD was not found
+ if ((!has_service && (_method != ANY_METHOD))
+ // allow client if the service / instance / ANY_METHOD was not found
+ // and it is a "deny nothing" policy
+ || (!has_service && (_method == ANY_METHOD) && p->services_.empty())) {
+ return true;
+ }
+ }
}
}
+ std::string security_mode_text = " ~> Skip!";
if (!check_credentials_) {
- VSOMEIP_INFO << "vSomeIP Security: Client 0x" << std::hex << _client
- << " isn't allowed to communicate with service/instance "
- << _service << "/" << _instance
- << " but will be allowed due to audit mode is active!";
+ security_mode_text = " but will be allowed due to audit mode is active!";
}
+ VSOMEIP_INFO << "vSomeIP Security: Client 0x" << std::hex << _client
+ << " with UID/GID=" << std::dec << its_uid << "/" << its_gid
+ << " : Isn't allowed to communicate with service/instance/(method / event) " << std::hex
+ << _service << "/" << _instance << "/" << _method
+ << security_mode_text;
+
return !check_credentials_;
}
@@ -2670,35 +3358,39 @@ bool configuration_impl::is_offer_allowed(client_t _client, service_t _service,
uint32_t its_uid(0xffffffff), its_gid(0xffffffff);
bool must_apply(true);
std::vector<std::shared_ptr<policy> > its_policies;
- auto its_client = policies_.find(_client);
-
- // Use client specific policy if it does exist
- if (its_client != policies_.end())
- its_policies.push_back(its_client->second);
+ auto found_policy = find_client_id_policy(_client);
+ if (found_policy)
+ its_policies.push_back(found_policy);
else {
must_apply = false;
- its_policies = any_client_policies_;
+ {
+ std::lock_guard<std::mutex> its_lock(any_client_policies_mutex_);
+ its_policies = any_client_policies_;
+ }
+ std::lock_guard<std::mutex> its_lock(ids_mutex_);
auto found_id = ids_.find(_client);
if (found_id != ids_.end()) {
its_uid = found_id->second.first;
its_gid = found_id->second.second;
} else {
+ std::string audit_mode_text = " ~> Skip offer!";
if (!check_credentials_) {
- VSOMEIP_INFO << "vSomeIP Security: Cannot determine uid/gid for"
- "client 0x" << std::hex << _client
- << ". Therefore it isn't allowed to offer service/instance "
- << _service << "/" << _instance
- << " but will be allowed due to audit mode is active!";
+ audit_mode_text = " but will be allowed due to audit mode is active!";
}
+
+ VSOMEIP_INFO << "vSomeIP Security: Client 0x" << std::hex << _client
+ << " : Cannot determine uid/gid. Therefore it isn't allowed to offer service/instance "
+ << _service << "/" << _instance << audit_mode_text;
+
return !check_credentials_;
}
}
for (const auto &p : its_policies) {
- bool has_uid(false), has_gid(false);
+ bool has_uid(false), has_gid(false), has_offer(false);
if (must_apply) {
- has_uid = has_gid = p->allow_what_;
+ has_uid = has_gid = p->allow_who_;
} else {
for (auto its_credential : p->ids_) {
has_uid = has_gid = false;
@@ -2720,26 +3412,152 @@ bool configuration_impl::is_offer_allowed(client_t _client, service_t _service,
}
}
- auto its_offer = p->offers_.find(std::make_pair(_service, _instance));
- if (has_uid && has_gid
- && p->allow_what_ && its_offer != p->offers_.end()) {
- return true;
- } else if (!has_uid && !has_gid
- && !p->allow_what_ && its_offer == p->offers_.end()) {
- return true;
+ for (auto its_offer : p->offers_) {
+ has_offer = false;
+ if (std::get<0>(its_offer) == _service) {
+ for (auto its_instance_range : std::get<1>(its_offer)) {
+ if (std::get<0>(its_instance_range) <= _instance && _instance <= std::get<1>(its_instance_range)) {
+ has_offer = true;
+ break;
+ }
+ }
+ if (has_offer)
+ break;
+ }
+ }
+
+ if ((has_uid && has_gid && p->allow_who_) || ((!has_uid || !has_gid) && !p->allow_who_)) {
+ if (p->allow_what_ == has_offer) {
+ return true;
+ }
}
}
+ std::string security_mode_text = " ~> Skip offer!";
if (!check_credentials_) {
- VSOMEIP_INFO << "vSomeIP Security: Client 0x" << std::hex << _client
- << " isn't allowed to offer service/instance "
- << _service << "/" << _instance
- << " but will be allowed due to audit mode is active!";
+ security_mode_text = " but will be allowed due to audit mode is active!";
}
+ VSOMEIP_INFO << "vSomeIP Security: Client 0x" << std::hex << _client
+ << " with UID/GID=" << std::dec << its_uid << "/" << its_gid
+ << " isn't allowed to offer service/instance " << std::hex
+ << _service << "/" << _instance
+ << security_mode_text;
+
+
return !check_credentials_;
}
+bool configuration_impl::store_client_to_uid_gid_mapping(client_t _client,
+ uint32_t _uid, uint32_t _gid) {
+ {
+ // store the client -> (uid, gid) mapping
+ std::lock_guard<std::mutex> its_lock(ids_mutex_);
+ auto found_client = ids_.find(_client);
+ if (found_client != ids_.end()) {
+ if (found_client->second != std::make_pair(_uid, _gid)) {
+ VSOMEIP_WARNING << "vSomeIP Security: Client 0x"
+ << std::hex << _client << " with UID/GID="
+ << std::dec << _uid << "/" << _gid << " : Overwriting existing credentials UID/GID="
+ << std::dec << std::get<0>(found_client->second) << "/"
+ << std::get<1>(found_client->second);
+ found_client->second = std::make_pair(_uid, _gid);
+ return true;
+ }
+ } else {
+ ids_[_client] = std::make_pair(_uid, _gid);
+ }
+ return true;
+ }
+}
+
+bool configuration_impl::get_client_to_uid_gid_mapping(client_t _client, std::pair<uint32_t, uint32_t> &_uid_gid) {
+ {
+ // get the UID / GID of the client
+ std::lock_guard<std::mutex> its_lock(ids_mutex_);
+ if (ids_.find(_client) != ids_.end()) {
+ _uid_gid = ids_[_client];
+ return true;
+ }
+ return false;
+ }
+}
+
+bool configuration_impl::remove_client_to_uid_gid_mapping(client_t _client) {
+ std::pair<uint32_t, uint32_t> its_uid_gid;
+ bool client_removed(false);
+ bool uid_gid_removed(false);
+ {
+ std::lock_guard<std::mutex> its_lock(ids_mutex_);
+ auto found_client = ids_.find(_client);
+ if (found_client != ids_.end()) {
+ its_uid_gid = found_client->second;
+ ids_.erase(found_client);
+ client_removed = true;
+ }
+ }
+ {
+ std::lock_guard<std::mutex> its_lock(uid_to_clients_mutex_);
+ if (client_removed) {
+ auto found_uid_gid = uid_to_clients_.find(its_uid_gid);
+ if (found_uid_gid != uid_to_clients_.end()) {
+ auto its_client = found_uid_gid->second.find(_client);
+ if (its_client != found_uid_gid->second.end()) {
+ found_uid_gid->second.erase(its_client);
+ if (found_uid_gid->second.empty()) {
+ uid_to_clients_.erase(found_uid_gid);
+ }
+ uid_gid_removed = true;
+ }
+ }
+ } else {
+ for (auto its_uid_gid = uid_to_clients_.begin();
+ its_uid_gid != uid_to_clients_.end(); ++its_uid_gid) {
+ auto its_client = its_uid_gid->second.find(_client);
+ if (its_client != its_uid_gid->second.end()) {
+ its_uid_gid->second.erase(its_client);
+ if (its_uid_gid->second.empty()) {
+ uid_to_clients_.erase(its_uid_gid);
+ }
+ uid_gid_removed = true;
+ break;
+ }
+ }
+ }
+ }
+ return (client_removed && uid_gid_removed);
+}
+
+void configuration_impl::store_uid_gid_to_client_mapping(uint32_t _uid, uint32_t _gid,
+ client_t _client) {
+ {
+ // store the uid gid to clients mapping
+ std::lock_guard<std::mutex> its_lock(uid_to_clients_mutex_);
+ std::set<client_t> mapped_clients;
+ if (uid_to_clients_.find(std::make_pair(_uid, _gid)) != uid_to_clients_.end()) {
+ mapped_clients = uid_to_clients_[std::make_pair(_uid, _gid)];
+ mapped_clients.insert(_client);
+ uid_to_clients_[std::make_pair(_uid, _gid)] = mapped_clients;
+ } else {
+ mapped_clients.insert(_client);
+ uid_to_clients_[std::make_pair(_uid, _gid)] = mapped_clients;
+ }
+ }
+}
+
+bool configuration_impl::get_uid_gid_to_client_mapping(std::pair<uint32_t, uint32_t> _uid_gid,
+ std::set<client_t> &_clients) {
+ {
+ // get the clients corresponding to uid, gid
+ std::lock_guard<std::mutex> its_lock(uid_to_clients_mutex_);
+ if (uid_to_clients_.find(_uid_gid) != uid_to_clients_.end()) {
+ _clients = uid_to_clients_[_uid_gid];
+ return true;
+ }
+ return false;
+ }
+}
+
std::map<plugin_type_e, std::set<std::string>> configuration_impl::get_plugins(
const std::string &_name) const {
std::map<plugin_type_e, std::set<std::string>> result;
@@ -2793,8 +3611,8 @@ void configuration_impl::load_e2e_protected(const boost::property_tree::ptree &_
uint16_t data_id(0);
std::string variant("");
std::string profile("");
- uint16_t service_id(0);
- uint16_t event_id(0);
+ service_t service_id(0);
+ event_t event_id(0);
uint16_t crc_offset(0);
uint8_t data_id_mode(0);
@@ -2861,8 +3679,7 @@ void configuration_impl::load_e2e_protected(const boost::property_tree::ptree &_
its_converter >> data_length;
}
}
- e2exf::data_identifier its_data_identifier = {service_id, event_id};
- e2e_configuration_[its_data_identifier] = std::make_shared<cfg::e2e>(
+ e2e_configuration_[std::make_pair(service_id, event_id)] = std::make_shared<cfg::e2e>(
data_id,
variant,
profile,
@@ -2876,7 +3693,7 @@ void configuration_impl::load_e2e_protected(const boost::property_tree::ptree &_
);
}
-std::map<e2exf::data_identifier, std::shared_ptr<cfg::e2e>> configuration_impl::get_e2e_configuration() const {
+std::map<e2exf::data_identifier_t, std::shared_ptr<cfg::e2e>> configuration_impl::get_e2e_configuration() const {
return e2e_configuration_;
}
@@ -3217,6 +4034,55 @@ void configuration_impl::load_event_debounce_ignore(
}
}
+void configuration_impl::load_offer_acceptance_required(
+ const element &_element) {
+ const std::string oar("offer_acceptance_required");
+ try {
+ std::lock_guard<std::mutex> its_lock(offer_acceptance_required_ips_mutex_);
+ if (_element.tree_.get_child_optional(oar)) {
+ if (is_configured_[ET_OFFER_ACCEPTANCE_REQUIRED]) {
+ VSOMEIP_WARNING << "Multiple definitions of " << oar
+ << " Ignoring definition from " << _element.name_;
+ } else {
+ for (const auto& ipe : _element.tree_.get_child(oar)) {
+ boost::system::error_code ec;
+ boost::asio::ip::address its_address =
+ boost::asio::ip::address::from_string(ipe.first.data(), ec);
+ if (!its_address.is_unspecified()) {
+ offer_acceptance_required_ips_[its_address] = ipe.second.data();
+ }
+ }
+ is_configured_[ET_OFFER_ACCEPTANCE_REQUIRED] = true;
+ }
+ }
+ } catch (...) {
+ // intentionally left empty
+ }
+}
+
+void configuration_impl::load_udp_receive_buffer_size(const element &_element) {
+ const std::string urbs("udp-receive-buffer-size");
+ try {
+ if (_element.tree_.get_child_optional(urbs)) {
+ if (is_configured_[ET_UDP_RECEIVE_BUFFER_SIZE]) {
+ VSOMEIP_WARNING << "Multiple definitions of " << urbs
+ << " Ignoring definition from " << _element.name_;
+ } else {
+ const std::string s(_element.tree_.get_child(urbs).data());
+ try {
+ udp_receive_buffer_size_ = static_cast<std::uint32_t>(std::stoul(
+ s.c_str(), NULL, 10));
+ } catch (const std::exception &e) {
+ VSOMEIP_ERROR<< __func__ << ": " << urbs << " " << e.what();
+ }
+ is_configured_[ET_UDP_RECEIVE_BUFFER_SIZE] = true;
+ }
+ }
+ } catch (...) {
+ // intentionally left empty
+ }
+}
+
std::shared_ptr<debounce> configuration_impl::get_debounce(
service_t _service, instance_t _instance, event_t _event) const {
auto found_service = debounces_.find(_service);
@@ -3232,5 +4098,296 @@ std::shared_ptr<debounce> configuration_impl::get_debounce(
return nullptr;
}
+void configuration_impl::load_tcp_restart_settings(const element &_element) {
+ const std::string tcp_restart_aborts_max("tcp-restart-aborts-max");
+ const std::string tcp_connect_time_max("tcp-connect-time-max");
+
+ try {
+ if (_element.tree_.get_child_optional(tcp_restart_aborts_max)) {
+ if (is_configured_[ET_TCP_RESTART_ABORTS_MAX]) {
+ VSOMEIP_WARNING << "Multiple definitions for "
+ << tcp_restart_aborts_max
+ << " Ignoring definition from " << _element.name_;
+ } else {
+ is_configured_[ET_TCP_RESTART_ABORTS_MAX] = true;
+ auto mpsl = _element.tree_.get_child(
+ tcp_restart_aborts_max);
+ std::string s(mpsl.data());
+ try {
+ tcp_restart_aborts_max_ =
+ static_cast<std::uint32_t>(std::stoul(
+ s.c_str(), NULL, 10));
+ } catch (const std::exception &e) {
+ VSOMEIP_ERROR<<__func__ << ": " << tcp_restart_aborts_max
+ << " " << e.what();
+ }
+ }
+ }
+ if (_element.tree_.get_child_optional(tcp_connect_time_max)) {
+ if (is_configured_[ET_TCP_CONNECT_TIME_MAX]) {
+ VSOMEIP_WARNING << "Multiple definitions for "
+ << tcp_connect_time_max
+ << " Ignoring definition from " << _element.name_;
+ } else {
+ is_configured_[ET_TCP_CONNECT_TIME_MAX] = true;
+ auto mpsl = _element.tree_.get_child(tcp_connect_time_max);
+ std::string s(mpsl.data());
+ try {
+ tcp_connect_time_max_=
+ static_cast<std::uint32_t>(
+ std::stoul(s.c_str(), NULL, 10));
+ } catch (const std::exception &e) {
+ VSOMEIP_ERROR<< __func__ << ": "<< tcp_connect_time_max
+ << " " << e.what();
+ }
+ }
+ }
+ } catch (...) {
+ }
+}
+
+std::uint32_t configuration_impl::get_max_tcp_restart_aborts() const {
+ return tcp_restart_aborts_max_;
+}
+
+std::uint32_t configuration_impl::get_max_tcp_connect_time() const {
+ return tcp_connect_time_max_;
+}
+
+bool configuration_impl::offer_acceptance_required(
+ const boost::asio::ip::address& _address) const {
+ std::lock_guard<std::mutex> its_lock(offer_acceptance_required_ips_mutex_);
+ return offer_acceptance_required_ips_.find(_address)
+ != offer_acceptance_required_ips_.end();
+}
+
+void configuration_impl::set_offer_acceptance_required(
+ const boost::asio::ip::address& _address, const std::string& _path,
+ bool _enable) {
+ std::lock_guard<std::mutex> its_lock(offer_acceptance_required_ips_mutex_);
+ if (_enable) {
+ const auto found_address = offer_acceptance_required_ips_.find(_address);
+ if (found_address != offer_acceptance_required_ips_.end()) {
+ boost::system::error_code ec;
+ VSOMEIP_WARNING << __func__ << " configuration for: "
+ << found_address->first.to_string(ec) << " -> "
+ << found_address->second << " already configured."
+ << " Won't update with: "<< _path;
+ } else {
+ offer_acceptance_required_ips_[_address] = _path;
+ }
+ } else {
+ offer_acceptance_required_ips_.erase(_address);
+ }
+}
+
+std::map<boost::asio::ip::address, std::string>
+configuration_impl::get_offer_acceptance_required() {
+ std::lock_guard<std::mutex> its_lock(offer_acceptance_required_ips_mutex_);
+ return offer_acceptance_required_ips_;
+}
+
+std::uint32_t configuration_impl::get_udp_receive_buffer_size() const {
+ return udp_receive_buffer_size_;
+}
+
+std::shared_ptr<policy> configuration_impl::find_client_id_policy(client_t _client) const {
+ std::lock_guard<std::mutex> its_lock(policies_mutex_);
+ for (auto client_id_pair : policies_) {
+ if (std::get<0>(client_id_pair.first) <= _client
+ && _client <= std::get<1>(client_id_pair.first)) {
+ return client_id_pair.second;
+ }
+ }
+ return nullptr;
+}
+
+bool configuration_impl::remove_security_policy(uint32_t _uid, uint32_t _gid) {
+ std::lock_guard<std::mutex> its_lock(any_client_policies_mutex_);
+ bool was_removed(false);
+ if (!any_client_policies_.empty()) {
+ std::vector<std::shared_ptr<policy>>::iterator p_it = any_client_policies_.begin();
+ while (p_it != any_client_policies_.end()) {
+ bool has_uid(false), has_gid(false);
+ for (auto its_credential : p_it->get()->ids_) {
+ has_uid = has_gid = false;
+ for (auto its_range : std::get<0>(its_credential)) {
+ if (std::get<0>(its_range) <= _uid && _uid <= std::get<1>(its_range)) {
+ has_uid = true;
+ break;
+ }
+ }
+ for (auto its_range : std::get<1>(its_credential)) {
+ if (std::get<0>(its_range) <= _gid && _gid <= std::get<1>(its_range)) {
+ has_gid = true;
+ break;
+ }
+ }
+ // only remove "credentials allow" policies to prevent removal of
+ // blacklist configured in file
+ if (has_uid && has_gid && p_it->get()->allow_who_) {
+ was_removed = true;
+ break;
+ }
+ }
+ if (was_removed) {
+ p_it = any_client_policies_.erase(p_it);
+ break;
+ } else {
+ ++p_it;
+ }
+ }
+ }
+ return was_removed;
+}
+
+void configuration_impl::update_security_policy(uint32_t _uid, uint32_t _gid, ::std::shared_ptr<policy> _policy) {
+ remove_security_policy(_uid, _gid);
+ std::lock_guard<std::mutex> its_lock(any_client_policies_mutex_);
+ any_client_policies_.push_back(_policy);
+}
+
+void configuration_impl::add_security_credentials(uint32_t _uid, uint32_t _gid,
+ ::std::shared_ptr<policy> _credentials_policy, client_t _client) {
+
+ bool was_found(false);
+ std::lock_guard<std::mutex> its_lock(any_client_policies_mutex_);
+ for (auto its_policy : any_client_policies_) {
+ bool has_uid(false), has_gid(false);
+ for (auto its_credential : its_policy->ids_) {
+ has_uid = has_gid = false;
+ for (auto its_range : std::get<0>(its_credential)) {
+ if (std::get<0>(its_range) <= _uid && _uid <= std::get<1>(its_range)) {
+ has_uid = true;
+ break;
+ }
+ }
+ for (auto its_range : std::get<1>(its_credential)) {
+ if (std::get<0>(its_range) <= _gid && _gid <= std::get<1>(its_range)) {
+ has_gid = true;
+ break;
+ }
+ }
+ if (has_uid && has_gid && its_policy->allow_who_) {
+ was_found = true;
+ break;
+ }
+ }
+ if (was_found) {
+ break;
+ }
+ }
+ // Do not add the new (credentials-only-policy) if a allow credentials policy with same credentials was found
+ if (!was_found) {
+ any_client_policies_.push_back(_credentials_policy);
+ VSOMEIP_INFO << __func__ << " Added security credentials at client: 0x"
+ << std::hex << _client << std::dec << " with UID: " << _uid << " GID: " << _gid;
+ }
+}
+
+bool configuration_impl::is_remote_client_allowed() const {
+ if (!check_credentials_) {
+ return true;
+ }
+ return allow_remote_clients_;
+}
+
+bool configuration_impl::is_policy_update_allowed(uint32_t _uid, std::shared_ptr<policy> &_policy) const {
+ bool uid_allowed(false);
+ {
+ std::lock_guard<std::mutex> its_lock(uid_whitelist_mutex_);
+ for (auto its_uid_range : uid_whitelist_) {
+ if (std::get<0>(its_uid_range) <= _uid && _uid <= std::get<1>(its_uid_range)) {
+ uid_allowed = true;
+ break;
+ }
+ }
+ }
+
+ if (uid_allowed) {
+ std::lock_guard<std::mutex> its_lock(service_interface_whitelist_mutex_);
+ for (auto its_request : _policy->services_) {
+ auto its_requested_service = std::get<0>(its_request);
+ bool has_service(false);
+ for (auto its_service_range : service_interface_whitelist_) {
+ if (std::get<0>(its_service_range) <= its_requested_service
+ && its_requested_service <= std::get<1>(its_service_range)) {
+ has_service = true;
+ break;
+ }
+ }
+ if (!has_service) {
+ if (!check_whitelist_) {
+ VSOMEIP_INFO << "vSomeIP Security: Policy update requesting service ID: "
+ << std::hex << its_requested_service
+ << " is not allowed, but will be allowed due to whitelist audit mode is active!";
+ } else {
+ VSOMEIP_WARNING << "vSomeIP Security: Policy update requesting service ID: "
+ << std::hex << its_requested_service
+ << " is not allowed! -> ignore update";
+ }
+ return !check_whitelist_;
+ }
+ }
+ return true;
+ } else {
+ if (!check_whitelist_) {
+ VSOMEIP_INFO << "vSomeIP Security: Policy update for UID: " << std::dec << _uid
+ << " is not allowed, but will be allowed due to whitelist audit mode is active!";
+ } else {
+ VSOMEIP_WARNING << "vSomeIP Security: Policy update for UID: " << std::dec << _uid
+ << " is not allowed! -> ignore update";
+ }
+ return !check_whitelist_;
+ }
+}
+
+bool configuration_impl::is_policy_removal_allowed(uint32_t _uid) const {
+ std::lock_guard<std::mutex> its_lock(uid_whitelist_mutex_);
+ for (auto its_uid_range : uid_whitelist_) {
+ if (std::get<0>(its_uid_range) <= _uid && _uid <= std::get<1>(its_uid_range)) {
+ return true;
+ }
+ }
+
+ if (!check_whitelist_) {
+ VSOMEIP_INFO << "vSomeIP Security: Policy removal for UID: " << std::dec << _uid
+ << " is not allowed, but will be allowed due to whitelist audit mode is active!";
+ } else {
+ VSOMEIP_WARNING << "vSomeIP Security: Policy removal for UID: " << std::dec << _uid
+ << " is not allowed! -> ignore removal";
+ }
+ return !check_whitelist_;
+}
+
+bool configuration_impl::check_routing_credentials(client_t _client, uint32_t _uid, uint32_t _gid) const {
+ if (_client != get_id(routing_host_)) {
+ return true;
+ } else {
+ std::lock_guard<std::mutex> its_lock(routing_credentials_mutex_);
+ if ( std::get<0>(routing_credentials_) == _uid
+ && std::get<1>(routing_credentials_) == _gid) {
+ return true;
+ }
+ }
+
+ std::string security_mode_text = "!";
+ if (!check_routing_credentials_) {
+ security_mode_text = " but will be allowed due to audit mode is active!";
+ }
+ VSOMEIP_INFO << "vSomeIP Security: Client 0x"
+ << std::hex << _client << " and UID/GID=" << std::dec << _uid
+ << "/" << _gid << " : Check routing credentials failed as "
+ << "configured routing manager credentials "
+ << "do not match with routing manager credentials"
+ << security_mode_text;
+
+ return !check_routing_credentials_;
+}
+
+std::uint32_t configuration_impl::get_shutdown_timeout() const {
+ return shutdown_timeout_;
+}
+
} // namespace config
} // namespace vsomeip