diff --git a/src/common.h b/src/common.h index d5db940..349e8b9 100644 --- a/src/common.h +++ b/src/common.h @@ -72,6 +72,7 @@ #define BUF_SIZE_256 (256 + 1) #define BUF_SIZE_2048 (2048 + 1) +#define ICWMP_TMP_PATH "/tmp/icwmp" #define FIREWALL_CWMP "/etc/firewall.cwmp" #define CWMP_VARSTATE_UCI_PACKAGE "/var/state/icwmp" #define DM_PPP_INTERFACE_PATH "Device\\.PPP\\.Interface\\." diff --git a/src/download.c b/src/download.c index fbf6a55..40f1800 100644 --- a/src/download.c +++ b/src/download.c @@ -120,6 +120,7 @@ int download_file_in_subprocess(const char *file_path, const char *url, const ch CWMP_LOG(ERROR, "download %s: url is null"); return 500; } + struct blob_buf bbuf; CWMP_MEMSET(&bbuf, 0, sizeof(struct blob_buf)); blob_buf_init(&bbuf, 0); @@ -133,8 +134,9 @@ int download_file_in_subprocess(const char *file_path, const char *url, const ch if (download_task != NULL) { char *ret = execute_task_in_subprocess(download_task); - return atoi(ret); + return ret ? atoi(ret) : 500; } + return 500; } /* @@ -412,7 +414,7 @@ int cwmp_apply_multiple_firmware_in_subprocess() { subprocess_start(apply_multiple_firmware_task_function); char *ret = execute_task_in_subprocess("{}"); //empty json object - return atoi(ret); + return ret ? atoi(ret) : 500; } int cwmp_launch_download(struct download *pdownload, char *download_file_name, enum load_type ltype, struct transfer_complete **ptransfer_complete) diff --git a/src/subprocess.c b/src/subprocess.c index 65fe29b..8878d5b 100644 --- a/src/subprocess.c +++ b/src/subprocess.c @@ -68,48 +68,52 @@ int subprocess_start(task_function task_fun) return CWMP_GEN_ERR; pid_t p; + if (pipe(pipefd1) == -1) { CWMP_LOG(ERROR, "pipefd1 failed\n"); return CWMP_GEN_ERR; } + if (pipe(pipefd2) == -1) { CWMP_LOG(ERROR, "pipefd2 failed\n"); return CWMP_GEN_ERR; } - p = fork(); - if (p == 0) { - while(1) { - char from_parent[512]; - int ret = 0; - read(pipefd1[0], from_parent, 512); //The received string should has the form {"task":"TaskName", "arg1_name":"xxx", "arg2_name":"xxxx"} - if (strlen(from_parent) == 0) - continue; - //get the task name - //if the task name is end - if (check_task_is_end(from_parent)) { - exit((write(pipefd2[1], EXIT_TASK, strlen(EXIT_TASK)+1) == -1) - ? EXIT_FAILURE : EXIT_SUCCESS); - } - char *to_child = task_fun(from_parent); + p = fork(); + if (p == 0) { + while(1) { + char from_parent[512]; + int ret = 0; - struct blob_buf bbuf; - CWMP_MEMSET(&bbuf, 0, sizeof(struct blob_buf)); - blob_buf_init(&bbuf, 0); - blobmsg_add_string(&bbuf, "ret", to_child ? to_child : "500"); - char *to_child_json = blobmsg_format_json(bbuf.head, true); + read(pipefd1[0], from_parent, 512); //The received string should has the form {"task":"TaskName", "arg1_name":"xxx", "arg2_name":"xxxx"} + if (strlen(from_parent) == 0) + continue; - ret = write(pipefd2[1], to_child_json, CWMP_STRLEN(to_child_json)+1); + //get the task name if the task name is end + if (check_task_is_end(from_parent)) { + exit((write(pipefd2[1], EXIT_TASK, strlen(EXIT_TASK)+1) == -1) + ? EXIT_FAILURE : EXIT_SUCCESS); + } - FREE(to_child); - FREE(to_child_json); - blob_buf_free(&bbuf); + char *to_child = task_fun(from_parent); - if (ret == -1) { - exit(EXIT_FAILURE); + struct blob_buf bbuf; + CWMP_MEMSET(&bbuf, 0, sizeof(struct blob_buf)); + blob_buf_init(&bbuf, 0); + blobmsg_add_string(&bbuf, "ret", to_child ? to_child : "500"); + char *to_child_json = blobmsg_format_json(bbuf.head, true); + + ret = write(pipefd2[1], to_child_json, CWMP_STRLEN(to_child_json)+1); + + FREE(to_child); + FREE(to_child_json); + blob_buf_free(&bbuf); + + if (ret == -1) { + exit(EXIT_FAILURE); + } } - } - } + } return CWMP_OK; } diff --git a/src/upload.c b/src/upload.c index 6eb453c..ce4dc4e 100644 --- a/src/upload.c +++ b/src/upload.c @@ -22,13 +22,13 @@ #include "subprocess.h" #include "session.h" -#define CURL_TIMEOUT 20 +#define CURL_TIMEOUT 30 int count_upload_queue = 0; LIST_HEAD(list_upload); -int lookup_vcf_name(int instance, char **value) +static int lookup_vcf_name(int instance, char **value) { char vcf_name_parameter[256]; LIST_HEAD(vcf_parameters); @@ -46,7 +46,7 @@ int lookup_vcf_name(int instance, char **value) return 0; } -int lookup_vlf_name(int instance, char **value) +static int lookup_vlf_name(int instance, char **value) { char vlf_name_parameter[256]; LIST_HEAD(vlf_parameters); @@ -67,9 +67,9 @@ int lookup_vlf_name(int instance, char **value) /* * Upload file */ -int upload_file(const char *file_path, const char *url, const char *username, const char *password) +static long upload_file(const char *file_path, const char *url, const char *username, const char *password) { - int res_code = 0; + long res_code = 0; CURL *curl; CURLcode res; FILE *fd_upload; @@ -77,24 +77,31 @@ int upload_file(const char *file_path, const char *url, const char *username, co if (url == NULL) { CWMP_LOG(ERROR, "upload %s: url is null", __FUNCTION__); - return -1; + return FAULT_CPE_INTERNAL_ERROR; } if (file_path == NULL) { CWMP_LOG(ERROR, "upload file name unknown"); - return -1; + return FAULT_CPE_INTERNAL_ERROR; } - if (0 != stat(file_path, &file_info)) { - CWMP_LOG(ERROR, "upload file %s not exists", file_path); - return -1; + if (!file_exists(file_path)) { + CWMP_LOG(ERROR, "upload_file %s does not exist", file_path); + return FAULT_CPE_INTERNAL_ERROR; } fd_upload = fopen(file_path, "rb"); if (fd_upload == NULL) { - CWMP_LOG(ERROR, "Failed to open url[%s] for upload", file_path); + CWMP_LOG(ERROR, "Failed to open file[%s] for upload", file_path); return FAULT_CPE_INTERNAL_ERROR; } + + if (fstat(fileno(fd_upload), &file_info) != 0) { + CWMP_LOG(ERROR, "Failed to get file info for %s\n", file_path); + fclose(fd_upload); + return FAULT_CPE_INTERNAL_ERROR; + } + curl_global_init(CURL_GLOBAL_ALL); curl = curl_easy_init(); @@ -104,18 +111,20 @@ int upload_file(const char *file_path, const char *url, const char *username, co snprintf(userpass, sizeof(userpass), "%s:%s", username, password ? password : ""); curl_easy_setopt(curl, CURLOPT_USERPWD, userpass); } + if (CWMP_STRNCMP(url, "https://", 8) == 0) curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, CURL_TIMEOUT); curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 50L); curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); - //curl_easy_setopt(curl, CURLOPT_POST, 1L); curl_easy_setopt(curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_ANY); curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_READDATA, fd_upload); curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)file_info.st_size); + res = curl_easy_perform(curl); - if(res != CURLE_OK) { + if (res != CURLE_OK) { CWMP_LOG(ERROR, "## curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); } @@ -130,13 +139,13 @@ int upload_file(const char *file_path, const char *url, const char *username, co char *upload_file_task_function(char *task) { - struct blob_buf bbuf; if (task == NULL) { CWMP_LOG(ERROR, "upload %s: task is null", __FUNCTION__); return NULL; } + CWMP_MEMSET(&bbuf, 0, sizeof(struct blob_buf)); blob_buf_init(&bbuf, 0); @@ -156,10 +165,13 @@ char *upload_file_task_function(char *task) char *username = blobmsg_get_string(tb[3]); char *password = blobmsg_get_string(tb[4]); - int http_code = upload_file(file_path, url, username, password); - char *http_ret = (char *)malloc(4 * sizeof(char)); - snprintf(http_ret, 4, "%d", http_code); - http_ret[3] = 0; + long http_code = upload_file(file_path, url, username, password); + char *http_ret = (char *)malloc(16 * sizeof(char)); + if (http_ret == NULL) + return NULL; + + snprintf(http_ret, 16, "%ld", http_code); + return http_ret; } @@ -184,7 +196,7 @@ int upload_file_in_subprocess(const char *file_path, const char *url, const char if (upload_task != NULL) { char *ret = execute_task_in_subprocess(upload_task); - return atoi(ret); + return ret ? atoi(ret) : 500; } return 500; } @@ -201,16 +213,23 @@ int cwmp_launch_upload(struct upload *pupload, struct transfer_complete **ptrans bkp_session_save(); char err_msg[256] = {0}; + if (!folder_exists(ICWMP_TMP_PATH)) { + int status = mkdir(ICWMP_TMP_PATH, S_IRWXU); + if (status != 0) { + snprintf(err_msg, sizeof(err_msg), "Failed to create (%s) folder", ICWMP_TMP_PATH); + goto end_upload; + } + } + if (pupload->file_type[0] == '1') { - snprintf(file_path, sizeof(file_path), "/tmp/all_configs"); + snprintf(file_path, sizeof(file_path), "%s/all_configs", ICWMP_TMP_PATH); cwmp_uci_init(); cwmp_uci_export(file_path, UCI_STANDARD_CONFIG); cwmp_uci_exit(); } else if (pupload->file_type[0] == '2') { lookup_vlf_name(1, &name); if (name && strlen(name) > 0) { - snprintf(file_path, sizeof(file_path), "/tmp/messages"); - // cppcheck-suppress uninitvar + snprintf(file_path, sizeof(file_path), "%s/messages", ICWMP_TMP_PATH); if (copy(name, file_path) != 0) { error = FAULT_CPE_UPLOAD_FAILURE; snprintf(err_msg, sizeof(err_msg), "Failed to copy the file content from %s to %s", file_path, name); @@ -223,7 +242,7 @@ int cwmp_launch_upload(struct upload *pupload, struct transfer_complete **ptrans } else if (pupload->file_type[0] == '3') { lookup_vcf_name(pupload->f_instance, &name); if (name && strlen(name) > 0) { - snprintf(file_path, sizeof(file_path), "/tmp/%s", name); + snprintf(file_path, sizeof(file_path), "%s/%s", ICWMP_TMP_PATH, name); cwmp_uci_init(); cwmp_uci_export_package(name, file_path, UCI_STANDARD_CONFIG); cwmp_uci_exit(); @@ -236,7 +255,7 @@ int cwmp_launch_upload(struct upload *pupload, struct transfer_complete **ptrans } else { //file_type is 4 lookup_vlf_name(pupload->f_instance, &name); if (name && strlen(name) > 0) { - snprintf(file_path, sizeof(file_path), "/tmp/.cwmp_upload"); + snprintf(file_path, sizeof(file_path), "%s/.cwmp_upload", ICWMP_TMP_PATH); if (copy(name, file_path) != 0) { error = FAULT_CPE_UPLOAD_FAILURE; snprintf(err_msg, sizeof(err_msg), "Failed to copy the file content from %s to %s", file_path, name);