Add class for checking client credential 27/68227/1
authorKyungwook Tak <k.tak@samsung.com>
Tue, 3 May 2016 02:14:15 +0000 (11:14 +0900)
committerKyungwook Tak <k.tak@samsung.com>
Tue, 3 May 2016 05:38:41 +0000 (14:38 +0900)
Change-Id: Id9ec5ff5238b2e1c6f7dfab44610c4588ae665d2
Signed-off-by: Kyungwook Tak <k.tak@samsung.com>
13 files changed:
src/CMakeLists.txt
src/framework/CMakeLists.txt
src/framework/common/connection.cpp
src/framework/common/connection.h
src/framework/common/credential.cpp [new file with mode: 0644]
src/framework/common/credential.h [new file with mode: 0644]
src/framework/service/access-control.cpp [new file with mode: 0644]
src/framework/service/access-control.h [new file with mode: 0644]
src/framework/service/file-system.cpp
src/framework/service/file-system.h
src/framework/service/fs-utils.cpp [new file with mode: 0644]
src/framework/service/fs-utils.h [new file with mode: 0644]
test/internals/CMakeLists.txt

index 2a73faf..6d702db 100755 (executable)
@@ -33,6 +33,8 @@ SET(${TARGET_CSR_SERVER}_SRCS
        framework/service/server-service.cpp
        framework/service/thread-pool.cpp
        framework/service/core-usage.cpp
+       framework/service/fs-utils.cpp
+       framework/service/access-control.cpp
        framework/service/file-system.cpp
        framework/service/app-deleter.cpp
        framework/service/cs-loader.cpp
index 0b8f44b..7aa9891 100644 (file)
@@ -38,6 +38,7 @@ SET(${TARGET_CSR_COMMON}_SRCS
        common/mainloop.cpp
        common/service.cpp
        common/socket.cpp
+       common/credential.cpp
 )
 
 INCLUDE_DIRECTORIES(
index 02909a7..8ba9bea 100644 (file)
@@ -63,4 +63,14 @@ int Connection::getFd() const
        return m_socket.getFd();
 }
 
+const Credential &Connection::getCredential()
+{
+       if (m_cred)
+               return *m_cred;
+
+       m_cred = Credential::get(getFd());
+
+       return *m_cred;
+}
+
 }
index ef85038..effb806 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "common/socket.h"
 #include "common/types.h"
+#include "common/credential.h"
 
 namespace Csr {
 
@@ -43,11 +44,14 @@ public:
        void send(const RawBuffer &) const;
        RawBuffer receive(void) const;
        int getFd(void) const;
+       const Credential &getCredential();
 
 private:
        Socket m_socket;
        mutable std::mutex m_mSend;
        mutable std::mutex m_mRecv;
+
+       std::unique_ptr<Credential> m_cred;
 };
 
 using ConnShPtr = std::shared_ptr<Connection>;
diff --git a/src/framework/common/credential.cpp b/src/framework/common/credential.cpp
new file mode 100644 (file)
index 0000000..10d0512
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ *  Copyright (c) 2016 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        credential.cpp
+ * @author      Kyungwook Tak (k.tak@samsung.com)
+ * @version     1.0
+ * @brief
+ */
+#include "common/credential.h"
+
+#include <vector>
+#include <sys/socket.h>
+#include <sys/smack.h>
+
+#include "common/exception.h"
+
+namespace Csr {
+
+Credential::Credential(uid_t _uid, gid_t _gid, const std::string &_label) :
+       uid(_uid), gid(_gid), label(_label) {}
+
+std::unique_ptr<Credential> Credential::get(int sockfd)
+{
+       std::unique_ptr<Credential> c;
+
+       struct ucred cred;
+       socklen_t lenCred = sizeof(ucred);
+
+       if (getsockopt(sockfd, SOL_SOCKET, SO_PEERCRED, &cred, &lenCred) != 0)
+               ThrowExc(InternalError, "getsockopt peercred failed. errno: " << errno);
+
+       std::vector<char> label(SMACK_LABEL_LEN + 1, '0');
+       socklen_t lenLabel = SMACK_LABEL_LEN;
+
+       if (getsockopt(sockfd, SOL_SOCKET, SO_PEERSEC, label.data(), &lenLabel) != 0)
+               ThrowExc(InternalError, "getsockopt peersec failed. errno: " << errno);
+
+       return std::unique_ptr<Credential>(new Credential(cred.uid, cred.gid,
+                                                                          std::string(label.data(), lenLabel)));
+
+}
+
+}
diff --git a/src/framework/common/credential.h b/src/framework/common/credential.h
new file mode 100644 (file)
index 0000000..8b97634
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ *  Copyright (c) 2016 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        credential.h
+ * @author      Kyungwook Tak (k.tak@samsung.com)
+ * @version     1.0
+ * @brief
+ */
+#pragma once
+
+#include <memory>
+#include <string>
+#include <sys/types.h>
+
+namespace Csr {
+
+struct Credential {
+       uid_t uid;
+       gid_t gid;
+       std::string label;
+
+       static std::unique_ptr<Credential> get(int sockfd);
+
+private:
+       explicit Credential(uid_t, gid_t, const std::string &);
+};
+
+}
diff --git a/src/framework/service/access-control.cpp b/src/framework/service/access-control.cpp
new file mode 100644 (file)
index 0000000..f98902a
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ *  Copyright (c) 2016 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        access-control.cpp
+ * @author      Kyungwook Tak (k.tak@samsung.com)
+ * @version     1.0
+ * @brief
+ */
+#include "service/access-control.h"
+
+#include <memory>
+#include <cstring>
+#include <sys/smack.h>
+
+#include "common/audit/logger.h"
+#include "common/exception.h"
+#include "service/fs-utils.h"
+
+namespace Csr {
+
+namespace {
+
+bool hasPermToWriteDac(const Credential &cred, const std::string &filepath)
+{
+       auto statptr = getStat(filepath);
+       return (cred.uid == statptr->st_uid && (statptr->st_mode & S_IWUSR)) ||
+                  (cred.gid == statptr->st_gid && (statptr->st_mode & S_IWGRP)) ||
+                  (statptr->st_mode & S_IWOTH);
+}
+
+bool hasPermToWriteMac(const Credential &cred, const std::string &filepath)
+{
+       char *label = nullptr;
+       int ret = smack_getlabel(filepath.c_str(), &label, SMACK_LABEL_ACCESS);
+       if (ret != 0)
+               ThrowExc(InternalError, "get smack label failed from file: " << filepath <<
+                                " ret: " << ret);
+
+       std::unique_ptr<char, void(*)(void *)> labelptr(label, ::free);
+
+       ret = smack_have_access(cred.label.c_str(), label, "w");
+       if (ret == -1)
+               ThrowExc(InternalError, "smack_have_access err on file: " << filepath <<
+                                " errno: " << errno);
+
+       return ret == 1;
+}
+
+} // namespace anonymous
+
+bool hasPermToRemove(const Credential &cred, const std::string &filepath)
+{
+       auto parent = filepath.substr(0, filepath.find_last_of('/'));
+
+       return hasPermToWriteDac(cred, parent) && hasPermToWriteMac(cred, parent);
+
+}
+
+}
diff --git a/src/framework/service/access-control.h b/src/framework/service/access-control.h
new file mode 100644 (file)
index 0000000..4b938b7
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ *  Copyright (c) 2016 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        access-control.h
+ * @author      Kyungwook Tak (k.tak@samsung.com)
+ * @version     1.0
+ * @brief
+ */
+#pragma once
+
+#include <string>
+
+#include "common/credential.h"
+
+namespace Csr {
+
+// filepath should be absolute and not ended with '/'
+bool hasPermToRemove(const Credential &cred, const std::string &filepath);
+
+}
index ee14137..8d0fd8c 100644 (file)
 #include <cstdio>
 #include <cstring>
 #include <cerrno>
-#include <sys/stat.h>
 
-#include "service/app-deleter.h"
 #include "common/audit/logger.h"
 #include "common/exception.h"
+#include "service/app-deleter.h"
+#include "service/fs-utils.h"
 
 namespace Csr {
 
-namespace {
-
-std::unique_ptr<struct stat> getStat(const std::string &target)
-{
-       std::unique_ptr<struct stat> statptr(new struct stat);
-       memset(statptr.get(), 0x00, sizeof(struct stat));
-
-       if (stat(target.c_str(), statptr.get()) != 0) {
-               if (errno == ENOENT) {
-                       WARN("target not exist: " << target);
-               } else {
-                       ERROR("stat() failed on target: " << target << " errno: " << errno);
-               }
-
-               return nullptr;
-       }
-
-       return statptr;
-}
-
-} // namespace anonymous
-
 const char *APP_DIRS[4] = {
        // Tizen 2.4 app directories
        "^(/usr/apps/([^/]+))",                      // /usr/apps/{pkgid}/
@@ -69,9 +47,6 @@ const char *APP_DIRS[4] = {
        //"^(/sdcard/apps/([^/]+)/apps_rw/([^/]+))"    // /sdcard/apps/{user}/apps_rw/{pkgid}/
 };
 
-//===========================================================================
-// File
-//===========================================================================
 std::vector<std::regex> File::m_regexprs;
 
 File::File(const std::string &fpath) : m_path(fpath), m_inApp(false)
@@ -133,7 +108,7 @@ void File::initRegex()
        }
 }
 
-bool File::remove()
+bool File::remove() const
 {
        if (m_inApp)
                return AppDeleter::remove(m_appPkgId);
index bd28e18..0910a47 100644 (file)
@@ -43,7 +43,7 @@ public:
        const std::string &getAppUser() const;
        const std::string &getAppPkgPath() const;
 
-       bool remove();
+       bool remove() const;
 
        // throws FileNotExist and FileSystemError
        static FilePtr create(const std::string &fpath, time_t modifiedSince = -1);
diff --git a/src/framework/service/fs-utils.cpp b/src/framework/service/fs-utils.cpp
new file mode 100644 (file)
index 0000000..3e351bc
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ *  Copyright (c) 2016 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        fs-utils.cpp
+ * @author      Kyungwook Tak (k.tak@samsung.com)
+ * @version     1.0
+ * @brief
+ */
+#include "service/fs-utils.h"
+
+#include <cstring>
+#include <cerrno>
+
+#include "common/audit/logger.h"
+
+namespace Csr {
+
+std::unique_ptr<struct stat> getStat(const std::string &target)
+{
+       std::unique_ptr<struct stat> statptr(new struct stat);
+       memset(statptr.get(), 0x00, sizeof(struct stat));
+
+       if (stat(target.c_str(), statptr.get()) != 0) {
+               if (errno == ENOENT) {
+                       WARN("target not exist: " << target);
+               } else {
+                       ERROR("stat() failed on target: " << target << " errno: " << errno);
+               }
+
+               return nullptr;
+       }
+
+       return statptr;
+}
+
+}
diff --git a/src/framework/service/fs-utils.h b/src/framework/service/fs-utils.h
new file mode 100644 (file)
index 0000000..1707a99
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ *  Copyright (c) 2016 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        fs-utils.h
+ * @author      Kyungwook Tak (k.tak@samsung.com)
+ * @version     1.0
+ * @brief
+ */
+#pragma once
+
+#include <memory>
+#include <string>
+#include <sys/stat.h>
+
+namespace Csr {
+
+std::unique_ptr<struct stat> getStat(const std::string &target);
+
+}
index 6987496..397ab51 100644 (file)
@@ -40,6 +40,8 @@ SET(${TARGET_CSR_INTERNAL_TEST}_SRCS
        ${CSR_FW_SRC_PATH}/db/statement.cpp
        ${CSR_FW_SRC_PATH}/db/manager.cpp
        ${CSR_FW_SRC_PATH}/service/core-usage.cpp
+       ${CSR_FW_SRC_PATH}/service/fs-utils.cpp
+       ${CSR_FW_SRC_PATH}/service/access-control.cpp
        ${CSR_FW_SRC_PATH}/service/file-system.cpp
        ${CSR_FW_SRC_PATH}/service/app-deleter.cpp
        ${CSR_FW_SRC_PATH}/service/cs-loader.cpp