tizen 2.3.1 release
[framework/security/secure-storage.git] / server / non-tz / src / ss_server_ipc.c
1 /*
2  * secure storage
3  *
4  * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved 
5  *
6  * Contact: Kidong Kim <kd0228.kim@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <signal.h>
26 #include <unistd.h>
27 #include <sys/un.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <sys/socket.h>
31 #include <errno.h>
32 #include <dirent.h>
33 #include <sys/ioctl.h>
34 #include <fcntl.h>
35 #include <systemd/sd-daemon.h>
36 #include <pthread.h>
37 #include <vconf.h>
38 #include <glib.h>
39 #include <dlfcn.h>
40
41 #include "secure_storage.h"
42 #include "ss_server_ipc.h"
43 #include "ss_server_main.h"
44
45 #define CONF_FILE_PATH  "/usr/share/secure-storage/config"
46 #define KEY_SIZE 16
47 #define VCONF_SMACK_UPDATE_FILE_PATH_KEY_NODE "db/smack/spd_policy_filepath"
48 #define VCONF_UPDATE_RESULT_KEY_NODE "db/smack/spd_update_result"
49 #define VCONF_UPDATE_RESULT_KEY_NODE_FOR_APP "db/smack/spd_update_result2"
50
51 static GMainLoop *event_loop;
52
53 char* get_key_file_path()
54 {
55         FILE* fp_conf = NULL;
56         char buf[128];
57         char* retbuf = NULL;
58         char seps[] = " :\n\r\t";
59         char* token = NULL;
60
61         retbuf = (char*)malloc(sizeof(char) * 128);
62         if(!retbuf)
63         {
64                 SLOGE("fail to allocate memory.\n");
65                 return NULL;
66         }
67         memset(buf, 0x00, 128);
68         memset(retbuf, 0x00, 128);
69
70         if(!(fp_conf = fopen(CONF_FILE_PATH, "r")))
71         {
72                 SLOGE("Configuration file is not exist\n");
73                 free(retbuf);
74                 return NULL;
75         }
76         
77         while(fgets(buf, 128, fp_conf))
78         {
79                 token = strtok(buf, seps);
80                 if(token != NULL)
81                 {
82                         if(!strncmp(token, "MASTER_KEY_PATH", 15))      // master key path
83                         {
84                                 token = strtok(NULL, seps);     // real path
85                                 break;
86                         }
87                 }
88                 token = NULL;
89         }
90         fclose(fp_conf);
91
92         if(token)
93                 strncpy(retbuf, token, 127);
94         else {
95                 if(retbuf != NULL)
96                         free(retbuf);
97                 return NULL;
98         }
99
100         return retbuf;
101 }
102
103 int check_key_file()
104 {
105         FILE* fp_key = NULL;
106         char* key_path = NULL;
107
108         key_path = get_key_file_path();
109         if(key_path == NULL)
110         {
111                 SLOGE("Configuration file is not exist\n");
112                 return 0;
113         }
114
115         if(!(fp_key = fopen(key_path, "r")))
116         {
117                 SLOGE("Secret key file is not exist, [%s]\n", key_path);
118                 free(key_path);
119                 return 0;
120         }
121
122         free(key_path);
123         fclose(fp_key);
124         return 1;
125 }
126
127 int make_key_file()
128 {
129         FILE* fp_key = NULL;
130         int random_dev = -1;
131         int i = 0;
132         char tmp_key[1];
133         char key[33];
134         char* key_path = NULL;
135         int read_len = 0;
136
137         memset(key, 0x00, 33);
138
139         key_path = get_key_file_path();
140         if(key_path == NULL)
141         {
142                 SLOGE("Configuration file is not exist\n");
143                 return 0;
144         }
145
146         if((random_dev = open("/dev/urandom", O_RDONLY)) < 0)
147         {
148                 SLOGE("Random device Open error\n");
149                 free(key_path);
150                 return 0;
151         }
152
153         while(i < 32)
154         {
155                 read_len = read(random_dev, tmp_key, 1);
156                 if(read_len < 0)
157                 {
158                         SLOGE("read error from random file");
159                         break;
160                 }
161
162                 if((tmp_key[0] >= '!') && (tmp_key[0] <= '~')) {
163                         key[i] = tmp_key[0];
164                         i++;
165                 }
166         }
167
168         if(!(fp_key = fopen(key_path, "w")))
169         {
170                 SECURE_SLOGE("Secret key file Open error, [%s]\n", key_path);
171                 free(key_path);
172                 close(random_dev);
173                 return 0;
174         }
175
176         fprintf(fp_key, "%s", key);
177
178         if(chmod(key_path, 0600)!=0)
179         {
180                 SLOGE("Secret key file chmod error, [%s]\n", strerror(errno));
181                 free(key_path);
182                 close(random_dev);
183                 fclose(fp_key);
184                 return 0;
185         }
186         
187         free(key_path);
188         fclose(fp_key);
189         close(random_dev);
190         return 1;
191 }
192
193 /* for executing coverage tool (2009-04-03) */
194 void SigHandler(int signo)
195 {
196         SLOGI("Got Signal %d\n", signo);
197         exit(1);
198 }
199 /* end */
200
201
202 int GetSocketFromSystemd(int* pSockfd)
203 {
204     int n = sd_listen_fds(0);
205     int fd;
206
207         for(fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START+n; ++fd) {
208                 if (0 < sd_is_socket_unix(fd, SOCK_STREAM, 1,
209                                                                   SS_SOCK_PATH, 0))
210                 {
211                         *pSockfd = fd;
212                         return 1;
213                 }
214         }
215         return 0;
216 }
217
218 int CreateNewSocket(int* pSockfd)
219 {
220         int server_sockfd = 0;
221         int temp_len_sock = 0;
222         struct sockaddr_un serveraddr;
223
224         if((server_sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
225         {
226                 SLOGE("Error in function socket()..\n");
227                 return 0;
228         }
229
230         temp_len_sock = strlen(SS_SOCK_PATH);
231         
232         bzero(&serveraddr, sizeof(serveraddr));
233         serveraddr.sun_family = AF_UNIX;
234         strncpy(serveraddr.sun_path, SS_SOCK_PATH, temp_len_sock);
235         serveraddr.sun_path[temp_len_sock] = '\0';
236
237         if((bind(server_sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr))) < 0)
238         {
239                 unlink("/tmp/SsSocket");
240                 if((bind(server_sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr))) < 0)
241                 {
242                         SLOGE("Error in function bind()..\n");
243                         close(server_sockfd);
244                         return 0;       // ipc error
245                 }
246         }
247
248         if(chmod(SS_SOCK_PATH, S_IRWXU | S_IRWXG | S_IRWXO) != 0)
249         {
250                 close(server_sockfd);
251                 return 0;
252         }
253
254         *pSockfd = server_sockfd;
255         return 1;
256 }
257
258
259 void SsServerComm(void)
260 {
261         int server_sockfd, client_sockfd;
262         int client_len;
263         struct sockaddr_un clientaddr, serveraddr;
264
265         struct ucred cr;        // for test client pid. 2009-03-24
266         int cl = sizeof(cr);    //
267         int temp_len_sock = 0;
268         int temp_len_in = 0;
269
270         ReqData_t recv_data = {0, };
271         RspData_t send_data = {0, };
272
273
274         server_sockfd = client_sockfd = -1;
275
276         if(!GetSocketFromSystemd(&server_sockfd))
277         {
278                 SLOGE("Failed to get sockfd from systemd");
279                 if(!CreateNewSocket(&server_sockfd))
280                 {
281                         SLOGE("Failed to create socket");
282                         send_data.rsp_type = SS_SOCKET_ERROR;   // ipc error
283                         goto Error_exit;
284                 }
285                 if((listen(server_sockfd, 5)) < 0)
286                 {
287                         SLOGE("Error in function listen()..\n");
288                         send_data.rsp_type = SS_SOCKET_ERROR;   // ipc error
289                         goto Error_close_exit;
290                 }
291         }
292         else
293         {
294                 SLOGD("Get socket from systemd");
295         }
296
297         client_len = sizeof(clientaddr);
298
299         signal(SIGINT, (void*)SigHandler);
300         
301         while(1) 
302         {
303                 errno = 0;
304                 
305                 if((client_sockfd = accept(server_sockfd, (struct sockaddr*)&clientaddr, (socklen_t*)&client_len)) < 0)
306                 {
307                         SLOGE("Error in function accept()..[%d, %d]\n", client_sockfd, errno);
308                         send_data.rsp_type = SS_SOCKET_ERROR;   // ipc error
309                         goto Error_close_exit;
310                 }
311                 
312                 // for test client pid. 2009-03-24
313                 if(getsockopt(client_sockfd, SOL_SOCKET, SO_PEERCRED, &cr, (socklen_t*)&cl) != 0)
314                 {
315                         SLOGE("getsockopt() fail\n");
316                 }
317                 // end
318                 
319                 if(read(client_sockfd, (char*)&recv_data, sizeof(recv_data)) < 0)
320                 {
321                         SLOGE("Error in function read()..\n");
322                         send_data.rsp_type = SS_SOCKET_ERROR;   // ipc error
323                         goto Error_close_exit;
324                 }
325
326                 temp_len_in = strlen(recv_data.data_infilepath);
327
328                 switch(recv_data.req_type)
329                 {
330                         case 1:
331                                 send_data.rsp_type = SsServerDataStoreFromFile(cr.pid, recv_data.data_infilepath, recv_data.flag, client_sockfd, recv_data.group_id);
332
333                                 if(send_data.rsp_type == 1)
334                                 {
335                                         strncpy(send_data.data_filepath, recv_data.data_infilepath, MAX_FILENAME_SIZE);
336                                         send_data.data_filepath[temp_len_in] = '\0';
337                                 }
338                                 else
339                                 {
340                                         strncpy(send_data.data_filepath, "Error Occured..", MAX_FILENAME_SIZE);
341                                         send_data.data_filepath[15] = '\0';
342                                 }
343
344                                 write(client_sockfd, (char*)&send_data, sizeof(send_data));
345                                 break;
346                         case 2:
347                                 send_data.rsp_type = SsServerDataStoreFromBuffer(cr.pid, recv_data.buffer, recv_data.count, recv_data.data_infilepath, recv_data.flag, client_sockfd, recv_data.group_id);
348
349                                 if(send_data.rsp_type == 1)
350                                 {
351                                         strncpy(send_data.data_filepath, recv_data.data_infilepath, MAX_FILENAME_SIZE);
352                                         send_data.data_filepath[temp_len_in] = '\0';
353                                 }
354                                 else
355                                 {
356                                         strncpy(send_data.data_filepath, "Error Occured..", MAX_FILENAME_SIZE);
357                                         send_data.data_filepath[15] = '\0';
358                                 }
359
360                                 write(client_sockfd, (char*)&send_data, sizeof(send_data));
361                                 break;
362                         case 3:
363                                 send_data.rsp_type = SsServerDataRead(cr.pid, recv_data.data_infilepath, send_data.buffer, recv_data.count, &(send_data.readLen), recv_data.flag, client_sockfd, recv_data.group_id);
364
365                                 if(send_data.rsp_type == 1)
366                                 {
367                                         strncpy(send_data.data_filepath, recv_data.data_infilepath, MAX_FILENAME_SIZE);
368                                         send_data.data_filepath[temp_len_in] = '\0';
369                                 }
370                                 else
371                                 {
372                                         strncpy(send_data.data_filepath, "Error Occured..", MAX_FILENAME_SIZE);
373                                         send_data.data_filepath[15] = '\0';
374                                 }
375
376                                 write(client_sockfd, (char*)&send_data, sizeof(send_data));
377                                 break;
378                         case 4:
379                                 send_data.rsp_type = SsServerGetInfo(cr.pid, recv_data.data_infilepath, send_data.buffer, recv_data.flag, client_sockfd /*recv_data.cookie*/, recv_data.group_id);
380
381                                 if(send_data.rsp_type == 1)
382                                 {
383                                         strncpy(send_data.data_filepath, recv_data.data_infilepath, MAX_FILENAME_SIZE);
384                                         send_data.data_filepath[temp_len_in] = '\0';
385                                 }
386                                 else
387                                 {
388                                         strncpy(send_data.data_filepath, "Error Occured..", MAX_FILENAME_SIZE);
389                                         send_data.data_filepath[15] = '\0';
390                                 }
391
392                                 write(client_sockfd, (char*)&send_data, sizeof(send_data));
393                                 break;                  
394                         case 5:
395                                 send_data.rsp_type = SsServerGetDuk(client_sockfd, send_data.buffer, &(send_data.readLen), recv_data.group_id, recv_data.flag);
396                                 write(client_sockfd, (char*)&send_data, sizeof(send_data));
397                                 break;
398                         case 10:
399                                 send_data.rsp_type = SsServerDeleteFile(cr.pid, recv_data.data_infilepath, recv_data.flag, client_sockfd, recv_data.group_id);
400                                 
401                                 if(send_data.rsp_type == 1)
402                                 {
403                                         strncpy(send_data.data_filepath, recv_data.data_infilepath, MAX_FILENAME_SIZE);
404                                         send_data.data_filepath[temp_len_in] = '\0';
405                                 }
406                                 else
407                                 {
408                                         strncpy(send_data.data_filepath, "Error Occured..", MAX_FILENAME_SIZE);
409                                         send_data.data_filepath[15] = '\0';
410                                 }
411
412                                 write(client_sockfd, (char*)&send_data, sizeof(send_data));
413                                 break;
414
415                         default:
416                                 SLOGE("Input error..Please check request type\n");
417                                 break;
418                 }
419                 close(client_sockfd);
420         }
421         
422 Error_close_exit:
423         close(server_sockfd);
424         
425 Error_exit:
426         strncpy(send_data.data_filepath, "error", MAX_FILENAME_SIZE);
427         send_data.data_filepath[5] = '\0';
428
429         if(client_sockfd >= 0)
430         {
431                 write(client_sockfd, (char*)&send_data, sizeof(send_data));
432                 close(client_sockfd);
433         }
434         else
435                 SLOGE("cannot connect to client socket.\n");
436 }
437
438 int SsServerUpdateSmackPolicy()
439 {
440         typedef int (*SmackPolicyUpdateFuncPointer)();
441         SmackPolicyUpdateFuncPointer pSmackPolicyUpdateFuncPointer = NULL;
442         int errCode = -1;
443
444         void* dlHandle = dlopen("/usr/lib/libsmack-update-service.so", RTLD_LAZY);
445
446         if (!dlHandle)
447         {
448                 SLOGE("Failed to open so with reason : %s",  dlerror());
449                 return errCode;
450         }
451
452         pSmackPolicyUpdateFuncPointer = (SmackPolicyUpdateFuncPointer)dlsym(dlHandle, "spd_smack_policy_update");
453         if (dlerror() != NULL)
454         {
455                 SLOGE("Failed to find spd_smack_policy_update symbol : %s",  dlerror());
456                 goto free_data;
457         }
458
459         errCode = pSmackPolicyUpdateFuncPointer();
460
461         free_data:
462
463         if(dlHandle){
464                 dlclose(dlHandle);
465         }
466
467         return errCode;
468 }
469
470 void vconf_smack_update_cb(keynode_t *key, void* data)
471 {
472         SLOGD("Callback received");
473         int errorCode;
474
475         switch(vconf_keynode_get_type(key))
476         {
477         case VCONF_TYPE_INT:
478                 printf("key = %s, value = %d(int)\n",
479                                 vconf_keynode_get_name(key), vconf_keynode_get_int(key));
480                 break;
481         case VCONF_TYPE_STRING:
482         {
483                 printf("key = %s, value = %s(string)\n",
484                                 vconf_keynode_get_name(key), vconf_keynode_get_str(key));
485                 if (vconf_keynode_get_str(key))
486                 {
487                         errorCode = SsServerUpdateSmackPolicy();
488                         LOGD("set the updation status with value %d", errorCode);
489                         // set the update result for fota team
490                         int ret = vconf_set_int(VCONF_UPDATE_RESULT_KEY_NODE, errorCode);
491                         if (ret != VCONF_OK)
492                         {
493                                 LOGD("failed to set the updation status for fota");
494                         }
495
496                         // set the update result for the app control
497                         ret = vconf_set_int(VCONF_UPDATE_RESULT_KEY_NODE_FOR_APP, errorCode);
498                         if (ret != VCONF_OK)
499                         {
500                                 LOGD("failed to set the updation status for app control");
501                         }
502                 }
503
504                 else
505                 {
506                         LOGD("file path is invalid");
507                 }
508         }
509         break;
510         fprintf(stderr, "Unknown Type(%d)\n", vconf_keynode_get_type(key));
511         break;
512         }
513
514         printf("%s Notification OK", (char *)data);
515         return;
516 }
517
518 int vconf_smack_update(void* pData)
519 {
520         vconf_notify_key_changed(VCONF_SMACK_UPDATE_FILE_PATH_KEY_NODE, vconf_smack_update_cb, NULL);
521
522         event_loop = g_main_loop_new(NULL, FALSE);
523         g_main_loop_run(event_loop);
524         return 0;
525 }
526
527
528 int main(void)
529 {
530         SLOGI("Secure Storage Server Start..\n");
531
532         int exist_ret = -1;
533         int make_ret = -1;
534         DIR* dp = NULL; // make default directory(if not exist)
535         pthread_t main_thread;
536
537         pthread_create(&main_thread, NULL, vconf_smack_update, NULL);
538         if((dp = opendir(SS_STORAGE_DEFAULT_PATH)) == NULL)
539         {
540                 SLOGI("directory [%s] is not exist, making now.\n", SS_STORAGE_DEFAULT_PATH);
541                 if(mkdir(SS_STORAGE_DEFAULT_PATH, 0700) < 0)
542                 {
543                     int err_tmp = errno;
544                     SLOGE("Failed while making [%s] directory. Errno: %s\n", SS_STORAGE_DEFAULT_PATH, strerror(err_tmp));
545                     return 0;
546                 }
547         }
548         else
549                 closedir(dp);
550
551         exist_ret = check_key_file(); // if 0, there is not key file. Or 1, exist.
552         
553         if(exist_ret == 0)
554         {
555                 make_ret = make_key_file();
556
557                 if(make_ret == 0)
558                 {
559                         SLOGE("Making key file fail. ss-server will be terminated..\n");
560                         return 0;
561                 }
562         }
563
564         SsServerComm();
565
566         return 0;
567 }