1 // Copyright (C) 2014-2017 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 #ifndef _WIN32
7 
8 #include <sys/socket.h>
9 
10 #include "../include/credentials.hpp"
11 
12 #include <vsomeip/internal/logger.hpp>
13 #ifdef ANDROID
14 #include "../../configuration/include/internal_android.hpp"
15 #else
16 #include "../../configuration/include/internal.hpp"
17 #endif
18 
19 namespace vsomeip_v3 {
20 
activate_credentials(const int _fd)21 void credentials::activate_credentials(const int _fd) {
22     int optval = 1;
23     if (setsockopt(_fd, SOL_SOCKET, SO_PASSCRED, &optval, sizeof(optval)) == -1) {
24         VSOMEIP_ERROR << "vSomeIP Security: Activating socket option for receiving "
25                       << "credentials failed.";
26     }
27 }
28 
deactivate_credentials(const int _fd)29 void credentials::deactivate_credentials(const int _fd) {
30     int optval = 0;
31     if (setsockopt(_fd, SOL_SOCKET, SO_PASSCRED, &optval, sizeof(optval)) == -1) {
32         VSOMEIP_ERROR << "vSomeIP Security: Deactivating socket option for receiving "
33                       << "credentials failed.";
34     }
35 }
36 
receive_credentials(const int _fd,uid_t & _uid,gid_t & _gid)37 client_t credentials::receive_credentials(const int _fd, uid_t& _uid, gid_t& _gid) {
38     struct ucred *ucredp;
39     struct msghdr msgh;
40     struct iovec iov;
41     union {
42         struct cmsghdr cmh;
43         char   control[CMSG_SPACE(sizeof(struct ucred))];
44     } control_un;
45     struct cmsghdr *cmhp;
46     // Sender client_id will be received as data
47     client_t client = VSOMEIP_ROUTING_CLIENT;
48 
49     // Set 'control_un' to describe ancillary data that we want to receive
50     control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred));
51     control_un.cmh.cmsg_level = SOL_SOCKET;
52     control_un.cmh.cmsg_type = SCM_CREDENTIALS;
53 
54     // Set 'msgh' fields to describe 'control_un'
55     msgh.msg_control = control_un.control;
56     msgh.msg_controllen = sizeof(control_un.control);
57 
58     // Set fields of 'msgh' to point to buffer used to receive (real) data read by recvmsg()
59     msgh.msg_iov = &iov;
60     msgh.msg_iovlen = 1;
61     iov.iov_base = &client;
62     iov.iov_len = sizeof(client_t);
63 
64     // We don't need address of peer as we using connect
65     msgh.msg_name = NULL;
66     msgh.msg_namelen = 0;
67 
68     // Receive client_id plus ancillary data
69     ssize_t nr = recvmsg(_fd, &msgh, 0);
70     if (nr == -1) {
71         VSOMEIP_ERROR << "vSomeIP Security: Receiving credentials failed. No data.";
72     }
73 
74     cmhp = CMSG_FIRSTHDR(&msgh);
75     if (cmhp == NULL || cmhp->cmsg_len != CMSG_LEN(sizeof(struct ucred))
76             || cmhp->cmsg_level != SOL_SOCKET || cmhp->cmsg_type != SCM_CREDENTIALS) {
77         VSOMEIP_ERROR << "vSomeIP Security: Receiving credentials failed. Invalid data.";
78     } else {
79         ucredp = (struct ucred *) CMSG_DATA(cmhp);
80         _uid = ucredp->uid;
81         _gid = ucredp->gid;
82     }
83 
84     return client;
85 }
86 
send_credentials(const int _fd,client_t _client)87 void credentials::send_credentials(const int _fd, client_t _client) {
88     struct msghdr msgh;
89     struct iovec iov;
90 
91     // data to send
92     msgh.msg_iov = &iov;
93     msgh.msg_iovlen = 1;
94     iov.iov_base = &_client;
95     iov.iov_len = sizeof(client_t);
96 
97     // destination not needed as we use connect
98     msgh.msg_name = NULL;
99     msgh.msg_namelen = 0;
100 
101     // credentials not need to set explicitly
102     msgh.msg_control = NULL;
103     msgh.msg_controllen = 0;
104 
105     // send client id with credentials
106     ssize_t ns = sendmsg(_fd, &msgh, 0);
107     if (ns == -1) {
108         VSOMEIP_ERROR << "Sending credentials failed.";
109     }
110 }
111 
112 } // namespace vsomeip_v3
113 
114 #endif // #ifndef _WIN32
115 
116