Example #1
0
DeviceStatus Device::readFile(string appId, string path, char *&buffer, int &bytesRead) {
    afc_client_t afc = this->getAfcFromApp(appId);
    if (afc == NULL) {
        house_arrest_client_free(this->mHouseArrestClient);
        this->mHouseArrestClient = NULL;
        return StatusError;
    }
    DeviceStatus status = this->readFileWithAfc(path, afc, buffer, bytesRead);
    afc_client_free(afc);
    house_arrest_client_free(this->mHouseArrestClient);
    this->mHouseArrestClient = NULL;
    return status;
}
Example #2
0
DeviceStatus Device::pullDirectory(string appId, string srcPath, string DstPath) {
    afc_client_t afc = this->getAfcFromApp(appId);
    if (afc == NULL) {
        house_arrest_client_free(this->mHouseArrestClient);
        this->mHouseArrestClient = NULL;
        return StatusError;
    }
    DeviceStatus status = this->pullDirectoryWithAfc(afc, srcPath, DstPath);
    afc_client_free(afc);
    house_arrest_client_free(this->mHouseArrestClient);
    this->mHouseArrestClient = NULL;
    return status;
}
Example #3
0
uint64_t Device::getFileLength(string appId, string path) {
    afc_client_t afc = this->getAfcFromApp(appId);
    if (afc == NULL) {
        house_arrest_client_free(this->mHouseArrestClient);
        this->mHouseArrestClient = NULL;
        return 0;
    }
    uint64_t length = this->getFileLengthWithAfc(path, afc);
    afc_client_free(afc);
    house_arrest_client_free(this->mHouseArrestClient);
    this->mHouseArrestClient = NULL;
    return length ;
}
Example #4
0
FileType Device::getFileType(string appId, string path) {
    afc_client_t afc = this->getAfcFromApp(appId);
    if (afc == NULL) {
        house_arrest_client_free(this->mHouseArrestClient);
        this->mHouseArrestClient = NULL;
        return TypeInvalid;
    }
    FileType type = this->getFileTypeWithAfc(afc, path);
    afc_client_free(afc);
    house_arrest_client_free(this->mHouseArrestClient);
    this->mHouseArrestClient = NULL;
    return type;
}
Example #5
0
DeviceStatus Device::getDirectory(string appId, string path, list<string> &fileList) {
    afc_client_t afc = this->getAfcFromApp(appId);
    if (afc == NULL) {
        house_arrest_client_free(this->mHouseArrestClient);
        this->mHouseArrestClient = NULL;
        return StatusError;
    }
    DeviceStatus status = this->getDirectoryWithAfc(afc, path, fileList);
    afc_client_free(afc);
    house_arrest_client_free(this->mHouseArrestClient);
    this->mHouseArrestClient = NULL;
    return status;
}
Example #6
0
afc_client_t Device::getAfcFromApp(string appId) {
    afc_client_t afc = NULL;
    if (appId.empty()) {
        if (afc_client_start_service(this->mDevice, &afc, NULL)  != AFC_E_SUCCESS) {
            return NULL;
        }
        return afc;
    }
    this->mHouseArrestClient = this->getHouseArrestClient();
    if (this->mHouseArrestClient == NULL) {
        return NULL;
    }
    if (house_arrest_send_command(this->mHouseArrestClient, "VendContainer", appId.c_str()) != HOUSE_ARREST_E_SUCCESS) {
        house_arrest_client_free(this->mHouseArrestClient);
        this->mHouseArrestClient = NULL;
        return NULL;
    }
    plist_t result = NULL;
    if (house_arrest_get_result(this->mHouseArrestClient, &result) != HOUSE_ARREST_E_SUCCESS) {
        house_arrest_client_free(this->mHouseArrestClient);
        this->mHouseArrestClient = NULL;
        return NULL;
    }
    plist_t status = NULL;
    status = plist_dict_get_item(result, "Status");
    if (status == NULL) {
        plist_free(result);
        house_arrest_client_free(this->mHouseArrestClient);
        this->mHouseArrestClient = NULL;
        return NULL;
    }
    char *sStatus = NULL;
    plist_get_string_val(status, &sStatus);
    plist_free(status);
    plist_free(result);
    if (strcmp(sStatus, "Complete")) {
        free(sStatus);
        house_arrest_client_free(this->mHouseArrestClient);
        this->mHouseArrestClient = NULL;
        return NULL;
    }
    free(sStatus);
    if (afc_client_new_from_house_arrest_client(this->mHouseArrestClient, &afc) != AFC_E_SUCCESS) {
        house_arrest_client_free(this->mHouseArrestClient);
        this->mHouseArrestClient = NULL;
        return NULL;
    }
    return afc;
}
Example #7
0
DeviceStatus Device::getDirectoryWithAfc(afc_client_t afc, string path, list<string> &fileList) {
    char **dir = NULL;
    if (afc_read_directory(afc, path.c_str(), &dir) != AFC_E_SUCCESS) {
        afc_client_free(afc);
        house_arrest_client_free(this->mHouseArrestClient);
        this->mHouseArrestClient = NULL;
        return StatusError;
    }
    for (int i = 0; dir[i]; i++) {
        if (strcmp(dir[i], ".") == 0 || strcmp(dir[i], "..") == 0) {
            continue;
        }
        //cout << dir[i] << endl;
        fileList.push_back(dir[i]);
    }
    afc_dictionary_free(dir);
    return StatusOK;
}
Example #8
0
int main(int argc, const char **argv)
{
	char *errmsg = "";
	idevice_t device = NULL;
	lockdownd_client_t client = NULL;
	lockdownd_service_descriptor_t service = NULL;
	house_arrest_client_t hac = NULL;
	const char *service_name = "com.apple.afc";
    const char *appid = NULL;
	char *device_name = NULL;
	int result = 0;
	char* udid = NULL;
	int cmd = CMD_INTERACTIVE;
	const char *cmdstr = NULL;
	int i;

	cwd = strdup("/");

	/* parse cmdline args */
	for (i = 1; i < argc; i++) {
		if (str_is_equal(argv[i], "-d") || str_is_equal(argv[i], "--debug")) {
			idevice_set_debug_level(1);
			continue;
		}
		else if (str_is_equal(argv[i], "-u") || str_is_equal(argv[i], "--udid")) {
			i++;
			if (!argv[i] || (strlen(argv[i]) != 40)) {
				print_usage(argc, argv);
				exit(EXIT_FAILURE);
			}
			udid = strdup(argv[i]);
			continue;
		}
		else if (str_is_equal(argv[i], "-2") || str_is_equal(argv[i], "--afc2")) {
			service_name = "com.apple.afc2";
			continue;
		}
        else if (str_is_equal(argv[i], "-a") || str_is_equal(argv[i], "--appid")) {
            if (++i >=  argc) {
                print_usage(argc, argv);
                exit(EXIT_FAILURE);
            }
            appid = argv[i];
        }
		else if (str_is_equal(argv[i], "-h") || str_is_equal(argv[i], "--help")) {
			print_usage(argc, argv);
			exit(EXIT_SUCCESS);
		}
		else if ((cmd = str_to_cmd(argv[i])) != CMD_UNKNOWN) {
			cmdstr = argv[i];
			i++;
			break;
		}
	}
	argc -= i;
	argv += i;

	/* Connect to device */
	if (udid) {
		result = idevice_new(&device, udid);
		if (result != IDEVICE_E_SUCCESS)
			errx(EXIT_FAILURE, "No device found with udid %s, is it plugged in?", udid);
	}
	else {
		result = idevice_new(&device, NULL);
		if (result != IDEVICE_E_SUCCESS)
			errx(EXIT_FAILURE, "No device found, is it plugged in?");
		idevice_get_udid(device, &udid);
	}

	/* Connect to lockdownd */
	result = lockdownd_client_new_with_handshake(device, &client, "afccl");
	if (result != LOCKDOWN_E_SUCCESS) {
		asprintf(&errmsg, "ERROR: Connecting to lockdownd service failed!");
		goto bail;
	}

	result = lockdownd_get_device_name(client, &device_name);
	if ((result != LOCKDOWN_E_SUCCESS) || !device_name) {
		asprintf(&errmsg, "ERROR: Could not get device name!");
		goto bail;
	}

    if (appid) {
        result = lockdownd_start_service(client, "com.apple.mobile.house_arrest", &service);
        if (result != LOCKDOWN_E_SUCCESS || !service || !service->port) {
			asprintf(&errmsg, "error starting house arrest service: (%d) %s", result, afc_strerror(result));
			goto bail;
        }
        if (client) {
            lockdownd_client_free(client);
            client = NULL;
        }
        
        if (house_arrest_client_new(device, service, &hac) != HOUSE_ARREST_E_SUCCESS) {
            asprintf(&errmsg, "could not connect to house_arrest service!\n");
			goto bail;
        }
        
        if (service) {
            lockdownd_service_descriptor_free(service);
            service = NULL;
        }
        
        result = house_arrest_send_command(hac, "VendDocuments", appid);
        if (result != HOUSE_ARREST_E_SUCCESS) {
            asprintf(&errmsg, "error %d when trying to get VendDocuments\n", result);
			goto bail;
        }
        
        plist_t dict = NULL;
        if (house_arrest_get_result(hac, &dict) != HOUSE_ARREST_E_SUCCESS) {
            if (house_arrest_get_result(hac, &dict) != HOUSE_ARREST_E_SUCCESS) {
                asprintf(&errmsg, "hmmm....\n");
				goto bail;
            }
        }
        
        plist_t node = plist_dict_get_item(dict, "Error");
        if (node) {
            char *str = NULL;
            plist_get_string_val(node, &str);
            asprintf(&errmsg, "Error: %s\n", str);
            if (str) free(str);
            plist_free(dict);
            dict = NULL;
			goto bail;
		}
        node = plist_dict_get_item(dict, "Status");
        if (node) {
            char *str = NULL;
            plist_get_string_val(node, &str);
            if (str && (strcmp(str, "Complete") != 0)) {
                printf("Warning: Status is not 'Complete' but '%s'\n", str);
            }
            if (str) free(str);
        }
        if (dict) {
            plist_free(dict);
        }
        
        afc_error_t ae = afc_client_new_from_house_arrest_client(hac, &afc);
        if (ae != AFC_E_SUCCESS) {
            printf("afc error %d\n", ae);
        }

    }
    else {
        result = lockdownd_start_service(client, service_name, &service);
        if (result != LOCKDOWN_E_SUCCESS || !service || !service->port) {
            asprintf(&errmsg, "error starting AFC service: (%d) %s", result, afc_strerror(result));
			goto bail;
        }

        /* Connect to AFC */
        result = afc_client_new(device, service, &afc);
        lockdownd_client_free(client);
        idevice_free(device);
        if (result != AFC_E_SUCCESS) {
            errx(EXIT_FAILURE, "AFC connection failed (%d) %s", result, afc_strerror(result));
        }
	}
	result = do_cmd(cmd, argc, argv);

	if (hac)
		house_arrest_client_free(hac);

	afc_client_free(afc);

	exit(result == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
    
bail:
    if (hac)
		house_arrest_client_free(hac);

	if (service)
		lockdownd_service_descriptor_free(service);

    if (client)
		lockdownd_client_free(client);

    if (device)
		idevice_free(device);

	errx(EXIT_FAILURE, "%s", errmsg);
}
int main(int argc, char **argv)
{
	idevice_t dev = NULL;
	lockdownd_client_t client = NULL;
	house_arrest_client_t hac = NULL;
	house_arrest_error_t res;
	int i;
	char *udid = NULL;
	const char *appid = NULL;
	int test_file_io = 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 = strdup(argv[i]);
			continue;
		}
		else if (!strcmp(argv[i], "-t") || !strcmp(argv[i], "--test")) {
			test_file_io = 1;
			continue;
		}
		else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
			print_usage(argc, argv);
			return 0;
		}
		else {
			appid = argv[i];
			break;
		}
	}

	if (!appid) {
		print_usage(argc, argv);
		return 0;
	}

	if (idevice_new(&dev, udid) != IDEVICE_E_SUCCESS) {
		printf("no device connected?!\n");
		goto leave_cleanup;
	}

	if (lockdownd_client_new_with_handshake(dev, &client, NULL) != LOCKDOWN_E_SUCCESS) {
		printf("could not connect to lockdownd!\n");
		goto leave_cleanup;
	}

	uint16_t port = 0;
	if (lockdownd_start_service(client, "com.apple.mobile.house_arrest", &port) != LOCKDOWN_E_SUCCESS) {
		printf("could not start house_arrest service!\n");
		goto leave_cleanup;
	}

	if (client) {
		lockdownd_client_free(client);
		client = NULL;
	}

	if (house_arrest_client_new(dev, port, &hac) != HOUSE_ARREST_E_SUCCESS) {
		printf("could not connect to house_arrest service!\n");
		goto leave_cleanup;
	}

	res = house_arrest_send_command(hac, "VendDocuments", appid);
	if (res != HOUSE_ARREST_E_SUCCESS) {
		printf("error %d when trying to get VendDocuments\n", res);
		goto leave_cleanup;
	}

	plist_t dict = NULL;
	if (house_arrest_get_result(hac, &dict) != HOUSE_ARREST_E_SUCCESS) {
		if (house_arrest_get_result(hac, &dict) != HOUSE_ARREST_E_SUCCESS) {
			printf("hmmm....\n");
			goto leave_cleanup;
		}
	}

	plist_t node = plist_dict_get_item(dict, "Error");
	if (node) {
		char *str = NULL;
		plist_get_string_val(node, &str);
		printf("Error: %s\n", str);
		if (str) free(str);
		plist_free(dict);
		dict = NULL;
		goto leave_cleanup;
	}
	node = plist_dict_get_item(dict, "Status");
	if (node) {
		char *str = NULL;
		plist_get_string_val(node, &str);
		if (str && (strcmp(str, "Complete") != 0)) {
			printf("Warning: Status is not 'Complete' but '%s'\n", str);
		}
		if (str) free(str);
		plist_free(dict);
		dict = NULL;
	}
	if (dict) {
		plist_free(dict);
	}

	afc_client_t afc = NULL;
	afc_error_t ae = afc_client_new_from_house_arrest_client(hac, &afc);
	if (ae != AFC_E_SUCCESS) {
		printf("afc error %d\n", ae);
	}
	if (ae == AFC_E_SUCCESS) {
		char **list = NULL;
		afc_read_directory(afc, "/", &list);
		printf("Directory contents:\n");
		if (list) {
			while (list[0]) {
				if (strcmp(list[0], ".") && strcmp(list[0], "..")) {
					puts(list[0]);
				}
				list++;
			}
		}

		if (test_file_io) {
			uint64_t tf = 0;
			printf("\n==== Performing file tests ====\n");
			printf("Opening file 'foobar' for writing: ");
			if (afc_file_open(afc, "/foobar", AFC_FOPEN_RW, &tf) == AFC_E_SUCCESS) {
				uint32_t wb = 0;
				printf("OK\n");

				printf("Writing to file: ");
				if (afc_file_write(afc, tf, "test\r\n", 6, &wb) != AFC_E_SUCCESS) {
					printf("ERROR\n");
				} else {
					printf("OK\n");
				}
				afc_file_close(afc, tf);
				printf("Deleting file 'foobar': ");
				if (afc_remove_path(afc, "/foobar") == AFC_E_SUCCESS) {
					printf("OK\n");
				} else {
					printf("ERROR\n");
				}
			} else {
				printf("ERROR\n");
			}
		}
		afc_client_free(afc);
	} else {
		printf("failed to connect to afc service, error %d\n", ae);
	}

leave_cleanup:
	if (hac) {
		house_arrest_client_free(hac);
	}
	if (client) {
		lockdownd_client_free(client);
	}
	if (dev) {
		idevice_free(dev);
	}

	return 0;
}
Example #10
0
int main(int argc, char *argv[])
{
	int res = EXIT_FAILURE;
	struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
	struct stat mst;
	lockdownd_error_t ret = LOCKDOWN_E_SUCCESS;

	memset(&opts, 0, sizeof(opts));
	opts.service_name = AFC_SERVICE_NAME;

	if (fuse_opt_parse(&args, NULL, ifuse_opts, ifuse_opt_proc) == -1) {
		return EXIT_FAILURE;
	}

	if (!opts.mount_point) {
		fprintf(stderr, "ERROR: No mount point specified\n");
		return EXIT_FAILURE;
	}

	if (opts.device_udid && strlen(opts.device_udid) != 40) {
		fprintf(stderr, "Invalid device UDID specified, length needs to be 40 characters\n");
		return EXIT_FAILURE;
	}

	if (stat(opts.mount_point, &mst) < 0) {
		if (errno == ENOENT) {
			fprintf(stderr, "ERROR: the mount point specified does not exist\n");
			return EXIT_FAILURE;
		}
		
		fprintf(stderr, "There was an error accessing the mount point: %s\n", strerror(errno));
		return EXIT_FAILURE;
	}

	idevice_new(&phone, opts.device_udid ? opts.device_udid : NULL);
	if (!phone) {
		fprintf(stderr, "No device found, is it connected?\n");
		fprintf(stderr, "If it is make sure that your user has permissions to access the raw usb device.\n");
		fprintf(stderr, "If you're still having issues try unplugging the device and reconnecting it.\n");
		return EXIT_FAILURE;
	}
	
	ret = lockdownd_client_new_with_handshake(phone, &control, "ifuse");
	if (ret != LOCKDOWN_E_SUCCESS) {
		idevice_free(phone);
		if (ret == LOCKDOWN_E_PASSWORD_PROTECTED) {
			fprintf(stderr, "Please disable the password protection on your device and try again.\n");
			fprintf(stderr, "The device does not allow pairing as long as a password has been set.\n");
			fprintf(stderr, "You can enable it again after the connection succeeded.\n");
		} else {
			fprintf(stderr, "Failed to connect to lockdownd service on the device.\n");
			fprintf(stderr, "Try again. If it still fails try rebooting your device.\n");
		}
		return EXIT_FAILURE;
	}

	if (
#ifdef HAVE_LIBIMOBILEDEVICE_1_1_5
	(lockdownd_start_service(control, opts.service_name, &opts.service) != LOCKDOWN_E_SUCCESS) || !opts.service
#else
	(lockdownd_start_service(control, opts.service_name, &opts.port) != LOCKDOWN_E_SUCCESS) || !opts.port
#endif
 	) {
		lockdownd_client_free(control);
		idevice_free(phone);
		fprintf(stderr, "Failed to start AFC service '%s' on the device.\n", opts.service_name);
		if (!strcmp(opts.service_name, AFC2_SERVICE_NAME)) {
			fprintf(stderr, "This service enables access to the root filesystem of your device.\n");
			fprintf(stderr, "Your device needs to be jailbroken and have the AFC2 service installed.\n");
		}
		return EXIT_FAILURE;
	}

#ifdef HAVE_LIBIMOBILEDEVICE_1_1
	if (!strcmp(opts.service_name, HOUSE_ARREST_SERVICE_NAME)) {
#ifdef HAVE_LIBIMOBILEDEVICE_1_1_5
		house_arrest_client_new(phone, opts.service, &house_arrest);
#else
		house_arrest_client_new(phone, opts.port, &house_arrest);
#endif
		if (!house_arrest) {
			fprintf(stderr, "Could not start document sharing service!\n");
			return EXIT_FAILURE;
		}
		if (house_arrest_send_command(house_arrest, "VendContainer", opts.appid) != HOUSE_ARREST_E_SUCCESS) {
			fprintf(stderr, "Could not send VendContainer command!\n");
			goto leave_err;
		}

		plist_t dict = NULL;
		if (house_arrest_get_result(house_arrest, &dict) != HOUSE_ARREST_E_SUCCESS) {
			fprintf(stderr, "Could not get result from document sharing service!\n");
			goto leave_err;
		}
		plist_t node = plist_dict_get_item(dict, "Error");
		if (node) {
			char *str = NULL;
			plist_get_string_val(node, &str);
			fprintf(stderr, "ERROR: %s\n", str);
			if (str) free(str);
			goto leave_err;
		}
		plist_free(dict);

		fuse_opt_add_arg(&args, "-omodules=subdir");
		fuse_opt_add_arg(&args, "-osubdir=Documents");
	}
#endif
	res = fuse_main(args.argc, args.argv, &ifuse_oper, NULL);

#ifdef HAVE_LIBIMOBILEDEVICE_1_1
leave_err:
	if (house_arrest) {
		house_arrest_client_free(house_arrest);
	}
#endif
	return res;
}