2 * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <system_info.h>
26 #include <cert-svc/ccert.h>
27 #include <cert-svc/cinstance.h>
28 #include <cynara-session.h>
29 #include <cynara-client.h>
30 #include <cynara-creds-gdbus.h>
31 #include <tzplatform_config.h>
33 #include "alarm-manager-util.h"
35 #define ALARMMGR_LOG_BUFFER_SIZE 10000
36 #define ALARMMGR_LOG_BUFFER_STRING_SIZE 400
37 #define ALARMMGR_LOG_DIR_PATH "/var/log/appfw/alarmmgr_log/"
38 #define ALARMMGR_LOG_FILE_PATH "/var/log/appfw/alarmmgr_log/alarmmgr.log"
39 static int log_index = 0;
40 static int log_fd = 0;
42 static int __bg_category_func(const char *name, void *user_data)
44 bg_category_cb_info_t *info = (bg_category_cb_info_t *)user_data;
45 LOGD("appid[%s], bg name = %s", info->appid, name);
46 if (name && strncmp("enable", name, strlen(name)) &&
47 strncmp("disable", name, strlen(name))) {
55 profile_t _get_profile()
57 static profile_t saved = PROFILE_UNKNOWN;
61 if (__builtin_expect(saved != PROFILE_UNKNOWN, 1))
64 r = system_info_get_platform_string("http://tizen.org/feature/profile",
66 if (r != SYSTEM_INFO_ERROR_NONE) {
67 LOGD("Failed to get profile info. error(%d)", r);
71 switch (*profileName) {
74 saved = PROFILE_MOBILE;
78 saved = PROFILE_WEARABLE;
88 default: // common or unknown ==> ALL ARE COMMON.
89 saved = PROFILE_COMMON;
96 int _pkg_is_global(const char *callee_pkgid, uid_t uid)
99 int return_code = ERR_ALARM_SYSTEM_FAIL;
100 pkgmgrinfo_pkginfo_h handle;
102 retval = pkgmgrinfo_pkginfo_get_usr_pkginfo(callee_pkgid, uid, &handle);
103 if (retval != PMINFO_R_OK) {
104 LOGE("Failed to get pkginfo\n");
105 return_code = ERR_ALARM_INVALID_ID;
108 retval = pkgmgrinfo_pkginfo_is_global(handle, &is_global);
109 if (retval == PMINFO_R_OK && is_global)
110 return_code = ALARMMGR_RESULT_SUCCESS;
111 else if (retval == PMINFO_R_OK && !is_global)
112 return_code = ERR_ALARM_NOT_PERMITTED_APP;
114 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
120 int _cynara_check(GDBusMethodInvocation *invocation, const char *privilege,
126 char *client_session = NULL;
127 cynara *p_cynara = NULL;
128 const char *sender_unique_name;
129 GDBusConnection *connection;
131 connection = g_dbus_method_invocation_get_connection(invocation);
132 sender_unique_name = g_dbus_method_invocation_get_sender(invocation);
134 ret = cynara_initialize(&p_cynara, NULL);
135 if (ret != CYNARA_API_SUCCESS) {
136 LOGE("cynara_initialize() failed : %d", ret);
137 ret = ERR_ALARM_SYSTEM_FAIL;
141 ret = cynara_creds_gdbus_get_user(connection, sender_unique_name,
142 USER_METHOD_DEFAULT, &user);
143 if (ret != CYNARA_API_SUCCESS) {
144 LOGE("cynara_creds_gdbus_get_user() failed : %d", ret);
145 ret = ERR_ALARM_SYSTEM_FAIL;
149 ret = cynara_creds_gdbus_get_client(connection, sender_unique_name,
150 CLIENT_METHOD_DEFAULT, &client);
151 if (ret != CYNARA_API_SUCCESS) {
152 LOGE("cynara_creds_gdbus_get_client() failed : %d", ret);
153 ret = ERR_ALARM_SYSTEM_FAIL;
157 LOGD("user :%s , client :%s ,unique_name : %s, pid() : %d",
158 user, client, sender_unique_name, pid);
160 client_session = cynara_session_from_pid(pid);
161 if (!client_session) {
162 LOGE("cynara_session_from_pid() failed : %d", ret);
163 ret = ERR_ALARM_SYSTEM_FAIL;
167 ret = cynara_check(p_cynara, client, client_session, user,
169 if (ret == CYNARA_API_ACCESS_ALLOWED) {
170 LOGD("CYNARA_ACCESS_ALLOWED");
171 ret = ALARMMGR_RESULT_SUCCESS;
174 LOGD("CYNARA_NOT_ALLOWED [%d]", ret);
175 ret = ERR_ALARM_NOT_PERMITTED_APP;
180 g_free(client_session);
186 cynara_finish(p_cynara);
191 int _get_pid_from_appid(const char *app_id, uid_t uid)
194 pid = aul_app_get_pid_for_uid(app_id, uid);
196 LOGE("aul_app_get_pid_for_uid() is failed. appid %s may not be app. uid : [%d]", app_id, uid);
200 LOGD("app_id:%s [pid:%d]", app_id, pid);
204 char *_get_pkgid_by_appid(const char *app_id, uid_t uid)
206 pkgmgrinfo_pkginfo_h handle;
210 if (pkgmgrinfo_appinfo_get_usr_appinfo(app_id, uid, &handle) == PMINFO_R_OK) {
211 if (pkgmgrinfo_appinfo_get_pkgid(handle, &temp) == PMINFO_R_OK) {
213 pkgid = strdup(temp);
215 pkgmgrinfo_appinfo_destroy_appinfo(handle);
221 int _is_ui_app(const char *appid, uid_t uid)
225 char *component = NULL;
226 pkgmgrinfo_appinfo_h appinfo_h = NULL;
231 ret = pkgmgrinfo_appinfo_get_usr_appinfo(appid, uid, &appinfo_h);
235 ret = pkgmgrinfo_appinfo_get_component_type(appinfo_h, &component);
236 if (ret == 0 && component != NULL && strncmp(component, "uiapp", 5) == 0)
240 pkgmgrinfo_appinfo_destroy_appinfo(appinfo_h);
245 bool _is_app(const char *appid, uid_t uid)
247 pkgmgrinfo_appinfo_h appinfo_h = NULL;
250 ret = pkgmgrinfo_appinfo_get_usr_appinfo(appid, uid, &appinfo_h);
251 if (ret != PMINFO_R_OK)
255 pkgmgrinfo_appinfo_destroy_appinfo(appinfo_h);
260 int _compare_api_version(int *result, int pid, uid_t uid)
263 pkgmgrinfo_pkginfo_h pkginfo = NULL;
264 char pkgid[MAX_PKG_ID_LEN] = {0, };
267 if (aul_app_get_pkgid_bypid_for_uid(pid, pkgid, sizeof(pkgid), uid) != AUL_R_OK) {
268 LOGE("aul_app_get_pkgid_bypid() is failed. PID %d may not be app.", getpid());
270 ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &pkginfo);
271 if (ret != PMINFO_R_OK) {
272 LOGE("Failed to get pkginfo\n");
274 ret = pkgmgrinfo_pkginfo_get_api_version(pkginfo, &pkg_version);
275 if (ret != PMINFO_R_OK)
276 LOGE("Failed to check api version [%d]\n", ret);
277 *result = strverscmp(pkg_version, "2.4");
278 pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo);
284 bool _permit_by_config(pkgmgrinfo_appinfo_h handle, uid_t uid)
286 if (access(tzplatform_mkpath(TZ_SYS_RO_SHARE,
287 "alarm-manager/alarm-config-service-restricted"), F_OK) == 0) {
288 LOGD("This profile restrict alarms for service applications\n");
292 if (access(tzplatform_mkpath(TZ_SYS_RO_SHARE,
293 "alarm-manager/alarm-config-platform-service-permitted"), F_OK) == 0) {
294 LOGD("This profile permit alarm for service applications which has platform cert\n");
297 const char *cert_value;
298 pkgmgrinfo_certinfo_h certinfo;
299 CertSvcInstance instance;
300 CertSvcCertificate certificate;
301 CertSvcVisibility visibility = CERTSVC_VISIBILITY_PUBLIC;
303 r = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
304 if (r != PMINFO_R_OK) {
305 LOGE("Failed to get certinfo pkgid");
309 r = pkgmgrinfo_pkginfo_create_certinfo(&certinfo);
310 if (r != PMINFO_R_OK) {
311 LOGE("Failed to create certinfo");
315 r = pkgmgrinfo_pkginfo_load_certinfo(pkgid, certinfo, uid);
316 if (r != PMINFO_R_OK) {
317 LOGE("Failed to load certinfo");
318 pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
322 r = pkgmgrinfo_pkginfo_get_cert_value(certinfo,
323 PMINFO_DISTRIBUTOR_ROOT_CERT, &cert_value);
324 if (r != PMINFO_R_OK || cert_value == NULL) {
325 LOGE("Failed to get cert value");
326 pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
330 r = certsvc_instance_new(&instance);
331 if (r != CERTSVC_SUCCESS) {
332 LOGE("certsvc_instance_new() is failed.");
333 pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
337 r = certsvc_certificate_new_from_memory(instance,
338 (const unsigned char *)cert_value,
340 CERTSVC_FORM_DER_BASE64,
342 if (r != CERTSVC_SUCCESS) {
343 LOGE("certsvc_certificate_new_from_memory() is failed.");
344 pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
345 certsvc_instance_free(instance);
349 r = certsvc_certificate_get_visibility(certificate, &visibility);
350 if (r != CERTSVC_SUCCESS)
351 LOGE("certsvc_certificate_get_visibility() is failed.");
353 pkgmgrinfo_pkginfo_destroy_certinfo(certinfo);
354 certsvc_instance_free(instance);
355 certsvc_certificate_free(certificate);
357 LOGW("visibility is %d", visibility);
358 if (visibility & CERTSVC_VISIBILITY_PLATFORM) {
363 if (access(tzplatform_mkpath(TZ_SYS_RO_SHARE,
364 "alarm-manager/alarm-config-all-service-permitted"), F_OK) == 0) {
365 LOGD("This profile permit alarms for all service applications\n");
372 bool _is_permitted(const char *app_id, int alarm_type, uid_t uid)
374 pkgmgrinfo_appinfo_h handle = NULL;
376 bool _return = false;
378 if (app_id == NULL) {
379 LOGE("app_id is NULL. Only expicit launch is permitted\n");
383 ret = pkgmgrinfo_appinfo_get_usr_appinfo(app_id, uid, &handle);
384 if (ret != PMINFO_R_OK) {
385 LOGE("Failed to get appinfo [%s]\n", app_id);
387 char *app_type = NULL;
388 ret = pkgmgrinfo_appinfo_get_component_type(handle, &app_type);
389 if (app_type && strcmp("uiapp", app_type) == 0) {
390 if (alarm_type & ALARM_TYPE_EXACT_SERVICE_APP) {
391 LOGE("[%s] is ui application.\
392 But alarm_type is ALARM_TYPE_EXACT_SERVICE_APP.\
393 soit is not allowed", app_id);
397 LOGD("[%s] is ui application. It is allowed", app_id);
400 } else if (app_type && strcmp("svcapp", app_type) == 0) {
401 LOGD("[%s] is service application.", app_id);
403 if (_permit_by_config(handle, uid)) {
404 LOGD("service applications are allowed");
409 bg_category_cb_info_t info = {
414 if (alarm_type & ALARM_TYPE_INEXACT || alarm_type & ALARM_TYPE_EXACT_SERVICE_APP) {
415 ret = pkgmgrinfo_appinfo_foreach_background_category(handle, __bg_category_func, &info);
416 if (ret == PMINFO_R_OK && info.has_bg) {
417 LOGD("[%s] has background categories. It is allowed", app_id);
421 LOGE("Failed to foreach background category. [%s] is not allowed", app_id);
429 pkgmgrinfo_appinfo_destroy_appinfo(handle);
434 void _initialize_module_log(void)
436 #ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG
439 if (access(ALARMMGR_LOG_DIR_PATH, F_OK)) {
440 LOGE("Not exist(%s)", ALARMMGR_LOG_DIR_PATH);
442 if (mkdir(ALARMMGR_LOG_DIR_PATH, (S_IRUSR | S_IWUSR | S_IXUSR |
443 S_IRGRP | S_IWGRP | S_IXGRP))) {
444 LOGE("Failed to create directory(%s). errno(%d)",
445 ALARMMGR_LOG_DIR_PATH, errno);
450 log_fd = open(ALARMMGR_LOG_FILE_PATH, O_CREAT | O_WRONLY, 0644);
452 LOGE("Opening the file for alarmmgr log is failed. err: %s", strerror_r(errno, buf, sizeof(buf)));
456 int offset = lseek(log_fd, 0, SEEK_END);
458 log_index = (int)(offset / ALARMMGR_LOG_BUFFER_STRING_SIZE);
459 if (log_index >= ALARMMGR_LOG_BUFFER_SIZE) {
461 lseek(log_fd, 0, SEEK_SET);
464 #endif /* _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG */
468 void _save_module_log(const char *tag, const char *message)
470 #ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG
471 char buffer[ALARMMGR_LOG_BUFFER_STRING_SIZE] = {0,};
477 LOGE("The file is not ready.");
482 lseek(log_fd, 0, SEEK_CUR);
484 lseek(log_fd, 0, SEEK_SET);
487 time_str = ctime(&now);
489 time_str[strlen(time_str) - 1] = '\0'; /* to avoid new line */
491 snprintf(buffer, ALARMMGR_LOG_BUFFER_STRING_SIZE, "[%-6d]%s\t%s\t : %ld %s\n", log_index, tag, message, now, time_str);
493 SECURE_LOGW("%s", buffer);
494 int ret = write(log_fd, buffer, strlen(buffer));
496 LOGE("Writing the alarmmgr log is failed. err: %s", strerror_r(errno, buf, sizeof(buf)));
500 if (++log_index >= ALARMMGR_LOG_BUFFER_SIZE)
502 #endif /* _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG */
506 void _save_alarm_info_log(const char *tag, __alarm_info_t *info)
508 #ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG
509 char log_message[ALARMMGR_LOG_MESSAGE_SIZE] = {0,};
510 char *due_time_str = ctime(&(info->due_time));
512 due_time_str[strlen(due_time_str) - 1] = '\0'; /* to avoid new line */
514 due_time_str = "NULL";
516 snprintf(log_message, sizeof(log_message),
517 "alarmID: %d, uid: %d, caller : %s -> callee : %s, "
518 "dst_name %s, dst_mod %s, "
519 "type 0x%x, mode %d, "
520 "interval:%ld, duetime: %ld %s",
521 info->alarm_id, info->uid, info->app_unique_name, info->callee_pkgid,
522 info->dst_service_name, info->dst_service_name_mod,
523 info->alarm_info.alarm_type, info->alarm_info.mode.repeat,
524 info->alarm_info.mode.u_interval.interval, info->due_time, due_time_str);
526 _save_module_log(tag, log_message);
527 #endif /* _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG */