mirror of
https://github.com/emqx/neuron.git
synced 2026-10-17 04:40:42 +08:00
Merge pull request #889 from eeff/eeff/2.2
Pick to v2.2: fix license api
This commit is contained in:
+38
-21
@@ -36,6 +36,7 @@
|
||||
#include <time.h>
|
||||
|
||||
#include "errcodes.h"
|
||||
#include "utils/asprintf.h"
|
||||
#include "utils/log.h"
|
||||
|
||||
#include "license.h"
|
||||
@@ -81,7 +82,7 @@ static uint64_t mktimestamp(struct tm dt)
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static uint64_t get_asn1_ts(ASN1_TIME *time)
|
||||
static uint64_t get_asn1_ts(ASN1_TIME *time, char **ts_str)
|
||||
{
|
||||
struct tm t;
|
||||
const char *str = (const char *) time->data;
|
||||
@@ -97,7 +98,11 @@ static uint64_t get_asn1_ts(ASN1_TIME *time)
|
||||
&t.tm_hour, &t.tm_min, &t.tm_sec);
|
||||
}
|
||||
|
||||
neu_asprintf(ts_str, "%4d-%02d-%02d %02d:%02d:%02d", t.tm_year, t.tm_mon,
|
||||
t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
|
||||
|
||||
t.tm_mon -= 1;
|
||||
|
||||
/* Note: we did not adjust the time based on time zone information */
|
||||
return mktimestamp(t);
|
||||
}
|
||||
@@ -245,9 +250,14 @@ static int extract_license(const char *license_fname, const char *pub_key,
|
||||
|
||||
not_before = X509_get_notBefore(cert);
|
||||
not_after = X509_get_notAfter(cert);
|
||||
license->since_ = get_asn1_ts(not_before);
|
||||
license->until_ = get_asn1_ts(not_after);
|
||||
license->since_ = get_asn1_ts(not_before, &license->since_str_);
|
||||
license->until_ = get_asn1_ts(not_after, &license->until_str_);
|
||||
nlog_info("certificate expire date: %s", not_after->data);
|
||||
if (NULL == license->since_str_ || NULL == license->until_str_) {
|
||||
nlog_warn("cannot strdup");
|
||||
rv = NEU_ERR_EINTERNAL;
|
||||
goto final;
|
||||
}
|
||||
|
||||
subj = X509_get_subject_name(cert);
|
||||
for (i = 0; i < X509_NAME_entry_count(subj); i++) {
|
||||
@@ -273,6 +283,7 @@ static int extract_license(const char *license_fname, const char *pub_key,
|
||||
goto final;
|
||||
}
|
||||
|
||||
unsigned mark = 0;
|
||||
for (i = 0; i < sk_X509_EXTENSION_num(ext_list); i++) {
|
||||
ext = sk_X509_EXTENSION_value(ext_list, i);
|
||||
obj = X509_EXTENSION_get_object(ext);
|
||||
@@ -286,25 +297,36 @@ static int extract_license(const char *license_fname, const char *pub_key,
|
||||
if (0 == strcmp(buf, LICENSE_KEY_TYPE)) {
|
||||
license->type_ = scan_licese_type(val);
|
||||
if (LICENSE_TYPE_MAX == license->type_) {
|
||||
zlog_error(neuron, "invalid license type:`%s`", val);
|
||||
nlog_error("invalid license type:`%s`", val);
|
||||
rv = NEU_ERR_LICENSE_INVALID;
|
||||
}
|
||||
mark |= 0x01;
|
||||
} else if (0 == strcmp(buf, LICENSE_KEY_MAX_NODES)) {
|
||||
license->max_nodes_ = strtoul(val, NULL, 0);
|
||||
mark |= 0x02;
|
||||
} else if (0 == strcmp(buf, LICENSE_KEY_MAX_NODE_TAGS)) {
|
||||
license->max_node_tags_ = strtoul(val, NULL, 0);
|
||||
mark |= 0x04;
|
||||
} else if (0 == strcmp(buf, LICENSE_KEY_PLUGIN_FLAG)) {
|
||||
if (0 !=
|
||||
scan_bitvec(license->plugin_flag_,
|
||||
sizeof(license->plugin_flag_), val)) {
|
||||
zlog_error(neuron, "fail to scan license plugin flag:`%s`",
|
||||
val);
|
||||
nlog_error("fail to scan license plugin flag:`%s`", val);
|
||||
rv = NEU_ERR_LICENSE_INVALID;
|
||||
}
|
||||
mark |= 0x08;
|
||||
} else if (0 == strcmp(buf, LICENSE_KEY_TOKEN)) {
|
||||
license->token_ = strdup(val);
|
||||
mark |= 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
nlog_info("certification verification success");
|
||||
if (0x0F == (mark & 0x0F)) {
|
||||
nlog_info("certification verification success");
|
||||
} else {
|
||||
rv = NEU_ERR_LICENSE_INVALID;
|
||||
nlog_error("missing license key fields, mark:%u", mark);
|
||||
}
|
||||
|
||||
final:
|
||||
if (pkey)
|
||||
@@ -330,26 +352,15 @@ const char *plugin_bit_str(plugin_bit_e b)
|
||||
|
||||
void license_print(license_t *license)
|
||||
{
|
||||
struct tm tm = {};
|
||||
char start[16] = {};
|
||||
char end[16] = {};
|
||||
time_t since = license->since_;
|
||||
time_t until = license->until_;
|
||||
const char *fmt = "%Y%m%dT%H%M%S";
|
||||
|
||||
gmtime_r(&since, &tm);
|
||||
strftime(start, sizeof(start), fmt, &tm);
|
||||
gmtime_r(&until, &tm);
|
||||
strftime(end, sizeof(end), fmt, &tm);
|
||||
|
||||
char flag[sizeof(license->plugin_flag_) * 2 + 1] = {};
|
||||
print_bitvec(flag, sizeof(flag), license->plugin_flag_,
|
||||
sizeof(license->plugin_flag_));
|
||||
|
||||
nlog_info("license `%s` for %s, from %s to %s, max_nodes:%" PRIu32
|
||||
", max_node_tags:%" PRIu32 ", flag:0x%s",
|
||||
license->fname_, license_type_str(license->type_), start, end,
|
||||
license->max_nodes_, license->max_node_tags_, flag);
|
||||
license->fname_, license_type_str(license->type_),
|
||||
license->since_str_, license->until_str_, license->max_nodes_,
|
||||
license->max_node_tags_, flag);
|
||||
}
|
||||
|
||||
void license_init(license_t *license)
|
||||
@@ -363,7 +374,10 @@ void license_init(license_t *license)
|
||||
|
||||
void license_fini(license_t *license)
|
||||
{
|
||||
free(license->since_str_);
|
||||
free(license->until_str_);
|
||||
free(license->fname_);
|
||||
free(license->token_);
|
||||
}
|
||||
|
||||
license_t *license_new()
|
||||
@@ -410,7 +424,10 @@ int license_read(license_t *license, const char *fname)
|
||||
|
||||
license_print(&lic);
|
||||
|
||||
free(license->since_str_);
|
||||
free(license->until_str_);
|
||||
free(license->fname_);
|
||||
free(license->token_);
|
||||
*license = lic;
|
||||
|
||||
return rv;
|
||||
|
||||
@@ -50,6 +50,8 @@
|
||||
//
|
||||
#define LICENSE_KEY_PLUGIN_FLAG "1.3.6.1.4.1.52509.13"
|
||||
|
||||
#define LICENSE_KEY_TOKEN "1.3.6.1.4.1.52509.14"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -91,10 +93,13 @@ typedef struct {
|
||||
license_type_e type_; // license type
|
||||
char * fname_; // license file name
|
||||
uint64_t since_; // not before
|
||||
char * since_str_; //
|
||||
uint64_t until_; // not after
|
||||
char * until_str_; //
|
||||
uint32_t max_nodes_; // max number of nodes
|
||||
uint32_t max_node_tags_; // max number of tags per node
|
||||
uint8_t plugin_flag_[200 / 8]; // plugin enable/disable bits
|
||||
char * token_; // hardware token
|
||||
} license_t;
|
||||
|
||||
// Initialize to be expired with no file.
|
||||
|
||||
@@ -135,17 +135,12 @@ int copy_license_file_if_necessary()
|
||||
|
||||
void handle_get_license(nng_aio *aio)
|
||||
{
|
||||
int rv = 0;
|
||||
char * license_path = NULL;
|
||||
license_t lic = {};
|
||||
neu_json_get_license_resp_t resp = {};
|
||||
time_t since = 0;
|
||||
time_t until = 0;
|
||||
char valid_since[20] = {};
|
||||
char valid_until[20] = {};
|
||||
struct tm tm = {};
|
||||
UT_array * plugin_names = NULL;
|
||||
char * result = NULL;
|
||||
int rv = 0;
|
||||
char * license_path = NULL;
|
||||
license_t lic = {};
|
||||
neu_json_get_license_resp_t resp = {};
|
||||
UT_array * plugin_names = NULL;
|
||||
char * result = NULL;
|
||||
|
||||
VALIDATE_JWT(aio);
|
||||
|
||||
@@ -163,26 +158,10 @@ void handle_get_license(nng_aio *aio)
|
||||
goto final;
|
||||
}
|
||||
|
||||
since = license_not_before(&lic);
|
||||
gmtime_r(&since, &tm);
|
||||
if (0 ==
|
||||
strftime(valid_since, sizeof(valid_since), "%Y-%m-%d %H:%M:%S", &tm)) {
|
||||
rv = NEU_ERR_EINTERNAL;
|
||||
goto final;
|
||||
}
|
||||
|
||||
until = license_not_after(&lic);
|
||||
gmtime_r(&until, &tm);
|
||||
if (0 ==
|
||||
strftime(valid_until, sizeof(valid_until), "%Y-%m-%d %H:%M:%S", &tm)) {
|
||||
rv = NEU_ERR_EINTERNAL;
|
||||
goto final;
|
||||
}
|
||||
|
||||
resp.license_type = (char *) license_type_str(license_get_type(&lic));
|
||||
resp.valid = !license_is_expired(&lic);
|
||||
resp.valid_since = valid_since;
|
||||
resp.valid_until = valid_until;
|
||||
resp.valid_since = lic.since_str_;
|
||||
resp.valid_until = lic.until_str_;
|
||||
resp.max_nodes = license_get_max_nodes(&lic);
|
||||
resp.max_node_tags = license_get_max_node_tags(&lic);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user