fix memory leak bugs
This commit is contained in:
@@ -3,9 +3,207 @@
|
||||
#include "MESA/MESA_prof_load.h"
|
||||
#include "MESA/MESA_handle_logger.h"
|
||||
#include "string.h"
|
||||
#include "cjson/cJSON.h"
|
||||
#include "ssl_utils.h"
|
||||
#include "key_keeper.h"
|
||||
|
||||
static void
|
||||
tfe_rpc_on_succ(void* result, void* user)
|
||||
struct keyring_private
|
||||
{
|
||||
struct keyring head;
|
||||
pthread_mutex_t mutex;
|
||||
size_t references;
|
||||
};
|
||||
|
||||
static struct keyring_private* keyring_new(void)
|
||||
{
|
||||
struct keyring_private *kyr;
|
||||
if (!(kyr = (struct keyring_private *)ALLOC(struct keyring_private, 1)))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (pthread_mutex_init(&kyr->mutex, NULL)) {
|
||||
free(kyr);
|
||||
return NULL;
|
||||
}
|
||||
kyr->references = 1;
|
||||
return kyr;
|
||||
}
|
||||
|
||||
|
||||
// Increment reference count.
|
||||
static void keyring_ref_inc(struct keyring_private* kyr)
|
||||
{
|
||||
pthread_mutex_lock(&kyr->mutex);
|
||||
kyr->references++;
|
||||
pthread_mutex_unlock(&kyr->mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
* Thread-safe setter functions; they copy the value (refcounts are inc'd).
|
||||
*/
|
||||
static void keyring_set_key(struct keyring_private* kyr, EVP_PKEY *key)
|
||||
{
|
||||
pthread_mutex_lock(&kyr->mutex);
|
||||
if ((kyr->head).key)
|
||||
{
|
||||
EVP_PKEY_free((kyr->head).key);
|
||||
}
|
||||
(kyr->head).key = key;
|
||||
if (key)
|
||||
{
|
||||
ssl_key_refcount_inc((kyr->head).key);
|
||||
}
|
||||
pthread_mutex_unlock(&kyr->mutex);
|
||||
}
|
||||
|
||||
static void keyring_set_cert(struct keyring_private* kry, X509 *cert)
|
||||
{
|
||||
pthread_mutex_lock(&kry->mutex);
|
||||
if ((kry->head).cert)
|
||||
{
|
||||
X509_free((kry->head).cert);
|
||||
}
|
||||
(kry->head).cert = cert;
|
||||
if (cert)
|
||||
{
|
||||
ssl_x509_refcount_inc((kry->head).cert);
|
||||
}
|
||||
pthread_mutex_unlock(&kry->mutex);
|
||||
}
|
||||
|
||||
static void keyring_set_chain(struct keyring_private* kyr, STACK_OF(X509) *chain)
|
||||
{
|
||||
pthread_mutex_lock(&kyr->mutex);
|
||||
if ((kyr->head).chain)
|
||||
{
|
||||
sk_X509_pop_free((kyr->head).chain, X509_free);
|
||||
}
|
||||
if (chain)
|
||||
{
|
||||
(kyr->head).chain = sk_X509_dup(chain);
|
||||
int i = 0;
|
||||
for (i = 0; i < sk_X509_num((kyr->head).chain); i++)
|
||||
{
|
||||
ssl_x509_refcount_inc(sk_X509_value((kyr->head).chain, i));
|
||||
}
|
||||
} else
|
||||
{
|
||||
(kyr->head).chain = NULL;
|
||||
}
|
||||
pthread_mutex_unlock(&kyr->mutex);
|
||||
}
|
||||
|
||||
static X509* transform_cert_to_x509(const char* str)
|
||||
{
|
||||
BIO *bio;
|
||||
X509 *cert;
|
||||
bio = BIO_new(BIO_s_mem());
|
||||
BIO_write(bio, (const void*)str, strnlen(str, TFE_STRING_MAX));
|
||||
cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
|
||||
return cert;
|
||||
}
|
||||
|
||||
static EVP_PKEY* transform_key_to_EVP(const char* str)
|
||||
{
|
||||
BIO *mem;
|
||||
mem = BIO_new_mem_buf(str, -1);
|
||||
EVP_PKEY* key = PEM_read_bio_PrivateKey(mem, NULL, NULL, 0);
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
static void err_out(X509* cert, EVP_PKEY* key, STACK_OF(X509)* chain)
|
||||
{
|
||||
if(cert)
|
||||
{
|
||||
X509_free(cert);
|
||||
}
|
||||
if(key)
|
||||
{
|
||||
EVP_PKEY_free(key);
|
||||
}
|
||||
if(chain)
|
||||
{
|
||||
sk_X509_pop_free(chain, X509_free);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static struct keyring* get_keyring_from_response(const char* data)
|
||||
{
|
||||
X509* cert = NULL;
|
||||
EVP_PKEY* key = NULL;
|
||||
STACK_OF(X509)* chain = NULL;
|
||||
if(data == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
cJSON* data_json = cJSON_Parse(data);
|
||||
if(data_json == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
cJSON* cert_json = NULL;
|
||||
cJSON* key_json = NULL;
|
||||
cJSON* chain_json = NULL;
|
||||
cert_json = cJSON_GetObjectItemCaseSensitive(data_json, "CERTIFICATE");
|
||||
key_json = cJSON_GetObjectItemCaseSensitive(data_json, "PRIVATE_KEY");
|
||||
chain_json = cJSON_GetObjectItemCaseSensitive(data_json, "CERTIFICATE_CHAIN");
|
||||
if (cert_json && cert_json->valuestring != NULL)
|
||||
{
|
||||
cert = transform_cert_to_x509(cert_json->valuestring);
|
||||
}
|
||||
if(cert == NULL)
|
||||
{
|
||||
err_out(cert, key, chain);
|
||||
return NULL;
|
||||
}
|
||||
if (key_json && key_json->valuestring != NULL)
|
||||
{
|
||||
key = transform_key_to_EVP(key_json->valuestring);
|
||||
}
|
||||
if(key == NULL)
|
||||
{
|
||||
err_out(cert, key, chain);
|
||||
return NULL;
|
||||
}
|
||||
if(chain_json == NULL)
|
||||
{
|
||||
err_out(cert, key, chain);
|
||||
return NULL;
|
||||
}
|
||||
cJSON* chain_cert_json = NULL;
|
||||
chain = sk_X509_new_null();
|
||||
cJSON_ArrayForEach(chain_cert_json, chain_json)
|
||||
{
|
||||
X509* chain_cert = NULL;
|
||||
if (chain_cert_json && chain_cert_json->valuestring != NULL)
|
||||
{
|
||||
chain_cert = transform_cert_to_x509(chain_cert_json->valuestring);
|
||||
}
|
||||
if(chain_cert == NULL)
|
||||
{
|
||||
err_out(cert, key, chain);
|
||||
return NULL;
|
||||
}
|
||||
if(chain_cert)
|
||||
printf("push to chain\n");
|
||||
sk_X509_push(chain, chain_cert);
|
||||
}
|
||||
struct keyring_private* _kyr= keyring_new();
|
||||
printf("cert is %s", cert == NULL ? "null" : "not null\n");
|
||||
printf("key is %s", key == NULL ? "null" : "not null\n");
|
||||
printf("chain is %s", chain == NULL ? "null" : "not null\n");
|
||||
keyring_set_cert(_kyr, cert);
|
||||
keyring_set_key(_kyr, key);
|
||||
keyring_set_chain(_kyr, chain);
|
||||
X509_free(cert);
|
||||
EVP_PKEY_free(key);
|
||||
sk_X509_pop_free(chain, X509_free);
|
||||
return &(_kyr->head);
|
||||
}
|
||||
|
||||
static void tfe_rpc_on_succ(void* result, void* user)
|
||||
{
|
||||
struct tfe_rpc_response_result* response = tfe_rpc_release(result);
|
||||
int status_code = response->status_code;
|
||||
@@ -15,24 +213,28 @@ tfe_rpc_on_succ(void* result, void* user)
|
||||
*(data+len) = '\0';
|
||||
printf("status_code is %d\n", status_code);
|
||||
printf("status_msg is %s\n", status_msg);
|
||||
printf("data is %s\n", data);
|
||||
//printf("data is %s\n", data);
|
||||
printf("len is %d\n", len);
|
||||
struct keyring* kyr = get_keyring_from_response(data);
|
||||
//add to hash table
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
tfe_rpc_on_fail(enum e_future_error err, const char * what, void * user){
|
||||
static void tfe_rpc_on_fail(enum e_future_error err, const char * what, void * user){
|
||||
printf("err is %d\n", err);
|
||||
printf("what is %s\n", what);
|
||||
printf("user is %s\n", user);
|
||||
printf("user is %s\n", (char*)user);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
char cert_store_host[TFE_STRING_MAX];
|
||||
unsigned int cert_store_port;
|
||||
const char* file_path = "./log/test_tfe_rpc.log",*host="localhost";
|
||||
void * logger = MESA_create_runtime_log_handle(file_path, RLOG_LV_INFO);
|
||||
future_promise_library_init();
|
||||
//const char* file_path = "./log/test_tfe_rpc.log",*host="localhost";
|
||||
//void * logger = MESA_create_runtime_log_handle(file_path, RLOG_LV_INFO);
|
||||
const char* profile = "./conf/tfe.conf";
|
||||
const char* section = "key_keeper";
|
||||
int keyring_id = 0;
|
||||
@@ -40,12 +242,11 @@ int main()
|
||||
MESA_load_profile_uint_def(profile, section, "cert_store_port", &cert_store_port, 80);
|
||||
struct event_base* evbase = event_base_new();
|
||||
struct future* f_tfe_rpc = future_create("tfe_rpc", tfe_rpc_on_succ, tfe_rpc_on_fail, NULL);
|
||||
struct tfe_rpc* rpc = tfe_rpc_init(NULL, NULL, logger);
|
||||
char url[TFE_STRING_MAX];
|
||||
strncpy(cert_store_host, "www.baidu.com", TFE_STRING_MAX);
|
||||
snprintf(url, TFE_STRING_MAX, "http://%s:%d/ca?host=%s&flag=1&valid=1&kering_id=%d", cert_store_host, cert_store_port, host, keyring_id);
|
||||
char sni[TFE_STRING_MAX] = "www.baidu.com";
|
||||
snprintf(url, TFE_STRING_MAX, "http://%s:%d/ca?host=%s&flag=1&valid=1&kering_id=%d", cert_store_host, cert_store_port, sni, keyring_id);
|
||||
printf("url is %s\n", url);
|
||||
tfe_rpc_async_ask(f_tfe_rpc, rpc, url, GET, DONE_CB, NULL, 0, evbase);
|
||||
event_base_dispatch(evbase);
|
||||
tfe_rpc_async_ask(f_tfe_rpc, url, GET, DONE_CB, NULL, 0, evbase);
|
||||
event_base_dispatch(evbase);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user