diff --git a/dap-sdk/crypto/include/dap_sign.h b/dap-sdk/crypto/include/dap_sign.h index b599e78a556cf8cd8a173c644c748a871d8f9e6d..9aa808415455bd2a4dc257fffcaff2e8f9e3b4fa 100755 --- a/dap-sdk/crypto/include/dap_sign.h +++ b/dap-sdk/crypto/include/dap_sign.h @@ -110,6 +110,8 @@ int dap_sign_verify (dap_sign_t * a_chain_sign, const void * a_data, const size_ dap_sign_t * dap_sign_create(dap_enc_key_t *a_key, const void * a_data, const size_t a_data_size , size_t a_output_wish_size ); +dap_sign_t * dap_sign_pack(dap_enc_key_t *a_key, const void * a_sign_ser, const size_t a_sign_ser_size, const void * a_pkey, const size_t a_pub_key_size); + size_t dap_sign_create_output_unserialized_calc_size(dap_enc_key_t * a_key,size_t a_output_wish_size ); //int dap_sign_create_output(dap_enc_key_t *a_key, const void * a_data, const size_t a_data_size // , void * a_output, size_t a_output_size ); diff --git a/dap-sdk/crypto/src/dap_sign.c b/dap-sdk/crypto/src/dap_sign.c index fea8f12eb6a982aa7b9b851f77db13304ce158f0..4b390b5258004767fce2a537e3d91017b82a6615 100755 --- a/dap-sdk/crypto/src/dap_sign.c +++ b/dap-sdk/crypto/src/dap_sign.c @@ -243,6 +243,27 @@ dap_sign_t * dap_sign_create(dap_enc_key_t *a_key, const void * a_data, } return NULL; } +/** + * @brief dap_sign_pack + * @param a_key + * @param a_sign_ser + * @param a_sign_ser_size + * @param a_pkey + * @param a_pub_key_size + * @return dap_sign_t* + */ +dap_sign_t * dap_sign_pack(dap_enc_key_t *a_key, const void * a_sign_ser, const size_t a_sign_ser_size, const void * a_pkey, const size_t a_pub_key_size) +{ + dap_sign_t * l_ret = DAP_NEW_Z_SIZE(dap_sign_t, sizeof(dap_sign_hdr_t) + a_sign_ser_size + a_pub_key_size); + // write serialized public key to dap_sign_t + memcpy(l_ret->pkey_n_sign, a_pkey, a_pub_key_size); + l_ret->header.type = dap_sign_type_from_key_type(a_key->type); + // write serialized signature to dap_sign_t + memcpy(l_ret->pkey_n_sign + a_pub_key_size, a_sign_ser, a_sign_ser_size); + l_ret->header.sign_pkey_size = (uint32_t) a_pub_key_size; + l_ret->header.sign_size = (uint32_t) a_sign_ser_size; + return l_ret; +} /** * @brief dap_sign_get_sign diff --git a/modules/net/dap_chain_node_cli.c b/modules/net/dap_chain_node_cli.c index 7e000f75d5159022319fbabb97d6e9d0a6687097..97c59fbf3180e2088ef8baf638327515ce8e232e 100644 --- a/modules/net/dap_chain_node_cli.c +++ b/modules/net/dap_chain_node_cli.c @@ -684,6 +684,7 @@ int dap_chain_node_cli_find_option_val( char** argv, int arg_start, int arg_end, { int arg_index = arg_start; const char *arg_string; + int l_ret_pos = 0; while(arg_index < arg_end) { @@ -698,6 +699,9 @@ int dap_chain_node_cli_find_option_val( char** argv, int arg_start, int arg_end, *opt_value = arg_string; return arg_index; } + // for case if opt_name exist without value + else + l_ret_pos = arg_index; } else // need only opt_name @@ -705,7 +709,7 @@ int dap_chain_node_cli_find_option_val( char** argv, int arg_start, int arg_end, } arg_index++; } - return 0; + return l_ret_pos; } /** diff --git a/modules/service/vpn/dap_chain_net_srv_vpn_cdb.c b/modules/service/vpn/dap_chain_net_srv_vpn_cdb.c index 236f73f4011b9c84c88db264ba26a49c3a96f9e2..a5dc9b5374738a345f8776092dd3ab0f5f57262f 100644 --- a/modules/service/vpn/dap_chain_net_srv_vpn_cdb.c +++ b/modules/service/vpn/dap_chain_net_srv_vpn_cdb.c @@ -103,7 +103,7 @@ int dap_chain_net_srv_vpn_cdb_init(dap_http_t * a_http) "[--acive_days <Setup active day thats left for user >]\n" "\tCreate user with login, password and some more optional fields\n\n" "vpn_cdb user update --login <Login> [--password <Password>] [--first_name <First Name] [--last_name <Last Name>] [--email <Email>]" - "[--active_days <Setup active day thats left for user >]\n" + "[--active_days <Setup active days that left for user >]\n" "\tUpdate existent user\n" "vpn_cdb user delete --login <Login>\n" "\tDelete user by login\n" @@ -113,6 +113,12 @@ int dap_chain_net_srv_vpn_cdb_init(dap_http_t * a_http) "\tCompare <Password> with stored in GDB for <Login>\n" "vpn_cdb user list\n" "\tShow all users\n" + "vpn_cdb serial generate -n <number of serial keys>] [-acive_days <active days that left for serial>]\n" + "\tGenerate new serial keys\n" + "vpn_cdb serial list [-n <How many show serial keys>] [-shift <How many skip serial keys>] [-nototal]\n" + "\tShow serial keys\n" + "vpn_cdb serial update -serial <serial keys> -acive_days <active days that left for serial>\n" + "\tEdit serial key\n" ); // Load all chain networks @@ -124,12 +130,13 @@ int dap_chain_net_srv_vpn_cdb_init(dap_http_t * a_http) } if (dap_config_get_item_bool_default( g_config,"cdb_auth","enabled",false) ){ - dap_chain_net_srv_vpn_cdb_auth_init( dap_config_get_item_str_default(g_config,"cdb_auth","domain","cdb"), - dap_config_get_item_bool_default(g_config,"cdb_auth","registration_open",false) - ); + ret = dap_chain_net_srv_vpn_cdb_auth_init( dap_config_get_item_str_default(g_config,"cdb_auth","domain","cdb"), + dap_config_get_item_str_default(g_config,"cdb_auth","mode","passwd"), + dap_config_get_item_bool_default(g_config,"cdb_auth","registration_open",false)); + if(ret<0) + return ret; dap_chain_net_srv_vpn_cdb_auth_add_proc( a_http , DB_URL ); - // Produce transaction for authorized users if (dap_config_get_item_bool_default( g_config, "cdb_auth", @@ -216,19 +223,32 @@ int dap_chain_net_srv_vpn_cdb_init(dap_http_t * a_http) return ret; } - static int s_cli_vpn_cdb(int a_argc, char ** a_argv, void *arg_func, char **a_str_reply) { const char *l_user_str = NULL; + const char *l_serial_add_param_str = NULL; int l_arg_index = 1; - int l_ret = 0; + int l_ret = -1; - dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "user", &l_user_str); + int l_user_pos = dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "user", &l_user_str); + int l_serial_pos = dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "serial", &l_serial_add_param_str); // Selected 'user' subcoummand if ( l_user_str ){ - return dap_chain_net_srv_vpn_cdb_auth_cli_cmd(l_user_str,l_arg_index, a_argc, a_argv,a_str_reply); + l_ret = 0; + return dap_chain_net_srv_vpn_cdb_auth_cli_cmd_user(l_user_str,l_arg_index, a_argc, a_argv,a_str_reply); + } + // Selected 'serial' subcoummand + else if(l_serial_add_param_str) { + l_ret = 0; + return dap_chain_net_srv_vpn_cdb_auth_cli_cmd_serial(l_serial_add_param_str, l_arg_index, a_argc, a_argv, a_str_reply); + } + else { + if(l_user_pos || l_user_pos) + dap_chain_node_cli_set_reply_text(a_str_reply, "require additional subcommand, see 'help vpn_cdb'"); + else + dap_chain_node_cli_set_reply_text(a_str_reply, "unknown subcommand, use 'user' or 'serial'", l_user_str); } return l_ret; } diff --git a/modules/service/vpn/dap_chain_net_srv_vpn_cdb_auth.c b/modules/service/vpn/dap_chain_net_srv_vpn_cdb_auth.c index 8136c7eb68cc956c6a522079f5c641d8c594fc7d..e44fbaf2f51da62c68e7c5885f0a5342098ad010 100644 --- a/modules/service/vpn/dap_chain_net_srv_vpn_cdb_auth.c +++ b/modules/service/vpn/dap_chain_net_srv_vpn_cdb_auth.c @@ -59,16 +59,20 @@ #define LOG_TAG "dap_chain_net_srv_vpn_cdb_auth" #define OP_CODE_LOGIN_INCORRECT_PSWD "0xf2" +#define OP_CODE_LOGIN_INCORRECT_SIGN "0xf2" #define OP_CODE_NOT_FOUND_LOGIN_IN_DB "0xf3" #define OP_CODE_SUBSCRIBE_EXPIRIED "0xf4" #define OP_CODE_INCORRECT_SYMOLS "0xf6" #define OP_CODE_LOGIN_INACTIVE "0xf7" +#define OP_CODE_SERIAL_ACTIVED "0xf8" dap_enc_http_callback_t s_callback_success = NULL; static char * s_domain = NULL; static char * s_group_users = NULL; +static char * s_group_serials = NULL; +static char * s_group_serials_activated = NULL; static char * s_group_password = NULL; static char * s_group_first_name = NULL; @@ -83,16 +87,18 @@ static char * s_group_ts_active_till = NULL; static char * s_salt_str = "Ijg24GAS56h3hg7hj245b"; static bool s_is_registration_open = false; +static bool s_mode_passwd = true; static int s_input_validation(const char * str); static void s_http_enc_proc(enc_http_delegate_t *a_delegate, void * a_arg); +static void s_http_enc_proc_key(enc_http_delegate_t *a_delegate, void * a_arg); static void s_http_proc(dap_http_simple_t *a_http_simple, void * arg ); /** * @brief dap_chain_net_srv_vpn_cdb_auth_init * @param a_domain * @return */ -int dap_chain_net_srv_vpn_cdb_auth_init (const char * a_domain, bool a_is_registration_open) +int dap_chain_net_srv_vpn_cdb_auth_init (const char * a_domain, const char * a_mode, bool a_is_registration_open) { s_is_registration_open = a_is_registration_open; @@ -100,10 +106,22 @@ int dap_chain_net_srv_vpn_cdb_auth_init (const char * a_domain, bool a_is_regist // Prefix for gdb groups s_group_users = dap_strdup_printf("cdb.%s.users",s_domain); + s_group_serials = dap_strdup_printf("cdb.%s.serials",s_domain); + s_group_serials_activated = dap_strdup_printf("cdb.%s.serials_activated",s_domain); // Cookie -> login s_group_cookies = dap_strdup_printf("cdb.%s.cookies",s_domain); + // mode: passwd or serial + if(!dap_strcmp(a_mode, "serial")) + s_mode_passwd = false; + else if(!dap_strcmp(a_mode, "passwd")) + s_mode_passwd = true; + else{ + log_it( L_ERROR, "Unknown cdb mode=%s", a_mode); + return -1; + } + // Login -> Password, First Name, Last Name, Email, Cookie,Timestamp Last Update, Timestamp Last Login s_group_password = dap_strdup_printf("%s.password",s_group_users); s_group_first_name = dap_strdup_printf("%s.first_name",s_group_users); @@ -133,13 +151,28 @@ void dap_chain_net_srv_vpn_cdb_auth_set_callback(dap_enc_http_callback_t a_callb s_callback_success = a_callback_success; } +/* + * Convert XXXXXXXXXXXXXXXX -> XXXX-XXXX-XXXX-XXXX + */ +static char* make_fullserial(const char * a_serial) +{ + if(dap_strlen(a_serial)!=16) + return dap_strdup(a_serial); + return dap_strdup_printf("%c%c%c%c-%c%c%c%c-%c%c%c%c-%c%c%c%c", + a_serial[0], a_serial[1], a_serial[2], a_serial[3], + a_serial[4], a_serial[5], a_serial[6], a_serial[7], + a_serial[8], a_serial[9], a_serial[10], a_serial[11], + a_serial[12], a_serial[13], a_serial[14], a_serial[15] + ); +} + /** * @brief dap_chain_net_srv_vpn_cdb_auth_check_password * @param a_login * @param a_password * @return */ -int dap_chain_net_srv_vpn_cdb_auth_check(const char * a_login, const char * a_password) +int dap_chain_net_srv_vpn_cdb_auth_check_login(const char * a_login, const char * a_password) { int l_ret; @@ -171,6 +204,104 @@ int dap_chain_net_srv_vpn_cdb_auth_check(const char * a_login, const char * a_pa return l_ret; } +/** + * @brief dap_chain_net_srv_vpn_cdb_auth_activate_serial + * @param a_login + * @param a_password + * @return + */ +int dap_chain_net_srv_vpn_cdb_auth_activate_serial(const char * a_serial_raw, const char * a_serial, const char * a_sign, const char * a_pkey) +{ + int l_ret = -1; + if(!a_sign || !a_pkey) + return -2;//OP_CODE_LOGIN_INCORRECT_SIGN + dap_serial_key_t *l_serial_key = dap_chain_net_srv_vpn_cdb_auth_get_serial_param(a_serial, NULL); + // not found + if(!l_serial_key) + return -1;//OP_CODE_NOT_FOUND_LOGIN_IN_DB + // already activated + if(l_serial_key->header.activated) { + l_ret = 0;// OK + } + else { + // check sign + int l_res = 0; + byte_t *l_pkey_raw = NULL; + size_t l_pkey_raw_size = 0; + { + // deserealize pkey + dap_enc_key_t *l_client_key = NULL; + size_t l_pkey_length = dap_strlen(a_pkey); + l_pkey_raw = DAP_NEW_Z_SIZE(byte_t, l_pkey_length); + memset(l_pkey_raw, 0, l_pkey_length); + l_pkey_raw_size = dap_enc_base64_decode(a_pkey, l_pkey_length, l_pkey_raw, DAP_ENC_DATA_TYPE_B64_URLSAFE); + l_client_key = dap_enc_key_new(DAP_ENC_KEY_TYPE_SIG_TESLA); + l_res = dap_enc_key_deserealize_pub_key(l_client_key, l_pkey_raw, l_pkey_raw_size); + // verify sign + if(!l_res) { + byte_t *l_sign_raw = NULL; + size_t l_sign_length = dap_strlen(a_sign); + l_sign_raw = DAP_NEW_Z_SIZE(byte_t, l_sign_length*2); + size_t l_sign_raw_size = dap_enc_base64_decode(a_sign, l_sign_length, l_sign_raw, DAP_ENC_DATA_TYPE_B64_URLSAFE); + dap_sign_t *l_sign = (dap_sign_t*)l_sign_raw;//dap_sign_pack(l_client_key, l_sign_raw, l_sign_raw_size, l_pkey_raw, l_pkey_length); + size_t as = dap_sign_get_size(l_sign); + size_t l_serial_len = dap_strlen(a_serial_raw); + l_res = dap_sign_verify(l_sign, a_serial_raw, l_serial_len); + DAP_DELETE(l_sign_raw); + } + //dap_enc_key_deserealize_sign + } + + // activate serial key + if(l_res==1) { + // added pkey to serial + l_serial_key->header.ext_size = l_pkey_raw_size; + l_serial_key = DAP_REALLOC(l_serial_key,dap_serial_key_len(l_serial_key)); + l_serial_key->header.activated = time(NULL); + memcpy(l_serial_key->ext, l_pkey_raw, l_pkey_raw_size); + // save updated serial + if(dap_chain_global_db_gr_set(dap_strdup(l_serial_key->header.serial), l_serial_key, + dap_serial_key_len(l_serial_key), + s_group_serials_activated)) { + dap_chain_global_db_gr_del(l_serial_key->header.serial, s_group_serials); + l_ret = 0;// OK + } + } + else{ + return -2;//OP_CODE_LOGIN_INCORRECT_SIGN + } + DAP_DELETE(l_pkey_raw); + } + DAP_DELETE(l_serial_key); + return l_ret; +} + +/** + * @brief dap_chain_net_srv_vpn_cdb_auth_check_password + * @param a_login + * @param a_password + * @return + */ +int dap_chain_net_srv_vpn_cdb_auth_check_serial(const char * a_serial, const char * a_pkey_b64) +{ + int l_ret = 0; + dap_serial_key_t *l_serial_key = dap_chain_net_srv_vpn_cdb_auth_get_serial_param(a_serial, NULL); + // not found + if(!l_serial_key) + return -1; + // inactive serial key + if(!l_serial_key->header.activated) { + l_ret = -3; + } + // check time expired + else if(l_serial_key->header.expired) { + if((l_serial_key->header.activated + l_serial_key->header.expired) < time(NULL)) + l_ret = -4; + } + DAP_DELETE(l_serial_key); + return l_ret; +} + /** * @brief s_input_validation * @param str @@ -183,12 +314,14 @@ static int s_input_validation(const char * str) static const char *nospecial="0123456789" "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - ".=@?_!#$%-"; + ".=@?_!#$%-";// /+ while(*str) // Loop until (*url) == 0. (*url) is about equivalent to url[0]. { // Can we find the character at *url in the string 'nospecial'? // If not, it's a special character and we should return 0. - if(strchr(nospecial, *str) == NULL) return(0); + if(strchr(nospecial, *str) == NULL){ + return(0); + } str++; // Jump to the next character. Adding one to a pointer moves it ahead one element. } @@ -196,7 +329,217 @@ static int s_input_validation(const char * str) } /** - * @brief dap_chain_net_srv_vpn_cdb_auth_cli_cmd + * Generate serial number like xxx-xxx-xxx + * without symbols 0,1,L,I,O + * a_group_sepa may be NULL + */ +static char* generate_serial(int a_group_count, int a_group_len, const char *a_group_sepa) +{ + size_t l_group_sepa_len = a_group_sepa ? strlen(a_group_sepa) : 0; + char *l_serial = DAP_NEW_Z_SIZE(char, a_group_count * (a_group_len + l_group_sepa_len)); + int l_serial_pos = 0; + for(int l_group_count = 0; l_group_count < a_group_count; l_group_count++) { + for(int l_group_len = 0; l_group_len < a_group_len; l_group_len++) { + uint32_t l_max_len = 'Z' - 'A' + 5; //['Z' - 'A' - 3]alpha + [10 - 2]digit + uint32_t l_value = random_uint32_t(l_max_len); + char l_sym; + if(l_value < 8) + l_sym = '2' + l_value; + // replace unused characters I,O,L + else if(l_value == 'I' - 'A' + 8) + l_sym = 'X'; + else if(l_value == 'L' - 'A' + 8) + l_sym = 'Y'; + else if(l_value == 'O' - 'A' + 8) + l_sym = 'Z'; + else + l_sym = 'A' + l_value - 8; + l_serial[l_serial_pos] = l_sym; + l_serial_pos++; + } + // copy separator to serial + if(l_group_sepa_len && l_group_count < a_group_count - 1) { + dap_stpcpy(l_serial + l_serial_pos, a_group_sepa); + l_serial_pos += l_group_sepa_len; + } + } + return l_serial; +} + + +size_t dap_serial_key_len(dap_serial_key_t *a_serial_key) +{ + if(!a_serial_key) + return 0; + return sizeof(dap_serial_key_t) + a_serial_key->header.ext_size; +} + +/** + * @brief dap_chain_net_srv_vpn_cdb_auth_cli_cmd_serial + * @param a_user_str + * @param a_arg_index + * @param a_argc + * @param a_argv + * @param a_str_reply + * @param a_group_out + * @return + */ +dap_serial_key_t* dap_chain_net_srv_vpn_cdb_auth_get_serial_param(const char *a_serial_str, const char **a_group_out) +{ + const char *l_group_out = s_group_serials_activated; + if(!a_serial_str) + return NULL; + size_t l_serial_data_len = 0; + dap_serial_key_t *l_serial_key = (dap_serial_key_t*)dap_chain_global_db_gr_get(a_serial_str, &l_serial_data_len, s_group_serials_activated); + if(!l_serial_key){ + l_serial_key = (dap_serial_key_t*)dap_chain_global_db_gr_get(a_serial_str, &l_serial_data_len, s_group_serials); + l_group_out = s_group_serials; + } + if(l_serial_data_len>=sizeof(dap_serial_key_t)){ + if(a_group_out) + *a_group_out = l_group_out; + return l_serial_key; + } + DAP_DELETE(l_serial_key); + return NULL; +} + +/** + * @brief dap_chain_net_srv_vpn_cdb_auth_cli_cmd_serial + * @param a_user_str + * @param a_arg_index + * @param a_argc + * @param a_argv + * @param a_str_reply + * @return + */ +int dap_chain_net_srv_vpn_cdb_auth_cli_cmd_serial(const char *a_serial_str, int a_arg_index, int a_argc, char ** a_argv, char **a_str_reply) +{ + int l_ret = 0; + // Command 'serial list' + if(!dap_strcmp(a_serial_str, "list")) { + const char * l_serial_count_str = NULL; + const char * l_serial_shift_str = NULL; + int l_serial_nototal = dap_chain_node_cli_find_option_val(a_argv, a_arg_index, a_argc, "-nototal", NULL); + dap_chain_node_cli_find_option_val(a_argv, a_arg_index, a_argc, "-n", &l_serial_count_str); + dap_chain_node_cli_find_option_val(a_argv, a_arg_index, a_argc, "-shift", &l_serial_shift_str); + size_t l_serial_count = l_serial_count_str ? strtoll(l_serial_count_str, NULL, 10) : 0; + size_t l_serial_shift = l_serial_shift_str ? strtoll(l_serial_shift_str, NULL, 10)+1 : 1; + size_t l_total = dap_chain_global_db_driver_count(s_group_serials, l_serial_shift); + l_serial_count = l_serial_count ? min(l_serial_count, l_total - l_serial_shift) : l_total; + dap_store_obj_t *l_obj = dap_chain_global_db_driver_cond_read(s_group_serials, l_serial_shift, &l_serial_count); + if(l_serial_count > 0) { + dap_string_t *l_keys = l_serial_count > 1 ? dap_string_new("serial keys:\n") : dap_string_new("serial key: "); + for(size_t i = 0; i < l_serial_count; i++) { + if((l_obj + i)->value_len < sizeof(dap_serial_key_t)) + continue; + dap_serial_key_t *l_serial = (dap_serial_key_t*) (l_obj + i)->value; + dap_string_append(l_keys, l_serial->header.serial); + //if(i < l_serial_count - 1) + dap_string_append(l_keys, "\n"); + } + if(!l_serial_nototal){ + char *l_total_str = dap_strdup_printf("total %u keys", l_total); + dap_string_append(l_keys, l_total_str); + DAP_DELETE(l_total_str); + //dap_chain_node_cli_set_reply_text(a_str_reply, "\ntotal %u keys", l_total); + //return 0; + } + dap_chain_node_cli_set_reply_text(a_str_reply, "%s", l_keys->str); + dap_string_free(l_keys, true); + dap_store_obj_free(l_obj, l_serial_count); + } + else + dap_chain_node_cli_set_reply_text(a_str_reply, "keys not found"); + return 0; + } + else + // Command 'serial generate' + if(!dap_strcmp(a_serial_str, "generate")) { + const char * l_serial_count_str = NULL; + const char * l_active_days_str = NULL; + dap_chain_node_cli_find_option_val(a_argv, a_arg_index, a_argc, "-n", &l_serial_count_str); + dap_chain_node_cli_find_option_val(a_argv, a_arg_index, a_argc, "-active_days", &l_active_days_str); + uint32_t l_serial_count = l_serial_count_str ? strtoll(l_serial_count_str, NULL, 10) : 1; + size_t l_active_days = l_active_days_str ? strtoll(l_active_days_str, NULL, 10) : 0; + if(l_serial_count < 1) + l_serial_count = 1; + dap_string_t *l_keys = l_serial_count > 1 ? dap_string_new("serial keys:\n") : dap_string_new("serial key: "); + for(uint32_t i = 0; i < l_serial_count; i++) { + dap_serial_key_t l_serial; + memset(&l_serial, 0, sizeof(dap_serial_key_t)); + while(1) { + char *l_serial_str = generate_serial(4, 4, "-"); + uint8_t *l_serial_str_prev = dap_chain_global_db_gr_get(l_serial_str, NULL, s_group_serials); + if(l_serial_str_prev) + DAP_DELETE(l_serial_str_prev); + else{ + strncpy(l_serial.header.serial, l_serial_str, sizeof(l_serial.header.serial)); + if(l_active_days) + l_serial.header.expired = l_active_days * 86400;// days to sec + break; + } + }; + l_serial.header.ext_size = 0; + + if(dap_chain_global_db_gr_set(dap_strdup(l_serial.header.serial), &l_serial, sizeof(l_serial), s_group_serials)) { + dap_string_append(l_keys, l_serial.header.serial); + if(i < l_serial_count - 1) + dap_string_append(l_keys, "\n"); + } + } + dap_chain_node_cli_set_reply_text(a_str_reply, "generated new %s", l_keys->str); + dap_string_free(l_keys, true); + // save gdb + dap_chain_global_db_flush(); + return 0; + } + else + // Command 'serial update' + if(!dap_strcmp(a_serial_str, "update")) { + const char * l_serial_number_str = NULL; + const char * l_active_days_str = NULL; + dap_chain_node_cli_find_option_val(a_argv, a_arg_index, a_argc, "-serial", &l_serial_number_str); + dap_chain_node_cli_find_option_val(a_argv, a_arg_index, a_argc, "-active_days", &l_active_days_str); + size_t l_active_days = l_active_days_str ? strtoll(l_active_days_str, NULL, 10) : 0; + if(!l_serial_number_str) { + dap_chain_node_cli_set_reply_text(a_str_reply, "option '-serial XXXX-XXXX-XXXX-XXXX' is not defined"); + } + else if(!l_active_days_str) { + dap_chain_node_cli_set_reply_text(a_str_reply, "option '-active_days <active days that left for serial after activation>' is not defined"); + } + else { + const char *l_group; + dap_serial_key_t *l_serial_key = dap_chain_net_srv_vpn_cdb_auth_get_serial_param(l_serial_number_str, &l_group); + if(l_serial_key){ + l_serial_key->header.expired = l_active_days; + // save updated serial + if(dap_chain_global_db_gr_set(dap_strdup(l_serial_key->header.serial), l_serial_key, dap_serial_key_len(l_serial_key), l_group)) { + dap_chain_node_cli_set_reply_text(a_str_reply, "serial '%s' successfully updated", l_serial_key->header.serial); + DAP_DELETE(l_serial_key); + // save gdb + dap_chain_global_db_flush(); + return 0; + } + else{ + dap_chain_node_cli_set_reply_text(a_str_reply, "serial '%s' can't updated", l_serial_key->header.serial); + } + DAP_DELETE(l_serial_key); + } + else{ + dap_chain_node_cli_set_reply_text(a_str_reply, "serial '%s' not found", l_serial_number_str); + } + return 0; + } + } + else { + dap_chain_node_cli_set_reply_text(a_str_reply, "unknown subcommand %s, use 'generate', 'list' or 'update'", a_serial_str); + } + return -1; +} + +/** + * @brief dap_chain_net_srv_vpn_cdb_auth_cli_cmd_user * @param a_user_str * @param a_arg_index * @param a_argc @@ -204,7 +547,7 @@ static int s_input_validation(const char * str) * @param a_str_reply * @return */ -int dap_chain_net_srv_vpn_cdb_auth_cli_cmd ( const char *a_user_str,int a_arg_index, int a_argc, char ** a_argv, char **a_str_reply) +int dap_chain_net_srv_vpn_cdb_auth_cli_cmd_user(const char *a_user_str, int a_arg_index, int a_argc, char ** a_argv, char **a_str_reply) { int l_ret = 0; dap_string_t * l_ret_str = dap_string_new(""); @@ -319,7 +662,7 @@ int dap_chain_net_srv_vpn_cdb_auth_cli_cmd ( const char *a_user_str,int a_arg const char * l_password_str = NULL; dap_chain_node_cli_find_option_val(a_argv, a_arg_index, a_argc, "--password", &l_password_str); if ( l_login_str && l_password_str) { - int l_check = dap_chain_net_srv_vpn_cdb_auth_check (l_login_str, l_password_str); + int l_check = dap_chain_net_srv_vpn_cdb_auth_check_login (l_login_str, l_password_str); if ( l_check == 0){ dap_string_append_printf(l_ret_str,"OK: Passed password check for '%s'\n",l_login_str ); l_ret = 0; @@ -438,9 +781,13 @@ static void s_http_proc(dap_http_simple_t *a_http_simple, void * arg ) l_delegate = enc_http_request_decode(a_http_simple); if(l_delegate){ - if(strcmp(l_delegate->url_path,"auth")==0){ + if(strcmp(l_delegate->url_path, "auth") == 0) { s_http_enc_proc(l_delegate, arg); - } else { + } + else if(strcmp(l_delegate->url_path, "auth_key") == 0) { + s_http_enc_proc_key(l_delegate, arg); + } + else { if(l_delegate->url_path) log_it(L_ERROR,"Wrong auth request %s",l_delegate->url_path); @@ -489,7 +836,7 @@ static void s_http_enc_proc(enc_http_delegate_t *a_delegate, void * a_arg) *l_return_code = Http_Status_OK; } - }else if(strcmp(a_delegate->in_query,"login")==0 ){ + }else if(strcmp(a_delegate->in_query,"login")==0 || strcmp(a_delegate->in_query,"serial")==0 ){ char l_login[128]={0}; char l_password[256]={0}; char l_pkey[6001]={0};//char l_pkey[4096]={0}; @@ -498,60 +845,67 @@ static void s_http_enc_proc(enc_http_delegate_t *a_delegate, void * a_arg) //log_it(L_DEBUG, "request_size=%d request_str='%s'\n",a_delegate->request_size, a_delegate->request_str); - if( sscanf(a_delegate->request_str,"%127s %255s %63s %6000s %63s",l_login,l_password,l_domain, l_pkey, l_domain2) >=4 || - sscanf(a_delegate->request_str,"%127s %255s %6000s ",l_login,l_password,l_pkey) >=3){ - log_it(L_INFO, "Trying to login with username '%s'",l_login); + // password mode + if(s_mode_passwd) { + if(sscanf(a_delegate->request_str, "%127s %255s %63s %6000s %63s", l_login, l_password, l_domain, + l_pkey, l_domain2) >= 4 || + sscanf(a_delegate->request_str, "%127s %255s %6000s ", l_login, l_password, l_pkey) >= 3) { + log_it(L_INFO, "Trying to login with username '%s'", l_login); - if(s_input_validation(l_login)==0){ - log_it(L_WARNING,"Wrong symbols in username"); - enc_http_reply_f(a_delegate, OP_CODE_INCORRECT_SYMOLS); - *l_return_code = Http_Status_BadRequest; - return; - } - if(s_input_validation(l_password)==0){ - log_it(L_WARNING,"Wrong symbols in password"); - enc_http_reply_f(a_delegate, OP_CODE_INCORRECT_SYMOLS); - *l_return_code = Http_Status_BadRequest; - return; - } - if(s_input_validation(l_pkey)==0){ - log_it(L_WARNING,"Wrong symbols in base64 pkey string"); - enc_http_reply_f(a_delegate, OP_CODE_INCORRECT_SYMOLS); - *l_return_code = Http_Status_BadRequest; - return; - } + if(s_input_validation(l_login) == 0) { + log_it(L_WARNING, "Wrong symbols in username"); + enc_http_reply_f(a_delegate, OP_CODE_INCORRECT_SYMOLS); + *l_return_code = Http_Status_BadRequest; + return; + } + if(s_input_validation(l_password) == 0) { + log_it(L_WARNING, "Wrong symbols in password"); + enc_http_reply_f(a_delegate, OP_CODE_INCORRECT_SYMOLS); + *l_return_code = Http_Status_BadRequest; + return; + } + if(s_input_validation(l_pkey) == 0) { + log_it(L_WARNING, "Wrong symbols in base64 pkey string"); + enc_http_reply_f(a_delegate, OP_CODE_INCORRECT_SYMOLS); + *l_return_code = Http_Status_BadRequest; + return; + } - int l_login_result = dap_chain_net_srv_vpn_cdb_auth_check( l_login, l_password ); - switch (l_login_result) { - case 0:{ + int l_login_result = dap_chain_net_srv_vpn_cdb_auth_check_login(l_login, l_password); + switch (l_login_result) { + case 0: { size_t l_tmp_size; - char * l_first_name = (char*) dap_chain_global_db_gr_get( l_login , &l_tmp_size,s_group_first_name); - char * l_last_name = (char*) dap_chain_global_db_gr_get( l_login , &l_tmp_size,s_group_last_name); - char * l_email = (char*) dap_chain_global_db_gr_get( l_login , &l_tmp_size,s_group_email); - dap_chain_time_t * l_ts_last_logined= (dap_chain_time_t*) dap_chain_global_db_gr_get( l_login , &l_tmp_size,s_group_ts_last_login); - dap_chain_time_t *l_ts_active_till = (dap_chain_time_t*) dap_chain_global_db_gr_get(l_login, &l_tmp_size, s_group_ts_active_till); + char * l_first_name = (char*) dap_chain_global_db_gr_get(l_login, &l_tmp_size, + s_group_first_name); + char * l_last_name = (char*) dap_chain_global_db_gr_get(l_login, &l_tmp_size, + s_group_last_name); + char * l_email = (char*) dap_chain_global_db_gr_get(l_login, &l_tmp_size, s_group_email); + dap_chain_time_t * l_ts_last_logined = (dap_chain_time_t*) dap_chain_global_db_gr_get( + l_login, &l_tmp_size, s_group_ts_last_login); + dap_chain_time_t *l_ts_active_till = (dap_chain_time_t*) dap_chain_global_db_gr_get(l_login, + &l_tmp_size, s_group_ts_active_till); enc_http_reply_f(a_delegate, - "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n" - "<auth_info>\n" - ); - enc_http_reply_f(a_delegate,"\t<login>%s</login>\n",l_login); - if ( l_first_name ) - enc_http_reply_f(a_delegate,"\t<first_name>%s</first_name>\n",l_first_name); - if( l_last_name ) - enc_http_reply_f(a_delegate,"\t<last_name>%s</last_name>\n",l_last_name); - if( l_email ) - enc_http_reply_f(a_delegate,"\t<email>%s</email>\n",l_email); - if ( l_ts_last_logined ) - enc_http_reply_f(a_delegate,"\t<ts_prev_login>%llu</ts_prev_login>\n",(long long unsigned)*l_ts_last_logined); - if ( l_ts_active_till ) - enc_http_reply_f(a_delegate,"\t<ts_active_till>%llu</ts_acyive_till>\n",(long long unsigned)*l_ts_active_till); - - if ( a_delegate->cookie ) - enc_http_reply_f(a_delegate,"\t<cookie>%s</cookie>\n",a_delegate->cookie); - dap_chain_net_srv_vpn_cdb_auth_after (a_delegate, l_login, l_pkey ) ; // Here if smbd want to add smth to the output - enc_http_reply_f(a_delegate,"</auth_info>"); - log_it(L_INFO, "Login: Successfuly logined user %s",l_login); + "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n" + "<auth_info>\n" + ); + enc_http_reply_f(a_delegate, "\t<login>%s</login>\n", l_login); + if(l_first_name) + enc_http_reply_f(a_delegate, "\t<first_name>%s</first_name>\n", l_first_name); + if(l_last_name) + enc_http_reply_f(a_delegate, "\t<last_name>%s</last_name>\n", l_last_name); + if(l_email) + enc_http_reply_f(a_delegate, "\t<email>%s</email>\n", l_email); + if(l_ts_last_logined) + enc_http_reply_f(a_delegate, "\t<ts_prev_login>%llu</ts_prev_login>\n", (long long unsigned) *l_ts_last_logined); + if(l_ts_active_till) + enc_http_reply_f(a_delegate, "\t<ts_active_till>%llu</ts_acyive_till>\n", (long long unsigned) *l_ts_active_till); + + if(a_delegate->cookie) + enc_http_reply_f(a_delegate, "\t<cookie>%s</cookie>\n", a_delegate->cookie); + dap_chain_net_srv_vpn_cdb_auth_after(a_delegate, l_login, l_pkey); // Here if smbd want to add smth to the output + enc_http_reply_f(a_delegate, "</auth_info>"); + log_it(L_INFO, "Login: Successfuly logined user %s", l_login); *l_return_code = Http_Status_OK; //log_it(L_DEBUG, "response_size='%d'",a_delegate->response_size); DAP_DELETE(l_first_name); @@ -563,33 +917,122 @@ static void s_http_enc_proc(enc_http_delegate_t *a_delegate, void * a_arg) // Update last logined l_ts_last_logined = DAP_NEW_Z(dap_chain_time_t); *l_ts_last_logined = dap_chain_time_now(); - - dap_chain_global_db_gr_set( dap_strdup( l_login), l_ts_last_logined, sizeof (time_t), s_group_ts_last_login ); - }break; + dap_chain_global_db_gr_set(dap_strdup(l_login), l_ts_last_logined, sizeof(time_t), s_group_ts_last_login); + DAP_DELETE(l_ts_last_logined); + } + break; case -1: - enc_http_reply_f( a_delegate, OP_CODE_NOT_FOUND_LOGIN_IN_DB); + enc_http_reply_f(a_delegate, OP_CODE_NOT_FOUND_LOGIN_IN_DB); *l_return_code = Http_Status_OK; break; case -2: - enc_http_reply_f( a_delegate, OP_CODE_LOGIN_INCORRECT_PSWD); + enc_http_reply_f(a_delegate, OP_CODE_LOGIN_INCORRECT_PSWD); *l_return_code = Http_Status_OK; break; case -3: - enc_http_reply_f( a_delegate, OP_CODE_LOGIN_INACTIVE ); + enc_http_reply_f(a_delegate, OP_CODE_LOGIN_INACTIVE); *l_return_code = Http_Status_OK; - break; + break; case -4: - enc_http_reply_f( a_delegate, OP_CODE_SUBSCRIBE_EXPIRIED ); + enc_http_reply_f(a_delegate, OP_CODE_SUBSCRIBE_EXPIRIED); *l_return_code = Http_Status_PaymentRequired; break; default: - log_it(L_WARNING, "Login: Unknown authorize error for login '%s'",l_login); + log_it(L_WARNING, "Login: Unknown authorize error for login '%s'", l_login); *l_return_code = Http_Status_BadRequest; break; + } + } else { + log_it(L_DEBUG, "Login: wrong auth's request body "); + *l_return_code = Http_Status_BadRequest; + } + } + // serial mode + else + { + char l_serial_tmp[64]={0}; + if(sscanf(a_delegate->request_str, "%63s %63s %6000s", l_serial_tmp, l_domain, l_pkey) >= 3) { + char *l_serial = make_fullserial(l_serial_tmp); + log_it(L_INFO, "Trying to login with serial '%s'", l_serial); + if(s_input_validation(l_serial) == 0) { + log_it(L_WARNING, "Wrong symbols in serial"); + enc_http_reply_f(a_delegate, OP_CODE_INCORRECT_SYMOLS); + *l_return_code = Http_Status_BadRequest; + DAP_DELETE(l_serial); + return; + } + if(s_input_validation(l_domain) == 0) { + log_it(L_WARNING, "Wrong symbols in l_domain"); + enc_http_reply_f(a_delegate, OP_CODE_INCORRECT_SYMOLS); + *l_return_code = Http_Status_BadRequest; + DAP_DELETE(l_serial); + return; + } + if(s_input_validation(l_pkey) == 0) { + log_it(L_WARNING, "Wrong symbols in base64 pkey string"); + enc_http_reply_f(a_delegate, OP_CODE_INCORRECT_SYMOLS); + *l_return_code = Http_Status_BadRequest; + DAP_DELETE(l_serial); + return; + } + int l_login_result = dap_chain_net_srv_vpn_cdb_auth_check_serial(l_serial, l_pkey); + log_it(L_INFO, "Check serial '%s' with code %d (Ok=0)", l_serial, l_login_result); + switch (l_login_result) { + case 0: { + size_t l_tmp_size; + enc_http_reply_f(a_delegate, + "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n" + "<auth_info>\n" + ); + enc_http_reply_f(a_delegate, "\t<serial>%s</serial>\n", l_serial); + + dap_chain_time_t * l_ts_last_logined = (dap_chain_time_t*) dap_chain_global_db_gr_get(l_serial, &l_tmp_size, s_group_ts_last_login); + dap_chain_time_t *l_ts_active_till = (dap_chain_time_t*) dap_chain_global_db_gr_get(l_serial, &l_tmp_size, s_group_ts_active_till); + if(l_ts_last_logined) + enc_http_reply_f(a_delegate, "\t<ts_prev_login>%llu</ts_prev_login>\n", (long long unsigned) *l_ts_last_logined); + if(l_ts_active_till) + enc_http_reply_f(a_delegate, "\t<ts_active_till>%llu</ts_acyive_till>\n", (long long unsigned) *l_ts_active_till); + if(a_delegate->cookie) + enc_http_reply_f(a_delegate, "\t<cookie>%s</cookie>\n", a_delegate->cookie); + dap_chain_net_srv_vpn_cdb_auth_after(a_delegate, l_serial, l_pkey); // Here if smbd want to add smth to the output + enc_http_reply_f(a_delegate, "</auth_info>"); + log_it(L_INFO, "Login: Successfuly logined user %s", l_login); + *l_return_code = Http_Status_OK; + //log_it(L_DEBUG, "response_size='%d'",a_delegate->response_size); + + DAP_DELETE(l_ts_last_logined); + DAP_DELETE(l_ts_active_till); + + // Update last logined + l_ts_last_logined = DAP_NEW_Z(dap_chain_time_t); + *l_ts_last_logined = dap_chain_time_now(); + dap_chain_global_db_gr_set(dap_strdup(l_serial), l_ts_last_logined, sizeof(time_t),s_group_ts_last_login); + DAP_DELETE(l_ts_last_logined); + } + break; + case -1: + enc_http_reply_f(a_delegate, OP_CODE_NOT_FOUND_LOGIN_IN_DB); + *l_return_code = Http_Status_OK; + break; + /*case -2: + enc_http_reply_f(a_delegate, OP_CODE_LOGIN_INCORRECT_PSWD); + *l_return_code = Http_Status_OK; + break;*/ + case -3: + enc_http_reply_f(a_delegate, OP_CODE_LOGIN_INACTIVE); + *l_return_code = Http_Status_OK; + break; + case -4: + enc_http_reply_f(a_delegate, OP_CODE_SUBSCRIBE_EXPIRIED); + *l_return_code = Http_Status_PaymentRequired; + break; + default: + log_it(L_WARNING, "Login: Unknown authorize error for login '%s'", l_login); + *l_return_code = Http_Status_BadRequest; + break; + } + DAP_DELETE(l_serial); } - }else{ - log_it(L_DEBUG, "Login: wrong auth's request body "); - *l_return_code = Http_Status_BadRequest; } }else if (s_is_registration_open && strcmp(a_delegate->in_query,"register")==0){ char l_login[128]; @@ -679,9 +1122,99 @@ static void s_http_enc_proc(enc_http_delegate_t *a_delegate, void * a_arg) } } +/** + * @brief s_http_enc_proc Auth http interface + * @param a_delegate HTTP Simple client instance + * @param a_arg Pointer to bool with okay status (true if everything is ok, by default) + */ +static void s_http_enc_proc_key(enc_http_delegate_t *a_delegate, void * a_arg) +{ + http_status_code_t * l_return_code = (http_status_code_t*) a_arg; - - - - - + if((a_delegate->request) && (strcmp(a_delegate->action, "POST") == 0)) { + if(a_delegate->in_query == NULL) { + log_it(L_WARNING, "Empty auth action"); + *l_return_code = Http_Status_BadRequest; + return; + } else { + if(strcmp(a_delegate->in_query, "serial") == 0) { + char l_serial_raw[64] = { 0 }; + char l_serial_sign[12000] = { 0 }; + char l_pkey[6001] = { 0 }; + + // only for serial mode + if(!s_mode_passwd) + { + char l_domain[64]; + if(sscanf(a_delegate->request_str, "%63s %12000s %63s %6000s", l_serial_raw, l_serial_sign, l_domain, l_pkey) >= 4) { + char *l_serial = make_fullserial(l_serial_raw); + /*size_t a1 = dap_strlen(l_serial); + size_t a2 = dap_strlen(l_serial_sign); + size_t a3 = dap_strlen(l_pkey);*/ + log_it(L_INFO, "Trying to activate with serial '%s'", l_serial); + if(s_input_validation(l_serial) == 0) { + log_it(L_WARNING, "Wrong symbols in serial"); + enc_http_reply_f(a_delegate, OP_CODE_INCORRECT_SYMOLS); + *l_return_code = Http_Status_BadRequest; + DAP_DELETE(l_serial); + return; + } + if(s_input_validation(l_pkey) == 0) { + log_it(L_WARNING, "Wrong symbols in base64 pkey string"); + enc_http_reply_f(a_delegate, OP_CODE_INCORRECT_SYMOLS); + *l_return_code = Http_Status_BadRequest; + DAP_DELETE(l_serial); + return; + } + if(s_input_validation(l_serial_sign) == 0) { + log_it(L_WARNING, "Wrong symbols in base64 serial sign"); + enc_http_reply_f(a_delegate, OP_CODE_INCORRECT_SYMOLS); + *l_return_code = Http_Status_BadRequest; + DAP_DELETE(l_serial); + return; + } + int l_activate_result = dap_chain_net_srv_vpn_cdb_auth_activate_serial(l_serial_raw, l_serial, l_serial_sign, l_pkey); + log_it(L_INFO, "Serial '%s' activated with code %d (Ok=0)", l_serial, l_activate_result); + switch (l_activate_result) { + case 0: + enc_http_reply_f(a_delegate, OP_CODE_SERIAL_ACTIVED); + *l_return_code = Http_Status_OK; + break; + case -1: + enc_http_reply_f(a_delegate, OP_CODE_NOT_FOUND_LOGIN_IN_DB); + *l_return_code = Http_Status_OK; + break; + case -2: + enc_http_reply_f(a_delegate, OP_CODE_LOGIN_INCORRECT_SIGN); + *l_return_code = Http_Status_OK; + break; + /*case -3: + enc_http_reply_f(a_delegate, OP_CODE_LOGIN_INACTIVE); + *l_return_code = Http_Status_OK; + break;*/ + case -4: + enc_http_reply_f(a_delegate, OP_CODE_SUBSCRIBE_EXPIRIED); + *l_return_code = Http_Status_PaymentRequired; + break; + default: + log_it(L_WARNING, "Login: Unknown authorize error for activate serial '%s'", l_serial); + *l_return_code = Http_Status_BadRequest; + break; + } + DAP_DELETE(l_serial); + } + else { + log_it(L_ERROR, "Registration: Wrong auth_key's request body "); + *l_return_code = Http_Status_BadRequest; + } + } + } else { + log_it(L_ERROR, "Unknown auth command was selected (query_string='%s')", a_delegate->in_query); + *l_return_code = Http_Status_BadRequest; + } + } + } else { + log_it(L_ERROR, "Wrong auth request action '%s'", a_delegate->action); + *l_return_code = Http_Status_BadRequest; + } +} diff --git a/modules/service/vpn/include/dap_chain_net_srv_vpn_cdb_auth.h b/modules/service/vpn/include/dap_chain_net_srv_vpn_cdb_auth.h index a5df0ae3e7e7c819fa59b934b263fceba11c2e1e..8682421039c334431ef333fc981e9b2e10e9e31a 100644 --- a/modules/service/vpn/include/dap_chain_net_srv_vpn_cdb_auth.h +++ b/modules/service/vpn/include/dap_chain_net_srv_vpn_cdb_auth.h @@ -27,11 +27,28 @@ #include "dap_http.h" #include "dap_enc_http.h" -int dap_chain_net_srv_vpn_cdb_auth_init (const char * a_domain, bool a_is_registration_open); +typedef struct dap_serial_key { + struct { + char serial[20]; + time_t activated; // if set, then serial is activated + time_t expired; // if zero then time no expired + int32_t os;// operating system. if zero then any operating system + size_t ext_size; + }DAP_ALIGN_PACKED header; + uint8_t ext[]; +}DAP_ALIGN_PACKED dap_serial_key_t; + +size_t dap_serial_key_len(dap_serial_key_t *a_serial_key); +dap_serial_key_t* dap_chain_net_srv_vpn_cdb_auth_get_serial_param(const char *a_serial_str, const char **a_group_out); + +int dap_chain_net_srv_vpn_cdb_auth_init (const char * a_domain, const char * a_mode, bool a_is_registration_open); void dap_chain_net_srv_vpn_cdb_auth_deinit(); void dap_chain_net_srv_vpn_cdb_auth_add_proc(dap_http_t * a_http, const char * a_url); void dap_chain_net_srv_vpn_cdb_auth_set_callback(dap_enc_http_callback_t a_callback_success); -int dap_chain_net_srv_vpn_cdb_auth_cli_cmd ( const char *a_user_str,int a_arg_index, int a_argc, char ** a_argv, char **a_str_reply); +int dap_chain_net_srv_vpn_cdb_auth_cli_cmd_serial(const char *a_user_str, int a_arg_index, int a_argc, char ** a_argv, char **a_str_reply); +int dap_chain_net_srv_vpn_cdb_auth_cli_cmd_user(const char *a_user_str, int a_arg_index, int a_argc, char ** a_argv, char **a_str_reply); -int dap_chain_net_srv_vpn_cdb_auth_check(const char * a_login, const char * a_password); +int dap_chain_net_srv_vpn_cdb_auth_check_login(const char * a_login, const char * a_password); +int dap_chain_net_srv_vpn_cdb_auth_activate_serial(const char * a_serial_raw, const char * a_serial, const char * a_sign, const char * a_pkey); +int dap_chain_net_srv_vpn_cdb_auth_check_serial(const char * a_serial, const char * a_pkey);