char compare_plist(plist_t node_l, plist_t node_r) { plist_t cur_l = NULL; plist_t cur_r = NULL; int res = 1; cur_l = plist_get_first_child(node_l); cur_r = plist_get_first_child(node_r); if ( (!cur_l && cur_r) || (cur_l && !cur_r)) return 0; if ( !cur_l && !cur_r ) return plist_compare_node_value( node_l, node_r ); while (cur_l && cur_r && res) { if (!(res = compare_plist(cur_l, cur_r))) return res; cur_l = plist_get_next_sibling(cur_l); cur_r = plist_get_next_sibling(cur_r); if ( (!cur_l && cur_r) || (cur_l && !cur_r)) return 0; } return res; }
static void tss_entry_apply_restore_request_rules(plist_t tss_entry, plist_t parameters, plist_t rules) { if (!tss_entry || !rules) { return; } if (plist_get_node_type(tss_entry) != PLIST_DICT) { return; } if (plist_get_node_type(rules) != PLIST_ARRAY) { return; } uint32_t i; for (i = 0; i < plist_array_get_size(rules); i++) { plist_t rule = plist_array_get_item(rules, i); plist_t conditions = plist_dict_get_item(rule, "Conditions"); plist_dict_iter iter = NULL; plist_dict_new_iter(conditions, &iter); char* key = NULL; plist_t value = NULL; plist_t value2 = NULL; int conditions_fulfilled = 1; while (conditions_fulfilled) { plist_dict_next_item(conditions, iter, &key, &value); if (key == NULL) break; if (!strcmp(key, "ApRawProductionMode")) { value2 = plist_dict_get_item(parameters, "ApProductionMode"); } else if (!strcmp(key, "ApCurrentProductionMode")) { value2 = plist_dict_get_item(parameters, "ApProductionMode"); } else if (!strcmp(key, "ApRawSecurityMode")) { value2 = plist_dict_get_item(parameters, "ApSecurityMode"); } else if (!strcmp(key, "ApRequiresImage4")) { value2 = plist_dict_get_item(parameters, "ApSupportsImg4"); } else if (!strcmp(key, "ApDemotionPolicyOverride")) { value2 = plist_dict_get_item(parameters, "DemotionPolicy"); } else if (!strcmp(key, "ApInRomDFU")) { value2 = plist_dict_get_item(parameters, "ApInRomDFU"); } else { error("WARNING: Unhandled condition '%s' while parsing RestoreRequestRules\n", key); value2 = NULL; } if (value2) { conditions_fulfilled = plist_compare_node_value(value, value2); } else { conditions_fulfilled = 0; } free(key); } free(iter); iter = NULL; if (!conditions_fulfilled) { continue; } plist_t actions = plist_dict_get_item(rule, "Actions"); plist_dict_new_iter(actions, &iter); while (1) { plist_dict_next_item(actions, iter, &key, &value); if (key == NULL) break; uint8_t bv = 0; plist_get_bool_val(value, &bv); if (bv) { value2 = plist_dict_get_item(tss_entry, key); if (value2) { plist_dict_remove_item(tss_entry, key); } debug("DEBUG: Adding action %s to TSS entry\n", key); plist_dict_set_item(tss_entry, key, plist_new_bool(1)); } free(key); } } }