| 
									
										
										
										
											2021-12-18 17:42:23 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |   Copyright (c) 2021, Grégory Soutadé | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   All rights reserved. | 
					
						
							|  |  |  |   Redistribution and use in source and binary forms, with or without | 
					
						
							|  |  |  |   modification, are permitted provided that the following conditions are met: | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   * Redistributions of source code must retain the above copyright | 
					
						
							|  |  |  |     notice, this list of conditions and the following disclaimer. | 
					
						
							|  |  |  |   * Redistributions in binary form must reproduce the above copyright | 
					
						
							|  |  |  |     notice, this list of conditions and the following disclaimer in the | 
					
						
							|  |  |  |     documentation and/or other materials provided with the distribution. | 
					
						
							|  |  |  |   * Neither the name of the copyright holder nor the | 
					
						
							|  |  |  |     names of its contributors may be used to endorse or promote products | 
					
						
							|  |  |  |     derived from this software without specific prior written permission. | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY | 
					
						
							|  |  |  |   EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 
					
						
							|  |  |  |   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 
					
						
							|  |  |  |   DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY | 
					
						
							|  |  |  |   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 
					
						
							|  |  |  |   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 
					
						
							|  |  |  |   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | 
					
						
							|  |  |  |   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
					
						
							|  |  |  |   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | 
					
						
							|  |  |  |   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <getopt.h>
 | 
					
						
							| 
									
										
										
										
											2023-03-28 20:32:05 +02:00
										 |  |  | #include <libgen.h>
 | 
					
						
							| 
									
										
										
										
											2021-12-18 17:42:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <iostream>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <libgourou.h>
 | 
					
						
							|  |  |  | #include <libgourou_common.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-16 22:45:33 +01:00
										 |  |  | #include "drmprocessorclientimpl.h"
 | 
					
						
							|  |  |  | #include "utils_common.h"
 | 
					
						
							| 
									
										
										
										
											2021-12-18 17:42:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | static const char* deviceFile     = "device.xml"; | 
					
						
							|  |  |  | static const char* activationFile = "activation.xml"; | 
					
						
							|  |  |  | static const char* devicekeyFile  = "devicesalt"; | 
					
						
							|  |  |  | static const char* inputFile      = 0; | 
					
						
							|  |  |  | static const char* outputFile     = 0; | 
					
						
							|  |  |  | static const char* outputDir      = 0; | 
					
						
							| 
									
										
										
										
											2022-03-16 22:45:33 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | static char*          encryptionKeyUser  = 0; | 
					
						
							|  |  |  | static unsigned char* encryptionKey      = 0; | 
					
						
							| 
									
										
										
										
											2022-03-12 23:04:16 +01:00
										 |  |  | static unsigned       encryptionKeySize  = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline unsigned char htoi(unsigned char c) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (c >= '0' && c <= '9') | 
					
						
							|  |  |  | 	c -= '0'; | 
					
						
							|  |  |  |     else if (c >= 'a' && c <= 'f') | 
					
						
							|  |  |  | 	c -= 'a' - 10; | 
					
						
							|  |  |  |     else if (c >= 'A' && c <= 'F') | 
					
						
							|  |  |  | 	c -= 'A' - 10; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  | 	EXCEPTION(gourou::USER_INVALID_INPUT, "Invalid character " << c << " in encryption key"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return c; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2021-12-18 17:42:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | static inline bool endsWith(const std::string& s, const std::string& suffix) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return s.rfind(suffix) == std::abs((int)(s.size()-suffix.size())); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-16 22:45:33 +01:00
										 |  |  | class ADEPTRemove | 
					
						
							| 
									
										
										
										
											2021-12-18 17:42:23 +01:00
										 |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     | 
					
						
							| 
									
										
										
										
											2022-03-16 22:45:33 +01:00
										 |  |  |     int run() | 
					
						
							| 
									
										
										
										
											2021-12-18 17:42:23 +01:00
										 |  |  |     { | 
					
						
							|  |  |  | 	int ret = 0; | 
					
						
							|  |  |  | 	try | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	    gourou::DRMProcessor::ITEM_TYPE type; | 
					
						
							|  |  |  | 	    DRMProcessorClientImpl client; | 
					
						
							|  |  |  | 	    gourou::DRMProcessor processor(&client, deviceFile, activationFile, devicekeyFile); | 
					
						
							|  |  |  | 	     | 
					
						
							|  |  |  | 	    std::string filename; | 
					
						
							|  |  |  | 	    if (!outputFile) | 
					
						
							|  |  |  | 		filename = std::string(inputFile); | 
					
						
							|  |  |  | 	    else | 
					
						
							|  |  |  | 		filename = outputFile; | 
					
						
							|  |  |  | 	     | 
					
						
							|  |  |  | 	    if (outputDir) | 
					
						
							|  |  |  | 	    { | 
					
						
							| 
									
										
										
										
											2022-03-16 22:45:33 +01:00
										 |  |  | 		if (!fileExists(outputDir)) | 
					
						
							|  |  |  | 		    mkpath(outputDir); | 
					
						
							| 
									
										
										
										
											2021-12-18 17:42:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		filename = std::string(outputDir) + "/" + filename; | 
					
						
							|  |  |  | 	    } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	    if (endsWith(filename, ".epub")) | 
					
						
							|  |  |  | 		type = gourou::DRMProcessor::ITEM_TYPE::EPUB; | 
					
						
							|  |  |  | 	    else if (endsWith(filename, ".pdf")) | 
					
						
							|  |  |  | 		type = gourou::DRMProcessor::ITEM_TYPE::PDF; | 
					
						
							|  |  |  | 	    else | 
					
						
							|  |  |  | 	    { | 
					
						
							|  |  |  | 		EXCEPTION(gourou::DRM_FORMAT_NOT_SUPPORTED, "Unsupported file format of " << filename); | 
					
						
							|  |  |  | 	    } | 
					
						
							|  |  |  | 	     | 
					
						
							|  |  |  | 	    if (inputFile != filename) | 
					
						
							|  |  |  | 	    { | 
					
						
							| 
									
										
										
										
											2022-03-16 22:45:33 +01:00
										 |  |  | 		unlink(filename.c_str()); | 
					
						
							|  |  |  | 		fileCopy(inputFile, filename.c_str()); | 
					
						
							| 
									
										
										
										
											2022-03-12 23:04:16 +01:00
										 |  |  | 		processor.removeDRM(inputFile, filename, type, encryptionKey, encryptionKeySize); | 
					
						
							| 
									
										
										
										
											2021-12-18 17:42:23 +01:00
										 |  |  | 		std::cout << "DRM removed into new file " << filename << std::endl; | 
					
						
							|  |  |  | 	    } | 
					
						
							|  |  |  | 	    else | 
					
						
							|  |  |  | 	    { | 
					
						
							|  |  |  | 		// Use temp file for PDF
 | 
					
						
							|  |  |  | 		if (type == gourou::DRMProcessor::ITEM_TYPE::PDF) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2022-04-23 17:41:54 +02:00
										 |  |  | 		    std::string tempFile = filename + ".tmp"; | 
					
						
							|  |  |  | 		    /* Be sure there is not already a temp file */ | 
					
						
							|  |  |  | 		    unlink(tempFile.c_str()); | 
					
						
							|  |  |  | 		    processor.removeDRM(filename, tempFile, type, encryptionKey, encryptionKeySize); | 
					
						
							| 
									
										
										
										
											2021-12-18 17:42:23 +01:00
										 |  |  | 		    /* Original file must be removed before doing a copy... */ | 
					
						
							| 
									
										
										
										
											2022-04-23 17:41:54 +02:00
										 |  |  | 		    unlink(filename.c_str()); | 
					
						
							|  |  |  | 		    if (rename(tempFile.c_str(), filename.c_str())) | 
					
						
							| 
									
										
										
										
											2021-12-18 17:42:23 +01:00
										 |  |  | 		    { | 
					
						
							| 
									
										
										
										
											2022-03-16 22:45:33 +01:00
										 |  |  | 			EXCEPTION(gourou::DRM_FILE_ERROR, "Unable to copy " << tempFile << " into " << filename); | 
					
						
							| 
									
										
										
										
											2021-12-18 17:42:23 +01:00
										 |  |  | 		    } | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							| 
									
										
										
										
											2022-03-12 23:04:16 +01:00
										 |  |  | 		    processor.removeDRM(inputFile, filename, type, encryptionKey, encryptionKeySize); | 
					
						
							| 
									
										
										
										
											2021-12-18 17:42:23 +01:00
										 |  |  | 		std::cout << "DRM removed from " << filename << std::endl; | 
					
						
							|  |  |  | 	    } | 
					
						
							|  |  |  | 	} catch(std::exception& e) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	    std::cout << e.what() << std::endl; | 
					
						
							|  |  |  | 	    ret = 1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-16 22:45:33 +01:00
										 |  |  | 	return ret; | 
					
						
							| 
									
										
										
										
											2021-12-18 17:42:23 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | };	       | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void usage(const char* cmd) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-01-08 21:02:59 +01:00
										 |  |  |     std::cout << basename((char*)cmd) << " remove ADEPT DRM (from Adobe) of EPUB/PDF file" << std::endl << std::endl; | 
					
						
							| 
									
										
										
										
											2021-12-18 17:42:23 +01:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2023-01-08 21:02:59 +01:00
										 |  |  |     std::cout << "Usage: " << basename((char*)cmd) << " [OPTIONS] file(.epub|pdf)" << std::endl << std::endl; | 
					
						
							| 
									
										
										
										
											2021-12-18 17:42:23 +01:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2023-01-08 21:02:59 +01:00
										 |  |  |     std::cout << "Global Options:" << std::endl; | 
					
						
							| 
									
										
										
										
											2021-12-18 17:42:23 +01:00
										 |  |  |     std::cout << "  " << "-O|--output-dir"      << "\t"   << "Optional output directory were to put result (default ./)" << std::endl; | 
					
						
							|  |  |  |     std::cout << "  " << "-o|--output-file"     << "\t"   << "Optional output filename (default inplace DRM removal>)" << std::endl; | 
					
						
							| 
									
										
										
										
											2023-01-08 21:02:59 +01:00
										 |  |  |     std::cout << "  " << "-f|--input-file"      << "\t"   << "Backward compatibility: EPUB/PDF file to process" << std::endl; | 
					
						
							| 
									
										
										
										
											2021-12-18 17:42:23 +01:00
										 |  |  |     std::cout << "  " << "-v|--verbose"         << "\t\t" << "Increase verbosity, can be set multiple times" << std::endl; | 
					
						
							|  |  |  |     std::cout << "  " << "-V|--version"         << "\t\t" << "Display libgourou version" << std::endl; | 
					
						
							|  |  |  |     std::cout << "  " << "-h|--help"            << "\t\t" << "This help" << std::endl; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-08 21:02:59 +01:00
										 |  |  |     std::cout << "ADEPT Options:" << std::endl; | 
					
						
							|  |  |  |     std::cout << "  " << "-D|--adept-directory" << "\t"   << ".adept directory that must contains device.xml, activation.xml and devicesalt" << std::endl; | 
					
						
							|  |  |  |     std::cout << "  " << "-d|--device-file"     << "\t"   << "device.xml file from eReader" << std::endl; | 
					
						
							|  |  |  |     std::cout << "  " << "-a|--activation-file" << "\t"   << "activation.xml file from eReader" << std::endl; | 
					
						
							|  |  |  |     std::cout << "  " << "-k|--device-key-file" << "\t"   << "private device key file (eg devicesalt/devkey.bin) from eReader" << std::endl; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-18 17:42:23 +01:00
										 |  |  |     std::cout << std::endl; | 
					
						
							| 
									
										
										
										
											2023-01-08 21:02:59 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     std::cout << "Environment:" << std::endl; | 
					
						
							| 
									
										
										
										
											2021-12-18 17:42:23 +01:00
										 |  |  |     std::cout << "Device file, activation file and device key file are optionals. If not set, they are looked into :" << std::endl; | 
					
						
							| 
									
										
										
										
											2023-01-05 21:29:55 +01:00
										 |  |  |     std::cout << "  * $ADEPT_DIR environment variable" << std::endl; | 
					
						
							|  |  |  |     std::cout << "  * /home/<user>/.config/adept" << std::endl; | 
					
						
							| 
									
										
										
										
											2021-12-18 17:42:23 +01:00
										 |  |  |     std::cout << "  * Current directory" << std::endl; | 
					
						
							|  |  |  |     std::cout << "  * .adept" << std::endl; | 
					
						
							|  |  |  |     std::cout << "  * adobe-digital-editions directory" << std::endl; | 
					
						
							|  |  |  |     std::cout << "  * .adobe-digital-editions directory" << std::endl; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int main(int argc, char** argv) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int c, ret = -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const char** files[] = {&devicekeyFile, &deviceFile, &activationFile}; | 
					
						
							|  |  |  |     int verbose = gourou::DRMProcessor::getLogLevel(); | 
					
						
							| 
									
										
										
										
											2022-12-21 21:23:42 +01:00
										 |  |  |     std::string _deviceFile, _activationFile, _devicekeyFile; | 
					
						
							| 
									
										
										
										
											2021-12-18 17:42:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     while (1) { | 
					
						
							|  |  |  | 	int option_index = 0; | 
					
						
							|  |  |  | 	static struct option long_options[] = { | 
					
						
							| 
									
										
										
										
											2022-12-21 21:23:42 +01:00
										 |  |  | 	    {"adept-directory",  required_argument, 0,  'D' }, | 
					
						
							| 
									
										
										
										
											2021-12-18 17:42:23 +01:00
										 |  |  | 	    {"device-file",      required_argument, 0,  'd' }, | 
					
						
							|  |  |  | 	    {"activation-file",  required_argument, 0,  'a' }, | 
					
						
							|  |  |  | 	    {"device-key-file",  required_argument, 0,  'k' }, | 
					
						
							|  |  |  | 	    {"output-dir",       required_argument, 0,  'O' }, | 
					
						
							|  |  |  | 	    {"output-file",      required_argument, 0,  'o' }, | 
					
						
							|  |  |  | 	    {"input-file",       required_argument, 0,  'f' }, | 
					
						
							| 
									
										
										
										
											2022-03-12 23:04:16 +01:00
										 |  |  | 	    {"encryption-key",   required_argument, 0,  'K' }, // Private option
 | 
					
						
							| 
									
										
										
										
											2021-12-18 17:42:23 +01:00
										 |  |  | 	    {"verbose",          no_argument,       0,  'v' }, | 
					
						
							|  |  |  | 	    {"version",          no_argument,       0,  'V' }, | 
					
						
							|  |  |  | 	    {"help",             no_argument,       0,  'h' }, | 
					
						
							|  |  |  | 	    {0,                  0,                 0,  0 } | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-21 21:23:42 +01:00
										 |  |  | 	c = getopt_long(argc, argv, "D:d:a:k:O:o:f:K:vVh", | 
					
						
							| 
									
										
										
										
											2021-12-18 17:42:23 +01:00
										 |  |  |                         long_options, &option_index); | 
					
						
							|  |  |  | 	if (c == -1) | 
					
						
							|  |  |  | 	    break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (c) { | 
					
						
							| 
									
										
										
										
											2022-12-21 21:23:42 +01:00
										 |  |  | 	case 'D': | 
					
						
							|  |  |  | 	    _deviceFile = std::string(optarg) + "/device.xml"; | 
					
						
							|  |  |  | 	    _activationFile = std::string(optarg) + "/activation.xml"; | 
					
						
							|  |  |  | 	    _devicekeyFile = std::string(optarg) + "/devicesalt"; | 
					
						
							|  |  |  | 	    deviceFile = _deviceFile.c_str(); | 
					
						
							|  |  |  | 	    activationFile = _activationFile.c_str(); | 
					
						
							|  |  |  | 	    devicekeyFile = _devicekeyFile.c_str(); | 
					
						
							|  |  |  | 	    break; | 
					
						
							| 
									
										
										
										
											2021-12-18 17:42:23 +01:00
										 |  |  | 	case 'd': | 
					
						
							|  |  |  | 	    deviceFile = optarg; | 
					
						
							|  |  |  | 	    break; | 
					
						
							|  |  |  | 	case 'a': | 
					
						
							|  |  |  | 	    activationFile = optarg; | 
					
						
							|  |  |  | 	    break; | 
					
						
							|  |  |  | 	case 'k': | 
					
						
							|  |  |  | 	    devicekeyFile = optarg; | 
					
						
							|  |  |  | 	    break; | 
					
						
							|  |  |  | 	case 'f': | 
					
						
							|  |  |  | 	    inputFile = optarg; | 
					
						
							|  |  |  | 	    break; | 
					
						
							|  |  |  | 	case 'O': | 
					
						
							|  |  |  | 	    outputDir = optarg; | 
					
						
							|  |  |  | 	    break; | 
					
						
							|  |  |  | 	case 'o': | 
					
						
							|  |  |  | 	    outputFile = optarg; | 
					
						
							|  |  |  | 	    break; | 
					
						
							| 
									
										
										
										
											2022-03-12 23:04:16 +01:00
										 |  |  | 	case 'K': | 
					
						
							|  |  |  | 	    encryptionKeyUser = optarg; | 
					
						
							|  |  |  | 	    break; | 
					
						
							| 
									
										
										
										
											2021-12-18 17:42:23 +01:00
										 |  |  | 	case 'v': | 
					
						
							|  |  |  | 	    verbose++; | 
					
						
							|  |  |  | 	    break; | 
					
						
							|  |  |  | 	case 'V': | 
					
						
							|  |  |  | 	    version(); | 
					
						
							|  |  |  | 	    return 0; | 
					
						
							|  |  |  | 	case 'h': | 
					
						
							|  |  |  | 	    usage(argv[0]); | 
					
						
							|  |  |  | 	    return 0; | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 	    usage(argv[0]); | 
					
						
							|  |  |  | 	    return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     | 
					
						
							|  |  |  |     gourou::DRMProcessor::setLogLevel(verbose); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-08 20:58:41 +01:00
										 |  |  |     if (optind == argc-1) | 
					
						
							|  |  |  | 	inputFile = argv[optind]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-18 17:42:23 +01:00
										 |  |  |     if (!inputFile || (outputDir && !outputDir[0]) || | 
					
						
							|  |  |  | 	(outputFile && !outputFile[0])) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  | 	usage(argv[0]); | 
					
						
							|  |  |  | 	return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-16 22:45:33 +01:00
										 |  |  |     ADEPTRemove remover; | 
					
						
							| 
									
										
										
										
											2021-12-18 17:42:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     int i; | 
					
						
							|  |  |  |     bool hasErrors = false; | 
					
						
							|  |  |  |     const char* orig; | 
					
						
							|  |  |  |     for (i=0; i<(int)ARRAY_SIZE(files); i++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  | 	orig = *files[i]; | 
					
						
							|  |  |  | 	*files[i] = findFile(*files[i]); | 
					
						
							|  |  |  | 	if (!*files[i]) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	    std::cout << "Error : " << orig << " doesn't exists, did you activate your device ?" << std::endl; | 
					
						
							|  |  |  | 	    ret = -1; | 
					
						
							|  |  |  | 	    hasErrors = true; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-12 23:04:16 +01:00
										 |  |  |     if (encryptionKeyUser) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  | 	int size = std::string(encryptionKeyUser).size(); | 
					
						
							|  |  |  | 	if ((size % 2)) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	    std::cout << "Error : Encryption key must be odd length" << std::endl; | 
					
						
							|  |  |  | 	    goto end; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (encryptionKeyUser[0] == '0' && encryptionKeyUser[1] == 'x') | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	    encryptionKeyUser += 2; | 
					
						
							|  |  |  | 	    size -= 2; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	encryptionKey = new unsigned char[size/2]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for(i=0; i<size; i+=2) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	    encryptionKey[i/2]  = htoi(encryptionKeyUser[i]) << 4; | 
					
						
							|  |  |  | 	    encryptionKey[i/2] |= htoi(encryptionKeyUser[i+1]); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	encryptionKeySize = size/2; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2021-12-18 17:42:23 +01:00
										 |  |  |     if (hasErrors) | 
					
						
							|  |  |  | 	goto end; | 
					
						
							|  |  |  |         | 
					
						
							| 
									
										
										
										
											2022-03-16 22:45:33 +01:00
										 |  |  |     ret = remover.run(); | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2021-12-18 17:42:23 +01:00
										 |  |  | end: | 
					
						
							|  |  |  |     for (i=0; i<(int)ARRAY_SIZE(files); i++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  | 	if (*files[i]) | 
					
						
							|  |  |  | 	    free((void*)*files[i]); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-12 23:04:16 +01:00
										 |  |  |     if (encryptionKey) | 
					
						
							|  |  |  | 	free(encryptionKey); | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2021-12-18 17:42:23 +01:00
										 |  |  |     return ret; | 
					
						
							|  |  |  | } |