1 // Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
2 // This Source Code Form is subject to the terms of the Mozilla Public
3 // License, v. 2.0. If a copy of the MPL was not distributed with this
4 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 
6 #include <iomanip>
7 
8 #include <vsomeip/internal/logger.hpp>
9 
10 #include "../include/policy.hpp"
11 #include "../../utility/include/byteorder.hpp"
12 
13 namespace vsomeip_v3 {
14 
15 bool
get_uid_gid(uid_t & _uid,gid_t & _gid) const16 policy::get_uid_gid(uid_t &_uid, gid_t &_gid) const {
17 
18     if (credentials_.size() != 1)
19         return (false);
20 
21     const auto its_uids = credentials_.begin()->first;
22     const auto its_gids = credentials_.begin()->second;
23 
24     if (its_gids.size() != 1)
25         return (false);
26 
27     if (its_uids.lower() != its_uids.upper()
28         || its_gids.begin()->lower() != its_gids.begin()->upper())
29         return (false);
30 
31     _uid = its_uids.lower();
32     _gid = its_gids.begin()->lower();
33 
34     return (true);
35 }
36 
37 bool
deserialize_uid_gid(const byte_t * & _data,uint32_t & _size,uid_t & _uid,gid_t & _gid) const38 policy::deserialize_uid_gid(const byte_t * &_data, uint32_t &_size,
39             uid_t &_uid, gid_t &_gid) const {
40 
41     bool its_result;
42 
43     its_result = deserialize_u32(_data, _size, _uid);
44     if (its_result == false)
45         return (false);
46 
47     its_result = deserialize_u32(_data, _size, _gid);
48     if (its_result == false)
49         return (false);
50 
51     return (true);
52 }
53 
54 bool
deserialize(const byte_t * & _data,uint32_t & _size)55 policy::deserialize(const byte_t * &_data, uint32_t &_size) {
56 
57     bool its_result;
58     uid_t its_uid;
59     gid_t its_gid;
60 
61     std::lock_guard<std::mutex> its_lock(mutex_);
62 
63     its_result = deserialize_uid_gid(_data, _size, its_uid, its_gid);
64     if (its_result == false)
65         return (false);
66 
67     // Fill policy uid/gid
68     const auto its_uid_interval
69         = boost::icl::interval<uid_t>::closed(its_uid, its_uid);
70     boost::icl::interval_set<gid_t> its_gid_set;
71     its_gid_set.insert(its_gid);
72     credentials_ += std::make_pair(its_uid_interval, its_gid_set);
73 
74     // Deserialized policies are always "Allow" - policies
75     allow_who_ = true;
76     allow_what_ = true;
77 
78     // Deserialize requests array length
79     uint32_t its_requests_length;
80     its_result = deserialize_u32(_data, _size, its_requests_length);
81     if (its_result == false)
82         return (false);
83 
84     // Deserialize requests
85     while (0 < its_requests_length) {
86 
87         uint32_t its_current_size(_size);
88 
89         uint16_t its_service;
90         its_result = deserialize_u16(_data, _size, its_service);
91         if (its_result == false)
92             return (false);
93 
94         if (its_service == 0x0000 || its_service == 0xffff) {
95             VSOMEIP_WARNING << "vSomeIP Security: Policy with service ID: 0x"
96                     << std::hex << its_service << " is not allowed!";
97             return (false);
98         }
99 
100         const auto its_service_interval
101             = boost::icl::interval<service_t>::closed(its_service, its_service);
102 
103         boost::icl::interval_map<instance_t,
104             boost::icl::interval_set<method_t> > its_ids;
105         its_result = deserialize_ids(_data, _size, its_ids);
106         if (its_result == false)
107             return (false);
108 
109         requests_ += std::make_pair(its_service_interval, its_ids);
110 
111         its_requests_length -= (its_current_size - _size);
112     }
113 
114     // Deserialize offers array length
115     uint32_t its_offers_length;
116     its_result = deserialize_u32(_data, _size, its_offers_length);
117     if (its_result == false)
118         return (false);
119 
120     while (0 < its_offers_length) {
121 
122         uint32_t its_current_size(_size);
123 
124         uint16_t its_service;
125         its_result = deserialize_u16(_data, _size, its_service);
126         if (its_result == false)
127             return (false);
128 
129         if (its_service == 0x0000 || its_service == 0xFFFF) {
130             VSOMEIP_WARNING << "vSomeIP Security: Policy with service ID: 0x"
131                     << std::hex << its_service << " is not allowed!";
132             return false;
133         }
134 
135         const auto its_service_interval
136             = boost::icl::interval<service_t>::closed(its_service, its_service);
137 
138         boost::icl::interval_set<instance_t> its_instance_interval_set;
139         its_result = deserialize_id_item_list(_data, _size,
140                 its_instance_interval_set);
141         if (its_result == false)
142             return (false);
143 
144         offers_ += std::make_pair(its_service_interval, its_instance_interval_set);
145 
146         its_offers_length -= (its_current_size - _size);
147     }
148 
149     return (true);
150 }
151 
152 bool
deserialize_ids(const byte_t * & _data,uint32_t & _size,boost::icl::interval_map<uint16_t,boost::icl::interval_set<uint16_t>> & _ids) const153 policy::deserialize_ids(const byte_t * &_data, uint32_t &_size,
154         boost::icl::interval_map<uint16_t,
155             boost::icl::interval_set<uint16_t> > &_ids) const {
156 
157     boost::icl::interval_map<uint16_t,
158         boost::icl::interval_set<uint16_t> > its_ids;
159     uint32_t its_array_length;
160     bool its_result;
161 
162     its_result = deserialize_u32(_data, _size, its_array_length);
163     if (its_result == false)
164         return (false);
165 
166     while (0 < its_array_length) {
167         uint32_t its_current_size(_size);
168 
169         boost::icl::interval_set<uint16_t> its_instances, its_methods;
170         its_result = deserialize_id_item_list(_data, _size, its_instances);
171         if (its_result == false)
172             return (false);
173 
174         its_result = deserialize_id_item_list(_data, _size, its_methods);
175         if (its_result == false)
176             return (false);
177 
178         for (const auto& i : its_instances)
179             its_ids += std::make_pair(i, its_methods);
180 
181         its_array_length -= (its_current_size - _size);
182     }
183 
184     _ids = std::move(its_ids);
185 
186     return (true);
187 }
188 
189 bool
deserialize_id_item_list(const byte_t * & _data,uint32_t & _size,boost::icl::interval_set<uint16_t> & _intervals) const190 policy::deserialize_id_item_list(const byte_t * &_data, uint32_t &_size,
191         boost::icl::interval_set<uint16_t> &_intervals) const {
192 
193     boost::icl::interval_set<uint16_t> its_intervals;
194     uint32_t its_length;
195     bool its_result;
196 
197     its_result = deserialize_u32(_data, _size, its_length);
198     if (its_result == false)
199         return (its_result);
200 
201     while (0 < its_length) {
202 
203         uint32_t its_current_size(_size);
204 
205         uint16_t its_low, its_high;
206         its_result = deserialize_id_item(_data, _size, its_low, its_high);
207         if (its_result == false)
208             return (false);
209 
210         its_intervals.insert(boost::icl::interval<uint16_t>::closed(its_low, its_high));
211 
212         its_length -= (its_current_size - _size);
213     }
214 
215     _intervals = std::move(its_intervals);
216 
217     return (true);
218 }
219 
220 bool
deserialize_id_item(const byte_t * & _data,uint32_t & _size,uint16_t & _low,uint16_t & _high) const221 policy::deserialize_id_item(const byte_t * &_data, uint32_t &_size,
222         uint16_t &_low, uint16_t &_high) const {
223 
224     uint32_t its_length, its_type;
225     bool its_result;
226 
227     its_result = deserialize_u32(_data, _size, its_length);
228     if (its_result == false)
229         return (false);
230 
231     its_result = deserialize_u32(_data, _size, its_type);
232     if (its_result == false)
233         return (false);
234 
235     if (its_type == 1 && its_length == sizeof(uint16_t)) {
236         its_result = deserialize_u16(_data, _size, _low);
237         if (its_result == false)
238             return (false);
239 
240         _high = _low;
241     } else if (its_type == 2
242             && its_length == sizeof(uint16_t) + sizeof(uint16_t)) {
243         its_result = deserialize_u16(_data, _size, _low);
244         if (its_result == false)
245             return (false);
246 
247         its_result = deserialize_u16(_data, _size, _high);
248         if (its_result == false)
249             return (false);
250 
251         if (_low > _high)
252             return (false);
253     }
254 
255     // handle ANY_METHOD configuration
256     if (_low == ANY_METHOD && _high == ANY_METHOD) {
257         _low = 0x01;
258     }
259 
260     return (_low != 0x0000);
261 }
262 
263 bool
deserialize_u16(const byte_t * & _data,uint32_t & _size,uint16_t & _value) const264 policy::deserialize_u16(const byte_t * &_data, uint32_t &_size,
265         uint16_t &_value) const {
266 
267     if (_size < sizeof(uint16_t))
268         return (false);
269 
270     _value = VSOMEIP_BYTES_TO_WORD(_data[0], _data[1]);
271 
272     _data += sizeof(uint16_t);
273     _size -= static_cast<uint16_t>(sizeof(uint16_t));
274 
275     return (true);
276 }
277 
278 bool
deserialize_u32(const byte_t * & _data,uint32_t & _size,uint32_t & _value) const279 policy::deserialize_u32(const byte_t * &_data, uint32_t &_size,
280         uint32_t &_value) const {
281 
282     if (_size < sizeof(uint32_t))
283         return (false);
284 
285     _value = VSOMEIP_BYTES_TO_LONG(_data[0], _data[1], _data[2], _data[3]);
286 
287     _data += sizeof(uint32_t);
288     _size -= static_cast<uint32_t>(sizeof(uint32_t));
289 
290     return (true);
291 }
292 
293 bool
serialize(std::vector<byte_t> & _data) const294 policy::serialize(std::vector<byte_t> &_data) const {
295 
296     bool its_result;
297 
298     std::lock_guard<std::mutex> its_lock(mutex_);
299 
300     its_result = serialize_uid_gid(_data);
301     if (!its_result)
302         return (false);
303 
304     size_t its_requests_pos = _data.size();
305     uint32_t its_requests_size(0);
306     serialize_u32(its_requests_size, _data);
307 
308     for (const auto &its_request : requests_) {
309         for (auto its_service = its_request.first.lower();
310                 its_service <= its_request.first.upper();
311                 its_service++) {
312 
313             serialize_u16(its_service, _data);
314 
315             size_t its_pos = _data.size();
316             uint32_t its_instances_size(0);
317             serialize_u32(its_instances_size, _data);
318 
319             for (const auto &i : its_request.second) {
320                 boost::icl::interval_set<instance_t> its_instances;
321                 its_instances.insert(i.first);
322                 serialize_interval_set(its_instances, _data);
323                 serialize_interval_set(i.second, _data);
324             }
325 
326             its_instances_size = static_cast<uint32_t>(_data.size() - its_pos - sizeof(uint32_t));
327             serialize_u32_at(its_instances_size, _data, its_pos);
328         }
329     }
330 
331     its_requests_size = static_cast<uint32_t>(_data.size() - its_requests_pos - sizeof(uint32_t));
332     serialize_u32_at(its_requests_size, _data, its_requests_pos);
333 
334     uint32_t its_offers_size = 0;
335     serialize_u32(its_offers_size, _data);
336 
337     return (true);
338 }
339 
340 bool
serialize_uid_gid(std::vector<byte_t> & _data) const341 policy::serialize_uid_gid(std::vector<byte_t> &_data) const {
342 
343     if (credentials_.size() != 1) {
344         VSOMEIP_ERROR << "Unserializable policy (ids).";
345         return (false);
346     }
347 
348     auto its_credential = *(credentials_.begin());
349     if (its_credential.second.size() != 1) {
350         VSOMEIP_ERROR << "Unserializable policy (intervals).";
351         return (false);
352     }
353 
354     auto its_uid_interval = its_credential.first;
355     if (its_uid_interval.lower() != its_uid_interval.upper()) {
356         VSOMEIP_ERROR << "Unserializable policy (uid).";
357         return (false);
358     }
359 
360     auto its_gid_interval = *(its_credential.second.begin());
361     if (its_gid_interval.lower() != its_gid_interval.upper()) {
362         VSOMEIP_ERROR << "Unserializable policy (gid).";
363         return (false);
364     }
365 
366     serialize_u32(its_uid_interval.lower(), _data);
367     serialize_u32(its_gid_interval.lower(), _data);
368 
369     return (true);
370 }
371 
372 void
serialize_interval_set(const boost::icl::interval_set<uint16_t> & _intervals,std::vector<byte_t> & _data) const373 policy::serialize_interval_set(
374         const boost::icl::interval_set<uint16_t> &_intervals,
375         std::vector<byte_t> &_data) const {
376 
377     size_t its_pos(_data.size());
378     uint32_t its_interval_set_size(0);
379     serialize_u32(its_interval_set_size, _data);
380 
381     for (const auto& i : _intervals)
382         serialize_interval(i, _data);
383 
384     its_interval_set_size = static_cast<uint32_t>(_data.size()
385             - its_pos - sizeof(uint32_t));
386     serialize_u32_at(its_interval_set_size, _data, its_pos);
387 }
388 
389 void
serialize_interval(const boost::icl::discrete_interval<uint16_t> & _interval,std::vector<byte_t> & _data) const390 policy::serialize_interval(
391         const boost::icl::discrete_interval<uint16_t> &_interval,
392         std::vector<byte_t> &_data) const {
393 
394     uint32_t its_union_length, its_union_type;
395 
396     if (_interval.lower() == _interval.upper()) { // single value
397         its_union_length = static_cast<uint32_t>(sizeof(uint16_t));
398         its_union_type = 1;
399 
400         serialize_u32(its_union_length, _data);
401         serialize_u32(its_union_type, _data);
402 
403         serialize_u16(_interval.lower(), _data);
404     } else { // value interval
405         its_union_type = 2;
406         its_union_length = static_cast<uint32_t>(
407                 sizeof(uint16_t) + sizeof(uint16_t));
408 
409         serialize_u32(its_union_length, _data);
410         serialize_u32(its_union_type, _data);
411 
412         serialize_u16(_interval.lower(), _data);
413         serialize_u16(_interval.upper(), _data);
414     }
415 }
416 
417 void
serialize_u16(uint16_t _value,std::vector<byte_t> & _data) const418 policy::serialize_u16(uint16_t _value,
419         std::vector<byte_t> &_data) const {
420 
421     _data.push_back(VSOMEIP_WORD_BYTE1(_value));
422     _data.push_back(VSOMEIP_WORD_BYTE0(_value));
423 }
424 
425 void
serialize_u32(uint32_t _value,std::vector<byte_t> & _data) const426 policy::serialize_u32(uint32_t _value,
427         std::vector<byte_t> &_data) const {
428 
429     _data.push_back(VSOMEIP_LONG_BYTE3(_value));
430     _data.push_back(VSOMEIP_LONG_BYTE2(_value));
431     _data.push_back(VSOMEIP_LONG_BYTE1(_value));
432     _data.push_back(VSOMEIP_LONG_BYTE0(_value));
433 }
434 
435 void
serialize_u32_at(uint32_t _value,std::vector<byte_t> & _data,size_t _pos) const436 policy::serialize_u32_at(uint32_t _value,
437         std::vector<byte_t> &_data, size_t _pos) const {
438 
439     _data[_pos] = VSOMEIP_LONG_BYTE3(_value);
440     _data[_pos+1] = VSOMEIP_LONG_BYTE2(_value);
441     _data[_pos+2] = VSOMEIP_LONG_BYTE1(_value);
442     _data[_pos+3] = VSOMEIP_LONG_BYTE0(_value);
443 }
444 
445 void
print() const446 policy::print() const {
447 
448     for (auto its_credential : credentials_) {
449         auto its_uid_interval = its_credential.first;
450         if (its_uid_interval.lower() == std::numeric_limits<uint32_t>::max()) {
451             VSOMEIP_INFO << "policy::print Security configuration: UID: any";
452         } else {
453             VSOMEIP_INFO << "policy::print Security configuration: UID: "
454                     << std::dec << its_uid_interval.lower();
455         }
456         for (auto its_gid_interval : its_credential.second) {
457             if (its_gid_interval.lower() == std::numeric_limits<uint32_t>::max()) {
458                 VSOMEIP_INFO << "    policy::print Security configuration: GID: any";
459             } else {
460                 VSOMEIP_INFO << "    policy::print Security configuration: GID: "
461                         << std::dec << its_gid_interval.lower();
462             }
463         }
464     }
465 
466     VSOMEIP_INFO << "policy::print Security configuration: REQUESTS POLICY SIZE: "
467             << std::dec << requests_.size();
468     for (auto its_request : requests_) {
469         VSOMEIP_INFO << "policy::print ALLOWED REQUESTS Services:"
470                 << std::hex << its_request.first;
471         for (auto its_instance : its_request.second) {
472             VSOMEIP_INFO << "policy::print     Instances: ";
473             VSOMEIP_INFO << "policy::print          first: 0x"
474                     << std::hex << its_instance.first.lower()
475                     << " last: 0x" << its_instance.first.upper();
476             VSOMEIP_INFO << "policy::print     Methods: ";
477             for (auto its_method : its_instance.second) {
478                 VSOMEIP_INFO << "policy::print          first: 0x"
479                         << std::hex << its_method.lower()
480                         << " last: 0x" << its_method.upper();
481             }
482         }
483     }
484 
485     VSOMEIP_INFO << "policy::print Security configuration: OFFER POLICY SIZE: "
486             << std::dec << offers_.size();
487     for (auto its_offer : offers_) {
488         VSOMEIP_INFO << "policy::print ALLOWED OFFERS Services:"
489                 << std::hex << its_offer.first;
490         for (auto its_instance : its_offer.second) {
491             VSOMEIP_INFO << "policy::print     Instances: ";
492             VSOMEIP_INFO << "policy::print          first: 0x"
493                         << std::hex << its_instance.lower()
494                         << " last: 0x" << its_instance.upper();
495         }
496     }
497 }
498 
499 } // namespace vsomeip_v3
500