/*
 * idevicepair.c
 * Manage pairings with devices and this host
 *
 * Copyright (c) 2010-2021 Nikias Bassen, All Rights Reserved.
 * Copyright (c) 2014 Martin Szulecki, All Rights Reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#define TOOL_NAME "idevicepair"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>
#include <ctype.h>
#include <unistd.h>
#ifdef WIN32
#include <windows.h>
#include <conio.h>
#else
#include <termios.h>
#include <signal.h>
#endif

#include "common/userpref.h"
#include <libimobiledevice-glue/utils.h>

#include <libimobiledevice/libimobiledevice.h>
#include <libimobiledevice/lockdown.h>
#include <plist/plist.h>

static char *udid = NULL;

#ifdef HAVE_WIRELESS_PAIRING

#ifdef WIN32
#define BS_CC '\b'
#define my_getch getch
#else
#define BS_CC 0x7f
static int my_getch(void)
{
	struct termios oldt, newt;
	int ch;
	tcgetattr(STDIN_FILENO, &oldt);
	newt = oldt;
	newt.c_lflag &= ~(ICANON | ECHO);
	tcsetattr(STDIN_FILENO, TCSANOW, &newt);
	ch = getchar();
	tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
	return ch;
}
#endif

static int get_hidden_input(char *buf, int maxlen)
{
	int pwlen = 0;
	int c;

	while ((c = my_getch())) {
		if ((c == '\r') || (c == '\n')) {
			break;
		} else if (isprint(c)) {
			if (pwlen < maxlen-1)
				buf[pwlen++] = c;
			fputc('*', stderr);
		} else if (c == BS_CC) {
			if (pwlen > 0) {
				fputs("\b \b", stderr);
				pwlen--;
			}
		}
	}
	buf[pwlen] = 0;
	return pwlen;
}

static void pairing_cb(lockdownd_cu_pairing_cb_type_t cb_type, void *user_data, void* data_ptr, unsigned int* data_size)
{
	if (cb_type == LOCKDOWN_CU_PAIRING_PIN_REQUESTED) {
		printf("Enter PIN: ");
		fflush(stdout);

		*data_size = get_hidden_input((char*)data_ptr, *data_size);

		printf("\n");
	} else if (cb_type == LOCKDOWN_CU_PAIRING_DEVICE_INFO) {
		printf("Device info:\n");
		plist_print_to_stream_with_indentation((plist_t)data_ptr, stdout, 2);
	} else if (cb_type == LOCKDOWN_CU_PAIRING_ERROR) {
		printf("ERROR: %s\n", (data_ptr) ? (char*)data_ptr : "(unknown)");
	}
}

#endif /* HAVE_WIRELESS_PAIRING */

static void print_error_message(lockdownd_error_t err)
{
	switch (err) {
		case LOCKDOWN_E_PASSWORD_PROTECTED:
			printf("ERROR: Could not validate with device %s because a passcode is set. Please enter the passcode on the device and retry.\n", udid);
			break;
		case LOCKDOWN_E_INVALID_CONF:
		case LOCKDOWN_E_INVALID_HOST_ID:
			printf("ERROR: Device %s is not paired with this host\n", udid);
			break;
		case LOCKDOWN_E_PAIRING_DIALOG_RESPONSE_PENDING:
			printf("ERROR: Please accept the trust dialog on the screen of device %s, then attempt to pair again.\n", udid);
			break;
		case LOCKDOWN_E_USER_DENIED_PAIRING:
			printf("ERROR: Device %s said that the user denied the trust dialog.\n", udid);
			break;
		case LOCKDOWN_E_PAIRING_FAILED:
			printf("ERROR: Pairing with device %s failed.\n", udid);
			break;
		case LOCKDOWN_E_GET_PROHIBITED:
		case LOCKDOWN_E_PAIRING_PROHIBITED_OVER_THIS_CONNECTION:
			printf("ERROR: Pairing is not possible over this connection.\n");
#ifdef HAVE_WIRELESS_PAIRING
			printf("To perform a wireless pairing use the -w command line switch. See usage or man page for details.\n");
#endif
			break;
		default:
			printf("ERROR: Device %s returned unhandled error code %d\n", udid, err);
			break;
	}
}

static void print_usage(int argc, char **argv, int is_error)
{
	char *name = strrchr(argv[0], '/');
	fprintf(is_error ? stderr : stdout, "Usage: %s [OPTIONS] COMMAND\n", (name ? name + 1: argv[0]));
	fprintf(is_error ? stderr : stdout,
		"\n"
		"Manage host pairings with devices and usbmuxd.\n"
		"\n"
		"Where COMMAND is one of:\n"
		"  systembuid   print the system buid of the usbmuxd host\n"
		"  hostid       print the host id for target device\n"
		"  pair         pair device with this host\n"
		"  validate     validate if device is paired with this host\n"
		"  unpair       unpair device with this host\n"
		"  list         list devices paired with this host\n"
		"\n"
		"The following OPTIONS are accepted:\n"
		"  -u, --udid UDID  target specific device by UDID\n"
	);
#ifdef HAVE_WIRELESS_PAIRING
	fprintf(is_error ? stderr : stdout,
		"  -w, --wireless   perform wireless pairing (see NOTE)\n"
		"  -n, --network    connect to network device (see NOTE)\n"
	);
#endif
	fprintf(is_error ? stderr : stdout,
		"  -d, --debug      enable communication debugging\n"
		"  -h, --help       prints usage information\n"
		"  -v, --version    prints version information\n"
	);
#ifdef HAVE_WIRELESS_PAIRING
	fprintf(is_error ? stderr : stdout,
		"\n"
		"NOTE: Pairing over network (wireless pairing) is only supported by Apple TV\n"
		"devices. To perform a wireless pairing, you need to use the -w command line\n"
		"switch. Make sure to put the device into pairing mode first by opening\n"
		"Settings > Remotes and Devices > Remote App and Devices.\n"
	);
#endif
	fprintf(is_error ? stderr : stdout,
		"\n"
		"Homepage:    <" PACKAGE_URL ">\n"
		"Bug Reports: <" PACKAGE_BUGREPORT ">\n"
	);
}

int main(int argc, char **argv)
{
	int c = 0;
	static struct option longopts[] = {
		{ "help",    no_argument,       NULL, 'h' },
		{ "udid",    required_argument, NULL, 'u' },
#ifdef HAVE_WIRELESS_PAIRING
		{ "wireless", no_argument,      NULL, 'w' },
		{ "network", no_argument,       NULL, 'n' },
		{ "hostinfo", required_argument, NULL,  1 },
#endif
		{ "debug",   no_argument,       NULL, 'd' },
		{ "version", no_argument,       NULL, 'v' },
		{ NULL, 0, NULL, 0}
	};
#ifdef HAVE_WIRELESS_PAIRING
#define SHORT_OPTIONS "hu:wndv"
#else
#define SHORT_OPTIONS "hu:dv"
#endif
	lockdownd_client_t client = NULL;
	idevice_t device = NULL;
	idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR;
	lockdownd_error_t lerr;
	int result;

	char *type = NULL;
	int use_network = 0;
	int wireless_pairing = 0;
#ifdef HAVE_WIRELESS_PAIRING
	plist_t host_info_plist = NULL;
#endif
	char *cmd;
	typedef enum {
		OP_NONE = 0, OP_PAIR, OP_VALIDATE, OP_UNPAIR, OP_LIST, OP_HOSTID, OP_SYSTEMBUID
	} op_t;
	op_t op = OP_NONE;

	while ((c = getopt_long(argc, argv, SHORT_OPTIONS, longopts, NULL)) != -1) {
		switch (c) {
		case 'h':
			print_usage(argc, argv, 0);
			exit(EXIT_SUCCESS);
		case 'u':
			if (!*optarg) {
				fprintf(stderr, "ERROR: UDID must not be empty!\n");
				print_usage(argc, argv, 1);
				result = EXIT_FAILURE;
				goto leave;
			}
			free(udid);
			udid = strdup(optarg);
			break;
#ifdef HAVE_WIRELESS_PAIRING
		case 'w':
			wireless_pairing = 1;
			break;
		case 'n':
			use_network = 1;
			break;
		case 1:
			if (!*optarg) {
				fprintf(stderr, "ERROR: --hostinfo argument must not be empty!\n");
				result = EXIT_FAILURE;
				goto leave;
			}
			if (*optarg == '@') {
				plist_read_from_filename(&host_info_plist, optarg+1);
				if (!host_info_plist) {
					fprintf(stderr, "ERROR: Could not read from file '%s'\n", optarg+1);
					result = EXIT_FAILURE;
					goto leave;
				}
			}
#ifdef HAVE_PLIST_JSON
			else if (*optarg == '{') {
				if (plist_from_json(optarg, strlen(optarg), &host_info_plist) != PLIST_ERR_SUCCESS) {
					fprintf(stderr, "ERROR: --hostinfo argument not valid. Make sure it is a JSON dictionary.\n");
					result = EXIT_FAILURE;
					goto leave;
				}
			}
#endif
			else {
				fprintf(stderr, "ERROR: --hostinfo argument not valid. To specify a path prefix with '@'\n");
				result = EXIT_FAILURE;
				goto leave;
			}
			break;
#endif
		case 'd':
			idevice_set_debug_level(1);
			break;
		case 'v':
			printf("%s %s\n", TOOL_NAME, PACKAGE_VERSION);
			result = EXIT_SUCCESS;
			goto leave;
		default:
			print_usage(argc, argv, 1);
			result = EXIT_FAILURE;
			goto leave;
		}
	}

#ifndef WIN32
	signal(SIGPIPE, SIG_IGN);
#endif

	if ((argc - optind) < 1) {
		fprintf(stderr, "ERROR: You need to specify a COMMAND!\n");
		print_usage(argc, argv, 1);
		result = EXIT_FAILURE;
		goto leave;
	}

	if (wireless_pairing && use_network) {
		fprintf(stderr, "ERROR: You cannot use -w and -n together.\n");
		print_usage(argc, argv, 1);
		result = EXIT_FAILURE;
		goto leave;
	}

	cmd = (argv+optind)[0];

	if (!strcmp(cmd, "pair")) {
		op = OP_PAIR;
	} else if (!strcmp(cmd, "validate")) {
		op = OP_VALIDATE;
	} else if (!strcmp(cmd, "unpair")) {
		op = OP_UNPAIR;
	} else if (!strcmp(cmd, "list")) {
		op = OP_LIST;
	} else if (!strcmp(cmd, "hostid")) {
		op = OP_HOSTID;
	} else if (!strcmp(cmd, "systembuid")) {
		op = OP_SYSTEMBUID;
	} else {
		fprintf(stderr, "ERROR: Invalid command '%s' specified\n", cmd);
		print_usage(argc, argv, 1);
		result = EXIT_FAILURE;
		goto leave;
	}

	if (wireless_pairing) {
		if (op == OP_VALIDATE || op == OP_UNPAIR) {
			fprintf(stderr, "ERROR: Command '%s' is not supported with -w\n", cmd);
			print_usage(argc, argv, 1);
			result = EXIT_FAILURE;
			goto leave;
		}
		use_network = 1;
	}

	if (op == OP_SYSTEMBUID) {
		char *systembuid = NULL;
		userpref_read_system_buid(&systembuid);

		printf("%s\n", systembuid);

		free(systembuid);

		result = EXIT_SUCCESS;
		goto leave;
	}

	if (op == OP_LIST) {
		unsigned int i;
		char **udids = NULL;
		unsigned int count = 0;
		userpref_get_paired_udids(&udids, &count);
		for (i = 0; i < count; i++) {
			printf("%s\n", udids[i]);
			free(udids[i]);
		}
		free(udids);
		result = EXIT_SUCCESS;
		goto leave;
	}

	ret = idevice_new_with_options(&device, udid, (use_network) ? IDEVICE_LOOKUP_NETWORK : IDEVICE_LOOKUP_USBMUX);
	if (ret != IDEVICE_E_SUCCESS) {
		if (udid) {
			printf("No device found with udid %s.\n", udid);
		} else {
			printf("No device found.\n");
		}
		result = EXIT_FAILURE;
		goto leave;
	}
	if (!udid) {
		ret = idevice_get_udid(device, &udid);
		if (ret != IDEVICE_E_SUCCESS) {
			printf("ERROR: Could not get device udid, error code %d\n", ret);
			result = EXIT_FAILURE;
			goto leave;
		}
	}

	if (op == OP_HOSTID) {
		plist_t pair_record = NULL;
		char *hostid = NULL;

		userpref_read_pair_record(udid, &pair_record);
		pair_record_get_host_id(pair_record, &hostid);

		printf("%s\n", hostid);

		free(hostid);
		plist_free(pair_record);

		result = EXIT_SUCCESS;
		goto leave;
	}

	lerr = lockdownd_client_new(device, &client, TOOL_NAME);
	if (lerr != LOCKDOWN_E_SUCCESS) {
		printf("ERROR: Could not connect to lockdownd, error code %d\n", lerr);
		result = EXIT_FAILURE;
		goto leave;
	}

	result = EXIT_SUCCESS;

	lerr = lockdownd_query_type(client, &type);
	if (lerr != LOCKDOWN_E_SUCCESS) {
		printf("QueryType failed, error code %d\n", lerr);
		result = EXIT_FAILURE;
		goto leave;
	} else {
		if (strcmp("com.apple.mobile.lockdown", type) != 0) {
			printf("WARNING: QueryType request returned '%s'\n", type);
		}
		free(type);
	}

	switch(op) {
		default:
		case OP_PAIR:
#ifdef HAVE_WIRELESS_PAIRING
		if (wireless_pairing) {
			lerr = lockdownd_cu_pairing_create(client, pairing_cb, NULL, host_info_plist, NULL);
			if (lerr == LOCKDOWN_E_SUCCESS) {
				lerr = lockdownd_pair_cu(client);
			}
		} else
#endif
		{
			lerr = lockdownd_pair(client, NULL);
		}
		if (lerr == LOCKDOWN_E_SUCCESS) {
			printf("SUCCESS: Paired with device %s\n", udid);
		} else {
			result = EXIT_FAILURE;
			print_error_message(lerr);
		}
		break;

		case OP_VALIDATE:
		lockdownd_client_free(client);
		client = NULL;
		lerr = lockdownd_client_new_with_handshake(device, &client, TOOL_NAME);
		if (lerr == LOCKDOWN_E_SUCCESS) {
			printf("SUCCESS: Validated pairing with device %s\n", udid);
		} else {
			result = EXIT_FAILURE;
			print_error_message(lerr);
		}
		break;

		case OP_UNPAIR:
		lerr = lockdownd_unpair(client, NULL);
		if (lerr == LOCKDOWN_E_SUCCESS) {
			printf("SUCCESS: Unpaired with device %s\n", udid);
		} else {
			result = EXIT_FAILURE;
			print_error_message(lerr);
		}
		break;
	}

leave:
	lockdownd_client_free(client);
	idevice_free(device);
	free(udid);

	return result;
}

