Lock file operations fixed in listener
[platform/core/security/key-manager.git] / src / listener / listener-daemon.cpp
index af2e6fd..e283269 100644 (file)
 
 #define CKM_LISTENER_TAG "CKM_LISTENER"
 
-#ifndef MDPP_MODE_ENFORCING
-#define MDPP_MODE_ENFORCING "Enforcing"
-#endif
-
-#ifndef MDPP_MODE_ENABLED
-#define MDPP_MODE_ENABLED   "Enabled"
-#endif
-
 #ifndef VCONFKEY_SECURITY_MDPP_STATE
 #define VCONFKEY_SECURITY_MDPP_STATE "file/security_mdpp/security_mdpp_state"
 #endif
 
+namespace {
+const char* const CKM_LOCK = "/var/run/key-manager.pid";
+const char* const LISTENER_LOCK = "/var/run/key-manager-listener.pid";
+};
+
 void daemonize()
 {
     // Let's operate in background
+    int fd;
     int result = fork();
     if (result < 0){
         SLOG(LOG_ERROR, CKM_LISTENER_TAG, "%s", "Error in fork!");
@@ -70,45 +68,62 @@ void daemonize()
 
     // Let's change current directory
     if (-1 == chdir("/")) {
-        SLOG(LOG_ERROR, CKM_LISTENER_TAG, "%s", "Error in chdir!");
+        SLOG(LOG_ERROR, CKM_LISTENER_TAG, "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_ERROR, CKM_LISTENER_TAG, "%s", "Error in opening lock file!");
+    fd = TEMP_FAILURE_RETRY(creat(LISTENER_LOCK, 0640));
+    if (fd < 0) {
+        SLOG(LOG_ERROR, CKM_LISTENER_TAG, "Error in opening lock file!");
         exit(1);
     }
 
-    if (lockf(result, F_TLOCK, 0) < 0) {
-        SLOG(LOG_ERROR, CKM_LISTENER_TAG, "%s", "Daemon already working!");
-        exit(0);
+    if (lockf(fd, F_TLOCK, 0) < 0) {
+        if (errno == EACCES || errno == EAGAIN) {
+            SLOG(LOG_ERROR, CKM_LISTENER_TAG, "Daemon already working!");
+            exit(0);
+        }
+        SLOG(LOG_ERROR, CKM_LISTENER_TAG, "lockf failed with error: %s" , strerror(errno));
+        exit(1);
     }
 
-    char str[100];
-    sprintf(str, "%d\n", getpid());
-    result = write(result, str, strlen(str));
+    std::string pid = std::to_string(getpid());
+    if (TEMP_FAILURE_RETRY(write(fd, pid.c_str(), pid.size())) <= 0) {
+        SLOG(LOG_ERROR, CKM_LISTENER_TAG, "Failed to write lock file. Error: %s", strerror(errno));
+        exit(1);
+    }
 
-    SLOG(LOG_DEBUG, CKM_LISTENER_TAG, "%s", str);
+    SLOG(LOG_DEBUG, CKM_LISTENER_TAG, "%s", pid.c_str());
 }
 
-void callSetCCMode(const char *mdpp_state)
+bool isCkmRunning()
 {
+    int lock = TEMP_FAILURE_RETRY(open(CKM_LOCK, O_RDWR));
+    if (lock == -1)
+        return false;
+
+    int ret = lockf(lock, F_TEST, 0);
+    close(lock);
+
+    // if lock test fails because of an error assume ckm is running
+    return (0 != ret);
+}
+
+void callUpdateCCMode()
+{
+    if(!isCkmRunning())
+        return;
+
     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);
+    int ret = control->updateCCMode();
 
     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);
+        SLOG(LOG_ERROR, CKM_LISTENER_TAG, "CKM::Control::updateCCMode error. ret : %d\n", ret);
     else
-        SLOG(LOG_DEBUG, CKM_LISTENER_TAG, "CKM::Control::setCCMode success. mdpp_state : %s", mdpp_state);
+        SLOG(LOG_DEBUG, CKM_LISTENER_TAG, "CKM::Control::updateCCMode success.\n");
 }
 
 void packageUninstalledEventCallback(
@@ -144,15 +159,9 @@ void packageUninstalledEventCallback(
     }
 }
 
-void ccModeChangedEventCallback(
-    keynode_t *key,
-    void *userData)
+void ccModeChangedEventCallback(keynode_t*, void*)
 {
-    (void) key;
-    (void) userData;
-
-    char *mdpp_state = vconf_get_str(VCONFKEY_SECURITY_MDPP_STATE);
-    callSetCCMode(mdpp_state);
+    callUpdateCCMode();
 }
 
 int main(void) {
@@ -175,8 +184,8 @@ int main(void) {
 
     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);
+    if ( mdpp_state ) { // Update cc mode and register event callback only when mdpp vconf key exists
+        callUpdateCCMode();
 
         SLOG(LOG_DEBUG, CKM_LISTENER_TAG, "register vconfCCModeChanged event callback start");
         if ( 0 != (ret = vconf_notify_key_changed(VCONFKEY_SECURITY_MDPP_STATE, ccModeChangedEventCallback, NULL)) ) {