diff options
author | Heonjae Jang and Juhee Park <pair+heonjae.jang+juhee82.park@samsung.com> | 2018-04-11 15:21:20 +0900 |
---|---|---|
committer | Heonjae Jang and Juhee Park <pair+heonjae.jang+juhee82.park@samsung.com> | 2018-04-11 15:21:20 +0900 |
commit | 6c5a901e3d290b4ba638e378a6e9d583ac2b4eee (patch) | |
tree | ad06766fea775852e49127fc5c5c9c41026ab2cd | |
parent | e14171633ddb2f489ca76f2987e271050e4d707e (diff) | |
download | ttsd-worker-package-6c5a901e3d290b4ba638e378a6e9d583ac2b4eee.tar.gz ttsd-worker-package-6c5a901e3d290b4ba638e378a6e9d583ac2b4eee.tar.bz2 ttsd-worker-package-6c5a901e3d290b4ba638e378a6e9d583ac2b4eee.zip |
Implements metadata parser and hash checkerh
-rwxr-xr-x | .pairs | 11 | ||||
-rw-r--r-- | CMakeLists.txt | 90 | ||||
-rw-r--r-- | inc/pm_downloader.h (renamed from inc/downloader.h) | 12 | ||||
-rw-r--r-- | inc/pm_installer.h (renamed from inc/installer.h) | 4 | ||||
-rw-r--r-- | inc/pm_result.h (renamed from inc/package-manager-result.h) | 0 | ||||
-rw-r--r-- | inc/pm_worker.h (renamed from inc/package-manager-worker.h) | 0 | ||||
-rw-r--r-- | org.tizen.package-manager-worker.xml | 2 | ||||
-rw-r--r-- | packaging/package-manager-worker.spec | 2 | ||||
-rw-r--r-- | src/downloader.c | 85 | ||||
-rw-r--r-- | src/pm_downloader.c | 286 | ||||
-rw-r--r-- | src/pm_installer.c (renamed from src/installer.c) | 7 | ||||
-rw-r--r-- | src/pm_result.c (renamed from src/package-manager-result.c) | 0 | ||||
-rw-r--r-- | src/pm_worker.c (renamed from src/package-manager-worker.c) | 90 |
13 files changed, 429 insertions, 160 deletions
@@ -0,0 +1,11 @@ +pairs: + # <initials>: <Firstname> <Lastname>[; <email-id>] + ey: Eunyung Lee; ey928.lee + jj: Jihee Choi; jjie.choi + hj: Heonjae Jang; heonjae.jang + jh: Juhee Park; juhee82.park +email: + prefix: pair + domain: samsung.com + no_solo_prefix: true +global: false # Set to true for git-pair to change git configuration for all your projects
\ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index e0171d1..ea0328f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,44 +1,46 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.6) -PROJECT(package-manager-worker C) - -INCLUDE(FindPkgConfig) -pkg_check_modules(APP_PKGS REQUIRED - dlog - capi-appfw-service-application - capi-appfw-package-manager - capi-appfw-app-manager - glib-2.0 - json-glib-1.0 - libcurl -) - -FOREACH (flag ${APP_PKGS_CFLAGS}) - SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") -ENDFOREACH(flag) - -SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -Wall -Winline -g -fno-builtin-malloc -fPIE") -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") -SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -pie") - -INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/inc) - -SET(SRCS - src/package-manager-worker.c - src/downloader.c - src/installer.c - src/package-manager-result.c - src/pm_report.c -) -ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS}) - -TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} -lm ${APP_PKGS_LDFLAGS}) - -SET(VENDOR "tizen") -SET(PACKAGE ${PROJECT_NAME}) -SET(PKGNAME "org.${VENDOR}.${PACKAGE}") -SET(PREFIX ${CMAKE_INSTALL_PREFIX}) -SET(BINDIR "${PREFIX}/bin") - -# application xml -INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${BINDIR}) -INSTALL(FILES ${CMAKE_BINARY_DIR}/${PKGNAME}.xml DESTINATION ${SYS_PACKAGES_DIR}) +CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(package-manager-worker C)
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(APP_PKGS REQUIRED
+ dlog
+ capi-appfw-service-application
+ capi-appfw-package-manager
+ capi-appfw-app-manager
+ glib-2.0
+ json-glib-1.0
+ libcurl
+ openssl
+ libcrypto
+)
+
+FOREACH (flag ${APP_PKGS_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -Wall -Winline -g -fno-builtin-malloc -fPIE")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -pie")
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/inc)
+
+SET(SRCS
+ src/pm_worker.c
+ src/pm_downloader.c
+ src/pm_installer.c
+ src/pm_result.c
+ src/pm_report.c
+)
+ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
+
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} -lm ${APP_PKGS_LDFLAGS})
+
+SET(VENDOR "tizen")
+SET(PACKAGE ${PROJECT_NAME})
+SET(PKGNAME "org.${VENDOR}.${PACKAGE}")
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(BINDIR "${PREFIX}/bin")
+
+# application xml
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${BINDIR})
+INSTALL(FILES ${CMAKE_BINARY_DIR}/${PKGNAME}.xml DESTINATION ${SYS_PACKAGES_DIR})
diff --git a/inc/downloader.h b/inc/pm_downloader.h index 8014964..99196e4 100644 --- a/inc/downloader.h +++ b/inc/pm_downloader.h @@ -17,6 +17,16 @@ #ifndef __PM_DOWNLOADER_H__ #define __PM_DOWNLOADER_H__ -char *pm_downloader_download(const char *url, const char *download_dir); +#include <stdbool.h> + +typedef struct { + char *url; + char *file_name; + char *hash; +} pm_downloader_metadata_s; + +pm_downloader_metadata_s *pm_downloader_get_metadata(const char *url); +bool pm_downloader_check_compatibility(const char *hash, const char* file_path); +char *pm_downloader_download(const char *url, const char *file_name, const char *download_dir); #endif /* __PM_DOWNLOADER_H__ */ diff --git a/inc/installer.h b/inc/pm_installer.h index 09b0854..ac86fee 100644 --- a/inc/installer.h +++ b/inc/pm_installer.h @@ -17,8 +17,8 @@ #ifndef __PM_INSTALLER_H__ #define __PM_INSTALLER_H__ -typedef void (pm_installer_res_cb)(const char *package, int result, void *user_data); +typedef void (*pm_installer_res_cb)(const char *package, int result, void *user_data); -int pm_installer_install(const char *path, pm_installer_res_cb *result_cb, void *cb_data); +int pm_installer_install(const char *path, pm_installer_res_cb result_cb, void *cb_data); #endif /* __PM_INSTALLER_H__ */ diff --git a/inc/package-manager-result.h b/inc/pm_result.h index 23bb309..23bb309 100644 --- a/inc/package-manager-result.h +++ b/inc/pm_result.h diff --git a/inc/package-manager-worker.h b/inc/pm_worker.h index 3814e86..3814e86 100644 --- a/inc/package-manager-worker.h +++ b/inc/pm_worker.h diff --git a/org.tizen.package-manager-worker.xml b/org.tizen.package-manager-worker.xml index 32e5601..2f95b40 100644 --- a/org.tizen.package-manager-worker.xml +++ b/org.tizen.package-manager-worker.xml @@ -12,6 +12,6 @@ <privilege>http://tizen.org/privilege/packagemanager.admin</privilege> <privilege>http://tizen.org/privilege/packagemanager.info</privilege> <privilege>http://tizen.org/privilege/packagemanager.clearcache</privilege> - <privilege>http://tizen.org/privilege/mediastorage</privilege> + <privilege>http://tizen.org/privilege/mediastorage</privilege> </privileges> </manifest> diff --git a/packaging/package-manager-worker.spec b/packaging/package-manager-worker.spec index 77769bc..72337c3 100644 --- a/packaging/package-manager-worker.spec +++ b/packaging/package-manager-worker.spec @@ -20,6 +20,8 @@ BuildRequires: pkgconfig(capi-appfw-app-manager) BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(json-glib-1.0) BuildRequires: pkgconfig(libcurl) +BuildRequires: pkgconfig(openssl) +BuildRequires: pkgconfig(libcrypto) %description Package manager worker diff --git a/src/downloader.c b/src/downloader.c deleted file mode 100644 index 0c2d34f..0000000 --- a/src/downloader.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2018 Samsung Electronics Co., Ltd. - * - * Licensed under the Flora License, Version 1.1 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://floralicense.org/license/ - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <app_common.h> -#include <curl/curl.h> -#include <stdlib.h> -#include <glib.h> -#include "log.h" - -static size_t _write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) -{ - size_t written = fwrite(ptr, size, nmemb, stream); - return written; -} - -char *pm_downloader_download(const char *url, const char *download_dir) -{ - CURL *curl = NULL; - FILE *fp = NULL; - char *downloaded_path = NULL; - - curl_global_init(CURL_GLOBAL_DEFAULT); - curl = curl_easy_init(); - - if (curl) { - CURLcode res; - char *file_name = NULL; - - file_name = g_path_get_basename(url); - downloaded_path = g_strdup_printf("%s%s", download_dir, file_name); - - free(file_name); - file_name = NULL; - - _D("download_path : {%s}", url); - _D("downloaded_path : {%s}", downloaded_path); - - fp = fopen(downloaded_path, "wb"); - if (!fp) { - _E("Failed to open file - %s", downloaded_path); - goto ERROR; - } - - curl_easy_setopt(curl, CURLOPT_URL, url); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _write_data); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); - res = curl_easy_perform(curl); - - if (res != CURLE_OK) { - _E("curl_easy_perform() failed: %s", curl_easy_strerror(res)); - goto ERROR; - } - - _D("Download Success: {%s}", downloaded_path); - curl_easy_cleanup(curl); - fclose(fp); - } - curl_global_cleanup(); - return downloaded_path; - -ERROR: - free(downloaded_path); - - if (curl) - curl_easy_cleanup(curl); - - if (fp) - fclose(fp); - - curl_global_cleanup(); - return NULL; -} diff --git a/src/pm_downloader.c b/src/pm_downloader.c new file mode 100644 index 0000000..620aa55 --- /dev/null +++ b/src/pm_downloader.c @@ -0,0 +1,286 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Flora License, Version 1.1 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <app_common.h> +#include <curl/curl.h> +#include <stdlib.h> +#include <glib.h> +#include <json-glib/json-glib.h> +#include <openssl/md5.h> +#include "log.h" +#include "pm_downloader.h" + + +static size_t _write_data(void *ptr, size_t size, size_t nmemb, char **data) +{ +/* + size_t old_length = data ? strlen(data) : 0; + char** temp = (char**)data; + _D("%d",old_length); + size_t new_length = size * nmemb + old_length; + _D("%d",new_length); + //_D("%s", data); + *temp = realloc(data, new_length + 1) ; + //_D("%s", data); + if(data == NULL){ + _D("FAIL"); + return 0; + } + memcpy(data + old_length, ptr, size * nmemb); + //_D("%s", data); + //temp[new_length] = '\0'; +*/ +/* + char **result = (char **)data; + if (NULL == *result) { + *result = malloc(size * nmemb + 1); + memcpy(*result, ptr, size * nmemb); + } else { + size_t len = strlen(*result); + char* result_temp = *result; + *result = realloc(*result, len + size * nmemb + 1); + if (*result == NULL) + free(result_temp); + memcpy(*result + len, ptr, size * nmemb); + (*result)[len+size*nmemb] = '\0'; + } +*/ + char *c; + + if(asprintf(&c, "%.*s%.*s", strlen(data), *data, size * nmemb, ptr) == -1){ + free(*data); + data = NULL; + return -1; + } + + free(*data); + *data = strdup(c); + free (c); + + return size * nmemb; +} + +static size_t _write_file(void *ptr, size_t size, size_t nmemb, FILE *stream) +{ + size_t written = fwrite(ptr, size, nmemb, stream); + return written; +} + +pm_downloader_metadata_s *_parsing_metadata(const char *data) +{ + pm_downloader_metadata_s *ret = (pm_downloader_metadata_s*)malloc(sizeof(pm_downloader_metadata_s)); + JsonParser *parser = json_parser_new(); + JsonNode *root = NULL; + GError *error = NULL; + + if(json_parser_load_from_data(parser, data, -1, &error)){ + _D("Start Parse"); + root = json_parser_get_root(parser); + JsonObject *object = NULL; + object = json_node_get_object(root); + if (object != NULL) { + GList * keysList = NULL; + GList * valsList = NULL; + guint size; + + keysList = json_object_get_members(object); + valsList = json_object_get_values(object); + size = json_object_get_size(object); + + JsonNode *tmpNode; + + for (int j = 0; j < size; j++) { + if(keysList && valsList){ + char *key = (char *)keysList->data; + JsonNode *value = (JsonNode *)valsList->data; + _D("%s", key); + _D("%s", (char *) json_node_dup_string(value)); + if(!strcmp(key, "url")){ + ret->url = (char *) json_node_dup_string(value); + } else if(!strcmp(key, "filename")){ + ret->file_name = (char *) json_node_dup_string(value); + } else if(!strcmp(key, "hash")){ + ret->hash = (char *) json_node_dup_string(value); + } + } + keysList = g_list_next(keysList); + valsList = g_list_next(valsList); + } + + g_object_unref(tmpNode); + g_list_free(keysList); + g_list_free(valsList); + } + if(object){ + g_object_unref(object); + } + } + + if(root){ + g_object_unref(root); + } + + if (parser){ + g_object_unref(parser); + } + + if (error){ + g_error_free(error); + } + return ret; +} + +pm_downloader_metadata_s *pm_downloader_get_metadata(const char *url) +{ + CURL *curl = NULL; + char *data = NULL; + pm_downloader_metadata_s *ret = NULL; + + curl_global_init(CURL_GLOBAL_DEFAULT); + curl = curl_easy_init(); + + if (curl) { + CURLcode res; + + _D("download_path : {%s}", url); + + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _write_data); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &data); + res = curl_easy_perform(curl); + + if (res != CURLE_OK) { + _E("curl_easy_perform() failed: %s", curl_easy_strerror(res)); + goto ERROR; + } + + _D("Download Success: {%s}", data); + curl_easy_cleanup(curl); + + if(data){ + ret = _parsing_metadata(data); + } + + _D("End Parse"); + } + curl_global_cleanup(); + + return ret; +ERROR: + if(ret){ + free(ret); + } + + if (curl){ + curl_easy_cleanup(curl); + } + + curl_global_cleanup(); + return NULL; +} + +bool pm_downloader_check_compatibility(const char *hash, const char* file_path) +{ + FILE *fp = fopen (file_path, "rb"); + MD5_CTX context; + int bytes; + int i; + unsigned char data[1024]; + unsigned char digest[MD5_DIGEST_LENGTH]; + char file_hash[50] = { 0, }; + if(fp == NULL){ + _D("can't be opened"); + return false; + } + + MD5_Init(&context); + while ((bytes = fread (data, 1, 1024, fp)) != 0){ + MD5_Update(&context, data, bytes); + } + + MD5_Final(digest, &context); + for (i = 0; i<MD5_DIGEST_LENGTH; ++i){ + sprintf(file_hash + (i * 2), "%02x", digest[i]); + } + + if (fp){ + fclose(fp); + } + + if (strcmp(hash, file_hash)){ + _D("Hash is different!"); + _D("Server Hash: \t%s",hash); + _D("File Hash: \t%s",file_hash); + return false; + } + + return true; +} + +char *pm_downloader_download(const char *url, const char *file_name, const char *download_dir) +{ + CURL *curl = NULL; + FILE *fp = NULL; + char *downloaded_path = NULL; + + curl_global_init(CURL_GLOBAL_DEFAULT); + curl = curl_easy_init(); + + if (curl) { + CURLcode res; + downloaded_path = g_strdup_printf("%s%s", download_dir, file_name); + + _D("download_path : {%s}", url); + _D("downloaded_path : {%s}", downloaded_path); + + fp = fopen(downloaded_path, "wb"); + if (!fp) { + _E("Failed to open file - %s", downloaded_path); + goto ERROR; + } + + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _write_file); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); + res = curl_easy_perform(curl); + + if (res != CURLE_OK) { + _E("curl_easy_perform() failed: %s", curl_easy_strerror(res)); + goto ERROR; + } + + _D("Download Success"); + curl_easy_cleanup(curl); + fclose(fp); + } + + curl_global_cleanup(); + return downloaded_path; +ERROR: + free(downloaded_path); + + if (curl){ + curl_easy_cleanup(curl); + } + + if (fp){ + fclose(fp); + } + + curl_global_cleanup(); + return NULL; +} + diff --git a/src/installer.c b/src/pm_installer.c index 20d3e06..85ce1af 100644 --- a/src/installer.c +++ b/src/pm_installer.c @@ -15,14 +15,14 @@ */ #include "log.h" -#include "installer.h" +#include "pm_installer.h" #include <package_manager.h> #include <glib.h> typedef struct __pm_installer_s { package_manager_request_h handle; int request_id; - pm_installer_res_cb *result_cb; + pm_installer_res_cb result_cb; void * cb_data; } pm_installer_s; @@ -52,8 +52,9 @@ static void _install_cb(int id, const char *type, const char *package, } } -int pm_installer_install(const char *path, pm_installer_res_cb *result_cb, void *cb_data) +int pm_installer_install(const char *path, pm_installer_res_cb result_cb, void *cb_data) { + _D("Install Start"); int ret = 0; int request_id = 0; pm_installer_s *pmi_d = NULL; diff --git a/src/package-manager-result.c b/src/pm_result.c index 82a23a0..82a23a0 100644 --- a/src/package-manager-result.c +++ b/src/pm_result.c diff --git a/src/package-manager-worker.c b/src/pm_worker.c index 8dc94c6..b8c079e 100644 --- a/src/package-manager-worker.c +++ b/src/pm_worker.c @@ -1,4 +1,4 @@ -/* + /* * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Flora License, Version 1.1 (the License); @@ -15,24 +15,26 @@ */ #include "log.h" -#include "downloader.h" -#include "installer.h" +#include "pm_downloader.h" +#include "pm_installer.h" #include "pm_report.h" -#include "package-manager-result.h" +#include "pm_result.h" #include <service_app.h> #include <stdlib.h> -#define TEST_PKG_URL "https://s3.ap-northeast-2.amazonaws.com/dm-firmware-bucket/firmwares/sumin.lim%40samsung.com/org.example.basic-ui-1.0.0-arm.tpk" +#define TEST_URL "https://test.showiot.xyz/api/package/metadata?id=test-page1523421701067&key=175b6545cca4f96bcd9ff2d1dcd6666bbafb1bec" static void __pkg_install_result_callback(const char *package, int result, void *user_data) { char *result_str = NULL; - if (result) - result_str = pm_result_get_install(package, true, NULL); - else /* TODO : read error code from result value */ + if (result){ result_str = pm_result_get_install(package, false, "INSTALL_PKG_FAILED"); + } + else { + result_str = pm_result_get_install(package, true, "INSTALL_PKG_SUCCESS"); + } pm_worker_report_result(result_str); free(result_str); @@ -59,31 +61,71 @@ static void service_app_control(app_control_h app_control, void *data) char *downloaded_pkg = NULL; char *data_path = NULL; - + char *result_str = NULL; + bool error = false; + bool is_valid = false; + pm_downloader_metadata_s * metadata = NULL; data_path = app_get_data_path(); - downloaded_pkg = pm_downloader_download(TEST_PKG_URL, data_path); + + metadata = pm_downloader_get_metadata(TEST_URL); + downloaded_pkg = pm_downloader_download(metadata->url, metadata->file_name, data_path); + free(data_path); if (!downloaded_pkg) { /* TODO : Reasons should be redefined */ - char *result_str = + result_str = pm_result_get_install(downloaded_pkg, false, "DOWNLOAD_FAILED"); pm_worker_report_result(result_str); - free(result_str); - service_app_exit(); + error = true; } else { - int ret = 0; - ret = pm_installer_install( - downloaded_pkg, __pkg_install_result_callback, NULL); - - if (ret) { - /* TODO : Reasons should be redefined */ - char *result_str = - pm_result_get_install(downloaded_pkg, false, "PKG_MANAGER_ERROR"); - pm_worker_report_result(result_str); - free(result_str); - service_app_exit(); + + is_valid = pm_downloader_check_compatibility(metadata->hash, downloaded_pkg); + if(!is_valid) { + result_str = + pm_result_get_install(downloaded_pkg, false, "HASH_CHECK_FAILED"); + error = true; } + else { + int ret = 0; + ret = pm_installer_install( + downloaded_pkg, __pkg_install_result_callback, NULL); + + if (ret) { + /* TODO : Reasons should be redefined */ + result_str = + pm_result_get_install(downloaded_pkg, false, "PKG_MANAGER_ERROR"); + pm_worker_report_result(result_str); + error = true; + } + + + } + + } + + if(metadata->url){ + free(metadata->url); + metadata->url = NULL; + } + if(metadata->hash){ + free(metadata->hash); + metadata->hash = NULL; + } + if(metadata){ + free(metadata); + metadata = NULL; + } + if(result_str){ + free(result_str); + result_str = NULL; + } + if(downloaded_pkg){ + free(downloaded_pkg); + downloaded_pkg = NULL; + } + if(error){ + service_app_exit(); } return; } |