blob: a2b42d25959ce7c3b452a842da1eefdb870f00d8 [file] [log] [blame]
/** @file
A brief file description
@section license License
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "ink_config.h"
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include "ink_code.h"
#include "Diags.h"
#include "ParseRules.h"
#include "PluginDB.h"
/***************************************************************************
*
* An Inktomi Traffic Server plugin license key should look like:
*
* XXXXXEEEEDDDDDD
*
* XXXXX is a 5 digit alphanumeric id used by plugin vendors to
* assign to their customers.
*
* EEEE is the hex encoding of the expiration date. It's the number
* of days from January 1, 1970. If a plugin has no expiration date,
* 0000 can be used instead.
*
* DDDDDD is the INK_MD5 encoding of some combination of the following
* strings: "Inktomi Traffic Server", "Plugin Name", "XXXXXEEEE".
*
*
***************************************************************************/
const char *
PluginDB::CheckLicenseResultStr[] = {
"license missing",
"license expired",
"license invalid",
"license ok"
};
const unsigned int
PluginDB::license_custid_len = 5;
const unsigned int
PluginDB::license_expire_len = 4;
const unsigned int
PluginDB::license_digest_len = 6;
const unsigned int
PluginDB::license_total_len = PluginDB::license_custid_len +
PluginDB::license_expire_len + PluginDB::license_digest_len;
PluginDB::PluginDB(const char *plugin_db_file)
{
info_table = ink_hash_table_create(InkHashTableKeyType_String);
ReadPluginDB(plugin_db_file);
}
PluginDB::~PluginDB(void)
{
ink_hash_table_destroy_and_free_values(info_table);
}
void
PluginDB::ReadPluginDB(const char *plugin_db_file)
{
FILE *pdb = fopen(plugin_db_file, "r");
if (pdb == NULL) {
Warning("unable to open plugin.db file '%s': %d, %s", plugin_db_file, errno, strerror(errno));
return;
}
char line[1024];
char plugin_obj[256];
plugin_obj[0] = '\0';
PluginDB::PluginInfo * pinfo = new PluginDB::PluginInfo();
while (fgets(line, sizeof(line) - 1, pdb) != NULL) {
char *p = line;
while (*p && ParseRules::is_wslfcr(*p)) {
p++;
}
if ((*p == '\0') || (*p == '#')) {
continue;
}
// We have a non-comment and non-blank line
// Nullify the newline character
int len = strlen(p);
int i;
p[len - 1] = '\0';
if (p[0] == '[') {
if (plugin_obj[0] != '\0' && (pinfo->name[0] != '\0' || pinfo->license[0] != '\0')) {
ink_hash_table_insert(info_table, (InkHashTableKey) plugin_obj, (InkHashTableValue) pinfo);
plugin_obj[0] = '\0';
pinfo = new PluginDB::PluginInfo();
}
p++;
for (i = 0; p[i] != '\0' && p[i] != ']' && i < 255; i++) {
pinfo->name[i] = p[i];
}
pinfo->name[i] = '\0';
} else {
if (strstr(p, "Object=")) {
p = p + sizeof("Object=") - 1;
for (i = 0; p[i] != '\0' && i < 255; i++) {
plugin_obj[i] = p[i];
}
plugin_obj[i] = '\0';
} else if (strstr(p, "License=")) {
p = p + sizeof("License=") - 1;
for (i = 0; p[i] != '\0' && i < 255; i++) {
pinfo->license[i] = p[i];
}
pinfo->license[i] = '\0';
}
}
}
if (plugin_obj[0] != '\0' && (pinfo->name[0] != '\0' || pinfo->license[0] != '\0')) {
ink_hash_table_insert(info_table, (InkHashTableKey) plugin_obj, (InkHashTableValue) pinfo);
} else {
delete pinfo;
}
fclose(pdb);
}
PluginDB::CheckLicenseResult PluginDB::CheckLicense(const char *plugin_obj)
{
char
buffer[1024],
buffer_md5[16],
buffer_md5_str[33];
char
expire_str[PluginDB::license_expire_len + 1];
unsigned long
expire_days;
INK_DIGEST_CTX
md5_context;
PluginDB::PluginInfo * pinfo;
char *
end_ptr = NULL;
InkHashTableEntry *
ht_entry = ink_hash_table_lookup_entry(info_table,
(InkHashTableKey) plugin_obj);
if (ht_entry != NULL) {
pinfo = (PluginDB::PluginInfo *) ink_hash_table_entry_value(info_table, ht_entry);
} else {
return PluginDB::license_missing;
}
if (strlen(pinfo->license) != PluginDB::license_total_len) {
return PluginDB::license_invalid;
}
snprintf(buffer, sizeof(buffer), "Inktomi Traffic Server %s ", pinfo->name);
strncat(buffer, pinfo->license, PluginDB::license_custid_len + PluginDB::license_expire_len);
ink_code_incr_md5_init(&md5_context);
ink_code_incr_md5_update(&md5_context, buffer, strlen(buffer));
ink_code_incr_md5_final(buffer_md5, &md5_context);
// coverity[uninit_use_in_call]
ink_code_md5_stringify(buffer_md5_str, sizeof(buffer_md5_str), buffer_md5);
if (strncmp(buffer_md5_str,
pinfo->license + PluginDB::license_custid_len
+ PluginDB::license_expire_len, PluginDB::license_digest_len) != 0) {
return PluginDB::license_invalid;
}
strncpy(expire_str, pinfo->license + PluginDB::license_custid_len, PluginDB::license_expire_len);
expire_str[PluginDB::license_expire_len] = '\0';
expire_days = strtoul(expire_str, &end_ptr, 16);
if (expire_days != 0) {
time_t
time_now = time(NULL);
if ((unsigned long) time_now > expire_days * (60 * 60 * 24)) {
return PluginDB::license_expired;
}
}
return PluginDB::license_ok;
}