diff --git a/dap-sdk/net/client/dap_client.c b/dap-sdk/net/client/dap_client.c index d33a1a96b022361521045842c2cecf0014d7db30..b799fe8080941db2ce65225fc546f9a3312f6650 100644 --- a/dap-sdk/net/client/dap_client.c +++ b/dap-sdk/net/client/dap_client.c @@ -138,7 +138,6 @@ void dap_client_set_active_channels (dap_client_t * a_client, const char * a_act DAP_CLIENT_PVT(a_client)->active_channels = dap_strdup( a_active_channels); } - /** * @brief dap_client_get_uplink_port * @param a_client @@ -149,6 +148,11 @@ uint16_t dap_client_get_uplink_port(dap_client_t * a_client) return DAP_CLIENT_PVT(a_client)->uplink_port; } +void dap_client_set_auth_cert(dap_client_t * a_client, dap_cert_t *a_cert) +{ + DAP_CLIENT_PVT(a_client)->auth_cert = a_cert; +} + /** * @brief dap_client_reset diff --git a/dap-sdk/net/client/dap_client_pvt.c b/dap-sdk/net/client/dap_client_pvt.c index fe892c30ea445dce090e2b003afeb31233c5fbab..47a67a2d840a802e157fbc2accce348bea081d33 100644 --- a/dap-sdk/net/client/dap_client_pvt.c +++ b/dap-sdk/net/client/dap_client_pvt.c @@ -399,13 +399,19 @@ static void s_stage_status_after(dap_client_pvt_t * a_client_pvt) case STAGE_ENC_INIT: { log_it(L_INFO, "Go to stage ENC: prepare the request"); a_client_pvt->session_key_open = dap_enc_key_new_generate(DAP_ENC_KEY_TYPE_MSRLN, NULL, 0, NULL, 0, 0); - dap_cert_t *l_cert = dap_cert_find_by_name("auth"); // TODO provide certificate choice size_t l_key_size = a_client_pvt->session_key_open->pub_key_data_size; - dap_sign_t *l_sign = dap_sign_create(l_cert->enc_key, a_client_pvt->session_key_open->pub_key_data, l_key_size, 0); - size_t l_sign_size = dap_sign_get_size(l_sign); + dap_cert_t *l_cert = a_client_pvt->auth_cert; + dap_sign_t *l_sign = NULL; + size_t l_sign_size = 0; + if (l_cert) { + l_sign = dap_sign_create(l_cert->enc_key, a_client_pvt->session_key_open->pub_key_data, l_key_size, 0); + l_sign_size = dap_sign_get_size(l_sign); + } uint8_t l_data[l_key_size + l_sign_size]; memcpy(l_data, a_client_pvt->session_key_open->pub_key_data, l_key_size); - memcpy(l_data + l_key_size, l_sign, l_sign_size); + if (l_sign) { + memcpy(l_data + l_key_size, l_sign, l_sign_size); + } size_t l_data_str_size_max = DAP_ENC_BASE64_ENCODE_SIZE(l_key_size + l_sign_size); char l_data_str[l_data_str_size_max + 1]; // DAP_ENC_DATA_TYPE_B64_URLSAFE not need because send it by POST request diff --git a/dap-sdk/net/client/include/dap_client.h b/dap-sdk/net/client/include/dap_client.h index 7a81af9734559fdf27c8efb458d548553c22a212..dc49c63796fc313f5084043988a51f75231ba117 100644 --- a/dap-sdk/net/client/include/dap_client.h +++ b/dap-sdk/net/client/include/dap_client.h @@ -28,6 +28,7 @@ #include "dap_events.h" #include "dap_stream.h" #include "dap_stream_ch.h" +#include "dap_cert.h" /** * @brief The dap_client_stage enum. Top level of client's state machine @@ -133,6 +134,7 @@ dap_stream_t * dap_client_get_stream(dap_client_t * a_client); dap_stream_ch_t * dap_client_get_stream_ch(dap_client_t * a_client, uint8_t a_ch_id); const char * dap_client_get_stream_id(dap_client_t * a_client); void dap_client_set_active_channels (dap_client_t * a_client, const char * a_active_channels); +void dap_client_set_auth_cert(dap_client_t * a_client, dap_cert_t *a_cert); dap_client_stage_t dap_client_get_stage(dap_client_t * a_client); dap_client_stage_status_t dap_client_get_stage_status(dap_client_t * a_client); diff --git a/dap-sdk/net/client/include/dap_client_pvt.h b/dap-sdk/net/client/include/dap_client_pvt.h index 9c93e03ad62ae463db9d407657e397b1d629810a..04aa7439242657964d7bd4bf8f5627aa36af1241 100644 --- a/dap-sdk/net/client/include/dap_client_pvt.h +++ b/dap-sdk/net/client/include/dap_client_pvt.h @@ -28,6 +28,8 @@ #include "dap_client.h" #include "dap_stream.h" #include "dap_events_socket.h" +#include "dap_cert.h" + typedef struct dap_enc_key dap_enc_key_t; typedef struct dap_http_client dap_http_client_t; @@ -47,7 +49,7 @@ typedef struct dap_client_internal dap_enc_key_t * session_key; // Symmetric private key for session encryption dap_enc_key_t * stream_key; // Stream private key for stream encryption char stream_id[25]; - + dap_cert_t *auth_cert; char * session_key_id; //void *curl;// curl connection descriptor diff --git a/dap-sdk/net/server/enc_server/dap_enc_http.c b/dap-sdk/net/server/enc_server/dap_enc_http.c index b2b10a72940aa921382661cbd5c6166795d6a7c9..d7cd6c71220413571afa96a3e4e3bc6475041d03 100644 --- a/dap-sdk/net/server/enc_server/dap_enc_http.c +++ b/dap-sdk/net/server/enc_server/dap_enc_http.c @@ -56,6 +56,8 @@ #define LOG_TAG "dap_enc_http" +static dap_enc_acl_callback_t s_acl_callback = NULL; + int enc_http_init() { return 0; @@ -80,6 +82,12 @@ static void _enc_http_write_reply(struct dap_http_simple *cl_st, } void dap_enc_http_json_response_format_enable(bool); + +void dap_enc_http_set_acl_callback(dap_enc_acl_callback_t a_callback) +{ + s_acl_callback = a_callback; +} + /** * @brief enc_http_proc Enc http interface * @param cl_st HTTP Simple client instance @@ -112,8 +120,14 @@ void enc_http_proc(struct dap_http_simple *cl_st, void * arg) msrln_key->gen_bob_shared_key(msrln_key, alice_msg, MSRLN_PKA_BYTES, (void**)&msrln_key->pub_key_data); dap_enc_ks_key_t * key_ks = dap_enc_ks_new(); - if (!dap_hash_fast_is_blank(&l_sign_hash)) { - memcpy(&key_ks->auth_hash, &l_sign_hash, sizeof(dap_chain_hash_fast_t)); + if (s_acl_callback) { + key_ks->acl_list = s_acl_callback(&l_sign_hash); + if (!key_ks->acl_list) { + *return_code = Http_Status_Unauthorized; + return; + } + } else { + log_it(L_WARNING, "Callback for ACL is not set, pass anauthorized"); } char encrypt_msg[DAP_ENC_BASE64_ENCODE_SIZE(msrln_key->pub_key_data_size) + 1]; diff --git a/dap-sdk/net/server/enc_server/include/dap_enc_http.h b/dap-sdk/net/server/enc_server/include/dap_enc_http.h index b92032188d2fa2f0c729f35a290182e1f442a3d1..4660b5250969586abea87ba461115e6169929bbc 100644 --- a/dap-sdk/net/server/enc_server/include/dap_enc_http.h +++ b/dap-sdk/net/server/enc_server/include/dap_enc_http.h @@ -22,6 +22,7 @@ #define _ENC_HTTP_H_ #include <stddef.h> #include <stdbool.h> +#include "dap_hash.h" struct dap_http; struct dap_http_client; @@ -63,6 +64,7 @@ typedef struct enc_http_delegate{ } enc_http_delegate_t; typedef void (*dap_enc_http_callback_t) (enc_http_delegate_t *,void *); // Callback for specific client operations +typedef uint8_t *(* dap_enc_acl_callback_t) (dap_chain_hash_fast_t *); // Callback for access list for private chain networks int enc_http_init(void); void enc_http_deinit(void); @@ -70,6 +72,7 @@ void enc_http_deinit(void); size_t enc_http_reply(enc_http_delegate_t * dg, void * data, size_t data_size); size_t enc_http_reply_f(enc_http_delegate_t * dg, const char * data, ...); +void dap_enc_http_set_acl_callback(dap_enc_acl_callback_t a_callback); enc_http_delegate_t *enc_http_request_decode(struct dap_http_simple *a_http_simple); diff --git a/dap-sdk/net/server/enc_server/include/dap_enc_ks.h b/dap-sdk/net/server/enc_server/include/dap_enc_ks.h index f31a04676e8f5929514833975e69b23c235a8d62..07c51b19ecf378acd9e7e776228aa7b89dbc4fe3 100644 --- a/dap-sdk/net/server/enc_server/include/dap_enc_ks.h +++ b/dap-sdk/net/server/enc_server/include/dap_enc_ks.h @@ -35,7 +35,7 @@ typedef struct dap_enc_ks_key{ dap_enc_key_t *key; time_t time_created; pthread_mutex_t mutex; - dap_chain_hash_fast_t auth_hash; + uint8_t *acl_list; UT_hash_handle hh; // makes this structure hashable with UTHASH library } dap_enc_ks_key_t; diff --git a/dap-sdk/net/stream/session/include/dap_stream_session.h b/dap-sdk/net/stream/session/include/dap_stream_session.h index 578ead691f6870b1547f98af56b5f9f8652b11ca..2f8d9e624d23a5eebb694515b06796f31aac87f7 100644 --- a/dap-sdk/net/stream/session/include/dap_stream_session.h +++ b/dap-sdk/net/stream/session/include/dap_stream_session.h @@ -57,7 +57,7 @@ struct dap_stream_session { stream_session_connection_type_t conn_type; stream_session_type_t type; - dap_chain_hash_fast_t auth_hash; + uint8_t *acl; UT_hash_handle hh; struct in_addr tun_client_addr; diff --git a/dap-sdk/net/stream/stream/dap_stream_ctl.c b/dap-sdk/net/stream/stream/dap_stream_ctl.c index ddf33e5fcfa61be8f59644fdff87eb71e0a0a4c9..e42b474d79654127858d38aacef56f5cb52d6735 100644 --- a/dap-sdk/net/stream/stream/dap_stream_ctl.c +++ b/dap-sdk/net/stream/stream/dap_stream_ctl.c @@ -149,7 +149,7 @@ void s_proc(struct dap_http_simple *a_http_simple, void * a_arg) dap_http_header_t *l_hdr_key_id = dap_http_header_find(a_http_simple->http->in_headers, "KeyID"); if (l_hdr_key_id) { dap_enc_ks_key_t *l_ks_key = dap_enc_ks_find(l_hdr_key_id->value); - memcpy(&ss->auth_hash, &l_ks_key->auth_hash, sizeof(dap_chain_hash_fast_t)); + ss->acl = l_ks_key->acl_list; } enc_http_reply_f(l_dg,"%u %s",ss->id,key_str); *return_code = Http_Status_OK; diff --git a/modules/channel/chain-net/dap_stream_ch_chain_net.c b/modules/channel/chain-net/dap_stream_ch_chain_net.c index 68de157c7481b4e45302ab440845db3a491a38dd..205b5c309c865dc4eedf715f6f4482b4688b04e7 100644 --- a/modules/channel/chain-net/dap_stream_ch_chain_net.c +++ b/modules/channel/chain-net/dap_stream_ch_chain_net.c @@ -193,8 +193,27 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) pthread_mutex_lock(&l_ch_chain_net->mutex); dap_stream_ch_pkt_t *l_ch_pkt = (dap_stream_ch_pkt_t *) a_arg; dap_stream_ch_chain_net_pkt_t *l_ch_chain_net_pkt = (dap_stream_ch_chain_net_pkt_t *) l_ch_pkt->data; - size_t l_ch_chain_net_pkt_data_size = (size_t) l_ch_pkt->hdr.size - sizeof (l_ch_chain_net_pkt->hdr); - if(l_ch_chain_net_pkt) { + uint8_t l_acl_idx = dap_chain_net_acl_idx_by_id(l_ch_chain_net_pkt->hdr.net_id); + bool l_error = false; + char l_err_str[64]; + if (l_acl_idx == (uint8_t)-1) { + log_it(L_ERROR, "Invalid net id in packet"); + strcpy(l_err_str, "ERROR_NET_INVALID_ID"); + l_error = true; + } + if (!l_error && !a_ch->stream->session->acl[l_acl_idx]) { // Access denied + log_it(L_WARNING, "Unauthorized request attempt to network %s", + dap_chain_net_by_id(l_ch_chain_net_pkt->hdr.net_id)->pub.name); + strcpy(l_err_str, "ERROR_NET_NOT_AUTHORIZED"); + l_error = true; + } + if (l_error) { + dap_stream_ch_chain_net_pkt_write(a_ch, DAP_STREAM_CH_CHAIN_NET_PKT_TYPE_ERROR , + l_ch_chain_net_pkt->hdr.net_id, l_err_str, strlen(l_err_str) + 1); + dap_stream_ch_set_ready_to_write(a_ch, true); + } + //size_t l_ch_chain_net_pkt_data_size = (size_t) l_ch_pkt->hdr.size - sizeof (l_ch_chain_net_pkt->hdr); + if (!l_error && l_ch_chain_net_pkt) { size_t l_ch_chain_net_pkt_data_size = l_ch_pkt->hdr.size - sizeof(dap_stream_ch_chain_net_pkt_hdr_t); switch (l_ch_pkt->hdr.type) { case DAP_STREAM_CH_CHAIN_NET_PKT_TYPE_DBG: { @@ -240,7 +259,7 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) dap_stream_ch_chain_net_pkt_write(a_ch, DAP_STREAM_CH_CHAIN_NET_PKT_TYPE_ERROR , l_ch_chain_net_pkt->hdr.net_id, l_err_str,sizeof (l_err_str)); dap_stream_ch_set_ready_to_write(a_ch, true); - log_it(L_WARNING,"Invalid net id in packet"); + log_it(L_ERROR, "Invalid net id in packet"); } else { if (dap_db_set_cur_node_addr_exp( l_addr->uint64, l_net->pub.name )) log_it(L_NOTICE,"Set up cur node address 0x%016llX",l_addr->uint64); @@ -276,77 +295,15 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) l_err_str,sizeof (l_err_str)); dap_stream_ch_set_ready_to_write(a_ch, true); } else { - const char l_path[] = "network/"; - char l_cfg_path[strlen(l_net->pub.name) + strlen(l_path) + 1]; - strcpy(l_cfg_path, l_path); - strcat(l_cfg_path, l_net->pub.name); - dap_config_t *l_cfg = dap_config_open(l_cfg_path); - const char *l_auth_type = dap_config_get_item_str(l_cfg, "auth", "type"); - bool l_authorized = true; - if (!strcmp(l_auth_type, "ca")) { - l_authorized = false; - const char *l_auth_hash_str = dap_chain_hash_fast_to_str_new(&a_ch->stream->session->auth_hash); - uint16_t l_acl_list_len = 0; - char **l_acl_list = dap_config_get_array_str(l_cfg, "auth", "acl_accept_ca_list", &l_acl_list_len); - for (uint16_t i = 0; i < l_acl_list_len; i++) { - if (!strcmp(l_acl_list[i], l_auth_hash_str)) { - l_authorized = true; - break; - } - } - if (!l_authorized) { - const char *l_acl_gdb = dap_config_get_item_str(l_cfg, "auth", "acl_accept_ca_gdb"); - if (l_acl_gdb) { - size_t l_objs_count; - dap_global_db_obj_t *l_objs = dap_chain_global_db_gr_load(l_acl_gdb, &l_objs_count); - for (size_t i = 0; i < l_objs_count; i++) { - if (!strcmp(l_objs[i].key, l_auth_hash_str)) { - l_authorized = true; - break; - } - } - dap_chain_global_db_objs_delete(l_objs, l_objs_count); - } - } - if (!l_authorized) { - const char *l_acl_chains = dap_config_get_item_str(l_cfg, "auth", "acl_accept_ca_chains"); - if (!strcmp(l_acl_chains, "all")) { - dap_list_t *l_certs = dap_cert_get_all_mem(); - for (dap_list_t *l_tmp = l_certs; l_tmp; l_tmp = dap_list_next(l_tmp)) { - dap_cert_t *l_cert = (dap_cert_t *)l_tmp->data; - size_t l_pkey_size; - uint8_t *l_pkey_ser = dap_enc_key_serealize_pub_key(l_cert->enc_key, &l_pkey_size); - dap_chain_hash_fast_t l_cert_hash; - dap_hash_fast(l_pkey_ser, l_pkey_size, &l_cert_hash); - DAP_DELETE(l_pkey_ser); - char *l_pkey_str = dap_chain_hash_fast_to_str_new(&l_cert_hash); - if (!strcmp(l_pkey_str, l_auth_hash_str)) { - l_authorized = true; - DAP_DELETE(l_pkey_str); - break; - } - DAP_DELETE(l_pkey_str); - } - } - } - } - if (l_authorized) { - dap_chain_node_addr_t *l_addr_new = dap_chain_node_gen_addr(l_net, &l_net->pub.cell_id ); - dap_stream_ch_chain_net_pkt_write(a_ch, DAP_STREAM_CH_CHAIN_NET_PKT_TYPE_NODE_ADDR_LEASE , - l_ch_chain_net_pkt->hdr.net_id, l_addr_new, sizeof (*l_addr_new)); - dap_stream_ch_set_ready_to_write(a_ch, true); - memcpy( &l_session_data->addr_remote,l_addr_new,sizeof (*l_addr_new) ); - DAP_DELETE(l_addr_new); - } else { - char l_err_str[]="ERROR_NET_NOT_AUTHORIZED"; - dap_stream_ch_chain_net_pkt_write(a_ch, DAP_STREAM_CH_CHAIN_NET_PKT_TYPE_ERROR , l_net->pub.id, - l_err_str,sizeof (l_err_str)); - dap_stream_ch_set_ready_to_write(a_ch, true); - } + dap_chain_node_addr_t *l_addr_new = dap_chain_node_gen_addr(l_net, &l_net->pub.cell_id ); + dap_stream_ch_chain_net_pkt_write(a_ch, DAP_STREAM_CH_CHAIN_NET_PKT_TYPE_NODE_ADDR_LEASE , + l_ch_chain_net_pkt->hdr.net_id, l_addr_new, sizeof (*l_addr_new)); + dap_stream_ch_set_ready_to_write(a_ch, true); + memcpy( &l_session_data->addr_remote,l_addr_new,sizeof (*l_addr_new) ); + DAP_DELETE(l_addr_new); } } break; - } if(l_ch_chain_net->notify_callback) l_ch_chain_net->notify_callback(l_ch_chain_net,l_ch_pkt->hdr.type, l_ch_chain_net_pkt, diff --git a/modules/channel/chain/dap_stream_ch_chain.c b/modules/channel/chain/dap_stream_ch_chain.c index 7f93f8111a2ece71cf4d45ca96c086a3f1399d6a..e81be2a66add7b67a7dfa26dcb14bcfa5e399222 100644 --- a/modules/channel/chain/dap_stream_ch_chain.c +++ b/modules/channel/chain/dap_stream_ch_chain.c @@ -130,8 +130,27 @@ void s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) if(l_ch_chain) { dap_stream_ch_pkt_t * l_ch_pkt = (dap_stream_ch_pkt_t *) a_arg; dap_stream_ch_chain_pkt_t * l_chain_pkt = (dap_stream_ch_chain_pkt_t *) l_ch_pkt->data; + uint8_t l_acl_idx = dap_chain_net_acl_idx_by_id(l_chain_pkt->hdr.net_id); + bool l_error = false; + char l_err_str[64]; + if (l_acl_idx == (uint8_t)-1) { + log_it(L_ERROR, "Invalid net id in packet"); + strcpy(l_err_str, "ERROR_NET_INVALID_ID"); + l_error = true; + } + if (!l_error && !a_ch->stream->session->acl[l_acl_idx]) { // Access denied + log_it(L_WARNING, "Unauthorized request attempt to network %s", + dap_chain_net_by_id(l_chain_pkt->hdr.net_id)->pub.name); + strcpy(l_err_str, "ERROR_NET_NOT_AUTHORIZED"); + l_error = true; + } + if (l_error) { + dap_stream_ch_chain_pkt_write_error(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, l_err_str); + dap_stream_ch_set_ready_to_write(a_ch, true); + } size_t l_chain_pkt_data_size = l_ch_pkt->hdr.size - sizeof(l_chain_pkt->hdr); - if(l_chain_pkt) { + if (!l_error && l_chain_pkt) { switch (l_ch_pkt->hdr.type) { case DAP_STREAM_CH_CHAIN_PKT_TYPE_SYNCED_ALL: { log_it(L_INFO, "In: SYNCED_ALL pkt"); diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c index 6477407468bfca8ac4f2d5794cbf113aaca1ed8b..b0f2b8ddbc12c3f60f9d43fed8a0ea620cfb64bf 100644 --- a/modules/net/dap_chain_net.c +++ b/modules/net/dap_chain_net.c @@ -61,6 +61,7 @@ #include "dap_hash.h" #include "dap_cert.h" #include "dap_cert_file.h" +#include "dap_enc_http.h" #include "dap_chain_common.h" #include "dap_chain_net.h" #include "dap_chain_net_srv.h" @@ -142,6 +143,7 @@ typedef struct dap_chain_net_pvt{ dap_chain_net_state_t state; dap_chain_net_state_t state_target; + uint16_t acl_idx; } dap_chain_net_pvt_t; typedef struct dap_chain_net_item{ @@ -175,7 +177,7 @@ static int s_net_states_proc(dap_chain_net_t * l_net); static void * s_net_proc_thread ( void * a_net); static void s_net_proc_thread_start( dap_chain_net_t * a_net ); static void s_net_proc_kill( dap_chain_net_t * a_net ); -int s_net_load(const char * a_net_name); +int s_net_load(const char * a_net_name, uint16_t a_acl_idx); static void s_gbd_history_callback_notify (void * a_arg,const char a_op_code, const char * a_prefix, const char * a_group, const char * a_key, const void * a_value, @@ -186,6 +188,7 @@ static int s_cli_net(int argc, char ** argv, void *arg_func, char **str_reply); static bool s_seed_mode = false; +static uint8_t *dap_chain_net_set_acl(dap_chain_hash_fast_t *a_pkey_hash); char *dap_chain_net_get_gdb_group_acl(dap_chain_net_t *a_net) { @@ -1052,6 +1055,8 @@ int dap_chain_net_init() s_required_links_count = dap_config_get_item_int32_default(g_config, "general", "require_links", s_required_links_count); dap_chain_net_load_all(); + + dap_enc_http_set_acl_callback(dap_chain_net_set_acl); return 0; } @@ -1061,6 +1066,7 @@ void dap_chain_net_load_all() DIR * l_net_dir = opendir( l_net_dir_str); if ( l_net_dir ){ struct dirent * l_dir_entry; + uint16_t l_acl_idx = 0; while ( (l_dir_entry = readdir(l_net_dir) )!= NULL ){ if (l_dir_entry->d_name[0]=='\0' || l_dir_entry->d_name[0]=='.') continue; @@ -1083,7 +1089,7 @@ void dap_chain_net_load_all() char* l_dot_pos = strchr(l_dir_entry->d_name,'.'); if ( l_dot_pos ) *l_dot_pos = '\0'; - s_net_load(l_dir_entry->d_name ); + s_net_load(l_dir_entry->d_name, l_acl_idx++); } closedir(l_net_dir); } @@ -1100,6 +1106,7 @@ void dap_chain_net_load_all() */ static int s_cli_net( int argc, char **argv, void *arg_func, char **a_str_reply) { + UNUSED(arg_func); int arg_index = 1; dap_chain_net_t * l_net = NULL; @@ -1409,7 +1416,7 @@ static int callback_compare_prioritity_list(const void * a_item1, const void * a * @param a_net_name * @return */ -int s_net_load(const char * a_net_name) +int s_net_load(const char * a_net_name, uint16_t a_acl_idx) { dap_config_t *l_cfg=NULL; dap_string_t *l_cfg_path = dap_string_new("network/"); @@ -1431,6 +1438,7 @@ int s_net_load(const char * a_net_name) return -1; } PVT(l_net)->load_mode = true; + PVT(l_net)->acl_idx = a_acl_idx; l_net->pub.gdb_groups_prefix = dap_strdup ( dap_config_get_item_str_default(l_cfg , "general" , "gdb_groups_prefix", dap_config_get_item_str(l_cfg , "general" , "name" ) ) ); @@ -1950,6 +1958,22 @@ dap_chain_net_t * dap_chain_net_by_id( dap_chain_net_id_t a_id) } +/** + * @brief dap_chain_net_by_id + * @param a_id + * @return + */ +uint16_t dap_chain_net_acl_idx_by_id(dap_chain_net_id_t a_id) +{ + dap_chain_net_item_t * l_net_item = NULL; + HASH_FIND(hh,s_net_items_ids,&a_id,sizeof (a_id), l_net_item ); + if (l_net_item) + return PVT(l_net_item->chain_net)->acl_idx; + else + return -1; + +} + /** * @brief dap_chain_net_id_by_name @@ -2508,3 +2532,85 @@ void dap_chain_net_dump_datum(dap_string_t * a_str_out, dap_chain_datum_t * a_da }break; } } + +static bool s_net_check_acl(dap_chain_net_t *a_net, dap_chain_hash_fast_t *a_pkey_hash) +{ + const char l_path[] = "network/"; + char l_cfg_path[strlen(a_net->pub.name) + strlen(l_path) + 1]; + strcpy(l_cfg_path, l_path); + strcat(l_cfg_path, a_net->pub.name); + dap_config_t *l_cfg = dap_config_open(l_cfg_path); + const char *l_auth_type = dap_config_get_item_str(l_cfg, "auth", "type"); + bool l_authorized = true; + if (!strcmp(l_auth_type, "ca")) { + if (dap_hash_fast_is_blank(a_pkey_hash)) { + return false; + } + l_authorized = false; + const char *l_auth_hash_str = dap_chain_hash_fast_to_str_new(a_pkey_hash); + uint16_t l_acl_list_len = 0; + char **l_acl_list = dap_config_get_array_str(l_cfg, "auth", "acl_accept_ca_list", &l_acl_list_len); + for (uint16_t i = 0; i < l_acl_list_len; i++) { + if (!strcmp(l_acl_list[i], l_auth_hash_str)) { + l_authorized = true; + break; + } + } + if (!l_authorized) { + const char *l_acl_gdb = dap_config_get_item_str(l_cfg, "auth", "acl_accept_ca_gdb"); + if (l_acl_gdb) { + size_t l_objs_count; + dap_global_db_obj_t *l_objs = dap_chain_global_db_gr_load(l_acl_gdb, &l_objs_count); + for (size_t i = 0; i < l_objs_count; i++) { + if (!strcmp(l_objs[i].key, l_auth_hash_str)) { + l_authorized = true; + break; + } + } + dap_chain_global_db_objs_delete(l_objs, l_objs_count); + } + } + if (!l_authorized) { + const char *l_acl_chains = dap_config_get_item_str(l_cfg, "auth", "acl_accept_ca_chains"); + if (!strcmp(l_acl_chains, "all")) { + dap_list_t *l_certs = dap_cert_get_all_mem(); + for (dap_list_t *l_tmp = l_certs; l_tmp; l_tmp = dap_list_next(l_tmp)) { + dap_cert_t *l_cert = (dap_cert_t *)l_tmp->data; + size_t l_pkey_size; + uint8_t *l_pkey_ser = dap_enc_key_serealize_pub_key(l_cert->enc_key, &l_pkey_size); + dap_chain_hash_fast_t l_cert_hash; + dap_hash_fast(l_pkey_ser, l_pkey_size, &l_cert_hash); + if (!memcmp(l_pkey_ser, a_pkey_hash, sizeof(dap_chain_hash_fast_t))) { + l_authorized = true; + DAP_DELETE(l_pkey_ser); + break; + } + DAP_DELETE(l_pkey_ser); + } + } + } + } + return l_authorized; +} + +static uint8_t *dap_chain_net_set_acl(dap_chain_hash_fast_t *a_pkey_hash) +{ + uint16_t l_net_count; + dap_chain_net_t **l_net_list = dap_chain_net_list(&l_net_count); + bool l_accessible = false; + if (l_net_count) { + uint8_t *l_ret = DAP_NEW_SIZE(uint8_t, l_net_count); + for (uint16_t i = 0; i < l_net_count; i++) { + l_ret[i] = s_net_check_acl(l_net_list[i], a_pkey_hash); + if (l_ret[i]) { + l_accessible = true; + } + } + if (!l_accessible) { // No one network can be accessed with this key + DAP_DELETE(l_ret); + l_ret = NULL; + } + return l_ret; + } + return NULL; +} diff --git a/modules/net/dap_chain_node_client.c b/modules/net/dap_chain_node_client.c index 84d03e43b69081b38ff4302c70bf58ffb51650be..5646cb9a81b41e575b8b15c9b6cf78035cb114a7 100644 --- a/modules/net/dap_chain_node_client.c +++ b/modules/net/dap_chain_node_client.c @@ -477,6 +477,8 @@ dap_chain_node_client_t* dap_chain_client_connect(dap_chain_node_info_t *a_node_ l_node_client->remote_node_addr.uint64 = a_node_info->hdr.address.uint64; dap_client_set_active_channels(l_node_client->client, a_active_channels); + // dap_client_set_auth_cert(l_node_client->client, dap_cert_find_by_name("auth")); // TODO provide the certificate choice + int hostlen = 128; char host[hostlen]; if(a_node_info->hdr.ext_addr_v4.s_addr) diff --git a/modules/net/include/dap_chain_net.h b/modules/net/include/dap_chain_net.h index edcbffcbf3927be70cf4f4525f911a1659804566..941019b63282482e9f5c6cd61dc7d59b69c32412 100644 --- a/modules/net/include/dap_chain_net.h +++ b/modules/net/include/dap_chain_net.h @@ -102,6 +102,7 @@ void dap_chain_net_proc_mempool (dap_chain_net_t * a_net); dap_chain_net_t * dap_chain_net_by_name( const char * a_name); dap_chain_net_t * dap_chain_net_by_id( dap_chain_net_id_t a_id); +uint16_t dap_chain_net_acl_idx_by_id(dap_chain_net_id_t a_id); dap_chain_net_id_t dap_chain_net_id_by_name( const char * a_name); dap_ledger_t * dap_chain_ledger_by_net_name( const char * a_net_name);