コード例 #1
0
ファイル: plist.c プロジェクト: Clstroud/libplist
static void plist_copy_node(node_t *node, void *parent_node_ptr)
{
    plist_type node_type = PLIST_NONE;
    plist_t newnode = NULL;
    plist_data_t data = plist_get_data(node);
    plist_data_t newdata = plist_new_plist_data();

    assert(data);				// plist should always have data

    memcpy(newdata, data, sizeof(struct plist_data_s));

    node_type = plist_get_node_type(node);
    if (node_type == PLIST_DATA || node_type == PLIST_STRING || node_type == PLIST_KEY)
    {
        switch (node_type)
        {
        case PLIST_DATA:
            newdata->buff = (uint8_t *) malloc(data->length);
            memcpy(newdata->buff, data->buff, data->length);
            break;
        case PLIST_KEY:
        case PLIST_STRING:
            newdata->strval = strdup((char *) data->strval);
            break;
        default:
            break;
        }
    }
    newnode = plist_new_node(newdata);

    if (*(plist_t*)parent_node_ptr)
    {
        node_attach(*(plist_t*)parent_node_ptr, newnode);
    }
    else
    {
        *(plist_t*)parent_node_ptr = newnode;
    }

    node_iterator_t *ni = node_iterator_create(node->children);
    node_t *ch;
    while ((ch = node_iterator_next(ni))) {
        plist_copy_node(ch, &newnode);
    }
    node_iterator_destroy(ni);
}
コード例 #2
0
Node* Node::FromPlist(plist_t node, Node* parent)
{
    Node* ret = NULL;
    if (node)
    {
        plist_type type = plist_get_node_type(node);
        switch (type)
        {
        case PLIST_DICT:
            ret = new Dictionary(node, parent);
            break;
        case PLIST_ARRAY:
            ret = new Array(node, parent);
            break;
        case PLIST_BOOLEAN:
            ret = new Boolean(node, parent);
            break;
        case PLIST_UINT:
            ret = new Integer(node, parent);
            break;
        case PLIST_REAL:
            ret = new Real(node, parent);
            break;
        case PLIST_STRING:
            ret = new String(node, parent);
            break;
        case PLIST_KEY:
            ret = new Key(node, parent);
            break;
        case PLIST_UID:
            ret = new Uid(node, parent);
            break;
        case PLIST_DATE:
            ret = new Date(node, parent);
            break;
        case PLIST_DATA:
            ret = new Data(node, parent);
            break;
        default:
            plist_free(node);
            break;
        }
    }
    return ret;
}
コード例 #3
0
ファイル: normal.c プロジェクト: optionalg/idevicerestore
int normal_get_nonce(struct idevicerestore_client_t* client, unsigned char** nonce, int* nonce_size) {
	idevice_t device = NULL;
	plist_t nonce_node = NULL;
	lockdownd_client_t lockdown = NULL;
	idevice_error_t device_error = IDEVICE_E_SUCCESS;
	lockdownd_error_t lockdown_error = IDEVICE_E_SUCCESS;

	device_error = idevice_new(&device, client->udid);
	if (device_error != IDEVICE_E_SUCCESS) {
		return -1;
	}

	lockdown_error = lockdownd_client_new(device, &lockdown, "idevicerestore");
	if (lockdown_error != LOCKDOWN_E_SUCCESS) {
		error("ERROR: Unable to connect to lockdownd\n");
		idevice_free(device);
		return -1;
	}

	lockdown_error = lockdownd_get_value(lockdown, NULL, "ApNonce", &nonce_node);
	if (lockdown_error != LOCKDOWN_E_SUCCESS) {
		error("ERROR: Unable to get ApNonce from lockdownd\n");
		lockdownd_client_free(lockdown);
		idevice_free(device);
		return -1;
	}

	if (!nonce_node || plist_get_node_type(nonce_node) != PLIST_DATA) {
		error("ERROR: Unable to get nonce\n");
		lockdownd_client_free(lockdown);
		idevice_free(device);
		return -1;
	}

	uint64_t n_size = 0;
	plist_get_data_val(nonce_node, (char**)nonce, &n_size);
	*nonce_size = (int)n_size;
	plist_free(nonce_node);

	lockdownd_client_free(lockdown);
	idevice_free(device);
	lockdown = NULL;
	device = NULL;
	return 0;
}
コード例 #4
0
ファイル: tss.c プロジェクト: MephistoLa/bootsigned
int tss_get_ticket(plist_t tss, unsigned char** ticket, uint32_t* tlen) {
	plist_t entry_node = plist_dict_get_item(tss, "APTicket");
	if (!entry_node || plist_get_node_type(entry_node) != PLIST_DATA) {
		error("ERROR: Unable to find APTicket entry in TSS response\n");
		return -1;
	}
	char *data = NULL;
	uint64_t len = 0;
	plist_get_data_val(entry_node, &data, &len);
	if (data) {
		*tlen = (uint32_t)len;
		*ticket = data;
		return 0;
	} else {
		error("ERROR: Unable to get APTicket data from TSS response\n");
		return -1;
	}
}
コード例 #5
0
PLIST_API void plist_dict_set_item(plist_t node, const char* key, plist_t item)
{
    if (node && PLIST_DICT == plist_get_node_type(node)) {
        node_t* old_item = plist_dict_get_item(node, key);
        if (old_item) {
            int idx = plist_free_node(old_item);
            if (idx < 0) {
                node_attach(node, item);
            } else {
                node_insert(node, idx, item);
            }
        } else {
            node_attach(node, plist_new_key(key));
            node_attach(node, item);
        }
    }
    return;
}
コード例 #6
0
ファイル: restore.c プロジェクト: rcg4u/idevicerestore
int restore_handle_data_request_msg(idevice_t device, restored_client_t restore, plist_t message, plist_t tss, const char* ipsw, const char* filesystem) {
	char* type = NULL;
	plist_t node = NULL;

	// checks and see what kind of data restored is requests and pass
	// the request to its own handler
	node = plist_dict_get_item(message, "DataType");
	if (node && PLIST_STRING == plist_get_node_type(node)) {
		plist_get_string_val(node, &type);

		// this request is sent when restored is ready to receive the filesystem
		if (!strcmp(type, "SystemImageData")) {
			restore_send_filesystem(device, filesystem);

		}

		else if (!strcmp(type, "KernelCache")) {
			int kernelcache_size = 0;
			char* kernelcache_data = NULL;
			char* kernelcache_path = NULL;
			if (tss_get_entry_path(tss, "KernelCache", &kernelcache_path) < 0) {
				error("ERROR: Unable to find kernelcache path\n");
				return -1;
			}

			if (get_signed_component(ipsw, tss, kernelcache_path, &kernelcache_data, &kernelcache_size) < 0) {
				error("ERROR: Unable to get kernelcache file\n");
				return -1;
			}
			restore_send_kernelcache(restore, kernelcache_data, kernelcache_size);
			free(kernelcache_data);

		}

		else if (!strcmp(type, "NORData")) {
			restore_send_nor(restore, ipsw, tss);

		} else {
			// Unknown DataType!!
			debug("Unknown data request received\n");
		}
	}
	return 0;
}
コード例 #7
0
LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_query_type(lockdownd_client_t client, char **type)
{
	if (!client)
		return LOCKDOWN_E_INVALID_ARG;

	lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR;

	plist_t dict = plist_new_dict();
	plist_dict_add_label(dict, client->label);
	plist_dict_set_item(dict,"Request", plist_new_string("QueryType"));

	debug_info("called");
	ret = lockdownd_send(client, dict);

	plist_free(dict);
	dict = NULL;

	ret = lockdownd_receive(client, &dict);

	if (LOCKDOWN_E_SUCCESS != ret)
		return ret;

	ret = LOCKDOWN_E_UNKNOWN_ERROR;
	plist_t type_node = plist_dict_get_item(dict, "Type");
	if (type_node && (plist_get_node_type(type_node) == PLIST_STRING)) {
		char* typestr = NULL;
		plist_get_string_val(type_node, &typestr);
		debug_info("success with type %s", typestr);
		/* return the type if requested */
		if (type != NULL) {
			*type = typestr;
		} else {
			free(typestr);
		}
		ret = LOCKDOWN_E_SUCCESS;
	} else {
		debug_info("hmm. QueryType response does not contain a type?!");
		debug_plist(dict);
	}
	plist_free(dict);
	dict = NULL;

	return ret;
}
コード例 #8
0
/**
 * Sends a DLMessageProcessMessage plist.
 *
 * @param client The device link service client to use.
 * @param message PLIST_DICT to send.
 *
 * @return DEVICE_LINK_SERVICE_E_SUCCESS on success,
 *     DEVICE_LINK_SERVICE_E_INVALID_ARG if client or message is invalid or
 *     message is not a PLIST_DICT, or DEVICE_LINK_SERVICE_E_MUX_ERROR if
 *     the DLMessageProcessMessage plist could not be sent.
 */
device_link_service_error_t device_link_service_send_process_message(device_link_service_client_t client, plist_t message)
{
    if (!client || !client->parent || !message)
        return DEVICE_LINK_SERVICE_E_INVALID_ARG;

    if (plist_get_node_type(message) != PLIST_DICT)
        return DEVICE_LINK_SERVICE_E_INVALID_ARG;

    plist_t array = plist_new_array();
    plist_array_append_item(array, plist_new_string("DLMessageProcessMessage"));
    plist_array_append_item(array, plist_copy(message));

    device_link_service_error_t err = DEVICE_LINK_SERVICE_E_SUCCESS;
    if (property_list_service_send_binary_plist(client->parent, array) != PROPERTY_LIST_SERVICE_E_SUCCESS) {
        err = DEVICE_LINK_SERVICE_E_MUX_ERROR;
    }
    plist_free(array);
    return err;
}
コード例 #9
0
ファイル: normal.c プロジェクト: MephistoLa/bootsigned
int normal_get_ecid(struct idevicerestore_client_t* client, uint64_t* ecid) {
	idevice_t device = NULL;
	plist_t unique_chip_node = NULL;
	lockdownd_client_t lockdown = NULL;
	idevice_error_t device_error = IDEVICE_E_SUCCESS;
	lockdownd_error_t lockdown_error = IDEVICE_E_SUCCESS;

	device_error = idevice_new(&device, client->uuid);
	if (device_error != IDEVICE_E_SUCCESS) {
		return -1;
	}

	lockdown_error = lockdownd_client_new_with_handshake(device, &lockdown, "idevicerestore");
	if (lockdown_error != LOCKDOWN_E_SUCCESS) {
		error("ERROR: Unable to connect to lockdownd\n");
		idevice_free(device);
		return -1;
	}

	lockdown_error = lockdownd_get_value(lockdown, NULL, "UniqueChipID", &unique_chip_node);
	if (lockdown_error != LOCKDOWN_E_SUCCESS) {
		error("ERROR: Unable to get UniqueChipID from lockdownd\n");
		lockdownd_client_free(lockdown);
		idevice_free(device);
		return -1;
	}

	if (!unique_chip_node || plist_get_node_type(unique_chip_node) != PLIST_UINT) {
		error("ERROR: Unable to get ECID\n");
		lockdownd_client_free(lockdown);
		idevice_free(device);
		return -1;
	}
	plist_get_uint_val(unique_chip_node, ecid);
	plist_free(unique_chip_node);

	lockdownd_client_free(lockdown);
	idevice_free(device);
	lockdown = NULL;
	device = NULL;
	return 0;
}
コード例 #10
0
ファイル: tss.c プロジェクト: zweed4u/idevicerestore
static int tss_response_get_data_by_key(plist_t response, const char* name, unsigned char** buffer, unsigned int* length) {

	plist_t node = plist_dict_get_item(response, name);
	if (!node || plist_get_node_type(node) != PLIST_DATA) {
		debug("DEBUG: %s: No entry '%s' in TSS response\n", __func__, name);
		return -1;
	}

	char *data = NULL;
	uint64_t len = 0;
	plist_get_data_val(node, &data, &len);
	if (data) {
		*length = (unsigned int)len;
		*buffer = (unsigned char*)data;
		return 0;
	} else {
		error("ERROR: Unable to get %s data from TSS response\n", name);
		return -1;
	}
}
コード例 #11
0
static mobileactivation_error_t mobileactivation_check_result(plist_t dict, const char *command)
{
	mobileactivation_error_t ret = MOBILEACTIVATION_E_UNKNOWN_ERROR;

	if (!dict || plist_get_node_type(dict) != PLIST_DICT) {
		return MOBILEACTIVATION_E_PLIST_ERROR;
	}

	plist_t err_node = plist_dict_get_item(dict, "Error");
	if (!err_node) {
		return MOBILEACTIVATION_E_SUCCESS;
	} else {
		char *errmsg = NULL;
		plist_get_string_val(err_node, &errmsg);
		debug_info("ERROR: %s: %s", command, errmsg);
		ret = MOBILEACTIVATION_E_REQUEST_FAILED;
		free(errmsg);
	}
	return ret;
}
コード例 #12
0
diagnostics_relay_error_t diagnostics_relay_query_mobilegestalt(diagnostics_relay_client_t client, plist_t keys, plist_t* result)
{
	if (!client || plist_get_node_type(keys) != PLIST_ARRAY || result == NULL)
		return DIAGNOSTICS_RELAY_E_INVALID_ARG;

	diagnostics_relay_error_t ret = DIAGNOSTICS_RELAY_E_UNKNOWN_ERROR;

	plist_t dict = plist_new_dict();
	plist_dict_insert_item(dict,"MobileGestaltKeys", plist_copy(keys));
	plist_dict_insert_item(dict,"Request", plist_new_string("MobileGestalt"));
	ret = diagnostics_relay_send(client, dict);
	plist_free(dict);
	dict = NULL;

	ret = diagnostics_relay_receive(client, &dict);
	if (!dict) {
		return DIAGNOSTICS_RELAY_E_PLIST_ERROR;
	}

	int check = diagnostics_relay_check_result(dict);
	if (check == RESULT_SUCCESS) {
		ret = DIAGNOSTICS_RELAY_E_SUCCESS;
	} else if (check == RESULT_UNKNOWN_REQUEST) {
		ret = DIAGNOSTICS_RELAY_E_UNKNOWN_REQUEST;
	} else {
		ret = DIAGNOSTICS_RELAY_E_UNKNOWN_ERROR;
	}

	if (ret != DIAGNOSTICS_RELAY_E_SUCCESS) {
		plist_free(dict);
		return ret;
	}

	plist_t value_node = plist_dict_get_item(dict, "Diagnostics");
	if (value_node) {
		*result = plist_copy(value_node);
	}

	plist_free(dict);
	return ret;
}
コード例 #13
0
static int
get_dictval_date_from_key(plist_t dict, const char *key, uint32_t *val)
{
  plist_t node;
  int32_t secs;
  int32_t dummy;

  node = plist_dict_get_item(dict, key);

  if (!node)
    return -1;

  if (plist_get_node_type(node) != PLIST_DATE)
    return -1;

  plist_get_date_val(node, &secs, &dummy);

  *val = (uint32_t) secs;

  return 0;
}
コード例 #14
0
/**
 * Send a command with specified options to the device.
 * Only used internally.
 *
 * @param client The connected installation_proxy client.
 * @param command The command to execute. Required.
 * @param client_options The client options to use, as PLIST_DICT, or NULL.
 * @param appid The ApplicationIdentifier to add or NULL if not required.
 * @param package_path The installation package path or NULL if not required.
 *
 * @return INSTPROXY_E_SUCCESS on success or an INSTPROXY_E_* error value if
 *     an error occured.
 */
static instproxy_error_t instproxy_send_command(instproxy_client_t client, const char *command, plist_t client_options, const char *appid, const char *package_path)
{
	if (!client || !command || (client_options && (plist_get_node_type(client_options) != PLIST_DICT)))
		return INSTPROXY_E_INVALID_ARG;

	plist_t dict = plist_new_dict();
	if (appid) {
		plist_dict_insert_item(dict, "ApplicationIdentifier", plist_new_string(appid));
	}
	if (client_options && (plist_dict_get_size(client_options) > 0)) {
		plist_dict_insert_item(dict, "ClientOptions", plist_copy(client_options));
	}
	plist_dict_insert_item(dict, "Command", plist_new_string(command));
	if (package_path) {
		plist_dict_insert_item(dict, "PackagePath", plist_new_string(package_path));
	}

	instproxy_error_t err = instproxy_error(property_list_service_send_xml_plist(client->parent, dict));
	plist_free(dict);
	return err;
}
コード例 #15
0
static int
get_dictval_bool_from_key(plist_t dict, const char *key, uint8_t *val)
{
  plist_t node;

  node = plist_dict_get_item(dict, key);

  /* Not present means false */
  if (!node)
    {
      *val = 0;

      return 0;
    }

  if (plist_get_node_type(node) != PLIST_BOOLEAN)
    return -1;

  plist_get_bool_val(node, val);

  return 0;
}
コード例 #16
0
static int
get_dictval_date_from_key(plist_t dict, const char *key, uint32_t *val)
{
  plist_t node;
  int32_t secs;
  int32_t dummy;

  node = plist_dict_get_item(dict, key);

  if (!node)
    return -1;

  if (plist_get_node_type(node) != PLIST_DATE)
    return -1;

  // secs will be number of seconds since 01/01/2001
  plist_get_date_val(node, &secs, &dummy);

  // make it a Unix Timestamp by adding seconds from 1/1/1970 to 1/1/2001
  *val = (uint32_t) (secs + 978307200);

  return 0;
}
コード例 #17
0
PLIST_API void plist_dict_merge(plist_t *target, plist_t source)
{
	if (!target || !*target || (plist_get_node_type(*target) != PLIST_DICT) || !source || (plist_get_node_type(source) != PLIST_DICT))
		return;

	char* key = NULL;
	plist_dict_iter it = NULL;
	plist_t subnode = NULL;
	plist_dict_new_iter(source, &it);
	if (!it)
		return;

	do {
		plist_dict_next_item(source, it, &key, &subnode);
		if (!key)
			break;

		plist_dict_set_item(*target, key, plist_copy(subnode));
		free(key);
		key = NULL;
	} while (1);
	free(it);	
}
コード例 #18
0
ファイル: iInfo.c プロジェクト: abhilash0505/iShot-iInfo
static void plist_dict_to_string(plist_t node)
{
	plist_dict_iter it = NULL;

	char* key = NULL;
	plist_t subnode = NULL;
	plist_dict_new_iter(node, &it);
	plist_dict_next_item(node, it, &key, &subnode);
	while (subnode)
	{
		printf("%*s", indent_level, "");
		printf("%s", key);
		if (plist_get_node_type(subnode) == PLIST_ARRAY)
			printf("[%d]: ", plist_array_get_size(subnode));
		else
			printf(": ");
		free(key);
		key = NULL;
		plist_node_to_string(subnode);
		plist_dict_next_item(node, it, &key, &subnode);
	}
	free(it);
}
コード例 #19
0
ファイル: plist.c プロジェクト: daiwx/libplist
plist_t plist_access_pathv(plist_t plist, uint32_t length, va_list v)
{
    plist_t current = plist;
    plist_type type = PLIST_NONE;
    uint32_t i = 0;

    for (i = 0; i < length && current; i++)
    {
        type = plist_get_node_type(current);

        if (type == PLIST_ARRAY)
        {
            uint32_t n = va_arg(v, uint32_t);
            current = plist_array_get_item(current, n);
        }
        else if (type == PLIST_DICT)
        {
            const char* key = va_arg(v, const char*);
            current = plist_dict_get_item(current, key);
        }
    }
    return current;
}
コード例 #20
0
/**
 * Internal function used by lockdownd_do_start_service to create the
 * StartService request's plist.
 *
 * @param client The lockdownd client
 * @param identifier The identifier of the service to start
 * @param send_escrow_bag Should we send the device's escrow bag with the request
 * @param request The request's plist on success, NULL on failure
 *
 * @return LOCKDOWN_E_SUCCESS on success, LOCKDOWN_E_INVALID_CONF on failure
 * to read the escrow bag from the device's record (when used).
 */
static lockdownd_error_t lockdownd_build_start_service_request(lockdownd_client_t client, const char *identifier, int send_escrow_bag, plist_t *request)
{
	plist_t dict = plist_new_dict();

	/* create the basic request params */
	plist_dict_add_label(dict, client->label);
	plist_dict_set_item(dict, "Request", plist_new_string("StartService"));
	plist_dict_set_item(dict, "Service", plist_new_string(identifier));

	/* if needed - get the escrow bag for the device and send it with the request */
	if (send_escrow_bag) {
		/* get the pairing record */
		plist_t pair_record = NULL;
		userpref_read_pair_record(client->udid, &pair_record);
		if (!pair_record) {
			debug_info("ERROR: failed to read pair record for device: %s", client->udid);
			plist_free(dict);
			return LOCKDOWN_E_INVALID_CONF;
		}

		/* try to read the escrow bag from the record */
		plist_t escrow_bag = plist_dict_get_item(pair_record, USERPREF_ESCROW_BAG_KEY);
		if (!escrow_bag || (PLIST_DATA != plist_get_node_type(escrow_bag))) {
			debug_info("ERROR: Failed to retrieve the escrow bag from the device's record");
			plist_free(dict);
			plist_free(pair_record);
			return LOCKDOWN_E_INVALID_CONF;
		}

		debug_info("Adding escrow bag to StartService for %s", identifier);
		plist_dict_set_item(dict, USERPREF_ESCROW_BAG_KEY, plist_copy(escrow_bag));
		plist_free(pair_record);
	}

	*request = dict;
	return LOCKDOWN_E_SUCCESS;
}
コード例 #21
0
static int extract_raw_crash_report(const char* filename) {
	int res = 0;
	plist_t report = NULL;
	char* raw = NULL;
	char* raw_filename = strdup(filename);

	/* create filename with '.crash' extension */
	char* p = strrchr(raw_filename, '.');
	if ((p == NULL) || (strcmp(p, ".plist") != 0)) {
		free(raw_filename);
		return res;
	}
	strcpy(p, ".crash");

	/* read plist crash report */
	if (plist_read_from_filename(&report, filename)) {
		plist_t description_node = plist_dict_get_item(report, "description");
		if (description_node && plist_get_node_type(description_node) == PLIST_STRING) {
			plist_get_string_val(description_node, &raw);

			if (raw != NULL) {
				/* write file */
				buffer_write_to_filename(raw_filename, raw, strlen(raw));
				free(raw);
				res = 1;
			}
		}
	}

	if (report)
		plist_free(report);

	if (raw_filename)
		free(raw_filename);

	return res;
}
コード例 #22
0
static void
process_pl_items(plist_t items, int pl_id)
{
  plist_t trk;
  uint64_t itml_id;
  uint32_t db_id;
  uint32_t alen;
  uint32_t i;
  int ret;

  alen = plist_array_get_size(items);
  for (i = 0; i < alen; i++)
    {
      trk = plist_array_get_item(items, i);

      if (plist_get_node_type(trk) != PLIST_DICT)
	continue;

      ret = get_dictval_int_from_key(trk, "Track ID", &itml_id);
      if (ret < 0)
	{
	  DPRINTF(E_WARN, L_SCAN, "No Track ID found for playlist item %u\n", i);
	  continue;
	}

      db_id = id_map_get(itml_id);
      if (!db_id)
	{
	  DPRINTF(E_INFO, L_SCAN, "Track ID %" PRIu64 " dropped\n", itml_id);
	  continue;
	}

      ret = db_pl_add_item_byid(pl_id, db_id);
      if (ret < 0)
	DPRINTF(E_WARN, L_SCAN, "Could not add ID %d to playlist\n", db_id);
    }
}
コード例 #23
0
LIBIMOBILEDEVICE_API void instproxy_status_get_current_list(plist_t status, uint64_t* total, uint64_t* current_index, uint64_t* current_amount, plist_t* list)
{
	plist_t node = NULL;

	if (status && plist_get_node_type(status) == PLIST_DICT) {
		/* command specific logic: parse browsed list */
		if (list != NULL) {
			node = plist_dict_get_item(status, "CurrentList");
			if (node) {
				*current_amount = plist_array_get_size(node);
				*list = plist_copy(node);
			}
		}

		if (total != NULL) {
			node = plist_dict_get_item(status, "Total");
			if (node) {
				plist_get_uint_val(node, total);
			}
		}

		if (current_amount != NULL) {
			node = plist_dict_get_item(status, "CurrentAmount");
			if (node) {
				plist_get_uint_val(node, current_amount);
			}
		}

		if (current_index != NULL) {
			node = plist_dict_get_item(status, "CurrentIndex");
			if (node) {
				plist_get_uint_val(node, current_index);
			}
		}
	}
}
コード例 #24
0
/**
 * Installs the given provisioning profile. Only works with valid profiles.
 *
 * @param client The connected misagent to use for installation
 * @param profile The valid provisioning profile to install. This has to be
 *    passed as a PLIST_DATA, otherwise the function will fail.
 *
 * @return MISAGENT_E_SUCCESS on success, MISAGENT_E_INVALID_ARG when
 *     client is invalid, or an MISAGENT_E_* error code otherwise.
 */
misagent_error_t misagent_install(misagent_client_t client, plist_t profile)
{
	if (!client || !client->parent || !profile || (plist_get_node_type(profile) != PLIST_DATA))
                return MISAGENT_E_INVALID_ARG;

	client->last_error = MISAGENT_E_UNKNOWN_ERROR;

	plist_t dict = plist_new_dict();
	plist_dict_insert_item(dict, "MessageType", plist_new_string("Install"));
	plist_dict_insert_item(dict, "Profile", plist_copy(profile));
	plist_dict_insert_item(dict, "ProfileType", plist_new_string("Provisioning"));

	misagent_error_t res = misagent_error(property_list_service_send_xml_plist(client->parent, dict));
	plist_free(dict);
	dict = NULL;

        if (res != MISAGENT_E_SUCCESS) {
                debug_info("could not send plist, error %d", res);
		return res;
        }

	res = misagent_error(property_list_service_receive_plist(client->parent, &dict));
	if (res != MISAGENT_E_SUCCESS) {
		debug_info("could not receive response, error %d", res);
		return res;
	}
	if (!dict) {
		debug_info("could not get response plist");
		return MISAGENT_E_UNKNOWN_ERROR;
	}

	res = misagent_check_result(dict, &client->last_error);
	plist_free(dict);

	return res;
}
コード例 #25
0
ファイル: xplist.c プロジェクト: EchoLiao/libplist
static void xml_to_node(xmlNodePtr xml_node, plist_t * plist_node)
{
    xmlNodePtr node = NULL;
    plist_data_t data = NULL;
    plist_t subnode = NULL;

    //for string
    long len = 0;
    int type = 0;

    if (!xml_node)
        return;

    for (node = xml_node->children; node; node = node->next)
    {

        while (node && !xmlStrcmp(node->name, XPLIST_TEXT))
            node = node->next;
        if (!node)
            break;

        if (!xmlStrcmp(node->name, BAD_CAST("comment"))) {
            continue;
        }

        data = plist_new_plist_data();
        subnode = plist_new_node(data);
        if (*plist_node)
            node_attach(*plist_node, subnode);
        else
            *plist_node = subnode;

        if (!xmlStrcmp(node->name, XPLIST_TRUE))
        {
            data->boolval = TRUE;
            data->type = PLIST_BOOLEAN;
            data->length = 1;
            continue;
        }

        if (!xmlStrcmp(node->name, XPLIST_FALSE))
        {
            data->boolval = FALSE;
            data->type = PLIST_BOOLEAN;
            data->length = 1;
            continue;
        }

        if (!xmlStrcmp(node->name, XPLIST_INT))
        {
            xmlChar *strval = xmlNodeGetContent(node);
            int is_negative = 0;
            char *str = (char*)strval;
            if ((str[0] == '-') || (str[0] == '+')) {
                if (str[0] == '-') {
                    is_negative = 1;
                }
                str++;
            }
            char* endp = NULL;
            data->intval = strtoull((char*)str, &endp, 0);
            if ((endp != NULL) && (strlen(endp) > 0)) {
                fprintf(stderr, "%s: integer parse error: string contains invalid characters: '%s'\n", __func__, endp);
            }
            if (is_negative || (data->intval <= INT64_MAX)) {
                int64_t v = data->intval;
                if (is_negative) {
                    v = -v;
                }
                data->intval = (uint64_t)v;
                data->length = 8;
            } else {
                data->length = 16;
            }
            data->type = PLIST_UINT;
            xmlFree(strval);
            continue;
        }

        if (!xmlStrcmp(node->name, XPLIST_REAL))
        {
            xmlChar *strval = xmlNodeGetContent(node);
            data->realval = atof((char *) strval);
            data->type = PLIST_REAL;
            data->length = 8;
            xmlFree(strval);
            continue;
        }

        if (!xmlStrcmp(node->name, XPLIST_DATE))
        {
            xmlChar *strval = xmlNodeGetContent(node);
            time_t timev = 0;
            if (strlen((const char*)strval) >= 11) {
                struct tm btime;
                struct tm* tm_utc;
                parse_date((const char*)strval, &btime);
                timev = mktime(&btime);
                tm_utc = gmtime(&timev);
                timev -= (mktime(tm_utc) - timev);
            }
            data->timeval.tv_sec = (long)(timev - MAC_EPOCH);
            data->timeval.tv_usec = 0;
            data->type = PLIST_DATE;
            data->length = sizeof(struct timeval);
            xmlFree(strval);
            continue;
        }

        if (!xmlStrcmp(node->name, XPLIST_STRING))
        {
            xmlChar *strval = xmlNodeGetContent(node);
            len = strlen((char *) strval);
            type = xmlDetectCharEncoding(strval, len);

            if (XML_CHAR_ENCODING_UTF8 == type || XML_CHAR_ENCODING_ASCII == type || XML_CHAR_ENCODING_NONE == type)
            {
                data->strval = strdup((char *) strval);
                data->type = PLIST_STRING;
                data->length = strlen(data->strval);
            }
            xmlFree(strval);
            continue;
        }

        if (!xmlStrcmp(node->name, XPLIST_KEY))
        {
            xmlChar *strval = xmlNodeGetContent(node);
            len = strlen((char *) strval);
            type = xmlDetectCharEncoding(strval, len);

            if (XML_CHAR_ENCODING_UTF8 == type || XML_CHAR_ENCODING_ASCII == type || XML_CHAR_ENCODING_NONE == type)
            {
                data->strval = strdup((char *) strval);
                data->type = PLIST_KEY;
                data->length = strlen(data->strval);
            }
            xmlFree(strval);
            continue;
        }

        if (!xmlStrcmp(node->name, XPLIST_DATA))
        {
            xmlChar *strval = xmlNodeGetContent(node);
            size_t size = 0;
            unsigned char *dec = base64decode((char*)strval, &size);
            data->buff = (uint8_t *) malloc(size * sizeof(uint8_t));
            memcpy(data->buff, dec, size * sizeof(uint8_t));
            free(dec);
            data->length = size;
            data->type = PLIST_DATA;
            xmlFree(strval);
            continue;
        }

        if (!xmlStrcmp(node->name, XPLIST_ARRAY))
        {
            data->type = PLIST_ARRAY;
            xml_to_node(node, &subnode);
            continue;
        }

        if (!xmlStrcmp(node->name, XPLIST_DICT))
        {
            data->type = PLIST_DICT;
            xml_to_node(node, &subnode);
            if (plist_get_node_type(subnode) == PLIST_DICT) {
                if (plist_dict_get_size(subnode) == 1) {
                    plist_t uid = plist_dict_get_item(subnode, "CF$UID");
                    if (uid) {
                        uint64_t val = 0;
                        plist_get_uint_val(uid, &val);
                        plist_dict_remove_item(subnode, "CF$UID");
                        plist_data_t nodedata = plist_get_data((node_t*)subnode);
                        free(nodedata->buff);
                        nodedata->type = PLIST_UID;
                        nodedata->length = sizeof(uint64_t);
                        nodedata->intval = val;
                    } 
                }
            }
            continue;
        }
    }
}
コード例 #26
0
ファイル: plist.c プロジェクト: daiwx/libplist
void plist_get_data_val(plist_t node, char **val, uint64_t * length)
{
    plist_type type = plist_get_node_type(node);
    if (PLIST_DATA == type)
        plist_get_type_and_value(node, &type, (void *) val, length);
}
コード例 #27
0
ファイル: normal.c プロジェクト: MephistoLa/bootsigned
static int normal_idevice_new(struct idevicerestore_client_t* client, idevice_t* device)
{
	int num_devices = 0;
	char **devices = NULL;
	idevice_get_device_list(&devices, &num_devices);
	if (num_devices == 0) {
		return -1;
	}
	*device = NULL;
	idevice_t dev = NULL;
	idevice_error_t device_error;
	lockdownd_client_t lockdown = NULL;
	int j;
	for (j = 0; j < num_devices; j++) {
		if (lockdown != NULL) {
			lockdownd_client_free(lockdown);
			lockdown = NULL;
		}
		if (dev != NULL) {
			idevice_free(dev);
			dev = NULL;
		}
		device_error = idevice_new(&dev, devices[j]);
		if (device_error != IDEVICE_E_SUCCESS) {
			error("ERROR: %s: can't open device with UUID %s", __func__, devices[j]);
			continue;
		}

		if (lockdownd_client_new(dev, &lockdown, "idevicerestore") != LOCKDOWN_E_SUCCESS) {
			error("ERROR: %s: can't connect to lockdownd on device with UUID %s", __func__, devices[j]);
			continue;

		}
		char* type = NULL;
		if (lockdownd_query_type(lockdown, &type) != LOCKDOWN_E_SUCCESS) {
			continue;
		}
		if (strcmp(type, "com.apple.mobile.lockdown") != 0) {
			free(type);
			continue;
		}
		free(type);

		if (client->ecid != 0) {
			plist_t node = NULL;
			if ((lockdownd_get_value(lockdown, NULL, "UniqueChipID", &node) != LOCKDOWN_E_SUCCESS) || !node || (plist_get_node_type(node) != PLIST_UINT)){
				if (node) {
					plist_free(node);
				}
				continue;
			}
			lockdownd_client_free(lockdown);
			lockdown = NULL;

			uint64_t this_ecid = 0;
			plist_get_uint_val(node, &this_ecid);
			plist_free(node);

			if (this_ecid != client->ecid) {
				continue;
			}
		}
		if (lockdown) {
			lockdownd_client_free(lockdown);
			lockdown = NULL;
		}
		client->uuid = strdup(devices[j]);
		*device = dev;
		break;
	}
	idevice_device_list_free(devices);

	return 0;
}
コード例 #28
0
ファイル: ideviceinfo.c プロジェクト: awadaolqi/irestore
static void plist_node_to_string(plist_t node)
{
	char *s = NULL;
	char *data = NULL;
	double d;
	uint8_t b;
	uint64_t u = 0;
	GTimeVal tv = { 0, 0 };

	plist_type t;

	if (!node)
		return;

	t = plist_get_node_type(node);

	switch (t) {
	case PLIST_BOOLEAN:
		plist_get_bool_val(node, &b);
		printf("%s\n", (b ? "true" : "false"));
		break;

	case PLIST_UINT:
		plist_get_uint_val(node, &u);
		printf("%llu\n", (long long)u);
		break;

	case PLIST_REAL:
		plist_get_real_val(node, &d);
		printf("%f\n", d);
		break;

	case PLIST_STRING:
		plist_get_string_val(node, &s);
		printf("%s\n", s);
		free(s);
		break;

	case PLIST_KEY:
		plist_get_key_val(node, &s);
		printf("%s: ", s);
		free(s);
		break;

	case PLIST_DATA:
		plist_get_data_val(node, &data, &u);
		s = g_base64_encode((guchar *)data, u);
		free(data);
		printf("%s\n", s);
		g_free(s);
		break;

	case PLIST_DATE:
		plist_get_date_val(node, (int32_t*)&tv.tv_sec, (int32_t*)&tv.tv_usec);
		s = g_time_val_to_iso8601(&tv);
		printf("%s\n", s);
		free(s);
		break;

	case PLIST_ARRAY:
		printf("\n");
		indent_level++;
		plist_array_to_string(node);
		indent_level--;
		break;

	case PLIST_DICT:
		printf("\n");
		indent_level++;
		plist_dict_to_string(node);
		indent_level--;
		break;

	default:
		break;
	}
}
コード例 #29
0
ファイル: tss.c プロジェクト: MephistoLa/bootsigned
plist_t tss_create_request(plist_t build_identity, uint64_t ecid, unsigned char* nonce, int nonce_size) {
	uint64_t unique_build_size = 0;
	char* unique_build_data = NULL;
	plist_t unique_build_node = plist_dict_get_item(build_identity, "UniqueBuildID");
	if (!unique_build_node || plist_get_node_type(unique_build_node) != PLIST_DATA) {
		error("ERROR: Unable to find UniqueBuildID node\n");
		return NULL;
	}
	plist_get_data_val(unique_build_node, &unique_build_data, &unique_build_size);

	int chip_id = 0;
	char* chip_id_string = NULL;
	plist_t chip_id_node = plist_dict_get_item(build_identity, "ApChipID");
	if (!chip_id_node || plist_get_node_type(chip_id_node) != PLIST_STRING) {
		error("ERROR: Unable to find ApChipID node\n");
		return NULL;
	}
	plist_get_string_val(chip_id_node, &chip_id_string);
	sscanf(chip_id_string, "%x", &chip_id);

	int board_id = 0;
	char* board_id_string = NULL;
	plist_t board_id_node = plist_dict_get_item(build_identity, "ApBoardID");
	if (!board_id_node || plist_get_node_type(board_id_node) != PLIST_STRING) {
		error("ERROR: Unable to find ApBoardID node\n");
		return NULL;
	}
	plist_get_string_val(board_id_node, &board_id_string);
	sscanf(board_id_string, "%x", &board_id);

	int security_domain = 0;
	char* security_domain_string = NULL;
	plist_t security_domain_node = plist_dict_get_item(build_identity, "ApSecurityDomain");
	if (!security_domain_node || plist_get_node_type(security_domain_node) != PLIST_STRING) {
		error("ERROR: Unable to find ApSecurityDomain node\n");
		return NULL;
	}
	plist_get_string_val(security_domain_node, &security_domain_string);
	sscanf(security_domain_string, "%x", &security_domain);

	char ecid_string[ECID_STRSIZE];
	memset(ecid_string, '\0', ECID_STRSIZE);
	if (ecid == 0) {
		error("ERROR: Unable to get ECID\n");
		return NULL;
	}
	snprintf(ecid_string, ECID_STRSIZE, FMT_qu, (long long unsigned int)ecid);

	// Add build information to TSS request
	plist_t tss_request = plist_new_dict();
	plist_dict_insert_item(tss_request, "@APTicket", plist_new_bool(1));
	plist_dict_insert_item(tss_request, "@BBTicket", plist_new_bool(1));
	plist_dict_insert_item(tss_request, "@HostIpAddress", plist_new_string("192.168.0.1"));
	plist_dict_insert_item(tss_request, "@HostPlatformInfo", plist_new_string("mac"));
	plist_dict_insert_item(tss_request, "@Locality", plist_new_string("en_US"));
	char* guid = generate_guid();
	if (guid) {
		plist_dict_insert_item(tss_request, "@UUID", plist_new_string(guid));
		free(guid);
	}
	plist_dict_insert_item(tss_request, "@VersionInfo", plist_new_string("libauthinstall-107.3"));
	plist_dict_insert_item(tss_request, "ApBoardID", plist_new_uint(board_id));
	plist_dict_insert_item(tss_request, "ApChipID", plist_new_uint(chip_id));
	plist_dict_insert_item(tss_request, "ApECID", plist_new_string(ecid_string));
	if (nonce && (nonce_size > 0)) {
		plist_dict_insert_item(tss_request, "ApNonce", plist_new_data(nonce, nonce_size));
	}
	plist_dict_insert_item(tss_request, "ApProductionMode", plist_new_bool(1));
	plist_dict_insert_item(tss_request, "ApSecurityDomain", plist_new_uint(security_domain));
	plist_dict_insert_item(tss_request, "UniqueBuildID", plist_new_data(unique_build_data, unique_build_size));
	free(unique_build_data);

	// Add all firmware files to TSS request
	plist_t manifest_node = plist_dict_get_item(build_identity, "Manifest");
	if (!manifest_node || plist_get_node_type(manifest_node) != PLIST_DICT) {
		error("ERROR: Unable to find restore manifest\n");
		plist_free(tss_request);
		return NULL;
	}

	char* key = NULL;
	plist_t manifest_entry = NULL;
	plist_dict_iter iter = NULL;
	plist_dict_new_iter(manifest_node, &iter);
	while (1) {
		plist_dict_next_item(manifest_node, iter, &key, &manifest_entry);
		if (key == NULL)
			break;
		if (!manifest_entry || plist_get_node_type(manifest_entry) != PLIST_DICT) {
			error("ERROR: Unable to fetch BuildManifest entry\n");
			free(tss_request);
			return NULL;
		}

		if (strcmp(key, "BasebandFirmware") == 0) {
			free(key);
			continue;
		}

		plist_t tss_entry = plist_copy(manifest_entry);
		plist_dict_insert_item(tss_request, key, tss_entry);
		free(key);
	}

	if (idevicerestore_debug) {
		debug_plist(tss_request);
	}

	return tss_request;
}
コード例 #30
0
ファイル: ideviceinfo.c プロジェクト: awadaolqi/irestore
int main(int argc, char *argv[])
{
	lockdownd_client_t client = NULL;
	idevice_t phone = NULL;
	idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR;
	int i;
	int simple = 0;
	int format = FORMAT_KEY_VALUE;
	char uuid[41];
	char *domain = NULL;
	char *key = NULL;
	char *xml_doc = NULL;
	uint32_t xml_length;
	plist_t node = NULL;
	plist_type node_type;
	uuid[0] = 0;

	/* parse cmdline args */
	for (i = 1; i < argc; i++) {
		if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) {
			idevice_set_debug_level(1);
			continue;
		}
		else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--uuid")) {
			i++;
			if (!argv[i] || (strlen(argv[i]) != 40)) {
				print_usage(argc, argv);
				return 0;
			}
			strcpy(uuid, argv[i]);
			continue;
		}
		else if (!strcmp(argv[i], "-q") || !strcmp(argv[i], "--domain")) {
			i++;
			if (!argv[i] || (strlen(argv[i]) < 4)) {
				print_usage(argc, argv);
				return 0;
			}
			if (!is_domain_known(argv[i])) {
				fprintf(stderr, "WARNING: Sending query with unknown domain \"%s\".\n", argv[i]);
			}
			domain = strdup(argv[i]);
			continue;
		}
		else if (!strcmp(argv[i], "-k") || !strcmp(argv[i], "--key")) {
			i++;
			if (!argv[i] || (strlen(argv[i]) <= 1)) {
				print_usage(argc, argv);
				return 0;
			}
			key = strdup(argv[i]);
			continue;
		}
		else if (!strcmp(argv[i], "-x") || !strcmp(argv[i], "--xml")) {
			format = FORMAT_XML;
			continue;
		}
		else if (!strcmp(argv[i], "-s") || !strcmp(argv[i], "--simple")) {
			simple = 1;
			continue;
		}
		else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
			print_usage(argc, argv);
			return 0;
		}
		else {
			print_usage(argc, argv);
			return 0;
		}
	}

	if (uuid[0] != 0) {
		ret = idevice_new(&phone, uuid);
		if (ret != IDEVICE_E_SUCCESS) {
			printf("No device found with uuid %s, is it plugged in?\n", uuid);
			return -1;
		}
	}
	else
	{
		ret = idevice_new(&phone, NULL);
		if (ret != IDEVICE_E_SUCCESS) {
			printf("No device found, is it plugged in?\n");
			return -1;
		}
	}

	if (LOCKDOWN_E_SUCCESS != (simple ?
			lockdownd_client_new(phone, &client, "ideviceinfo"):
			lockdownd_client_new_with_handshake(phone, &client, "ideviceinfo"))) {
		idevice_free(phone);
		return -1;
	}

	/* run query and output information */
	if(lockdownd_get_value(client, domain, key, &node) == LOCKDOWN_E_SUCCESS) {
		if (node) {
			switch (format) {
			case FORMAT_XML:
				plist_to_xml(node, &xml_doc, &xml_length);
				printf("%s", xml_doc);
				free(xml_doc);
				break;
			case FORMAT_KEY_VALUE:
				node_type = plist_get_node_type(node);
				if (node_type == PLIST_DICT) {
					plist_dict_to_string(node);
				} else if (node_type == PLIST_ARRAY) {
					plist_array_to_string(node);
					break;
				}
			default:
				if (key != NULL)
					plist_node_to_string(node);
			break;
			}
			plist_free(node);
			node = NULL;
		}
	}

	if (domain != NULL)
		free(domain);
	lockdownd_client_free(client);
	idevice_free(phone);

	return 0;
}