From b5001a9a6e6d0f63f2f2d26a2f710519a6fcc6a0 Mon Sep 17 00:00:00 2001
From: open-license-manager <rillf@maildrop.cc>
Date: 周一, 26 5月 2014 01:00:10 +0800
Subject: [PATCH] pc id

---
 src/library/pc-identifiers.h  |    2 
 src/library/base/base64.h     |  170 ++++++++++++++++++++++++++++++++++
 src/library/api/datatypes.h   |    2 
 src/library/LicenseReader.cpp |   23 ++++
 src/library/pc-identifiers.c  |   62 +++++++++++-
 5 files changed, 250 insertions(+), 9 deletions(-)

diff --git a/src/library/LicenseReader.cpp b/src/library/LicenseReader.cpp
index 093b276..16662dd 100644
--- a/src/library/LicenseReader.cpp
+++ b/src/library/LicenseReader.cpp
@@ -64,6 +64,14 @@
 			er.addEvent(PRODUCT_EXPIRED, SEVERITY_ERROR);
 		}
 	}
+	if (has_client_sig) {
+		UserPcIdentifier str_code;
+		strncpy(str_code, client_signature.c_str(), sizeof(str_code));
+		EVENT_TYPE event = validate_user_pc_identifier(str_code);
+		if (event != OK) {
+			er.addEvent(event, SEVERITY_ERROR);
+		}
+	}
 	return er;
 }
 
@@ -123,7 +131,7 @@
 		 *  sw_version_to = (optional int)
 		 *  from_date = YYYY-MM-DD (optional)
 		 *  to_date  = YYYY-MM-DD (optional)
-		 *  client_signature = XXXXXXXX (optional string 16)
+		 *  client_signature = XXXX-XXXX-XXXX-XXXX (optional string 16)
 		 *  license_signature = XXXXXXXXXX (mandatory, 1024)
 		 *  application_data = xxxxxxxxx (optional string 16)
 		 */
@@ -138,8 +146,19 @@
 			string to_date = trim_copy(
 					ini.GetValue(productNamePtr, "to_date",
 							FullLicenseInfo::UNUSED_TIME));
+			string client_signature = trim_copy(
+					ini.GetValue(productNamePtr, "client_signature", ""));
+			client_signature.erase(
+					std::remove(client_signature.begin(),
+							client_signature.end(), "-"),
+					client_signature.end());
+			int from_sw_version = ini.GetLongValue(productNamePtr,
+					"from_sw_version", FullLicenseInfo::UNUSED_SOFTWARE_VERSION);
+			int to_sw_version = ini.GetLongValue(productNamePtr,
+					"to_sw_version", FullLicenseInfo::UNUSED_SOFTWARE_VERSION);
 			FullLicenseInfo licInfo(*it, product, license_signature,
-					(int) license_version, from_date, to_date);
+					(int) license_version, from_date, to_date,
+					client_signature,from_sw_version,to_sw_version);
 			licenseInfoOut.push_back(licInfo);
 			atLeastOneLicenseComplete = true;
 		} else {
diff --git a/src/library/api/datatypes.h b/src/library/api/datatypes.h
index dad399e..e2dcda3 100644
--- a/src/library/api/datatypes.h
+++ b/src/library/api/datatypes.h
@@ -93,7 +93,7 @@
  * in most cases.
  */
 typedef enum {
-	DEFAULT, ETHERNET, IP_ADDRESS, DISK_NUM, DISK_LABEL
+	DEFAULT, ETHERNET, IP_ADDRESS, DISK_NUM, DISK_LABEL, STRATEGY_UNKNOWN
 } IDENTIFICATION_STRATEGY;
 
 #ifdef __cplusplus
diff --git a/src/library/base/base64.h b/src/library/base/base64.h
new file mode 100644
index 0000000..27f49cd
--- /dev/null
+++ b/src/library/base/base64.h
@@ -0,0 +1,170 @@
+/*
+
+ https://github.com/superwills/NibbleAndAHalf
+ base64.h -- Fast base64 encoding and decoding.
+ version 1.0.0, April 17, 2013 143a
+
+ Copyright (C) 2013 William Sherif
+
+ This software is provided 'as-is', without any express or implied
+ warranty.  In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ William Sherif
+ will.sherif@gmail.com
+
+ YWxsIHlvdXIgYmFzZSBhcmUgYmVsb25nIHRvIHVz
+
+ */
+#ifndef BASE64_H
+#define BASE64_H
+
+#include <stdio.h>
+#include <stdlib.h>
+
+const static char* b64 =
+		"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+// maps A=>0,B=>1..
+const static unsigned char unb64[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //10
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //20
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //30
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //40
+		0, 0, 0, 62, 0, 0, 0, 63, 52, 53, //50
+		54, 55, 56, 57, 58, 59, 60, 61, 0, 0, //60
+		0, 0, 0, 0, 0, 0, 1, 2, 3, 4, //70
+		5, 6, 7, 8, 9, 10, 11, 12, 13, 14, //80
+		15, 16, 17, 18, 19, 20, 21, 22, 23, 24, //90
+		25, 0, 0, 0, 0, 0, 0, 26, 27, 28, //100
+		29, 30, 31, 32, 33, 34, 35, 36, 37, 38, //110
+		39, 40, 41, 42, 43, 44, 45, 46, 47, 48, //120
+		49, 50, 51, 0, 0, 0, 0, 0, 0, 0, //130
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //140
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //150
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //160
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //170
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //180
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //190
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //200
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //210
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //220
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //230
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //240
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //250
+		0, 0, 0, 0, 0, 0, }; // This array has 255 elements
+
+// Converts binary data of length=len to base64 characters.
+// Length of the resultant string is stored in flen
+// (you must pass pointer flen).
+char* base64(const void* binaryData, int len, int *flen) {
+	const unsigned char* bin = (const unsigned char*) binaryData;
+	char* res;
+
+	int rc = 0; // result counter
+	int byteNo; // I need this after the loop
+
+	int modulusLen = len % 3;
+	int pad = ((modulusLen & 1) << 1) + ((modulusLen & 2) >> 1); // 2 gives 1 and 1 gives 2, but 0 gives 0.
+
+	*flen = 4 * (len + pad) / 3;
+	res = (char*) malloc(*flen + 1); // and one for the null
+	if (!res) {
+		puts("ERROR: base64 could not allocate enough memory.");
+		puts("I must stop because I could not get enough");
+		return 0;
+	}
+
+	for (byteNo = 0; byteNo <= len - 3; byteNo += 3) {
+		unsigned char BYTE0 = bin[byteNo];
+		unsigned char BYTE1 = bin[byteNo + 1];
+		unsigned char BYTE2 = bin[byteNo + 2];
+		res[rc++] = b64[BYTE0 >> 2];
+		res[rc++] = b64[((0x3 & BYTE0) << 4) + (BYTE1 >> 4)];
+		res[rc++] = b64[((0x0f & BYTE1) << 2) + (BYTE2 >> 6)];
+		res[rc++] = b64[0x3f & BYTE2];
+	}
+
+	if (pad == 2) {
+		res[rc++] = b64[bin[byteNo] >> 2];
+		res[rc++] = b64[(0x3 & bin[byteNo]) << 4];
+		res[rc++] = '=';
+		res[rc++] = '=';
+	} else if (pad == 1) {
+		res[rc++] = b64[bin[byteNo] >> 2];
+		res[rc++] = b64[((0x3 & bin[byteNo]) << 4) + (bin[byteNo + 1] >> 4)];
+		res[rc++] = b64[(0x0f & bin[byteNo + 1]) << 2];
+		res[rc++] = '=';
+	}
+
+	res[rc] = 0; // NULL TERMINATOR! ;)
+	return res;
+}
+
+unsigned char* unbase64(const char* ascii, int len, int *flen) {
+	const unsigned char *safeAsciiPtr = (const unsigned char*) ascii;
+	unsigned char *bin;
+	int cb = 0;
+	int charNo;
+	int pad = 0;
+
+	if (len < 2) { // 2 accesses below would be OOB.
+		// catch empty string, return NULL as result.
+		puts(
+				"ERROR: You passed an invalid base64 string (too short). You get NULL back.");
+		*flen = 0;
+		return 0;
+	}
+	if (safeAsciiPtr[len - 1] == '=')
+		++pad;
+	if (safeAsciiPtr[len - 2] == '=')
+		++pad;
+
+	*flen = 3 * len / 4 - pad;
+	bin = (unsigned char*) malloc(*flen);
+	if (!bin) {
+		puts("ERROR: unbase64 could not allocate enough memory.");
+		puts("I must stop because I could not get enough");
+		return 0;
+	}
+
+	for (charNo = 0; charNo <= len - 4 - pad; charNo += 4) {
+		int A = unb64[safeAsciiPtr[charNo]];
+		int B = unb64[safeAsciiPtr[charNo + 1]];
+		int C = unb64[safeAsciiPtr[charNo + 2]];
+		int D = unb64[safeAsciiPtr[charNo + 3]];
+
+		bin[cb++] = (A << 2) | (B >> 4);
+		bin[cb++] = (B << 4) | (C >> 2);
+		bin[cb++] = (C << 6) | (D);
+	}
+
+	if (pad == 1) {
+		int A = unb64[safeAsciiPtr[charNo]];
+		int B = unb64[safeAsciiPtr[charNo + 1]];
+		int C = unb64[safeAsciiPtr[charNo + 2]];
+
+		bin[cb++] = (A << 2) | (B >> 4);
+		bin[cb++] = (B << 4) | (C >> 2);
+	} else if (pad == 2) {
+		int A = unb64[safeAsciiPtr[charNo]];
+		int B = unb64[safeAsciiPtr[charNo + 1]];
+
+		bin[cb++] = (A << 2) | (B >> 4);
+	}
+
+	return bin;
+}
+
+#endif
diff --git a/src/library/pc-identifiers.c b/src/library/pc-identifiers.c
index a4ea81c..e60a5b0 100644
--- a/src/library/pc-identifiers.c
+++ b/src/library/pc-identifiers.c
@@ -9,6 +9,7 @@
 #include "pc-identifiers.h"
 #include <stdlib.h>
 #include <stdbool.h>
+#include "base/base64.h"
 
 static FUNCTION_RETURN generate_default_pc_id(PcIdentifier * identifiers,
 		unsigned int * num_identifiers) {
@@ -43,8 +44,9 @@
 	for (i = 0; i < disk_num; i++) {
 		for (j = 0; j < adapter_num; i++) {
 			for (k = 0; k < 6; k++)
-				identifiers[i * adapter_num + j][k] = diskInfos[i].disk_sn[k
-						+ 2] ^ adapterInfos[j].mac_address[k + 2];
+				identifiers[i * adapter_num + j][k] =
+						diskInfos[i].disk_sn[k + 2]
+								^ adapterInfos[j].mac_address[k + 2];
 		}
 	}
 
@@ -147,7 +149,7 @@
 		result = generate_default_pc_id(identifiers, array_size);
 		break;
 	case ETHERNET:
-		result = generate_ethernet_pc_id(identifiers, array_size, false);
+		result = generate_ethernet_pc_id(identifiers, array_size, true);
 		break;
 	case IP_ADDRESS:
 		result = generate_ethernet_pc_id(identifiers, array_size, false);
@@ -156,7 +158,7 @@
 		result = generate_disk_pc_id(identifiers, array_size, false);
 		break;
 	case DISK_LABEL:
-		result = generate_disk_pc_id(identifiers, array_size, false);
+		result = generate_disk_pc_id(identifiers, array_size, true);
 		break;
 	default:
 		return ERROR;
@@ -188,7 +190,55 @@
  * @param str_code: the code in the string format XXXX-XXXX-XXXX-XXXX
  * @return
  */
-int decode_pc_id(PcIdentifier* identifier1_out, PcIdentifier* identifier2_out,
-		UserPcIdentifier str_code) {
+static FUNCTION_RETURN decode_pc_id(PcIdentifier* identifier1_out,
+		PcIdentifier* identifier2_out, UserPcIdentifier str_code) {
 
 }
+
+static IDENTIFICATION_STRATEGY strategy_from_pc_id(PcIdentifier identifier) {
+	return (IDENTIFICATION_STRATEGY) identifier[0] >> 5;
+}
+
+EVENT_TYPE validate_user_pc_identifier(UserPcIdentifier str_code) {
+	PcIdentifier user_identifiers[2];
+	FUNCTION_RETURN result;
+	IDENTIFICATION_STRATEGY previous_strategy_id, current_strategy_id;
+	PcIdentifier* calculated_identifiers;
+	size_t calc_identifiers_size;
+	int i, j;
+	bool found;
+
+	result = decode_pc_id(&user_identifiers[0], &user_identifiers[1], str_code);
+	if (result != OK) {
+		return result;
+	}
+	previous_strategy_id = STRATEGY_UNKNOWN;
+	found = false;
+	for (i = 0; i < 2; i++) {
+		current_strategy_id = strategy_from_pc_id(user_identifiers[i]);
+		if (current_strategy_id == STRATEGY_UNKNOWN) {
+			return LICENSE_MALFORMED;
+		}
+		if (current_strategy_id != previous_strategy_id) {
+			if (calculated_identifiers != NULL) {
+				free(calculated_identifiers);
+			}
+			current_strategy_id = previous_strategy_id;
+			generate_pc_id(NULL, &calc_identifiers_size, current_strategy_id);
+			calculated_identifiers = (PcIdentifier *) malloc(
+					sizeof(PcIdentifier) * calc_identifiers_size);
+			generate_pc_id(calculated_identifiers, &calc_identifiers_size,
+					current_strategy_id);
+		}
+		//maybe skip the byte 0
+		for (j = 0; j < calc_identifiers_size; j++) {
+			if (!memcmp(user_identifiers[i], calculated_identifiers[j],
+					sizeof(PcIdentifier))) {
+				free(calculated_identifiers);
+				return LICENSE_OK;
+			}
+		}
+	}
+	free(calculated_identifiers);
+	return IDENTIFIERS_MISMATCH;
+}
diff --git a/src/library/pc-identifiers.h b/src/library/pc-identifiers.h
index 99d50c0..88d2442 100644
--- a/src/library/pc-identifiers.h
+++ b/src/library/pc-identifiers.h
@@ -17,4 +17,6 @@
 FUNCTION_RETURN generate_pc_id(PcIdentifier * identifiers, unsigned int * array_size,
 		IDENTIFICATION_STRATEGY strategy);
 
+EVENT_TYPE validate_user_pc_identifier(UserPcIdentifier str_code);
+
 #endif /* PC_IDENTIFIERS_H_ */

--
Gitblit v1.9.1