Modify privilege version validation logic to support x.x.x.x format (x = integer... 43/94343/7
authorYunjin Lee <yunjin-.lee@samsung.com>
Fri, 28 Oct 2016 10:26:27 +0000 (19:26 +0900)
committerYunjin Lee <yunjin-.lee@samsung.com>
Mon, 31 Oct 2016 10:29:59 +0000 (19:29 +0900)
Change-Id: I0fd8978559abe5db19be62de14f3c0bcf97f4269
Signed-off-by: Yunjin Lee <yunjin-.lee@samsung.com>
capi/src/privilege_manager.c
test/tc-privilege-manager.c

index f84a619..abf9e54 100755 (executable)
@@ -2,6 +2,7 @@
 #include <stdio.h>
 #include <unistd.h>
 #include <sys/types.h>
+#include <ctype.h>
 #include <string.h>
 #include "privilege_db_manager.h"
 #include "privilege_manager.h"
                return returnValue; \
        }
 
+typedef u_int32_t api_version_code_t;
+
+static int __get_api_version_code(const char *api_version, api_version_code_t *api_version_code )
+{
+       TryReturn(api_version != NULL, , PRVMGR_ERR_INVALID_PARAMETER, "[PRVMGR_ERR_INVALID_PARAMETER] api_version is NULL");
+
+       unsigned int parts[4] = {0};
+       unsigned int *pParts = parts;
+       int value = 0;
+       char ch = *api_version;
+       int is_number = 0;
+
+       while (ch != 0)
+       {
+               if (isdigit(ch)) {
+                       is_number = 1;
+                       value = 0;
+                       do {
+                               value = (value * 10) + (ch - '0');
+                               ch = *++api_version;
+                       } while (isdigit(ch));
+                       TryReturn(value <= 0xFF, , PRVMGR_ERR_INVALID_PARAMETER, "[PRVMGR_ERR_INVALID_PARAMETER] The api_version is invalid. A part of api_version exceed 255");
+               } else if (ch == '.' && is_number == 1) {
+                       is_number = 0;
+                       TryReturn(pParts < parts + 3, , PRVMGR_ERR_INVALID_PARAMETER, "[PRVMGR_ERR_INVALID_PARAMETER] The api_version is invalid. api_version should be in form of x, x.x, x.x.x, or x.x.x.x");
+                       *pParts++ = value;
+                       ch = *++api_version;
+               } else {
+                       _LOGE("[PRVMGR_ERR_INVALID_PARAMETER] The api_version is invalid. api_version should be consist of digit(0 <= x <= 255) and dot(.) in form of x, x.x, x.x.x, or x.x.x.x");
+                       return PRVMGR_ERR_INVALID_PARAMETER;
+               }
+       }
+
+       TryReturn(pParts <= parts + 3 && is_number == 1, , PRVMGR_ERR_INVALID_PARAMETER, "[PRVMGR_ERR_INVALID_PARAMETER] The api_version is invalid. api_version should be in form of x, x.x, x.x.x, or x.x.x.x");
+
+       *pParts++ = value;
+       *api_version_code = (parts[0] << 24);
+       *api_version_code |= (parts[1] << 16);
+       *api_version_code |= (parts[2] << 8);
+       *api_version_code |= parts[3];
+       return PRVMGR_ERR_NONE;
+}
+
 static void __free_privilege_list(GList * privilege_list)
 {
        GList *l = NULL;
@@ -65,11 +109,10 @@ static void __free_privilege_list(GList * privilege_list)
 static int __privilege_manager_check_privilege_list(const char *api_version, const char *privilege, GList * valid_privilege_list, int *privilege_level, char **changed_to, char **valid_api_version)
 {
        TryReturn(privilege != NULL, , PRVMGR_ERR_INVALID_PARAMETER, "[PRVMGR_ERR_INVALID_PARAMETER] privilege is NULL");
-       int i, is_valid_version = 0;
        int ret_val = PRVMGR_ERR_NO_EXIST_PRIVILEGE;
-       char *tmp_api_version = NULL;
-       char *tmp_expired_version = NULL;
-       char *tmp_issued_version = NULL;
+       api_version_code_t api_version_code = 0;
+       int ret = __get_api_version_code(api_version, &api_version_code);
+       TryReturn(ret == PRVMGR_ERR_NONE && api_version_code != 0, , PRVMGR_ERR_INTERNAL_ERROR, "[PRVMGR_ERR_INTERNAL_ERROR] __get_api_version_code() for api_version failed. api_version = %s", api_version);
        GList *l = NULL;
        for (l = valid_privilege_list; l != NULL; l = l->next) {
                privilege_info_db_row_s *privilege_info_db_row = (privilege_info_db_row_s *)l->data;
@@ -77,73 +120,32 @@ static int __privilege_manager_check_privilege_list(const char *api_version, con
                        _LOGD("Matched privilege name exist");
                        _LOGD("Check api version");
 
-                       if (tmp_api_version != NULL) {
-                               free(tmp_api_version);
-                               tmp_api_version = NULL;
-                       }
-                       if (tmp_issued_version != NULL) {
-                               free(tmp_issued_version);
-                               tmp_issued_version = NULL;
-                       }
-                       if (tmp_expired_version != NULL) {
-                               free(tmp_expired_version);
-                               tmp_expired_version = NULL;
-                       }
-                       is_valid_version = 0;
-
-                       tmp_api_version = strdup(api_version);
-                       TryReturn(tmp_api_version != NULL, ret_val = PRVMGR_ERR_OUT_OF_MEMORY; goto FINISH, PRVMGR_ERR_OUT_OF_MEMORY, "[PRVMGR_ERR_OUT_OF_MEMORY] tmp_api_version's strdup is failed.");
-                       size_t new_size = snprintf(0, 0, "%s%s", tmp_api_version, API_VERSION_PADDING) + 1;
-                       tmp_api_version = realloc(tmp_api_version, new_size * sizeof(char));
-                       TryReturn(tmp_api_version != NULL, ret_val = PRVMGR_ERR_OUT_OF_MEMORY; goto FINISH, PRVMGR_ERR_OUT_OF_MEMORY, "[PRVMGR_ERR_OUT_OF_MEMORY] tmp_api_version's realloc is failed.");
-                       strncat(tmp_api_version, API_VERSION_PADDING, API_VERSION_PADDING_LEN);
-
-                       tmp_expired_version = strdup(privilege_info_db_row->expired_version);
-                       TryReturn(tmp_expired_version != NULL, ret_val = PRVMGR_ERR_OUT_OF_MEMORY; goto FINISH, PRVMGR_ERR_OUT_OF_MEMORY, "[PRVMGR_ERR_OUT_OF_MEMORY] tmp_expired_version's strdup is failed.");
-                       new_size = snprintf(0, 0, "%s%s", tmp_expired_version, API_VERSION_PADDING) + 1;
-                       tmp_expired_version = realloc(tmp_expired_version, new_size * sizeof(char));
-                       TryReturn(tmp_expired_version != NULL, ret_val = PRVMGR_ERR_OUT_OF_MEMORY; goto FINISH, PRVMGR_ERR_OUT_OF_MEMORY, "[PRVMGR_ERR_OUT_OF_MEMORY] tmp_expired_version's realloc is failed.");
-                       strncat(tmp_expired_version, API_VERSION_PADDING, API_VERSION_PADDING_LEN);
-
-                       tmp_issued_version = strdup(privilege_info_db_row->issued_version);
-                       TryReturn(tmp_issued_version != NULL, ret_val = PRVMGR_ERR_OUT_OF_MEMORY; goto FINISH, PRVMGR_ERR_OUT_OF_MEMORY, "[PRVMGR_ERR_OUT_OF_MEMORY] tmp_issued_version's strdup is failed.");
-                       new_size = snprintf(0, 0, "%s%s", tmp_issued_version, API_VERSION_PADDING) + 1;
-                       tmp_issued_version = realloc(tmp_issued_version, new_size * sizeof(char));
-                       TryReturn(tmp_issued_version != NULL, ret_val = PRVMGR_ERR_OUT_OF_MEMORY; goto FINISH, PRVMGR_ERR_OUT_OF_MEMORY, "[PRVMGR_ERR_OUT_OF_MEMORY] tmp_issued_version's realloc is failed.");
-                       strncat(tmp_issued_version, API_VERSION_PADDING, API_VERSION_PADDING_LEN);
-
-                       if (strncmp(tmp_api_version, tmp_expired_version, MAX_API_VERSION_LEN) == 0) {
-                               is_valid_version = 1;
-                       } else {
-                               for (i = 0; is_valid_version == 0 && i < MAX_API_VERSION_LEN; i++) {
-                                       if (tmp_api_version[i] > tmp_expired_version[i])
-                                               is_valid_version = 1;
-                                       else if (tmp_api_version[i] < tmp_expired_version[i])
-                                               break;
-                               }
-                       }
+                       api_version_code_t issued_version_code = 0;
+                       api_version_code_t expired_version_code = 0;
 
-                       for (i = 0; is_valid_version == 0 && i < MAX_API_VERSION_LEN; i++) {
-                               if (tmp_api_version[i] < tmp_issued_version[i])
-                                       is_valid_version = 2;
-                               else if (tmp_api_version[i] > tmp_issued_version[i])
-                                       break;
-                       }
+                       ret = __get_api_version_code(privilege_info_db_row->expired_version, &expired_version_code);
+                       TryReturn(ret == PRVMGR_ERR_NONE && expired_version_code != 0, , PRVMGR_ERR_INTERNAL_ERROR, "[PRVMGR_ERR_INTERNAL_ERROR] __get_api_version_code() for expired_version of privilege (%s) failed. expired_version = %s", privilege, privilege_info_db_row->expired_version);
 
-                       if (is_valid_version == 0) {
-                               *privilege_level = privilege_info_db_row->privilege_level_id;
-                               ret_val = PRVMGR_ERR_NONE;
-                               goto FINISH;
-                       } else if (is_valid_version == 1) {
+                       ret = __get_api_version_code(privilege_info_db_row->issued_version, &issued_version_code);
+                       TryReturn(ret == PRVMGR_ERR_NONE && issued_version_code != 0, , PRVMGR_ERR_INTERNAL_ERROR, "[PRVMGR_ERR_INTERNAL_ERROR] __get_api_version_code() for issued_version of privilege (%s) failed. issued_version = %s", privilege, privilege_info_db_row->issued_version);
+
+                       if (api_version_code < issued_version_code) {
                                _LOGD("%s is invalid in tizen version: %s", privilege_info_db_row->privilege_name, api_version);
-                               _LOGD("privilege deprecated version is equal to or lower than api version");
+                               _LOGD("privilege issued version is higher than api version");
                                if (*valid_api_version != NULL) {
                                        free(*valid_api_version);
                                        *valid_api_version = NULL;
                                }
-                               *valid_api_version = strdup(privilege_info_db_row->expired_version);
+                               *valid_api_version = strdup(privilege_info_db_row->issued_version);
                                TryReturn(valid_api_version != NULL, ret_val = PRVMGR_ERR_OUT_OF_MEMORY; goto FINISH, PRVMGR_ERR_OUT_OF_MEMORY, "[PRVMGR_ERR_OUT_OF_MEMORY] valid_api_version's strdup is failed.");
 
+                               ret_val = PRVMGR_ERR_NO_EXIST_PRIVILEGE;
+                       }
+                       if (api_version_code >= expired_version_code) {
+                               _LOGD("%s is invalid in tizen version: %s", privilege_info_db_row->privilege_name, api_version);
+                               _LOGD("privilege deprecated version is equal to or lower than api version");
+                               *valid_api_version = strdup(privilege_info_db_row->expired_version);
+                               TryReturn(valid_api_version != NULL, ret_val = PRVMGR_ERR_OUT_OF_MEMORY; goto FINISH, PRVMGR_ERR_OUT_OF_MEMORY, "[PRVMGR_ERR_OUT_OF_MEMORY] valid_api_version's strdup is failed.");
                                if (privilege_info_db_row->changed_to != NULL && strcmp(privilege_info_db_row->changed_to, "") != 0) {
                                        if (*changed_to != NULL) {
                                                free(*changed_to);
@@ -153,27 +155,17 @@ static int __privilege_manager_check_privilege_list(const char *api_version, con
                                        *changed_to = strdup(privilege_info_db_row->changed_to);
                                        TryReturn(changed_to != NULL, ret_val = PRVMGR_ERR_OUT_OF_MEMORY; goto FINISH, PRVMGR_ERR_OUT_OF_MEMORY, "[PRVMGR_ERR_OUT_OF_MEMORY] changed_to's strdup is failed.");
                                }
-
                                ret_val = PRVMGR_ERR_DEPRECATED_PRIVILEGE;
-                       } else if (is_valid_version == 2) {
-                               _LOGD("%s is invalid in tizen version: %s", privilege_info_db_row->privilege_name, api_version);
-                               _LOGD("privilege issued version is higher than api version");
-                               if (*valid_api_version != NULL) {
-                                       free(*valid_api_version);
-                                       *valid_api_version = NULL;
-                               }
-                               *valid_api_version = strdup(privilege_info_db_row->issued_version);
-                               TryReturn(valid_api_version != NULL, ret_val = PRVMGR_ERR_OUT_OF_MEMORY; goto FINISH, PRVMGR_ERR_OUT_OF_MEMORY, "[PRVMGR_ERR_OUT_OF_MEMORY] valid_api_version's strdup is failed.");
-
-                               ret_val = PRVMGR_ERR_NO_EXIST_PRIVILEGE;
+                       }
+                       if (api_version_code >= issued_version_code && api_version_code < expired_version_code) {
+                               *privilege_level = privilege_info_db_row->privilege_level_id;
+                               ret_val = PRVMGR_ERR_NONE;
+                               goto FINISH;
                        }
                }
        }
 
- FINISH:
-       free(tmp_issued_version);
-       free(tmp_expired_version);
-       free(tmp_api_version);
+FINISH:
        return ret_val;
 }
 
@@ -189,32 +181,6 @@ const char *__get_privilege_level_string(privilege_db_manager_privilege_level_e
                return "not defined privilege";
 }
 
-int __check_api_version_validity(const char *api_version)
-{
-
-       int i;
-       int is_valid_version_type = 1;
-       int api_version_size = strlen(api_version);
-       if (api_version_size % 2 == 1 && (3 <= api_version_size && api_version_size <= 7)) {
-               for (i = 0; i < api_version_size; i++) {
-                       if (i % 2 == 0) {
-                               if (!('0' <= api_version[i] && api_version[i] <= '9'))
-                                       is_valid_version_type = 0;
-                       } else {
-                               if (api_version[i] != '.')
-                                       is_valid_version_type = 0;
-                       }
-               }
-       } else {
-               is_valid_version_type = 0;
-       }
-
-       if (is_valid_version_type == 0)
-               return PRVMGR_ERR_INVALID_PARAMETER;
-
-       return PRVMGR_ERR_NONE;
-}
-
 int privilege_manager_verify_privilege(const char *api_version, privilege_manager_package_type_e package_type, GList * privilege_list, privilege_manager_visibility_e visibility, char **error_message)
 {
        _LOGD("privilege_manager_verify_privilege called");
@@ -233,7 +199,7 @@ int privilege_manager_verify_privilege(const char *api_version, privilege_manage
        char *wrt_active_version = "2.3.1";
        int is_valid_wrt_version = 1;
        char *pkg_type = NULL;
-       int i = 0;
+       api_version_code_t api_version_code = 0;
 
        /* Check invalid parameters */
        if (api_version == NULL) {
@@ -243,10 +209,10 @@ int privilege_manager_verify_privilege(const char *api_version, privilege_manage
 
                return PRVMGR_ERR_INVALID_PARAMETER;
        } else {
-               ret = __check_api_version_validity(api_version);
+               ret = __get_api_version_code(api_version, &api_version_code);
                if (ret != PRVMGR_ERR_NONE) {
-                       _LOGE("[PRVMGR_ERR_INVALID_PARAMETER] %s is in invalid form. api_version form should be X.X, X.X.X or X.X.X.X(X=integer)", api_version);
-                       *error_message = strdup("[PRVMGR_ERR_INVALID_PARAMETER] api_version form should be a X.X, X.X.X or X.X.X.X(X=integer)");
+                       _LOGE("[PRVMGR_ERR_INVALID_PARAMETER] The api_version is invalid. api_version should be consist of digit(0 <= x <= 255) and dot(.) in form of x, x.x, x.x.x, or x.x.x.x");
+                       *error_message = strdup("[PRVMGR_ERR_INVALID_PARAMETER] The api_version is invalid. api_version should be consist of digit(0 <= x <= 255) and dot(.) in form of x, x.x, x.x.x, or x.x.x.x");
                        TryReturn(error_message != NULL, , PRVMGR_ERR_OUT_OF_MEMORY, "[PRVMGR_ERR_OUT_OF_MEMORY] error_message's strdup is failed");
                        return ret;
                }
@@ -261,23 +227,14 @@ int privilege_manager_verify_privilege(const char *api_version, privilege_manage
                return PRVMGR_ERR_INVALID_PARAMETER;
        }
        if (package_type == PRVMGR_PACKAGE_TYPE_WRT) {
-               char *tmp_api_version = strdup(api_version);
-               TryReturn(tmp_api_version != NULL, , PRVMGR_ERR_OUT_OF_MEMORY, "[PRVMGR_ERR_OUT_OF_MEMORY] tmp_api_version's strdup is failed.");
-               size_t new_size = snprintf(0, 0, "%s%s", tmp_api_version, API_VERSION_PADDING) + 1;
-               tmp_api_version = realloc(tmp_api_version, new_size * sizeof(char));
-               TryReturn(tmp_api_version != NULL, free(tmp_api_version), PRVMGR_ERR_OUT_OF_MEMORY, "[PRVMGR_ERR_OUT_OF_MEMORY] tmp_api_version's realloc is failed.");
-               strncat(tmp_api_version, API_VERSION_PADDING, API_VERSION_PADDING_LEN);
-               for (i = 0; is_valid_wrt_version == 1 && i < MAX_API_VERSION_LEN; i++) {
-                       if (tmp_api_version[i] < wrt_active_version[i])
-                               is_valid_wrt_version = 0;
-                       else if (tmp_api_version[i] > wrt_active_version[i])
-                               break;
-               }
+               api_version_code_t wrt_active_version_code = 0;
+               ret = __get_api_version_code(wrt_active_version, &wrt_active_version_code);
+               TryReturn(ret == PRVMGR_ERR_NONE && wrt_active_version_code != 0, , PRVMGR_ERR_INTERNAL_ERROR, "[PRVMGR_ERR_INTERNAL_ERROR] __get_api_version_code() for wrt_active_version failed.");
+               if (wrt_active_version_code > api_version_code)
+                       is_valid_wrt_version = 0;
                pkg_type = strdup("WRT");
-               TryReturn(pkg_type != NULL, free(tmp_api_version), PRVMGR_ERR_OUT_OF_MEMORY, "[PRVMGR_ERR_OUT_OF_MEMORY] pkg_type's strdup is failed.");
                _LOGD("package type = %s, api version %s, is valid wrt version %d", pkg_type, api_version, is_valid_wrt_version);
                snprintf(guide_message, MESSAGE_SIZE, "Check config.xml| - Current required_version(=api version) = %s, |   ", api_version);
-               free(tmp_api_version);
        } else if (package_type == PRVMGR_PACKAGE_TYPE_CORE) {
                pkg_type = strdup("Native");
                TryReturn(pkg_type != NULL, , PRVMGR_ERR_OUT_OF_MEMORY, "[PRVMGR_ERR_OUT_OF_MEMORY] pkg_type's strdup is failed.");
@@ -505,8 +462,9 @@ int privilege_manager_get_mapped_privilege_list(const char *api_version, privile
 {
        int ret;
        TryReturn(api_version != NULL, , PRVMGR_ERR_INVALID_PARAMETER, "[PRVMGR_ERR_INVALID_PARAMETER] api_version is NULL.");
-       ret = __check_api_version_validity(api_version);
-       TryReturn(ret == PRVMGR_ERR_NONE, , PRVMGR_ERR_INVALID_PARAMETER, "[PRVMGR_ERR_INVALID_PARAMETER] %s is in invalid form. api_version form should be X.X, X.X.X or X.X.X.X(X=integer)", api_version);
+       api_version_code_t api_version_code;
+       ret = __get_api_version_code(api_version, &api_version_code);
+       TryReturn(ret == PRVMGR_ERR_NONE && api_version_code != 0, , PRVMGR_ERR_INVALID_PARAMETER, "[PRVMGR_ERR_INVALID_PARAMETER] %s is in invalid form. api_version form should be X.X, X.X.X or X.X.X.X(X=integer)", api_version);
 
        if (package_type != PRVMGR_PACKAGE_TYPE_WRT && package_type != PRVMGR_PACKAGE_TYPE_CORE) {
                _LOGE("[PRVMGR_ERR_INVALID_PARAMETER] package_type is not a PRVMGR_PACKAGE_TYPE_WRT or PRVMGR_PACKAGE_TYPE_CORE");
index ba12a69..ed7e973 100755 (executable)
@@ -297,6 +297,20 @@ static void __test_privilege_manager_verify_privilege()
        __tcinfo(expect, PRVMGR_ERR_INVALID_PARAMETER);
        __privilege_manager_verify_privilege();
 
+       __tcinfo(version_type, "2.3.0.256", "core");
+       __tcinfo(goal, "invalid api_version == 2.3.0.256");
+       __privinfo("http://tizen.org/privilege/internet", "Public", NULL);
+       __tcinfo(cert_level, "public");
+       __tcinfo(expect, PRVMGR_ERR_INVALID_PARAMETER);
+       __privilege_manager_verify_privilege();
+
+       __tcinfo(version_type, "2.3.1.255", "core");
+       __tcinfo(goal, "valid api_version == 2.3.1.255");
+       __privinfo("http://tizen.org/privilege/internet", "Public", NULL);
+       __tcinfo(cert_level, "public");
+       __tcinfo(expect, PRVMGR_ERR_NONE);
+       __privilege_manager_verify_privilege();
+
 #ifdef PROFILE_TYPE_MOBILE
 
        /* 2.3 core - mobile */