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