diff --git a/src/edge_utils.c b/src/edge_utils.c index 306e0f4..983fb4f 100644 --- a/src/edge_utils.c +++ b/src/edge_utils.c @@ -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); diff --git a/src/sn_utils.c b/src/sn_utils.c index e84a464..c180afa 100644 --- a/src/sn_utils.c +++ b/src/sn_utils.c @@ -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, ®, comm, &(ack.sock), SN_ADD_SKIP, now); + ret_value = update_edge(sss, ®, comm, &(ack.sock), &(ack.auth), SN_ADD_SKIP, now); } else { - ret_value = update_edge(sss, ®, comm, &(ack.sock), SN_ADD, now); + ret_value = update_edge(sss, ®, 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); } }