Replace smack label with pkgId. 87/46187/6
authorBartlomiej Grzelewski <b.grzelewski@samsung.com>
Mon, 17 Aug 2015 12:31:36 +0000 (14:31 +0200)
committerBartlomiej Grzelewski <b.grzelewski@samsung.com>
Tue, 25 Aug 2015 14:07:20 +0000 (16:07 +0200)
Change-Id: I2775a65349bf2103cf7de4702572b031244d9f28

packaging/key-manager.spec
src/CMakeLists.txt
src/include/ckmc/ckmc-type.h
src/manager/client-capi/ckmc-type.cpp
src/manager/common/protocols.cpp
src/manager/common/protocols.h
src/manager/initial-values/InitialValueHandler.cpp
src/manager/main/socket-2-id.cpp [new file with mode: 0644]
src/manager/main/socket-2-id.h [new file with mode: 0644]
src/manager/main/socket-manager.cpp
src/manager/service/ckm-logic.cpp

index a547123..7329cf3 100644 (file)
@@ -20,6 +20,7 @@ BuildRequires: pkgconfig(vconf)
 BuildRequires: pkgconfig(libsystemd-journal)
 BuildRequires: pkgconfig(libxml-2.0)
 BuildRequires: pkgconfig(capi-system-info)
+BuildRequires: pkgconfig(security-manager)
 BuildRequires: boost-devel
 Requires: libkey-manager-common = %{version}-%{release}
 %{?systemd_requires}
index 47061c9..2fa3e94 100644 (file)
@@ -9,6 +9,7 @@ PKG_CHECK_MODULES(KEY_MANAGER_DEP
     capi-system-info
     vconf
     libxml-2.0
+    security-manager
     )
 FIND_PACKAGE(Threads REQUIRED)
 
@@ -18,6 +19,7 @@ SET(KEY_MANAGER_PATH ${PROJECT_SOURCE_DIR}/src/manager)
 SET(KEY_MANAGER_SOURCES
     ${KEY_MANAGER_PATH}/main/generic-socket-manager.cpp
     ${KEY_MANAGER_PATH}/main/socket-manager.cpp
+    ${KEY_MANAGER_PATH}/main/socket-2-id.cpp
     ${KEY_MANAGER_PATH}/main/key-manager-main.cpp
     ${KEY_MANAGER_PATH}/main/smack-check.cpp
     ${KEY_MANAGER_PATH}/main/thread-service.cpp
index e0a6e60..4f2fce1 100644 (file)
@@ -38,6 +38,16 @@ extern "C" {
  * @{
  */
 
+/*
+ * Note: on tizen 3.0 owner id is equal to pkgId.
+ *       Preinstalled system(uid < 5000) and user (uid >= 5000) applications
+ *       does not have any pkgId. Thats why ckm uses special "virtual"
+ *       pkgid for them. The virtual strings are defined under:
+ *          ckmc_ownerid_system
+ *          ckmc_ownerid_user
+ *
+ */
+
 /**
  * @brief Separator between alias and label.
  * @since_tizen 2.3
@@ -49,6 +59,9 @@ extern "C" {
 KEY_MANAGER_CAPI extern char const * const ckmc_label_name_separator;
 
 /**
+ * This is deprecated: Tizen 3.0 does not use smack labels directly.
+ *                     You should use pkgId instead.
+ *
  * @brief Shared owner label
  * @since_tizen 3.0
  * @remarks Shared database label - user may be given permission to access shared
@@ -61,6 +74,24 @@ KEY_MANAGER_CAPI extern char const * const ckmc_label_name_separator;
 KEY_MANAGER_CAPI extern char const * const ckmc_label_shared_owner;
 
 /**
+ * alias can be provided as an alias alone, or together with owner id - in this
+ * case, separator " " (space bar) is used to separate id and alias.
+ * @see key-manager_doc.h
+ */
+KEY_MANAGER_CAPI extern char const * const ckmc_owner_id_separator;
+
+/**
+ * ckmc_owner_id_system constains id connected with all SYSTEM applications that runs
+ * with uid less then 5000.
+ *
+ * Client should use ckmc_owner_id_system to access data owned by system application
+ * and stored in system database.
+ *
+ * Note: Client must have permission to access proper row.
+ */
+KEY_MANAGER_CAPI extern char const * const ckmc_owner_id_system;
+
+/**
  * @brief Enumeration for key types of key manager.
  * @since_tizen 2.3
  */
index c7458ab..6f1ddd2 100644 (file)
@@ -67,7 +67,9 @@ int _ckmc_load_cert_from_x509(X509 *xCert, ckmc_cert_s **cert)
 
 
 const char * const ckmc_label_name_separator    = CKM::LABEL_NAME_SEPARATOR;
-const char * const ckmc_label_shared_owner      = CKM::LABEL_SYSTEM_DB;
+const char * const ckmc_label_shared_owner      = CKM::OWNER_ID_SYSTEM;
+const char * const ckmc_owner_id_separator      = CKM::LABEL_NAME_SEPARATOR;
+const char * const ckmc_owner_id_system         = CKM::OWNER_ID_SYSTEM;
 
 KEY_MANAGER_CAPI
 int ckmc_key_new(unsigned char *raw_key, size_t key_size, ckmc_key_type_e key_type, char *password, ckmc_key_s **ppkey)
index 91a3497..6f6c6c2 100644 (file)
@@ -35,8 +35,7 @@ char const * const SERVICE_SOCKET_CKM_STORAGE = "/tmp/.central-key-manager-api-s
 char const * const SERVICE_SOCKET_OCSP = "/tmp/.central-key-manager-api-ocsp.sock";
 char const * const SERVICE_SOCKET_ENCRYPTION = "/tmp/.central-key-manager-api-encryption.sock";
 char const * const LABEL_NAME_SEPARATOR = " ";
-char const * const LABEL_SYSTEM_DB = "/";
-
+char const * const OWNER_ID_SYSTEM = "/System";
 
 PKCS12Serializable::PKCS12Serializable() {}
 PKCS12Serializable::PKCS12Serializable(const PKCS12 &pkcs)
index 4f0fd2c..63a92bd 100644 (file)
@@ -75,7 +75,8 @@ enum class EncryptionCommand : int {
 
 // (client side) Alias = (service side) Label::Name
 COMMON_API extern char const * const LABEL_NAME_SEPARATOR;
-COMMON_API extern char const * const LABEL_SYSTEM_DB;
+COMMON_API extern char const * const OWNER_ID_SYSTEM;
+
 typedef std::string Name;
 typedef std::vector<std::pair<Label, Name> > LabelNameVector;
 
index b811aa7..43f9ef3 100644 (file)
@@ -70,9 +70,9 @@ void InitialValueHandler::End()
         // save data
         Policy policy(m_password, m_exportable);
         int ec = m_db_logic.verifyAndSaveDataHelper(
-                Credentials(CKMLogic::SYSTEM_DB_UID, LABEL_SYSTEM_DB),
+                Credentials(CKMLogic::SYSTEM_DB_UID, OWNER_ID_SYSTEM),
                 m_name,
-                LABEL_SYSTEM_DB,
+                OWNER_ID_SYSTEM,
                 m_bufferHandler->getData(),
                 getDataType(),
                 PolicySerializable(policy));
@@ -82,9 +82,9 @@ void InitialValueHandler::End()
             for(const auto & permission : m_permissions)
             {
                 ec = m_db_logic.setPermissionHelper(
-                        Credentials(CKMLogic::SYSTEM_DB_UID, LABEL_SYSTEM_DB),
+                        Credentials(CKMLogic::SYSTEM_DB_UID, OWNER_ID_SYSTEM),
                         m_name,
-                        LABEL_SYSTEM_DB,
+                        OWNER_ID_SYSTEM,
                         permission->getAccessor(),
                         Permission::READ);
                 if(CKM_API_SUCCESS != ec)
diff --git a/src/manager/main/socket-2-id.cpp b/src/manager/main/socket-2-id.cpp
new file mode 100644 (file)
index 0000000..b522b5f
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ *  Copyright (c) 2000 - 2015 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
+ */
+/*
+ * @file       socket-2-id.cpp
+ * @author     Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version    1.0
+ */
+#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 {
+namespace {
+
+int getCredentialsFromSocket(int sock, std::string &res)  {
+    std::vector<char> result(1);
+    socklen_t length = 1;
+
+    if ((0 > getsockopt(sock, SOL_SOCKET, SO_PEERSEC, result.data(), &length))
+      && errno != ERANGE)
+    {
+        LogError("getsockopt failed");
+        return -1;
+    }
+
+    result.resize(length);
+
+    if (0 > getsockopt(sock, SOL_SOCKET, SO_PEERSEC, result.data(), &length)) {
+        LogError("getsockopt failed");
+        return -1;
+    }
+
+    result.push_back('\0');
+    res = result.data();
+    return 0;
+}
+
+int getPkgIdFromSmack(const std::string &smack, std::string &pkgId) {
+    // TODO
+    // Conversion from smack label to pkgId should be done
+    // by security-manager. Current version of security-manager
+    // does not support this feature yet.
+
+    static const std::string SMACK_PREFIX_APPID  = "User::App::";
+
+    if (smack.empty()) {
+        LogError("Smack is empty. Connection will be rejected");
+        return -1;
+    }
+
+    if (smack.compare(0, SMACK_PREFIX_APPID.size(), SMACK_PREFIX_APPID)) {
+        pkgId = "/" + smack;
+        LogDebug("Smack: " << smack << " Was translated to owner id: " << pkgId);
+        return 0;
+    }
+
+    std::string appId = smack.substr(SMACK_PREFIX_APPID.size(), std::string::npos);
+
+    char *pkg = nullptr;
+
+    if (0 > security_manager_get_app_pkgid(&pkg, appId.c_str())) {
+        LogError("Error in security_manager_get_app_pkgid");
+        return -1;
+    }
+
+    if (!pkg) {
+        LogError("PkgId could not be NULL");
+        return -1;
+    }
+
+    pkgId = pkg;
+    free(pkg);
+    LogDebug("Smack: " << smack << " Was translated to owner id: " << pkgId);
+    return 0;
+}
+
+} // namespace anonymous
+
+
+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);
+
+    if (it != m_stringMap.end()) {
+        result = it->second;
+        return 0;
+    }
+
+    std::string pkgId;
+    if (0 > getPkgIdFromSmack(smack, pkgId)) {
+        return -1;
+    }
+
+    result = pkgId;
+    m_stringMap.emplace(std::move(smack), std::move(pkgId));
+    return 0;
+}
+
+void Socket2Id::resetCache() {
+    m_stringMap.clear();
+}
+
+} // namespace CKM
+
diff --git a/src/manager/main/socket-2-id.h b/src/manager/main/socket-2-id.h
new file mode 100644 (file)
index 0000000..1e83662
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ *  Copyright (c) 2000 - 2015 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
+ */
+/*
+ * @file       socket-2-id.h
+ * @author     Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version    1.0
+ */
+#pragma once
+
+#include <map>
+#include <string>
+
+namespace CKM {
+
+class Socket2Id {
+public:
+    Socket2Id() {}
+
+    int translate(int sock, std::string &result);
+    void resetCache();
+
+    virtual ~Socket2Id() {}
+private:
+    typedef std::map<std::string, std::string> StringMap;
+    StringMap m_stringMap;
+};
+
+} // namespace CKM
+
index f831d8e..9d6a632 100644 (file)
@@ -1,7 +1,5 @@
 /*
- *  Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
- *
- *  Contact: Bumjin Im <bj.im@samsung.com>
+ *  Copyright (c) 2000 - 2015 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.
 
 #include <smack-check.h>
 #include <socket-manager.h>
+#include <socket-2-id.h>
 
 namespace {
 
 const time_t SOCKET_TIMEOUT = 1000;
 
 int getCredentialsFromSocket(int sock, CKM::Credentials &cred) {
-    std::vector<char> result(1);
-    socklen_t length = 1;
-    ucred peerCred;
-
-    if ((0 > getsockopt(sock, SOL_SOCKET, SO_PEERSEC, result.data(), &length))
-        && errno != ERANGE)
-    {
-        LogError("getsockopt failed");
-        return -1;
-    }
-
-    result.resize(length);
+    static CKM::Socket2Id sock2id;
+    std::string ownerId;
 
-    if (0 > getsockopt(sock, SOL_SOCKET, SO_PEERSEC, result.data(), &length)) {
-        LogError("getsockopt failed");
+    if (0 > sock2id.translate(sock, ownerId)) {
         return -1;
     }
 
-    length = sizeof(ucred);
+    ucred peerCred;
+    socklen_t length = sizeof(ucred);
 
     if (0 > getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &peerCred, &length)) {
         LogError("getsockopt failed");
         return -1;
     }
 
-    result.push_back('\0');
-    cred = CKM::Credentials(peerCred.uid, result.data());
+    cred = CKM::Credentials(peerCred.uid, std::move(ownerId));
     return 0;
 }
 
index c5915e8..b0cea2c 100644 (file)
@@ -191,7 +191,7 @@ UserData & CKMLogic::selectDatabase(const Credentials &cred, const Label &incomi
         if (0 == m_userDataMap.count(cred.clientUid))
             ThrowErr(Exc::DatabaseLocked, "database with UID: ", cred.clientUid, " locked");
 
-        if (0 != incoming_label.compare(LABEL_SYSTEM_DB))
+        if (0 != incoming_label.compare(OWNER_ID_SYSTEM))
             return m_userDataMap[cred.clientUid];
     }
 
@@ -1047,7 +1047,7 @@ RawBuffer CKMLogic::getDataList(
         {
             // lookup system DB
             retCode = getDataListHelper(Credentials(SYSTEM_DB_UID,
-                                                    LABEL_SYSTEM_DB),
+                                                    OWNER_ID_SYSTEM),
                                         dataType,
                                         systemVector);
         }
@@ -1094,7 +1094,7 @@ int CKMLogic::saveDataHelper(
 
     // use client label if not explicitly provided
     const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
-    if( m_accessControl.isSystemService(cred) && ownerLabel.compare(LABEL_SYSTEM_DB)!=0)
+    if( m_accessControl.isSystemService(cred) && ownerLabel.compare(OWNER_ID_SYSTEM)!=0)
         return CKM_API_ERROR_INPUT_PARAM;
 
     // check if save is possible
@@ -1123,7 +1123,7 @@ int CKMLogic::saveDataHelper(
 
     // use client label if not explicitly provided
     const Label &ownerLabel = label.empty() ? cred.smackLabel : label;
-    if( m_accessControl.isSystemService(cred) && ownerLabel.compare(LABEL_SYSTEM_DB)!=0)
+    if( m_accessControl.isSystemService(cred) && ownerLabel.compare(OWNER_ID_SYSTEM)!=0)
         return CKM_API_ERROR_INPUT_PARAM;
 
     // check if save is possible
@@ -1579,7 +1579,7 @@ int CKMLogic::setPermissionHelper(
         return CKM_API_ERROR_INPUT_PARAM;
 
     // system database does not support write/remove permissions
-    if ((0 == ownerLabel.compare(LABEL_SYSTEM_DB)) &&
+    if ((0 == ownerLabel.compare(OWNER_ID_SYSTEM)) &&
         (permissionMask & Permission::REMOVE))
         return CKM_API_ERROR_INPUT_PARAM;