diff --git a/commandline.c b/commandline.c index 74ed1da3..b8e1e469 100644 --- a/commandline.c +++ b/commandline.c @@ -2614,9 +2614,9 @@ struct cli_schema command_line_options[]={ "Return identity(s) as URIs of own node, or of known routable peers, or all known peers"}, {app_id_pin, {"id", "enter", "pin", "", NULL}, 0, "Unlock any pin protected identities and enable routing packets to them"}, - {app_revoke_pin, {"id", "revoke", "pin", "", NULL}, 0, + {app_revoke_pin, {"id", "relinquish", "pin", "", NULL}, 0, "Unload any identities protected by this pin and drop all routes to them"}, - {app_revoke_pin, {"id", "revoke", "sid", "", NULL}, 0, + {app_revoke_pin, {"id", "relinquish", "sid", "", NULL}, 0, "Unload a specific identity and drop all routes to it"}, {app_route_print, {"route","print",NULL}, 0, "Print the routing table"}, diff --git a/constants.h b/constants.h index 4a28f0b9..f99cc307 100644 --- a/constants.h +++ b/constants.h @@ -215,4 +215,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #define ENCAP_OVERLAY 1 #define ENCAP_SINGLE 2 +// numbers chosen to not conflict with KEYTYPE flags +#define UNLOCK_REQUEST (0xF0) +#define UNLOCK_CHALLENGE (0xF1) +#define UNLOCK_RESPONSE (0xF2) + + #endif // __SERVALD_CONSTANTS_H diff --git a/crypto.c b/crypto.c index 7a9060cd..ce048c67 100644 --- a/crypto.c +++ b/crypto.c @@ -43,6 +43,9 @@ int crypto_verify_message(struct subscriber *subscriber, unsigned char *message, return WHY("SAS key not currently on record, cannot verify"); } + if (*message_len < SIGNATURE_BYTES) + return WHY("Message is too short to include a signature"); + *message_len -= SIGNATURE_BYTES; unsigned char hash[crypto_hash_sha512_BYTES]; diff --git a/keyring.c b/keyring.c index 8af3ee1f..f9ce8821 100644 --- a/keyring.c +++ b/keyring.c @@ -27,6 +27,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "rhizome.h" #include "nacl.h" #include "overlay_address.h" +#include "crypto.h" +#include "overlay_packet.h" static void keyring_free_keypair(keypair *kp); static void keyring_free_context(keyring_context *c); @@ -182,11 +184,12 @@ static void add_subscriber(keyring_identity *id, unsigned keypair) assert(id->keypairs[keypair]->type == KEYTYPE_CRYPTOBOX); id->subscriber = find_subscriber(id->keypairs[keypair]->public_key, SID_SIZE, 1); if (id->subscriber) { - if (id->subscriber->reachable == REACHABLE_NONE) + if (id->subscriber->reachable == REACHABLE_NONE){ id->subscriber->reachable = REACHABLE_SELF; + if (!my_subscriber) + my_subscriber = id->subscriber; + } id->subscriber->identity = id; - if (!my_subscriber) - my_subscriber = id->subscriber; } } @@ -248,6 +251,14 @@ void keyring_release_identity(keyring_file *k, int cn, int id){ } } +void keyring_release_subscriber(keyring_file *k, const sid_t *sid) +{ + int cn=0,in=0,kp=0; + if (keyring_find_sid(keyring, &cn, &in, &kp, sid) + && keyring->contexts[cn]->identities[in]->subscriber != my_subscriber) + keyring_release_identity(keyring, cn, in); +} + static void keyring_free_context(keyring_context *c) { int i; @@ -288,11 +299,8 @@ void keyring_free_identity(keyring_identity *id) for(i=0;ikeypairs[i]) keyring_free_keypair(id->keypairs[i]); - if (id->subscriber) { - id->subscriber->identity=NULL; - if (id->subscriber->reachable == REACHABLE_SELF) - id->subscriber->reachable = REACHABLE_NONE; - } + if (id->subscriber) + link_stop_routing(id->subscriber); bzero(id,sizeof(keyring_identity)); free(id); return; @@ -1569,7 +1577,137 @@ static int keyring_store_sas(overlay_mdp_frame *req) return 0; } -int keyring_mapping_request(keyring_file *k, overlay_mdp_frame *req) +static int keyring_respond_sas(keyring_file *k, overlay_mdp_frame *req) +{ + /* It's a request, so find the SAS for the SID the request was addressed to, + use that to sign that SID, and then return it in an authcrypted frame. */ + unsigned char *sas_public=NULL; + unsigned char *sas_priv =keyring_find_sas_private(k, &req->out.dst.sid, &sas_public); + + if ((!sas_priv)||(!sas_public)) + return WHY("I don't have that SAS key"); + + unsigned long long slen; + /* type of key being verified */ + req->out.payload[0]=KEYTYPE_CRYPTOSIGN; + /* the public key itself */ + bcopy(sas_public,&req->out.payload[1], SAS_SIZE); + /* and a signature of the SID using the SAS key, to prove possession of + the key. Possession of the SID has already been established by the + decrypting of the surrounding MDP packet. + XXX - We could chop the SID out of the middle of the signed block here, + just as we do for signed MDP packets to save 32 bytes. We won't worry + about doing this, however, as the mapping process is only once per session, + not once per packet. Unless I get excited enough to do it, that is. + */ + if (crypto_sign_edwards25519sha512batch(&req->out.payload[1+SAS_SIZE], &slen, req->out.dst.sid.binary, SID_SIZE, sas_priv)) + return WHY("crypto_sign() failed"); + /* chop the SID from the end of the signature, since it can be reinserted on reception */ + slen-=SID_SIZE; + /* and record the full length of this */ + req->out.payload_length = 1 + SAS_SIZE + slen; + overlay_mdp_swap_src_dst(req); + req->out.ttl=0; + req->packetTypeAndFlags=MDP_TX; /* crypt and sign */ + req->out.queue=OQ_MESH_MANAGEMENT; + if (config.debug.keyring) + DEBUGF("Sending SID:SAS mapping, %d bytes, %s:%"PRImdp_port_t" -> %s:%"PRImdp_port_t, + req->out.payload_length, + alloca_tohex_sid_t(req->out.src.sid), req->out.src.port, + alloca_tohex_sid_t(req->out.dst.sid), req->out.dst.port + ); + return overlay_mdp_dispatch(req,0,NULL,0); +} + +// someone else is claiming to be me on this network +// politely request that they release my identity +int keyring_send_unlock(struct subscriber *subscriber) +{ + if (!subscriber->identity) + return WHY("Cannot unlock an identity we don't have in our keyring"); + if (subscriber->reachable==REACHABLE_SELF) + return 0; + + overlay_mdp_frame mdp; + memset(&mdp,0,sizeof(overlay_mdp_frame)); + + mdp.packetTypeAndFlags=MDP_TX; + mdp.out.queue=OQ_MESH_MANAGEMENT; + mdp.out.dst.sid = subscriber->sid; + mdp.out.dst.port=MDP_PORT_KEYMAPREQUEST; + mdp.out.src.port=MDP_PORT_KEYMAPREQUEST; + mdp.out.src.sid = my_subscriber->sid; + mdp.out.payload[0]=UNLOCK_REQUEST; + int len=1; + if (crypto_sign_message(subscriber, mdp.out.payload, sizeof(mdp.out.payload), &len)) + return -1; + mdp.out.payload_length=len; + return overlay_mdp_dispatch(&mdp, 0 /* system generated */, NULL, 0); +} + +static int keyring_send_challenge(struct subscriber *source, struct subscriber *dest) +{ + overlay_mdp_frame mdp; + memset(&mdp,0,sizeof(overlay_mdp_frame)); + + mdp.packetTypeAndFlags=MDP_TX; + mdp.out.queue=OQ_MESH_MANAGEMENT; + mdp.out.dst.sid = dest->sid; + mdp.out.dst.port=MDP_PORT_KEYMAPREQUEST; + mdp.out.src.port=MDP_PORT_KEYMAPREQUEST; + mdp.out.src.sid = source->sid; + mdp.out.payload_length=1; + mdp.out.payload[0]=UNLOCK_CHALLENGE; + + time_ms_t now = gettime_ms(); + if (source->identity->challenge_expires < now){ + source->identity->challenge_expires = now + 5000; + urandombytes(source->identity->challenge, sizeof(source->identity->challenge)); + } + bcopy(source->identity->challenge, &mdp.out.payload[1], sizeof(source->identity->challenge)); + mdp.out.payload_length+=sizeof(source->identity->challenge); + + return overlay_mdp_dispatch(&mdp, 0 /* system generated */, NULL, 0); +} + +static int keyring_respond_challenge(struct subscriber *subscriber, overlay_mdp_frame *req) +{ + if (!subscriber->identity) + return WHY("Cannot unlock an identity we don't have in our keyring"); + if (subscriber->reachable==REACHABLE_SELF) + return 0; + overlay_mdp_frame mdp; + memset(&mdp,0,sizeof(overlay_mdp_frame)); + + mdp.packetTypeAndFlags=MDP_TX; + mdp.out.queue=OQ_MESH_MANAGEMENT; + mdp.out.dst.sid = subscriber->sid; + mdp.out.dst.port=MDP_PORT_KEYMAPREQUEST; + mdp.out.src.port=MDP_PORT_KEYMAPREQUEST; + mdp.out.src.sid = my_subscriber->sid; + mdp.out.payload[0]=UNLOCK_RESPONSE; + bcopy(&req->out.payload[1], &mdp.out.payload[1], req->out.payload_length -1); + int len=req->out.payload_length; + if (crypto_sign_message(subscriber, mdp.out.payload, sizeof(mdp.out.payload), &len)) + return -1; + mdp.out.payload_length=len; + return overlay_mdp_dispatch(&mdp, 0 /* system generated */, NULL, 0); +} + +static int keyring_process_challenge(keyring_file *k, struct subscriber *subscriber, overlay_mdp_frame *req) +{ + time_ms_t now = gettime_ms(); + if (subscriber->identity->challenge_expires < now) + return WHY("Identity challenge has already expired"); + if (req->out.payload_length-1 != sizeof(subscriber->identity->challenge)) + return WHY("Challenge was not the right size"); + if (memcmp(&req->out.payload[1], subscriber->identity->challenge, sizeof(subscriber->identity->challenge))) + return WHY("Challenge failed"); + keyring_release_subscriber(k, &subscriber->sid); + return 0; +} + +int keyring_mapping_request(keyring_file *k, struct overlay_frame *frame, overlay_mdp_frame *req) { if (!k) return WHY("keyring is null"); if (!req) return WHY("req is null"); @@ -1578,46 +1716,32 @@ int keyring_mapping_request(keyring_file *k, overlay_mdp_frame *req) owner of the SID, and so is absolutely compulsory. */ if (req->packetTypeAndFlags&(MDP_NOCRYPT|MDP_NOSIGN)) return WHY("mapping requests must be performed under authcryption"); - - if (req->out.payload_length==1) { - /* It's a request, so find the SAS for the SID the request was addressed to, - use that to sign that SID, and then return it in an authcrypted frame. */ - unsigned char *sas_public=NULL; - unsigned char *sas_priv =keyring_find_sas_private(keyring, &req->out.dst.sid, &sas_public); - - if ((!sas_priv)||(!sas_public)) return WHY("I don't have that SAS key"); - unsigned long long slen; - /* type of key being verified */ - req->out.payload[0]=KEYTYPE_CRYPTOSIGN; - /* the public key itself */ - bcopy(sas_public,&req->out.payload[1], SAS_SIZE); - /* and a signature of the SID using the SAS key, to prove possession of - the key. Possession of the SID has already been established by the - decrypting of the surrounding MDP packet. - XXX - We could chop the SID out of the middle of the signed block here, - just as we do for signed MDP packets to save 32 bytes. We won't worry - about doing this, however, as the mapping process is only once per session, - not once per packet. Unless I get excited enough to do it, that is. - */ - if (crypto_sign_edwards25519sha512batch(&req->out.payload[1+SAS_SIZE], &slen, req->out.dst.sid.binary, SID_SIZE, sas_priv)) - return WHY("crypto_sign() failed"); - /* chop the SID from the end of the signature, since it can be reinserted on reception */ - slen-=SID_SIZE; - /* and record the full length of this */ - req->out.payload_length = 1 + SAS_SIZE + slen; - overlay_mdp_swap_src_dst(req); - req->out.ttl=0; - req->packetTypeAndFlags=MDP_TX; /* crypt and sign */ - req->out.queue=OQ_MESH_MANAGEMENT; - if (config.debug.keyring) - DEBUGF("Sending SID:SAS mapping, %d bytes, %s:%"PRImdp_port_t" -> %s:%"PRImdp_port_t, - req->out.payload_length, - alloca_tohex_sid_t(req->out.src.sid), req->out.src.port, - alloca_tohex_sid_t(req->out.dst.sid), req->out.dst.port - ); - return overlay_mdp_dispatch(req,0,NULL,0); - } else { - return keyring_store_sas(req); + + switch(req->out.payload[0]){ + case KEYTYPE_CRYPTOSIGN: + if (req->out.payload_length==1) + return keyring_respond_sas(k, req); + else + return keyring_store_sas(req); + break; + case UNLOCK_REQUEST: + { + int len = req->out.payload_length; + if (crypto_verify_message(frame->destination, req->out.payload, &len)) + return WHY("Signature check failed"); + req->out.payload_length = len; + } + return keyring_send_challenge(frame->destination, frame->source); + case UNLOCK_CHALLENGE: + return keyring_respond_challenge(frame->source, req); + case UNLOCK_RESPONSE: + { + int len = req->out.payload_length; + if (crypto_verify_message(frame->destination, req->out.payload, &len)) + return WHY("Signature check failed"); + req->out.payload_length = len; + } + return keyring_process_challenge(k, frame->destination, req); } return WHY("Not implemented"); } diff --git a/overlay_mdp.c b/overlay_mdp.c index d18800b1..135be70b 100644 --- a/overlay_mdp.c +++ b/overlay_mdp.c @@ -1000,10 +1000,7 @@ static int mdp_process_identity_request(struct mdp_client *client, struct mdp_he break; case TYPE_SID: while(payload_len>=SID_SIZE){ - int cn=0,in=0,kp=0; - if (keyring_find_sid(keyring, &cn, &in, &kp, (const sid_t *)payload) - && keyring->contexts[cn]->identities[in]->subscriber != my_subscriber) - keyring_release_identity(keyring, cn, in); + keyring_release_subscriber(keyring, (const sid_t*)payload); payload+=SID_SIZE; payload_len-=SID_SIZE; } diff --git a/overlay_mdp_services.c b/overlay_mdp_services.c index 5bd8317b..b3d42fc7 100644 --- a/overlay_mdp_services.c +++ b/overlay_mdp_services.c @@ -374,7 +374,7 @@ int overlay_mdp_try_interal_services(struct overlay_frame *frame, overlay_mdp_fr switch(mdp->out.dst.port) { case MDP_PORT_LINKSTATE: RETURN(link_receive(frame, mdp)); case MDP_PORT_VOMP: RETURN(vomp_mdp_received(mdp)); - case MDP_PORT_KEYMAPREQUEST: RETURN(keyring_mapping_request(keyring,mdp)); + case MDP_PORT_KEYMAPREQUEST: RETURN(keyring_mapping_request(keyring, frame, mdp)); case MDP_PORT_DNALOOKUP: RETURN(overlay_mdp_service_dnalookup(mdp)); case MDP_PORT_ECHO: RETURN(overlay_mdp_service_echo(mdp)); case MDP_PORT_TRACE: RETURN(overlay_mdp_service_trace(mdp)); diff --git a/rhizome.c b/rhizome.c index 3148d547..4c93ab17 100644 --- a/rhizome.c +++ b/rhizome.c @@ -103,7 +103,7 @@ int rhizome_bundle_import_files(rhizome_manifest *m, const char *manifest_path, if (ret==0){ buffer_len = read_uint16(marker); if (buffer_len < 1 || buffer_len > MAX_MANIFEST_BYTES) - ret=WHYF("Invalid manifest length %d", buffer_len); + ret=WHYF("Invalid manifest length %zd", buffer_len); } if (ret==0){ diff --git a/rhizome_bundle.c b/rhizome_bundle.c index 3075de8b..4cf1f7d3 100644 --- a/rhizome_bundle.c +++ b/rhizome_bundle.c @@ -93,7 +93,7 @@ ssize_t read_whole_file(const char *path, unsigned char *buffer, size_t buffer_s return WHYF_perror("open(%s,O_RDONLY)", alloca_str_toprint(path)); ssize_t ret = read(fd, buffer, buffer_size); if (ret == -1) - ret = WHYF_perror("read(%s,%u)", alloca_str_toprint(path), buffer_size); + ret = WHYF_perror("read(%s,%zu)", alloca_str_toprint(path), buffer_size); if (close(fd) == -1) ret = WHY_perror("close"); return ret; @@ -367,7 +367,7 @@ int rhizome_hash_file(rhizome_manifest *m, const char *path, rhizome_filehash_t ssize_t r; while ((r = read(fd, buffer, sizeof buffer))) { if (r == -1) { - WHYF_perror("read(%s,%u)", alloca_str_toprint(path), sizeof buffer); + WHYF_perror("read(%s,%zu)", alloca_str_toprint(path), sizeof buffer); close(fd); return -1; } diff --git a/rhizome_database.c b/rhizome_database.c index d559cd15..cef548ab 100644 --- a/rhizome_database.c +++ b/rhizome_database.c @@ -661,7 +661,7 @@ int _sqlite_vbind(struct __sourceloc __whence, int log_level, sqlite_retry_state BIND_NULL(SID_T); } else { const char *sid_hex = alloca_tohex_sid_t(*sidp); - BIND_DEBUG(SID_T, sqlite3_bind_text, "%s,%d,SQLITE_TRANSIENT", sid_hex, SID_STRLEN); + BIND_DEBUG(SID_T, sqlite3_bind_text, "%s,%u,SQLITE_TRANSIENT", sid_hex, SID_STRLEN); BIND_RETRY(sqlite3_bind_text, sid_hex, SID_STRLEN, SQLITE_TRANSIENT); } } @@ -673,7 +673,7 @@ int _sqlite_vbind(struct __sourceloc __whence, int log_level, sqlite_retry_state BIND_NULL(RHIZOME_BID_T); } else { const char *bid_hex = alloca_tohex_rhizome_bid_t(*bidp); - BIND_DEBUG(RHIZOME_BID_T, sqlite3_bind_text, "%s,%d,SQLITE_TRANSIENT", bid_hex, RHIZOME_MANIFEST_ID_STRLEN); + BIND_DEBUG(RHIZOME_BID_T, sqlite3_bind_text, "%s,%u,SQLITE_TRANSIENT", bid_hex, RHIZOME_MANIFEST_ID_STRLEN); BIND_RETRY(sqlite3_bind_text, bid_hex, RHIZOME_MANIFEST_ID_STRLEN, SQLITE_TRANSIENT); } } @@ -686,7 +686,7 @@ int _sqlite_vbind(struct __sourceloc __whence, int log_level, sqlite_retry_state } else { char hash_hex[RHIZOME_FILEHASH_STRLEN]; tohex(hash_hex, sizeof hash_hex, hashp->binary); - BIND_DEBUG(RHIZOME_FILEHASH_T, sqlite3_bind_text, "%s,%d,SQLITE_TRANSIENT", hash_hex, sizeof hash_hex); + BIND_DEBUG(RHIZOME_FILEHASH_T, sqlite3_bind_text, "%s,%zu,SQLITE_TRANSIENT", hash_hex, sizeof hash_hex); BIND_RETRY(sqlite3_bind_text, hash_hex, sizeof hash_hex, SQLITE_TRANSIENT); } } @@ -699,7 +699,7 @@ int _sqlite_vbind(struct __sourceloc __whence, int log_level, sqlite_retry_state BIND_NULL(TOHEX); } else { const char *hex = alloca_tohex(binary, bytes); - BIND_DEBUG(TOHEX, sqlite3_bind_text, "%s,%d,SQLITE_TRANSIENT", hex, bytes * 2); + BIND_DEBUG(TOHEX, sqlite3_bind_text, "%s,%u,SQLITE_TRANSIENT", hex, bytes * 2); BIND_RETRY(sqlite3_bind_text, hex, bytes * 2, SQLITE_TRANSIENT); } } @@ -713,7 +713,7 @@ int _sqlite_vbind(struct __sourceloc __whence, int log_level, sqlite_retry_state unsigned bytes = strlen(text); char upper[bytes + 1]; str_toupper_inplace(strcpy(upper, text)); - BIND_DEBUG(TEXT_TOUPPER, sqlite3_bind_text, "%s,%d,SQLITE_TRANSIENT", alloca_toprint(-1, upper, bytes), bytes); + BIND_DEBUG(TEXT_TOUPPER, sqlite3_bind_text, "%s,%u,SQLITE_TRANSIENT", alloca_toprint(-1, upper, bytes), bytes); BIND_RETRY(sqlite3_bind_text, upper, bytes, SQLITE_TRANSIENT); } } @@ -729,7 +729,7 @@ int _sqlite_vbind(struct __sourceloc __whence, int log_level, sqlite_retry_state unsigned i; for (i = 0; i != bytes; ++i) upper[i] = toupper(text[i]); - BIND_DEBUG(TEXT_LEN_TOUPPER, sqlite3_bind_text, "%s,%d,SQLITE_TRANSIENT", alloca_toprint(-1, upper, bytes), bytes); + BIND_DEBUG(TEXT_LEN_TOUPPER, sqlite3_bind_text, "%s,%u,SQLITE_TRANSIENT", alloca_toprint(-1, upper, bytes), bytes); BIND_RETRY(sqlite3_bind_text, upper, bytes, SQLITE_TRANSIENT); } } diff --git a/route_link.c b/route_link.c index 6a64923f..5fa4edec 100644 --- a/route_link.c +++ b/route_link.c @@ -357,7 +357,7 @@ static struct link * find_best_link(struct subscriber *subscriber) IN(); if (subscriber->reachable==REACHABLE_SELF) RETURN(NULL); - + struct link_state *state = get_link_state(subscriber); if (state->route_version == route_version) RETURN(state->link); @@ -420,11 +420,14 @@ next: if (next_hop == subscriber) next_hop = NULL; + if (set_reachable(subscriber, destination, next_hop)) changed = 1; - if (subscriber->identity && subscriber->reachable==REACHABLE_NONE){ + if (subscriber->identity && subscriber->reachable == REACHABLE_NONE){ subscriber->reachable=REACHABLE_SELF; + changed = 1; + best_link = NULL; if (config.debug.overlayrouting || config.debug.linkstate) DEBUGF("REACHABLE via self %s", alloca_tohex_sid_t(subscriber->sid)); } @@ -519,6 +522,8 @@ static int append_link(struct subscriber *subscriber, void *context) time_ms_t now = gettime_ms(); + struct link *best_link = find_best_link(subscriber); + if (subscriber->reachable==REACHABLE_SELF){ if (state->next_update - INCLUDE_ANYWAY <= now){ // Other entries in our keyring are always one hop away from us. @@ -530,8 +535,10 @@ static int append_link(struct subscriber *subscriber, void *context) state->next_update = now + 5000; } } else { - struct link *best_link = find_best_link(subscriber); - + + if (subscriber->identity) + keyring_send_unlock(subscriber); + if (state->next_update - INCLUDE_ANYWAY <= now){ if (append_link_state(payload, 0, state->transmitter, subscriber, -1, best_link?best_link->link_version:-1, -1, 0, best_link?best_link->drop_rate:32)){ @@ -909,6 +916,20 @@ static void update_alarm(time_ms_t limit){ } } +int link_stop_routing(struct subscriber *subscriber) +{ + if (subscriber->reachable!=REACHABLE_SELF) + return 0; + subscriber->reachable = REACHABLE_NONE; + subscriber->identity=NULL; + if (subscriber==my_subscriber) + my_subscriber=NULL; + struct link_state *state = get_link_state(subscriber); + state->next_update = gettime_ms(); + update_alarm(state->next_update); + return 0; +} + struct link_in * get_neighbour_link(struct neighbour *neighbour, struct overlay_interface *interface, int sender_interface, int unicast) { struct link_in *link = neighbour->links; @@ -1174,7 +1195,7 @@ int link_received_packet(struct decode_context *context, int sender_seq, char un // force an update when we start hearing a new neighbour link if (link->link_timeout < now){ - if (neighbour->next_neighbour_update > now + 10); + if (neighbour->next_neighbour_update > now + 10) neighbour->next_neighbour_update = now + 10; } link->link_timeout = now + (context->interface->destination->tick_ms *5); diff --git a/serval.h b/serval.h index 3dc44809..c990ebc8 100644 --- a/serval.h +++ b/serval.h @@ -263,6 +263,8 @@ typedef struct keypair { typedef struct keyring_identity { char *PKRPin; struct subscriber *subscriber; + time_ms_t challenge_expires; + unsigned char challenge[24]; unsigned int slot; unsigned int keypair_count; keypair *keypairs[PKR_MAX_KEYPAIRS]; @@ -700,7 +702,9 @@ typedef struct overlay_mdp_frame { }; } overlay_mdp_frame; -int keyring_mapping_request(keyring_file *k,overlay_mdp_frame *req); +int keyring_mapping_request(keyring_file *k, struct overlay_frame *frame, overlay_mdp_frame *req); +int keyring_send_unlock(struct subscriber *subscriber); +void keyring_release_subscriber(keyring_file *k, const sid_t *sid); /* Server-side MDP functions */ int overlay_mdp_swap_src_dst(overlay_mdp_frame *mdp); @@ -909,6 +913,7 @@ int link_unicast_ack(struct subscriber *subscriber, struct overlay_interface *in int link_add_destinations(struct overlay_frame *frame); void link_neighbour_short_status_html(struct strbuf *b, const char *link_prefix); void link_neighbour_status_html(struct strbuf *b, struct subscriber *neighbour); +int link_stop_routing(struct subscriber *subscriber); int generate_nonce(unsigned char *nonce,int bytes); diff --git a/tests/keyring b/tests/keyring index 4c93ff67..dc4ff125 100755 --- a/tests/keyring +++ b/tests/keyring @@ -235,13 +235,13 @@ test_KeyringEntryPinServer() { assertStdoutGrep --fixed-strings "$ONE" assertStdoutGrep --fixed-strings "$TWOA" assertStdoutGrep --fixed-strings "$TWOB" - executeOk_servald id revoke pin 'one' + executeOk_servald id relinquish pin 'one' executeOk_servald id self assertStdoutLineCount == 3 assertStdoutGrep --fixed-strings "$SIDA" assertStdoutGrep --fixed-strings "$TWOA" assertStdoutGrep --fixed-strings "$TWOB" - executeOk_servald id revoke sid "$TWOB" + executeOk_servald id relinquish sid "$TWOB" tfw_cat --stderr executeOk_servald id self assertStdoutLineCount == 2 diff --git a/tests/routing b/tests/routing index 299a36f4..8b15cbbd 100755 --- a/tests/routing +++ b/tests/routing @@ -164,7 +164,7 @@ test_unlock_ids() { executeOk_servald id enter pin 'entry-pin' wait_until has_link +B +A +A $SIDA $SIDX set_instance +A - executeOk_servald id revoke pin 'entry-pin' + executeOk_servald id relinquish pin 'entry-pin' set_instance +B wait_until --timeout=30 sid_offline $SIDX } @@ -192,8 +192,6 @@ test_migrate_id() { wait_until has_link +B +A +A $SIDA $SIDX set_instance +B executeOk_servald id enter pin 'entry-pin' - set_instance +A - executeOk_servald id revoke pin 'entry-pin' wait_until --timeout=30 has_link +A +B +B $SIDB $SIDX } diff --git a/version_string.sh b/version_string.sh index 066a2816..0a7cd3df 100755 --- a/version_string.sh +++ b/version_string.sh @@ -17,6 +17,11 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +if [ ! -e .git ]; then + echo "UNKNOWN-VERSION" + exit +fi + usage() { echo "Usage: ${0##*/} [options]"'