Adjust app identification to no-smack 89/320389/5
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Thu, 27 Feb 2025 17:43:52 +0000 (18:43 +0100)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Tue, 18 Mar 2025 13:56:09 +0000 (14:56 +0100)
Change-Id: Id835ba7e0fcd64d54319173b9830e8addee1c179

src/manager/common/protocols.cpp
src/manager/common/protocols.h
src/manager/main/socket-2-id.cpp
src/manager/main/socket-2-id.h
src/manager/main/socket-manager.cpp
src/manager/service/access-control.cpp
src/manager/service/access-control.h

index 13cbd615cb295c0adc014865e4516b17207e7082..5cbc66d5bca8d4a36aa8d3b4625dc7d9218fb7d4 100644 (file)
@@ -43,6 +43,7 @@ char const *const SERVICE_SOCKET_ENCRYPTION =
 char const *const ALIAS_SEPARATOR = " ";
 char const *const CLIENT_ID_SYSTEM = "/System";
 char const *const CLIENT_ID_ADMIN_USER = "/User";
+char const *const CLIENT_ID_UNKNOWN = "/Unknown";
 char const *const KEY_MANAGER_BOOST_TARGET = "key-manager";
 
 PolicySerializable::PolicySerializable(IStream &stream)
index cf9375da4e3a2d0afb54c088781e0e8fd910be79..c02f82698b55cc5ec6577ef91866dbfc8c87d042 100644 (file)
@@ -93,6 +93,7 @@ enum class EncryptionCommand : int {
 COMMON_API extern char const *const ALIAS_SEPARATOR;
 COMMON_API extern char const *const CLIENT_ID_SYSTEM;
 COMMON_API extern char const *const CLIENT_ID_ADMIN_USER;
+COMMON_API extern char const *const CLIENT_ID_UNKNOWN;
 
 typedef std::vector<std::pair<ClientId, Name>> OwnerNameVector;
 
index 8d4f712ff1efbdf694ef431df72c22c090479840..29defbb8f1a46d70034ee7793a0237e6a2642708 100644 (file)
  * @author     Bartlomiej Grzelewski (b.grzelewski@samsung.com)
  * @version    1.0
  */
+
+#include "socket-2-id.h"
+
+#include "access-control.h"
+#include "dpl/log/log.h"
+#include "protocols.h"
+#include "security-manager.h"
+
 #include <sys/smack.h>
 #include <sys/types.h>
-#include <sys/socket.h>
-
-#include <security-manager.h>
 
-#include <dpl/log/log.h>
-#include <protocols.h>
-#include <socket-2-id.h>
 
 namespace CKM {
 
@@ -73,7 +75,18 @@ int assignToString(std::vector<char> &vec, socklen_t len, std::string &res)
 
 } // namespace anonymous
 
-int Socket2Id::getCredentialsFromSocket(int sock, std::string &res)
+int Socket2Id::getPeerCred(int sock, ucred &peerCred)
+{
+       socklen_t length = sizeof(ucred);
+
+       if (0 > getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &peerCred, &length)) {
+               LogError("getsockopt failed");
+               return -1;
+       }
+       return 0;
+}
+
+int Socket2IdSmack::getCredentialsFromSocket(int sock, std::string &res)
 {
        std::vector<char> result(SMACK_LABEL_LEN + 1);
        socklen_t length = SMACK_LABEL_LEN;
@@ -82,7 +95,7 @@ int Socket2Id::getCredentialsFromSocket(int sock, std::string &res)
                return assignToString(result, length, res);
 
        if (errno != ERANGE) {
-               LogError("getsockopt failed");
+               LogError("getsockopt failed with errno: " << errno);
                return -1;
        }
 
@@ -96,7 +109,7 @@ int Socket2Id::getCredentialsFromSocket(int sock, std::string &res)
        return assignToString(result, length, res);
 }
 
-void Socket2Id::mapToDomainClient(std::string &pkgId)
+void Socket2IdSmack::mapToDomainClient(std::string &pkgId)
 {
        static const std::string subdomainSep = "::";
        static const auto systemClientLen = strlen(CLIENT_ID_SYSTEM);
@@ -108,22 +121,23 @@ void Socket2Id::mapToDomainClient(std::string &pkgId)
        }
 }
 
-void Socket2Id::resetCache()
+int Socket2IdSmack::translate(int sock, CKM::Credentials &creds)
 {
-       m_stringMap.clear();
-}
+       ucred peerCred;
+       if (0 > Socket2Id::getPeerCred(sock, peerCred))
+               return -1;
+
+       creds.clientUid = peerCred.uid;
 
-int Socket2Id::translate(int sock, std::string &result)
-{
        std::string smack;
 
        if (0 > getCredentialsFromSocket(sock, smack))
                return -1;
 
-       StringMap::iterator it = m_stringMap.find(smack);
+       auto it = m_smack2pkgId.find(smack);
 
-       if (it != m_stringMap.end()) {
-               result = it->second;
+       if (it != m_smack2pkgId.end()) {
+               creds.client = it->second;
                return 0;
        }
 
@@ -140,10 +154,36 @@ int Socket2Id::translate(int sock, std::string &result)
 
        mapToDomainClient(pkgId);
 
-       result = pkgId;
-       m_stringMap.emplace(std::move(smack), std::move(pkgId));
+       creds.client = pkgId;
+       m_smack2pkgId.emplace(std::move(smack), std::move(pkgId));
        return 0;
 }
 
+int Socket2IdDac::translate(int sock, CKM::Credentials &creds)
+{
+       ucred peerCred;
+       if (0 > Socket2Id::getPeerCred(sock, peerCred))
+               return -1;
+
+       int ret = security_manager_get_app_owner_uid(peerCred.pid, &creds.clientUid);
+       if (ret == SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT) {
+               if (AccessControl::isSystemService(peerCred.uid)) {
+                       LogInfo("System service client");
+                       creds.client = CLIENT_ID_SYSTEM;
+               } else {
+                       LogInfo("Unrecognized application");
+                       creds.client = CLIENT_ID_UNKNOWN;
+               }
+               creds.clientUid = peerCred.uid;
+               return 0;
+       } else if (ret != SECURITY_MANAGER_SUCCESS) {
+               LogError("security_manager_get_app_owner_uid failed");
+               return -1;
+       }
+
+       int retCode = getPkgIdFromSocket(sock, creds.client);
+       return retCode < 0 ? -1: 0;
+}
+
 } // namespace CKM
 
index 754683d9021ab5ae7280c95c131af07f08e9806a..3c3f73b8dbd752f6bac29ba3e237368beb049d7c 100644 (file)
  */
 #pragma once
 
+#include "credentials.h"
+
 #include <map>
 #include <string>
 
+#include <sys/socket.h>
+
 namespace CKM {
 
 class Socket2Id {
 public:
        Socket2Id() {}
 
-       int translate(int sock, std::string &result);
-       void resetCache();
+       virtual int translate(int sock, CKM::Credentials &creds) = 0;
 
-       virtual ~Socket2Id() {}
+       virtual ~Socket2Id() = default;
+
+protected:
+       int getPeerCred(int sock, ucred &peerCred);
+};
+
+class Socket2IdSmack : public Socket2Id {
+public:
+       int translate(int sock, CKM::Credentials &creds) override;
 
 private:
        int getCredentialsFromSocket(int sock, std::string &res);
        void mapToDomainClient(std::string &label);
 
-       typedef std::map<std::string, std::string> StringMap;
-       StringMap m_stringMap;
+       std::map<std::string, std::string> m_smack2pkgId;
+};
+
+class Socket2IdDac : public Socket2Id {
+public:
+       int translate(int sock, CKM::Credentials &creds) override;
 };
 
 } // namespace CKM
index 0d6d26b171d2fa7074f28fb34ab627cdbd429bf0..652e91d00f312c382e778eb9207e391e72bd1497 100644 (file)
@@ -39,6 +39,8 @@
 
 #include <systemd/sd-daemon.h>
 
+#include <security-manager.h>
+
 #include <dpl/errno_string.h>
 #include <dpl/log/log.h>
 
@@ -48,6 +50,9 @@
 
 #include <cynara.h>
 
+#include "access-control.h"
+
+
 namespace {
 
 #ifdef OVERRIDE_SOCKET_TIMEOUT
@@ -58,21 +63,15 @@ const std::chrono::seconds SOCKET_TIMEOUT(1000);
 
 int getCredentialsFromSocket(int sock, CKM::Credentials &cred)
 {
-       static CKM::Socket2Id sock2id;
+       static auto sock2id =
+                       CKM::smack_check() ?
+                                       std::unique_ptr<CKM::Socket2Id>(new CKM::Socket2IdSmack()) :
+                                       std::unique_ptr<CKM::Socket2Id>(new CKM::Socket2IdDac());
        CKM::ClientId client;
 
-       if (0 > sock2id.translate(sock, client))
+       if (0 > sock2id->translate(sock, cred))
                return -1;
 
-       ucred peerCred;
-       socklen_t length = sizeof(ucred);
-
-       if (0 > getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &peerCred, &length)) {
-               LogError("getsockopt failed");
-               return -1;
-       }
-
-       cred = CKM::Credentials(peerCred.uid, std::move(client));
        return 0;
 }
 
index 31058c7fcc13d24a8a41bf56524ba8c623af2aa6..eb5586a4a5a965b6e6ace6ca70411815ef348683 100644 (file)
@@ -47,12 +47,12 @@ bool AccessControl::isCCMode() const
        return m_ccMode;
 }
 
-bool AccessControl::isSystemService(const uid_t uid) const
+bool AccessControl::isSystemService(const uid_t uid)
 {
        return uid <= SYSTEM_SVC_MAX_UID;
 }
 
-bool AccessControl::isSystemService(const CKM::Credentials &cred) const
+bool AccessControl::isSystemService(const CKM::Credentials &cred)
 {
        return isSystemService(cred.clientUid);
 }
index 91d71f5c6fe2fb71ee7a674899115aa163260b55..b9113d10ea12d1f902d4dbe830b22fae219bf3e0 100644 (file)
@@ -36,8 +36,8 @@ public:
        /**
         * return true if client uid is from the system services uid space
         */
-       bool isSystemService(const uid_t uid) const;
-       bool isSystemService(const CKM::Credentials &cred) const;
+       static bool isSystemService(const uid_t uid);
+       static bool isSystemService(const CKM::Credentials &cred);
 
        /**
         * check if given data can be saved by current accessor