diff options
| author | 2022-10-04 15:10:52 +0200 | |
|---|---|---|
| committer | 2022-10-04 15:10:52 +0200 | |
| commit | b314f04bd791b263cf43fadc6ac0756e67ab4ed0 (patch) | |
| tree | 29d87392ef1e9f76b0e05c42e1e1658b9bf0ec12 | |
| parent | 5debcee5a74550c28da735bb1cfc5b4c8f2614a9 (diff) | |
| download | libimobiledevice-b314f04bd791b263cf43fadc6ac0756e67ab4ed0.tar.gz libimobiledevice-b314f04bd791b263cf43fadc6ac0756e67ab4ed0.tar.bz2 | |
lockdown: Fix error parsing for older iOS versions
A logical bug did prevent parsing the 'Error' node since the code
path is never reached when a 'Result' node is found first. This
is mitigated by always checking for the 'Error' node first.
| -rw-r--r-- | src/lockdown.c | 54 | 
1 files changed, 19 insertions, 35 deletions
| diff --git a/src/lockdown.c b/src/lockdown.c index 505b13e..92af186 100644 --- a/src/lockdown.c +++ b/src/lockdown.c | |||
| @@ -165,51 +165,38 @@ lockdownd_error_t lockdown_check_result(plist_t dict, const char *query_match) | |||
| 165 | return ret; | 165 | return ret; | 
| 166 | } | 166 | } | 
| 167 | 167 | ||
| 168 | char *query_value = NULL; | 168 | const char *query_value = plist_get_string_ptr(query_node, NULL); | 
| 169 | |||
| 170 | plist_get_string_val(query_node, &query_value); | ||
| 171 | if (!query_value) { | 169 | if (!query_value) { | 
| 172 | return ret; | 170 | return ret; | 
| 173 | } | 171 | } | 
| 174 | 172 | ||
| 175 | if (query_match && (strcmp(query_value, query_match) != 0)) { | 173 | if (query_match && (strcmp(query_value, query_match) != 0)) { | 
| 176 | free(query_value); | ||
| 177 | return ret; | 174 | return ret; | 
| 178 | } | 175 | } | 
| 179 | 176 | ||
| 180 | free(query_value); | 177 | /* Check for 'Error' in reply */ | 
| 181 | 178 | plist_t err_node = plist_dict_get_item(dict, "Error"); | |
| 182 | plist_t result_node = plist_dict_get_item(dict, "Result"); | 179 | if (err_node) { | 
| 183 | if (!result_node) { | 180 | if (plist_get_node_type(err_node) == PLIST_STRING) { | 
| 184 | /* iOS 5: the 'Result' key is not present anymore. | 181 | const char *err_value = plist_get_string_ptr(err_node, NULL); | 
| 185 | But we need to check for the 'Error' key. */ | 182 | if (err_value) { | 
| 186 | plist_t err_node = plist_dict_get_item(dict, "Error"); | 183 | debug_info("ERROR: %s", err_value); | 
| 187 | if (err_node) { | 184 | ret = lockdownd_strtoerr(err_value); | 
| 188 | if (plist_get_node_type(err_node) == PLIST_STRING) { | 185 | } else { | 
| 189 | char *err_value = NULL; | 186 | debug_info("ERROR: unknown error occurred"); | 
| 190 | |||
| 191 | plist_get_string_val(err_node, &err_value); | ||
| 192 | if (err_value) { | ||
| 193 | debug_info("ERROR: %s", err_value); | ||
| 194 | ret = lockdownd_strtoerr(err_value); | ||
| 195 | free(err_value); | ||
| 196 | } else { | ||
| 197 | debug_info("ERROR: unknown error occurred"); | ||
| 198 | } | ||
| 199 | } | 187 | } | 
| 200 | return ret; | ||
| 201 | } | 188 | } | 
| 202 | |||
| 203 | ret = LOCKDOWN_E_SUCCESS; | ||
| 204 | |||
| 205 | return ret; | 189 | return ret; | 
| 206 | } | 190 | } | 
| 207 | 191 | ||
| 208 | plist_type result_type = plist_get_node_type(result_node); | 192 | plist_t result_node = plist_dict_get_item(dict, "Result"); | 
| 209 | if (result_type == PLIST_STRING) { | 193 | if (!result_node) { | 
| 210 | char *result_value = NULL; | 194 | /* With iOS 5+ 'Result' is not present anymore. | 
| 211 | 195 | If there is no 'Error', we can just assume success. */ | |
| 212 | plist_get_string_val(result_node, &result_value); | 196 | return LOCKDOWN_E_SUCCESS; | 
| 197 | } | ||
| 198 | if (plist_get_node_type(result_node) == PLIST_STRING) { | ||
| 199 | const char *result_value = plist_get_string_ptr(result_node, NULL); | ||
| 213 | if (result_value) { | 200 | if (result_value) { | 
| 214 | if (!strcmp(result_value, "Success")) { | 201 | if (!strcmp(result_value, "Success")) { | 
| 215 | ret = LOCKDOWN_E_SUCCESS; | 202 | ret = LOCKDOWN_E_SUCCESS; | 
| @@ -219,9 +206,6 @@ lockdownd_error_t lockdown_check_result(plist_t dict, const char *query_match) | |||
| 219 | debug_info("ERROR: unknown result value '%s'", result_value); | 206 | debug_info("ERROR: unknown result value '%s'", result_value); | 
| 220 | } | 207 | } | 
| 221 | } | 208 | } | 
| 222 | |||
| 223 | if (result_value) | ||
| 224 | free(result_value); | ||
| 225 | } | 209 | } | 
| 226 | 210 | ||
| 227 | return ret; | 211 | return ret; | 
