summaryrefslogtreecommitdiff
path: root/implementation/security/include/policy_manager_impl.hpp
blob: 4dd3a865425c002c6689c3928eecb2e2f7ed8a02 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
// Copyright (C) 2019-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef VSOMEIP_V3_SECURITY_POLICY_MANAGER_IMPL_HPP_
#define VSOMEIP_V3_SECURITY_POLICY_MANAGER_IMPL_HPP_

#include <map>
#include <mutex>
#include <unordered_set>
#include <vector>

#include <boost/property_tree/ptree.hpp>
#include <boost/filesystem.hpp>
#include <boost/thread.hpp>

#include <vsomeip/export.hpp>
#include <vsomeip/internal/policy_manager.hpp>
#include <vsomeip/vsomeip_sec.h>

#include "../include/policy.hpp"

namespace vsomeip_v3 {

struct configuration_element;

class VSOMEIP_IMPORT_EXPORT policy_manager_impl
#ifndef VSOMEIP_DISABLE_SECURITY
        : public policy_manager
#endif // !VSOMEIP_DISABLE_SECURITY
{
public:
    enum class policy_loaded_e : std::uint8_t {
        POLICY_PATH_FOUND_AND_LOADED = 0x0,
        POLICY_PATH_FOUND_AND_NOT_LOADED = 0x1,
        POLICY_PATH_INEXISTENT = 0x2
    };

    static std::shared_ptr<policy_manager_impl> get();

    policy_manager_impl();

#ifndef VSOMEIP_DISABLE_SECURITY
    // policy_manager interface
    std::shared_ptr<policy> create_policy() const;
    void print_policy(const std::shared_ptr<policy> &_policy) const;

    bool parse_uid_gid(const byte_t* &_buffer, uint32_t &_buffer_size,
            uint32_t &_uid, uint32_t &_gid) const;
    bool parse_policy(const byte_t* &_buffer, uint32_t &_buffer_size,
            uint32_t &_uid, uint32_t &_gid,
            const std::shared_ptr<policy> &_policy) const;

    bool is_policy_update_allowed(uint32_t _uid,
            std::shared_ptr<policy> &_policy) const;
    bool is_policy_removal_allowed(uint32_t _uid) const;

    // extension
    void load(const configuration_element &_element,
            const bool _lazy_load = false);

    void update_security_policy(uint32_t _uid, uint32_t _gid, const std::shared_ptr<policy>& _policy);
    bool remove_security_policy(uint32_t _uid, uint32_t _gid);

    void add_security_credentials(uint32_t _uid, uint32_t _gid,
            const std::shared_ptr<policy>& _credentials_policy, client_t _client);

    void get_requester_policies(const std::shared_ptr<policy> _policy,
            std::set<std::shared_ptr<policy> > &_requesters) const;
    void get_clients(uid_t _uid, gid_t _gid, std::unordered_set<client_t> &_clients) const;

    bool is_policy_extension(const std::string &_path) const;
    std::string get_policy_extension_path(const std::string &_client_host) const;

    void set_policy_extension_base_path(const std::string &_path);
    std::string get_security_config_folder(const std::string &its_folder) const;
    std::string get_policy_extension_path_unlocked(const std::string &_client_host) const;

    policy_loaded_e is_policy_extension_loaded(const std::string &_client_host) const;
    void set_is_policy_extension_loaded(const std::string &_client_host, const bool _loaded);

private:

    // Configuration
    void load_policies(const configuration_element &_element);
    void load_policy(const boost::property_tree::ptree &_tree);
    void load_policy_body(std::shared_ptr<policy> &_policy,
            const boost::property_tree::ptree::const_iterator &_tree);
    void load_credential(const boost::property_tree::ptree &_tree,
            boost::icl::interval_map<uid_t, boost::icl::interval_set<gid_t> > &_ids);
    bool load_routing_credentials(const configuration_element &_element);
    template<typename T_>
    void load_interval_set(const boost::property_tree::ptree &_tree,
            boost::icl::interval_set<T_> &_range, bool _exclude_margins = false);
    void load_security_update_whitelist(const configuration_element &_element);
    void load_security_policy_extensions(const configuration_element &_element);
#endif // !VSOMEIP_DISABLE_SECURITY

public:
    bool is_enabled() const;
    bool is_audit() const;

    bool check_credentials(client_t _client,
            const vsomeip_sec_client_t *_sec_client);
    bool check_routing_credentials(
            const vsomeip_sec_client_t *_sec_client) const;
    void set_routing_credentials(uint32_t _uid, uint32_t _gid,
            const std::string &_name);

    bool is_client_allowed(const vsomeip_sec_client_t *_sec_client,
            service_t _service, instance_t _instance, method_t _method,
            bool _is_request_service = false) const;
    bool is_offer_allowed(const vsomeip_sec_client_t *_sec_client,
            service_t _service, instance_t _instance) const;

    bool get_sec_client_to_clients_mapping(const vsomeip_sec_client_t *_sec_client,
            std::set<client_t> &_clients);
    bool remove_client_to_sec_client_mapping(client_t _client);

    bool get_client_to_sec_client_mapping(client_t _client, vsomeip_sec_client_t &_sec_client);
    bool store_client_to_sec_client_mapping(client_t _client, const vsomeip_sec_client_t *_sec_client);
    void store_sec_client_to_client_mapping(const vsomeip_sec_client_t *_sec_client, client_t _client);

private:
#ifdef _WIN32
#pragma warning(push)
#pragma warning(disable : 4251)
#endif
#ifndef VSOMEIP_DISABLE_SECURITY
    mutable boost::shared_mutex  any_client_policies_mutex_;
    std::vector<std::shared_ptr<policy> > any_client_policies_;

    mutable boost::shared_mutex is_client_allowed_cache_mutex_;
    mutable std::map<std::pair<uid_t, gid_t>,
        std::set<std::tuple<service_t, instance_t, method_t> >
    > is_client_allowed_cache_;

    bool policy_enabled_;
    bool check_credentials_;
    bool allow_remote_clients_;
    bool check_whitelist_;

    mutable std::mutex service_interface_whitelist_mutex_;
    boost::icl::interval_set<service_t> service_interface_whitelist_;

    mutable std::mutex uid_whitelist_mutex_;
    boost::icl::interval_set<uint32_t> uid_whitelist_;

    mutable std::mutex policy_base_path_mutex_;
    std::string policy_base_path_;

    mutable boost::shared_mutex policy_extension_paths_mutex_;
    //map[hostname, pair[path,  map[complete path with UID/GID, control loading]]
    std::map<std::string, std::pair<std::string, std::map<std::string, bool>>> policy_extension_paths_;
#endif // !VSOMEIP_DISABLE_SECURITY

    bool is_configured_;
    bool check_routing_credentials_;

    mutable std::mutex routing_credentials_mutex_;
    std::pair<uint32_t, uint32_t> routing_credentials_;

    mutable std::mutex ids_mutex_;
    std::map<client_t, vsomeip_sec_client_t> ids_;

    struct vsomeip_sec_client_comparator_t {
        bool operator()(const vsomeip_sec_client_t &_lhs, const vsomeip_sec_client_t &_rhs) const {
            if (_lhs.client_type < _rhs.client_type) {
                return true;
            } else if (_lhs.client_type == _rhs.client_type) {
                switch (_lhs.client_type) {
                case VSOMEIP_CLIENT_UDS:
                    return ((_lhs.client.uds_client.user < _rhs.client.uds_client.user)
                        || ((_lhs.client.uds_client.user == _rhs.client.uds_client.user)
                        && (_lhs.client.uds_client.group < _rhs.client.uds_client.group)));
                case VSOMEIP_CLIENT_TCP:
                    return ((_lhs.client.ip_client.ip < _rhs.client.ip_client.ip)
                        || ((_lhs.client.ip_client.ip == _rhs.client.ip_client.ip)
                        && (_lhs.client.ip_client.port < _rhs.client.ip_client.port)));
                default:
                    ;
                }
            }
            return false;
        }
    };

    mutable std::mutex sec_client_to_clients_mutex_;
    std::map<vsomeip_sec_client_t, std::set<client_t>, vsomeip_sec_client_comparator_t> sec_client_to_clients_;
#ifdef _WIN32
#pragma warning(pop)
#endif
};

} // namespace vsomeip_v3

#endif // VSOMEIP_V3_SECURITY_POLICY_MANAGER_IMPL_HPP_