generalized auth scheme handling (#624)

This commit is contained in:
Logan oos Even
2021-02-03 20:52:41 +05:45
committed by GitHub
parent b3a4eac4d7
commit 08a4e332c8
2 changed files with 81 additions and 23 deletions
+33 -12
View File
@@ -266,20 +266,18 @@ n2n_edge_t* edge_init (const n2n_edge_conf_t *conf, int *rv) {
if(eee->transop.no_encryption)
traceEvent(TRACE_WARNING, "Encryption is disabled in edge");
// setup authenitcation scheme
eee->conf.auth.scheme = n2n_auth_simple_id;
for(idx = 0; idx < N2N_AUTH_TOKEN_SIZE; ++idx) {
eee->conf.auth.token[idx] = n2n_rand() % 0xff;
}
eee->conf.auth.toksize = sizeof(eee->conf.auth.token);
// first time calling edge_init_sockets needs -1 in the sockets for it does throw an error
// on trying to close them (open_sockets does so for also being able to RE-open the sockets
// if called in-between, see "Supernode not responding" in update_supernode_reg(...)
eee->udp_sock = -1;
eee->udp_mgmt_sock = -1;
eee->conf.auth.scheme = n2n_auth_simple_id;
for(idx = 0; idx < N2N_AUTH_TOKEN_SIZE; ++idx) {
eee->conf.auth.token[idx] = n2n_rand() % 0xff;
}
eee->conf.auth.toksize = sizeof(eee->conf.auth.token);
#ifndef SKIP_MULTICAST_PEERS_DISCOVERY
eee->udp_multicast_sock = -1;
#endif
@@ -616,6 +614,27 @@ static void peer_set_p2p_confirmed (n2n_edge_t * eee,
traceEvent(TRACE_DEBUG, "Failed to find sender in pending_peers.");
}
// provides the current / a new local auth token
// REVISIT: behavior should depend on some local auth scheme setting (to be implemented)
static int get_local_auth (n2n_edge_t *eee, n2n_auth_t *auth) {
// n2n_auth_simple_id scheme
memcpy(auth, &(eee->conf.auth), sizeof(n2n_auth_t));
return 0;
}
// handles an returning (remote) auth token, takes action as required by auth scheme, and
// REVISIT: behavior should depend on some local auth scheme setting (to be implemented)
static int handle_remote_auth (n2n_edge_t *eee, struct peer_info *peer, const n2n_auth_t *remote_auth) {
// n2n_auth_simple_id scheme: no action required
return 0;
}
/* ************************************** */
int is_empty_ip_address (const n2n_sock_t * sock) {
@@ -869,7 +888,7 @@ void send_register_super (n2n_edge_t *eee) {
reg.dev_addr.net_addr = ntohl(eee->device.ip_addr);
reg.dev_addr.net_bitlen = mask2bitlen(ntohl(eee->device.device_mask));
memcpy(reg.dev_desc, eee->conf.dev_desc, N2N_DESC_SIZE);
memcpy(&(reg.auth), &(eee->conf.auth), sizeof(n2n_auth_t));
get_local_auth(eee, &(reg.auth));
idx = 0;
encode_mac(reg.edgeMac, &idx, eee->device.mac_addr);
@@ -905,8 +924,7 @@ static void send_unregister_super (n2n_edge_t *eee) {
cmn.pc = n2n_unregister_super;
cmn.flags = 0;
memcpy(cmn.community, eee->conf.community_name, N2N_COMMUNITY_SIZE);
memcpy(&(unreg.auth), &(eee->conf.auth), sizeof(n2n_auth_t));
get_local_auth(eee, &(unreg.auth));
idx = 0;
encode_mac(unreg.srcMac, &idx, eee->device.mac_addr);
@@ -2163,8 +2181,11 @@ void readFromIPSocket (n2n_edge_t * eee, int in_sock) {
if(0 == memcmp(ra.cookie, eee->curr_sn->last_cookie, N2N_COOKIE_SIZE)) {
handle_remote_auth(eee, sn, &(ra.auth));
payload = (n2n_REGISTER_SUPER_ACK_payload_t*)tmpbuf;
// from here on, 'sn' gets used differently
for(i = 0; i < ra.num_sn; i++) {
skip_add = SN_ADD;
sn = add_sn_to_list_by_mac_or_sock(&(eee->conf.supernodes), &(payload->sock), payload->mac, &skip_add);
+48 -11
View File
@@ -52,6 +52,7 @@ static int update_edge (n2n_sn_t *sss,
const n2n_REGISTER_SUPER_t* reg,
struct sn_community *comm,
const n2n_sock_t *sender_sock,
n2n_auth_t *answer_auth,
int skip_add,
time_t now);
@@ -288,11 +289,9 @@ int sn_init(n2n_sn_t *sss) {
/* Random auth token */
sss->auth.scheme = n2n_auth_simple_id;
for(idx = 0; idx < N2N_AUTH_TOKEN_SIZE; ++idx) {
sss->auth.token[idx] = n2n_rand() % 0xff;
}
sss->auth.toksize = sizeof(sss->auth.token);
/* Random MAC address */
@@ -357,22 +356,60 @@ static uint16_t reg_lifetime (n2n_sn_t *sss) {
return 15;
}
/** Compare two authentication tokens. It is called by update_edge
* and in UNREGISTER_SUPER handling to compare the stored auth token
* with the one received from the packet.
*/
static int auth_edge (const n2n_auth_t *auth1, const n2n_auth_t *auth2) {
static int auth_edge (const n2n_auth_t *auth1, const n2n_auth_t *auth2, n2n_auth_t *answer_auth) {
/* 0 = success (tokens are equal). */
return (memcmp(auth1, auth2, sizeof(n2n_auth_t)));
if((auth1->scheme == n2n_auth_simple_id) && (auth2->scheme == n2n_auth_simple_id)) {
// n2n_auth_simple_id scheme: if required, zero_token answer (not for NAK)
if(answer_auth)
memset(answer_auth, 0, sizeof(n2n_auth_t));
// 0 = success (tokens are equal)
return (memcmp(auth1, auth2, sizeof(n2n_auth_t)));
}
// if not successful earlier: failure
return -1;
}
// provides the current / a new local auth token
// REVISIT: behavior should depend on some local auth scheme setting (to be implemented)
static int get_local_auth (n2n_sn_t *sss, n2n_auth_t *auth) {
// n2n_auth_simple_id scheme
memcpy(auth, &(sss->auth), sizeof(n2n_auth_t));
return 0;
}
// handles an incoming (remote) auth token, takes action as required by auth scheme, and
// could provide an answer auth token for use in REGISTER_SUPER_ACK
// REVISIT: behavior should depend on some local auth scheme setting (to be implemented)
static int handle_remote_auth (n2n_sn_t *sss, struct peer_info *peer, const n2n_auth_t *remote_auth,
n2n_auth_t *answer_auth) {
// n2n_auth_simple_id scheme: store the arrived token
memcpy(&(peer->auth), remote_auth, sizeof(n2n_auth_t));
// n2n_auth_simple_id scheme: zero_token answer
memset(answer_auth, 0, sizeof(n2n_auth_t));
return 0;
}
/** Update the edge table with the details of the edge which contacted the
* supernode. */
static int update_edge (n2n_sn_t *sss,
const n2n_REGISTER_SUPER_t* reg,
struct sn_community *comm,
const n2n_sock_t *sender_sock,
n2n_auth_t *answer_auth,
int skip_add,
time_t now) {
@@ -411,7 +448,7 @@ static int update_edge (n2n_sn_t *sss,
memcpy((char*)scan->dev_desc, reg->dev_desc, N2N_DESC_SIZE);
memcpy(&(scan->sock), sender_sock, sizeof(n2n_sock_t));
memcpy(&(scan->last_cookie), reg->cookie, sizeof(N2N_COOKIE_SIZE));
memcpy(&(scan->auth), &(reg->auth), sizeof(n2n_auth_t));
handle_remote_auth(sss, scan, &(reg->auth), answer_auth);
scan->last_valid_time_stamp = initial_time_stamp();
HASH_ADD_PEER(comm->edges, scan);
@@ -424,7 +461,7 @@ static int update_edge (n2n_sn_t *sss,
} else {
/* Known */
if(!sock_equal(sender_sock, &(scan->sock))) {
if((auth = auth_edge(&(scan->auth), &(reg->auth))) == 0) {
if((auth = auth_edge(&(scan->auth), &(reg->auth), answer_auth)) == 0) {
memcpy(&(scan->sock), sender_sock, sizeof(n2n_sock_t));
memcpy(&(scan->last_cookie), reg->cookie, sizeof(N2N_COOKIE_SIZE));
@@ -696,7 +733,7 @@ static int re_register_and_purge_supernodes (n2n_sn_t *sss, struct sn_community
memcpy(reg.cookie, cookie, N2N_COOKIE_SIZE);
reg.dev_addr.net_addr = ntohl(peer->dev_addr.net_addr);
reg.dev_addr.net_bitlen = mask2bitlen(ntohl(peer->dev_addr.net_bitlen));
memcpy(&(reg.auth), &(sss->auth), sizeof(n2n_auth_t));
get_local_auth(sss, &(reg.auth));
idx = 0;
encode_mac(reg.edgeMac, &idx, sss->mac_addr);
@@ -1340,9 +1377,9 @@ static int process_udp (n2n_sn_t * sss,
if(!is_null_mac(reg.edgeMac)) {
if(cmn.flags & N2N_FLAGS_SOCKET) {
ret_value = update_edge(sss, &reg, comm, &(ack.sock), SN_ADD_SKIP, now);
ret_value = update_edge(sss, &reg, comm, &(ack.sock), &(ack.auth), SN_ADD_SKIP, now);
} else {
ret_value = update_edge(sss, &reg, comm, &(ack.sock), SN_ADD, now);
ret_value = update_edge(sss, &reg, comm, &(ack.sock), &(ack.auth), SN_ADD, now);
}
}
@@ -1451,7 +1488,7 @@ static int process_udp (n2n_sn_t * sss,
HASH_FIND_PEER(comm->edges, unreg.srcMac, peer);
if(peer != NULL) {
if((auth = auth_edge(&(peer->auth), &unreg.auth)) == 0) {
if((auth = auth_edge(&(peer->auth), &unreg.auth, NULL)) == 0) {
HASH_DEL(comm->edges, peer);
}
}