summaryrefslogtreecommitdiff
path: root/implementation/endpoints/src/credentials.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'implementation/endpoints/src/credentials.cpp')
-rw-r--r--implementation/endpoints/src/credentials.cpp105
1 files changed, 65 insertions, 40 deletions
diff --git a/implementation/endpoints/src/credentials.cpp b/implementation/endpoints/src/credentials.cpp
index 3b9762c..70d8dcc 100644
--- a/implementation/endpoints/src/credentials.cpp
+++ b/implementation/endpoints/src/credentials.cpp
@@ -1,10 +1,12 @@
-// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// Copyright (C) 2014-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 _WIN32
+#if defined(__linux__) || defined(ANDROID)
+#include <cerrno>
+#include <cstring>
#include <sys/socket.h>
#include "../include/credentials.hpp"
@@ -21,7 +23,7 @@ namespace vsomeip_v3 {
void credentials::activate_credentials(const int _fd) {
int optval = 1;
if (setsockopt(_fd, SOL_SOCKET, SO_PASSCRED, &optval, sizeof(optval)) == -1) {
- VSOMEIP_ERROR << "vSomeIP Security: Activating socket option for receiving "
+ VSOMEIP_ERROR << __func__ << ": vSomeIP Security: Activating socket option for receiving "
<< "credentials failed.";
}
}
@@ -29,70 +31,94 @@ void credentials::activate_credentials(const int _fd) {
void credentials::deactivate_credentials(const int _fd) {
int optval = 0;
if (setsockopt(_fd, SOL_SOCKET, SO_PASSCRED, &optval, sizeof(optval)) == -1) {
- VSOMEIP_ERROR << "vSomeIP Security: Deactivating socket option for receiving "
+ VSOMEIP_ERROR << __func__ << ": vSomeIP Security: Deactivating socket option for receiving "
<< "credentials failed.";
}
}
-client_t credentials::receive_credentials(const int _fd, uid_t& _uid, gid_t& _gid) {
- struct ucred *ucredp;
+boost::optional<credentials::received_t> credentials::receive_credentials(const int _fd) {
struct msghdr msgh;
- struct iovec iov;
+ struct iovec iov[2];
union {
struct cmsghdr cmh;
char control[CMSG_SPACE(sizeof(struct ucred))];
} control_un;
- struct cmsghdr *cmhp;
- // Sender client_id will be received as data
- client_t client = VSOMEIP_ROUTING_CLIENT;
- // Set 'control_un' to describe ancillary data that we want to receive
- control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred));
- control_un.cmh.cmsg_level = SOL_SOCKET;
- control_un.cmh.cmsg_type = SCM_CREDENTIALS;
+ // We don't need address of peer as we using connect
+ msgh.msg_name = NULL;
+ msgh.msg_namelen = 0;
+
+ // Set fields of 'msgh' to point to buffer used to receive (real) data read by recvmsg()
+ msgh.msg_iov = iov;
+ msgh.msg_iovlen = 2;
// Set 'msgh' fields to describe 'control_un'
msgh.msg_control = control_un.control;
msgh.msg_controllen = sizeof(control_un.control);
- // Set fields of 'msgh' to point to buffer used to receive (real) data read by recvmsg()
- msgh.msg_iov = &iov;
- msgh.msg_iovlen = 1;
- iov.iov_base = &client;
- iov.iov_len = sizeof(client_t);
+ // Sender client_id and client_host_length will be received as data
+ client_t client = VSOMEIP_ROUTING_CLIENT;
+ uint8_t client_host_length(0);
+ iov[0].iov_base = &client;
+ iov[0].iov_len = sizeof(client_t);
+ iov[1].iov_base = &client_host_length;
+ iov[1].iov_len = sizeof(uint8_t);
- // We don't need address of peer as we using connect
- msgh.msg_name = NULL;
- msgh.msg_namelen = 0;
+ // Set 'control_un' to describe ancillary data that we want to receive
+ control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred));
+ control_un.cmh.cmsg_level = SOL_SOCKET;
+ control_un.cmh.cmsg_type = SCM_CREDENTIALS;
- // Receive client_id plus ancillary data
+ // Receive client_id plus client_host_length plus ancillary data
ssize_t nr = recvmsg(_fd, &msgh, 0);
if (nr == -1) {
- VSOMEIP_ERROR << "vSomeIP Security: Receiving credentials failed. No data.";
+ VSOMEIP_ERROR << __func__ << ": vSomeIP Security: Receiving credentials failed. No data. errno: " << std::strerror(errno);
+ return boost::none;
}
- cmhp = CMSG_FIRSTHDR(&msgh);
+ struct cmsghdr* cmhp = CMSG_FIRSTHDR(&msgh);
if (cmhp == NULL || cmhp->cmsg_len != CMSG_LEN(sizeof(struct ucred))
|| cmhp->cmsg_level != SOL_SOCKET || cmhp->cmsg_type != SCM_CREDENTIALS) {
- VSOMEIP_ERROR << "vSomeIP Security: Receiving credentials failed. Invalid data.";
- } else {
- ucredp = (struct ucred *) CMSG_DATA(cmhp);
- _uid = ucredp->uid;
- _gid = ucredp->gid;
+ VSOMEIP_ERROR << __func__ << ": vSomeIP Security: Receiving credentials failed. Invalid data.";
+ return boost::none;
}
- return client;
+ // Use the implicitly-defined copy constructor
+ struct ucred ucred = *reinterpret_cast<struct ucred*>(CMSG_DATA(cmhp));
+
+ msgh.msg_iov = iov;
+ msgh.msg_iovlen = 1;
+ msgh.msg_control = nullptr;
+ msgh.msg_controllen = 0;
+
+ // Receive client_host as data
+ std::string client_host(client_host_length, '\0');
+ iov[0].iov_base = &client_host.front();
+ iov[0].iov_len = client_host.length();
+
+ nr = recvmsg(_fd, &msgh, 0);
+ if (nr == -1) {
+ VSOMEIP_ERROR << __func__ << ": vSomeIP Security: Receiving client host failed. No data. errno: " << std::strerror(errno);
+ return boost::none;
+ }
+
+ return received_t{client, ucred.uid, ucred.gid, client_host};
}
-void credentials::send_credentials(const int _fd, client_t _client) {
+void credentials::send_credentials(const int _fd, client_t _client, std::string _client_host) {
struct msghdr msgh;
- struct iovec iov;
+ struct iovec iov[3];
+ uint8_t client_host_length = (uint8_t)_client_host.length();
// data to send
- msgh.msg_iov = &iov;
- msgh.msg_iovlen = 1;
- iov.iov_base = &_client;
- iov.iov_len = sizeof(client_t);
+ msgh.msg_iov = &iov[0];
+ msgh.msg_iovlen = 3;
+ iov[0].iov_base = &_client;
+ iov[0].iov_len = sizeof(client_t);
+ iov[1].iov_base = &client_host_length;
+ iov[1].iov_len = sizeof(uint8_t);
+ iov[2].iov_base = &_client_host[0];
+ iov[2].iov_len = client_host_length;
// destination not needed as we use connect
msgh.msg_name = NULL;
@@ -105,11 +131,10 @@ void credentials::send_credentials(const int _fd, client_t _client) {
// send client id with credentials
ssize_t ns = sendmsg(_fd, &msgh, 0);
if (ns == -1) {
- VSOMEIP_ERROR << "Sending credentials failed.";
+ VSOMEIP_ERROR << __func__ << ": Sending credentials failed. errno: " << std::strerror(errno);
}
}
} // namespace vsomeip_v3
-#endif // #ifndef _WIN32
-
+#endif // __linux__ || ANDROID