Add additional functions related to CC mode 44/28844/1
authoryuseok.jeon <yuseok.jeon@samsung.com>
Fri, 26 Sep 2014 06:36:02 +0000 (15:36 +0900)
committerBartlomiej Grzelewski <b.grzelewski@samsung.com>
Thu, 16 Oct 2014 13:44:30 +0000 (15:44 +0200)
 * to fix issue about providing optional password encryption only when cc mode is off in key-manager
 * check cc mode by registering callback
 * event callback is added in key-manager-listener daemon

Change-Id: I00e84225b3d06e2b2442ec405d02484c767304e5
Signed-off-by: yuseok.jeon <yuseok.jeon@samsung.com>
packaging/key-manager.spec
src/include/ckm/ckm-control.h
src/include/ckm/ckm-type.h
src/listener/CMakeLists.txt
src/listener/listener-daemon.cpp
src/manager/client/client-control.cpp
src/manager/common/protocols.h
src/manager/service/ckm-logic.cpp
src/manager/service/ckm-logic.h
src/manager/service/ckm-service.cpp

index ebc2b12..4f1a59d 100644 (file)
@@ -30,6 +30,7 @@ Central Key Manager and utilities
 %package -n key-manager-listener
 Summary:    Package with listener daemon
 Group:      System/Security
+BuildRequires: pkgconfig(vconf)
 Requires:   libkey-manager-client = %{version}-%{release}
 
 %description -n key-manager-listener
index 17ffaa3..5006dac 100644 (file)
@@ -62,6 +62,8 @@ public:
     // database only. This function may be used during application uninstallation.
     virtual int removeApplicationData(const std::string &smackLabel) = 0;
 
+    virtual int setCCMode(CCModeState mode) = 0;
+
     virtual ~Control(){}
 
     static ControlShPtr create();
index 17a4c39..169978d 100644 (file)
@@ -92,6 +92,11 @@ enum class DBCMAlgType : int {
     COUNT
 };
 
+enum class CCModeState : int {
+    CC_MODE_OFF = 0,
+    CC_MODE_ON
+};
+
 const char * ErrorToString(int error);
 
 } // namespace CKM
index 912eac1..cb91757 100644 (file)
@@ -4,6 +4,7 @@ PKG_CHECK_MODULES(LISTENER_DEP
     glib-2.0
     capi-appfw-package-manager
     libsystemd-daemon
+    vconf
     )
 
 SET(LISTENER_SOURCES ${PROJECT_SOURCE_DIR}/src/listener/listener-daemon.cpp)
index 294612f..af2e6fd 100644 (file)
 #include <glib.h>
 #include <package_manager.h>
 #include <ckm/ckm-control.h>
+#include <ckm/ckm-type.h>
+#include <vconf/vconf.h>
 #include <dlog.h>
 
-#define CKM_TAG "CKM_LISTENER"
+#define CKM_LISTENER_TAG "CKM_LISTENER"
 
-void eventCallback(
-    const char *type,
-    const char *package,
-    package_manager_event_type_e eventType,
-    package_manager_event_state_e eventState,
-    int progress,
-    package_manager_error_e error,
-    void *userData)
-{
-    (void) type;
-    (void) progress;
-    (void) error;
-    (void) userData;
-
-    if (eventType != PACKAGE_MANAGER_EVENT_TYPE_UNINSTALL)
-        return;
-
-    if (eventState != PACKAGE_MANAGER_EVENT_STATE_STARTED)
-        return;
+#ifndef MDPP_MODE_ENFORCING
+#define MDPP_MODE_ENFORCING "Enforcing"
+#endif
 
-    if (package == NULL)
-        return;
+#ifndef MDPP_MODE_ENABLED
+#define MDPP_MODE_ENABLED   "Enabled"
+#endif
 
-    SLOG(LOG_DEBUG, CKM_TAG, "Get callback. Uninstalation of: %s", package);
-    auto control = CKM::Control::create();
-    control->removeApplicationData(std::string(package));
-}
-
-int main(void) {
-    SLOG(LOG_DEBUG, CKM_TAG, "%s", "Start!");
+#ifndef VCONFKEY_SECURITY_MDPP_STATE
+#define VCONFKEY_SECURITY_MDPP_STATE "file/security_mdpp/security_mdpp_state"
+#endif
 
+void daemonize()
+{
     // Let's operate in background
     int result = fork();
     if (result < 0){
-        SLOG(LOG_DEBUG, CKM_TAG, "%s", "Error in fork!");
+        SLOG(LOG_ERROR, CKM_LISTENER_TAG, "%s", "Error in fork!");
         exit(1);
     }
 
@@ -59,13 +44,13 @@ int main(void) {
 
     // Let's disconnect from terminal
     if (-1 == setsid()) {
-        SLOG(LOG_DEBUG, CKM_TAG, "%s", "Error in fork!");
+        SLOG(LOG_ERROR, CKM_LISTENER_TAG, "%s", "Error in fork!");
         exit(1);
     }
 
     // Let's close all descriptors
 //    for (result = getdtablesize(); result>=0; --result)
-//        close(result);
+//    close(result);
 
     close(0);
     close(1);
@@ -77,27 +62,27 @@ int main(void) {
     int fd_stderr = 0;
     fd_stdout = dup(result); // stdout
     fd_stderr = dup(result); // stderr
-    SLOG(LOG_DEBUG, CKM_TAG, "%d : %s", fd_stdout, "stdout file descriptor");
-    SLOG(LOG_DEBUG, CKM_TAG, "%d : %s", fd_stderr, "stderr file descriptor");
+    SLOG(LOG_DEBUG, CKM_LISTENER_TAG, "%d : %s", fd_stdout, "stdout file descriptor");
+    SLOG(LOG_DEBUG, CKM_LISTENER_TAG, "%d : %s", fd_stderr, "stderr file descriptor");
 
 
     umask(027);
 
     // Let's change current directory
     if (-1 == chdir("/")) {
-        SLOG(LOG_DEBUG, CKM_TAG, "%s", "Error in chdir!");
+        SLOG(LOG_ERROR, CKM_LISTENER_TAG, "%s", "Error in chdir!");
         exit(1);
     }
 
     // Let's create lock file
     result = open("/tmp/ckm-listener.lock", O_RDWR | O_CREAT, 0640);
     if (result < 0) {
-        SLOG(LOG_DEBUG, CKM_TAG, "%s", "Error in opening lock file!");
+        SLOG(LOG_ERROR, CKM_LISTENER_TAG, "%s", "Error in opening lock file!");
         exit(1);
     }
 
     if (lockf(result, F_TLOCK, 0) < 0) {
-        SLOG(LOG_DEBUG, CKM_TAG, "%s", "Daemon already working!");
+        SLOG(LOG_ERROR, CKM_LISTENER_TAG, "%s", "Daemon already working!");
         exit(0);
     }
 
@@ -105,21 +90,106 @@ int main(void) {
     sprintf(str, "%d\n", getpid());
     result = write(result, str, strlen(str));
 
-    SLOG(LOG_DEBUG, CKM_TAG, "%s", str);
+    SLOG(LOG_DEBUG, CKM_LISTENER_TAG, "%s", str);
+}
+
+void callSetCCMode(const char *mdpp_state)
+{
+    auto control = CKM::Control::create();
+    int ret = CKM_API_SUCCESS;
+    if ( !strcmp(mdpp_state, MDPP_MODE_ENABLED) ||
+            !strcmp(mdpp_state, MDPP_MODE_ENFORCING) )
+        ret = control->setCCMode(CKM::CCModeState::CC_MODE_ON);
+    else
+        ret = control->setCCMode(CKM::CCModeState::CC_MODE_OFF);
+
+    SLOG(LOG_DEBUG, CKM_LISTENER_TAG, "Callback caller process id : %d\n", getpid());
+
+    if ( ret != CKM_API_SUCCESS )
+        SLOG(LOG_ERROR, CKM_LISTENER_TAG, "CKM::Control::setCCMode error. ret : %d\n", ret);
+    else
+        SLOG(LOG_DEBUG, CKM_LISTENER_TAG, "CKM::Control::setCCMode success. mdpp_state : %s", mdpp_state);
+}
+
+void packageUninstalledEventCallback(
+    const char *type,
+    const char *package,
+    package_manager_event_type_e eventType,
+    package_manager_event_state_e eventState,
+    int progress,
+    package_manager_error_e error,
+    void *userData)
+{
+    (void) type;
+    (void) progress;
+    (void) error;
+    (void) userData;
+
+    if (eventType != PACKAGE_MANAGER_EVENT_TYPE_UNINSTALL ||
+            eventState != PACKAGE_MANAGER_EVENT_STATE_STARTED ||
+            package == NULL) {
+        SLOG(LOG_DEBUG, CKM_LISTENER_TAG, "PackageUninstalled Callback error of Invalid Param");
+    }
+    else {
+        SLOG(LOG_DEBUG, CKM_LISTENER_TAG, "PackageUninstalled Callback. Uninstalation of: %s", package);
+        auto control = CKM::Control::create();
+        int ret = 0;
+        if ( CKM_API_SUCCESS != (ret = control->removeApplicationData(std::string(package))) ) {
+            SLOG(LOG_ERROR, CKM_LISTENER_TAG, "CKM::Control::removeApplicationData error. ret : %d\n", ret);
+        }
+        else {
+            SLOG(LOG_DEBUG, CKM_LISTENER_TAG,
+                "CKM::Control::removeApplicationData success. Uninstallation package : %s\n", package);
+        }
+    }
+}
+
+void ccModeChangedEventCallback(
+    keynode_t *key,
+    void *userData)
+{
+    (void) key;
+    (void) userData;
+
+    char *mdpp_state = vconf_get_str(VCONFKEY_SECURITY_MDPP_STATE);
+    callSetCCMode(mdpp_state);
+}
+
+int main(void) {
+    SLOG(LOG_DEBUG, CKM_LISTENER_TAG, "%s", "Start!");
+
+    daemonize();
 
     // Let's start to listen
     GMainLoop *main_loop = g_main_loop_new(NULL, FALSE);
-    package_manager_h request;
 
+    package_manager_h request;
     package_manager_create(&request);
-    if (0 != package_manager_set_event_cb(request, eventCallback, NULL)) {
-        SLOG(LOG_DEBUG, CKM_TAG, "%s", "Error in package_manager_set_event_cb");
+
+    SLOG(LOG_DEBUG, CKM_LISTENER_TAG, "register uninstalledApp event callback start");
+    if (0 != package_manager_set_event_cb(request, packageUninstalledEventCallback, NULL)) {
+        SLOG(LOG_ERROR, CKM_LISTENER_TAG, "%s", "Error in package_manager_set_event_cb");
         exit(-1);
     }
+    SLOG(LOG_DEBUG, CKM_LISTENER_TAG, "register uninstalledApp event callback success");
+
+    int ret = 0;
+    char *mdpp_state = vconf_get_str(VCONFKEY_SECURITY_MDPP_STATE);
+    if ( mdpp_state ) { // set CC mode and register event callback only when mdpp vconf key exists
+        callSetCCMode(mdpp_state);
+
+        SLOG(LOG_DEBUG, CKM_LISTENER_TAG, "register vconfCCModeChanged event callback start");
+        if ( 0 != (ret = vconf_notify_key_changed(VCONFKEY_SECURITY_MDPP_STATE, ccModeChangedEventCallback, NULL)) ) {
+            SLOG(LOG_ERROR, CKM_LISTENER_TAG, "Error in vconf_notify_key_changed. ret : %d", ret);
+            exit(-1);
+        }
+        SLOG(LOG_DEBUG, CKM_LISTENER_TAG, "register vconfCCModeChanged event callback success");
+    }
+    else
+        SLOG(LOG_DEBUG, CKM_LISTENER_TAG,
+            "vconfCCModeChanged event callback is not registered. No vconf key exists : %s", VCONFKEY_SECURITY_MDPP_STATE);
 
-    /* Change file mode mask */
-
-    SLOG(LOG_DEBUG, CKM_TAG, "%s", "Ready to listen!");
+    SLOG(LOG_DEBUG, CKM_LISTENER_TAG, "%s", "Ready to listen!");
     g_main_loop_run(main_loop);
     return 0;
 }
index 7c2b927..3048fad 100644 (file)
@@ -192,6 +192,31 @@ public:
         });
     }
 
+    virtual int setCCMode(CCModeState mode) {
+        return try_catch([&] {
+            if(((mode != CCModeState::CC_MODE_OFF)) && (mode != CCModeState::CC_MODE_ON)) {
+                return CKM_API_ERROR_INPUT_PARAM;
+            }
+
+            MessageBuffer send, recv;
+            Serialization::Serialize(send, static_cast<int>(ControlCommand::SET_CC_MODE));
+            Serialization::Serialize(send, static_cast<int>(mode));
+
+            int retCode = sendToServer(
+                SERVICE_SOCKET_CKM_CONTROL,
+                send.Pop(),
+                recv);
+
+            if (CKM_API_SUCCESS != retCode) {
+                return retCode;
+            }
+
+            Deserialization::Deserialize(recv, retCode);
+
+            return retCode;
+        });
+    }
+
     virtual ~ControlImpl(){}
 };
 
index a3cf3ad..2755322 100644 (file)
@@ -39,7 +39,8 @@ enum class ControlCommand : int {
     REMOVE_USER_DATA,
     CHANGE_USER_PASSWORD,
     RESET_USER_PASSWORD,
-    REMOVE_APP_DATA
+    REMOVE_APP_DATA,
+    SET_CC_MODE
 };
 
 enum class LogicCommand : int {
index 9c60b0e..17053bb 100644 (file)
@@ -46,6 +46,8 @@ CKMLogic::CKMLogic()
     if (CKM_API_SUCCESS != m_certStore.setSystemCertificateDir(CERT_SYSTEM_DIR)) {
         LogError("Fatal error in CertificateStore::setSystemCertificateDir. Chain creation will not work");
     }
+
+    cc_mode_status = CCModeState::CC_MODE_OFF;
 }
 
 CKMLogic::~CKMLogic(){}
@@ -111,6 +113,21 @@ RawBuffer CKMLogic::unlockUserKey(uid_t user, const Password &password) {
     return response.Pop();
 }
 
+RawBuffer CKMLogic::setCCModeStatus(CCModeState mode_status) {
+
+    int retCode = CKM_API_SUCCESS;
+
+    if((mode_status != CCModeState:: CC_MODE_OFF) && (mode_status != CCModeState:: CC_MODE_ON)) {
+        retCode = CKM_API_ERROR_INPUT_PARAM;
+    }
+
+    cc_mode_status = mode_status;
+
+    MessageBuffer response;
+    Serialization::Serialize(response, retCode);
+    return response.Pop();
+}
+
 RawBuffer CKMLogic::lockUserKey(uid_t user) {
     int retCode = CKM_API_SUCCESS;
     // TODO try catch for all errors that should be supported by error code
@@ -249,7 +266,14 @@ int CKMLogic::saveDataHelper(
         key = handler.keyProvider.getPureDEK(key);
         handler.crypto.pushKey(cred.smackLabel, key);
     }
-    handler.crypto.encryptRow(policy.password, row);
+
+    // Do not encrypt data with password during cc_mode on
+    if(cc_mode_status == CCModeState::CC_MODE_ON) {
+        handler.crypto.encryptRow("", row);
+    } else {
+        handler.crypto.encryptRow(policy.password, row);
+    }
+
     handler.database.saveDBRow(row);
     transaction.commit();
     return CKM_API_SUCCESS;
@@ -406,6 +430,12 @@ RawBuffer CKMLogic::getData(
         retCode = CKM_API_ERROR_NOT_EXPORTABLE;
     }
 
+    // Prevent extracting private keys during cc-mode on
+    if((cc_mode_status == CCModeState::CC_MODE_ON) && (row.dataType == DBDataType::KEY_RSA_PRIVATE || row.dataType == DBDataType::KEY_ECDSA_PRIVATE ||  row.dataType == DBDataType::KEY_DSA_PRIVATE)) {
+        row.data.clear();
+        retCode = CKM_API_ERROR_BAD_REQUEST;
+    }
+
     MessageBuffer response;
     Serialization::Serialize(response, static_cast<int>(LogicCommand::GET));
     Serialization::Serialize(response, commandId);
index e089d16..b57243c 100644 (file)
@@ -134,6 +134,8 @@ public:
         const HashAlgorithm hash,
         const RSAPaddingAlgorithm padding);
 
+    RawBuffer setCCModeStatus(CCModeState mode_status);
+
 private:
 
     int saveDataHelper(
@@ -167,6 +169,7 @@ private:
 
     std::map<uid_t, UserData> m_userDataMap;
     CertificateStore m_certStore;
+    CCModeState cc_mode_status;
 };
 
 } // namespace CKM
index b60d185..b64c344 100644 (file)
@@ -107,6 +107,7 @@ bool CKMService::processOne(
 
 RawBuffer CKMService::processControl(MessageBuffer &buffer) {
     int command;
+    int cc_mode_status;
     uid_t user;
     ControlCommand cc;
     Password newPass, oldPass;
@@ -141,6 +142,9 @@ RawBuffer CKMService::processControl(MessageBuffer &buffer) {
     case ControlCommand::REMOVE_APP_DATA:
         Deserialization::Deserialize(buffer, smackLabel);
         return m_logic->removeApplicationData(smackLabel);
+    case ControlCommand::SET_CC_MODE:
+        Deserialization::Deserialize(buffer, cc_mode_status);
+        return m_logic->setCCModeStatus(static_cast<CCModeState>(cc_mode_status));
     default:
         Throw(Exception::BrokenProtocol);
     }