Get credentials from peer
authorSangwan Kwon <sangwan.kwon@samsung.com>
Thu, 16 Jan 2020 06:50:34 +0000 (15:50 +0900)
committer권상완/Security 2Lab(SR)/Engineer/삼성전자 <sangwan.kwon@samsung.com>
Fri, 17 Jan 2020 06:24:01 +0000 (15:24 +0900)
Signed-off-by: Sangwan Kwon <sangwan.kwon@samsung.com>
src/vist/rmi/impl/credentials.hpp [new file with mode: 0644]
src/vist/rmi/impl/tests/socket.cpp

diff --git a/src/vist/rmi/impl/credentials.hpp b/src/vist/rmi/impl/credentials.hpp
new file mode 100644 (file)
index 0000000..f4af021
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ *  Copyright (c) 2020-present Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+#pragma once
+
+#include <vist/exception.hpp>
+
+#include <sys/socket.h>
+#include <sys/types.h>
+
+namespace vist {
+namespace rmi {
+namespace impl {
+
+struct Credentials {
+       pid_t pid;
+       uid_t uid;
+       gid_t gid;
+
+       static Credentials GetPeers(int fd)
+       {
+               struct ucred cred;
+               socklen_t credsz = sizeof(cred);
+               errno = 0;
+               if (::getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cred, &credsz))
+                       THROW(ErrCode::RuntimeError) << "Failed to get peer credential: " << errno;
+
+               return {cred.pid, cred.uid, cred.gid};
+       }
+};
+
+} // namespace impl
+} // namespace rmi
+} // namespace vist
index 2437e3acb7c13cd17661efb442e82cb9ef0a0ca8..85d4e25b63bcaf4d5cb734d3fc038e553c818663 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2020-present Samsung Electronics Co., Ltd All Rights Reserved
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
  *  limitations under the License
  */
 
+#include <vist/rmi/impl/credentials.hpp>
 #include <vist/rmi/impl/socket.hpp>
 
-#include <string>
+#include <cstring>
 #include <limits>
+#include <string>
 #include <thread>
-#include <chrono>
-#include <cstring>
 
 #include <gtest/gtest.h>
 
@@ -38,8 +38,6 @@ TEST(SocketTests, socket_read_write)
        bool output2 = false;
 
        auto client = std::thread([&]() {
-               std::this_thread::sleep_for(std::chrono::seconds(1));
-
                // Send input to server.
                Socket connected = Socket::connect(sockPath);
                connected.send(&input);
@@ -75,8 +73,6 @@ TEST(SocketTests, socket_abstract)
        bool output2 = false;
 
        auto client = std::thread([&]() {
-               std::this_thread::sleep_for(std::chrono::seconds(1));
-
                // Send input to server.
                Socket connected = Socket::connect(sockPath);
                connected.send(&input);
@@ -99,3 +95,28 @@ TEST(SocketTests, socket_abstract)
        if (client.joinable())
                client.join();
 }
+
+TEST(SocketTests, peer_credeintials)
+{
+       std::string sockPath = "@sock";
+       Socket socket(sockPath);
+
+       int input = std::numeric_limits<int>::max();
+       auto client = std::thread([&]() {
+               Socket connected = Socket::connect(sockPath);
+               connected.send(&input);
+       });
+
+       Socket accepted = socket.accept();
+
+       auto cred = Credentials::GetPeers(accepted.getFd());
+       EXPECT_TRUE(cred.pid > 0);
+
+       // Recv input from client.
+       int output = 0;
+       accepted.recv(&output);
+       EXPECT_EQ(input, output);
+
+       if (client.joinable())
+               client.join();
+}