sensord: fix a bug which did not check privilege
[platform/core/system/sensord.git] / src / server / permission_checker.cpp
1 /*
2  * sensord
3  *
4  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include "permission_checker.h"
21
22 #include <cynara-client.h>
23 #include <cynara-creds-socket.h>
24 #include <cynara-session.h>
25 #include <sensor_log.h>
26 #include <unordered_map>
27
28 #define CACHE_SIZE 16
29
30 using namespace sensor;
31
32 static cynara *cynara_env = NULL;
33 static std::unordered_map<int, std::string> permissions;
34
35 permission_checker::permission_checker()
36 {
37         init_cynara();
38 }
39
40 permission_checker::~permission_checker()
41 {
42         deinit_cynara();
43 }
44
45 void permission_checker::init(void)
46 {
47         /* if needed, add privilege to permissions */
48         permissions[SENSOR_PERMISSION_HEALTH_INFO] = "http://tizen.org/privilege/healthinfo";
49 }
50
51 void permission_checker::init_cynara(void)
52 {
53         int err;
54         cynara_configuration *conf;
55
56         err = cynara_configuration_create(&conf);
57         retm_if(err != CYNARA_API_SUCCESS, "Failed to create cynara configuration");
58
59         err = cynara_configuration_set_cache_size(conf, CACHE_SIZE);
60         if (err != CYNARA_API_SUCCESS) {
61                 _E("Failed to set cynara cache");
62                 cynara_configuration_destroy(conf);
63                 return;
64         }
65
66         err = cynara_initialize(&cynara_env, conf);
67         cynara_configuration_destroy(conf);
68
69         if (err != CYNARA_API_SUCCESS) {
70                 _E("Failed to initialize cynara");
71                 cynara_env = NULL;
72                 return;
73         }
74
75         _I("Initialized");
76 }
77
78 void permission_checker::deinit_cynara(void)
79 {
80         if (cynara_env) {
81                 cynara_finish(cynara_env);
82                 cynara_env = NULL;
83         }
84
85         _I("Deinitialized");
86 }
87
88 bool permission_checker::has_permission_cynara(int sock_fd, std::string &perm)
89 {
90         retvm_if(cynara_env == NULL, false, "Cynara not initialized");
91
92         int ret;
93         int pid = -1;
94         char *client = NULL;
95         char *session = NULL;
96         char *user = NULL;
97
98         retvm_if(cynara_creds_socket_get_pid(sock_fd, &pid) != CYNARA_API_SUCCESS,
99                         false, "Failed to get pid");
100
101         if (cynara_creds_socket_get_client(sock_fd,
102                                 CLIENT_METHOD_DEFAULT, &client) != CYNARA_API_SUCCESS ||
103                         cynara_creds_socket_get_user(sock_fd,
104                                 USER_METHOD_DEFAULT, &user) != CYNARA_API_SUCCESS ||
105                         (session = cynara_session_from_pid(pid)) == NULL) {
106                 _E("Failed to get client information");
107                 free(client);
108                 free(user);
109                 free(session);
110                 return false;
111         }
112
113         ret = cynara_check(cynara_env, client, session, user, perm.c_str());
114
115         free(client);
116         free(session);
117         free(user);
118
119         return (ret == CYNARA_API_ACCESS_ALLOWED);
120 }
121
122 bool permission_checker::has_permission(int sock_fd, std::string &perm)
123 {
124         retv_if(perm.empty(), true);
125
126         return has_permission_cynara(sock_fd, perm);
127 }
128
129 /* TODO: remove sensor_permission_t and this function */
130 bool permission_checker::has_permission(int sock_fd, sensor_permission_t perm)
131 {
132         auto it = permissions.find(perm);
133         retv_if(it == permissions.end(), true);
134
135         return has_permission(sock_fd, permissions[perm]);
136 }