コード例 #1
0
ファイル: restore.c プロジェクト: rcg4u/idevicerestore
int restore_handle_progress_msg(restored_client_t client, plist_t msg) {
	plist_t node = NULL;
	uint64_t progress = 0;
	uint64_t operation = 0;

	node = plist_dict_get_item(msg, "Operation");
	if (!node || plist_get_node_type(node) != PLIST_UINT) {
		debug("Failed to parse operation from ProgressMsg plist\n");
		return -1;
	}
	plist_get_uint_val(node, &operation);

	node = plist_dict_get_item(msg, "Progress");
	if (!node || plist_get_node_type(node) != PLIST_UINT) {
		debug("Failed to parse progress from ProgressMsg plist \n");
		return -1;
	}
	plist_get_uint_val(node, &progress);

	if ((progress > 0) && (progress < 100)) {
		print_progress_bar(restore_progress_string(operation), (double) progress);

	} else {
		info("%s\n", restore_progress_string(operation));
	}

	return 0;
}
コード例 #2
0
ファイル: openiapp.c プロジェクト: jevinskie/OpenSun-C
void minst_client(const char *operation, plist_t status, void *unused) {
    cb++;
    if (cb == 8) {
    }
    if (status && operation) {
        plist_t npercent = plist_dict_get_item(status, "PercentComplete");
        plist_t nstatus = plist_dict_get_item(status, "Status");
        plist_t nerror = plist_dict_get_item(status, "Error");
        int percent = 0;
        char *status_msg = NULL;
        if (npercent) {
            uint64_t val = 0;
            plist_get_uint_val(npercent, &val);
            percent = val;
        }
        if (nstatus) {
            plist_get_string_val(nstatus, &status_msg);
            if (!strcmp(status_msg, "Complete")) {
                sleep(1);
                installing = 0;
            }
        }

        if (nerror) {
            char *err_msg = NULL;
            plist_get_string_val(nerror, &err_msg);
            free(err_msg);
            installing = 0;
            installError = 1;
        }
    } else {
    }
}
コード例 #3
0
ファイル: iphoneinfo.c プロジェクト: sladen/libiphone
void plist_node_to_string(plist_t *node)
{
	char *s = NULL;
	double d;
	uint8_t b;

	uint64_t u = 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", 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:
		printf("\n");
		break;
	case PLIST_DATE:
		printf("\n");
		break;
	case PLIST_ARRAY:
	case PLIST_DICT:
		printf("\n");
		plist_children_to_string(node);
		break;
	default:
		break;
	}
}
コード例 #4
0
ファイル: restore.c プロジェクト: skposs/WinLibmobiledevice
LIBIMOBILEDEVICE_API restored_error_t restored_query_type(restored_client_t client, char **type, uint64_t *version)
{
	if (!client)
		return RESTORE_E_INVALID_ARG;

	restored_error_t ret = RESTORE_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 = restored_send(client, dict);

	plist_free(dict);
	dict = NULL;

	ret = restored_receive(client, &dict);

	if (RESTORE_E_SUCCESS != ret)
		return ret;

	ret = RESTORE_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;

		/* save our device information info */
		client->info = dict;

		plist_get_string_val(type_node, &typestr);
		debug_info("success with type %s", typestr);
		/* return the type if requested */
		if (type) {
			*type = typestr;
		} else {
			free(typestr);
		}

		/* fetch the restore protocol version */
		if (version) {
			plist_t version_node = plist_dict_get_item(dict, "RestoreProtocolVersion");
			if (version_node && PLIST_UINT == plist_get_node_type(version_node)) {
				plist_get_uint_val(version_node, version);
				debug_info("restored protocol version %llu", *version);
			} else {
				return RESTORE_E_UNKNOWN_ERROR;
			}
		}
		ret = RESTORE_E_SUCCESS;
	} else {
		debug_info("hmm. QueryType response does not contain a type?!");
		debug_plist(dict);
		plist_free(dict);
	}

	return ret;
}
コード例 #5
0
ファイル: asr.c プロジェクト: aburgh/idevicerestore
int asr_handle_oob_data_request(asr_client_t asr, plist_t packet, FILE* file) {
	char* oob_data = NULL;
	uint64_t oob_offset = 0;
	uint64_t oob_length = 0;
	plist_t oob_length_node = NULL;
	plist_t oob_offset_node = NULL;

	oob_length_node = plist_dict_get_item(packet, "OOB Length");
	if (!oob_length_node || PLIST_UINT != plist_get_node_type(oob_length_node)) {
		error("ERROR: Unable to find OOB data length\n");
		return -1;
	}
	plist_get_uint_val(oob_length_node, &oob_length);

	oob_offset_node = plist_dict_get_item(packet, "OOB Offset");
	if (!oob_offset_node || PLIST_UINT != plist_get_node_type(oob_offset_node)) {
		error("ERROR: Unable to find OOB data offset\n");
		return -1;
	}
	plist_get_uint_val(oob_offset_node, &oob_offset);

	oob_data = (char*) malloc(oob_length);
	if (oob_data == NULL) {
		error("ERROR: Out of memory\n");
		plist_free(packet);
		return -1;
	}

	fseek(file, oob_offset, SEEK_SET);
	if (fread(oob_data, 1, oob_length, file) != oob_length) {
		error("ERROR: Unable to read OOB data from filesystem offset\n");
		plist_free(packet);
		free(oob_data);
		return -1;
	}

	if (asr_send_buffer(asr, oob_data, oob_length) < 0) {
		error("ERROR: Unable to send OOB data to ASR\n");
		plist_free(packet);
		free(oob_data);
		return -1;
	}
	free(oob_data);
	return 0;
}
コード例 #6
0
/**
 * Performs the mobilebackup2 protocol version exchange.
 * 
 * @param client The MobileBackup client to use.
 * @param local_versions An array of supported versions to send to the remote.
 * @param count The number of items in local_versions.
 * @param remote_version Holds the protocol version of the remote on success.
 * 
 * @return MOBILEBACKUP2_E_SUCCESS on success, or a MOBILEBACKUP2_E_* error
 *     code otherwise.
 */
mobilebackup2_error_t mobilebackup2_version_exchange(mobilebackup2_client_t client, double local_versions[], char count, double *remote_version)
{
	int i;

	if (!client || !client->parent)
		return MOBILEBACKUP2_E_INVALID_ARG;

	plist_t dict = plist_new_dict();
	plist_t array = plist_new_array();
	for (i = 0; i < count; i++) {
		plist_array_append_item(array, plist_new_real(local_versions[i]));
	}
	plist_dict_insert_item(dict, "SupportedProtocolVersions", array);

	mobilebackup2_error_t err = mobilebackup2_send_message(client, "Hello", dict);
	plist_free(dict);

	if (err != MOBILEBACKUP2_E_SUCCESS)
		goto leave;

	dict = NULL;
	err = internal_mobilebackup2_receive_message(client, "Response", &dict);
	if (err != MOBILEBACKUP2_E_SUCCESS)
		goto leave;

	/* check if we received an error */
	plist_t node = plist_dict_get_item(dict, "ErrorCode");
	if (!node || (plist_get_node_type(node) != PLIST_UINT)) {
		err = MOBILEBACKUP2_E_PLIST_ERROR;
		goto leave;
	}

	uint64_t val = 0;
	plist_get_uint_val(node, &val);
	if (val != 0) {
		if (val == 1) {
			err = MOBILEBACKUP2_E_NO_COMMON_VERSION;
		} else {
			err = MOBILEBACKUP2_E_REPLY_NOT_OK;
		}
		goto leave;
	}

	/* retrieve the protocol version of the device */
	node = plist_dict_get_item(dict, "ProtocolVersion");
	if (!node || (plist_get_node_type(node) != PLIST_REAL)) {
		err = MOBILEBACKUP2_E_PLIST_ERROR;
		goto leave;
	}

	*remote_version = 0.0;
	plist_get_real_val(node, remote_version);
leave:
	if (dict)
		plist_free(dict);
	return err;
}
コード例 #7
0
/**
 * Query the type of the service daemon. Depending on whether the device is
 * queried in normal mode or restore mode, different types will be returned.
 *
 * @param client The restored client
 * @param type The type returned by the service daemon. Pass NULL to ignore.
 * @param version The restore protocol version. Pass NULL to ignore.
 *
 * @return RESTORE_E_SUCCESS on success, NP_E_INVALID_ARG when client is NULL
 */
restored_error_t restored_query_type(restored_client_t client, char **type, uint64_t *version)
{
	if (!client)
		return RESTORE_E_INVALID_ARG;

	restored_error_t ret = RESTORE_E_UNKNOWN_ERROR;

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

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

	plist_free(dict);
	dict = NULL;

	ret = restored_receive(client, &dict);
	
	if (RESTORE_E_SUCCESS != ret)
		return ret;

	ret = RESTORE_E_UNKNOWN_ERROR;
	if (restored_check_result(dict) == RESULT_SUCCESS) {
		/* save our device information info */
		client->info = dict;
		
		/* return the type if requested */
		if (type) {
			plist_t type_node = plist_dict_get_item(dict, "Type");
			if (type_node && PLIST_STRING == plist_get_node_type(type_node)) {
				plist_get_string_val(type_node, type);
				debug_info("success with type %s", *type);
				ret = RESTORE_E_SUCCESS;
			} else {
				return RESTORE_E_UNKNOWN_ERROR;
			}
		}

		/* fetch the restore protocol version */
		if (version) {
			plist_t version_node = plist_dict_get_item(dict, "RestoreProtocolVersion");
			if (version_node && PLIST_UINT == plist_get_node_type(version_node)) {
				plist_get_uint_val(version_node, version);
				debug_info("restored protocol version %llu", *version);
				ret = RESTORE_E_SUCCESS;
			} else {
				return RESTORE_E_UNKNOWN_ERROR;
			}
		}
		ret = RESTORE_E_SUCCESS;
	}

	return ret;
}
コード例 #8
0
LIBIMOBILEDEVICE_API void instproxy_status_get_percent_complete(plist_t status, int *percent)
{
	uint64_t val = 0;
	if (percent) {
		plist_t node = plist_dict_get_item(status, "PercentComplete");
		if (node) {
			plist_get_uint_val(node, &val);
			*percent = val;
		}
	}
}
コード例 #9
0
ファイル: rproxy.c プロジェクト: 4kzeng/idevicerestore
static int get_plist_uint_val(plist_t dict, const char * key, uint64_t * val)
{
    plist_t node = plist_dict_get_item(dict, key);
    if (NULL == node) {
        return -1;
    }
    if (PLIST_UINT != plist_get_node_type(node)) {
        return -1;
    }

    plist_get_uint_val(node, val);
    return 0;
}
コード例 #10
0
static void status_cb(const char *operation, plist_t status)
#endif
{
	if (status && operation) {
		plist_t npercent = plist_dict_get_item(status, "PercentComplete");
		plist_t nstatus = plist_dict_get_item(status, "Status");
		plist_t nerror = plist_dict_get_item(status, "Error");
		int percent = 0;
		char *status_msg = NULL;
		if (npercent) {
			uint64_t val = 0;
			plist_get_uint_val(npercent, &val);
			percent = val;
		}
		if (nstatus) {
			plist_get_string_val(nstatus, &status_msg);
			if (!strcmp(status_msg, "Complete")) {
				op_completed = 1;
			}
		}
		if (!nerror) {
			if (last_status && (strcmp(last_status, status_msg))) {
				printf("\r");
			}

			if (!npercent) {
				printf("%s - %s\n", operation, status_msg);
			} else {
				printf("%s - %s (%d%%)\n", operation, status_msg, percent);
			}
		} else {
			char *err_msg = NULL;
			plist_get_string_val(nerror, &err_msg);
			printf("%s - Error occured: %s\n", operation, err_msg);
			free(err_msg);
			err_occured = 1;
		}
		if (last_status) {
			free(last_status);
			last_status = NULL;
		}
		if (status_msg) {
			last_status = strdup(status_msg);
			free(status_msg);
		}
	} else {
		printf("%s: called with invalid data!\n", __func__);
	}
}
コード例 #11
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);
			}
		}
	}
}
コード例 #12
0
/* plist helpers */
static int
get_dictval_int_from_key(plist_t dict, const char *key, uint64_t *val)
{
  plist_t node;

  node = plist_dict_get_item(dict, key);

  if (!node)
    return -1;

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

  plist_get_uint_val(node, val);

  return 0;
}
コード例 #13
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;
}
コード例 #14
0
/**
 * Checks the response from misagent to determine if the operation
 * was successful or an error occured. Internally used only.
 *
 * @param response a PLIST_DICT received from device's misagent
 * @param status_code pointer to an int that will be set to the status code
 *   contained in the response
 */
static misagent_error_t misagent_check_result(plist_t response, int* status_code)
{
	if (plist_get_node_type(response) != PLIST_DICT) {
		return MISAGENT_E_PLIST_ERROR;
	}

	plist_t node = plist_dict_get_item(response, "Status");
	if (!node || (plist_get_node_type(node) != PLIST_UINT)) {
		return MISAGENT_E_PLIST_ERROR;
	}

	uint64_t val = -1LL;
	plist_get_uint_val(node, &val);
	if ((int64_t)val == -1LL) {
		return MISAGENT_E_PLIST_ERROR;
	}
	*status_code = (int)(val & 0xFFFFFFFF);
	if (*status_code == 0) {
		return MISAGENT_E_SUCCESS;
	} else {
		return MISAGENT_E_REQUEST_FAILED;
	}
}
コード例 #15
0
LIBIMOBILEDEVICE_API instproxy_error_t instproxy_status_get_error(plist_t status, char **name, char** description, uint64_t* code)
{
	instproxy_error_t res = INSTPROXY_E_UNKNOWN_ERROR;

	if (!status || !name)
		return INSTPROXY_E_INVALID_ARG;

	plist_t node = plist_dict_get_item(status, "Error");
	if (node) {
		plist_get_string_val(node, name);
	} else {
		/* no error here */
		res = INSTPROXY_E_SUCCESS;
	}

	if (code != NULL) {
		*code = 0;
		node = plist_dict_get_item(status, "ErrorDetail");
		if (node) {
			plist_get_uint_val(node, code);
			*code &= 0xffffffff;
		}
	}

	if (description != NULL) {
		node = plist_dict_get_item(status, "ErrorDescription");
		if (node) {
			plist_get_string_val(node, description);
		}
	}

	if (*name) {
		res = instproxy_strtoerr(*name);
	}

	return res;
}
コード例 #16
0
/**
 * Gets the interface orientation of the device.
 *
 * @param client The connected sbservices client to use.
 * @param interface_orientation The interface orientation upon successful return.
 *
 * @return SBSERVICES_E_SUCCESS on success, SBSERVICES_E_INVALID_ARG when
 *     client or state is invalid, or an SBSERVICES_E_* error code otherwise.
 */
sbservices_error_t sbservices_get_interface_orientation(sbservices_client_t client, sbservices_interface_orientation_t* interface_orientation)
{
	if (!client || !client->parent || !interface_orientation)
		return SBSERVICES_E_INVALID_ARG;

	sbservices_error_t res = SBSERVICES_E_UNKNOWN_ERROR;

	plist_t dict = plist_new_dict();
	plist_dict_insert_item(dict, "command", plist_new_string("getInterfaceOrientation"));

	sbs_lock(client);

	res = sbservices_error(property_list_service_send_binary_plist(client->parent, dict));
	if (res != SBSERVICES_E_SUCCESS) {
		debug_info("could not send plist, error %d", res);
		goto leave_unlock;
	}
	plist_free(dict);
	dict = NULL;

	res = sbservices_error(property_list_service_receive_plist(client->parent, &dict));
	if (res	== SBSERVICES_E_SUCCESS) {
		plist_t node = plist_dict_get_item(dict, "interfaceOrientation");
		if (node) {
			uint64_t value = SBSERVICES_INTERFACE_ORIENTATION_UNKNOWN;
			plist_get_uint_val(node, &value);
			*interface_orientation = (sbservices_interface_orientation_t)value;
		}
	}

leave_unlock:
	if (dict) {
		plist_free(dict);
	}
	sbs_unlock(client);
	return res;
}
コード例 #17
0
ファイル: restore.c プロジェクト: rcg4u/idevicerestore
int restore_handle_status_msg(restored_client_t client, plist_t msg) {
	uint64_t value = 0;
	info("Got status message\n");
	debug_plist(msg);

	plist_t node = plist_dict_get_item(msg, "Status");
	plist_get_uint_val(node, &value);

	switch(value) {
		case 0:
			info("Status: Restore Finished\n");
			break;
		case 6:
			info("Status: Disk Failure\n");
			break;
		case 14:
			info("Status: Fail\n");
			break;
		default:
			info("Unknown status message.\n");
	}

	return 0;
}
コード例 #18
0
ファイル: idevicedate.c プロジェクト: HJoYer/libimobiledevice
int main(int argc, char *argv[])
{
	lockdownd_client_t client = NULL;
	lockdownd_error_t ldret = LOCKDOWN_E_UNKNOWN_ERROR;
	idevice_t device = NULL;
	idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR;
	int i;
	const char* udid = NULL;
	time_t setdate = 0;
	plist_t node = NULL;
	int node_type = -1;
	uint64_t datetime = 0;
	time_t rawtime;
	struct tm * tmp;
	char const *format = NULL;
	char buffer[80];
	int result = 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], "--udid")) {
			i++;
			if (!argv[i] || (strlen(argv[i]) != 40)) {
				print_usage(argc, argv);
				return 0;
			}
			udid = argv[i];
			continue;
		}
		else if (!strcmp(argv[i], "-s") || !strcmp(argv[i], "--set")) {
			i++;
			if (!argv[i] || (strlen(argv[i]) <= 1)) {
				print_usage(argc, argv);
				return 0;
			}
			setdate = atoi(argv[i]);
			if (setdate == 0) {
				printf("ERROR: Invalid timestamp value.\n");
				print_usage(argc, argv);
				return 0;
			}
			continue;
		}
		else if (!strcmp(argv[i], "-c") || !strcmp(argv[i], "--sync")) {
			i++;
			/* get current time */
			setdate = time(NULL);
			/* convert it to local time which sets timezone/daylight variables */
			tmp = localtime(&setdate);
			/* recalculate to make it UTC */
			setdate = mktime(tmp);
			continue;
		}
		else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
			print_usage(argc, argv);
			return 0;
		}
		else {
			print_usage(argc, argv);
			return 0;
		}
	}

	/* determine a date format */
	if (!format) {
		format = DATE_FMT_LANGINFO ();
		if (!*format) {
			format = "%a %b %e %H:%M:%S %Z %Y";
		}
	}

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

	if (LOCKDOWN_E_SUCCESS != (ldret = lockdownd_client_new_with_handshake(device, &client, "idevicedate"))) {
		fprintf(stderr, "ERROR: Could not connect to lockdownd, error code %d\n", ldret);
		result = -1;
		goto cleanup;
	}

	if(lockdownd_get_value(client, NULL, "TimeIntervalSince1970", &node) != LOCKDOWN_E_SUCCESS) {
		fprintf(stderr, "ERROR: Unable to retrieve 'TimeIntervalSince1970' node from device.\n");
		result = -1;
		goto cleanup;
	}

	if (node == NULL) {
		fprintf(stderr, "ERROR: Empty node for 'TimeIntervalSince1970' received.\n");
		result = -1;
		goto cleanup;
	}

	node_type = plist_get_node_type(node);

	/* get or set? */
	if (setdate == 0) {
		/* get time value from device */
		switch (node_type) {
			case PLIST_UINT:
				plist_get_uint_val(node, &datetime);
				break;
			case PLIST_REAL:
				{
					double rv = 0;
					plist_get_real_val(node, &rv);
					datetime = rv;
				}
				break;
			default:
				fprintf(stderr, "ERROR: Unexpected node type for 'TimeIntervalSince1970'\n");
				break;
		}
		plist_free(node);
		node = NULL;

		/* date/time calculations */
		rawtime = (time_t)datetime;
		tmp = localtime(&rawtime);

		/* finally we format and print the current date */
		strftime(buffer, 80, format, tmp);
		puts(buffer);
	} else {
		datetime = setdate;

		plist_free(node);
		node = NULL;

		switch (node_type) {
			case PLIST_UINT:
				node = plist_new_uint(datetime);
				break;
			case PLIST_REAL:
				node = plist_new_real((double)datetime);
				break;
			default:
				fprintf(stderr, "ERROR: Unexpected node type for 'TimeIntervalSince1970'\n");
				break;
		}

		if(lockdownd_set_value(client, NULL, "TimeIntervalSince1970", node) == LOCKDOWN_E_SUCCESS) {
			tmp = localtime(&setdate);
			strftime(buffer, 80, format, tmp);
			puts(buffer);
		} else {
			printf("ERROR: Failed to set date on device.\n");
		}
		node = NULL;
	}

cleanup:
	if (client)
		lockdownd_client_free(client);

	if (device)
		idevice_free(device);

	return result;
}
コード例 #19
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;
        }
    }
}
コード例 #20
0
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;
	char udid[41];
	time_t setdate = 0;
	plist_t node = NULL;
	udid[0] = 0;
	uint64_t datetime = 0;
	time_t rawtime;
	struct tm * tmp;
	char const *format = NULL;
	char buffer[80];

	/* 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], "--udid")) {
			i++;
			if (!argv[i] || (strlen(argv[i]) != 40)) {
				print_usage(argc, argv);
				return 0;
			}
			strcpy(udid, argv[i]);
			continue;
		}
		else if (!strcmp(argv[i], "-s") || !strcmp(argv[i], "--set")) {
			i++;
			if (!argv[i] || (strlen(argv[i]) <= 1)) {
				print_usage(argc, argv);
				return 0;
			}
			setdate = atoi(argv[i]);
			if (setdate == 0) {
				printf("ERROR: Invalid timestamp value.\n");
				print_usage(argc, argv);
				return 0;
			}
			continue;
		}
		else if (!strcmp(argv[i], "-c") || !strcmp(argv[i], "--sync")) {
			i++;
			/* get current time */
			setdate = time(NULL);
			/* convert it to local time which sets timezone/daylight variables */
			tmp = localtime(&setdate);
			/* recalculate to make it UTC */
			setdate = mktime(tmp);
			continue;
		}
		else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
			print_usage(argc, argv);
			return 0;
		}
		else {
			print_usage(argc, argv);
			return 0;
		}
	}

	/* determine a date format */
	if (!format) {
		format = DATE_FMT_LANGINFO ();
		if (!*format) {
			format = "%a %b %e %H:%M:%S %Z %Y";
		}
	}

	if (udid[0] != 0) {
		ret = idevice_new(&phone, udid);
		if (ret != IDEVICE_E_SUCCESS) {
			printf("No device found with udid %s, is it plugged in?\n", udid);
			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 != lockdownd_client_new_with_handshake(phone, &client, "idevicedate")) {
		idevice_free(phone);
		return -1;
	}

	/* get or set? */
	if (setdate == 0) {
		/* get time value from device */
		if(lockdownd_get_value(client, NULL, "TimeIntervalSince1970", &node) == LOCKDOWN_E_SUCCESS) {
			if (node) {
				plist_get_uint_val(node, &datetime);
				plist_free(node);
				node = NULL;

				/* date/time calculations */
				rawtime = (time_t)datetime;
				tmp = localtime(&rawtime);

				/* finally we format and print the current date */
				strftime(buffer, 80, format, tmp);
				puts(buffer);
			}
		}
	} else {
		datetime = setdate;

		if(lockdownd_set_value(client, NULL, "TimeIntervalSince1970", plist_new_uint(datetime)) == LOCKDOWN_E_SUCCESS) {
			tmp = localtime(&setdate);
			strftime(buffer, 80, format, tmp);
			puts(buffer);
		} else {
			printf("ERROR: Failed to set date on device.\n");
		}
	}

	lockdownd_client_free(client);
	idevice_free(phone);

	return 0;
}
コード例 #21
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;
	}
}
コード例 #22
0
/**
 * List installed applications. This function runs synchronously.
 *
 * @param client The connected installation_proxy client
 * @param client_options The client options to use, as PLIST_DICT, or NULL.
 *        Valid client options include:
 *          "ApplicationType" -> "User"
 *          "ApplicationType" -> "System"
 * @param result Pointer that will be set to a plist that will hold an array
 *        of PLIST_DICT holding information about the applications found.
 *
 * @return INSTPROXY_E_SUCCESS on success or an INSTPROXY_E_* error value if
 *     an error occured.
 */
instproxy_error_t instproxy_browse(instproxy_client_t client, plist_t client_options, plist_t *result)
{
	if (!client || !client->parent || !result)
		return INSTPROXY_E_INVALID_ARG;

	instproxy_error_t res = INSTPROXY_E_UNKNOWN_ERROR;

	instproxy_lock(client);
	res = instproxy_send_command(client, "Browse", client_options, NULL, NULL);
	if (res != INSTPROXY_E_SUCCESS) {
		debug_info("could not send plist");
		goto leave_unlock;
	}

	int browsing = 0;
	plist_t apps_array = plist_new_array();
	plist_t dict = NULL;

	do {
		browsing = 0;
		dict = NULL;
		res = instproxy_error(property_list_service_receive_plist(client->parent, &dict));
		if (res != INSTPROXY_E_SUCCESS) {
			break;
		}
		if (dict) {
			uint64_t i;
			uint64_t current_amount = 0;
			char *status = NULL;
			plist_t camount = plist_dict_get_item(dict, "CurrentAmount");
			plist_t pstatus = plist_dict_get_item(dict, "Status");
			if (camount) {
				plist_get_uint_val(camount, &current_amount);
			}
			if (current_amount > 0) {
				plist_t current_list = plist_dict_get_item(dict, "CurrentList");
				for (i = 0; current_list && (i < current_amount); i++) {
					plist_t item = plist_array_get_item(current_list, i);
					plist_array_append_item(apps_array, plist_copy(item));
				}
			}
			if (pstatus) {
				plist_get_string_val(pstatus, &status);
			}
			if (status) {
				if (!strcmp(status, "BrowsingApplications")) {
					browsing = 1;
				} else if (!strcmp(status, "Complete")) {
					debug_info("Browsing applications completed");
					res = INSTPROXY_E_SUCCESS;
				}
				free(status);
			}
			plist_free(dict);
		}
	} while (browsing);

	if (res == INSTPROXY_E_SUCCESS) {
		*result = apps_array;
	} else {
		plist_free(apps_array);
	}

leave_unlock:
	instproxy_unlock(client);
	return res;
}
コード例 #23
0
/**
 * Internally used function that will synchronously receive messages from
 * the specified installation_proxy until it completes or an error occurs.
 *
 * If status_cb is not NULL, the callback function will be called each time
 * a status update or error message is received.
 *
 * @param client The connected installation proxy client
 * @param status_cb Pointer to a callback function or NULL
 * @param operation Operation name. Will be passed to the callback function
 *        in async mode or shown in debug messages in sync mode. 
 * @param user_data Callback data passed to status_cb.
 */
static instproxy_error_t instproxy_perform_operation(instproxy_client_t client, instproxy_status_cb_t status_cb, const char *operation, void *user_data)
{
	instproxy_error_t res = INSTPROXY_E_UNKNOWN_ERROR;
	int ok = 1;
	plist_t dict = NULL;

	do {
		instproxy_lock(client);
		res = instproxy_error(property_list_service_receive_plist_with_timeout(client->parent, &dict, 30000));
		instproxy_unlock(client);
		if (res != INSTPROXY_E_SUCCESS) {
			debug_info("could not receive plist, error %d", res);
			break;
		}
		if (dict) {
			/* invoke callback function */
			if (status_cb) {
				status_cb(operation, dict, user_data);
			}
			/* check for 'Error', so we can abort cleanly */
			plist_t err = plist_dict_get_item(dict, "Error");
			if (err) {
#ifndef STRIP_DEBUG_CODE
				char *err_msg = NULL;
				plist_get_string_val(err, &err_msg);
				if (err_msg) {
					debug_info("(%s): ERROR: %s", operation, err_msg);
					free(err_msg);
				}
#endif
				ok = 0;
				res = INSTPROXY_E_OP_FAILED;
			}
			/* get 'Status' */
			plist_t status = plist_dict_get_item(dict, "Status");
			if (status) {
				char *status_msg = NULL;
				plist_get_string_val(status, &status_msg);
				if (status_msg) {
					if (!strcmp(status_msg, "Complete")) {
						ok = 0;
						res = INSTPROXY_E_SUCCESS;
					}
#ifndef STRIP_DEBUG_CODE
					plist_t npercent = plist_dict_get_item(dict, "PercentComplete");
					if (npercent) {
						uint64_t val = 0;
						int percent;
						plist_get_uint_val(npercent, &val);
						percent = val;
						debug_info("(%s): %s (%d%%)", operation, status_msg, percent);
					} else {
						debug_info("(%s): %s", operation, status_msg);
					}
#endif
					free(status_msg);
				}
			}
			plist_free(dict);
			dict = NULL;
		}
	} while (ok && client->parent);

	return res;
}
コード例 #24
0
ファイル: tss.c プロジェクト: zweed4u/idevicerestore
int tss_request_add_baseband_tags(plist_t request, plist_t parameters, plist_t overrides) {
	plist_t node = NULL;

	/* BbChipID */
	node = plist_dict_get_item(parameters, "BbChipID");
	if (node) {
		plist_dict_set_item(request, "BbChipID", plist_copy(node));
	}
	node = NULL;

	/* BbProvisioningManifestKeyHash */
	node = plist_dict_get_item(parameters, "BbProvisioningManifestKeyHash");
	if (node) {
		plist_dict_set_item(request, "BbProvisioningManifestKeyHash", plist_copy(node));
	}
	node = NULL;

	/* BbActivationManifestKeyHash - Used by Qualcomm MDM6610 */
	node = plist_dict_get_item(parameters, "BbActivationManifestKeyHash");
	if (node) {
		plist_dict_set_item(request, "BbActivationManifestKeyHash", plist_copy(node));
	}
	node = NULL;

	node = plist_dict_get_item(parameters, "BbCalibrationManifestKeyHash");
	if (node) {
		plist_dict_set_item(request, "BbCalibrationManifestKeyHash", plist_copy(node));
	}
	node = NULL;

	/* BbFactoryActivationManifestKeyHash */
	node = plist_dict_get_item(parameters, "BbFactoryActivationManifestKeyHash");
	if (node) {
		plist_dict_set_item(request, "BbFactoryActivationManifestKeyHash", plist_copy(node));
	}
	node = NULL;

	/* BbFDRSecurityKeyHash */
	node = plist_dict_get_item(parameters, "BbFDRSecurityKeyHash");
	if (node) {
		plist_dict_set_item(request, "BbFDRSecurityKeyHash", plist_copy(node));
	}
	node = NULL;

	/* BbSkeyId - Used by XMM 6180/GSM */
	node = plist_dict_get_item(parameters, "BbSkeyId");
	if (node) {
		plist_dict_set_item(request, "BbSkeyId", plist_copy(node));
	}
	node = NULL;

	/* BbNonce */
	node = plist_dict_get_item(parameters, "BbNonce");
	if (node) {
		plist_dict_set_item(request, "BbNonce", plist_copy(node));
	}
	node = NULL;

	/* @BBTicket */
	plist_dict_set_item(request, "@BBTicket", plist_new_bool(1));

	/* BbGoldCertId */
	node = plist_dict_get_item(parameters, "BbGoldCertId");
	if (!node || plist_get_node_type(node) != PLIST_UINT) {
		error("ERROR: Unable to find required BbGoldCertId in parameters\n");
		return -1;
	}
	node = plist_copy(node);
	uint64_t val;
	plist_get_uint_val(node, &val);
	plist_set_uint_val(node, (int32_t)val);
	plist_dict_set_item(request, "BbGoldCertId", node);
	node = NULL;

	/* BbSNUM */
	node = plist_dict_get_item(parameters, "BbSNUM");
	if (!node || plist_get_node_type(node) != PLIST_DATA) {
		error("ERROR: Unable to find required BbSNUM in parameters\n");
		return -1;
	}
	plist_dict_set_item(request, "BbSNUM", plist_copy(node));
	node = NULL;

	/* BasebandFirmware */
	node = plist_access_path(parameters, 2, "Manifest", "BasebandFirmware");
	if (!node || plist_get_node_type(node) != PLIST_DICT) {
		error("ERROR: Unable to get BasebandFirmware node\n");
		return -1;
	}
	plist_t bbfwdict = plist_copy(node);
	node = NULL;
	if (plist_dict_get_item(bbfwdict, "Info")) {
		plist_dict_remove_item(bbfwdict, "Info");
	}
	plist_dict_set_item(request, "BasebandFirmware", bbfwdict);

	/* apply overrides */
	if (overrides) {
		plist_dict_merge(&request, overrides);
	}

	return 0;
}
コード例 #25
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;
}
コード例 #26
0
static void plist_node_to_string(plist_t node)
{
	char *s = NULL;
	char *data = NULL;
	double d;
	uint8_t b;
	uint64_t u = 0;
	struct timeval 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);
		uint64_t i;
		for (i = 0; i < u; i++) {
			printf("%02x", (unsigned char)data[i]);
		}
		free(data);
		printf("\n");
		break;

	case PLIST_DATE:
		plist_get_date_val(node, (int32_t*)&tv.tv_sec, (int32_t*)&tv.tv_usec);
		{
			time_t ti = (time_t)tv.tv_sec;
			struct tm *btime = localtime(&ti);
			if (btime) {
				s = (char*)malloc(24);
 				memset(s, 0, 24);
				if (strftime(s, 24, "%Y-%m-%dT%H:%M:%SZ", btime) <= 0) {
					free (s);
					s = NULL;
				}
			}
		}
		if (s) {
			puts(s);
			free(s);
		}
		puts("\n");
		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;
	}
}
コード例 #27
0
ファイル: client.c プロジェクト: badania/usbmuxd
static int client_command(struct mux_client *client, struct usbmuxd_header *hdr)
{
	int res;
	usbmuxd_log(LL_DEBUG, "Client command in fd %d len %d ver %d msg %d tag %d", client->fd, hdr->length, hdr->version, hdr->message, hdr->tag);

	if(client->state != CLIENT_COMMAND) {
		usbmuxd_log(LL_ERROR, "Client %d command received in the wrong state", client->fd);
		if(send_result(client, hdr->tag, RESULT_BADCOMMAND) < 0)
			return -1;
		client_close(client);
		return -1;
	}

	if((hdr->version != 0) && (hdr->version != 1)) {
		usbmuxd_log(LL_INFO, "Client %d version mismatch: expected 0 or 1, got %d", client->fd, hdr->version);
		send_result(client, hdr->tag, RESULT_BADVERSION);
		return 0;
	}

	struct usbmuxd_connect_request *ch;
	char *payload;
	uint32_t payload_size;

	switch(hdr->message) {
		case MESSAGE_PLIST:
			client->proto_version = 1;
			payload = (char*)(hdr) + sizeof(struct usbmuxd_header);
			payload_size = hdr->length - sizeof(struct usbmuxd_header);
			plist_t dict = NULL;
			plist_from_xml(payload, payload_size, &dict);
			if (!dict) {
				usbmuxd_log(LL_ERROR, "Could not parse plist from payload!");
				return -1;
			} else {
				char *message = NULL;
				plist_t node = plist_dict_get_item(dict, "MessageType");
				plist_get_string_val(node, &message);
				if (!message) {
					usbmuxd_log(LL_ERROR, "Could not extract MessageType from plist!");
					plist_free(dict);
					return -1;
				}
				if (!strcmp(message, "Listen")) {
					free(message);
					plist_free(dict);
					if (send_result(client, hdr->tag, 0) < 0)
						return -1;
					usbmuxd_log(LL_DEBUG, "Client %d now LISTENING", client->fd);
					return start_listen(client);
				} else if (!strcmp(message, "Connect")) {
					uint64_t val;
					uint16_t portnum = 0;
					uint32_t device_id = 0;
					free(message);
					// get device id
					node = plist_dict_get_item(dict, "DeviceID");
					if (!node) {
						usbmuxd_log(LL_ERROR, "Received connect request without device_id!");
						plist_free(dict);
						if (send_result(client, hdr->tag, RESULT_BADDEV) < 0)
							return -1;
						return 0;
					}
					val = 0;
					plist_get_uint_val(node, &val);
					device_id = (uint32_t)val;

					// get port number
					node = plist_dict_get_item(dict, "PortNumber");
					if (!node) {
						usbmuxd_log(LL_ERROR, "Received connect request without port number!");
						plist_free(dict);
						if (send_result(client, hdr->tag, RESULT_BADCOMMAND) < 0)
							return -1;
						return 0;
					}
					val = 0;
					plist_get_uint_val(node, &val);
					portnum = (uint16_t)val;
					plist_free(dict);

					usbmuxd_log(LL_DEBUG, "Client %d connection request to device %d port %d", client->fd, device_id, ntohs(portnum));
					res = device_start_connect(device_id, ntohs(portnum), client);
					if(res < 0) {
						if (send_result(client, hdr->tag, -res) < 0)
							return -1;
					} else {
						client->connect_tag = hdr->tag;
						client->connect_device = device_id;
						client->state = CLIENT_CONNECTING1;
					}
					return 0;
				} else if (!strcmp(message, "ListDevices")) {
					free(message);
					plist_free(dict);
					if (send_device_list(client, hdr->tag) < 0)
						return -1;
					return 0;
				} else if (!strcmp(message, "ReadBUID")) {
					free(message);
					plist_free(dict);
					if (send_system_buid(client, hdr->tag) < 0)
						return -1;
					return 0;
				} else if (!strcmp(message, "ReadPairRecord")) {
					free(message);
					char* record_id = plist_dict_get_string_val(dict, "PairRecordID");
					plist_free(dict);

					res = send_pair_record(client, hdr->tag, record_id);
					if (record_id)
						free(record_id);
					if (res < 0)
						return -1;
					return 0;
				} else if (!strcmp(message, "SavePairRecord")) {
					uint32_t rval = RESULT_OK;
					free(message);
					char* record_id = plist_dict_get_string_val(dict, "PairRecordID");
					char* record_data = NULL;
					uint64_t record_size = 0;
					plist_t rdata = plist_dict_get_item(dict, "PairRecordData");
					if (rdata && plist_get_node_type(rdata) == PLIST_DATA) {
						plist_get_data_val(rdata, &record_data, &record_size);
					}
					plist_free(dict);

					if (record_id && record_data) {
						res = config_set_device_record(record_id, record_data, record_size);
						if (res < 0) {
							rval = -res;
						}
						free(record_id);
					} else {
						rval = EINVAL;
					}
					if (send_result(client, hdr->tag, rval) < 0)
						return -1;
					return 0;
				} else if (!strcmp(message, "DeletePairRecord")) {
					uint32_t rval = RESULT_OK;
					free(message);
					char* record_id = plist_dict_get_string_val(dict, "PairRecordID");
					plist_free(dict);
					if (record_id) {
						res = config_remove_device_record(record_id);
						if (res < 0) {
							rval = -res;
						}
						free(record_id);
					} else {
						rval = EINVAL;
					}
					if (send_result(client, hdr->tag, rval) < 0)
						return -1;
					return 0;
				} else {
					usbmuxd_log(LL_ERROR, "Unexpected command '%s' received!", message);
					free(message);
					plist_free(dict);
					if (send_result(client, hdr->tag, RESULT_BADCOMMAND) < 0)
						return -1;
					return 0;
				}
			}
			// should not be reached?!
			return -1;
		case MESSAGE_LISTEN:
			if(send_result(client, hdr->tag, 0) < 0)
				return -1;
			usbmuxd_log(LL_DEBUG, "Client %d now LISTENING", client->fd);
			return start_listen(client);
		case MESSAGE_CONNECT:
			ch = (void*)hdr;
			usbmuxd_log(LL_DEBUG, "Client %d connection request to device %d port %d", client->fd, ch->device_id, ntohs(ch->port));
			res = device_start_connect(ch->device_id, ntohs(ch->port), client);
			if(res < 0) {
				if(send_result(client, hdr->tag, -res) < 0)
					return -1;
			} else {
				client->connect_tag = hdr->tag;
				client->connect_device = ch->device_id;
				client->state = CLIENT_CONNECTING1;
			}
			return 0;
		default:
			usbmuxd_log(LL_ERROR, "Client %d invalid command %d", client->fd, hdr->message);
			if(send_result(client, hdr->tag, RESULT_BADCOMMAND) < 0)
				return -1;
			return 0;
	}
	return -1;
}
コード例 #28
0
/**
 * Performs the DLMessageVersionExchange with the connected device.
 * This should be the first operation to be executed by an implemented
 * device link service client.
 *
 * @param client The device_link_service client to use.
 * @param version_major The major version number to check.
 * @param version_minor The minor version number to check.
 *
 * @return DEVICE_LINK_SERVICE_E_SUCCESS on success,
 *     DEVICE_LINK_SERVICE_E_INVALID_ARG when client is NULL,
 *     DEVICE_LINK_SERVICE_E_MUX_ERROR when a communication error occurs,
 *     DEVICE_LINK_SERVICE_E_PLIST_ERROR when the received plist has not the
 *     expected contents, DEVICE_LINK_SERVICE_E_BAD_VERSION when the version
 *     given by the device is larger than the given version,
 *     or DEVICE_LINK_SERVICE_E_UNKNOWN_ERROR otherwise.
 */
device_link_service_error_t device_link_service_version_exchange(device_link_service_client_t client, uint64_t version_major, uint64_t version_minor)
{
    if (!client)
        return DEVICE_LINK_SERVICE_E_INVALID_ARG;

    device_link_service_error_t err = DEVICE_LINK_SERVICE_E_UNKNOWN_ERROR;

    /* perform version exchange */
    plist_t array = NULL;
    char *msg = NULL;

    /* receive DLMessageVersionExchange from device */
    if (property_list_service_receive_plist(client->parent, &array) != PROPERTY_LIST_SERVICE_E_SUCCESS) {
        debug_info("Did not receive initial message from device!");
        err = DEVICE_LINK_SERVICE_E_MUX_ERROR;
        goto leave;
    }
    msg = device_link_service_get_message(array);
    if (!msg || strcmp(msg, "DLMessageVersionExchange")) {
        debug_info("Did not receive DLMessageVersionExchange from device!");
        err = DEVICE_LINK_SERVICE_E_PLIST_ERROR;
        goto leave;
    }
    free(msg);
    msg = NULL;

    /* get major and minor version number */
    if (plist_array_get_size(array) < 3) {
        debug_info("DLMessageVersionExchange has unexpected format!");
        err = DEVICE_LINK_SERVICE_E_PLIST_ERROR;
        goto leave;
    }
    plist_t maj = plist_array_get_item(array, 1);
    plist_t min = plist_array_get_item(array, 2);
    uint64_t vmajor = 0;
    uint64_t vminor = 0;
    if (maj) {
        plist_get_uint_val(maj, &vmajor);
    }
    if (min) {
        plist_get_uint_val(min, &vminor);
    }
    if (vmajor > version_major) {
        debug_info("Version mismatch: device=(%lld,%lld) > expected=(%lld,%lld)", vmajor, vminor, version_major, version_minor);
        err = DEVICE_LINK_SERVICE_E_BAD_VERSION;
        goto leave;
    } else if ((vmajor == version_major) && (vminor > version_minor)) {
        debug_info("WARNING: Version mismatch: device=(%lld,%lld) > expected=(%lld,%lld)", vmajor, vminor, version_major, version_minor);
        err = DEVICE_LINK_SERVICE_E_BAD_VERSION;
        goto leave;
    }
    plist_free(array);

    /* version is ok, send reply */
    array = plist_new_array();
    plist_array_append_item(array, plist_new_string("DLMessageVersionExchange"));
    plist_array_append_item(array, plist_new_string("DLVersionsOk"));
    plist_array_append_item(array, plist_new_uint(version_major));
    if (property_list_service_send_binary_plist(client->parent, array) != PROPERTY_LIST_SERVICE_E_SUCCESS) {
        debug_info("Error when sending DLVersionsOk");
        err = DEVICE_LINK_SERVICE_E_MUX_ERROR;
        goto leave;
    }
    plist_free(array);

    /* receive DeviceReady message */
    array = NULL;
    if (property_list_service_receive_plist(client->parent, &array) != PROPERTY_LIST_SERVICE_E_SUCCESS) {
        debug_info("Error when receiving DLMessageDeviceReady!");
        err = DEVICE_LINK_SERVICE_E_MUX_ERROR;
        goto leave;
    }
    msg = device_link_service_get_message(array);
    if (!msg || strcmp(msg, "DLMessageDeviceReady")) {
        debug_info("Did not get DLMessageDeviceReady!");
        err = DEVICE_LINK_SERVICE_E_PLIST_ERROR;
        goto leave;
    }
    err = DEVICE_LINK_SERVICE_E_SUCCESS;

leave:
    if (msg) {
        free(msg);
    }
    if (array) {
        plist_free(array);
    }
    return err;
}
コード例 #29
0
/**
 * Function used internally by lockdownd_start_service and lockdownd_start_service_with_escrow_bag.
 *
 * @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 descriptor The service descriptor on success or NULL on failure
 *
 * @return LOCKDOWN_E_SUCCESS on success, LOCKDOWN_E_INVALID_ARG if a parameter
 *  is NULL, LOCKDOWN_E_INVALID_SERVICE if the requested service is not known
 *  by the device, LOCKDOWN_E_START_SERVICE_FAILED if the service could not because
 *  started by the device, LOCKDOWN_E_INVALID_CONF if the host id or escrow bag (when
 *  used) are missing from the device record.
 */
static lockdownd_error_t lockdownd_do_start_service(lockdownd_client_t client, const char *identifier, int send_escrow_bag, lockdownd_service_descriptor_t *service)
{
	if (!client || !identifier || !service)
		return LOCKDOWN_E_INVALID_ARG;

	if (*service) {
		// reset fields if service descriptor is reused
		(*service)->port = 0;
		(*service)->ssl_enabled = 0;
	}

	plist_t dict = NULL;
	uint16_t port_loc = 0;
	lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR;

	/* create StartService request */
	ret = lockdownd_build_start_service_request(client, identifier, send_escrow_bag, &dict);
	if (LOCKDOWN_E_SUCCESS != ret)
		return ret;

	/* send to device */
	ret = lockdownd_send(client, dict);
	plist_free(dict);
	dict = NULL;

	if (LOCKDOWN_E_SUCCESS != ret)
		return ret;

	ret = lockdownd_receive(client, &dict);

	if (LOCKDOWN_E_SUCCESS != ret)
		return ret;

	if (!dict)
		return LOCKDOWN_E_PLIST_ERROR;

	ret = LOCKDOWN_E_UNKNOWN_ERROR;
	if (lockdown_check_result(dict, "StartService") == RESULT_SUCCESS) {
		if (*service == NULL)
			*service = (lockdownd_service_descriptor_t)malloc(sizeof(struct lockdownd_service_descriptor));
		(*service)->port = 0;
		(*service)->ssl_enabled = 0;

		/* read service port number */
		plist_t node = plist_dict_get_item(dict, "Port");
		if (node && (plist_get_node_type(node) == PLIST_UINT)) {
			uint64_t port_value = 0;
			plist_get_uint_val(node, &port_value);

			if (port_value) {
				port_loc = port_value;
				ret = LOCKDOWN_E_SUCCESS;
			}
			if (port_loc && ret == LOCKDOWN_E_SUCCESS) {
				(*service)->port = port_loc;
			}
		}

		/* check if the service requires SSL */
		node = plist_dict_get_item(dict, "EnableServiceSSL");
		if (node && (plist_get_node_type(node) == PLIST_BOOLEAN)) {
			uint8_t b = 0;
			plist_get_bool_val(node, &b);
			(*service)->ssl_enabled = b;
		}
	} else {
		ret = LOCKDOWN_E_START_SERVICE_FAILED;
		plist_t error_node = plist_dict_get_item(dict, "Error");
		if (error_node && PLIST_STRING == plist_get_node_type(error_node)) {
			char *error = NULL;
			plist_get_string_val(error_node, &error);
			if (!strcmp(error, "InvalidService")) {
				ret = LOCKDOWN_E_INVALID_SERVICE;
			} else if (!strcmp(error, "NoRunningSession")) {
				ret = LOCKDOWN_E_NO_RUNNING_SESSION;
			}
			free(error);
		}
	}

	plist_free(dict);
	dict = NULL;
	return ret;
}
コード例 #30
0
ファイル: bplist.c プロジェクト: JonathanBeck/libplist
static plist_t parse_bin_node(char *object, uint8_t dict_size, char **next_object)
{
    uint16_t type = 0;
    uint64_t size = 0;

    if (!object)
        return NULL;

    type = (*object) & 0xF0;
    size = (*object) & 0x0F;
    object++;

    switch (type)
    {

    case BPLIST_NULL:
        switch (size)
        {

        case BPLIST_TRUE:
        {
            plist_data_t data = plist_new_plist_data();
            data->type = PLIST_BOOLEAN;
            data->boolval = TRUE;
            data->length = 1;
            return g_node_new(data);
        }

        case BPLIST_FALSE:
        {
            plist_data_t data = plist_new_plist_data();
            data->type = PLIST_BOOLEAN;
            data->boolval = FALSE;
            data->length = 1;
            return g_node_new(data);
        }

        case BPLIST_NULL:
        default:
            return NULL;
        }

    case BPLIST_UINT:
        return parse_uint_node(object, size, next_object);

    case BPLIST_REAL:
        return parse_real_node(object, size);

    case BPLIST_DATE:
        if (3 != size)
            return NULL;
        else
            return parse_date_node(object, size);

    case BPLIST_DATA:
        if (0x0F == size)
        {
            plist_t size_node = parse_bin_node(object, dict_size, &object);
            if (plist_get_node_type(size_node) != PLIST_UINT)
                return NULL;
            plist_get_uint_val(size_node, &size);
            plist_free(size_node);
        }
        return parse_data_node(object, size);

    case BPLIST_STRING:
        if (0x0F == size)
        {
            plist_t size_node = parse_bin_node(object, dict_size, &object);
            if (plist_get_node_type(size_node) != PLIST_UINT)
                return NULL;
            plist_get_uint_val(size_node, &size);
            plist_free(size_node);
        }
        return parse_string_node(object, size);

    case BPLIST_UNICODE:
        if (0x0F == size)
        {
            plist_t size_node = parse_bin_node(object, dict_size, &object);
            if (plist_get_node_type(size_node) != PLIST_UINT)
                return NULL;
            plist_get_uint_val(size_node, &size);
            plist_free(size_node);
        }
        return parse_unicode_node(object, size);

    case BPLIST_UID:
    case BPLIST_ARRAY:
        if (0x0F == size)
        {
            plist_t size_node = parse_bin_node(object, dict_size, &object);
            if (plist_get_node_type(size_node) != PLIST_UINT)
                return NULL;
            plist_get_uint_val(size_node, &size);
            plist_free(size_node);
        }
        return parse_array_node(object, size, dict_size);

    case BPLIST_SET:
    case BPLIST_DICT:
        if (0x0F == size)
        {
            plist_t size_node = parse_bin_node(object, dict_size, &object);
            if (plist_get_node_type(size_node) != PLIST_UINT)
                return NULL;
            plist_get_uint_val(size_node, &size);
            plist_free(size_node);
        }
        return parse_dict_node(object, size, dict_size);
    default:
        return NULL;
    }
    return NULL;
}