diff --git a/common.c b/common.c index c5e8549..48ce027 100755 --- a/common.c +++ b/common.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "common.h" #include "cwmp_uci.h" @@ -41,36 +42,60 @@ struct cwmp_mem { char mem[0]; }; -struct option cwmp_long_options[] = { { "boot-event", no_argument, NULL, 'b' }, { "get-rpc-methods", no_argument, NULL, 'g' }, { "command-input", no_argument, NULL, 'c' }, { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'v' }, { NULL, 0, NULL, 0 } }; +struct option cwmp_long_options[] = { + { "boot-event", no_argument, NULL, 'b' }, { "get-rpc-methods", no_argument, NULL, 'g' }, + { "command-input", no_argument, NULL, 'c' }, { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, 'v' }, { NULL, 0, NULL, 0 } +}; -struct FAULT_CPE FAULT_CPE_ARRAY[] = { [FAULT_CPE_METHOD_NOT_SUPPORTED] = { "9000", FAULT_9000, FAULT_CPE_TYPE_SERVER, "Method not supported" }, - [FAULT_CPE_REQUEST_DENIED] = { "9001", FAULT_9001, FAULT_CPE_TYPE_SERVER, "Request denied (no reason specified)" }, - [FAULT_CPE_INTERNAL_ERROR] = { "9002", FAULT_9002, FAULT_CPE_TYPE_SERVER, "Internal error" }, - [FAULT_CPE_INVALID_ARGUMENTS] = { "9003", FAULT_9003, FAULT_CPE_TYPE_CLIENT, "Invalid arguments" }, - [FAULT_CPE_RESOURCES_EXCEEDED] = { "9004", FAULT_9004, FAULT_CPE_TYPE_SERVER, "Resources exceeded" }, - [FAULT_CPE_INVALID_PARAMETER_NAME] = { "9005", FAULT_9005, FAULT_CPE_TYPE_CLIENT, "Invalid parameter name" }, - [FAULT_CPE_INVALID_PARAMETER_TYPE] = { "9006", FAULT_9006, FAULT_CPE_TYPE_CLIENT, "Invalid parameter type" }, - [FAULT_CPE_INVALID_PARAMETER_VALUE] = { "9007", FAULT_9007, FAULT_CPE_TYPE_CLIENT, "Invalid parameter value" }, - [FAULT_CPE_NON_WRITABLE_PARAMETER] = { "9008", FAULT_9008, FAULT_CPE_TYPE_CLIENT, "Attempt to set a non-writable parameter" }, - [FAULT_CPE_NOTIFICATION_REJECTED] = { "9009", FAULT_9009, FAULT_CPE_TYPE_SERVER, "Notification request rejected" }, - [FAULT_CPE_DOWNLOAD_FAILURE] = { "9010", FAULT_9010, FAULT_CPE_TYPE_SERVER, "Download failure" }, - [FAULT_CPE_UPLOAD_FAILURE] = { "9011", FAULT_9011, FAULT_CPE_TYPE_SERVER, "Upload failure" }, - [FAULT_CPE_FILE_TRANSFER_AUTHENTICATION_FAILURE] = { "9012", FAULT_9012, FAULT_CPE_TYPE_SERVER, "File transfer server authentication failure" }, - [FAULT_CPE_FILE_TRANSFER_UNSUPPORTED_PROTOCOL] = { "9013", FAULT_9013, FAULT_CPE_TYPE_SERVER, "Unsupported protocol for file transfer" }, - [FAULT_CPE_DOWNLOAD_FAIL_MULTICAST_GROUP] = { "9014", FAULT_9014, FAULT_CPE_TYPE_SERVER, "Download failure: unable to join multicast group" }, - [FAULT_CPE_DOWNLOAD_FAIL_CONTACT_SERVER] = { "9015", FAULT_9015, FAULT_CPE_TYPE_SERVER, "Download failure: unable to contact file server" }, - [FAULT_CPE_DOWNLOAD_FAIL_ACCESS_FILE] = { "9016", FAULT_9016, FAULT_CPE_TYPE_SERVER, "Download failure: unable to access file" }, - [FAULT_CPE_DOWNLOAD_FAIL_COMPLETE_DOWNLOAD] = { "9017", FAULT_9017, FAULT_CPE_TYPE_SERVER, "Download failure: unable to complete download" }, - [FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED] = { "9018", FAULT_9018, FAULT_CPE_TYPE_SERVER, "Download failure: file corrupted" }, - [FAULT_CPE_DOWNLOAD_FAIL_FILE_AUTHENTICATION] = { "9019", FAULT_9019, FAULT_CPE_TYPE_SERVER, "Download failure: file authentication failure" }, - [FAULT_CPE_DOWNLOAD_FAIL_WITHIN_TIME_WINDOW] = { "9020", FAULT_9020, FAULT_CPE_TYPE_SERVER, "Download failure: unable to complete download" }, - [FAULT_CPE_DUPLICATE_DEPLOYMENT_UNIT] = { "9026", FAULT_9026, FAULT_CPE_TYPE_SERVER, "Duplicate deployment unit" }, - [FAULT_CPE_SYSTEM_RESOURCES_EXCEEDED] = { "9027", FAULT_9027, FAULT_CPE_TYPE_SERVER, "System ressources exceeded" }, - [FAULT_CPE_UNKNOWN_DEPLOYMENT_UNIT] = { "9028", FAULT_9028, FAULT_CPE_TYPE_SERVER, "Unknown deployment unit" }, - [FAULT_CPE_INVALID_DEPLOYMENT_UNIT_STATE] = { "9029", FAULT_9029, FAULT_CPE_TYPE_SERVER, "Invalid deployment unit state" }, - [FAULT_CPE_INVALID_DOWNGRADE_REJECTED] = { "9030", FAULT_9030, FAULT_CPE_TYPE_SERVER, "Invalid deployment unit Update: Downgrade not permitted" }, - [FAULT_CPE_INVALID_UPDATE_VERSION_UNSPECIFIED] = { "9031", FAULT_9031, FAULT_CPE_TYPE_SERVER, "Invalid deployment unit Update: Version not specified" }, - [FAULT_CPE_INVALID_UPDATE_VERSION_EXIST] = { "9031", FAULT_9032, FAULT_CPE_TYPE_SERVER, "Invalid deployment unit Update: Version already exist" } }; +struct FAULT_CPE FAULT_CPE_ARRAY[] = { + [FAULT_CPE_METHOD_NOT_SUPPORTED] = { "9000", FAULT_9000, FAULT_CPE_TYPE_SERVER, "Method not supported" }, + [FAULT_CPE_REQUEST_DENIED] = { "9001", FAULT_9001, FAULT_CPE_TYPE_SERVER, + "Request denied (no reason specified)" }, + [FAULT_CPE_INTERNAL_ERROR] = { "9002", FAULT_9002, FAULT_CPE_TYPE_SERVER, "Internal error" }, + [FAULT_CPE_INVALID_ARGUMENTS] = { "9003", FAULT_9003, FAULT_CPE_TYPE_CLIENT, "Invalid arguments" }, + [FAULT_CPE_RESOURCES_EXCEEDED] = { "9004", FAULT_9004, FAULT_CPE_TYPE_SERVER, "Resources exceeded" }, + [FAULT_CPE_INVALID_PARAMETER_NAME] = { "9005", FAULT_9005, FAULT_CPE_TYPE_CLIENT, "Invalid parameter name" }, + [FAULT_CPE_INVALID_PARAMETER_TYPE] = { "9006", FAULT_9006, FAULT_CPE_TYPE_CLIENT, "Invalid parameter type" }, + [FAULT_CPE_INVALID_PARAMETER_VALUE] = { "9007", FAULT_9007, FAULT_CPE_TYPE_CLIENT, "Invalid parameter value" }, + [FAULT_CPE_NON_WRITABLE_PARAMETER] = { "9008", FAULT_9008, FAULT_CPE_TYPE_CLIENT, + "Attempt to set a non-writable parameter" }, + [FAULT_CPE_NOTIFICATION_REJECTED] = { "9009", FAULT_9009, FAULT_CPE_TYPE_SERVER, + "Notification request rejected" }, + [FAULT_CPE_DOWNLOAD_FAILURE] = { "9010", FAULT_9010, FAULT_CPE_TYPE_SERVER, "Download failure" }, + [FAULT_CPE_UPLOAD_FAILURE] = { "9011", FAULT_9011, FAULT_CPE_TYPE_SERVER, "Upload failure" }, + [FAULT_CPE_FILE_TRANSFER_AUTHENTICATION_FAILURE] = { "9012", FAULT_9012, FAULT_CPE_TYPE_SERVER, + "File transfer server authentication failure" }, + [FAULT_CPE_FILE_TRANSFER_UNSUPPORTED_PROTOCOL] = { "9013", FAULT_9013, FAULT_CPE_TYPE_SERVER, + "Unsupported protocol for file transfer" }, + [FAULT_CPE_DOWNLOAD_FAIL_MULTICAST_GROUP] = { "9014", FAULT_9014, FAULT_CPE_TYPE_SERVER, + "Download failure: unable to join multicast group" }, + [FAULT_CPE_DOWNLOAD_FAIL_CONTACT_SERVER] = { "9015", FAULT_9015, FAULT_CPE_TYPE_SERVER, + "Download failure: unable to contact file server" }, + [FAULT_CPE_DOWNLOAD_FAIL_ACCESS_FILE] = { "9016", FAULT_9016, FAULT_CPE_TYPE_SERVER, + "Download failure: unable to access file" }, + [FAULT_CPE_DOWNLOAD_FAIL_COMPLETE_DOWNLOAD] = { "9017", FAULT_9017, FAULT_CPE_TYPE_SERVER, + "Download failure: unable to complete download" }, + [FAULT_CPE_DOWNLOAD_FAIL_FILE_CORRUPTED] = { "9018", FAULT_9018, FAULT_CPE_TYPE_SERVER, + "Download failure: file corrupted" }, + [FAULT_CPE_DOWNLOAD_FAIL_FILE_AUTHENTICATION] = { "9019", FAULT_9019, FAULT_CPE_TYPE_SERVER, + "Download failure: file authentication failure" }, + [FAULT_CPE_DOWNLOAD_FAIL_WITHIN_TIME_WINDOW] = { "9020", FAULT_9020, FAULT_CPE_TYPE_SERVER, + "Download failure: unable to complete download" }, + [FAULT_CPE_DUPLICATE_DEPLOYMENT_UNIT] = { "9026", FAULT_9026, FAULT_CPE_TYPE_SERVER, + "Duplicate deployment unit" }, + [FAULT_CPE_SYSTEM_RESOURCES_EXCEEDED] = { "9027", FAULT_9027, FAULT_CPE_TYPE_SERVER, + "System ressources exceeded" }, + [FAULT_CPE_UNKNOWN_DEPLOYMENT_UNIT] = { "9028", FAULT_9028, FAULT_CPE_TYPE_SERVER, "Unknown deployment unit" }, + [FAULT_CPE_INVALID_DEPLOYMENT_UNIT_STATE] = { "9029", FAULT_9029, FAULT_CPE_TYPE_SERVER, + "Invalid deployment unit state" }, + [FAULT_CPE_INVALID_DOWNGRADE_REJECTED] = { "9030", FAULT_9030, FAULT_CPE_TYPE_SERVER, + "Invalid deployment unit Update: Downgrade not permitted" }, + [FAULT_CPE_INVALID_UPDATE_VERSION_UNSPECIFIED] = { "9031", FAULT_9031, FAULT_CPE_TYPE_SERVER, + "Invalid deployment unit Update: Version not specified" }, + [FAULT_CPE_INVALID_UPDATE_VERSION_EXIST] = { "9031", FAULT_9032, FAULT_CPE_TYPE_SERVER, + "Invalid deployment unit Update: Version already exist" } +}; static void show_help(void) { @@ -122,7 +147,8 @@ int global_env_init(int argc, char **argv, struct env *env) /* * List dm_paramter */ -void add_dm_parameter_to_list(struct list_head *head, char *param_name, char *param_val, char *param_type, int notification, bool writable) +void add_dm_parameter_to_list(struct list_head *head, char *param_name, char *param_val, char *param_type, + int notification, bool writable) { struct cwmp_dm_parameter *dm_parameter; struct list_head *ilist; @@ -301,9 +327,13 @@ int update_firewall_cwmp_file(int port, char *zone_name, char *ip_addr, int ip_t fprintf(fp, " iptables -X zone_icwmp_input 2> /dev/null\n"); fprintf(fp, "fi\n"); if (ip_type == 0) - fprintf(fp, "iptables -I zone_%s_input -p tcp -s %s --dport %d -j ACCEPT -m comment --comment=\"Open ACS port\"\n", zone_name, ip_addr, port); + fprintf(fp, + "iptables -I zone_%s_input -p tcp -s %s --dport %d -j ACCEPT -m comment --comment=\"Open ACS port\"\n", + zone_name, ip_addr, port); else - fprintf(fp, "ip6tables -I zone_%s_input -p tcp -s %s --dport %d -j ACCEPT -m comment --comment=\"Open ACS port\"\n", zone_name, ip_addr, port); + fprintf(fp, + "ip6tables -I zone_%s_input -p tcp -s %s --dport %d -j ACCEPT -m comment --comment=\"Open ACS port\"\n", + zone_name, ip_addr, port); fclose(fp); return 0; } @@ -602,7 +632,60 @@ void icwmp_restart_services() if (strlen(list_services[i]) == 0) continue; - cwmp_ubus_call("uci", "commit", CWMP_UBUS_ARGS{ { "config", { .str_val = list_services[i] }, UBUS_String } }, 1, NULL, NULL); + cwmp_ubus_call("uci", "commit", + CWMP_UBUS_ARGS{ { "config", { .str_val = list_services[i] }, UBUS_String } }, 1, NULL, + NULL); } icwmp_free_list_services(); } + +/* + * Arguments validation + */ +bool icwmp_validate_string_length(char *arg, int max_length) +{ + if (arg != NULL && strlen(arg) > max_length) + return false; + return true; +} + +bool icwmp_validate_boolean_value(char *arg) +{ + if (!arg ||( strcmp(arg, "1") != 0 && strcmp(arg, "0") != 0 && strcmp(arg, "true") != 0 && strcmp(arg, "false") != 0)) + return false; + return true; +} + +bool icwmp_validate_unsignedint(char *arg) +{ + int arg_int; + + if(arg == NULL) + return false; + + if (strcmp(arg, "0") == 0) + arg_int = 0; + else { + arg_int = atoi(arg); + if (arg_int == 0) + return false; + } + return arg_int >= 0; +} + +bool icwmp_validate_int_in_range(char *arg, int min, int max) +{ + int arg_int; + + if(arg == NULL) + return false; + + if (strcmp(arg, "0") == 0) + arg_int = 0; + else { + arg_int = atoi(arg); + if (arg_int == 0) + return false; + } + return arg_int >= min && arg_int <= max; +} diff --git a/inc/common.h b/inc/common.h index 2a73c7a..bc9d6ba 100644 --- a/inc/common.h +++ b/inc/common.h @@ -143,22 +143,16 @@ typedef struct cwmp { int cr_socket_desc; } cwmp; -enum action -{ +enum action { NONE = 0, START, STOP, RESTART, }; -enum cwmp_start -{ - CWMP_START_BOOT = 1, - CWMP_START_PERIODIC = 2 -}; +enum cwmp_start { CWMP_START_BOOT = 1, CWMP_START_PERIODIC = 2 }; -enum cwmp_ret_err -{ +enum cwmp_ret_err { CWMP_XML_ERR = -1, CWMP_OK = 0, /* No Error */ CWMP_GEN_ERR, /* General Error */ @@ -167,18 +161,9 @@ enum cwmp_ret_err CWMP_RETRY_SESSION }; -enum http_compression -{ - COMP_NONE, - COMP_GZIP, - COMP_DEFLATE -}; +enum http_compression { COMP_NONE, COMP_GZIP, COMP_DEFLATE }; -enum enum_ip_version -{ - IPv4 = 4, - IPv6 = 6 -}; +enum enum_ip_version { IPv4 = 4, IPv6 = 6 }; typedef struct rpc { struct list_head list; @@ -202,8 +187,7 @@ struct cwmp_dm_parameter { bool writable; }; -enum amd_version_enum -{ +enum amd_version_enum { AMD_1 = 1, AMD_2, AMD_3, @@ -211,11 +195,7 @@ enum amd_version_enum AMD_5, }; -enum instance_mode -{ - INSTANCE_MODE_NUMBER, - INSTANCE_MODE_ALIAS -}; +enum instance_mode { INSTANCE_MODE_NUMBER, INSTANCE_MODE_ALIAS }; struct cwmp_namespaces { char *soap_env; @@ -225,8 +205,7 @@ struct cwmp_namespaces { char *cwmp; } ns; -enum rpc_cpe_methods_idx -{ +enum rpc_cpe_methods_idx { RPC_CPE_GET_RPC_METHODS = 1, RPC_CPE_SET_PARAMETER_VALUES, RPC_CPE_GET_PARAMETER_VALUES, @@ -248,8 +227,7 @@ enum rpc_cpe_methods_idx __RPC_CPE_MAX }; -enum rpc_acs_methods_idx -{ +enum rpc_acs_methods_idx { RPC_ACS_INFORM = 1, RPC_ACS_GET_RPC_METHODS, RPC_ACS_TRANSFER_COMPLETE, @@ -257,22 +235,11 @@ enum rpc_acs_methods_idx __RPC_ACS_MAX }; -enum load_type -{ - TYPE_DOWNLOAD = 0, - TYPE_SCHEDULE_DOWNLOAD, - TYPE_UPLOAD -}; +enum load_type { TYPE_DOWNLOAD = 0, TYPE_SCHEDULE_DOWNLOAD, TYPE_UPLOAD }; -enum dustate_type -{ - DU_INSTALL = 1, - DU_UPDATE, - DU_UNINSTALL -}; +enum dustate_type { DU_INSTALL = 1, DU_UPDATE, DU_UNINSTALL }; -enum fault_cpe_idx -{ +enum fault_cpe_idx { FAULT_CPE_NO_FAULT, FAULT_CPE_METHOD_NOT_SUPPORTED, FAULT_CPE_REQUEST_DENIED, @@ -305,8 +272,7 @@ enum fault_cpe_idx __FAULT_CPE_MAX }; -enum fault_code_enum -{ +enum fault_code_enum { FAULT_9000 = 9000, // Method not supported FAULT_9001, // Request denied FAULT_9002, // Internal error @@ -343,11 +309,7 @@ enum fault_code_enum __FAULT_MAX }; -enum client_server_faults -{ - FAULT_CPE_TYPE_CLIENT, - FAULT_CPE_TYPE_SERVER -}; +enum client_server_faults { FAULT_CPE_TYPE_CLIENT, FAULT_CPE_TYPE_SERVER }; struct rpc_cpe_method { const char *name; @@ -475,7 +437,8 @@ extern struct cwmp cwmp_main; extern long int flashsize; extern struct FAULT_CPE FAULT_CPE_ARRAY[]; -void add_dm_parameter_to_list(struct list_head *head, char *param_name, char *param_data, char *param_type, int notification, bool writable); +void add_dm_parameter_to_list(struct list_head *head, char *param_name, char *param_data, char *param_type, + int notification, bool writable); void delete_dm_parameter_from_list(struct cwmp_dm_parameter *dm_parameter); void cwmp_free_all_dm_parameter_list(struct list_head *list); int global_env_init(int argc, char **argv, struct env *env); @@ -510,20 +473,24 @@ void icwmp_init_list_services(); int icwmp_add_service(char *service); void icwmp_free_list_services(); void icwmp_restart_services(); +bool icwmp_validate_string_length(char *arg, int max_length); +bool icwmp_validate_boolean_value(char *arg); +bool icwmp_validate_unsignedint(char *arg); +bool icwmp_validate_int_in_range(char *arg, int min, int max); #ifndef FREE -#define FREE(x) \ - do { \ - if (x) { \ - free(x); \ - x = NULL; \ - } \ +#define FREE(x) \ + do { \ + if (x) { \ + free(x); \ + x = NULL; \ + } \ } while (0) #endif -#define CWMP_STRNCPY(DST, SRC, SIZE) \ - do { \ - strncpy(DST, SRC, SIZE - 1); \ - DST[SIZE - 1] = '\0'; \ +#define CWMP_STRNCPY(DST, SRC, SIZE) \ + do { \ + strncpy(DST, SRC, SIZE - 1); \ + DST[SIZE - 1] = '\0'; \ } while (0) #endif diff --git a/rpc_soap.c b/rpc_soap.c index 6f40861..a07d947 100755 --- a/rpc_soap.c +++ b/rpc_soap.c @@ -851,6 +851,12 @@ int cwmp_handle_rpc_cpe_get_parameter_names(struct session *session, struct rpc } b = mxmlWalkNext(b, session->body_in, MXML_DESCEND); } + + if (!icwmp_validate_boolean_value(NextLevel)) { + fault_code = FAULT_CPE_INVALID_ARGUMENTS; + goto fault; + } + if (parameter_name && NextLevel) { char *err = cwmp_get_parameter_names(parameter_name, strcmp(NextLevel, "true") == 0 || strcmp(NextLevel, "1") == 0 ? true : false, ¶meters_list); if (err) { @@ -1090,6 +1096,12 @@ int cwmp_handle_rpc_cpe_set_parameter_values(struct session *session, struct rpc b = mxmlWalkNext(b, session->tree_in, MXML_DESCEND_FIRST); if (b && b->type == MXML_OPAQUE && b->value.opaque) parameter_key = b->value.opaque; + + if (!icwmp_validate_string_length(parameter_key, 32)) { + fault_code = FAULT_CPE_INVALID_ARGUMENTS; + goto fault; + } + int flag = 0; if (transaction_id == 0) { if (!cwmp_transaction_start("cwmp")) @@ -1149,6 +1161,7 @@ int cwmp_handle_rpc_cpe_set_parameter_attributes(struct session *session, struct mxml_node_t *n, *b = session->body_in; char *parameter_name = NULL, *parameter_notification = NULL; int fault_code = FAULT_CPE_INTERNAL_ERROR, ret = 0; + char *notification_change = NULL; char c[256]; /* handle cwmp:SetParameterAttributes */ @@ -1167,9 +1180,9 @@ int cwmp_handle_rpc_cpe_set_parameter_attributes(struct session *session, struct } while (b != NULL) { if (b && b->type == MXML_ELEMENT && !strcmp(b->value.element.name, "SetParameterAttributesStruct")) { - //attr_notification_update = NULL; parameter_name = NULL; parameter_notification = NULL; + notification_change = NULL; } if (b && b->type == MXML_OPAQUE && b->value.opaque && b->parent->type == MXML_ELEMENT && !strcmp(b->parent->value.element.name, "Name")) { parameter_name = b->value.opaque; @@ -1178,10 +1191,10 @@ int cwmp_handle_rpc_cpe_set_parameter_attributes(struct session *session, struct parameter_name = ""; } if (b && b->type == MXML_OPAQUE && b->value.opaque && b->parent->type == MXML_ELEMENT && !strcmp(b->parent->value.element.name, "NotificationChange")) { - //attr_notification_update = b->value.opaque; + notification_change = b->value.opaque; } if (b && b->type == MXML_ELEMENT && !strcmp(b->value.element.name, "NotificationChange") && !b->child) { - //attr_notification_update = ""; + notification_change = ""; } if (b && b->type == MXML_OPAQUE && b->value.opaque && b->parent->type == MXML_ELEMENT && !strcmp(b->parent->value.element.name, "Notification")) { parameter_notification = b->value.opaque; @@ -1189,7 +1202,15 @@ int cwmp_handle_rpc_cpe_set_parameter_attributes(struct session *session, struct if (b && b->type == MXML_ELEMENT && !strcmp(b->value.element.name, "Notification") && !b->child) { parameter_notification = ""; } - if (parameter_name && parameter_notification) { + if (parameter_name && parameter_notification && notification_change) { + if (!icwmp_validate_boolean_value(notification_change)) { + fault_code = FAULT_CPE_INVALID_ARGUMENTS; + goto fault; + } + if (!icwmp_validate_int_in_range(parameter_notification, 0, 6)) { + fault_code = FAULT_CPE_INVALID_ARGUMENTS; + goto fault; + } char *err = cwmp_set_parameter_attributes(parameter_name, parameter_notification); if (err) { fault_code = cwmp_get_fault_code_by_string(err); @@ -1248,6 +1269,10 @@ int cwmp_handle_rpc_cpe_add_object(struct session *session, struct rpc *rpc) b = mxmlWalkNext(b, session->body_in, MXML_DESCEND); } + if (!icwmp_validate_string_length(parameter_key, 32)) { + fault_code = FAULT_CPE_INVALID_ARGUMENTS; + goto fault; + } if (transaction_id == 0) { if (!cwmp_transaction_start("cwmp")) goto fault; @@ -1328,6 +1353,10 @@ int cwmp_handle_rpc_cpe_delete_object(struct session *session, struct rpc *rpc) } b = mxmlWalkNext(b, session->body_in, MXML_DESCEND); } + if (!icwmp_validate_string_length(parameter_key, 32)) { + fault_code = FAULT_CPE_INVALID_ARGUMENTS; + goto fault; + } if (transaction_id == 0) { if (!cwmp_transaction_start("cwmp")) goto fault; @@ -1502,6 +1531,7 @@ int cwmp_handle_rpc_cpe_cancel_transfer(struct session *session, struct rpc *rpc { mxml_node_t *b; char *command_key = NULL; + int fault_code = FAULT_CPE_INTERNAL_ERROR; b = session->body_in; while (b) { @@ -1510,6 +1540,10 @@ int cwmp_handle_rpc_cpe_cancel_transfer(struct session *session, struct rpc *rpc } b = mxmlWalkNext(b, session->body_in, MXML_DESCEND); } + if (!icwmp_validate_string_length(command_key, 32)) { + fault_code = FAULT_CPE_INVALID_ARGUMENTS; + goto fault; + } if (command_key) { cancel_transfer(command_key); } @@ -1522,7 +1556,7 @@ int cwmp_handle_rpc_cpe_cancel_transfer(struct session *session, struct rpc *rpc goto fault; return 0; fault: - if (cwmp_create_fault_message(session, rpc, FAULT_CPE_INTERNAL_ERROR)) + if (cwmp_create_fault_message(session, rpc, fault_code)) goto error; return 0; @@ -1579,7 +1613,7 @@ int cwmp_handle_rpc_cpe_reboot(struct session *session, struct rpc *rpc) mxml_node_t *b; struct event_container *event_container; char *command_key = NULL; - + int fault_code = FAULT_CPE_INTERNAL_ERROR; b = session->body_in; while (b) { @@ -1589,7 +1623,10 @@ int cwmp_handle_rpc_cpe_reboot(struct session *session, struct rpc *rpc) } b = mxmlWalkNext(b, session->body_in, MXML_DESCEND); } - + if (!icwmp_validate_string_length(commandKey, 32)) { + fault_code = FAULT_CPE_INVALID_ARGUMENTS; + goto fault; + } pthread_mutex_lock(&(cwmp_main.mutex_session_queue)); event_container = cwmp_add_event_container(&cwmp_main, EVENT_IDX_M_Reboot, command_key); if (event_container == NULL) { @@ -1612,7 +1649,7 @@ int cwmp_handle_rpc_cpe_reboot(struct session *session, struct rpc *rpc) return 0; fault: - if (cwmp_create_fault_message(session, rpc, FAULT_CPE_INTERNAL_ERROR)) + if (cwmp_create_fault_message(session, rpc, fault_code)) goto error; return 0; @@ -1646,7 +1683,11 @@ int cwmp_handle_rpc_cpe_schedule_inform(struct session *session, struct rpc *rpc } b = mxmlWalkNext(b, session->body_in, MXML_DESCEND); } - + if (!icwmp_validate_string_length(command_key, 32)) { + fault = FAULT_CPE_INVALID_ARGUMENTS; + pthread_mutex_unlock(&mutex_schedule_inform); + goto fault; + } if (delay_seconds <= 0) { fault = FAULT_CPE_INVALID_ARGUMENTS; pthread_mutex_unlock(&mutex_schedule_inform); @@ -1809,6 +1850,10 @@ int cwmp_handle_rpc_cpe_change_du_state(struct session *session, struct rpc *rpc } b = mxmlWalkNext(b, n, MXML_DESCEND); } + if (!icwmp_validate_string_length(change_du_state->command_key, 32)) { + error = FAULT_CPE_INVALID_ARGUMENTS; + goto fault; + } t = mxmlFindElement(session->tree_out, session->tree_out, "soap_env:Body", NULL, NULL, MXML_DESCEND); if (!t) goto fault; @@ -1889,6 +1934,7 @@ int cwmp_handle_rpc_cpe_download(struct session *session, struct rpc *rpc) struct list_head *ilist; time_t scheduled_time = 0; time_t download_delay = 0; + char *str_file_size = NULL, *str_download_delay = NULL; if (snprintf(c, sizeof(c), "%s:%s", ns.cwmp, "Download") == -1) { error = FAULT_CPE_INTERNAL_ERROR; @@ -1934,15 +1980,45 @@ int cwmp_handle_rpc_cpe_download(struct session *session, struct rpc *rpc) download->password = strdup(b->value.opaque); } if (b && b->type == MXML_OPAQUE && b->value.opaque && b->parent->type == MXML_ELEMENT && !strcmp(b->parent->value.element.name, "FileSize")) { + str_file_size = strdup(b->value.opaque ? b->value.opaque: "0"); download->file_size = atoi(b->value.opaque); } if (b && b->type == MXML_OPAQUE && b->value.opaque && b->parent->type == MXML_ELEMENT && !strcmp(b->parent->value.element.name, "DelaySeconds")) { + str_download_delay = strdup(b->value.opaque ? b->value.opaque: "0"); download_delay = atol(b->value.opaque); } b = mxmlWalkNext(b, n, MXML_DESCEND); } + if (!icwmp_validate_string_length(download->command_key, 32)) { + error = FAULT_CPE_INVALID_ARGUMENTS; + goto fault; + } + if (!icwmp_validate_string_length(download->url, 256)) { + error = FAULT_CPE_INVALID_ARGUMENTS; + goto fault; + } + if (!icwmp_validate_string_length(download->username, 256)) { + error = FAULT_CPE_INVALID_ARGUMENTS; + goto fault; + } + if (!icwmp_validate_string_length(download->password, 256)) { + error = FAULT_CPE_INVALID_ARGUMENTS; + goto fault; + } + if (!icwmp_validate_unsignedint(str_file_size)) { + error = FAULT_CPE_INVALID_ARGUMENTS; + FREE(str_file_size); + goto fault; + } + FREE(str_file_size); + if (!icwmp_validate_unsignedint(str_download_delay)) { + error = FAULT_CPE_INVALID_ARGUMENTS; + FREE(str_download_delay); + goto fault; + } + FREE(str_download_delay); - if (strcmp(file_type, "1 Firmware Upgrade Image") && strcmp(file_type, "2 Web Content") && strcmp(file_type, "3 Vendor Configuration File") && strcmp(file_type, "6 Stored Firmware Image")) { + if (strcmp(file_type, "1 Firmware Upgrade Image") && strcmp(file_type, "2 Web Content") && strcmp(file_type, "3 Vendor Configuration File") && strcmp(file_type, "4 Tone File") && strcmp(file_type, "5 Ringer File") && strcmp(file_type, "6 Stored Firmware Image")) { error = FAULT_CPE_INVALID_ARGUMENTS; } else if (count_download_queue >= MAX_DOWNLOAD_QUEUE) { error = FAULT_CPE_RESOURCES_EXCEEDED; @@ -2007,7 +2083,7 @@ int cwmp_handle_rpc_cpe_schedule_download(struct session *session, struct rpc *r { mxml_node_t *n, *t, *b = session->body_in; char c[256], *tmp, *file_type = NULL; - char *windowmode0 = NULL, *windowmode1 = NULL; + char *windowmode0 = NULL, *windowmode1 = NULL, *str_file_size = NULL; int i = 0, j = 0; int error = FAULT_CPE_NO_FAULT; struct download *schedule_download = NULL; @@ -2057,6 +2133,7 @@ int cwmp_handle_rpc_cpe_schedule_download(struct session *session, struct rpc *r schedule_download->password = strdup(b->value.opaque); } if (b && b->type == MXML_OPAQUE && b->value.opaque && b->parent->type == MXML_ELEMENT && !strcmp(b->parent->value.element.name, "FileSize")) { + str_file_size = strdup(b->value.opaque); schedule_download->file_size = atoi(b->value.opaque); } @@ -2107,6 +2184,28 @@ int cwmp_handle_rpc_cpe_schedule_download(struct session *session, struct rpc *r } b = mxmlWalkNext(b, n, MXML_DESCEND); } + if (!icwmp_validate_string_length(schedule_download->command_key, 32)) { + error = FAULT_CPE_INVALID_ARGUMENTS; + goto fault; + } + if (!icwmp_validate_string_length(schedule_download->url, 256)) { + error = FAULT_CPE_INVALID_ARGUMENTS; + goto fault; + } + if (!icwmp_validate_string_length(schedule_download->username, 256)) { + error = FAULT_CPE_INVALID_ARGUMENTS; + goto fault; + } + if (!icwmp_validate_string_length(schedule_download->password, 256)) { + error = FAULT_CPE_INVALID_ARGUMENTS; + goto fault; + } + if (!icwmp_validate_unsignedint(str_file_size)) { + error = FAULT_CPE_INVALID_ARGUMENTS; + FREE(str_file_size); + goto fault; + } + FREE(str_file_size); if (strcmp(file_type, "1 Firmware Upgrade Image") && strcmp(file_type, "2 Web Content") && strcmp(file_type, "3 Vendor Configuration File") && strcmp(file_type, "4 Tone File") && strcmp(file_type, "5 Ringer File") && strcmp(file_type, "6 Stored Firmware Image")) { error = FAULT_CPE_INVALID_ARGUMENTS; } else if ((strcmp(windowmode0, "1 At Any Time") && strcmp(windowmode0, "2 Immediately") && strcmp(windowmode0, "3 When Idle")) || (strcmp(windowmode1, "1 At Any Time") && strcmp(windowmode1, "2 Immediately") && strcmp(windowmode1, "3 When Idle"))) { @@ -2188,6 +2287,7 @@ int cwmp_handle_rpc_cpe_upload(struct session *session, struct rpc *rpc) struct list_head *ilist; time_t scheduled_time = 0; time_t upload_delay = 0; + char *str_upload_delay = NULL; char c[256]; if (snprintf(c, sizeof(c), "%s:%s", ns.cwmp, "Upload") == -1) { @@ -2236,10 +2336,34 @@ int cwmp_handle_rpc_cpe_upload(struct session *session, struct rpc *rpc) upload->password = strdup(b->value.opaque); } if (b && b->type == MXML_OPAQUE && b->value.opaque && b->parent->type == MXML_ELEMENT && !strcmp(b->parent->value.element.name, "DelaySeconds")) { + str_upload_delay = strdup(b->value.opaque); upload_delay = atol(b->value.opaque); } b = mxmlWalkNext(b, n, MXML_DESCEND); } + if (!icwmp_validate_string_length(upload->command_key, 32)) { + error = FAULT_CPE_INVALID_ARGUMENTS; + goto fault; + } + if (!icwmp_validate_string_length(upload->url, 256)) { + error = FAULT_CPE_INVALID_ARGUMENTS; + goto fault; + } + if (!icwmp_validate_string_length(upload->username, 256)) { + error = FAULT_CPE_INVALID_ARGUMENTS; + goto fault; + } + if (!icwmp_validate_string_length(upload->password, 256)) { + error = FAULT_CPE_INVALID_ARGUMENTS; + goto fault; + } + if (!icwmp_validate_unsignedint(str_upload_delay)) { + error = FAULT_CPE_INVALID_ARGUMENTS; + FREE(str_upload_delay); + goto fault; + } + FREE(str_upload_delay); + if (strncmp(file_type, "1 Vendor Configuration File", sizeof "1 Vendor Configuration File" - 1) != 0 && strncmp(file_type, "3 Vendor Configuration File", sizeof "3 Vendor Configuration File" - 1) != 0 && strncmp(file_type, "2 Vendor Log File", sizeof "2 Vendor Log File" - 1) != 0 && strncmp(file_type, "4 Vendor Log File", sizeof "4 Vendor Log File" - 1) != 0) { error = FAULT_CPE_REQUEST_DENIED; diff --git a/test/cmocka/icwmp_soap_msg_unit_test.c b/test/cmocka/icwmp_soap_msg_unit_test.c index 1cf6da1..c706c98 100644 --- a/test/cmocka/icwmp_soap_msg_unit_test.c +++ b/test/cmocka/icwmp_soap_msg_unit_test.c @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include #include