Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • cellframe/cellframe-sdk
  • MIKA83/cellframe-sdk
2 results
Show changes
Showing with 1380 additions and 483 deletions
......@@ -15,8 +15,9 @@ endif()
add_library(${PROJECT_NAME} STATIC ${DAP_CHAIN_NET_SRV_VPN_SRCS} ${DAP_CHAIN_NET_SRV_VPN_HEADERS})
target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_stream dap_chain dap_chain_net dap_chain_net_srv)
target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_stream dap_stream_ch_chain_net_srv dap_chain dap_chain_crypto dap_chain_net dap_chain_net_srv)
add_definitions("-DDAP_TUN_IN_WORKER")
target_include_directories(${PROJECT_NAME} INTERFACE .)
target_include_directories(${PROJECT_NAME} PUBLIC include)
......@@ -63,15 +63,19 @@
#include "dap_chain_net.h"
#include "dap_chain_net_srv.h"
#include "dap_chain_net_srv_client.h"
#include "dap_chain_net_srv_vpn.h"
#include "dap_chain_net_srv_vpn_cmd.h"
#include "dap_chain_net_srv_vpn_cdb.h"
#include "dap_chain_net_srv_stream_session.h"
#include "dap_chain_net_vpn_client.h"
#include "dap_chain_net_vpn_client_tun.h"
#include "dap_chain_ledger.h"
#include "dap_events.h"
#define LOG_TAG "dap_chain_net_srv_vpn"
#define DAP_TUN_IN_WORKER
#define SF_MAX_EVENTS 256
typedef struct usage_client {
......@@ -144,7 +148,7 @@ static void s_tun_destroy(void);
// Stream callbacks
static void s_new(dap_stream_ch_t* ch, void* arg);
static void srv_ch_vpn_delete(dap_stream_ch_t* ch, void* arg);
static void s_ch_packet_in(dap_stream_ch_t* ch, void* arg);
static void s_ch_packet_in(dap_stream_ch_t* ch, void* a_arg);
static void s_ch_packet_out(dap_stream_ch_t* ch, void* arg);
//static int srv_ch_sf_raw_write(uint8_t op_code, const void * data, size_t data_size);
......@@ -161,12 +165,21 @@ static void m_es_tun_delete(dap_events_socket_t * a_es, void * arg);
static void m_es_tun_read(dap_events_socket_t * a_es, void * arg);
static void m_es_tun_error(dap_events_socket_t * a_es, void * arg);
bool is_dap_tun_in_worker(void)
{
#ifdef DAP_TUN_IN_WORKER
return true;
#else
return false;
#endif
}
//TODO: create .new_callback for event sockets
int s_tun_event_stream_create()
{
static dap_events_socket_callbacks_t l_s_callbacks = {
.read_callback = m_es_tun_read,
.write_callback = NULL,
.read_callback = m_es_tun_read,// for server
.write_callback = NULL,// for client
.error_callback = m_es_tun_error,
.delete_callback = m_es_tun_delete
};
......@@ -181,6 +194,137 @@ int s_tun_event_stream_create()
}
#endif
static int s_callback_client_success(dap_chain_net_srv_t * a_srv, uint32_t a_usage_id, dap_chain_net_srv_client_t * a_srv_client,
const void * a_success, size_t a_success_size)
{
if(!a_srv || !a_srv_client || !a_srv_client->ch || !a_success || a_success_size < sizeof(dap_stream_ch_chain_net_srv_pkt_success_t))
return -1;
dap_stream_ch_chain_net_srv_pkt_success_t * l_success = (dap_stream_ch_chain_net_srv_pkt_success_t*) a_success;
dap_chain_net_srv_stream_session_t * l_srv_session =
(dap_chain_net_srv_stream_session_t *) a_srv_client->ch->stream->session->_inheritor;
dap_chain_net_srv_vpn_t* l_srv_vpn = (dap_chain_net_srv_vpn_t*) a_srv->_inhertor;
//a_srv_client->ch->
dap_chain_net_t * l_net = dap_chain_net_by_id(l_success->hdr.net_id);
dap_chain_net_srv_usage_t *l_usage = dap_chain_net_srv_usage_add(l_srv_session, l_net, a_srv);
if(!l_usage)
return -2;
dap_chain_net_srv_ch_vpn_t * l_srv_ch_vpn =
(dap_chain_net_srv_ch_vpn_t*) a_srv_client->ch->stream->channel[DAP_CHAIN_NET_SRV_VPN_ID] ?
a_srv_client->ch->stream->channel[DAP_CHAIN_NET_SRV_VPN_ID]->internal : NULL;
if ( ! l_srv_ch_vpn ){
log_it(L_ERROR, "No VPN service stream channel, its closed?");
return -3;
}
l_srv_ch_vpn->usage_id = l_usage->id;
l_usage->is_active = true;
l_usage->is_free = true;
dap_stream_ch_t *l_ch = dap_chain_net_vpn_client_get_stream_ch();
int remote_sock_id = 0;//l_vpn_pkt->header.sock_id;
ch_vpn_socket_proxy_t * sf_sock = NULL;
sf_sock = DAP_NEW_Z(ch_vpn_socket_proxy_t);
sf_sock->id = remote_sock_id;
sf_sock->sock = l_ch->stream->events_socket->socket;
sf_sock->ch = l_ch;
pthread_mutex_init(&sf_sock->mutex, NULL);
dap_chain_net_srv_ch_vpn_t *f = CH_VPN(a_srv_client->ch);
//pthread_mutex_lock(&s_sf_socks_mutex);
pthread_mutex_lock(&l_srv_ch_vpn->mutex);
HASH_ADD_INT(l_srv_ch_vpn->socks, id, sf_sock);
pthread_mutex_unlock(&l_srv_ch_vpn->mutex);
//HASH_ADD_INT(CH_VPN(a_srv_client->ch)->socks, id, sf_sock);
log_it(L_DEBUG, "Added %d sock_id with sock %d to the hash table", sf_sock->id, sf_sock->sock);
//!!!//l_usage->receipt = ;
/*
dap_chain_net_srv_stream_session_t * l_srv_session = DAP_CHAIN_NET_SRV_STREAM_SESSION( a_ch->stream->session );
dap_chain_net_srv_ch_vpn_t *l_ch_vpn = CH_VPN(a_ch);
dap_chain_net_srv_usage_t * l_usage = dap_chain_net_srv_usage_find(l_srv_session, l_ch_vpn->usage_id);
if ( ! l_usage->is_active
*/
if(l_ch) { // Is present in hash table such destination address
size_t l_ipv4_str_len = 0; //dap_strlen(a_ipv4_str);
ch_vpn_pkt_t *pkt_out = (ch_vpn_pkt_t*) calloc(1, sizeof(pkt_out->header) + l_ipv4_str_len);
pkt_out->header.op_code = VPN_PACKET_OP_CODE_VPN_ADDR_REQUEST;
//pkt_out->header.sock_id = l_stream->stream->events_socket->socket;
//pkt_out->header.op_connect.addr_size = l_ipv4_str_len; //remoteAddrBA.length();
//pkt_out->header.op_connect.port = a_port;
//memcpy(pkt_out->data, a_ipv4_str, l_ipv4_str_len);
sf_sock->pkt_out[sf_sock->pkt_out_size] = pkt_out;
sf_sock->pkt_out_size++;
dap_stream_ch_pkt_write(l_ch, DAP_STREAM_CH_PKT_TYPE_NET_SRV_VPN_DATA, pkt_out,
pkt_out->header.op_data.data_size + sizeof(pkt_out->header));
dap_stream_ch_set_ready_to_write(l_ch, true);
//DAP_DELETE(pkt_out);
}
// usage is present, we've accepted packets
dap_stream_ch_set_ready_to_read( l_srv_ch_vpn->ch , true );
return 0;
}
static int callback_client_sign_request(dap_chain_net_srv_t * a_srv, uint32_t a_usage_id, dap_chain_net_srv_client_t * a_srv_client,
const void **a_receipt, size_t a_receipt_size)
{
dap_chain_datum_tx_receipt_t *l_receipt = (dap_chain_datum_tx_receipt_t*)*a_receipt;
char *l_gdb_group = dap_strdup_printf("local.%s", DAP_CHAIN_NET_SRV_VPN_CDB_GDB_PREFIX);
char *l_wallet_name = dap_chain_global_db_gr_get(dap_strdup("wallet_name"), NULL, l_gdb_group);
dap_chain_wallet_t *l_wallet = dap_chain_wallet_open(l_wallet_name, dap_chain_wallet_get_path(g_config));
if(l_wallet) {
dap_enc_key_t *l_enc_key = dap_chain_wallet_get_key(l_wallet, 0);
dap_chain_datum_tx_receipt_sign_add(&l_receipt, dap_chain_datum_tx_receipt_get_size(l_receipt), l_enc_key);
dap_chain_wallet_close(l_wallet);
*a_receipt = l_receipt;
}
DAP_DELETE(l_gdb_group);
DAP_DELETE(l_wallet_name);
return 0;
}
/*
* Client VPN init (after dap_chain_net_srv_vpn_init!)
*/
int dap_chain_net_srv_client_vpn_init(dap_config_t * g_config) {
dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_VPN_ID };
dap_chain_net_srv_t *l_srv = dap_chain_net_srv_get(l_uid);
dap_chain_net_srv_vpn_t* l_srv_vpn = l_srv ? (dap_chain_net_srv_vpn_t*) l_srv->_inhertor : NULL;
// if vpn server disabled
if(!l_srv_vpn) {
l_srv_vpn = DAP_NEW_Z(dap_chain_net_srv_vpn_t);
if(l_srv)
l_srv->_inhertor = l_srv_vpn;
dap_stream_ch_proc_add(DAP_STREAM_CH_ID_NET_SRV_VPN, s_new, srv_ch_vpn_delete, s_ch_packet_in, s_ch_packet_out);
pthread_mutex_init(&s_sf_socks_mutex, NULL);
pthread_cond_init(&s_sf_socks_cond, NULL);
}
if(!dap_chain_net_srv_client_init(l_uid, s_callback_requested,
s_callback_response_success, s_callback_response_error,
s_callback_receipt_next_success,
s_callback_client_success,
callback_client_sign_request,
l_srv_vpn)) {
l_srv = dap_chain_net_srv_get(l_uid);
//l_srv_vpn = l_srv ? (dap_chain_net_srv_vpn_t*)l_srv->_inhertor : NULL;
//l_srv_vpn->parent = l_srv;
l_srv->_inhertor = l_srv_vpn;
}
l_srv_vpn->parent = (dap_chain_net_srv_t*) l_srv;
return 0;
}
/**
* @brief dap_stream_ch_vpn_init Init actions for VPN stream channel
* @param vpn_addr Zero if only client mode. Address if the node shares its local VPN
......@@ -300,9 +444,9 @@ int dap_chain_net_srv_vpn_init(dap_config_t * g_config) {
}
}
int retVal = dap_chain_net_srv_vpn_cmd_init();
return retVal;
return 0;
//int retVal = dap_chain_net_srv_vpn_cmd_init();
//return retVal;
}
return -1;
}
......@@ -636,101 +780,6 @@ static ch_vpn_pkt_t* srv_ch_sf_raw_read()
return ret;
}
/**
* @brief stream_sf_packet_out Packet Out Ch callback
* @param ch
* @param arg
*/
static void s_ch_packet_out(dap_stream_ch_t* a_ch, void* a_arg)
{
(void) a_arg;
ch_vpn_socket_proxy_t * cur, *tmp;
dap_chain_net_srv_stream_session_t * l_srv_session = DAP_CHAIN_NET_SRV_STREAM_SESSION( a_ch->stream->session );
dap_chain_net_srv_ch_vpn_t *l_ch_vpn = CH_VPN(a_ch);
dap_chain_net_srv_usage_t * l_usage = dap_chain_net_srv_usage_find(l_srv_session, l_ch_vpn->usage_id);
if ( ! l_usage){
log_it(L_NOTICE, "No active usage in list, possible disconnected. Send nothin on this channel");
dap_stream_ch_set_ready_to_write(a_ch,false);
dap_stream_ch_set_ready_to_read(a_ch,false);
return;
}
if ( ! l_usage->is_active ){
log_it(L_INFO, "Usage inactivation: switch off packet output channel");
dap_stream_ch_set_ready_to_write(a_ch,false);
dap_stream_ch_set_ready_to_read(a_ch,false);
if (l_usage->clients)
dap_stream_ch_pkt_write( l_usage->clients->ch , DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_NOTIFY_STOPPED , NULL, 0 );
return;
}
if ( (! l_usage->is_free) && (! l_usage->receipt) ){
log_it(L_WARNING, "No active receipt, switching off");
dap_stream_ch_set_ready_to_write(a_ch,false);
dap_stream_ch_set_ready_to_read(a_ch,false);
if (l_usage->clients)
dap_stream_ch_pkt_write( l_usage->clients->ch , DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_NOTIFY_STOPPED , NULL, 0 );
return;
}
bool l_is_smth_out = false;
// log_it(L_DEBUG,"Socket forwarding packet out callback: %u sockets in hashtable", HASH_COUNT(CH_SF(ch)->socks) );
HASH_ITER(hh, l_ch_vpn->socks , cur, tmp)
{
bool l_signal_to_break = false;
pthread_mutex_lock(&(cur->mutex));
size_t i;
//log_it(L_DEBUG, "Socket with id %d has %u packets in output buffer", cur->id, cur->pkt_out_size);
if(cur->pkt_out_size) {
for(i = 0; i < cur->pkt_out_size; i++) {
ch_vpn_pkt_t * pout = cur->pkt_out[i];
if(pout) {
size_t l_wrote_size;
if((l_wrote_size = dap_stream_ch_pkt_write(a_ch, DAP_STREAM_CH_PKT_TYPE_NET_SRV_VPN_DATA, pout,
pout->header.op_data.data_size + sizeof(pout->header)))>0 ) {
l_is_smth_out = true;
DAP_DELETE(pout);
cur->pkt_out[i] = NULL;
} else {
//log_it(L_WARNING,
// "Buffer is overflowed, breaking cycle to let the upper level cycle drop data to the output socket");
l_is_smth_out = true;
l_signal_to_break = true;
break;
}
s_update_limits (a_ch, l_srv_session, l_usage,l_wrote_size );
}
}
}
if(l_signal_to_break) {
pthread_mutex_unlock(&(cur->mutex));
break;
}
cur->pkt_out_size = 0;
if(cur->signal_to_delete) {
log_it(L_NOTICE, "Socket id %d got signal to be deleted", cur->id);
pthread_mutex_lock(&( CH_VPN(a_ch)->mutex));
HASH_DEL(l_ch_vpn->socks, cur);
pthread_mutex_unlock(&( CH_VPN(a_ch)->mutex));
pthread_mutex_lock(&(s_sf_socks_mutex));
HASH_DELETE(hh2, sf_socks, cur);
HASH_DELETE(hh_sock, sf_socks_client, cur);
pthread_mutex_unlock(&(s_sf_socks_mutex));
pthread_mutex_unlock(&(cur->mutex));
s_ch_proxy_delete(cur);
} else
pthread_mutex_unlock(&(cur->mutex));
}
if(l_is_smth_out) {
a_ch->stream->conn_http->state_write = DAP_HTTP_CLIENT_STATE_DATA;
}
dap_stream_ch_set_ready_to_write(a_ch, l_is_smth_out);
}
/**
* @brief s_check_limits
* @param a_ch
......@@ -836,14 +885,27 @@ static void s_update_limits(dap_stream_ch_t * a_ch ,
}
static void send_pong_pkt(dap_stream_ch_t* a_ch)
{
// log_it(L_DEBUG,"---------------------------------- PONG!");
ch_vpn_pkt_t *pkt_out = (ch_vpn_pkt_t*) calloc(1, sizeof(pkt_out->header));
pkt_out->header.op_code = VPN_PACKET_OP_CODE_PONG;
dap_stream_ch_pkt_write(a_ch, 'd', pkt_out,
pkt_out->header.op_data.data_size + sizeof(pkt_out->header));
dap_stream_ch_set_ready_to_write(a_ch, true);
free(pkt_out);
}
/**
* @brief stream_sf_packet_in
* @param ch
* @param arg
*/
void s_ch_packet_in(dap_stream_ch_t* a_ch, void* arg)
void s_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
{
dap_stream_ch_pkt_t * pkt = (dap_stream_ch_pkt_t *) arg;
dap_stream_ch_pkt_t * l_pkt = (dap_stream_ch_pkt_t *) a_arg;
dap_chain_net_srv_stream_session_t * l_srv_session = DAP_CHAIN_NET_SRV_STREAM_SESSION (a_ch->stream->session );
dap_chain_net_srv_ch_vpn_t *l_ch_vpn = CH_VPN(a_ch);
dap_chain_net_srv_usage_t * l_usage = dap_chain_net_srv_usage_find(l_srv_session, l_ch_vpn->usage_id);
......@@ -865,18 +927,33 @@ void s_ch_packet_in(dap_stream_ch_t* a_ch, void* arg)
// TODO move address leasing to this structure
dap_chain_net_srv_vpn_t * l_srv_vpn =(dap_chain_net_srv_vpn_t *) l_usage->service->_inhertor;
if ( pkt->hdr.type == DAP_STREAM_CH_PKT_TYPE_NET_SRV_VPN_CLIENT )
dap_chain_net_vpn_client_pkt_in( a_ch, pkt);
else {
//if ( pkt->hdr.type == DAP_STREAM_CH_PKT_TYPE_NET_SRV_VPN_CLIENT )
// dap_chain_net_vpn_client_pkt_in( a_ch, l_pkt);
if(l_pkt->hdr.type == DAP_STREAM_CH_PKT_TYPE_NET_SRV_VPN_DATA) {
static bool client_connected = false;
ch_vpn_pkt_t * l_vpn_pkt = (ch_vpn_pkt_t *) pkt->data;
size_t l_vpn_pkt_size = pkt->hdr.size - sizeof (l_vpn_pkt->header);
ch_vpn_pkt_t * l_vpn_pkt = (ch_vpn_pkt_t *) l_pkt->data;
size_t l_vpn_pkt_size = l_pkt->hdr.size - sizeof (l_vpn_pkt->header);
int remote_sock_id = l_vpn_pkt->header.sock_id;
//log_it(L_DEBUG, "Got SF packet with id %d op_code 0x%02x", remote_sock_id, sf_pkt->header.op_code);
if(l_vpn_pkt->header.op_code >= 0xb0) { // Raw packets
switch (l_vpn_pkt->header.op_code) {
case VPN_PACKET_OP_CODE_PING:
a_ch->stream->events_socket->last_ping_request = time(NULL);
send_pong_pkt(a_ch);
break;
case VPN_PACKET_OP_CODE_PONG:
a_ch->stream->events_socket->last_ping_request = time(NULL);
break;
// for client
case VPN_PACKET_OP_CODE_VPN_ADDR_REPLY: { // Assigned address for peer
if(ch_sf_tun_addr_leased(CH_VPN(a_ch), l_vpn_pkt, l_vpn_pkt_size) < 0) {
log_it(L_ERROR, "Can't create tun");
}
}
break;
// for server
case VPN_PACKET_OP_CODE_VPN_ADDR_REQUEST: { // Client request after L3 connection the new IP address
log_it(L_INFO, "Received address request ");
if ( l_ch_vpn->addr_ipv4.s_addr ){
......@@ -983,6 +1060,14 @@ void s_ch_packet_in(dap_stream_ch_t* a_ch, void* arg)
}
}
break;
// for client only
case VPN_PACKET_OP_CODE_VPN_RECV:{
a_ch->stream->events_socket->last_ping_request = time(NULL); // not ping, but better ;-)
ch_sf_tun_send(CH_VPN(a_ch), l_vpn_pkt->data, l_vpn_pkt->header.op_data.data_size);
}
break;
// for servier only
case VPN_PACKET_OP_CODE_VPN_SEND: {
struct in_addr in_saddr, in_daddr;
in_saddr.s_addr = ((struct iphdr*) l_vpn_pkt->data)->saddr;
......@@ -1075,7 +1160,7 @@ void s_ch_packet_in(dap_stream_ch_t* a_ch, void* arg)
pthread_mutex_unlock(&sf_sock->mutex);
}
//log_it(L_INFO, "Send action from %d sock_id (sf_packet size %lu, ch packet size %lu, have sent %d)"
// , sf_sock->id, sf_pkt->header.op_data.data_size, pkt->hdr.size, ret);
// , sf_sock->id, sf_pkt->header.op_data.data_size, l_pkt->hdr.size, ret);
}
break;
case VPN_PACKET_OP_CODE_DISCONNECT: {
......@@ -1197,6 +1282,101 @@ void s_ch_packet_in(dap_stream_ch_t* a_ch, void* arg)
}
}
/**
* @brief stream_sf_packet_out Packet Out Ch callback
* @param ch
* @param arg
*/
static void s_ch_packet_out(dap_stream_ch_t* a_ch, void* a_arg)
{
(void) a_arg;
ch_vpn_socket_proxy_t * cur, *tmp;
dap_chain_net_srv_stream_session_t * l_srv_session = DAP_CHAIN_NET_SRV_STREAM_SESSION( a_ch->stream->session );
dap_chain_net_srv_ch_vpn_t *l_ch_vpn = CH_VPN(a_ch);
dap_chain_net_srv_usage_t * l_usage = dap_chain_net_srv_usage_find(l_srv_session, l_ch_vpn->usage_id);
if ( ! l_usage){
log_it(L_NOTICE, "No active usage in list, possible disconnected. Send nothin on this channel");
dap_stream_ch_set_ready_to_write(a_ch,false);
dap_stream_ch_set_ready_to_read(a_ch,false);
return;
}
if ( ! l_usage->is_active ){
log_it(L_INFO, "Usage inactivation: switch off packet output channel");
dap_stream_ch_set_ready_to_write(a_ch,false);
dap_stream_ch_set_ready_to_read(a_ch,false);
if (l_usage->clients)
dap_stream_ch_pkt_write( l_usage->clients->ch , DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_NOTIFY_STOPPED , NULL, 0 );
return;
}
if ( (! l_usage->is_free) && (! l_usage->receipt) ){
log_it(L_WARNING, "No active receipt, switching off");
dap_stream_ch_set_ready_to_write(a_ch,false);
dap_stream_ch_set_ready_to_read(a_ch,false);
if (l_usage->clients)
dap_stream_ch_pkt_write( l_usage->clients->ch , DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_NOTIFY_STOPPED , NULL, 0 );
return;
}
bool l_is_smth_out = false;
// log_it(L_DEBUG,"Socket forwarding packet out callback: %u sockets in hashtable", HASH_COUNT(CH_SF(ch)->socks) );
HASH_ITER(hh, l_ch_vpn->socks , cur, tmp)
{
bool l_signal_to_break = false;
pthread_mutex_lock(&(cur->mutex));
size_t i;
//log_it(L_DEBUG, "Socket with id %d has %u packets in output buffer", cur->id, cur->pkt_out_size);
if(cur->pkt_out_size) {
for(i = 0; i < cur->pkt_out_size; i++) {
ch_vpn_pkt_t * pout = cur->pkt_out[i];
if(pout) {
size_t l_wrote_size;
if((l_wrote_size = dap_stream_ch_pkt_write(a_ch, DAP_STREAM_CH_PKT_TYPE_NET_SRV_VPN_DATA, pout,
pout->header.op_data.data_size + sizeof(pout->header)))>0 ) {
l_is_smth_out = true;
DAP_DELETE(pout);
cur->pkt_out[i] = NULL;
} else {
log_it(L_WARNING, "Buffer is overflowed, breaking cycle to let the upper level cycle drop data to the output socket");
l_is_smth_out = true;
l_signal_to_break = true;
break;
}
s_update_limits (a_ch, l_srv_session, l_usage,l_wrote_size );
}
}
}
if(l_signal_to_break) {
pthread_mutex_unlock(&(cur->mutex));
break;
}
cur->pkt_out_size = 0;
if(cur->signal_to_delete) {
log_it(L_NOTICE, "Socket id %d got signal to be deleted", cur->id);
pthread_mutex_lock(&( CH_VPN(a_ch)->mutex));
HASH_DEL(l_ch_vpn->socks, cur);
pthread_mutex_unlock(&( CH_VPN(a_ch)->mutex));
pthread_mutex_lock(&(s_sf_socks_mutex));
HASH_DELETE(hh2, sf_socks, cur);
HASH_DELETE(hh_sock, sf_socks_client, cur);
pthread_mutex_unlock(&(s_sf_socks_mutex));
pthread_mutex_unlock(&(cur->mutex));
s_ch_proxy_delete(cur);
} else
pthread_mutex_unlock(&(cur->mutex));
}
if(l_is_smth_out) {
if(a_ch->stream->conn_http)
a_ch->stream->conn_http->state_write = DAP_HTTP_CLIENT_STATE_DATA;
}
dap_stream_ch_set_ready_to_write(a_ch, l_is_smth_out);
}
/**
* @brief stream_sf_disconnect
* @param sf
......@@ -1457,6 +1637,11 @@ void m_es_tun_delete(dap_events_socket_t * a_es, void * arg)
s_tun_destroy();
}
void m_es_tun_write(dap_events_socket_t * a_es, void * arg)
{
}
void m_es_tun_read(dap_events_socket_t * a_es, void * arg)
{
const static int tun_MTU = 100000; /// TODO Replace with detection of MTU size
......
......@@ -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
// Selected 'user' subcommand
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;
}
......
......@@ -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;
}
}
#include <dap_chain_node_cli.h>
#include "dap_chain_node_cli_cmd.h"
#include "dap_chain_net_srv_vpn_cmd.h"
#include "dap_chain_net_vpn_client.h"
/**
* vpn_client command
*
* VPN client control
*/
int com_vpn_client(int a_argc, char ** a_argv, void *arg_func, char **a_str_reply)
{
#ifndef _WIN32
enum {
CMD_NONE, CMD_START, CMD_STOP, CMD_STATUS
};
int l_arg_index = 1;
// find net
dap_chain_net_t *l_net = NULL;
if(dap_chain_node_cli_cmd_values_parse_net_chain(&l_arg_index, a_argc, a_argv, a_str_reply, NULL, &l_net) < 0)
return -2;
int cmd_num = CMD_NONE;
if(dap_chain_node_cli_find_option_val(a_argv, l_arg_index, min(a_argc, l_arg_index + 1), "start", NULL)) {
cmd_num = CMD_START;
}
else if(dap_chain_node_cli_find_option_val(a_argv, l_arg_index, min(a_argc, l_arg_index + 1), "stop", NULL)) {
cmd_num = CMD_STOP;
}
else if(dap_chain_node_cli_find_option_val(a_argv, l_arg_index, min(a_argc, l_arg_index + 1), "status", NULL)) {
cmd_num = CMD_STATUS;
}
if(cmd_num == CMD_NONE) {
if(!a_argv[1])
dap_chain_node_cli_set_reply_text(a_str_reply, "invalid parameters");
else
dap_chain_node_cli_set_reply_text(a_str_reply, "parameter %s not recognized", a_argv[1]);
return -1;
}
switch (cmd_num)
{
case CMD_START: {
const char * l_str_addr = NULL; // for example, "192.168.100.93"
const char * l_str_port = NULL; // for example, "8079"
dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-addr", &l_str_addr);
if(!l_str_addr) {
dap_chain_node_cli_set_reply_text(a_str_reply,
"VPN server address not defined, use -addr <vpn server ipv4 address> parameter");
break;
}
dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-port", &l_str_port);
int l_srv_port = (l_str_port) ? (int) strtoll(l_str_port, 0, 10) : 0;
if(!l_srv_port) {
dap_chain_node_cli_set_reply_text(a_str_reply,
"VPN server port not defined, use -port <vpn server port> parameter");
break;
}
int l_res = dap_chain_net_vpn_client_start(l_net, l_str_addr, NULL, l_srv_port);
switch (l_res) {
case 0:
dap_chain_node_cli_set_reply_text(a_str_reply, "VPN client started successfully");
break;
case 1:
dap_chain_node_cli_set_reply_text(a_str_reply, "VPN client already started");
break;
case -2:
case -3:
dap_chain_node_cli_set_reply_text(a_str_reply, "Can't connect to VPN server");
break;
default:
dap_chain_node_cli_set_reply_text(a_str_reply, "Can't start VPN client");
break;
}
return l_res;
}
break;
case CMD_STOP: {
int res = dap_chain_net_vpn_client_stop();
if(!res)
dap_chain_node_cli_set_reply_text(a_str_reply, "VPN client stopped successfully");
else
dap_chain_node_cli_set_reply_text(a_str_reply, "VPN client not stopped");
return res;
}
//break;
case CMD_STATUS:
switch (dap_chain_net_vpn_client_status()) {
// switch (0){
case 0:
dap_chain_node_cli_set_reply_text(a_str_reply, "VPN client stopped");
return 0;
case 1:
dap_chain_node_cli_set_reply_text(a_str_reply, "VPN client started");
return 0;
case -1:
dap_chain_node_cli_set_reply_text(a_str_reply, "Can't get VPN state");
return -1;
}
break;
}
#endif
return 0;
}
int dap_chain_net_srv_vpn_cmd_init()
{
dap_chain_node_cli_cmd_item_create ("vpn_client", com_vpn_client, NULL, "VPN client control",
"vpn_client [start -addr <server address> -port <server port>| stop | status]\n");
return 0;
}
......@@ -26,6 +26,7 @@
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <time.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
......@@ -42,19 +43,30 @@
#include "dap_chain_node_client.h"
#include "dap_stream_ch_proc.h"
//#include "dap_stream_ch_chain_net_srv.h"
#include "dap_chain_common.h"
#include "dap_chain_mempool.h"
#include "dap_chain_net_srv_vpn.h"
#include "dap_chain_net_srv_vpn_cdb.h" // for DAP_CHAIN_NET_SRV_VPN_CDB_GDB_PREFIX
#include "dap_chain_net_vpn_client.h"
#include "dap_stream_ch_pkt.h"
#include "dap_stream_ch_chain_net_srv.h"
//#include "dap_stream_ch_chain_net_srv.h"
#include "dap_chain_net_vpn_client_tun.h"
//#include "dap_chain_net_vpn_client_data.h"
typedef enum dap_http_client_state {
DAP_HTTP_CLIENT_STATE_NONE = 0,
DAP_HTTP_CLIENT_STATE_START = 1,
DAP_HTTP_CLIENT_STATE_HEADERS = 2,
DAP_HTTP_CLIENT_STATE_DATA = 3
} dap_http_client_state_t;
/*
#if !defined( dap_http_client_state_t )
typedef enum dap_http_client_state {
DAP_HTTP_CLIENT_STATE_NONE = 0,
DAP_HTTP_CLIENT_STATE_START = 1,
DAP_HTTP_CLIENT_STATE_HEADERS = 2,
DAP_HTTP_CLIENT_STATE_DATA = 3
} dap_http_client_state_t;
#endif
*/
#define LOG_TAG "vpn_client"
......@@ -72,44 +84,223 @@ dap_stream_ch_t* dap_chain_net_vpn_client_get_stream_ch(void)
{
if(!s_vpn_client)
return NULL;
dap_stream_ch_t *l_stream = dap_client_get_stream_ch(s_vpn_client->client, DAP_STREAM_CH_ID_NET_SRV_VPN );
dap_stream_ch_t *l_stream = dap_client_get_stream_ch(s_vpn_client->client, DAP_STREAM_CH_ID_NET_SRV_VPN);
return l_stream;
}
/// TODO convert below callback to processor of stage
/*
void s_stage_callback()
void s_stage_callback()
{
char* l_full_path = NULL;
const char * l_path = "stream";
const char *l_suburl = "globaldb";
int l_full_path_size = snprintf(l_full_path, 0, "%s/%s?session_id=%s", DAP_UPLINK_PATH_STREAM, l_suburl,
dap_client_get_stream_id(a_client_pvt->client));
l_full_path = DAP_NEW_Z_SIZE(char, l_full_path_size + 1);
snprintf(l_full_path, l_full_path_size + 1, "%s/%s?session_id=%s", DAP_UPLINK_PATH_STREAM, l_suburl,
dap_client_get_stream_id(a_client_pvt->client));
//dap_client_request(a_client_pvt->client, l_full_path, "12345", 0, m_stream_response, m_stream_error);
const char *l_add_str = "";
// if connect to vpn server
const char l_active_vpn_channels[] = { VPN_CLIENT_ID, 0 };
if(!dap_strcmp(a_client_pvt->active_channels, l_active_vpn_channels))
l_add_str = "\r\nService-Key: test";
{
char *l_message = dap_strdup_printf("GET /%s HTTP/1.1\r\nHost: %s:%d%s\r\n\r\n",
l_full_path, a_client_pvt->uplink_addr, a_client_pvt->uplink_port, l_add_str);
size_t l_message_size = dap_strlen(l_message);
int count = send(a_client_pvt->stream_socket, l_message, l_message_size, 0);
DAP_DELETE(l_message);
}
DAP_DELETE(l_full_path);
}*/
/**
* Get tx_cond_hash
*
* return: 0 Ok, 1 Already started, <0 Error
*/
static dap_chain_hash_fast_t* dap_chain_net_vpn_client_tx_cond_hash(dap_chain_net_t *a_net,
dap_chain_wallet_t *a_wallet, const char *a_token_ticker, uint64_t a_value_datoshi)
{
char* l_full_path = NULL;
const char * l_path = "stream";
const char *l_suburl = "globaldb";
int l_full_path_size = snprintf(l_full_path, 0, "%s/%s?session_id=%s", DAP_UPLINK_PATH_STREAM, l_suburl,
dap_client_get_stream_id(a_client_pvt->client));
l_full_path = DAP_NEW_Z_SIZE(char, l_full_path_size + 1);
snprintf(l_full_path, l_full_path_size + 1, "%s/%s?session_id=%s", DAP_UPLINK_PATH_STREAM, l_suburl,
dap_client_get_stream_id(a_client_pvt->client));
//dap_client_request(a_client_pvt->client, l_full_path, "12345", 0, m_stream_response, m_stream_error);
const char *l_add_str = "";
// if connect to vpn server
const char l_active_vpn_channels[] = { VPN_CLIENT_ID, 0 };
if(!dap_strcmp(a_client_pvt->active_channels, l_active_vpn_channels))
l_add_str = "\r\nService-Key: test";
uint8_t *l_pkey_b64 = NULL;
size_t l_pkey_b64_size = 0;
// Try to load from gdb
size_t l_gdb_group_size = 0;
char *l_gdb_group = dap_strdup_printf("local.%s", DAP_CHAIN_NET_SRV_VPN_CDB_GDB_PREFIX);
dap_chain_hash_fast_t *l_tx_cond_hash = (dap_chain_hash_fast_t*) dap_chain_global_db_gr_get(
dap_strdup("client_tx_cond_hash"), &l_gdb_group_size, l_gdb_group);
time_t l_tx_cond_ts = 0;
// Check for entry size
if(l_tx_cond_hash && l_gdb_group_size && l_gdb_group_size != sizeof(dap_chain_hash_fast_t)) {
log_it(L_ERROR, "Wrong size of tx condition on database (%zd but expected %zd), may be old entry",
l_gdb_group_size, sizeof(dap_chain_hash_fast_t));
l_tx_cond_hash = NULL;
}
// If loaded lets check is it spent or not
if(l_tx_cond_hash) {
log_it(L_DEBUG, "2791: Search for unspent tx, net %s", a_net);
dap_chain_datum_tx_t *l_tx = dap_chain_net_get_tx_by_hash(a_net, l_tx_cond_hash, TX_SEARCH_TYPE_NET_UNSPENT);
if(!l_tx) { // If not found - all outs are used. Create new one
// pass all chains
l_tx = dap_chain_net_get_tx_by_hash(a_net, l_tx_cond_hash, TX_SEARCH_TYPE_NET);
DAP_DELETE(l_tx_cond_hash);
l_tx_cond_hash = NULL;
if(l_tx) {
l_tx_cond_ts = (time_t) l_tx->header.ts_created;
log_it(L_DEBUG, "2791: got some tx, created %d", l_tx->header.ts_created);
}
}
}
if(l_tx_cond_hash)
return l_tx_cond_hash;
//l_pkey_b64 = (char*) dap_chain_global_db_gr_get(dap_strdup("client_pkey"), &l_gdb_group_size, l_gdb_group);
dap_enc_key_t *l_enc_key = NULL;
if(a_wallet) {
l_enc_key = dap_chain_wallet_get_key(a_wallet, 0);
}
// use default pkey
else {
{
char *l_message = dap_strdup_printf("GET /%s HTTP/1.1\r\nHost: %s:%d%s\r\n\r\n",
l_full_path, a_client_pvt->uplink_addr, a_client_pvt->uplink_port, l_add_str);
size_t l_message_size = dap_strlen(l_message);
int count = send(a_client_pvt->stream_socket, l_message, l_message_size, 0);
DAP_DELETE(l_message);
}
DAP_DELETE(l_full_path);
/*
// generate new pub key
if(!l_pkey_b64){
//if(!l_pub_key_data || !l_pub_key_data_size){
char *l_certs_name_str = dap_strdup_printf("client.%s", DAP_CHAIN_NET_SRV_VPN_CDB_GDB_PREFIX);
dap_cert_t ** l_certs = NULL;
size_t l_certs_size = 0;
dap_cert_t * l_cert = NULL;
// Load certs or create if not found
if(!dap_cert_parse_str_list(l_certs_name_str, &l_certs, &l_certs_size)) { // Load certs
const char *l_cert_folder = dap_cert_get_folder(0);
// create new cert
if(l_cert_folder) {
char *l_cert_path = dap_strdup_printf("%s/%s.dcert", l_cert_folder, l_certs_name_str);
l_cert = dap_cert_generate(l_certs_name_str, l_cert_path, DAP_ENC_KEY_TYPE_SIG_DILITHIUM);
DAP_DELETE(l_cert_path);
}
}
if(l_certs_size > 0)
l_cert = l_certs[0];
if(l_cert) {
size_t l_pub_key_data_size = 0;
uint8_t *l_pub_key_data = dap_enc_key_serealize_pub_key(l_cert->enc_key, &l_pub_key_data_size);
// save pub key
if(l_pub_key_data && l_pub_key_data_size > 0){
if(dap_chain_global_db_gr_set(dap_strdup("client_pkey"), l_pub_key_data, l_pub_key_data_size,
l_gdb_group)){
l_pkey_b64 = l_pub_key_data;
l_pkey_b64_size = l_pub_key_data_size;
}
else
DAP_DELETE(l_pub_key_data);
}
}
DAP_DELETE(l_certs_name_str);
}*/
if(!l_enc_key)
return NULL;
// Try to create condition
if(!l_tx_cond_hash) {
dap_chain_wallet_t *l_wallet_from = a_wallet;
log_it(L_DEBUG, "Create tx from wallet %s", l_wallet_from->name);
dap_enc_key_t *l_key_from = l_enc_key; //dap_chain_wallet_get_key(l_wallet_from, 0);
dap_enc_key_t *l_client_key = l_enc_key;
//dap_chain_cell_id_t *xccell = dap_chain_net_get_cur_cell(l_tpl->net);
//uint64_t uint64 =dap_chain_net_get_cur_cell(l_tpl->net)->uint64;
size_t l_pub_key_data_size = 0;
uint8_t *l_pub_key_data = dap_enc_key_serealize_pub_key(l_enc_key, &l_pub_key_data_size);
// where to take coins for service
dap_chain_addr_t *l_addr_from = dap_chain_wallet_get_addr(l_wallet_from, a_net->pub.id);
dap_chain_net_srv_price_unit_uid_t l_price_unit = { .enm = SERV_UNIT_SEC };
dap_chain_net_srv_uid_t l_srv_uid = { .uint64 = DAP_CHAIN_NET_SRV_VPN_ID };
l_tx_cond_hash = dap_chain_proc_tx_create_cond(a_net, l_key_from, l_client_key, l_addr_from,
a_token_ticker, a_value_datoshi, 0, l_price_unit, l_srv_uid, 0, l_pub_key_data, l_pub_key_data_size);
//char *l_addr_from_str = dap_chain_addr_to_str(l_addr_from);
DAP_DELETE(l_addr_from);
if(!l_tx_cond_hash) {
log_it(L_ERROR, "Can't create condition for user");
} else {
// save transaction for login
dap_chain_global_db_gr_set("client_tx_cond_hash", l_tx_cond_hash, sizeof(dap_chain_hash_fast_t),
l_gdb_group);
}
//DAP_DELETE(l_addr_from_str);
DAP_DELETE(l_pub_key_data);
}
DAP_DELETE(l_tx_cond_hash);
dap_enc_key_delete(l_enc_key);
DAP_DELETE(l_gdb_group);
return l_tx_cond_hash;
}
/**
* Init VPN client
*
* return: 0 Ok, 1 Ok, <0 Error
*/
int dap_chain_net_vpn_client_update(dap_chain_net_t *a_net, const char *a_wallet_name, const char *a_str_token,
uint64_t a_value_datoshi)
{
dap_chain_wallet_t *l_wallet = dap_chain_wallet_open(a_wallet_name, dap_chain_wallet_get_path(g_config));
if(!l_wallet) {
return -1;
}
size_t l_gdb_group_size = 0;
char *l_gdb_group = dap_strdup_printf("local.%s", DAP_CHAIN_NET_SRV_VPN_CDB_GDB_PREFIX);
if(!dap_chain_global_db_gr_set(dap_strdup("wallet_name"), (void*) a_wallet_name, dap_strlen(a_wallet_name) + 1,
l_gdb_group))
return -2;
if(!dap_chain_global_db_gr_set(dap_strdup("token_name"), (void*) a_str_token, dap_strlen(a_str_token) + 1,
l_gdb_group))
return -2;
if(!dap_chain_global_db_gr_set(dap_strdup("value_datoshi"), &a_value_datoshi, sizeof(a_value_datoshi), l_gdb_group))
return -2;
DAP_DELETE(l_gdb_group);
dap_chain_hash_fast_t *l_hash = dap_chain_net_vpn_client_tx_cond_hash(a_net, l_wallet, a_str_token,
a_value_datoshi);
dap_chain_wallet_close(l_wallet);
if(!l_hash)
return -3;
DAP_DELETE(l_hash);
return 0;
}
}*/
/**
* Init VPN client
*
* return: 0 Ok, 1 Ok, <0 Error
*/
int dap_chain_net_vpn_client_get_wallet_info(dap_chain_net_t *a_net, char **a_wallet_name, char **a_str_token,
uint64_t *a_value_datoshi)
{
size_t l_gdb_group_size = 0;
char *l_gdb_group = dap_strdup_printf("local.%s", DAP_CHAIN_NET_SRV_VPN_CDB_GDB_PREFIX);
if(a_wallet_name)
*a_wallet_name = (char*) dap_chain_global_db_gr_get("wallet_name", NULL, l_gdb_group);
if(a_str_token)
*a_str_token = (char*) dap_chain_global_db_gr_get("token_name", NULL, l_gdb_group);
if(a_value_datoshi) {
uint64_t *l_value_datoshi = (uint64_t*) dap_chain_global_db_gr_get("value_datoshi", NULL, l_gdb_group);
*a_value_datoshi = l_value_datoshi ? *l_value_datoshi : 0;
DAP_DELETE(l_value_datoshi);
}
return 0;
}
/**
* Start VPN client
......@@ -121,29 +312,17 @@ int dap_chain_net_vpn_client_start(dap_chain_net_t *a_net, const char *a_ipv4_st
int l_ret = 0;
if(!a_ipv4_str) // && !a_ipv6_str)
return -1;
/*
dap_client_t *l_client = DAP_NEW_Z(dap_client_t);
dap_events_t *l_events = NULL; //dap_events_new();
l_client = dap_client_new(l_events, s_stage_status_callback, s_stage_status_error_callback);
char l_channels[2] = { VPN_CLIENT_ID, 0 };
dap_client_set_active_channels(l_client, l_channels);
dap_client_set_uplink(l_client, strdup(a_ip_v4), a_port);
dap_client_go_stage(l_client, STAGE_STREAM_STREAMING, s_stage_connected_callback);
*/
if(!s_node_info)
s_node_info = DAP_NEW_Z(dap_chain_node_info_t);
s_node_info->hdr.ext_port = a_port;
dap_client_stage_t l_stage_target = STAGE_STREAM_STREAMING; //DAP_CLIENT_STAGE_STREAM_CTL;//STAGE_STREAM_STREAMING;
const char l_active_channels[] = { DAP_STREAM_CH_ID_NET_SRV_VPN , 0 };
const char l_active_channels[] = { dap_stream_ch_chain_net_srv_get_id(), DAP_STREAM_CH_ID_NET_SRV_VPN, 0 }; //R, S
if(a_ipv4_str)
inet_pton(AF_INET, a_ipv4_str, &(s_node_info->hdr.ext_addr_v4));
if(a_ipv6_str)
inet_pton(AF_INET6, a_ipv6_str, &(s_node_info->hdr.ext_addr_v6));
s_vpn_client = dap_chain_client_connect(s_node_info, l_stage_target, l_active_channels);
if(!s_vpn_client) {
log_it(L_ERROR, "Can't connect to VPN server=%s:%d", a_ipv4_str, a_port);
......@@ -154,7 +333,7 @@ int dap_chain_net_vpn_client_start(dap_chain_net_t *a_net, const char *a_ipv4_st
return -2;
}
// wait connected
int timeout_ms = 500000; //5 sec = 5000 ms
int timeout_ms = 5000; //5 sec = 5000 ms
int res = dap_chain_node_client_wait(s_vpn_client, NODE_CLIENT_STATE_CONNECTED, timeout_ms);
if(res) {
log_it(L_ERROR, "No response from VPN server=%s:%d", a_ipv4_str, a_port);
......@@ -168,77 +347,36 @@ int dap_chain_net_vpn_client_start(dap_chain_net_t *a_net, const char *a_ipv4_st
l_ret = dap_chain_net_vpn_client_tun_init(a_ipv4_str);
// send first packet to server
// if(0)
{
dap_stream_ch_t *l_ch = dap_chain_net_vpn_client_get_stream_ch();
if(l_ch) { // Is present in hash table such destination address
size_t l_ipv4_str_len = 0; //dap_strlen(a_ipv4_str);
ch_vpn_pkt_t *pkt_out = (ch_vpn_pkt_t*) calloc(1, sizeof(pkt_out->header) + l_ipv4_str_len);
pkt_out->header.op_code = VPN_PACKET_OP_CODE_VPN_ADDR_REQUEST;
//pkt_out->header.sock_id = l_stream->stream->events_socket->socket;
//pkt_out->header.op_connect.addr_size = l_ipv4_str_len; //remoteAddrBA.length();
//pkt_out->header.op_connect.port = a_port;
//memcpy(pkt_out->data, a_ipv4_str, l_ipv4_str_len);
dap_stream_ch_pkt_write(l_ch, DAP_STREAM_CH_PKT_TYPE_NET_SRV_VPN_DATA, pkt_out,
pkt_out->header.op_data.data_size + sizeof(pkt_out->header));
uint8_t l_ch_id = dap_stream_ch_chain_net_srv_get_id(); // Channel id for chain net request = 'R'
dap_stream_ch_t *l_ch = dap_client_get_stream_ch(s_vpn_client->client, l_ch_id);
if(l_ch) {
dap_stream_ch_chain_net_srv_pkt_request_t l_request;
memset(&l_request, 0, sizeof(dap_stream_ch_chain_net_srv_pkt_request_t));
l_request.hdr.net_id.uint64 = a_net->pub.id.uint64;
l_request.hdr.srv_uid.uint64 = DAP_CHAIN_NET_SRV_VPN_ID;
dap_chain_hash_fast_t *l_tx_cond = dap_chain_net_vpn_client_tx_cond_hash(a_net, NULL, NULL, 0);
if(l_tx_cond) {
memcpy(&l_request.hdr.tx_cond, l_tx_cond, sizeof(dap_chain_hash_fast_t));
DAP_DELETE(l_tx_cond);
}
// set srv id
dap_stream_ch_chain_net_srv_set_srv_uid(l_ch, l_request.hdr.srv_uid);
//dap_chain_hash_fast_t l_request
//.hdr.tx_cond = a_txCond.value();
// strncpy(l_request->hdr.token, a_token.toLatin1().constData(),sizeof (l_request->hdr.token)-1);
dap_stream_ch_pkt_write(l_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_REQUEST, &l_request, sizeof(l_request));
dap_stream_ch_set_ready_to_write(l_ch, true);
DAP_DELETE(pkt_out);
}
}
/* dap_stream_ch_t *l_stream = dap_client_get_stream_ch(s_vpn_client->client, VPN_CLIENT_ID);//dap_stream_ch_chain_get_id());
size_t l_res = dap_stream_ch_chain_pkt_write(l_stream,
VPN_PACKET_OP_CODE_CONNECT, a_net->pub.id, (dap_chain_id_t ) { { 0 } },
a_net->pub.cell_id, NULL, 0);*/
//return l_ret;
// send connect packet to server
/* {
dap_stream_ch_t *l_stream = dap_chain_net_vpn_client_get_stream();
if(l_stream) { // Is present in hash table such destination address
size_t l_ipv4_str_len = dap_strlen(a_ipv4_str);
ch_vpn_pkt_t *pkt_out = (ch_vpn_pkt_t*) calloc(1, sizeof(pkt_out->header) + l_ipv4_str_len);
pkt_out->header.op_code = VPN_PACKET_OP_CODE_CONNECT;
pkt_out->header.sock_id = l_stream->stream->events_socket->socket;
pkt_out->header.op_connect.addr_size = l_ipv4_str_len; //remoteAddrBA.length();
pkt_out->header.op_connect.port = a_port;
memcpy(pkt_out->data, a_ipv4_str, l_ipv4_str_len);
// pkt_out->header.op_code = VPN_PACKET_OP_CODE_VPN_RECV;
// pkt_out->header.sock_id = 123;
// pkt_out->header.op_data.data_size = 0;
//memcpy(pkt_out->data, 0, 0);
dap_stream_ch_pkt_write(l_stream, DATA_CHANNEL_ID, pkt_out,
pkt_out->header.op_data.data_size + sizeof(pkt_out->header));
dap_stream_ch_set_ready_to_write(l_stream, true);
DAP_DELETE(pkt_out);
}
}*/
//l_ret = dap_chain_net_vpn_client_tun_init(a_ipv4_str);
/* {
dap_stream_ch_t *l_stream = dap_chain_net_vpn_client_get_stream();
if(l_stream) { // Is present in hash table such destination address
ch_vpn_pkt_t *pkt_out = (ch_vpn_pkt_t*) calloc(1, sizeof(pkt_out->header) + 0);
pkt_out->header.op_code = VPN_PACKET_OP_CODE_VPN_RECV;
pkt_out->header.sock_id = 123;
pkt_out->header.op_data.data_size = 0;
//memcpy(pkt_out->data, 0, 0);
dap_stream_ch_pkt_write(l_stream, DATA_CHANNEL_ID, pkt_out,
pkt_out->header.op_data.data_size + sizeof(pkt_out->header));
dap_stream_ch_set_ready_to_write(l_stream, true);
}
}*/
return l_ret;
}
int dap_chain_net_vpn_client_stop(void)
{
// delete connection with VPN server
if(!s_vpn_client) {
if(s_vpn_client) {
dap_chain_node_client_close(s_vpn_client);
s_vpn_client = NULL;
}
......@@ -249,12 +387,20 @@ int dap_chain_net_vpn_client_stop(void)
return l_ret;
}
int dap_chain_net_vpn_client_status(void)
dap_chain_net_vpn_client_status_t dap_chain_net_vpn_client_status(void)
{
if(s_vpn_client) {
uint8_t l_ch_id = dap_stream_ch_chain_net_srv_get_id(); // Channel id for chain net request = 'R'
dap_stream_ch_t *l_ch = dap_client_get_stream_ch(s_vpn_client->client, l_ch_id);
if(!l_ch)
return VPN_CLIENT_STATUS_CONN_LOST;
}
else
return VPN_CLIENT_STATUS_NOT_STARTED;
if(!dap_chain_net_vpn_client_tun_status())
// VPN client started
return 1;
return 0;
return VPN_CLIENT_STATUS_STARTED;
return VPN_CLIENT_STATUS_STOPPED;
}
static void vpn_socket_delete(ch_vpn_socket_proxy_t * sf)
......@@ -265,18 +411,6 @@ static void vpn_socket_delete(ch_vpn_socket_proxy_t * sf)
free(sf);
}
static void send_pong_pkt(dap_stream_ch_t* a_ch)
{
// log_it(L_DEBUG,"---------------------------------- PONG!");
ch_vpn_pkt_t *pkt_out = (ch_vpn_pkt_t*) calloc(1, sizeof(pkt_out->header));
pkt_out->header.op_code = VPN_PACKET_OP_CODE_PONG;
dap_stream_ch_pkt_write(a_ch, 'd', pkt_out,
pkt_out->header.op_data.data_size + sizeof(pkt_out->header));
dap_stream_ch_set_ready_to_write(a_ch, true);
free(pkt_out);
}
/**
* @brief dap_chain_net_vpn_client_pkt_in
* @param a_ch
......@@ -301,30 +435,32 @@ void dap_chain_net_vpn_client_pkt_in(dap_stream_ch_t* a_ch, dap_stream_ch_pkt_t*
// ,remote_sock_id, l_sf_pkt->header.op_code, l_sf_pkt_data_size );
if(l_sf_pkt->header.op_code >= 0xb0) { // Raw packets
switch (l_sf_pkt->header.op_code) {
case VPN_PACKET_OP_CODE_VPN_ADDR_REPLY: { // Assigned address for peer
if(ch_sf_tun_addr_leased(CH_VPN(a_ch), l_sf_pkt, l_sf_pkt_data_size) < 0) {
log_it(L_WARNING, "Can't create tun");
}
}
break;
case VPN_PACKET_OP_CODE_VPN_ADDR_REQUEST: // Client request after L3 connection the new IP address
log_it(L_WARNING, "Got VPN_PACKET_OP_CODE_VPN_ADDR_REQUEST packet with id %d, it's very strange' ",
remote_sock_id);
break;
case VPN_PACKET_OP_CODE_VPN_SEND:
log_it(L_WARNING, "Got VPN_PACKET_OP_CODE_VPN_SEND packet with id %d, it's very strange' ", remote_sock_id);
case VPN_PACKET_OP_CODE_VPN_RECV:
a_ch->stream->events_socket->last_ping_request = time(NULL); // not ping, but better ;-)
ch_sf_tun_send(CH_VPN(a_ch), l_sf_pkt->data, l_sf_pkt->header.op_data.data_size);
break;
case VPN_PACKET_OP_CODE_PING:
a_ch->stream->events_socket->last_ping_request = time(NULL);
send_pong_pkt(a_ch);
break;
case VPN_PACKET_OP_CODE_PONG:
a_ch->stream->events_socket->last_ping_request = time(NULL);
break;
/* case VPN_PACKET_OP_CODE_VPN_ADDR_REPLY: { // Assigned address for peer
if(ch_sf_tun_addr_leased(CH_VPN(a_ch), l_sf_pkt, l_sf_pkt_data_size) < 0) {
log_it(L_WARNING, "Can't create tun");
}
}
break;
case VPN_PACKET_OP_CODE_VPN_ADDR_REQUEST: // Client request after L3 connection the new IP address
log_it(L_WARNING, "Got VPN_PACKET_OP_CODE_VPN_ADDR_REQUEST packet with id %d, it's very strange' ",
remote_sock_id);
break;
case VPN_PACKET_OP_CODE_VPN_SEND:
log_it(L_WARNING, "Got VPN_PACKET_OP_CODE_VPN_SEND packet with id %d, it's very strange' ", remote_sock_id);
case VPN_PACKET_OP_CODE_VPN_RECV:
a_ch->stream->events_socket->last_ping_request = time(NULL); // not ping, but better ;-)
ch_sf_tun_send(CH_VPN(a_ch), l_sf_pkt->data, l_sf_pkt->header.op_data.data_size);
break;*/
/*
case VPN_PACKET_OP_CODE_PING:
a_ch->stream->events_socket->last_ping_request = time(NULL);
send_pong_pkt(a_ch);
break;
case VPN_PACKET_OP_CODE_PONG:
a_ch->stream->events_socket->last_ping_request = time(NULL);
break;
*/
default:
log_it(L_WARNING, "Can't process SF type 0x%02x", l_sf_pkt->header.op_code);
}
......@@ -540,7 +676,8 @@ void dap_chain_net_vpn_client_pkt_out(dap_stream_ch_t* a_ch)
for(i = 0; i < l_cur->pkt_out_size; i++) {
ch_vpn_pkt_t * pout = l_cur->pkt_out[i];
if(pout) {
if(dap_stream_ch_pkt_write(a_ch, DAP_STREAM_CH_PKT_TYPE_NET_SRV_VPN_DATA, pout, pout->header.op_data.data_size + sizeof(pout->header))) {
if(dap_stream_ch_pkt_write(a_ch, DAP_STREAM_CH_PKT_TYPE_NET_SRV_VPN_DATA, pout,
pout->header.op_data.data_size + sizeof(pout->header))) {
l_is_smth_out = true;
if(pout)
free(pout);
......@@ -587,8 +724,7 @@ void dap_chain_net_vpn_client_pkt_out(dap_stream_ch_t* a_ch)
int dap_chain_net_vpn_client_init(dap_config_t * g_config)
{
pthread_mutex_init(&sf_socks_mutex, NULL);
return 0;
return dap_chain_net_srv_client_vpn_init(g_config);
}
void dap_chain_net_vpn_client_deinit()
......
......@@ -73,6 +73,7 @@ static char *s_last_used_connection_name = NULL, *s_last_used_connection_device
static pthread_t s_thread_read_tun_id;
static pthread_mutex_t s_clients_mutex;
static dap_events_socket_t * s_tun_events_socket = NULL;
//list_addr_element * list_addr_head = NULL;
//ch_sf_tun_server_t * m_tun_server = NULL;
......@@ -146,13 +147,20 @@ static char* get_def_gateway(void)
*
* return: connection name or NULL
*/
static char* get_connection(const char *a_conn_name)
static char* get_connection(const char *a_conn_name, char **a_connection_dev)
{
if(!a_conn_name)
return NULL;
// NAME UUID TYPE DEVICE
//nodeVPNClient a2b4cbc4-b8d2-4dd9-ac7f-81d9bf6fa276 tun --
char *l_cmd = dap_strdup_printf("nmcli connection show | grep %s | awk '{print $1}'", a_conn_name);
char* l_connection_name = run_bash_cmd(l_cmd);
DAP_DELETE(l_cmd);
if(a_connection_dev) {
l_cmd = dap_strdup_printf("nmcli connection show | grep %s | awk '{print $4}'", a_conn_name);
*a_connection_dev = run_bash_cmd(l_cmd);
DAP_DELETE(l_cmd);
}
return l_connection_name;
}
......@@ -363,6 +371,71 @@ int dap_chain_net_vpn_client_tun_init(const char *a_ipv4_server_str)
return 0;
}
static void m_client_tun_delete(dap_events_socket_t * a_es, void * arg)
{
log_it(L_DEBUG, __PRETTY_FUNCTION__);
//dap_chain_net_vpn_client_tun_delete();
log_it(L_NOTICE, "Raw sockets listen thread is stopped");
}
static void m_client_tun_write(dap_events_socket_t * a_es, void * arg)
{
// log_it(L_WARNING, __PRETTY_FUNCTION__);
}
static void m_client_tun_read(dap_events_socket_t * a_es, void * arg)
{
const static int tun_MTU = 100000; /// TODO Replace with detection of MTU size
uint8_t l_tmp_buf[tun_MTU];
size_t l_read_ret;
log_it(L_WARNING, __PRETTY_FUNCTION__);
do{
l_read_ret = dap_events_socket_read(a_es, l_tmp_buf, sizeof(l_tmp_buf));
if(l_read_ret > 0) {
struct iphdr *iph = (struct iphdr*) l_tmp_buf;
struct in_addr in_daddr, in_saddr;
in_daddr.s_addr = iph->daddr;
in_saddr.s_addr = iph->saddr;
char str_daddr[42], str_saddr[42];
dap_snprintf(str_saddr, sizeof(str_saddr), "%s",inet_ntoa(in_saddr) );
dap_snprintf(str_daddr, sizeof(str_daddr), "%s",inet_ntoa(in_daddr) );
dap_stream_ch_t *l_stream = dap_chain_net_vpn_client_get_stream_ch();
if(l_stream) {
// form packet to vpn-server
ch_vpn_pkt_t *pkt_out = (ch_vpn_pkt_t*) calloc(1, sizeof(pkt_out->header) + l_read_ret);
pkt_out->header.op_code = VPN_PACKET_OP_CODE_VPN_SEND; //VPN_PACKET_OP_CODE_VPN_RECV
pkt_out->header.sock_id = s_fd_tun;
pkt_out->header.op_data.data_size = l_read_ret;
memcpy(pkt_out->data, l_tmp_buf, l_read_ret);
pthread_mutex_lock(&s_clients_mutex);
// sent packet to vpn server
dap_stream_ch_pkt_write(l_stream, DAP_STREAM_CH_PKT_TYPE_NET_SRV_VPN_DATA, pkt_out,
pkt_out->header.op_data.data_size + sizeof(pkt_out->header));
dap_stream_ch_set_ready_to_write(l_stream, true);
pthread_mutex_unlock(&s_clients_mutex);
DAP_DELETE(pkt_out);
}
else {
log_it(L_DEBUG, "No remote client for income IP packet with addr %s", inet_ntoa(in_daddr));
}
}
}while(l_read_ret > 0);
dap_events_socket_set_readable(a_es, true);
}
static void m_client_tun_error(dap_events_socket_t * a_es, void * arg)
{
log_it(L_DEBUG, __PRETTY_FUNCTION__);
}
int dap_chain_net_vpn_client_tun_create(const char *a_ipv4_addr_str, const char *a_ipv4_gw_str)
{
// char dev[IFNAMSIZ] = { 0 };
......@@ -382,9 +455,11 @@ int dap_chain_net_vpn_client_tun_create(const char *a_ipv4_addr_str, const char
char *l_cmd_del_gw = dap_strdup_printf("ip route del default via %s", s_cur_gw);
char *l_cmd_ret = run_bash_cmd(l_cmd_del_gw);
DAP_DELETE(l_cmd_del_gw);
if(!l_cmd_del_gw) {
log_it(L_ERROR, "Can't delete dafault gateway %s)", s_cur_gw);
DAP_DELETE(s_cur_gw);
// check gateway
char *s_cur_gw_tmp = get_def_gateway();
if(s_cur_gw_tmp) {
log_it(L_ERROR, "Can't delete default gateway %s)", s_cur_gw);
DAP_DELETE(s_cur_gw_tmp);
return -3;
}
DAP_DELETE(l_cmd_ret);
......@@ -397,8 +472,7 @@ int dap_chain_net_vpn_client_tun_create(const char *a_ipv4_addr_str, const char
disableIPV6(s_last_used_connection_device);
// add new default gateway for vpn-server address
if(!is_local_address(s_cur_ipv4_server))
{
if(!is_local_address(s_cur_ipv4_server)) {
// This route don't need if address is local
char *l_str_cmd = dap_strdup_printf("route add -host %s gw %s metric 10", s_cur_ipv4_server, s_cur_gw);
char *l_cmd_ret = run_bash_cmd(l_str_cmd);
......@@ -407,7 +481,7 @@ int dap_chain_net_vpn_client_tun_create(const char *a_ipv4_addr_str, const char
}
// check and delete present connection
char *l_conn_present = get_connection(s_conn_name);
char *l_conn_present = get_connection(s_conn_name, NULL);
if(!dap_strcmp(l_conn_present, s_conn_name)) {
char *l_str_cmd = dap_strdup_printf("nmcli c delete %s", s_conn_name);
exe_bash_cmd(l_str_cmd);
......@@ -422,7 +496,7 @@ int dap_chain_net_vpn_client_tun_create(const char *a_ipv4_addr_str, const char
"nmcli connection add type tun con-name %s autoconnect false ifname %s mode tun ip4 %s gw4 %s",
s_conn_name, s_dev, a_ipv4_addr_str, a_ipv4_gw_str);
char *l_cmd_ret = run_bash_cmd(l_cmd_add_con);
l_conn_present = get_connection(s_conn_name);
l_conn_present = get_connection(s_conn_name, NULL);
if(dap_strcmp(l_conn_present, s_conn_name))
l_ret = -1;
DAP_DELETE(l_cmd_ret);
......@@ -468,7 +542,28 @@ int dap_chain_net_vpn_client_tun_create(const char *a_ipv4_addr_str, const char
}
pthread_mutex_init(&s_clients_mutex, NULL);
pthread_create(&s_thread_read_tun_id, NULL, thread_read_tun, NULL);
if(is_dap_tun_in_worker()) {
static dap_events_socket_callbacks_t l_s_callbacks = {
.read_callback = m_client_tun_read,// for server
.write_callback = m_client_tun_write,// for client
.error_callback = m_client_tun_error,
.delete_callback = m_client_tun_delete
};
s_tun_events_socket = dap_events_socket_wrap_no_add(NULL, s_fd_tun, &l_s_callbacks);
s_tun_events_socket->type = DESCRIPTOR_TYPE_FILE;
dap_events_socket_create_after(s_tun_events_socket);
s_tun_events_socket->_inheritor = NULL;
return 0;
}
else {
pthread_create(&s_thread_read_tun_id, NULL, thread_read_tun, NULL);
}
//m_tunDeviceName = dev;
//m_tunSocket = fd;
return l_ret;
......@@ -476,6 +571,14 @@ int dap_chain_net_vpn_client_tun_create(const char *a_ipv4_addr_str, const char
int dap_chain_net_vpn_client_tun_delete(void)
{
if(is_dap_tun_in_worker())
{
pthread_mutex_lock(&s_clients_mutex);
dap_events_socket_kill_socket(s_tun_events_socket);
s_tun_events_socket = NULL;
pthread_mutex_unlock(&s_clients_mutex);
}
// restore previous routing
if(!s_conn_name || !s_last_used_connection_name)
return -1;
......@@ -518,27 +621,31 @@ int dap_chain_net_vpn_client_tun_delete(void)
int dap_chain_net_vpn_client_tun_status(void)
{
char *l_str_cmd = get_connection(s_conn_name);
char *l_conn_dev = NULL;
char *l_str_cmd = get_connection(s_conn_name, &l_conn_dev);
if(!l_str_cmd)
return 0;
return -1;
// connection must be present
if(dap_strcmp(l_str_cmd, s_conn_name)) {
if(dap_strcmp(l_str_cmd, s_conn_name) || dap_strcmp(l_conn_dev, s_dev)) {
DAP_DELETE(l_str_cmd);
return 0;
DAP_DELETE(l_conn_dev);
return -2;
}
DAP_DELETE(l_str_cmd);
DAP_DELETE(l_conn_dev);
/* alternative method
char *l_used_connection_name = NULL;
char *l_used_connection_device = NULL;
save_current_connection_interface_data(&l_used_connection_name, &l_used_connection_device);
// connection must be upped
if(dap_strcmp(l_used_connection_name, s_conn_name) || dap_strcmp(l_used_connection_device, s_dev)) {
if(!s_dev || dap_strcmp(l_used_connection_name, s_conn_name) || dap_strcmp(l_used_connection_device, s_dev)) {
DAP_DELETE(l_used_connection_name);
DAP_DELETE(l_used_connection_device);
return -1;
}
DAP_DELETE(l_used_connection_name);
DAP_DELETE(l_used_connection_device);
DAP_DELETE(l_used_connection_device);*/
// VPN client started
return 0;
......
......@@ -155,6 +155,10 @@ typedef struct dap_chain_net_srv_vpn
#define CH_VPN(a) ((dap_chain_net_srv_ch_vpn_t *) ((a)->internal) )
bool is_dap_tun_in_worker(void);
int dap_chain_net_srv_client_vpn_init(dap_config_t * g_config);
int dap_chain_net_srv_vpn_init(dap_config_t * g_config);
void dap_chain_net_srv_vpn_deinit(void);
......
......@@ -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);
#pragma once
int dap_chain_net_srv_vpn_cmd_init();
......@@ -29,11 +29,22 @@
#include "dap_chain_net.h"
#include "dap_chain_net_srv_vpn.h"
typedef enum dap_chain_net_vpn_client_status_enum{
VPN_CLIENT_STATUS_NOT_STARTED=0,
VPN_CLIENT_STATUS_STARTED,
VPN_CLIENT_STATUS_STOPPED,
VPN_CLIENT_STATUS_CONN_LOST,
} dap_chain_net_vpn_client_status_t;
dap_stream_ch_t* dap_chain_net_vpn_client_get_stream_ch(void);
int dap_chain_net_vpn_client_update(dap_chain_net_t *a_net, const char *a_wallet_name, const char *a_str_token, uint64_t a_value_datoshi);
int dap_chain_net_vpn_client_get_wallet_info(dap_chain_net_t *a_net, char **a_wallet_name, char **a_str_token, uint64_t *a_value_datoshi);
int dap_chain_net_vpn_client_start(dap_chain_net_t *a_net, const char *a_ipv4_str, const char *a_ipv6_str, int a_port);
int dap_chain_net_vpn_client_stop(void);
int dap_chain_net_vpn_client_status(void);
dap_chain_net_vpn_client_status_t dap_chain_net_vpn_client_status(void);
int dap_chain_net_vpn_client_init(dap_config_t * g_config);
void dap_chain_net_vpn_client_deinit();
......