Move PAM module, volume manager from device-policy-manager git 79/80779/5
authorSungbae Yoo <sungbae.yoo@samsung.com>
Wed, 20 Jul 2016 07:05:01 +0000 (16:05 +0900)
committerSungbae Yoo <sungbae.yoo@samsung.com>
Wed, 3 Aug 2016 05:22:57 +0000 (14:22 +0900)
Change-Id: Ib93d3ffdf839eaf5b1bb644b3328809a2d1d9fb2
Signed-off-by: Sungbae Yoo <sungbae.yoo@samsung.com>
30 files changed:
CMakeLists.txt
data/DefaultManifest.xml [moved from module/data/DefaultZoneManifest.xml with 100% similarity]
data/indicator_icon.png [moved from module/data/zone_indicator_icon.png with 100% similarity]
data/notification_sub_icon.png [moved from module/data/zone_noti_list_sub_icon.png with 100% similarity]
module/CMakeLists.txt
module/krate-builder.cpp [new file with mode: 0644]
module/krate-builder.h [moved from module/zone-builder.h with 53% similarity]
module/krate-guard.h [moved from module/zone-guard.h with 50% similarity]
module/krate.cpp [new file with mode: 0644]
module/pam.d/systemd-user.in [moved from module/pam.d/systemd-user-zone with 68% similarity]
module/session.cpp
module/session.h
module/zone-builder.cpp [deleted file]
module/zone.cpp [deleted file]
packaging/krate.spec
server/CMakeLists.txt
tools/CMakeLists.txt
tools/cli/CMakeLists.txt
tools/cli/krate-admin-cli.cpp
tools/gumd-scripts/20_krate-add.post [moved from tools/gumd-scripts/20_pam-krate-add.post with 100% similarity]
tools/gumd-scripts/20_krate-remove.post [moved from tools/gumd-scripts/20_pam-krate-remove.post with 100% similarity]
volume/CMakeLists.txt [new file with mode: 0644]
volume/ecryptfs.h [new file with mode: 0755]
volume/kernel-keyring.cpp [new file with mode: 0755]
volume/kernel-keyring.h [new file with mode: 0755]
volume/key-generator.cpp [new file with mode: 0755]
volume/key-generator.h [new file with mode: 0755]
volume/key-manager.cpp [new file with mode: 0755]
volume/key-manager.h [new file with mode: 0644]
volume/main.cpp [new file with mode: 0755]

index df3adf8..f3f02d5 100755 (executable)
@@ -28,13 +28,13 @@ IF(NOT CMAKE_BUILD_TYPE)
        SET(CMAKE_BUILD_TYPE "DEBUG")
 ENDIF(NOT CMAKE_BUILD_TYPE)
 
-SET(KRATE_COMMON    ${PROJECT_SOURCE_DIR}/common)
 SET(KRATE_API       ${PROJECT_SOURCE_DIR}/api)
 SET(KRATE_LIB       ${PROJECT_SOURCE_DIR}/lib)
 SET(KRATE_SERVER    ${PROJECT_SOURCE_DIR}/server)
-SET(KRATE_VOLUME    ${PROJECT_SOURCE_DIR}/volume)
+SET(KRATE_DATA      ${PROJECT_SOURCE_DIR}/data)
 SET(KRATE_TOOLS     ${PROJECT_SOURCE_DIR}/tools)
 SET(KRATE_MODULE    ${PROJECT_SOURCE_DIR}/module)
+SET(KRATE_VOLUME    ${PROJECT_SOURCE_DIR}/volume)
 
 IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7)
        SET(CXX_STD "c++0x")
@@ -86,11 +86,10 @@ ENDIF(NOT DEFINED CONF_DIR)
 
 ADD_DEFINITIONS(-DUG_WAYLAND)
 
-#ADD_SUBDIRECTORY(${KRATE_COMMON})
-ADD_SUBDIRECTORY(${KRATE_SERVER})
-#ADD_SUBDIRECTORY(${KRATE_VOLUME})
 #ADD_SUBDIRECTORY(${KRATE_LIB})
-#ADD_SUBDIRECTORY(${KRATE_MODULE})
+ADD_SUBDIRECTORY(${KRATE_SERVER})
+ADD_SUBDIRECTORY(${KRATE_MODULE})
+ADD_SUBDIRECTORY(${KRATE_VOLUME})
 IF("${TIZEN_PROFILE_NAME}" STREQUAL "mobile")
 ADD_SUBDIRECTORY(${KRATE_TOOLS})
 ENDIF()
index d7ef612..be7a884 100644 (file)
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-
-PROJECT(zone-provider)
-
-FILE(GLOB ZONE_PAM_SRCS                 zone-builder.cpp
-                                                        session.cpp
-                                                        zone.cpp
+FILE(GLOB PAM_SRCS     krate.cpp
+                                       session.cpp
+                                       krate-builder.cpp
 )
 
 SET (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,noexecstack")
 
-SET(ZONE_PAM_NAME "pam_zone")
-ADD_LIBRARY(${ZONE_PAM_NAME} MODULE ${ZONE_PAM_SRCS})
-SET_TARGET_PROPERTIES(${ZONE_PAM_NAME} PROPERTIES  PREFIX ""
-    COMPILE_DEFINITIONS PID_FILE_PATH="${RUN_INSTALL_DIR}/zone"
-    COMPILE_FLAGS "-fvisibility=hidden"
+ADD_LIBRARY(pam_${PROJECT_NAME} MODULE ${PAM_SRCS})
+SET_TARGET_PROPERTIES(pam_${PROJECT_NAME} PROPERTIES  PREFIX ""
+       COMPILE_DEFINITIONS PID_FILE_PATH="${RUN_INSTALL_DIR}/krate"
+       COMPILE_FLAGS "-fvisibility=hidden"
 )
 
 FIND_PATH(PAM_INCLUDE_DIR NAMES security/pam_appl.h security/pam_ext.h security/pam_modules.h
-    HINTS ${PAM_ROOT_DIR} PATH_SUFFIXES include)
+       HINTS ${PAM_ROOT_DIR} PATH_SUFFIXES include)
 FIND_LIBRARY(PAM_LIBRARY pam  HINTS ${PAM_ROOT_DIR} PATH_SUFFIXES ${LIB_INSTALL_DIR})
 MARK_AS_ADVANCED(PAM_INCLUDE_DIR PAM_LIBRARY)
 
 INCLUDE(FindPackageHandleStandardArgs)
 FIND_PACKAGE_HANDLE_STANDARD_ARGS(PAM DEFAULT_MSG PAM_LIBRARY PAM_INCLUDE_DIR)
 
-INCLUDE_DIRECTORIES(${PAM_INCLUDE_DIR} ${DPM_COMMON})
-TARGET_LINK_LIBRARIES(${ZONE_PAM_NAME} ${PAM_LIBRARY} dpm-common pthread)
+PKG_CHECK_MODULES(PAM_DEPS     REQUIRED
+                                                       klay
+)
 
-TARGET_COMPILE_DEFINITIONS(${ZONE_PAM_NAME} PRIVATE
-    CONF_PATH="${CONF_INSTALL_DIR}"
+INCLUDE_DIRECTORIES(${PAM_INCLUDE_DIR} ${PAM_DEPS_INCLUDE_DIRS})
+TARGET_LINK_LIBRARIES(pam_${PROJECT_NAME} ${PAM_LIBRARY} ${PAM_DEPS_LIBRARIES} pthread)
+
+TARGET_COMPILE_DEFINITIONS(pam_${PROJECT_NAME} PRIVATE
+       CONF_PATH="${CONF_INSTALL_DIR}"
 )
 
-INSTALL(TARGETS ${ZONE_PAM_NAME} DESTINATION ${LIB_INSTALL_DIR}/security)
-INSTALL(FILES data/DefaultZoneManifest.xml DESTINATION ${CONF_INSTALL_DIR}/zone RENAME owner.xml)
-INSTALL(FILES data/zone_indicator_icon.png DESTINATION /opt/data/dpm)
-INSTALL(FILES data/zone_noti_list_sub_icon.png DESTINATION /opt/data/dpm)
-INSTALL(FILES pam.d/systemd-user-zone DESTINATION ${PAMD_INSTALL_DIR})
+CONFIGURE_FILE(pam.d/systemd-user.in pam.d/systemd-user-${PROJECT_NAME})
+
+INSTALL(TARGETS pam_${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR}/security)
+INSTALL(FILES pam.d/systemd-user-${PROJECT_NAME} DESTINATION ${PAMD_DIR})
diff --git a/module/krate-builder.cpp b/module/krate-builder.cpp
new file mode 100644 (file)
index 0000000..bbb8797
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ *  Copyright (c) 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
+ */
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/mount.h>
+
+#include "krate-builder.h"
+
+#include <klay/exception.h>
+#include <klay/filesystem.h>
+
+KrateBuilder::KrateBuilder(const runtime::User& user, const std::string& manifestPath) :
+       name(user.getName()), uid(user.getUid()), gid(user.getGid())
+{
+       manifest.reset(xml::Parser::parseFile(manifestPath));
+}
+
+KrateBuilder::~KrateBuilder()
+{
+}
+
+void KrateBuilder::bindFilesystemNode(const std::string& source, const std::string& target,
+                                                                        const std::string& type, const std::string& options,
+                                                                        bool create)
+{
+       if (create) {
+               runtime::File dir(target);
+               if (!dir.exists()) {
+                       dir.makeDirectory(true, uid, gid);
+               }
+       }
+
+       runtime::Mount::mountEntry(source, target, type, options);
+}
+
+void KrateBuilder::containerize(bool create)
+{
+       int nsFlags = CLONE_NEWIPC | CLONE_NEWNS;
+
+       if (::unshare(nsFlags)) {
+               throw runtime::Exception("Failed to unshare namespace");
+       }
+
+       if (::mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) == -1) {
+               throw runtime::Exception("Failed to mount root filesystem");
+       }
+
+       xml::Node::NodeList entries = manifest->evaluate("/manifest/filesystem/entry");
+       for (const xml::Node& entry : entries) {
+               bindFilesystemNode(entry.getProp("source"), entry.getProp("target"),
+                                                  entry.getProp("type"), entry.getProp("options"));
+       }
+
+       bindFilesystemNode("/home/" + name,
+                                          "/home/" + name + "/.krate/" + name,
+                                          "none", "rw,bind");
+
+       bindFilesystemNode("/home/" + name + "/.krate", "/home",
+                                          "none", "rw,rbind");
+}
similarity index 53%
rename from module/zone-builder.h
rename to module/krate-builder.h
index 52b02a4..094b747 100644 (file)
  *  See the License for the specific language governing permissions and
  *  limitations under the License
  */
-
- #ifndef __ZONE_BUILDER_H__
- #define __ZONE_BUILDER_H__
+#ifndef __KRATE_BUILDER_H__
+#define __KRATE_BUILDER_H__
 
 #include <string>
 #include <vector>
 #include <memory>
 
-#include "xml/parser.h"
-#include "xml/document.h"
-#include "auth/user.h"
+#include <klay/xml/parser.h>
+#include <klay/xml/document.h>
+#include <klay/auth/user.h>
 
-class ZoneBuilder {
+class KrateBuilder {
 public:
-    ZoneBuilder(const runtime::User& user, const std::string& manifestPath);
-    virtual ~ZoneBuilder();
+       KrateBuilder(const runtime::User& user, const std::string& manifestPath);
+       virtual ~KrateBuilder();
 
-    void containerize(bool create = true);
+       void containerize(bool create = true);
 
 protected:
-    void bindFilesystemNode(const std::string& source, const std::string& target,
-                            const std::string& type, const std::string& options,
-                            bool create = true);
+       void bindFilesystemNode(const std::string& source, const std::string& target,
+                                                       const std::string& type, const std::string& options,
+                                                       bool create = true);
 private:
-    std::string name;
-    uid_t uid;
-    gid_t gid;
-    std::unique_ptr<xml::Document> manifest;
+       std::string name;
+       uid_t uid;
+       gid_t gid;
+       std::unique_ptr<xml::Document> manifest;
 };
 
- #endif //!__ZONE_BUILDER_H__
+#endif //!__KRATE_BUILDER_H__
similarity index 50%
rename from module/zone-guard.h
rename to module/krate-guard.h
index ded6ba2..8e09748 100644 (file)
  *
  */
 
-#ifndef __ZONE_GUARD_H__
-#define __ZONE_GUARD_H__
+#ifndef __KRATE_GUARD_H__
+#define __KRATE_GUARD_H__
 
-#include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <semaphore.h>
+#include <sys/stat.h>
 
 #include <string>
 
-#include "exception.h"
+#include <klay/exception.h>
 
-class ZoneGuard {
+class KrateGuard {
 public:
-    ZoneGuard(const std::string& name) :
-        zoneName(name),
-        semaphore(nullptr)
-    {
-        semaphore = ::sem_open(zoneName.c_str(), O_CREAT, 0700, 1);
-        if (semaphore == nullptr) {
-            throw runtime::Exception("Filed to create semaphore for zone guard");
-        }
-    }
-
-    ~ZoneGuard()
-    {
-        if (semaphore == nullptr) {
-            return;
-        }
-
-        ::sem_post(semaphore);
-        ::sem_close(semaphore);
-        ::sem_unlink(zoneName.c_str());
-    }
-
-    void wait()
-    {
-        while ((::sem_wait(semaphore) == -1) && (errno == EINTR));
-    }
+       KrateGuard(const std::string& name) :
+               krateName(name), semaphore(nullptr)
+       {
+               semaphore = ::sem_open(krateName.c_str(), O_CREAT, 0700, 1);
+               if (semaphore == nullptr) {
+                       throw runtime::Exception("Filed to create semaphore for krate guard");
+               }
+       }
+
+       ~KrateGuard()
+       {
+               if (semaphore == nullptr) {
+                       return;
+               }
+
+               ::sem_post(semaphore);
+               ::sem_close(semaphore);
+               ::sem_unlink(krateName.c_str());
+       }
+
+       void wait()
+       {
+               while ((::sem_wait(semaphore) == -1) && (errno == EINTR));
+       }
 
 private:
-    std::string zoneName;
-    sem_t* semaphore;
+       std::string krateName;
+       sem_t* semaphore;
 };
 
-#endif //!__ZONE_GUARD_H__
+#endif //!__KRATE_GUARD_H__
diff --git a/module/krate.cpp b/module/krate.cpp
new file mode 100644 (file)
index 0000000..06fea56
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ *  Copyright (c) 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
+ */
+
+#include <syslog.h>
+#include <security/pam_ext.h>
+#include <security/pam_modules.h>
+
+#include <string>
+#include <vector>
+
+#include "session.h"
+#include "krate-guard.h"
+#include "krate-builder.h"
+
+#include <klay/exception.h>
+#include <klay/filesystem.h>
+#include <klay/xml/parser.h>
+#include <klay/xml/document.h>
+
+#define KRATE_MANIFEST_DIR CONF_PATH "/krate/"
+
+std::string buildKrateManifestPath(const std::string& name)
+{
+       return KRATE_MANIFEST_DIR + name + ".xml";
+}
+
+std::string getKrateName(pam_handle_t* handle)
+{
+       const void* retItem;
+       int error = ::pam_get_item(handle, PAM_USER, &retItem);
+       if (error != PAM_SUCCESS) {
+               throw runtime::Exception("Failed to get user");
+       }
+
+       return static_cast<const char*>(retItem);
+}
+
+void openKrateSession(const std::string& name)
+{
+       auto sessionBuilder = [](const runtime::User& user) {
+               KrateBuilder builder(user, buildKrateManifestPath(user.getName()));
+               builder.containerize();
+       };
+
+       createSession(runtime::User(name), sessionBuilder);
+}
+
+void closeKrateSession(const std::string& name)
+{
+       destroySession(runtime::User(name));
+}
+
+extern "C" {
+PAM_EXTERN  __attribute__((visibility("default")))
+int pam_sm_open_session(pam_handle_t* pamh, int flags, int argc, const char* argv[])
+{
+       try {
+               std::string name = getKrateName(pamh);
+               KrateGuard krateGuard(name);
+               krateGuard.wait();
+
+               openKrateSession(name);
+       } catch (runtime::Exception& e) {
+               ::pam_syslog(pamh, LOG_ERR, "%s", e.what());
+               return PAM_SESSION_ERR;
+       }
+
+       return PAM_SUCCESS;
+}
+
+PAM_EXTERN  __attribute__((visibility("default")))
+int pam_sm_close_session(pam_handle_t* pamh, int flags, int argc, const char* argv[])
+{
+       try {
+               std::string name = getKrateName(pamh);
+               KrateGuard krateGuard(name);
+               krateGuard.wait();
+
+               closeKrateSession(name);
+       } catch (runtime::Exception& e) {
+               ::pam_syslog(pamh, LOG_ERR, "%s", e.what());
+               return PAM_SESSION_ERR;
+       }
+
+       return PAM_SUCCESS;
+}
+
+#ifdef PAM_MODULE_ENTRY
+PAM_MODULE_ENTRY("pam_krate");
+#endif
+
+}
similarity index 68%
rename from module/pam.d/systemd-user-zone
rename to module/pam.d/systemd-user.in
index 2245de4..1d5e242 100644 (file)
@@ -1,4 +1,4 @@
 account  include system-auth
 session  include system-auth
 session  optional pam_systemd.so
-session  required pam_zone.so
+session  required pam_${PROJECT_NAME}.so
index 24b71ae..4fcd9df 100644 (file)
  *  See the License for the specific language governing permissions and
  *  limitations under the License
  */
-
-#include <stdio.h>
+#include <errno.h>
 #include <unistd.h>
-#include <sys/stat.h>
-#include <sys/file.h>
 #include <string.h>
-#include <errno.h>
 #include <signal.h>
+#include <sys/stat.h>
+#include <sys/file.h>
 
 #include "session.h"
-#include "exception.h"
-#include "filesystem.h"
+
+#include <klay/exception.h>
+#include <klay/filesystem.h>
 
 bool isValidSessionLeader(pid_t pid)
 {
-    runtime::File proc("/proc/" + std::to_string(pid));
-    return proc.exists();
+       runtime::File proc("/proc/" + std::to_string(pid));
+       return proc.exists();
 }
 
 void createSession(const runtime::User& user, const SessionBuilder& sessionBuilder)
 {
-    runtime::File file("/var/run/zone/" + user.getName());
-    if (file.exists()) {
-        if (isValidSessionLeader(getSessionLeader(user))) {
-            throw runtime::Exception("Session already opened");
-        }
-        file.remove();
-    } else {
-        file.makeBaseDirectory();
-    }
+       runtime::File file("/var/run/krate/" + user.getName());
+       if (file.exists()) {
+               if (isValidSessionLeader(getSessionLeader(user))) {
+                       throw runtime::Exception("Session already opened");
+               }
+               file.remove();
+       } else {
+               file.makeBaseDirectory();
+       }
 
-    sessionBuilder(user);
+       sessionBuilder(user);
 
-    file.create(0600);
-    file.lock();
-    file.chown(user.getUid(), user.getGid());
-    pid_t pid = ::getpid();
-    file.write(&pid, sizeof(pid_t));
-    file.unlock();
+       file.create(0600);
+       file.lock();
+       file.chown(user.getUid(), user.getGid());
+       pid_t pid = ::getpid();
+       file.write(&pid, sizeof(pid_t));
+       file.unlock();
 }
 
 pid_t getSessionLeader(const runtime::User& user)
 {
-    runtime::File file("/var/run/zone/" + user.getName(), O_RDONLY);
-    file.lock();
-    pid_t pid = -1;
-    file.read(&pid, sizeof(pid_t));
-    file.unlock();
+       runtime::File file("/var/run/krate/" + user.getName(), O_RDONLY);
+       file.lock();
+       pid_t pid = -1;
+       file.read(&pid, sizeof(pid_t));
+       file.unlock();
 
-    return pid;
+       return pid;
 }
 
 void destroySession(const runtime::User& user)
 {
-    std::string path = "/var/run/zone/" + user.getName();
-    ::unlink(path.c_str());
+       std::string path = "/var/run/krate/" + user.getName();
+       ::unlink(path.c_str());
 }
index df01173..ebb053e 100644 (file)
  *  limitations under the License
  */
 
-#ifndef __ZONE_SESSION_ENV_H__
-#define __ZONE_SESSION_ENV_H__
+#ifndef __KRATE_SESSION_ENV_H__
+#define __KRATE_SESSION_ENV_H__
 
-#include <sys/types.h>
 #include <unistd.h>
+#include <sys/types.h>
 
 #include <string>
 #include <functional>
 
-#include "auth/user.h"
+#include <klay/auth/user.h>
 
 typedef std::function<void(const runtime::User& user)> SessionBuilder;
 
@@ -32,4 +32,4 @@ void createSession(const runtime::User& user, const SessionBuilder& sessionBuild
 pid_t getSessionLeader(const runtime::User& user);
 void destroySession(const runtime::User& user);
 
-#endif //!__ZONE_SESSION_ENV_H__
+#endif //!__KRATE_SESSION_ENV_H__
diff --git a/module/zone-builder.cpp b/module/zone-builder.cpp
deleted file mode 100644 (file)
index c36e9da..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- *  Copyright (c) 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
- */
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/mount.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <stdio.h>
-
-#include "zone-builder.h"
-
-#include "exception.h"
-#include "filesystem.h"
-
-ZoneBuilder::ZoneBuilder(const runtime::User& user, const std::string& manifestPath) :
-    name(user.getName()), uid(user.getUid()), gid(user.getGid())
-{
-    manifest.reset(xml::Parser::parseFile(manifestPath));
-}
-
-ZoneBuilder::~ZoneBuilder()
-{
-}
-
-void ZoneBuilder::bindFilesystemNode(const std::string& source, const std::string& target,
-                                     const std::string& type, const std::string& options,
-                                     bool create)
-{
-    if (create) {
-        runtime::File dir(target);
-        if (!dir.exists()) {
-            dir.makeDirectory(true, uid, gid);
-        }
-    }
-
-    runtime::Mount::mountEntry(source, target, type, options);
-}
-
-void ZoneBuilder::containerize(bool create)
-{
-    int nsFlags = CLONE_NEWIPC | CLONE_NEWNS;
-
-    if (::unshare(nsFlags)) {
-        throw runtime::Exception("Failed to unshare namespace");
-    }
-
-    if (::mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) == -1) {
-        throw runtime::Exception("Failed to mount root filesystem");
-    }
-
-    xml::Node::NodeList entries = manifest->evaluate("/manifest/filesystem/entry");
-    for (const xml::Node& entry : entries) {
-        bindFilesystemNode(entry.getProp("source"), entry.getProp("target"),
-                           entry.getProp("type"), entry.getProp("options"));
-    }
-
-    bindFilesystemNode("/home/" + name,
-                       "/home/" + name + "/.zone/" + name,
-                       "none", "rw,bind");
-
-    bindFilesystemNode("/home/" + name + "/.zone", "/home",
-                       "none", "rw,rbind");
-}
diff --git a/module/zone.cpp b/module/zone.cpp
deleted file mode 100644 (file)
index 99b9699..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- *  Copyright (c) 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
- */
-
-#include <security/pam_ext.h>
-#include <security/pam_modules.h>
-#include <syslog.h>
-
-#include <string>
-#include <vector>
-
-#include "zone-guard.h"
-#include "zone-builder.h"
-#include "session.h"
-
-#include "exception.h"
-#include "filesystem.h"
-#include "xml/parser.h"
-#include "xml/document.h"
-
-#define ZONE_MANIFEST_DIR CONF_PATH "/zone/"
-
-std::string buildZoneManifestPath(const std::string& name)
-{
-    return ZONE_MANIFEST_DIR + name + ".xml";
-}
-
-std::string getZoneName(pam_handle_t* handle)
-{
-    const void* retItem;
-    int error = ::pam_get_item(handle, PAM_USER, &retItem);
-    if (error != PAM_SUCCESS) {
-        throw runtime::Exception("Failed to get user");
-    }
-
-    return static_cast<const char*>(retItem);
-}
-
-void openZoneSession(const std::string& name)
-{
-    auto sessionBuilder = [](const runtime::User& user) {
-        ZoneBuilder builder(user, buildZoneManifestPath(user.getName()));
-        builder.containerize();
-    };
-
-    createSession(runtime::User(name), sessionBuilder);
-}
-
-void closeZoneSession(const std::string& name)
-{
-    destroySession(runtime::User(name));
-}
-
-extern "C" {
-PAM_EXTERN  __attribute__((visibility("default")))
-int pam_sm_open_session(pam_handle_t* pamh, int flags, int argc, const char* argv[])
-{
-    try {
-        std::string name = getZoneName(pamh);
-        ZoneGuard zoneGuard(name);
-        zoneGuard.wait();
-
-        openZoneSession(name);
-    } catch (runtime::Exception& e) {
-        ::pam_syslog(pamh, LOG_ERR, "%s", e.what());
-        return PAM_SESSION_ERR;
-    }
-
-    return PAM_SUCCESS;
-}
-
-PAM_EXTERN  __attribute__((visibility("default")))
-int pam_sm_close_session(pam_handle_t* pamh, int flags, int argc, const char* argv[])
-{
-    try {
-        std::string name = getZoneName(pamh);
-        ZoneGuard zoneGuard(name);
-        zoneGuard.wait();
-
-        closeZoneSession(name);
-    } catch (runtime::Exception& e) {
-        ::pam_syslog(pamh, LOG_ERR, "%s", e.what());
-        return PAM_SESSION_ERR;
-    }
-
-    return PAM_SUCCESS;
-}
-
-#ifdef PAM_MODULE_ENTRY
-PAM_MODULE_ENTRY("pam_zone");
-#endif
-
-}
index 36f2523..a6e952e 100644 (file)
@@ -7,8 +7,8 @@ Summary: Tizen Krate Manager
 Group:   Security/Other
 BuildRequires: gcc
 BuildRequires: cmake
-BuildRequires: pam-devel
 BuildRequires: gettext-tools
+BuildRequires: pkgconfig(klay)
 BuildRequires: pkgconfig(glib-2.0)
 BuildRequires: pkgconfig(libxml-2.0)
 BuildRequires: pkgconfig(bundle)
@@ -32,10 +32,16 @@ krates.
 %files
 %manifest krate.manifest
 %defattr(644,root,root,755)
-#%attr(700,root,root) %{_sbindir}/zone-volume-manager
 #%attr(755,root,root) %{_bindir}/krate
+%attr(700,root,root) %{_sbindir}/krate-volume-manager
 %{_unitdir}/krate.service
 #%{_unitdir}/multi-user.target.wants/krate.service
+%attr(700,root,root) /etc/gumd/useradd.d/20_krate-add.post
+%attr(700,root,root) /etc/gumd/userdel.d/20_krate-remove.post
+%attr(644,root,root) %{TZ_SYS_RO_ICONS}/krate/indicator_icon.png
+%attr(644,root,root) %{TZ_SYS_RO_ICONS}/krate/notification_sub_icon.png
+%attr(700,root,root) %dir %{TZ_SYS_ETC}/krate
+%attr(600,root,root) %config %{TZ_SYS_ETC}/krate/owner.xml
 
 %prep
 %setup -q
@@ -119,11 +125,14 @@ developing the krate client program.
 %{_includedir}/krate
 %{_libdir}/pkgconfig/krate.pc
 
+%endif
+
 ## PAM Plugin Package ########################################################
 %package -n dpm-pam-krate
 Summary: PAM Plugin for zone policy in device policy manager
 Group: Development/Libraries
 Requires: systemd
+BuildRequires: pam-devel
 
 %description -n dpm-pam-krate
 PAM Plugin for zone policy in device policy manager and CLI tool
@@ -139,17 +148,9 @@ mv /etc/pam.d/systemd-user.keep /etc/pam.d/systemd-user
 %manifest krate.manifest
 %defattr(600,root,root,700)
 %attr(700,root,root) %{_libdir}/security/pam_*.so
-%attr(700,root,root) %{_sbindir}/krate-admin-cli
-%attr(700,root,root) %dir %{TZ_SYS_ETC}/krate
-%attr(600,root,root) %config %{TZ_SYS_ETC}/krate/owner.xml
-%attr(700,root,root) /etc/gumd/useradd.d/20_pam-krate-add.post
-%attr(700,root,root) /etc/gumd/userdel.d/20_pam-krate-remove.post
-%attr(644,root,root) %{TZ_SYS_RO_ICONS}/krate/indicator_icon.png
-%attr(644,root,root) %{TZ_SYS_RO_ICONS}/krate/noti_list_sub_icon.png
+#%attr(700,root,root) %{_sbindir}/zone-admin-cli
 %config /etc/pam.d/*
 
-%endif
-
 ## Begin of mobile feature ###################################################
 %if "%{profile}" == "mobile"
 
index 7b5f240..48b71a3 100644 (file)
@@ -19,3 +19,10 @@ SET(TARGET ${PROJECT_NAME})
 CONFIGURE_FILE(systemd/krate.service.in systemd/krate.service)
 
 INSTALL(FILES systemd/krate.service DESTINATION ${SYSTEMD_UNIT_DIR})
+
+INSTALL(FILES ${KRATE_TOOLS}/gumd-scripts/20_krate-add.post DESTINATION /etc/gumd/useradd.d)
+INSTALL(FILES ${KRATE_TOOLS}/gumd-scripts/20_krate-remove.post DESTINATION /etc/gumd/userdel.d)
+
+INSTALL(FILES ${KRATE_DATA}/DefaultManifest.xml DESTINATION ${CONF_DIR} RENAME owner.xml)
+INSTALL(FILES ${KRATE_DATA}/indicator_icon.png DESTINATION ${APP_ICON_DIR_PREFIX}/krate)
+INSTALL(FILES ${KRATE_DATA}/notification_sub_icon.png DESTINATION ${APP_ICON_DIR_PREFIX}/krate)
index baa8c10..2ce3d84 100755 (executable)
@@ -15,5 +15,7 @@
 #
 
 SET(KRATE_APPS  ${KRATE_TOOLS}/apps)
+#SET(KRATE_CLI  ${KRATE_TOOLS}/cli)
 
 ADD_SUBDIRECTORY(${KRATE_APPS})
+#ADD_SUBDIRECTORY(${KRATE_CLI})
index d458cee..67a843a 100644 (file)
 # limitations under the License.
 #
 
-PROJECT(krate-admin-cli)
-
-FILE(GLOB KRATE_ADMIN_CLI_SRCS  krate-admin-cli.cpp
-                                ${KRATE_MODULE}/session.cpp
-                                ${KRATE_MODULE}/zone-builder.cpp
+FILE(GLOB CLI_SRCS     krate-admin-cli.cpp
+                                       ${KRATE_MODULE}/session.cpp
+                                       ${KRATE_MODULE}/krate-builder.cpp
 )
 
-SET(KRATE_ADMIN_CLI_NAME "zone-admin-cli")
+SET(CLI_NAME "zone-admin-cli")
 
-ADD_EXECUTABLE(${ZONE_CLI_NAME} ${ZONE_CLI_SRCS})
-SET_TARGET_PROPERTIES(${ZONE_CLI_NAME} PROPERTIES PREFIX ""
-    COMPILE_DEFINITIONS PID_FILE_PATH="${RUN_INSTALL_DIR}/zone"
-    COMPILE_FLAGS "-fPIE"
-    LINK_FLAGS "-pie"
+ADD_EXECUTABLE(${CLI_NAME} ${CLI_SRCS})
+SET_TARGET_PROPERTIES(${CLI_NAME} PROPERTIES PREFIX ""
+       COMPILE_DEFINITIONS PID_FILE_PATH="${RUN_DIR}/krate"
+       COMPILE_FLAGS "-fPIE"
+       LINK_FLAGS "-pie"
 )
 
-PKG_CHECK_MODULES(ZONE_CLI_DEPS  REQUIRED
-                                 glib-2.0
-                                 capi-appfw-package-manager
-                                 capi-appfw-app-manager
+PKG_CHECK_MODULES(CLI_DEPS     REQUIRED
+                                                       klay
+                                                       glib-2.0
+                                                       libxml-2.0
+                                                       capi-appfw-package-manager
+                                                       capi-appfw-app-manager
+                                                       zone
 )
 
-INCLUDE_DIRECTORIES(SYSTEM ${ZONE_CLI_DEPS_INCLUDE_DIRS} ${DPM_COMMON} ${ZONE_MODULE} ${ZONE_LIBS})
-TARGET_LINK_LIBRARIES(${ZONE_CLI_NAME} ${ZONE_CLI_DEPS_LIBRARIES} dpm-common zone)
+INCLUDE_DIRECTORIES(SYSTEM ${CLI_DEPS_INCLUDE_DIRS} ${KRATE_MODULE})
+TARGET_LINK_LIBRARIES(${CLI_NAME} ${CLI_DEPS_LIBRARIES})
 
-INSTALL(TARGETS ${ZONE_CLI_NAME} DESTINATION sbin)
+INSTALL(TARGETS ${CLI_NAME} DESTINATION sbin)
index 9fe5157..e46e45b 100644 (file)
  * @author  Sungbae Yoo (sungbae.yoo@samsung.com)
  * @brief   CLI tool to attach to existing namespace by pam-attach.so
  */
+
 #define _XOPEN_SOURCE
+#include <grp.h>
 #include <glib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <getopt.h>
 #include <sys/wait.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/param.h>
 
-#include <grp.h>
-#include <string.h>
-#include <unistd.h>
-#include <getopt.h>
-#include <fcntl.h>
-
+#include <cstring>
 #include <string>
 #include <vector>
-#include <iostream>
 #include <utility>
+#include <iostream>
+
+#include <klay/exception.h>
+#include <klay/filesystem.h>
+#include <klay/auth/user.h>
 
-#include <zone/package-proxy.h>
 #include <zone/app-proxy.h>
+#include <zone/package-proxy.h>
 
 #include "session.h"
 
-#include "error.h"
-#include "exception.h"
-#include "filesystem.h"
-#include "auth/user.h"
-
 
 #define DEFAULT_SHELL "/bin/bash"
 
 typedef std::pair<std::string, int> NamespacePair;
 
 std::vector<NamespacePair> namespaces = {
-    {"mnt",  CLONE_NEWNS},
-    {"net",  CLONE_NEWNET},
-    {"uts",  CLONE_NEWUTS},
-    {"user", CLONE_NEWUSER},
-    {"ipc",  CLONE_NEWIPC},
-    {"pid",  CLONE_NEWPID}
+       {"mnt",  CLONE_NEWNS},
+       {"net",  CLONE_NEWNET},
+       {"uts",  CLONE_NEWUTS},
+       {"user", CLONE_NEWUSER},
+       {"ipc",  CLONE_NEWIPC},
+       {"pid",  CLONE_NEWPID}
 };
 
 extern char** environ;
 
 static inline void usage(const std::string name)
 {
-    std::cout << "Usage: " << name << " [Option] -- COMMAND" << std::endl
-              << "Run a program in the zone" << std::endl
-              << std::endl
-              << "Options :" << std::endl
-              << "   -a, --attach=zone  execute command in the zone" << std::endl
-              << "   -p, --pkginfo=zone show all packages in the zone" << std::endl
-              << "   -q, --appinfo=zone show all applications in the zone" << std::endl
-              << "   -m, --zone-monitor monitor all zone events" << std::endl
-              << "   -n, --pkg-monitor  monitor all package events in the zone" << std::endl
-              << "   -l, --list         show all zone instances" << std::endl
-              << "   -h, --help         show this" << std::endl
-              << std::endl;
+       std::cout << "Usage: " << name << " [Option] -- COMMAND" << std::endl
+                         << "Run a program in the krate" << std::endl
+                         << std::endl
+                         << "Options :" << std::endl
+                         << "   -a, --attach=krate  execute command in the krate" << std::endl
+                         << "   -p, --pkginfo=krate show all packages in the krate" << std::endl
+                         << "   -q, --appinfo=krate show all applications in the krate" << std::endl
+                         << "   -m, --krate-monitor monitor all krate events" << std::endl
+                         << "   -n, --pkg-monitor  monitor all package events in the krate" << std::endl
+                         << "   -l, --list         show all krate instances" << std::endl
+                         << "   -h, --help         show this" << std::endl
+                         << std::endl;
 }
 
-int showZoneInstances()
+int showKrateInstances()
 {
-    try {
-        runtime::DirectoryIterator iter(runtime::Path("/var/run/zone")), end;
-
-        while (iter != end) {
-            const std::string& path = (*iter).getPath();
-            size_t name = path.rfind('/') + 1;
-            std::cout << path.substr(name) << std::endl;
-            ++iter;
-        }
-    } catch (runtime::Exception& e) {
-        std::cerr << e.what() << std::endl;
-        return -1;
-    }
-
-    return 0;
+       try {
+               runtime::DirectoryIterator iter("/var/run/krate"), end;
+
+               while (iter != end) {
+                       const std::string& path = (*iter).getPath();
+                       size_t name = path.rfind('/') + 1;
+                       std::cout << path.substr(name) << std::endl;
+                       ++iter;
+               }
+       } catch (runtime::Exception& e) {
+               std::cerr << e.what() << std::endl;
+               return -1;
+       }
+
+       return 0;
 }
 
 void attachNamespaces(pid_t pid)
 {
-    int fd;
-    for (const NamespacePair& ns : namespaces) {
-        std::string nspath = "/proc/" + std::to_string(pid) + "/ns/" + ns.first;
-
-        do {
-            fd = ::open(nspath.c_str(), O_RDONLY);
-        } while (fd == -1 && errno == EINTR);
-
-        if (fd == -1) {
-            if (errno != ENOENT) {
-                throw runtime::Exception("Failed to open namesapce: " + nspath);
-            }
-        } else {
-            if (::setns(fd, ns.second)) {
-                ::close(fd);
-                throw runtime::Exception("Failed to attach namespace: " + nspath);
-            }
-            ::close(fd);
-        }
-    }
+       int fd;
+       for (const NamespacePair& ns : namespaces) {
+               std::string nspath = "/proc/" + std::to_string(pid) + "/ns/" + ns.first;
+
+               do {
+                       fd = ::open(nspath.c_str(), O_RDONLY);
+               } while (fd == -1 && errno == EINTR);
+
+               if (fd == -1) {
+                       if (errno != ENOENT) {
+                               throw runtime::Exception("Failed to open namesapce: " + nspath);
+                       }
+               } else {
+                       if (::setns(fd, ns.second)) {
+                               ::close(fd);
+                               throw runtime::Exception("Failed to attach namespace: " + nspath);
+                       }
+                       ::close(fd);
+               }
+       }
 }
 
 void launchProcess(runtime::User& user, char** args)
 {
-    int status;
-
-    pid_t pid = ::fork();
-    if (pid == -1) {
-        throw runtime::Exception("Failed to create child process");
-    }
-
-    if (pid != 0) {
-        ::waitpid(pid, &status, 0);
-        if (WEXITSTATUS(status) != EXIT_SUCCESS) {
-            throw runtime::Exception("Child process terminated abnormally");
-        }
-        return;
-    }
-
-    if (::initgroups(user.getName().c_str(), user.getGid()) == -1) {
-        std::cerr << "Failed to initgroups()" << std::endl;
-        ::exit(EXIT_FAILURE);
-    }
-
-    if (::setgid(user.getGid()) == -1) {
-        std::cerr << "Failed to setgid()" << std::endl;
-        ::exit(EXIT_FAILURE);
-    }
-
-    if (::setuid(user.getUid()) == -1) {
-        std::cerr << "Failed to setuid()" << std::endl;
-        ::exit(EXIT_FAILURE);
-    }
-
-    char *default_args[2];
-    default_args[0] = ::strdup(DEFAULT_SHELL);
-    default_args[1] = NULL;
-
-    if (args == NULL) {
-        args = default_args;
-    }
-
-    ::execve(*args, args, environ);
-    std::cerr << "Failed to execute " << args[0] << std::endl;
-
-    ::free(default_args[0]);
-
-    ::exit(EXIT_FAILURE);
+       int status;
+
+       pid_t pid = ::fork();
+       if (pid == -1) {
+               throw runtime::Exception("Failed to create child process");
+       }
+
+       if (pid != 0) {
+               ::waitpid(pid, &status, 0);
+               if (WEXITSTATUS(status) != EXIT_SUCCESS) {
+                       throw runtime::Exception("Child process terminated abnormally");
+               }
+               return;
+       }
+
+       if (::initgroups(user.getName().c_str(), user.getGid()) == -1) {
+               std::cerr << "Failed to initgroups()" << std::endl;
+               ::exit(EXIT_FAILURE);
+       }
+
+       if (::setgid(user.getGid()) == -1) {
+               std::cerr << "Failed to setgid()" << std::endl;
+               ::exit(EXIT_FAILURE);
+       }
+
+       if (::setuid(user.getUid()) == -1) {
+               std::cerr << "Failed to setuid()" << std::endl;
+               ::exit(EXIT_FAILURE);
+       }
+
+       char *default_args[2];
+       default_args[0] = ::strdup(DEFAULT_SHELL);
+       default_args[1] = NULL;
+
+       if (args == NULL) {
+               args = default_args;
+       }
+
+       ::execve(*args, args, environ);
+       std::cerr << "Failed to execute " << args[0] << std::endl;
+
+       ::free(default_args[0]);
+
+       ::exit(EXIT_FAILURE);
 }
 
-int attachToZone(const std::string& name, char* args[])
+int attachToKrate(const std::string& name, char* args[])
 {
-    try {
-        runtime::User user(name);
+       try {
+               runtime::User user(name);
 
-        attachNamespaces(getSessionLeader(user));
-        launchProcess(user, args);
-    } catch (runtime::Exception& e) {
-        std::cerr << e.what() << std::endl;
-        return -1;
-    }
+               attachNamespaces(getSessionLeader(user));
+               launchProcess(user, args);
+       } catch (runtime::Exception& e) {
+               std::cerr << e.what() << std::endl;
+               return -1;
+       }
 
-    return 0;
+       return 0;
 }
 
 bool packgeListCallback(package_info_h info, void *user_data)
 {
-    bool checked;
-    char *val;
-
-    std::cout << "Package #" << (*(int*)user_data)++ << " :" << std::endl;
-
-    package_info_get_package(info, &val);
-    std::cout << val;
-    free(val);
-
-    package_info_get_version(info, &val);
-    std::cout << " (" << val << ")" << std::endl;
-    free(val);
-
-    package_info_get_type(info, &val);
-    std::cout << "    Type : " << val << " (";
-    free(val);
-
-    package_info_is_system_package(info, &checked);
-    if (checked) {
-        std::cout <<" System ";
-    }
-    package_info_is_removable_package(info, &checked);
-    if (checked) {
-        std::cout <<" Removable ";
-    }
-    package_info_is_preload_package(info, &checked);
-    if (checked) {
-        std::cout <<" Preload ";
-    }
-    std::cout << ")" << std::endl;
-
-    package_info_get_label(info, &val);
-    std::cout << "    Label : " << val << std::endl;
-    free(val);
-
-    package_info_get_icon(info, &val);
-    std::cout << "    Icon : " << val << std::endl;
-    free(val);
-
-    std::cout << std::endl;
-
-    return true;
+       bool checked;
+       char *val;
+
+       std::cout << "Package #" << (*(int*)user_data)++ << " :" << std::endl;
+
+       package_info_get_package(info, &val);
+       std::cout << val;
+       free(val);
+
+       package_info_get_version(info, &val);
+       std::cout << " (" << val << ")" << std::endl;
+       free(val);
+
+       package_info_get_type(info, &val);
+       std::cout << "    Type : " << val << " (";
+       free(val);
+
+       package_info_is_system_package(info, &checked);
+       if (checked) {
+               std::cout <<" System ";
+       }
+       package_info_is_removable_package(info, &checked);
+       if (checked) {
+               std::cout <<" Removable ";
+       }
+       package_info_is_preload_package(info, &checked);
+       if (checked) {
+               std::cout <<" Preload ";
+       }
+       std::cout << ")" << std::endl;
+
+       package_info_get_label(info, &val);
+       std::cout << "    Label : " << val << std::endl;
+       free(val);
+
+       package_info_get_icon(info, &val);
+       std::cout << "    Icon : " << val << std::endl;
+       free(val);
+
+       std::cout << std::endl;
+
+       return true;
 }
 
 int showPkgInfo(const std::string& name)
 {
-    int num = 0;
+       int num = 0;
 
-    zone_manager_h zoneMgr;
-    zone_package_proxy_h pkgProxy;
+       zone_manager_h krateMgr;
+       zone_package_proxy_h pkgProxy;
 
-    zone_manager_create(&zoneMgr);
-    zone_package_proxy_create(zoneMgr, name.c_str(), &pkgProxy);
-    zone_package_proxy_foreach_package_info(pkgProxy, packgeListCallback, &num);
-    std::cout << num << " packages are found" << std::endl;
-    zone_package_proxy_destroy(pkgProxy);
-    zone_manager_destroy(zoneMgr);
+       zone_manager_create(&krateMgr);
+       zone_package_proxy_create(krateMgr, name.c_str(), &pkgProxy);
+       zone_package_proxy_foreach_package_info(pkgProxy, packgeListCallback, &num);
+       std::cout << num << " packages are found" << std::endl;
+       zone_package_proxy_destroy(pkgProxy);
+       zone_manager_destroy(krateMgr);
 
-    return 0;
+       return 0;
 }
 
 bool applicationListCallback(app_info_h info, void *user_data)
 {
-    bool checked;
-    char *val;
+       bool checked;
+       char *val;
 
-    std::cout << "Application #" << (*(int*)user_data)++ << " :" << std::endl;
+       std::cout << "Application #" << (*(int*)user_data)++ << " :" << std::endl;
 
-    app_info_get_app_id(info, &val);
-    std::cout << val;
-    free(val);
+       app_info_get_app_id(info, &val);
+       std::cout << val;
+       free(val);
 
-    app_info_get_package(info, &val);
-    std::cout << " (" << val << ")" << std::endl;
-    free(val);
+       app_info_get_package(info, &val);
+       std::cout << " (" << val << ")" << std::endl;
+       free(val);
 
-    app_info_get_type(info, &val);
-    std::cout << "    Type : " << val << " (";
-    free(val);
+       app_info_get_type(info, &val);
+       std::cout << "    Type : " << val << " (";
+       free(val);
 
-    app_info_is_nodisplay(info, &checked);
-    if (checked) {
-        std::cout <<" NoDisplay ";
-    }
-    std::cout << ")"<< std::endl;
+       app_info_is_nodisplay(info, &checked);
+       if (checked) {
+               std::cout <<" NoDisplay ";
+       }
+       std::cout << ")"<< std::endl;
 
-    app_info_get_label(info, &val);
-    std::cout << "    Label : " << val << std::endl;
-    free(val);
+       app_info_get_label(info, &val);
+       std::cout << "    Label : " << val << std::endl;
+       free(val);
 
-    if (app_info_get_icon(info, &val) == APP_MANAGER_ERROR_NONE) {
-        std::cout << "    Icon : " << val << std::endl;
-        free(val);
-    } else {
-        std::cout << "App Manager error" << std::endl;
-    }
+       if (app_info_get_icon(info, &val) == APP_MANAGER_ERROR_NONE) {
+               std::cout << "    Icon : " << val << std::endl;
+               free(val);
+       } else {
+               std::cout << "App Manager error" << std::endl;
+       }
 
-    std::cout << std::endl;
+       std::cout << std::endl;
 
-    return true;
+       return true;
 }
 
 int showAppInfo(const std::string& name)
 {
-    int num = 0;
+       int num = 0;
 
-    zone_manager_h zoneMgr;
-    zone_app_proxy_h appMgr;
+       zone_manager_h krateMgr;
+       zone_app_proxy_h appMgr;
 
-    zone_manager_create(&zoneMgr);
-    zone_app_proxy_create(zoneMgr, name.c_str(), &appMgr);
-    zone_app_proxy_foreach_app_info(appMgr, applicationListCallback, &num);
-    std::cout << num << " applications are found" << std::endl;
-    zone_app_proxy_destroy(appMgr);
-    zone_manager_destroy(zoneMgr);
+       zone_manager_create(&krateMgr);
+       zone_app_proxy_create(krateMgr, name.c_str(), &appMgr);
+       zone_app_proxy_foreach_app_info(appMgr, applicationListCallback, &num);
+       std::cout << num << " applications are found" << std::endl;
+       zone_app_proxy_destroy(appMgr);
+       zone_manager_destroy(krateMgr);
 
-    return 0;
+       return 0;
 }
 
 GMainLoop *gmainloop = NULL;
 
 void monitorSigHandler(int sig)
 {
-    g_main_loop_quit(gmainloop);
+       g_main_loop_quit(gmainloop);
 }
 
-void zoneCallback(const char* name, const char* object, void *user_data)
+void krateCallback(const char* name, const char* object, void *user_data)
 {
-    std::cout << "--- Zone event ---" << std::endl;
-    std::cout << "Type : " << (char*)user_data << std::endl;
-    std::cout << "Name : " << name <<std::endl;
-    std::cout << std::endl;
+       std::cout << "--- Krate event ---" << std::endl;
+       std::cout << "Type : " << (char*)user_data << std::endl;
+       std::cout << "Name : " << name <<std::endl;
+       std::cout << std::endl;
 }
 
 int monitorEvent()
 {
-    int zoneCallbackId[2];
-    zone_manager_h zoneMgr;
-    zone_manager_create(&zoneMgr);
+       int krateCallbackId[2];
+       zone_manager_h krateMgr;
+       zone_manager_create(&krateMgr);
 
-    zone_manager_add_event_cb(zoneMgr, "created", zoneCallback,
-                                (void*)"created", &zoneCallbackId[0]);
-    zone_manager_add_event_cb(zoneMgr, "removed", zoneCallback,
-                                (void*)"removed", &zoneCallbackId[1]);
+       zone_manager_add_event_cb(krateMgr, "created", krateCallback,
+                                                               (void*)"created", &krateCallbackId[0]);
+       zone_manager_add_event_cb(krateMgr, "removed", krateCallback,
+                                                               (void*)"removed", &krateCallbackId[1]);
 
-    std::cout << "=== Monitoring start ===" << std::endl << std::endl;
+       std::cout << "=== Monitoring start ===" << std::endl << std::endl;
 
-    signal(SIGINT, monitorSigHandler);
+       signal(SIGINT, monitorSigHandler);
 
-    gmainloop = g_main_loop_new(NULL, FALSE);
-    g_main_loop_run(gmainloop);
-    g_main_loop_unref(gmainloop);
+       gmainloop = g_main_loop_new(NULL, FALSE);
+       g_main_loop_run(gmainloop);
+       g_main_loop_unref(gmainloop);
 
-    zone_manager_remove_event_cb(zoneMgr, zoneCallbackId[0]);
-    zone_manager_remove_event_cb(zoneMgr, zoneCallbackId[1]);
+       zone_manager_remove_event_cb(krateMgr, krateCallbackId[0]);
+       zone_manager_remove_event_cb(krateMgr, krateCallbackId[1]);
 
-    std::cout << "===  Monitoring end  ===" << std::endl;
+       std::cout << "===  Monitoring end  ===" << std::endl;
 
-    zone_manager_destroy(zoneMgr);
+       zone_manager_destroy(krateMgr);
 
-    return 0;
+       return 0;
 }
 
 void packageEventCallback(const char *type,
-                          const char *package,
-                          package_manager_event_type_e event_type,
-                          package_manager_event_state_e event_state,
-                          int progress, package_manager_error_e error,
-                          void *user_data)
+                                                 const char *package,
+                                                 package_manager_event_type_e event_type,
+                                                 package_manager_event_state_e event_state,
+                                                 int progress, package_manager_error_e error,
+                                                 void *user_data)
 {
-    std::cout << "--- Package event ---" << std::endl;
-    std::cout << "Pacakge : " << package << std::endl;
-    std::cout << "Pacakge type : " << type << std::endl;
-
-    std::cout << "Event state : ";
-    switch (event_state) {
-    case PACKAGE_MANAGER_EVENT_STATE_STARTED:
-        std::cout << "started" << std::endl;
-        std::cout << "Event type : ";
-        switch (event_type) {
-        case PACKAGE_MANAGER_EVENT_TYPE_INSTALL:
-            std::cout << "install";
-            break;
-        case PACKAGE_MANAGER_EVENT_TYPE_UNINSTALL:
-            std::cout << "uninstall";
-            break;
-        case PACKAGE_MANAGER_EVENT_TYPE_UPDATE:
-            std::cout << "update";
-            break;
-        }
-        break;
-    case PACKAGE_MANAGER_EVENT_STATE_PROCESSING:
-        std::cout << "processing" << std::endl;
-        std::cout << "Progress : " << std::to_string(progress) << "%";
-        break;
-    case PACKAGE_MANAGER_EVENT_STATE_FAILED:
-        std::cout << "failed";
-        break;
-    case PACKAGE_MANAGER_EVENT_STATE_COMPLETED:
-        std::cout << "completed";
-        break;
-    }
-    std::cout << std::endl;
-
-    std::cout << std::endl;
+       std::cout << "--- Package event ---" << std::endl;
+       std::cout << "Pacakge : " << package << std::endl;
+       std::cout << "Pacakge type : " << type << std::endl;
+
+       std::cout << "Event state : ";
+       switch (event_state) {
+       case PACKAGE_MANAGER_EVENT_STATE_STARTED:
+               std::cout << "started" << std::endl;
+               std::cout << "Event type : ";
+               switch (event_type) {
+               case PACKAGE_MANAGER_EVENT_TYPE_INSTALL:
+                       std::cout << "install";
+                       break;
+               case PACKAGE_MANAGER_EVENT_TYPE_UNINSTALL:
+                       std::cout << "uninstall";
+                       break;
+               case PACKAGE_MANAGER_EVENT_TYPE_UPDATE:
+                       std::cout << "update";
+                       break;
+               }
+               break;
+       case PACKAGE_MANAGER_EVENT_STATE_PROCESSING:
+               std::cout << "processing" << std::endl;
+               std::cout << "Progress : " << std::to_string(progress) << "%";
+               break;
+       case PACKAGE_MANAGER_EVENT_STATE_FAILED:
+               std::cout << "failed";
+               break;
+       case PACKAGE_MANAGER_EVENT_STATE_COMPLETED:
+               std::cout << "completed";
+               break;
+       }
+       std::cout << std::endl;
+
+       std::cout << std::endl;
 }
 
 int monitorPkgEvent(const std::string& name)
 {
-    zone_manager_h zoneMgr;
-    zone_package_proxy_h pkgProxy;
+       zone_manager_h krateMgr;
+       zone_package_proxy_h pkgProxy;
 
-    zone_manager_create(&zoneMgr);
-    zone_package_proxy_create(zoneMgr, name.c_str(), &pkgProxy);
+       zone_manager_create(&krateMgr);
+       zone_package_proxy_create(krateMgr, name.c_str(), &pkgProxy);
 
-    zone_package_proxy_set_event_cb(pkgProxy, packageEventCallback, NULL);
+       zone_package_proxy_set_event_cb(pkgProxy, packageEventCallback, NULL);
 
-    std::cout << "=== Monitoring start ===" << std::endl << std::endl;
+       std::cout << "=== Monitoring start ===" << std::endl << std::endl;
 
-    signal(SIGINT, monitorSigHandler);
+       signal(SIGINT, monitorSigHandler);
 
-    gmainloop = g_main_loop_new(NULL, FALSE);
-    g_main_loop_run(gmainloop);
-    g_main_loop_unref(gmainloop);
+       gmainloop = g_main_loop_new(NULL, FALSE);
+       g_main_loop_run(gmainloop);
+       g_main_loop_unref(gmainloop);
 
-    zone_package_proxy_unset_event_cb(pkgProxy);
+       zone_package_proxy_unset_event_cb(pkgProxy);
 
-    std::cout << "===  Monitoring end  ===" << std::endl;
+       std::cout << "===  Monitoring end  ===" << std::endl;
 
-    zone_package_proxy_destroy(pkgProxy);
-    zone_manager_destroy(zoneMgr);
+       zone_package_proxy_destroy(pkgProxy);
+       zone_manager_destroy(krateMgr);
 
-    return 0;
+       return 0;
 }
 
 int main(int argc, char* argv[])
 {
-    int opt = 0, index, ret = 0;
-
-    struct option options[] = {
-        {"attach", required_argument, 0, 'a'},
-        {"list", no_argument, 0, 'l'},
-        {"pkginfo", required_argument, 0, 'p'},
-        {"appinfo", required_argument, 0, 'q'},
-        {"zone-monitor", no_argument, 0, 'm'},
-        {"pkg-monitor", no_argument, 0, 'n'},
-        {"help", no_argument, 0, 'h'},
-        {0, 0, 0, 0}
-    };
-
-    if (argc <= 1) {
-        usage(argv[0]);
-        return EXIT_SUCCESS;
-    }
-
-    while ((opt = getopt_long(argc, argv, "a:p:q:mn:lh", options, &index)) != -1) {
-        switch (opt) {
-        case 'a':
-            ret = attachToZone(optarg, optind >= argc ? NULL : argv + optind);
-            break;
-        case 'p':
-            ret = showPkgInfo(optarg);
-            break;
-        case 'q':
-            ret = showAppInfo(optarg);
-            break;
-        case 'm':
-            ret = monitorEvent();
-            break;
-        case 'n':
-            ret = monitorPkgEvent(optarg);
-            break;
-        case 'l':
-            ret = showZoneInstances();
-            break;
-        case 'h':
-            usage(argv[0]);
-            break;
-        default:
-            usage(argv[0]);
-            ret = -1;
-        }
-    }
-
-    return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+       int opt = 0, index, ret = 0;
+
+       struct option options[] = {
+               {"attach", required_argument, 0, 'a'},
+               {"list", no_argument, 0, 'l'},
+               {"pkginfo", required_argument, 0, 'p'},
+               {"appinfo", required_argument, 0, 'q'},
+               {"krate-monitor", no_argument, 0, 'm'},
+               {"pkg-monitor", no_argument, 0, 'n'},
+               {"help", no_argument, 0, 'h'},
+               {0, 0, 0, 0}
+       };
+
+       if (argc <= 1) {
+               usage(argv[0]);
+               return EXIT_SUCCESS;
+       }
+
+       while ((opt = getopt_long(argc, argv, "a:p:q:mn:lh", options, &index)) != -1) {
+               switch (opt) {
+               case 'a':
+                       ret = attachToKrate(optarg, optind >= argc ? NULL : argv + optind);
+                       break;
+               case 'p':
+                       ret = showPkgInfo(optarg);
+                       break;
+               case 'q':
+                       ret = showAppInfo(optarg);
+                       break;
+               case 'm':
+                       ret = monitorEvent();
+                       break;
+               case 'n':
+                       ret = monitorPkgEvent(optarg);
+                       break;
+               case 'l':
+                       ret = showKrateInstances();
+                       break;
+               case 'h':
+                       usage(argv[0]);
+                       break;
+               default:
+                       usage(argv[0]);
+                       ret = -1;
+               }
+       }
+
+       return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
 }
diff --git a/volume/CMakeLists.txt b/volume/CMakeLists.txt
new file mode 100644 (file)
index 0000000..0ae5e95
--- /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.
+#
+SET(VOLUME_MANAGER_SRCS        key-manager.cpp
+                                               key-generator.cpp
+                                               kernel-keyring.cpp
+                                               main.cpp
+)
+
+PKG_CHECK_MODULES(VOLUME_MANAGER_DEPS  REQUIRED
+                                                                               klay
+                                                                               key-manager
+)
+
+INCLUDE_DIRECTORIES(SYSTEM ${VOLUME_MANAGER_DEPS_INCLUDE_DIRS})
+
+ADD_EXECUTABLE(${PROJECT_NAME}-volume-manager ${VOLUME_MANAGER_SRCS})
+
+TARGET_LINK_LIBRARIES(${PROJECT_NAME}-volume-manager ${VOLUME_MANAGER_DEPS_LIBRARIES})
+
+INSTALL(TARGETS ${PROJECT_NAME}-volume-manager DESTINATION sbin)
diff --git a/volume/ecryptfs.h b/volume/ecryptfs.h
new file mode 100755 (executable)
index 0000000..9962e34
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ *  Copyright (c) 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
+ */
+
+#ifndef __ECRYPTFS_H__
+#define __ECRYPTFS_H__
+
+#include <sys/types.h>
+#include <errno.h>
+
+// this is versions of ecryptfs module
+#define ECRYPTFS_MAJOR_VERSION 0x00
+#define ECRYPTFS_MINOR_VERSION 0x04
+#define ECRYPTFS_VERSION ((ECRYPTFS_MAJOR_VERSION << 8) | ECRYPTFS_MINOR_VERSION)
+
+#define ECRYPTFS_MAX_PKI_NAME_BYTES             16
+#define ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET 0x02
+
+#define PGP_DIGEST_ALGO_SHA512  10
+
+#define ECRYPTFS_FEK_CIPHER     "aes"
+#define ECRYPTFS_MOUNT_DEVICE   "ecryptfs"
+
+#define ECRYPTFS_MAX_OPTIONS    1024
+
+#define ECRYPTFS_MAX_SIG_SIZE   8
+#define ECRYPTFS_MAX_SIG_HEX (ECRYPTFS_MAX_SIG_SIZE*2)
+#define ECRYPTFS_PASSWORD_SIG_SIZE ECRYPTFS_MAX_SIG_HEX
+
+#define ECRYPTFS_MAX_KEY_SIZE               32
+#define ECRYPTFS_MAX_KEY_HEX                (ECRYPTFS_MAX_KEY_SIZE * 2)
+
+#define ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES     512
+#define ECRYPTFS_MAX_PKI_NAME_BYTES          16
+
+#define ECRYPTFS_MAX_SALT_SIZE               4
+#define ECRYPTFS_MAX_SALT_HEX                8
+
+#define ECRYPTFS_PWD_PAYLOAD_TYPE            0 // password
+
+struct ecryptfs_session_key {
+#define ECRYPTFS_USERSPACE_SHOULD_TRY_TO_DECRYPT    0x00000001
+#define ECRYPTFS_USERSPACE_SHOULD_TRY_TO_ENCRYPT    0x00000002
+#define ECRYPTFS_CONTAINS_DECRYPTED_KEY             0x00000004
+#define ECRYPTFS_CONTAINS_ENCRYPTED_KEY             0x00000008
+       int32_t flags;
+       int32_t encrypted_key_size;
+       int32_t decrypted_key_size;
+       u_int8_t encrypted_key[ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES];
+       u_int8_t decrypted_key[ECRYPTFS_MAX_KEY_HEX];
+};
+
+struct ecryptfs_password {
+       int32_t password_bytes;
+       int32_t hash_algo;
+       int32_t hash_iterations;
+       int32_t session_key_encryption_key_bytes;
+#define ECRYPTFS_PERSISTENT_PASSWORD                0x01
+#define ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET     0x02
+       u_int32_t flags;
+       /* Iterated-hash concatenation of salt and passphrase */
+       u_int8_t session_key_encryption_key[ECRYPTFS_MAX_KEY_HEX];
+       u_int8_t signature[ECRYPTFS_PASSWORD_SIG_SIZE + 1];
+       /* Always in expanded hex */
+       u_int8_t salt[ECRYPTFS_MAX_SALT_SIZE];
+};
+
+enum ecryptfs_token_types {
+       ECRYPTFS_PASSWORD,
+       ECRYPTFS_PRIVATE_KEY
+};
+
+struct ecryptfs_private_key {
+       u_int32_t key_size;
+       u_int32_t data_len;
+       u_int8_t signature[ECRYPTFS_PASSWORD_SIG_SIZE + 1];
+       char pki_type[ECRYPTFS_MAX_PKI_NAME_BYTES + 1];
+       u_int8_t data[];
+};
+
+struct ecryptfs_auth_tok {
+       u_int16_t version; /* 8-bit major and 8-bit minor */
+       u_int16_t token_type;
+#define ECRYPTFS_ENCRYPT_ONLY                       0x00000001
+       u_int32_t flags;
+       struct ecryptfs_session_key session_key;
+       u_int8_t reserved[32];
+       union {
+               struct ecryptfs_password password;
+               struct ecryptfs_private_key private_key;
+       } token;
+}  __attribute__((packed));
+
+typedef struct ecryptfs_auth_tok ecryptfs_payload;
+#endif
diff --git a/volume/kernel-keyring.cpp b/volume/kernel-keyring.cpp
new file mode 100755 (executable)
index 0000000..11d2373
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ *  Copyright (c) 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
+ */
+
+#include <unistd.h>
+#include <sys/mount.h>
+#include <sys/syscall.h>
+#include <linux/limits.h>
+
+#include "kernel-keyring.h"
+
+#ifndef KEYCTL_SEARCH
+#define KEYCTL_SEARCH   10
+#endif
+
+KeySerial KernelKeyRing::add(const char *type, const char* description, const void* payload, size_t plen, KeySerial ringid)
+{
+       return ::syscall(__NR_add_key, type, description, payload, plen, ringid);
+}
+
+long KernelKeyRing::search(KeySerial ringid, const char* type, const char* description, KeySerial destringid)
+{
+       return ::syscall(__NR_keyctl, KEYCTL_SEARCH, ringid, type, description, destringid);
+}
+
+long KernelKeyRing::link(KeySerial keyid, KeySerial ringid)
+{
+       return ::syscall(__NR_keyctl, KEYCTL_LINK, keyid, ringid);
+}
+
+long KernelKeyRing::unlink(KeySerial keyid, KeySerial ringid)
+{
+       return ::syscall(__NR_keyctl, KEYCTL_UNLINK, keyid, ringid);
+}
diff --git a/volume/kernel-keyring.h b/volume/kernel-keyring.h
new file mode 100755 (executable)
index 0000000..c23d70f
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ *  Copyright (c) 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
+ */
+
+#ifndef __KERNEL_KEY_RING_H__
+#define __KERNEL_KEY_RING_H__
+
+#include <sys/types.h>
+#include <linux/keyctl.h>
+
+#include <string>
+
+typedef int32_t KeySerial;
+
+class KernelKeyRing {
+public:
+       KernelKeyRing() = delete;
+       KernelKeyRing(const KernelKeyRing&) = delete;
+       KernelKeyRing(KernelKeyRing&&) = delete;
+
+       KernelKeyRing& operator=(const KernelKeyRing&) = delete;
+       KernelKeyRing& operator=(KernelKeyRing&&) = delete;
+
+       static KeySerial add(const char* type, const char* description, const void* payload, size_t plen, KeySerial ringid);
+       static long search(KeySerial ringid, const char* type, const char* description, KeySerial destringid);
+       static long link(KeySerial keyid, KeySerial ringid);
+       static long unlink(KeySerial keyid, KeySerial ringid);
+};
+
+#endif //!__KERNEL_KEY_RING_H__
diff --git a/volume/key-generator.cpp b/volume/key-generator.cpp
new file mode 100755 (executable)
index 0000000..d6440f6
--- /dev/null
@@ -0,0 +1,322 @@
+/*
+ *  Copyright (c) 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
+ */
+
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <cstring>
+#include <cstdlib>
+#include <string>
+#include <iomanip>
+#include <sstream>
+#include <iostream>
+
+#include <klay/error.h>
+#include <klay/exception.h>
+
+#include "key-generator.h"
+
+#define RAND_READ_BYTES 8
+#define PBKDF2_ITERATION 1000
+#define SHA_BLOCKSIZE 64
+
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
+
+#if defined (BYTE_ORDER) && defined(BIG_ENDIAN) && (BYTE_ORDER == BIG_ENDIAN)
+#define WORDS_BIGENDIAN 1
+#endif
+#ifdef _BIG_ENDIAN
+#define WORDS_BIGENDIAN 1
+#endif
+
+#ifdef WORDS_BIGENDIAN
+#define blk0(i) block->l[i]
+#else
+#define blk0(i) (block->l[i] = (rol(block->l[i], 24)&0xff00ff00) \
+       |(rol(block->l[i], 8)&0x00ff00ff))
+#endif
+#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
+       ^block->l[(i+2)&15]^block->l[i&15], 1))
+
+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
+#define R0(v, w, x, y, z, i) \
+       z+=((w&(x^y))^y)+blk0(i)+0x5a827999+rol(v, 5);w=rol(w, 30);
+#define R1(v, w, x, y, z, i) \
+       z+=((w&(x^y))^y)+blk(i)+0x5a827999+rol(v, 5);w=rol(w, 30);
+#define R2(v, w, x, y, z, i) \
+       z+=(w^x^y)+blk(i)+0x6ed9eba1+rol(v, 5);w=rol(w, 30);
+#define R3(v, w, x, y, z, i) \
+       z+=(((w|x)&y)|(w&x))+blk(i)+0x8f1bbcdc+rol(v, 5);w=rol(w, 30);
+#define R4(v, w, x, y, z, i) \
+       z+=(w^x^y)+blk(i)+0xca62c1d6+rol(v, 5);w=rol(w, 30);
+
+#define __min__(a, b) (((a) < (b)) ? (a) : (b))
+
+std::string KeyGenerator::hexConvert(unsigned char* src, int srcLen)
+{
+       std::ostringstream ss;
+
+       for (int i = 0; i <srcLen; i++) {
+               ss << std::hex << std::setfill('0') << std::setw(2);
+               ss << (src[i] & 0xffffffff);
+       }
+
+       return ss.str();
+}
+
+std::string KeyGenerator::generateKey(int len)
+{
+       int randomLen = 0;
+       unsigned char buf[len];
+       int randomDev;
+
+       while (((randomDev = ::open("/dev/urandom", O_RDONLY)) == -1) && (errno == EINTR));
+
+       if (randomDev == -1) {
+               throw runtime::Exception(runtime::GetSystemErrorMessage());
+       }
+
+       while (randomLen < len) {
+               ssize_t result = ::read(randomDev, buf + randomLen, len - randomLen);
+               if (result == -1) {
+                       if (errno != EINTR) {
+                               throw runtime::Exception(runtime::GetSystemErrorMessage());
+                       } else {
+                               continue;
+                       }
+               }
+
+               randomLen += result;
+       }
+
+       std::string ret = hexConvert(buf, len);
+
+       while (::close(randomDev) == -1 && errno == EINTR);
+
+       return ret;
+}
+
+std::string KeyGenerator::wrapKey(const std::string& decrypted, const std::string& salt, int len)
+{
+       unsigned char encrypted[len];
+       int ret;
+
+       ret = pbkdf2(decrypted.c_str(), decrypted.size(),
+                                (const unsigned char *)salt.c_str(), salt.size(),
+                                PBKDF2_ITERATION, len,
+                                encrypted);
+       if (ret < 0) {
+               throw runtime::Exception("Failed to wrap key");
+       }
+
+       return hexConvert(encrypted, len);
+}
+
+void KeyGenerator::sha1Init(SHA1_CTX* context)
+{
+       /* SHA1 initialization constants */
+       context->state[0] = 0x67452301;
+       context->state[1] = 0xefcdab89;
+       context->state[2] = 0x98badcfe;
+       context->state[3] = 0x10325476;
+       context->state[4] = 0xc3d2e1f0;
+       context->count[0] = context->count[1] = 0;
+}
+
+void KeyGenerator::sha1Update(SHA1_CTX* context, const void* p, unsigned int len)
+{
+       const unsigned char* data = (unsigned char*)p;
+       unsigned int i, j;
+
+       j = (context->count[0] >> 3) & 63;
+       if ((context->count[0] += (len << 3)) < (len << 3)) {
+               context->count[1]++;
+       }
+       context->count[1] += (len >> 29);
+       if ((j + len) > 63) {
+               ::memcpy(&context->buffer[j], data, (i = 64 - j));
+               sha1Transform(context->state, context->buffer);
+               for (; i + 63 < len; i += 64) {
+                       sha1Transform(context->state, data + i);
+               }
+               j = 0;
+       } else {
+               i = 0;
+       }
+
+       ::memcpy(&context->buffer[j], &data[i], len - i);
+}
+
+void KeyGenerator::sha1Final(unsigned char digest[SHA1_DIGEST_SIZE], SHA1_CTX* context)
+{
+       unsigned int i;
+       unsigned char finalcount[8];
+       for (i = 0; i < 8; i++) {
+               finalcount[i] = (unsigned char) ((context->count[(i >= 4 ? 0 : 1)]
+                       >> ((3 - (i & 3)) * 8)) & 255);
+       }
+       sha1Update(context, (unsigned char*) "\200", 1);
+       while ((context->count[0] & 504) != 448) {
+               sha1Update(context, (unsigned char*) "\0", 1);
+       }
+       sha1Update(context, finalcount, 8);
+       /* Should cause SHA1_Transform */
+       for (i = 0; i < SHA1_DIGEST_SIZE; i++) {
+               digest[i] = (unsigned char)
+                       ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
+       }
+       /* Wipe variables */
+       i = 0;
+       ::memset(context->buffer, 0, 64);
+       ::memset(context->state, 0, 20);
+       ::memset(context->count, 0, 8);
+       ::memset(finalcount, 0, 8);    /* SWR */
+
+#ifdef SHA1HANDSOFF    /* make SHA1Transform overwrite its own static vars */
+       transform(context->state, context->buffer);
+#endif
+}
+
+void KeyGenerator::sha1Transform(unsigned int state[5], const unsigned char buffer[64])
+{
+       uint32_t a, b, c, d, e;
+       typedef union {
+               unsigned char c[64];
+               unsigned int l[16];
+       } CHAR64LONG16;
+       CHAR64LONG16 *block;
+
+#ifdef SHA1HANDSOFF
+       CHAR64LONG16 workspace;
+       block = &workspace;
+       ::memcpy(block, buffer, 64);
+#else
+       block = (CHAR64LONG16*)buffer;
+#endif
+
+       a = state[0];
+       b = state[1];
+       c = state[2];
+       d = state[3];
+       e = state[4];
+
+       /* 4 rounds of 20 operations each. Loop unrolled. */
+       R0(a, b, c, d, e, 0);    R0(e, a, b, c, d, 1);    R0(d, e, a, b, c, 2);    R0(c, d, e, a, b, 3);
+       R0(b, c, d, e, a, 4);    R0(a, b, c, d, e, 5);    R0(e, a, b, c, d, 6);    R0(d, e, a, b, c, 7);
+       R0(c, d, e, a, b, 8);    R0(b, c, d, e, a, 9);    R0(a, b, c, d, e, 10);    R0(e, a, b, c, d, 11);
+       R0(d, e, a, b, c, 12);    R0(c, d, e, a, b, 13);    R0(b, c, d, e, a, 14);    R0(a, b, c, d, e, 15);
+       R1(e, a, b, c, d, 16);    R1(d, e, a, b, c, 17);    R1(c, d, e, a, b, 18);    R1(b, c, d, e, a, 19);
+       R2(a, b, c, d, e, 20);    R2(e, a, b, c, d, 21);    R2(d, e, a, b, c, 22);    R2(c, d, e, a, b, 23);
+       R2(b, c, d, e, a, 24);    R2(a, b, c, d, e, 25);    R2(e, a, b, c, d, 26);    R2(d, e, a, b, c, 27);
+       R2(c, d, e, a, b, 28);    R2(b, c, d, e, a, 29);    R2(a, b, c, d, e, 30);    R2(e, a, b, c, d, 31);
+       R2(d, e, a, b, c, 32);    R2(c, d, e, a, b, 33);    R2(b, c, d, e, a, 34);    R2(a, b, c, d, e, 35);
+       R2(e, a, b, c, d, 36);    R2(d, e, a, b, c, 37);    R2(c, d, e, a, b, 38);    R2(b, c, d, e, a, 39);
+       R3(a, b, c, d, e, 40);    R3(e, a, b, c, d, 41);    R3(d, e, a, b, c, 42);    R3(c, d, e, a, b, 43);
+       R3(b, c, d, e, a, 44);    R3(a, b, c, d, e, 45);    R3(e, a, b, c, d, 46);    R3(d, e, a, b, c, 47);
+       R3(c, d, e, a, b, 48);    R3(b, c, d, e, a, 49);    R3(a, b, c, d, e, 50);    R3(e, a, b, c, d, 51);
+       R3(d, e, a, b, c, 52);    R3(c, d, e, a, b, 53);    R3(b, c, d, e, a, 54);    R3(a, b, c, d, e, 55);
+       R3(e, a, b, c, d, 56);    R3(d, e, a, b, c, 57);    R3(c, d, e, a, b, 58);    R3(b, c, d, e, a, 59);
+       R4(a, b, c, d, e, 60);    R4(e, a, b, c, d, 61);    R4(d, e, a, b, c, 62);    R4(c, d, e, a, b, 63);
+       R4(b, c, d, e, a, 64);    R4(a, b, c, d, e, 65);    R4(e, a, b, c, d, 66);    R4(d, e, a, b, c, 67);
+       R4(c, d, e, a, b, 68);    R4(b, c, d, e, a, 69);    R4(a, b, c, d, e, 70);    R4(e, a, b, c, d, 71);
+       R4(d, e, a, b, c, 72);    R4(c, d, e, a, b, 73);    R4(b, c, d, e, a, 74);    R4(a, b, c, d, e, 75);
+       R4(e, a, b, c, d, 76);    R4(d, e, a, b, c, 77);    R4(c, d, e, a, b, 78);    R4(b, c, d, e, a, 79);
+
+       /* Add the working vars back into context.state[] */
+       state[0] += a;
+       state[1] += b;
+       state[2] += c;
+       state[3] += d;
+       state[4] += e;
+
+       /* Wipe variables */
+       a = b = c = d = e = 0;
+}
+
+void KeyGenerator::sha1Hmac(const unsigned char* key, int keyLen, const unsigned char* data, int dataLen, unsigned char out[SHA1_DIGEST_SIZE])
+{
+       SHA1_CTX ctx;
+       unsigned char buf[SHA_BLOCKSIZE], outPad[SHA_BLOCKSIZE], inPad[SHA_BLOCKSIZE];
+       unsigned char tempKey[SHA1_DIGEST_SIZE];
+       int i;
+
+       ::memset(buf, 0, SHA_BLOCKSIZE);
+
+       if (keyLen > SHA_BLOCKSIZE) {
+               sha1Init(&ctx);
+               sha1Update(&ctx, key, keyLen);
+               sha1Final(tempKey, &ctx);
+               key = tempKey;
+               keyLen = SHA1_DIGEST_SIZE;
+       }
+
+       ::memcpy(buf, key, keyLen);
+       ::memset(inPad, 0, SHA_BLOCKSIZE);
+       ::memset(outPad, 0, SHA_BLOCKSIZE);
+
+       for (i = 0; i < SHA_BLOCKSIZE; i++) {
+               outPad[i] = buf[i] ^ 0x5c;
+               inPad[i]= buf[i] ^ 0x36;
+       }
+
+       sha1Init(&ctx);
+       sha1Update(&ctx, inPad, SHA_BLOCKSIZE);
+       sha1Update(&ctx, data, dataLen);
+       sha1Final(out, &ctx);
+
+       sha1Init(&ctx);
+       sha1Update(&ctx, outPad, SHA_BLOCKSIZE);
+       sha1Update(&ctx, out, SHA1_DIGEST_SIZE);
+       sha1Final(out, &ctx);
+}
+
+int KeyGenerator::pbkdf2(const char * pass, int passLen, const unsigned char* salt, int saltLen, int iter, int keyLen, unsigned char* out)
+{
+       unsigned char digtmp1[SHA1_DIGEST_SIZE], digtmp2[SHA1_DIGEST_SIZE], itmp[saltLen + 4];
+       int j, k;
+       int genKeyLen = 0, toWriteLen;
+       unsigned long i = 1;
+
+       if (passLen <= 0 || saltLen <= 0 || iter <= 0 || keyLen <= 0)
+               return -1;
+
+       ::memcpy(itmp, salt, saltLen);
+       while (genKeyLen < keyLen) {
+               itmp[saltLen + 0] = (unsigned char)((i >> 24) & 0xff);
+               itmp[saltLen + 1] = (unsigned char)((i >> 16) & 0xff);
+               itmp[saltLen + 2] = (unsigned char)((i >> 8) & 0xff);
+               itmp[saltLen + 3] = (unsigned char)(i & 0xff);
+
+               sha1Hmac((unsigned char*)pass, passLen, itmp, saltLen+4,  digtmp1);
+               ::memcpy(digtmp2, digtmp1, SHA1_DIGEST_SIZE);
+
+               for (j = 1; j < iter; j++) {
+                       sha1Hmac((unsigned char*)pass, passLen, digtmp1, SHA1_DIGEST_SIZE,  digtmp1);
+                       for (k = 0; k < SHA1_DIGEST_SIZE; k++) {
+                               digtmp2[k] ^= digtmp1[k];
+                       }
+               }
+               toWriteLen = __min__((keyLen - genKeyLen), SHA1_DIGEST_SIZE);
+               ::memcpy(out+genKeyLen, digtmp2, toWriteLen);
+               genKeyLen += toWriteLen;
+               ++i;
+       }
+
+       return 1;
+}
diff --git a/volume/key-generator.h b/volume/key-generator.h
new file mode 100755 (executable)
index 0000000..e0d9796
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ *  Copyright (c) 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
+ */
+
+#ifndef __VOLUME_MANAGER_KEY_GENERATOR_H__
+#define __VOLUME_MANAGER_KEY_GENERATOR_H__
+
+#include "ecryptfs.h"
+
+#define SHA1_DIGEST_SIZE 20
+
+typedef struct {
+       unsigned int state[5];
+       unsigned int count[2];
+       unsigned char buffer[64];
+} SHA1_CTX;
+
+class KeyGenerator {
+public:
+       KeyGenerator() = delete;
+       KeyGenerator(const KeyGenerator&) = delete;
+       KeyGenerator(KeyGenerator&&) = delete;
+
+       KeyGenerator& operator=(const KeyGenerator&) = delete;
+       KeyGenerator& operator=(KeyGenerator&&) = delete;
+
+       static std::string wrapKey(const std::string& decrypted, const std::string& salt, int len);
+       static std::string generateKey(int len);
+       static void generateToken(char* key, ecryptfs_payload** outToken);
+
+private:
+       static void sha1Init(SHA1_CTX* context);
+       static void sha1Update(SHA1_CTX* context, const void* p, unsigned int len);
+       static void sha1Final(unsigned char digsest[SHA1_DIGEST_SIZE], SHA1_CTX* context);
+       static void sha1Transform(unsigned int state[5], const unsigned char buffer[64]);
+       static void sha1Hmac(const unsigned char* key, int keyLen, const unsigned char* data, int dataLen, unsigned char out[SHA1_DIGEST_SIZE]);
+
+       static int pbkdf2(const char* pass, int passLen, const unsigned char* salt, int saltLen, int iter, int keyLen, unsigned char* out);
+       static std::string hexConvert(unsigned char* src, int srcLen);
+};
+
+#endif //!__VOLUME_MANAGER_KEY_GENERATOR_H__
diff --git a/volume/key-manager.cpp b/volume/key-manager.cpp
new file mode 100755 (executable)
index 0000000..d143c31
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ *  Copyright (c) 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
+ */
+
+#include <string>
+
+#include <klay/exception.h>
+#include <ckmc/ckmc-manager.h>
+
+#include "key-manager.h"
+
+
+#define addAliasPrefix(alias)  \
+       (ckmcIdSystem + ckmcIdSeperator + alias)
+
+namespace {
+
+const std::string ckmcIdSystem = ckmc_owner_id_system;
+const std::string ckmcIdSeperator = ckmc_owner_id_separator;
+
+} //namespace
+
+bool KeyManager::isKeyExist(const std::string& keyName)
+{
+       int ret;
+       ckmc_raw_buffer_s* keyData = NULL;
+       std::string ckmAlias = addAliasPrefix(keyName);
+
+       ret = ::ckmc_get_data(ckmAlias.c_str(), NULL, &keyData);
+       ::ckmc_buffer_free(keyData);
+
+       return (ret != CKMC_ERROR_DB_ALIAS_UNKNOWN);
+}
+
+void KeyManager::addKey(const std::string& keyName, const std::string& data)
+{
+       int ret;
+       const std::string ckmAlias = addAliasPrefix(keyName);
+       ckmc_raw_buffer_s keyData;
+       ckmc_policy_s keyPolicy;
+
+       keyData.data = (unsigned char*)data.c_str();
+       keyData.size = data.size();
+
+       keyPolicy.password = NULL;
+       keyPolicy.extractable = true;
+
+       ret = ::ckmc_save_data(ckmAlias.c_str(), keyData, keyPolicy);
+       if (ret != 0) {
+               throw runtime::Exception("Failed to add key data");
+       }
+}
+
+std::string KeyManager::getKey(const std::string& keyName)
+{
+       int ret;
+       const std::string ckmAlias = addAliasPrefix(keyName);
+       ckmc_raw_buffer_s* keyData;
+       std::string result;
+
+       ret = ::ckmc_get_data(ckmAlias.c_str(), NULL, &keyData);
+       if (ret != CKMC_ERROR_NONE) {
+               throw runtime::Exception("Failed to get key data");
+       }
+
+       result = std::string(reinterpret_cast<char*>(keyData->data), keyData->size);
+
+       ::ckmc_buffer_free(keyData);
+
+       return result;
+}
+
+void KeyManager::removeKey(const std::string& keyName)
+{
+       const std::string ckmAlias = addAliasPrefix(keyName);
+
+       if (::ckmc_remove_data(ckmAlias.c_str()) != 0) {
+               throw runtime::Exception("Failed to remove key data");
+       }
+}
diff --git a/volume/key-manager.h b/volume/key-manager.h
new file mode 100644 (file)
index 0000000..48bcdc8
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ *  Copyright (c) 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
+ */
+
+#ifndef __KEY_MANAGER_H__
+#define __KEY_MANAGER_H__
+
+class KeyManager {
+public:
+       KeyManager() = delete;
+       KeyManager(const KeyManager&) = delete;
+       KeyManager(KeyManager&&) = delete;
+
+       KeyManager& operator=(const KeyManager&) = delete;
+       KeyManager& operator=(KeyManager&&) = delete;
+
+       static bool isKeyExist(const std::string& keyName);
+       static void addKey(const std::string& keyName, const std::string& data);
+       static std::string getKey(const std::string& keyName);
+       static void removeKey(const std::string& keyName);
+};
+
+#endif //!__KEY_MANAGER_H__*/
diff --git a/volume/main.cpp b/volume/main.cpp
new file mode 100755 (executable)
index 0000000..4de5260
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+ *  Copyright (c) 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
+ */
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <sys/stat.h>
+#include <sys/mount.h>
+#include <sys/types.h>
+
+#include <cstring>
+#include <string>
+#include <vector>
+#include <iostream>
+
+#include <klay/error.h>
+#include <klay/exception.h>
+#include <klay/audit/logger.h>
+
+#include "ecryptfs.h"
+#include "kernel-keyring.h"
+#include "key-manager.h"
+#include "key-generator.h"
+
+int generateKey(const std::string& keyName)
+{
+       if (KeyManager::isKeyExist(keyName)) {
+               ERROR("Key already registered");
+               return -1;
+       }
+
+       try {
+               std::string pass = KeyGenerator::generateKey(ECRYPTFS_MAX_KEY_SIZE);
+               std::string salt = KeyGenerator::generateKey(ECRYPTFS_MAX_SALT_SIZE);
+               std::string wrappedKey = KeyGenerator::wrapKey(pass, salt, ECRYPTFS_MAX_KEY_SIZE);
+
+               KeyManager::addKey(keyName, wrappedKey);
+       } catch (runtime::Exception& e) {
+               ERROR(e.what());
+               return -1;
+       }
+
+       return 0;
+}
+
+ecryptfs_payload* generateToken(char* key)
+{
+       struct ecryptfs_password* tokenKey;
+
+       unsigned char keyBuffer[ECRYPTFS_MAX_KEY_SIZE+1];
+
+       ecryptfs_payload* authToken = (ecryptfs_payload *)::malloc(sizeof(ecryptfs_payload));
+       if (authToken == NULL) {
+               return NULL;
+       }
+
+       ::memset(authToken, 0, sizeof(ecryptfs_payload));
+       ::strncpy((char*)keyBuffer, key, ECRYPTFS_MAX_KEY_SIZE);
+       keyBuffer[ECRYPTFS_MAX_KEY_SIZE] = '\0';
+
+       tokenKey = &authToken->token.password;
+
+       authToken->version = ECRYPTFS_VERSION;
+       authToken->token_type = ECRYPTFS_PWD_PAYLOAD_TYPE;
+       tokenKey->session_key_encryption_key_bytes = ECRYPTFS_MAX_KEY_SIZE;
+       tokenKey->flags = ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET;
+       ::memcpy(tokenKey->session_key_encryption_key, keyBuffer, ECRYPTFS_MAX_KEY_SIZE);
+       ::memcpy(tokenKey->signature, keyBuffer, ECRYPTFS_MAX_SIG_HEX);
+
+       return authToken;
+}
+
+int mountEcryptfs(const std::string& src, const std::string& keyName)
+{
+       int rc;
+       char ecryptfsOpts[1024];
+       ecryptfs_payload* authTok = NULL;
+
+       std::string key;
+       try {
+               key = KeyManager::getKey(keyName);
+       } catch (runtime::Exception& e) {
+               ERROR(e.what());
+               return -1;
+       }
+
+       if (KernelKeyRing::link(KEY_SPEC_USER_KEYRING, KEY_SPEC_SESSION_KEYRING) != 0) {
+               ERROR("Failed to link key");
+               return -1;
+       }
+
+       if ((authTok = generateToken((char*)key.c_str())) == NULL) {
+               ERROR("Failed to generate Token");
+               return -1;
+       }
+
+       const char* signature = (const char*)authTok->token.password.signature;
+       rc = KernelKeyRing::search(KEY_SPEC_USER_KEYRING,
+                                                          "user",
+                                                          signature,
+                                                          0);
+       if (rc == -1 && errno != ENOKEY) {
+               ERROR("Failed to find key");
+               return -1;
+       }
+       if (rc == -1) {
+               rc = KernelKeyRing::add("user",
+                                                               signature,
+                                                               (void*)authTok,
+                                                               sizeof(ecryptfs_payload),
+                                                               KEY_SPEC_USER_KEYRING);
+               if (rc == -1) {
+                       ERROR("Failed to add key");
+                       return -1;
+               }
+       }
+
+       ::snprintf(ecryptfsOpts, 1024,
+                          "ecryptfs_passthrough,"
+                          "ecryptfs_cipher=aes,"
+                          "ecryptfs_key_bytes=%d,"
+                          "ecryptfs_sig=%s,"
+                          "smackfsroot=*,smackfsdef=*",
+                          ECRYPTFS_MAX_KEY_SIZE, signature);
+
+       rc = ::mount(src.c_str(), src.c_str(), "ecryptfs", MS_NODEV, ecryptfsOpts);
+       if (rc != 0) {
+               ERROR(runtime::GetSystemErrorMessage());
+               return -1;
+       }
+
+       return 0;
+}
+
+int mountEcryptfsToAll()
+{
+       return 0;
+}
+
+void usage(const std::string& prog)
+{
+       std::cout << "Usage: " << prog << std::endl
+                         << "-a            : Automount" << std::endl
+                         << "-g name       : Generate key for krate" << std::endl
+                         << "-m name       : Apply filesystem encrytion to krate" << std::endl;
+}
+
+int main(int argc, char* argv[])
+{
+       int opt, index, ret = -1;
+       struct option options[] = {
+               {"automount", no_argument, 0, 'a'},
+               {"generate", required_argument, 0, 'g'},
+               {"mount", required_argument, 0, 'm'},
+               {0, 0, 0, 0}
+       };
+
+       while ((opt = getopt_long(argc, argv, "ag:m:", options, &index)) != -1) {
+               switch (opt) {
+               case 'a':
+                       ret = mountEcryptfsToAll();
+                       break;
+               case 'g':
+                       ret = generateKey(optarg);
+                       break;
+               case 'm':
+                       ret = mountEcryptfs("/home/" + std::string(optarg), optarg);
+                       break;
+               default:
+                       std::cerr << "unknown" << std::endl;
+                       usage(argv[0]);
+                       break;
+               }
+       }
+
+       if (ret != 0) {
+               return EXIT_FAILURE;
+       }
+
+       return EXIT_SUCCESS;
+}