README for PPMTester app
+Installation
+------------
+
The PPMTester app is an app created for testing CAPI of Privacy Privilege
Manager. The app is created in Tizen Studio 4.0 and is based on the
example app 'Account Manager' for profile mobile-4.0.
In order to import the app into the Tizen Studio and build it for Tizen
emulator, one needs to perform following steps (steps 1. and 2. may be
ommited if the CAPI is already installed in Tizen Studio IDE and Tizen
-Emulator; if mobile-4 profile may be accessed when new a project is
+Emulator; if mobile-4 profile may be accessed when a new project is
created, then probably the CAPI is installed):
1 Prepare Tizen Studio IDE
b) Select proper emulator from drop-down list
c) Project -> Build All
d) Run
+
+Usage
+-----
+
+A. Checking if an unprivileged app is not able to check permissions of other app
+
+In order to perform the test, one needs to:
+1) build the app with default manifest,
+2) turn on two emulator terminals,
+3) type in the first emulator terminal 'journalctl -f | grep ppmtester',
+4) type in the second emulator terminal 'dlogutil ppmtester',
+5) run the app and click on the button "check other apps permissions",
+6) for most of tested pairs of apps and privileges, permission should be denied:
+ in the first terminal, the following message should appear: "Authentication failed
+ in security-manager API function: _NAME_OF_SM_FUNCTION_"; in the second terminal,
+ the message "Permission denied" should appear; in the log section of the app,
+ "Permission denied" message should appear.
+
+B. Checking if a privileged app is able to check permissions of other app
+
+In order to perform the test, one needs to:
+1) add following privilege to the tizen-manifest.xml file:
+ http://tizen.org/privilege/permission.check and rebuild the app in Tizen Studio,
+2) connect to the emulator via terminal and modify manually privilege-manager database
+ in order to change the privilege level from 'platform' to 'public':
+ a) mount -o remount,rw /
+ b) sqlite3 /usr/share/privilege-manager/.privilege.db
+ c) update PRIVILEGE_INFO set PRIVILEGE_LEVEL_ID='0', PRIVILEGE_LEVEL="public"
+ where PRIVILEGE_NAME="http://tizen.org/privilege/permission.check";
+3) install app using Tizen Studio and perform steps A.2-A.5,
+4) for all tested pairs of apps and privileges, policy should be displayed both in
+ the terminals and in the log section of the app.
+
+C. Checking if the policy is properly read after manual changes (assuming that
+ steps B.1 and B.2 were performed)
+
+In order to perform the test, one needs to:
+1) click on the button "check other apps permissions",
+2) in section SINGLE CHECKS (in log part), second position should be:
+ "A user has to be asked wheter to grant a permission to use the privilege
+ http://tizen.org/privilege/location for the following application:
+ org.tizen.camera-app.",
+3) change privacy setting of the location privilege: app Settings -> Privacy and security
+ -> Privacy settings -> Location -> Camera -> change setting to Allow (green circle),
+4) click on the button "check other apps permissions" again,
+5) in section SINGLE CHECKS (in log part), second position should be:
+ "The application org.tizen.camera-app has a permission to use the following
+ privilege: http://tizen.org/privilege/location.".
elm_scroller_region_show(obj, 0, c_y, 0, 0);
}
+void log_msg(appdata_s *ad, const char* msg, ...)
+{
+ if (msg == NULL)
+ return;
+
+ va_list args;
+ va_start(args, msg);
+ char buffer[BUFFER_SIZE];
+ vsnprintf(buffer, BUFFER_SIZE, msg, args);
+ va_end(args);
+
+ const char* separator = "";
+
+ print_msg(ad->msg_box, buffer);
+ print_msg(ad->msg_box, separator);
+
+ dlog_print(DLOG_INFO, LOG_TAG, buffer);
+ dlog_print(DLOG_INFO, LOG_TAG, separator);
+}
+
static void _btn_clear_cb(void *data, Evas_Object *btn, void *event_info)
{
appdata_s *ad = data;
switch (ret)
{
case PRIVACY_PRIVILEGE_MANAGER_ERROR_IO_ERROR:
- log_privilege(ad, privilege, "I/O error");
+ log_msg(ad, "I/O error");
break;
case PRIVACY_PRIVILEGE_MANAGER_ERROR_INVALID_PARAMETER:
- log_privilege(ad, privilege, "Invalid parameter");
+ log_msg(ad, "Invalid parameter");
break;
case PRIVACY_PRIVILEGE_MANAGER_ERROR_ALREADY_IN_PROGRESS:
- log_privilege(ad, privilege, "Operation already in progress");
+ log_msg(ad, "Operation already in progress");
break;
case PRIVACY_PRIVILEGE_MANAGER_ERROR_OUT_OF_MEMORY:
- log_privilege(ad, privilege, "Out of memory");
+ log_msg(ad, "Out of memory");
break;
- case PRIVACY_PRIVILEGE_MANAGER_ERROR_UNKNOWN:
- log_privilege(ad, privilege, "Unknown error");
+ case PRIVACY_PRIVILEGE_MANAGER_ERROR_PERMISSION_DENIED:
+ log_msg(ad, "Permission denied");
break;
+ case PRIVACY_PRIVILEGE_MANAGER_ERROR_UNKNOWN:
default:
- log_privilege(ad, privilege, "Unknown error");
+ log_msg(ad, "Unknown error");
break;
}
}
}
}
+void check_app_privilege(appdata_s *ad, const char* app_id, const char* privilege)
+{
+ ppm_check_result_e result;
+
+ int ret = ppm_check_app_permission(app_id, privilege, &result);
+
+ if (ret != PRIVACY_PRIVILEGE_MANAGER_ERROR_NONE) // If there is an error, print log.
+ {
+ app_log_errors(ad, privilege, ret);
+ return;
+ }
+
+ switch (result) // Allow, deny or ask.
+ {
+ case PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_ALLOW:
+ log_msg(ad, "The application %s has a permission to use the following privilege: %s.", app_id, privilege);
+ break;
+ case PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_DENY:
+ log_msg(ad, "The application %s doesn't have a permission to use the following privilege: %s.", app_id, privilege);
+ break;
+ case PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_ASK:
+ log_msg(ad, "A user has to be asked whether to grant a permission to use the privilege %s for the following application: %s.", privilege, app_id);
+ break;
+ default:
+ log_msg(ad, "Unknown result (%d) for %s privilege and %s app.", result, privilege, app_id);
+ break;
+ }
+}
+
void check_privileges(appdata_s *ad, const char** privileges, size_t privileges_count, bool request_privs_ignore_ask_status)
{
ppm_check_result_e* results = malloc(sizeof(ppm_check_result_e) * privileges_count);
}
}
+void check_app_privileges(appdata_s *ad, const char* app_id, const char** privileges, size_t privileges_count)
+{
+ ppm_check_result_e* results = malloc(sizeof(ppm_check_result_e) * privileges_count);
+ if (!results)
+ {
+ log_msg(ad, "Unable to allocate memory for results.");
+ return;
+ }
+
+ int ret = ppm_check_app_permissions(app_id, privileges, privileges_count, results);
+
+ if (ret != PRIVACY_PRIVILEGE_MANAGER_ERROR_NONE) // If there is an error, print log.
+ {
+ for (int it = 0; it < privileges_count; ++it)
+ {
+ app_log_errors(ad, privileges[it], ret);
+ }
+ free(results);
+ return;
+ }
+
+ for (int it = 0; it < privileges_count; ++it)
+ {
+ switch (results[it]) // Allow, deny or ask.
+ {
+ case PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_ALLOW:
+ log_msg(ad, "The application %s has a permission to use the following privilege: %s.", app_id, privileges[it]);
+ break;
+ case PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_DENY:
+ log_msg(ad, "The application %s doesn't have a permission to use the following privilege: %s.", app_id, privileges[it]);
+ break;
+ case PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_ASK:
+ log_msg(ad, "A user has to be asked whether to grant a permission to use the privilege %s for the following application: %s.", privileges[it], app_id);
+ break;
+ default:
+ log_msg(ad, "Unknown result (%d) for %s privilege and %s app.", results[it], privileges[it], app_id);
+ break;
+ }
+ }
+ free(results);
+}
+
void _test_privilege_camera(appdata_s *ad, Evas_Object *obj)
{
check_privilege(ad, "http://tizen.org/privilege/camera");
true);
}
+void _check_other_apps_permissions(appdata_s *ad, Evas_Object *obj)
+{
+ log_msg(ad, "SINGLE CHECKS:");
+
+ // 1) the privilege is not in the manifest
+ check_app_privilege(ad, "org.tizen.chromium-efl", "http://tizen.org/privilege/location");
+
+ // 2) the privilege is in the manifest but is privacy
+ check_app_privilege(ad, "org.tizen.camera-app", "http://tizen.org/privilege/location");
+
+ // 3) the privilege is in the manifest and is not privacy
+ check_app_privilege(ad, "org.example.bluetoothlescanner", "http://tizen.org/privilege/bluetooth");
+
+ // 4) checking the privilege of non-existing app
+ check_app_privilege(ad, "non-existing-app", "http://tizen.org/privilege/bluetooth");
+
+ // 5) checking own privacy privilege
+ check_app_privilege(ad, "org.example.ppmtester", "http://tizen.org/privilege/location");
+
+ // 6) checking own non-privacy privilege
+ check_app_privilege(ad, "org.example.ppmtester", "http://tizen.org/privilege/alarm.get");
+
+ log_msg(ad, "MULTIPLE CHECK:");
+
+ check_app_privileges(ad, "org.tizen.camera-app", unique_privacies.privileges,
+ sizeof(unique_privacies.privileges)/sizeof(unique_privacies.privileges[0]));
+}
+
void create_buttons_in_main_window(appdata_s *ad)
{
Evas_Object *display = _create_new_cd_display(ad, "PPM Tester", _pop_cb);
_new_button(ad, display, "contact.write", _test_privilege_contact_write);
_new_button(ad, display, "check.privacies", _test_check_privacy_privileges);
_new_button(ad, display, "check.privacies.ignore.ask", _test_check_privacy_privileges_ignore_ask);
+ _new_button(ad, display, "check other apps permissions", _check_other_apps_permissions);
}
static void create_base_gui(appdata_s *ad)
*/
void print_msg(Evas_Object *obj, const char* msg, ...);
+/**
+ * @brief Prints massage into the message box and into the dlogutil logger.
+ *
+ * @param[in] ad The structure with GUI elements.
+ * @param[in] msg The text message that is written to the message box.
+ * @param[in] ... Additional arguments declared in the text message.
+ */
+void log_msg(appdata_s *ad, const char* msg, ...);
+
/**
* @brief Clears the message box.
*
*/
void check_privilege(appdata_s *ad, const char* privilege);
+/**
+ * @brief Checks the privilege for the app with a given app_id. Writes messages
+ * in the bottom part of the main window and into the shell (in order to read these
+ * messages use command: dlogutil ppmtester).
+ *
+ * @param[in] ad The structure with GUI elements.
+ * @param[in] app_id The app_id of the app that is to be checked.
+ * @param[in] privilege A privilege that is to be checked.
+ */
+void check_app_privilege(appdata_s *ad, const char* app_id, const char* privilege);
+
/**
* @brief Checks the privileges. Writes messages in the bottom part of the main window and
* into the shell (in order to read these messages use command: dlogutil ppmtester).
*/
void check_privileges(appdata_s *ad, const char** privileges, size_t privileges_count, bool request_privs_no_ask_status);
+/**
+ * @brief Checks the privileges. Writes messages in the bottom part of the main window and
+ * into the shell (in order to read these messages use command: dlogutil ppmtester).
+ *
+ * @param[in] ad The structure with GUI elements.
+ * @param[in] app_id The app_id of the app that is to be checked.
+ * @param[in] privileges A privileges that is to be checked.
+ * @param[in] privileges_count Privileges count passed as second argument
+ */
+void check_app_privileges(appdata_s *ad, const char* app_id, const char** privileges, size_t privileges_count);
+
/**
* @brief Callback for 'camera' button.
*
*/
void _test_check_privacy_privileges_ignore_ask(appdata_s *ad, Evas_Object *obj);
+/**
+ * @brief Callback for 'check other apps permissions' button.
+ *
+ * @param[in] ad The structure with GUI elements.
+ * @param[in] obj Display object.
+ */
+void _check_other_apps_permissions(appdata_s *ad, Evas_Object *obj);
+
/**
* @brief Creates buttons in the main window.
*