<commit_before>/**
 * \file mtpz.c
 *
 * Copyright (C) 2011-2012 <NAME> <<EMAIL>>
 *
 * 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 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * This file provides mtp zune cryptographic setup interfaces.
 * It is also used with Windows Phone 7, but Microsoft/Nokiad seem
 * to have discontinued MTPZ on Windows Phone 8.
 *
 * DISCLAIMER:
 *
 * The intention of this implementation is for users to be able
 * to interoperate with their devices, i.e. copy music to them in
 * operating systems other than Microsoft Windows, so it can be
 * played back on the device. We do not provide encryption keys
 * and constants in libmtp, we never will. You have to have these
 * on file in your home directory in $HOME/.mtpz-data, and we suggest
 * that you talk to Microsoft about providing the proper numbers if
 * you want to use this facility.
 */
#include "config.h"
#include "libmtp.h"
#include "unicode.h"
#include "ptp.h"
#include "libusb-glue.h"
#include "device-flags.h"
#include "playlist-spl.h"
#include "util.h"
#include "mtpz.h"

#include <gcrypt.h>

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <errno.h>


/* Microsoft MTPZ extensions */

/*
 * The ~/.mtpz-data file contains all four necessary pieces of data:
 *
 *   encryption key
 *   public exponent
 *   modulus
 *   private key
 *   certificate data
 *
 * These four pieces of data are each stored in hex representation,
 * separated by newline characters.
 *
 * If you know of a published, public reference for one of these
 * arrays of data, please inform us, so we can include it here and
 * drop it from the external file. Even better is if you convince
 * Microsoft to officially provide keys to this project.
 */

static unsigned char *MTPZ_ENCRYPTION_KEY;
static unsigned char *MTPZ_PUBLIC_EXPONENT;
static unsigned char *MTPZ_MODULUS;
static unsigned char *MTPZ_PRIVATE_KEY;
static char *MTPZ_CERTIFICATES;

// Strip the trailing newline from fgets().
static char *fgets_strip(char * str, int num, FILE * stream)
{
	char *result = str;

	if ((result = fgets(str, num, stream)))
	{
		size_t newlen = strlen(result);

		if (result[newlen - 1] == '\n')
			result[newlen - 1] = '\0';
	}

	return result;
}

static char *hex_to_bytes(char *hex, size_t len)
{
	if (len % 2)
		return NULL;

	char *bytes = malloc(len / 2);
	unsigned int u;
	int i = 0;

	while (i < len && sscanf(hex + i, "%2x", &u) == 1)
	{
		bytes[i / 2] = u;
		i += 2;
	}

	return bytes;
}

int mtpz_loaddata()
{
	char *home = getenv("HOME");
	int ret = -1;
	if (!home)
	{
		LIBMTP_ERROR("Unable to determine user's home directory, MTPZ disabled.\n");
		return -1;
	}

	int plen = strlen(home) + strlen("/.mtpz-data") + 1;
	char path[plen];
	sprintf(path, "%s/.mtpz-data", home);

	FILE *fdata = fopen(path, "r");
	if (!fdata)
	{
		LIBMTP_ERROR("Unable to open ~/.mtpz-data for reading, MTPZ disabled.\n");
		return ret;
	}


	// Should only be six characters in length, but fgets will encounter a newline and stop.
	MTPZ_PUBLIC_EXPONENT = (unsigned char *)fgets_strip((char *)malloc(8), 8, fdata);
	if (!MTPZ_PUBLIC_EXPONENT)
	{
		LIBMTP_ERROR("Unable to read MTPZ public exponent from ~/.mtpz-data, MTPZ disabled.\n");
		goto cleanup;
	}

	// Should only be 33 characters in length, but fgets will encounter a newline and stop.
	char *hexenckey = fgets_strip((char *)malloc(35), 35, fdata);
	if (!hexenckey)
	{
		LIBMTP_ERROR("Unable to read MTPZ encryption key from ~/.mtpz-data, MTPZ disabled.\n");
		goto cleanup;
	}

	MTPZ_ENCRYPTION_KEY = hex_to_bytes(hexenckey, strlen(hexenckey));
	if (!MTPZ_ENCRYPTION_KEY)
	{
		LIBMTP_ERROR("Unable to read MTPZ encryption key from ~/.mtpz-data, MTPZ disabled.\n");
		goto cleanup;<commit_msg>do not report missing .mtpz-data files, most common output line ever.<commit_after>/**
 * \file mtpz.c
 *
 * Copyright (C) 2011-2012 <NAME> <s<EMAIL>>
 *
 * 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 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * This file provides mtp zune cryptographic setup interfaces.
 * It is also used with Windows Phone 7, but Microsoft/Nokiad seem
 * to have discontinued MTPZ on Windows Phone 8.
 *
 * DISCLAIMER:
 *
 * The intention of this implementation is for users to be able
 * to interoperate with their devices, i.e. copy music to them in
 * operating systems other than Microsoft Windows, so it can be
 * played back on the device. We do not provide encryption keys
 * and constants in libmtp, we never will. You have to have these
 * on file in your home directory in $HOME/.mtpz-data, and we suggest
 * that you talk to Microsoft about providing the proper numbers if
 * you want to use this facility.
 */
#include "config.h"
#include "libmtp.h"
#include "unicode.h"
#include "ptp.h"
#include "libusb-glue.h"
#include "device-flags.h"
#include "playlist-spl.h"
#include "util.h"
#include "mtpz.h"

#include <gcrypt.h>

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <errno.h>


/* Microsoft MTPZ extensions */

/*
 * The ~/.mtpz-data file contains all four necessary pieces of data:
 *
 *   encryption key
 *   public exponent
 *   modulus
 *   private key
 *   certificate data
 *
 * These four pieces of data are each stored in hex representation,
 * separated by newline characters.
 *
 * If you know of a published, public reference for one of these
 * arrays of data, please inform us, so we can include it here and
 * drop it from the external file. Even better is if you convince
 * Microsoft to officially provide keys to this project.
 */

static unsigned char *MTPZ_ENCRYPTION_KEY;
static unsigned char *MTPZ_PUBLIC_EXPONENT;
static unsigned char *MTPZ_MODULUS;
static unsigned char *MTPZ_PRIVATE_KEY;
static char *MTPZ_CERTIFICATES;

// Strip the trailing newline from fgets().
static char *fgets_strip(char * str, int num, FILE * stream)
{
	char *result = str;

	if ((result = fgets(str, num, stream)))
	{
		size_t newlen = strlen(result);

		if (result[newlen - 1] == '\n')
			result[newlen - 1] = '\0';
	}

	return result;
}

static char *hex_to_bytes(char *hex, size_t len)
{
	if (len % 2)
		return NULL;

	char *bytes = malloc(len / 2);
	unsigned int u;
	int i = 0;

	while (i < len && sscanf(hex + i, "%2x", &u) == 1)
	{
		bytes[i / 2] = u;
		i += 2;
	}

	return bytes;
}

int mtpz_loaddata()
{
	char *home = getenv("HOME");
	int ret = -1;
	if (!home)
	{
		LIBMTP_ERROR("Unable to determine user's home directory, MTPZ disabled.\n");
		return -1;
	}

	int plen = strlen(home) + strlen("/.mtpz-data") + 1;
	char path[plen];
	sprintf(path, "%s/.mtpz-data", home);

	FILE *fdata = fopen(path, "r");
	if (!fdata)
		return ret;

	// Should only be six characters in length, but fgets will encounter a newline and stop.
	MTPZ_PUBLIC_EXPONENT = (unsigned char *)fgets_strip((char *)malloc(8), 8, fdata);
	if (!MTPZ_PUBLIC_EXPONENT)
	{
		LIBMTP_ERROR("Unable to read MTPZ public exponent from ~/.mtpz-data, MTPZ disabled.\n");
		goto cleanup;
	}

	// Should only be 33 characters in length, but fgets will encounter a newline and stop.
	char *hexenckey = fgets_strip((char *)malloc(35), 35, fdata);
	if (!hexenckey)
	{
		LIBMTP_ERROR("Unable to read MTPZ encryption key from ~/.mtpz-data, MTPZ disabled.\n");
		goto cleanup;
	}

	MTPZ_ENCRYPTION_KEY = hex_to_bytes(hexenckey, strlen(hexenckey));
	if (!MTPZ_ENCRYPTION_KEY)
	{
		LIBMTP_ERROR("Unable to read MTPZ encryption key from ~/.mtpz-data, MTPZ disabled.\n");
		goto cleanup;
{'fraction_non_alphanumeric': 0.10818746470920385, 'fraction_numerical': 0.01038961038961039, 'mean_word_length': 3.771551724137931, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6454104', 'n_tokens_mistral': 3083, 'n_tokens_neox': 2882, 'n_words': 1149}