Add additional functions related to CC mode
[platform/core/security/key-manager.git] / src / listener / listener-daemon.cpp
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <fcntl.h>
4 #include <errno.h>
5 #include <unistd.h>
6 #include <syslog.h>
7 #include <string.h>
8 #include <sys/types.h>
9 #include <sys/stat.h>
10 #include <systemd/sd-daemon.h>
11
12 #include <glib.h>
13 #include <package_manager.h>
14 #include <ckm/ckm-control.h>
15 #include <ckm/ckm-type.h>
16 #include <vconf/vconf.h>
17 #include <dlog.h>
18
19 #define CKM_LISTENER_TAG "CKM_LISTENER"
20
21 #ifndef MDPP_MODE_ENFORCING
22 #define MDPP_MODE_ENFORCING "Enforcing"
23 #endif
24
25 #ifndef MDPP_MODE_ENABLED
26 #define MDPP_MODE_ENABLED   "Enabled"
27 #endif
28
29 #ifndef VCONFKEY_SECURITY_MDPP_STATE
30 #define VCONFKEY_SECURITY_MDPP_STATE "file/security_mdpp/security_mdpp_state"
31 #endif
32
33 void daemonize()
34 {
35     // Let's operate in background
36     int result = fork();
37     if (result < 0){
38         SLOG(LOG_ERROR, CKM_LISTENER_TAG, "%s", "Error in fork!");
39         exit(1);
40     }
41
42     if (result > 0)
43         exit(0);
44
45     // Let's disconnect from terminal
46     if (-1 == setsid()) {
47         SLOG(LOG_ERROR, CKM_LISTENER_TAG, "%s", "Error in fork!");
48         exit(1);
49     }
50
51     // Let's close all descriptors
52 //    for (result = getdtablesize(); result>=0; --result)
53 //    close(result);
54
55     close(0);
56     close(1);
57     close(2);
58
59     result = open("/dev/null", O_RDWR); // open stdin
60
61     int fd_stdout = 0;
62     int fd_stderr = 0;
63     fd_stdout = dup(result); // stdout
64     fd_stderr = dup(result); // stderr
65     SLOG(LOG_DEBUG, CKM_LISTENER_TAG, "%d : %s", fd_stdout, "stdout file descriptor");
66     SLOG(LOG_DEBUG, CKM_LISTENER_TAG, "%d : %s", fd_stderr, "stderr file descriptor");
67
68
69     umask(027);
70
71     // Let's change current directory
72     if (-1 == chdir("/")) {
73         SLOG(LOG_ERROR, CKM_LISTENER_TAG, "%s", "Error in chdir!");
74         exit(1);
75     }
76
77     // Let's create lock file
78     result = open("/tmp/ckm-listener.lock", O_RDWR | O_CREAT, 0640);
79     if (result < 0) {
80         SLOG(LOG_ERROR, CKM_LISTENER_TAG, "%s", "Error in opening lock file!");
81         exit(1);
82     }
83
84     if (lockf(result, F_TLOCK, 0) < 0) {
85         SLOG(LOG_ERROR, CKM_LISTENER_TAG, "%s", "Daemon already working!");
86         exit(0);
87     }
88
89     char str[100];
90     sprintf(str, "%d\n", getpid());
91     result = write(result, str, strlen(str));
92
93     SLOG(LOG_DEBUG, CKM_LISTENER_TAG, "%s", str);
94 }
95
96 void callSetCCMode(const char *mdpp_state)
97 {
98     auto control = CKM::Control::create();
99     int ret = CKM_API_SUCCESS;
100     if ( !strcmp(mdpp_state, MDPP_MODE_ENABLED) ||
101             !strcmp(mdpp_state, MDPP_MODE_ENFORCING) )
102         ret = control->setCCMode(CKM::CCModeState::CC_MODE_ON);
103     else
104         ret = control->setCCMode(CKM::CCModeState::CC_MODE_OFF);
105
106     SLOG(LOG_DEBUG, CKM_LISTENER_TAG, "Callback caller process id : %d\n", getpid());
107
108     if ( ret != CKM_API_SUCCESS )
109         SLOG(LOG_ERROR, CKM_LISTENER_TAG, "CKM::Control::setCCMode error. ret : %d\n", ret);
110     else
111         SLOG(LOG_DEBUG, CKM_LISTENER_TAG, "CKM::Control::setCCMode success. mdpp_state : %s", mdpp_state);
112 }
113
114 void packageUninstalledEventCallback(
115     const char *type,
116     const char *package,
117     package_manager_event_type_e eventType,
118     package_manager_event_state_e eventState,
119     int progress,
120     package_manager_error_e error,
121     void *userData)
122 {
123     (void) type;
124     (void) progress;
125     (void) error;
126     (void) userData;
127
128     if (eventType != PACKAGE_MANAGER_EVENT_TYPE_UNINSTALL ||
129             eventState != PACKAGE_MANAGER_EVENT_STATE_STARTED ||
130             package == NULL) {
131         SLOG(LOG_DEBUG, CKM_LISTENER_TAG, "PackageUninstalled Callback error of Invalid Param");
132     }
133     else {
134         SLOG(LOG_DEBUG, CKM_LISTENER_TAG, "PackageUninstalled Callback. Uninstalation of: %s", package);
135         auto control = CKM::Control::create();
136         int ret = 0;
137         if ( CKM_API_SUCCESS != (ret = control->removeApplicationData(std::string(package))) ) {
138             SLOG(LOG_ERROR, CKM_LISTENER_TAG, "CKM::Control::removeApplicationData error. ret : %d\n", ret);
139         }
140         else {
141             SLOG(LOG_DEBUG, CKM_LISTENER_TAG,
142                 "CKM::Control::removeApplicationData success. Uninstallation package : %s\n", package);
143         }
144     }
145 }
146
147 void ccModeChangedEventCallback(
148     keynode_t *key,
149     void *userData)
150 {
151     (void) key;
152     (void) userData;
153
154     char *mdpp_state = vconf_get_str(VCONFKEY_SECURITY_MDPP_STATE);
155     callSetCCMode(mdpp_state);
156 }
157
158 int main(void) {
159     SLOG(LOG_DEBUG, CKM_LISTENER_TAG, "%s", "Start!");
160
161     daemonize();
162
163     // Let's start to listen
164     GMainLoop *main_loop = g_main_loop_new(NULL, FALSE);
165
166     package_manager_h request;
167     package_manager_create(&request);
168
169     SLOG(LOG_DEBUG, CKM_LISTENER_TAG, "register uninstalledApp event callback start");
170     if (0 != package_manager_set_event_cb(request, packageUninstalledEventCallback, NULL)) {
171         SLOG(LOG_ERROR, CKM_LISTENER_TAG, "%s", "Error in package_manager_set_event_cb");
172         exit(-1);
173     }
174     SLOG(LOG_DEBUG, CKM_LISTENER_TAG, "register uninstalledApp event callback success");
175
176     int ret = 0;
177     char *mdpp_state = vconf_get_str(VCONFKEY_SECURITY_MDPP_STATE);
178     if ( mdpp_state ) { // set CC mode and register event callback only when mdpp vconf key exists
179         callSetCCMode(mdpp_state);
180
181         SLOG(LOG_DEBUG, CKM_LISTENER_TAG, "register vconfCCModeChanged event callback start");
182         if ( 0 != (ret = vconf_notify_key_changed(VCONFKEY_SECURITY_MDPP_STATE, ccModeChangedEventCallback, NULL)) ) {
183             SLOG(LOG_ERROR, CKM_LISTENER_TAG, "Error in vconf_notify_key_changed. ret : %d", ret);
184             exit(-1);
185         }
186         SLOG(LOG_DEBUG, CKM_LISTENER_TAG, "register vconfCCModeChanged event callback success");
187     }
188     else
189         SLOG(LOG_DEBUG, CKM_LISTENER_TAG,
190             "vconfCCModeChanged event callback is not registered. No vconf key exists : %s", VCONFKEY_SECURITY_MDPP_STATE);
191
192     SLOG(LOG_DEBUG, CKM_LISTENER_TAG, "%s", "Ready to listen!");
193     g_main_loop_run(main_loop);
194     return 0;
195 }
196