From 83b6ecb453cd4a326c33d2457ce28397164328f0 Mon Sep 17 00:00:00 2001 From: Jeremy Lakeman Date: Wed, 15 Jun 2016 17:08:25 +0930 Subject: [PATCH] Roll an in memory identity when the keyring is empty --- dna_helper.c | 7 +-- keyring.c | 121 +++++++++++++++++++--------------------- keyring.h | 3 +- monitor.c | 11 +--- overlay_address.c | 35 +++++++++--- overlay_address.h | 3 +- overlay_link.c | 8 +-- overlay_mdp.c | 10 ++-- overlay_mdp_services.c | 8 +-- overlay_olsr.c | 4 +- overlay_packetformats.c | 8 +-- overlay_queue.c | 2 +- rhizome_fetch.c | 7 +-- rhizome_packetformats.c | 4 +- rhizome_sync.c | 6 +- rhizome_sync_keys.c | 4 +- route_link.c | 44 +++++++-------- server.c | 23 ++++---- server_httpd.c | 2 +- tests/keyring | 45 +++++++++++---- 20 files changed, 190 insertions(+), 165 deletions(-) diff --git a/dna_helper.c b/dna_helper.c index 63868b41..de0285f5 100644 --- a/dna_helper.c +++ b/dna_helper.c @@ -183,10 +183,7 @@ dna_helper_start() return 0; } - if (!my_subscriber) - return WHY("Unable to lookup my SID"); - - const char *mysid = alloca_tohex_sid_t(my_subscriber->sid); + const char *mysid = alloca_tohex_sid_t(get_my_subscriber()->sid); int stdin_fds[2], stdout_fds[2], stderr_fds[2]; if (pipe(stdin_fds) == -1) @@ -452,7 +449,7 @@ void handle_reply_line(const char *bufp, size_t len) WHYF("DNAHELPER reply %s contains spurious trailing chars -- ignored", alloca_toprint(-1, bufp, len)); else { DEBUGF(dnahelper, "DNAHELPER reply %s", alloca_toprint(-1, bufp, len)); - overlay_mdp_dnalookup_reply(request_source, request_port, my_subscriber, uri, did, name); + overlay_mdp_dnalookup_reply(request_source, request_port, get_my_subscriber(), uri, did, name); } } } else { diff --git a/keyring.c b/keyring.c index 6c061689..627aed99 100644 --- a/keyring.c +++ b/keyring.c @@ -42,8 +42,8 @@ static int keyring_initialise(keyring_file *k); static int keyring_load(keyring_file *k, const char *pin); static keyring_file *keyring_open_create_instance(const char *pin, int force_create); static void keyring_free_keypair(keypair *kp); -static void keyring_free_identity(keyring_identity *id); static int keyring_identity_mac(const keyring_identity *id, unsigned char *pkrsalt, unsigned char *mac); +static int keyring_commit_identity(keyring_file *k, keyring_identity *id); struct combined_pk{ uint8_t sign_key[crypto_sign_PUBLICKEYBYTES]; @@ -292,11 +292,8 @@ static void add_subscriber(keyring_identity *id) id->subscriber = find_subscriber(id->box_pk->binary, SID_SIZE, 1); if (id->subscriber) { // TODO flag for unroutable identities...? - 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 (id->sign_pk){ @@ -398,8 +395,6 @@ int keyring_release_subscriber(keyring_file *k, const sid_t *sid) if (!keyring_find_sid(&it, sid)) return WHYF("Keyring entry for %s not found", alloca_tohex_sid_t(*sid)); - if (it.identity->subscriber == my_subscriber) - return WHYF("Cannot release my main subscriber"); return keyring_release_identity(&it); } @@ -473,7 +468,8 @@ static int keyring_munge_block( infeasible */ ofs=0; APPEND(PKRSalt,PKRSaltLen); - APPEND(PKRPin,strlen(PKRPin)); + if (PKRPin) + APPEND(PKRPin,strlen(PKRPin)); APPEND(PKRSalt,PKRSaltLen); APPEND(KeyRingPin,strlen(KeyRingPin)); crypto_hash_sha512(hashKey,work,ofs); @@ -483,7 +479,8 @@ static int keyring_munge_block( APPEND(KeyRingPin,strlen(KeyRingPin)); APPEND(KeyRingSalt,KeyRingSaltLen); APPEND(KeyRingPin,strlen(KeyRingPin)); - APPEND(PKRPin,strlen(PKRPin)); + if (PKRPin) + APPEND(PKRPin,strlen(PKRPin)); crypto_hash_sha512(hashNonce,work,ofs); /* Now en/de-crypt the remainder of the block. @@ -1107,7 +1104,8 @@ static keyring_identity *keyring_unpack_identity(unsigned char *slot, const char keyring_identity *id = emalloc_zero(sizeof(keyring_identity)); if (!id) return NULL; - id->PKRPin = str_edup(pin); + if (pin && *pin) + id->PKRPin = str_edup(pin); // The two bytes immediately following the MAC describe the rotation offset. uint16_t rotation = (slot[PKR_SALT_BYTES + PKR_MAC_BYTES] << 8) | slot[PKR_SALT_BYTES + PKR_MAC_BYTES + 1]; /* Pack the key pairs into the rest of the slot as a rotated buffer. */ @@ -1218,13 +1216,14 @@ static int keyring_identity_mac(const keyring_identity *id, unsigned char *pkrsa DEBUG(keyring,"Identity does not have a primary key"); return -1; } - APPEND(id->PKRPin, strlen(id->PKRPin)); + if (id->PKRPin) + APPEND(id->PKRPin, strlen(id->PKRPin)); #undef APPEND crypto_hash_sha512(mac, work, ofs); return 0; } -static int keyring_finalise_identity(keyring_file *k, keyring_identity *id) +static int keyring_finalise_identity(uint8_t *dirty, keyring_identity *id) { keypair *kp = id->keypairs; while(kp){ @@ -1239,7 +1238,8 @@ static int keyring_finalise_identity(keyring_file *k, keyring_identity *id) so replace it */ WARN("SAS key is invalid -- regenerating."); crypto_sign_keypair(kp->public_key, kp->private_key); - k->dirty = 1; + if (dirty) + *dirty = 1; } id->sign_pk = kp->public_key; id->sign_sk = kp->private_key; @@ -1300,16 +1300,9 @@ static int keyring_decrypt_pkr(keyring_file *k, const char *pin, int slot_number goto kdp_safeexit; } - if (keyring_finalise_identity(k, id)!=0) + if (keyring_commit_identity(k, id)!=1) goto kdp_safeexit; - add_subscriber(id); - - /* All fine, so add the id into the context and return. */ - keyring_identity **i=&k->identities; - while(*i) - i=&(*i)->next; - *i=id; return 0; kdp_safeexit: @@ -1333,7 +1326,10 @@ int keyring_enter_pin(keyring_file *k, const char *pin) int identitiesFound=0; keyring_identity *id = k->identities; while(id){ - if (strcmp(id->PKRPin, pin) == 0) + if (pin && *pin){ + if (id->PKRPin && strcmp(id->PKRPin, pin) == 0) + identitiesFound++; + }else if(!id->PKRPin) identitiesFound++; id=id->next; } @@ -1410,7 +1406,7 @@ static unsigned find_free_slot(const keyring_file *k) static int keyring_commit_identity(keyring_file *k, keyring_identity *id) { - keyring_finalise_identity(k, id); + keyring_finalise_identity(&k->dirty, id); // Do nothing if an identity with this sid already exists keyring_iterator it; keyring_iterator_start(k, &it); @@ -1427,6 +1423,37 @@ static int keyring_commit_identity(keyring_file *k, keyring_identity *id) return 1; } +static keyring_identity *keyring_new_identity() +{ + keyring_identity *id = emalloc_zero(sizeof(keyring_identity)); + if (!id) + return NULL; + + /* Allocate key pairs */ + unsigned ktype; + for (ktype = 1; ktype < NELS(keytypes); ++ktype) { + if (keytypes[ktype].creator) { + keypair *kp = keyring_alloc_keypair(ktype, 0); + if (kp == NULL){ + keyring_free_identity(id); + return NULL; + } + keytypes[ktype].creator(kp); + keyring_identity_add_keypair(id, kp); + } + } + assert(id->keypairs); + return id; +} + +keyring_identity *keyring_inmemory_identity(){ + keyring_identity *id = keyring_new_identity(); + keyring_finalise_identity(NULL, id); + if (id) + add_subscriber(id); + return id; +} + /* Create a new identity in the specified context (which supplies the keyring pin) with the * specified PKR pin. The crypto_box and crypto_sign key pairs are automatically created, and the * PKR is packed and written to a hithero unallocated slot which is then marked full. Requires an @@ -1440,12 +1467,12 @@ keyring_identity *keyring_create_identity(keyring_file *k, const char *pin) if (!pin) pin=""; - keyring_identity *id = emalloc_zero(sizeof(keyring_identity)); + keyring_identity *id = keyring_new_identity(); if (!id) - return NULL; + goto kci_safeexit; /* Remember pin */ - if (!(id->PKRPin = str_edup(pin))) + if (pin && *pin && !(id->PKRPin = str_edup(pin))) goto kci_safeexit; /* Find free slot in keyring. */ @@ -1455,19 +1482,6 @@ keyring_identity *keyring_create_identity(keyring_file *k, const char *pin) goto kci_safeexit; } - /* Allocate key pairs */ - unsigned ktype; - for (ktype = 1; ktype < NELS(keytypes); ++ktype) { - if (keytypes[ktype].creator) { - keypair *kp = keyring_alloc_keypair(ktype, 0); - if (kp == NULL) - goto kci_safeexit; - keytypes[ktype].creator(kp); - keyring_identity_add_keypair(id, kp); - } - } - assert(id->keypairs); - /* Mark slot as occupied and internalise new identity. */ if (keyring_commit_identity(k, id)!=1) goto kci_safeexit; @@ -1777,7 +1791,7 @@ int keyring_send_unlock(struct subscriber *subscriber) struct internal_mdp_header header; bzero(&header, sizeof header); - header.source = my_subscriber; + header.source = get_my_subscriber(); header.destination = subscriber; header.source_port = MDP_PORT_KEYMAPREQUEST; header.destination_port = MDP_PORT_KEYMAPREQUEST; @@ -1803,9 +1817,6 @@ int keyring_send_unlock(struct subscriber *subscriber) static int keyring_send_challenge(struct subscriber *source, struct subscriber *dest) { - if (source == my_subscriber) - return WHY("Cannot release my main subscriber"); - struct internal_mdp_header header; bzero(&header, sizeof header); @@ -1856,7 +1867,7 @@ static int keyring_respond_challenge(struct subscriber *subscriber, struct overl struct internal_mdp_header header; bzero(&header, sizeof header); - header.source = my_subscriber; + header.source = get_my_subscriber(); header.destination = subscriber; header.source_port = MDP_PORT_KEYMAPREQUEST; header.destination_port = MDP_PORT_KEYMAPREQUEST; @@ -1947,16 +1958,13 @@ int keyring_send_sas_request(struct subscriber *subscriber){ return 0; } - if (!my_subscriber) - return WHY("couldn't request SAS (I don't know who I am)"); - DEBUGF(keyring, "Requesting SAS mapping for SID=%s", alloca_tohex_sid_t(subscriber->sid)); /* request mapping (send request auth-crypted). */ struct internal_mdp_header header; bzero(&header, sizeof header); - header.source = my_subscriber; + header.source = get_my_subscriber(); header.destination = subscriber; header.source_port = MDP_PORT_KEYMAPREQUEST; header.destination_port = MDP_PORT_KEYMAPREQUEST; @@ -2049,21 +2057,6 @@ keyring_file *keyring_open_instance_cli(const struct cli_parsed *parsed) OUT(); } -/* If no identities, create an initial identity with a phone number. - This identity will not be pin protected (initially). */ -int keyring_seed(keyring_file *k) -{ - /* nothing to do if there is already an identity */ - if (k->identities) - return 0; - keyring_identity *id=keyring_create_identity(k,""); - if (!id) - return WHY("Could not create new identity"); - if (keyring_commit(k)) - return WHY("Could not commit new identity to keyring file"); - return 0; -} - /* The CryptoBox function of NaCl involves a scalar mult operation between the public key of the recipient and the private key of the sender (or vice versa). @@ -2237,7 +2230,7 @@ int keyring_load_from_dump(keyring_file *k, unsigned entry_pinc, const char **en keyring_free_keypair(kp); return -1; } - if ((id->PKRPin = str_edup(pini < entry_pinc ? entry_pinv[pini++] : "")) == NULL) { + if (pini < entry_pinc && (id->PKRPin = str_edup(entry_pinv[pini++])) == NULL) { keyring_free_keypair(kp); keyring_free_identity(id); return -1; diff --git a/keyring.h b/keyring.h index d595a835..17ad23af 100644 --- a/keyring.h +++ b/keyring.h @@ -122,8 +122,9 @@ int keyring_sign_message(struct keyring_identity *identity, unsigned char *conte int keyring_send_sas_request(struct subscriber *subscriber); int keyring_commit(keyring_file *k); +keyring_identity *keyring_inmemory_identity(); +void keyring_free_identity(keyring_identity *id); keyring_identity *keyring_create_identity(keyring_file *k, const char *pin); -int keyring_seed(keyring_file *k); void keyring_identity_extract(const keyring_identity *id, const char **didp, const char **namep); int keyring_load_from_dump(keyring_file *k, unsigned entry_pinc, const char **entry_pinv, FILE *input); int keyring_dump(keyring_file *k, XPRINTF xpf, int include_secret); diff --git a/monitor.c b/monitor.c index 4505136d..3c908747 100644 --- a/monitor.c +++ b/monitor.c @@ -487,9 +487,6 @@ static int monitor_lookup_match(const struct cli_parsed *parsed, struct cli_cont const char *ext = parsed->args[4]; const char *name = parsed->argc >= 4 ? parsed->args[5] : ""; - if (!my_subscriber) - return monitor_write_error(c,"I don't know who I am"); - mdp_port_t dest_port = atoi(parsed->args[3]); sid_t dest; if (str_to_sid_t(&dest, sid) == -1) @@ -498,9 +495,9 @@ static int monitor_lookup_match(const struct cli_parsed *parsed, struct cli_cont struct subscriber *destination = find_subscriber(dest.binary, sizeof(dest), 1); char uri[256]; - snprintf(uri, sizeof(uri), "sid://%s/external/%s", alloca_tohex_sid_t(my_subscriber->sid), ext); + snprintf(uri, sizeof(uri), "sid://%s/external/%s", alloca_tohex_sid_t(get_my_subscriber()->sid), ext); DEBUGF(monitor, "Sending response to %s for %s", sid, uri); - overlay_mdp_dnalookup_reply(destination, dest_port, my_subscriber, uri, ext, name); + overlay_mdp_dnalookup_reply(destination, dest_port, get_my_subscriber(), uri, ext, name); return 0; } @@ -510,10 +507,8 @@ static int monitor_call(const struct cli_parsed *parsed, struct cli_context *con sid_t sid; if (str_to_sid_t(&sid, parsed->args[1]) == -1) return monitor_write_error(c,"invalid SID, so cannot place call"); - if (!my_subscriber) - return monitor_write_error(c,"I don't know who I am"); struct subscriber *remote = find_subscriber(sid.binary, SID_SIZE, 1); - vomp_dial(my_subscriber, remote, parsed->args[2], parsed->args[3]); + vomp_dial(get_my_subscriber(), remote, parsed->args[2], parsed->args[3]); return 0; } diff --git a/overlay_address.c b/overlay_address.c index defe4aee..db761af6 100644 --- a/overlay_address.c +++ b/overlay_address.c @@ -62,7 +62,29 @@ struct tree_node{ static __thread struct tree_node root; -__thread struct subscriber *my_subscriber=NULL; +static __thread struct subscriber *my_subscriber=NULL; + +struct subscriber *get_my_subscriber(){ + if (!serverMode) + return NULL; + if (my_subscriber && my_subscriber->reachable != REACHABLE_SELF) + my_subscriber = NULL; + if (!my_subscriber){ + keyring_identity *id = keyring->identities; + while(id && id->subscriber->reachable != REACHABLE_SELF) + id = id->next; + if (!id) + id = keyring_inmemory_identity(); + my_subscriber = id->subscriber; + } + return my_subscriber; +} + +void release_my_subscriber(){ + if (my_subscriber && my_subscriber->identity->slot==0) + keyring_free_identity(my_subscriber->identity); + my_subscriber = NULL; +} static unsigned char get_nibble(const unsigned char *sidp, int pos) { @@ -266,7 +288,7 @@ void overlay_address_append(struct decode_context *context, struct overlay_buffe ob_append_byte(b, OA_CODE_P2P_YOU); else if(context && !subscriber->send_full - && subscriber == my_subscriber + && subscriber == get_my_subscriber() && context->point_to_point_device && ((context->flags & DECODE_FLAG_ENCODING_HEADER)==0 || !context->interface->local_echo)) ob_append_byte(b, OA_CODE_P2P_ME); @@ -316,7 +338,7 @@ static int add_explain_response(struct subscriber *subscriber, void *context) // if our primary routing identities is unknown, // the header of this packet must include our full sid. - if (subscriber==my_subscriber){ + if (subscriber==get_my_subscriber()){ DEBUGF(subscriber, "Explaining SELF sid=%s", alloca_tohex_sid_t(subscriber->sid)); response->please_explain->source_full=1; return 0; @@ -431,8 +453,7 @@ int overlay_address_parse(struct decode_context *context, struct overlay_buffer case OA_CODE_P2P_YOU: // if we don't know who they are, we can't assume they mean us. if (context->point_to_point_device){ - *subscriber=my_subscriber; - context->previous=my_subscriber; + context->previous = *subscriber = get_my_subscriber(); }else{ WHYF("Could not resolve address on %s, this isn't a configured point to point link", context->interface->name); context->flags|=DECODE_FLAG_INVALID_ADDRESS; @@ -499,7 +520,7 @@ int send_please_explain(struct decode_context *context, struct subscriber *sourc if (source) frame->source = source; else - frame->source = my_subscriber; + frame->source = get_my_subscriber(); if (!context->sender) frame->source_full=1; @@ -545,7 +566,7 @@ int process_explain(struct overlay_frame *frame) int len = ob_get(b); switch (len){ case OA_CODE_P2P_YOU: - add_explain_response(my_subscriber, &context); + add_explain_response(get_my_subscriber(), &context); break; case OA_CODE_SIGNKEY: decode_sid_from_signkey(b, NULL); diff --git a/overlay_address.h b/overlay_address.h index 519512c2..edb1c26e 100644 --- a/overlay_address.h +++ b/overlay_address.h @@ -115,7 +115,8 @@ struct decode_context{ struct subscriber *point_to_point_device; }; -extern __thread struct subscriber *my_subscriber; +struct subscriber *get_my_subscriber(); +void release_my_subscriber(); extern __thread struct subscriber *directory_service; struct subscriber *_find_subscriber(struct __sourceloc, const unsigned char *sid, int len, int create); diff --git a/overlay_link.c b/overlay_link.c index 09cd9d33..6a259086 100644 --- a/overlay_link.c +++ b/overlay_link.c @@ -178,7 +178,7 @@ int overlay_send_probe(struct subscriber *peer, struct network_destination *dest struct overlay_frame *frame=malloc(sizeof(struct overlay_frame)); bzero(frame,sizeof(struct overlay_frame)); frame->type=OF_TYPE_DATA; - frame->source = my_subscriber; + frame->source = get_my_subscriber(); frame->destination = peer; frame->ttl=1; frame->queue=queue; @@ -313,7 +313,7 @@ int overlay_send_stun_request(struct subscriber *server, struct subscriber *requ if (request->reachable&REACHABLE || (server && server->reachable & REACHABLE)){ struct internal_mdp_header header; bzero(&header, sizeof header); - header.source = my_subscriber; + header.source = get_my_subscriber(); header.destination = request; header.source_port = MDP_PORT_STUNREQ; header.destination_port = MDP_PORT_STUN; @@ -327,7 +327,7 @@ int overlay_send_stun_request(struct subscriber *server, struct subscriber *requ if (overlay_interfaces[i].state == INTERFACE_STATE_UP && overlay_interfaces[i].address.addr.sa_family == AF_INET){ - overlay_address_append(NULL, payload, my_subscriber); + overlay_address_append(NULL, payload, get_my_subscriber()); ob_append_ui32(payload, overlay_interfaces[i].address.inet.sin_addr.s_addr); ob_append_ui16(payload, overlay_interfaces[i].address.inet.sin_port); if (ob_overrun(payload)){ @@ -347,7 +347,7 @@ int overlay_send_stun_request(struct subscriber *server, struct subscriber *requ if (server && server->reachable & REACHABLE){ struct internal_mdp_header header; bzero(&header, sizeof header); - header.source = my_subscriber; + header.source = get_my_subscriber(); header.destination = server; header.source_port = MDP_PORT_STUN; diff --git a/overlay_mdp.c b/overlay_mdp.c index fd695bc2..579d0d02 100644 --- a/overlay_mdp.c +++ b/overlay_mdp.c @@ -527,7 +527,7 @@ int overlay_saw_mdp_containing_frame(struct overlay_frame *f) void mdp_init_response(const struct internal_mdp_header *in, struct internal_mdp_header *out) { - out->source = in->destination ? in->destination : my_subscriber; + out->source = in->destination ? in->destination : get_my_subscriber(); out->source_port = in->destination_port; out->destination = in->source; out->destination_port = in->source_port; @@ -949,7 +949,7 @@ static int overlay_mdp_dispatch(overlay_mdp_frame *mdp, struct socket_address *c if (is_sid_t_any(mdp->out.src.sid)){ /* set source to ourselves */ - header.source = my_subscriber; + header.source = get_my_subscriber(); mdp->out.src.sid = header.source->sid; }else if (is_sid_t_broadcast(mdp->out.src.sid)){ /* Nope, I'm sorry but we simply can't send packets from @@ -1183,7 +1183,7 @@ static int mdp_process_identity_request(struct socket_address *client, struct md keyring_iterator_start(keyring, &it); keyring_next_identity(&it); while(it.identity){ - if (it.identity->subscriber != my_subscriber && strcmp(it.identity->PKRPin, pin) == 0) + if (it.identity->PKRPin && strcmp(it.identity->PKRPin, pin) == 0) keyring_release_identity(&it); else keyring_next_identity(&it); @@ -1416,8 +1416,8 @@ static void mdp_process_packet(struct socket_address *client, struct mdp_header switch(sid_type=sid_get_special_type(&header->local.sid)){ case SID_TYPE_ANY: // leaving the sid blank indicates that we should use our main identity - internal_header.source = my_subscriber; - header->local.sid = my_subscriber->sid; + internal_header.source = get_my_subscriber(); + header->local.sid = internal_header.source->sid; break; case SID_TYPE_INTERNAL: internal_header.source = internal; diff --git a/overlay_mdp_services.c b/overlay_mdp_services.c index b3b230ae..80296ffe 100644 --- a/overlay_mdp_services.c +++ b/overlay_mdp_services.c @@ -61,7 +61,7 @@ int rhizome_mdp_send_block(struct subscriber *dest, const rhizome_bid_t *bid, ui // beginning. header.crypt_flags = MDP_FLAG_NO_CRYPT | MDP_FLAG_NO_SIGN; - header.source = my_subscriber; + header.source = get_my_subscriber(); header.source_port = MDP_PORT_RHIZOME_RESPONSE; if (dest && (dest->reachable==REACHABLE_UNICAST || dest->reachable==REACHABLE_INDIRECT)){ @@ -302,7 +302,7 @@ static int overlay_mdp_service_trace(struct internal_mdp_header *header, struct INFOF("Trace from %s to %s", alloca_tohex_sid_t(src->sid), alloca_tohex_sid_t(dst->sid)); struct internal_mdp_header next_header; next_header = *header; - next_header.source = my_subscriber; + next_header.source = get_my_subscriber(); next_header.destination = NULL; while(ob_remaining(payload)>0){ @@ -347,8 +347,8 @@ static int overlay_mdp_service_trace(struct internal_mdp_header *header, struct INFOF("Next node is %s", alloca_tohex_sid_t(next_header.destination->sid)); // always write a full sid into the payload - my_subscriber->send_full=1; - overlay_address_append(&context, next_payload, my_subscriber); + next_header.source->send_full=1; + overlay_address_append(&context, next_payload, next_header.source); if (ob_overrun(next_payload)) { ret = WHYF("Unable to append my address to the trace"); goto end; diff --git a/overlay_olsr.c b/overlay_olsr.c index ebcb4e78..a6f0c584 100644 --- a/overlay_olsr.c +++ b/overlay_olsr.c @@ -208,7 +208,7 @@ static void parse_frame(struct overlay_buffer *buff){ end: // if we didn't understand one of the address abreviations, ask for explanation - send_please_explain(&context, my_subscriber, context.sender); + send_please_explain(&context, get_my_subscriber(), context.sender); } static void olsr_read(struct sched_ent *alarm){ @@ -292,7 +292,7 @@ int olsr_send(struct overlay_frame *frame){ ob_append_byte(b, frame->ttl); // address the packet as transmitted by me - overlay_address_append(&context, b, my_subscriber); + overlay_address_append(&context, b, get_my_subscriber()); overlay_address_append(&context, b, frame->source); overlay_broadcast_append(b, &frame->broadcast_id); ob_append_byte(b, frame->modifiers); diff --git a/overlay_packetformats.c b/overlay_packetformats.c index c5b3ed26..2f942556 100644 --- a/overlay_packetformats.c +++ b/overlay_packetformats.c @@ -55,10 +55,10 @@ int overlay_packet_init_header(int packet_version, int encapsulation, ) context->point_to_point_device = context->interface->other_device; context->flags = DECODE_FLAG_ENCODING_HEADER; - overlay_address_append(context, buff, my_subscriber); + overlay_address_append(context, buff, get_my_subscriber()); context->flags = 0; - context->sender = my_subscriber; + context->sender = get_my_subscriber(); int flags=0; @@ -464,7 +464,7 @@ int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, s // We may need to schedule an ACK / NACK soon when we receive a payload addressed to us, or broadcast if (f.modifiers & PAYLOAD_FLAG_ACK_SOON && - (f.next_hop == my_subscriber || f.destination == my_subscriber || !f.destination)) + (f.next_hop == get_my_subscriber() || f.destination == get_my_subscriber() || !f.destination)) link_state_ack_soon(context.sender); } @@ -476,7 +476,7 @@ int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, s } end: - send_please_explain(&context, my_subscriber, context.sender); + send_please_explain(&context, get_my_subscriber(), context.sender); ob_free(b); diff --git a/overlay_queue.c b/overlay_queue.c index ce55b706..3f6b1056 100644 --- a/overlay_queue.c +++ b/overlay_queue.c @@ -447,7 +447,7 @@ overlay_stuff_packet(struct outgoing_packet *packet, overlay_txqueue *queue, tim // send a packet to this destination if (frame->source_full) - my_subscriber->send_full=1; + get_my_subscriber()->send_full=1; if (overlay_init_packet(packet, frame->packet_version, dest) != -1) { if (debug){ strbuf_sprintf(debug, "building packet %s %s %d [", diff --git a/rhizome_fetch.c b/rhizome_fetch.c index d1625eda..a2961d9b 100644 --- a/rhizome_fetch.c +++ b/rhizome_fetch.c @@ -1038,7 +1038,7 @@ static int rhizome_fetch_mdp_requestblocks(struct rhizome_fetch_slot *slot) struct internal_mdp_header header; bzero(&header, sizeof header); - header.source = my_subscriber; + header.source = get_my_subscriber(); header.source_port = MDP_PORT_RHIZOME_RESPONSE; header.destination = (struct subscriber *)slot->peer; header.destination_port = MDP_PORT_RHIZOME_REQUEST; @@ -1137,11 +1137,6 @@ static enum rhizome_start_fetch_result rhizome_fetch_switch_to_mdp(struct rhizom rhizome_fetch_close(slot); RETURN(-1); } - if (!my_subscriber) { - WARN("I don't have an identity, so we cannot fall back to MDP"); - rhizome_fetch_close(slot); - RETURN(-1); - } DEBUGF(rhizome_rx, "Trying to switch to MDP for Rhizome fetch: slot=0x%p (%"PRIu64" bytes)", slot, slot->write_state.file_length); diff --git a/rhizome_packetformats.c b/rhizome_packetformats.c index f8e7db26..1a41f47c 100644 --- a/rhizome_packetformats.c +++ b/rhizome_packetformats.c @@ -147,7 +147,7 @@ int rhizome_advertise_manifest(struct subscriber *dest, rhizome_manifest *m){ struct overlay_frame *frame = malloc(sizeof(struct overlay_frame)); bzero(frame,sizeof(struct overlay_frame)); frame->type = OF_TYPE_RHIZOME_ADVERT; - frame->source = my_subscriber; + frame->source = get_my_subscriber(); if (dest && dest->reachable&REACHABLE) frame->destination = dest; else @@ -331,7 +331,7 @@ next: if (rhizome_is_bar_interesting(bars[index])==1){ // add a request for the manifest if (!payload){ - header.source = my_subscriber; + header.source = get_my_subscriber(); header.source_port = MDP_PORT_RHIZOME_RESPONSE; header.destination = f->source; header.destination_port = MDP_PORT_RHIZOME_MANIFEST_REQUEST; diff --git a/rhizome_sync.c b/rhizome_sync.c index a3d8cc4b..0cc333de 100644 --- a/rhizome_sync.c +++ b/rhizome_sync.c @@ -109,7 +109,7 @@ static void rhizome_sync_request(struct subscriber *subscriber, uint64_t token, struct internal_mdp_header header; bzero(&header, sizeof header); - header.source = my_subscriber; + header.source = get_my_subscriber(); header.source_port = MDP_PORT_RHIZOME_SYNC; header.destination = subscriber; header.destination_port = MDP_PORT_RHIZOME_SYNC; @@ -157,7 +157,7 @@ static void rhizome_sync_send_requests(struct subscriber *subscriber, struct rhi } if (!payload){ - header.source = my_subscriber; + header.source = get_my_subscriber(); header.source_port = MDP_PORT_RHIZOME_RESPONSE; header.destination = subscriber; header.destination_port = MDP_PORT_RHIZOME_MANIFEST_REQUEST; @@ -455,7 +455,7 @@ static void sync_send_response(struct subscriber *dest, int forwards, uint64_t t struct internal_mdp_header header; bzero(&header, sizeof header); - header.source = my_subscriber; + header.source = get_my_subscriber(); header.source_port = MDP_PORT_RHIZOME_SYNC; header.destination = dest; header.destination_port = MDP_PORT_RHIZOME_SYNC; diff --git a/rhizome_sync_keys.c b/rhizome_sync_keys.c index 74e0be08..815d9089 100644 --- a/rhizome_sync_keys.c +++ b/rhizome_sync_keys.c @@ -111,7 +111,7 @@ static struct transfers **find_and_update_transfer(struct subscriber *peer, stru if (!keys_state->connection) keys_state->connection = msp_find_or_connect(&sync_connections, peer, MDP_PORT_RHIZOME_SYNC_KEYS, - my_subscriber, MDP_PORT_RHIZOME_SYNC_KEYS, + get_my_subscriber(), MDP_PORT_RHIZOME_SYNC_KEYS, OQ_OPPORTUNISTIC); if (msp_can_send(keys_state->connection)){ @@ -524,7 +524,7 @@ void sync_send_keys(struct sched_ent *alarm) bzero(&header, sizeof header); header.crypt_flags = MDP_FLAG_NO_CRYPT | MDP_FLAG_NO_SIGN; - header.source = my_subscriber; + header.source = get_my_subscriber(); header.source_port = MDP_PORT_RHIZOME_SYNC_KEYS; header.destination_port = MDP_PORT_RHIZOME_SYNC_KEYS; header.qos = OQ_OPPORTUNISTIC; diff --git a/route_link.c b/route_link.c index e1eab1ae..59ea867d 100644 --- a/route_link.c +++ b/route_link.c @@ -339,7 +339,7 @@ static void update_path_score(struct neighbour *neighbour, struct link *link){ int hop_count = -1; int drop_rate = 0; - if (link->transmitter == my_subscriber){ + if (link->transmitter == get_my_subscriber()){ if (link->receiver==neighbour->subscriber){ hop_count = 1; } @@ -403,7 +403,7 @@ static struct link * find_best_link(struct subscriber *subscriber) if (!(link && link->transmitter)) goto next; - if (link->transmitter != my_subscriber){ + if (link->transmitter != get_my_subscriber()){ struct link_state *parent_state = get_link_state(link->transmitter); find_best_link(link->transmitter); if (parent_state->next_hop != neighbour->subscriber) @@ -498,7 +498,7 @@ static int append_link_state(struct overlay_buffer *payload, char flags, static int append_link(struct subscriber *subscriber, void *context) { - if (subscriber == my_subscriber) + if (subscriber == get_my_subscriber()) return 0; struct link_state *state = get_link_state(subscriber); @@ -513,7 +513,7 @@ static int append_link(struct subscriber *subscriber, void *context) if (subscriber->reachable==REACHABLE_SELF){ if (state->next_update - 20 <= now){ // Other entries in our keyring are always one hop away from us. - if (append_link_state(payload, 0, my_subscriber, subscriber, -1, 1, -1, 0, 0)){ + if (append_link_state(payload, 0, get_my_subscriber(), subscriber, -1, 1, -1, 0, 0)){ ALARM_STRUCT(link_send).alarm = now+5; return 1; } @@ -743,7 +743,7 @@ static int send_legacy_self_announce_ack(struct neighbour *neighbour, struct lin frame->type = OF_TYPE_SELFANNOUNCE_ACK; frame->ttl = 6; frame->destination = neighbour->subscriber; - frame->source = my_subscriber; + frame->source = get_my_subscriber(); if ((frame->payload = ob_new()) == NULL) { op_free(frame); return -1; @@ -829,7 +829,7 @@ static int send_neighbour_link(struct neighbour *n) } else { struct overlay_frame *frame = emalloc_zero(sizeof(struct overlay_frame)); frame->type=OF_TYPE_DATA; - frame->source=my_subscriber; + frame->source=get_my_subscriber(); frame->ttl=1; frame->queue=OQ_MESH_MANAGEMENT; if ((frame->payload = ob_new()) == NULL) { @@ -867,7 +867,7 @@ static int send_neighbour_link(struct neighbour *n) DEBUGF(ack, "LINK STATE; Sending ack to %s for seq %d", alloca_tohex_sid_t(n->subscriber->sid), n->best_link->ack_sequence); - append_link_state(frame->payload, flags, n->subscriber, my_subscriber, n->best_link->neighbour_interface, 1, + append_link_state(frame->payload, flags, n->subscriber, get_my_subscriber(), n->best_link->neighbour_interface, 1, n->best_link->ack_sequence, n->best_link->ack_mask, -1); if (overlay_payload_enqueue(frame) == -1) op_free(frame); @@ -941,7 +941,7 @@ void link_send(struct sched_ent *alarm) }else{ struct internal_mdp_header header; bzero(&header, sizeof(header)); - header.source = my_subscriber; + header.source = get_my_subscriber(); header.source_port = MDP_PORT_LINKSTATE; header.destination_port = MDP_PORT_LINKSTATE; header.ttl = 1; @@ -984,9 +984,7 @@ int link_stop_routing(struct subscriber *subscriber) return 0; subscriber->reachable = REACHABLE_NONE; subscriber->identity=NULL; - if (subscriber==my_subscriber) - my_subscriber=NULL; - if (subscriber->link_state){ + if (serverMode && subscriber->link_state){ struct link_state *state = get_link_state(subscriber); state->next_update = gettime_ms(); update_alarm(__WHENCE__, state->next_update); @@ -1319,9 +1317,11 @@ static int link_receive(struct internal_mdp_header *header, struct overlay_buffe { IN(); - if (header->source == my_subscriber) + if (header->source->reachable == REACHABLE_SELF) RETURN(0); - + + struct subscriber *myself = get_my_subscriber(); + struct neighbour *neighbour = get_neighbour(header->source, 1); struct decode_context context; @@ -1402,7 +1402,7 @@ static int link_receive(struct internal_mdp_header *header, struct overlay_buffe ack_mask, drop_rate); - if (transmitter && transmitter!=my_subscriber && transmitter->reachable==REACHABLE_SELF){ + if (transmitter && transmitter!=myself && transmitter->reachable==REACHABLE_SELF){ // Our neighbour is talking about a path *from* a secondary SID of ours? Impossible. // Maybe we decoded an abbreviation incorrectly and this indicates a SID collision. // TODO add a test for this case! @@ -1410,7 +1410,7 @@ static int link_receive(struct internal_mdp_header *header, struct overlay_buffe continue; } - if (receiver == my_subscriber){ + if (receiver == myself){ // track if our neighbour is using us as an immediate neighbour, if they are we need to ack / nack promptly neighbour->using_us = (transmitter==header->source?1:0); @@ -1420,7 +1420,7 @@ static int link_receive(struct internal_mdp_header *header, struct overlay_buffe } if (receiver->reachable == REACHABLE_SELF){ - if (transmitter && transmitter!=my_subscriber){ + if (transmitter && transmitter!=myself){ // An alternative path to a secondary SID, that isn't via me? Impossible. // Maybe we decoded an abbreviation incorrectly and this indicates a SID collision. // TODO add a test for this case! @@ -1433,7 +1433,7 @@ static int link_receive(struct internal_mdp_header *header, struct overlay_buffe if (receiver == header->source){ // ignore other incoming links to our neighbour - if (transmitter!=my_subscriber || interface_id==-1) + if (transmitter!=myself || interface_id==-1) continue; interface = &overlay_interfaces[interface_id]; @@ -1462,7 +1462,7 @@ static int link_receive(struct internal_mdp_header *header, struct overlay_buffe out->timeout=now + out->destination->ifconfig.reachable_timeout_ms; destination = out->destination; - }else if(transmitter == my_subscriber){ + }else if(transmitter == myself){ // if our neighbour starts using us to reach this receiver, we have to treat the link in our routing table as if it just died. transmitter = NULL; if (receiver->reachable != REACHABLE_SELF){ @@ -1476,7 +1476,7 @@ static int link_receive(struct internal_mdp_header *header, struct overlay_buffe if (!link) continue; - if (transmitter == my_subscriber && receiver == header->source && interface_id != -1 && destination){ + if (transmitter == myself && receiver == header->source && interface_id != -1 && destination){ // they can hear us? we can route through them! version = link->link_version; @@ -1535,7 +1535,7 @@ static int link_receive(struct internal_mdp_header *header, struct overlay_buffe } } - send_please_explain(&context, my_subscriber, header->source); + send_please_explain(&context, myself, header->source); if (changed){ route_version++; @@ -1590,10 +1590,10 @@ int link_state_legacy_ack(struct overlay_frame *frame, time_ms_t now) } if (neighbour->link_in_timeout < now) changed = 1; - if (link->transmitter != my_subscriber) + if (link->transmitter != get_my_subscriber()) changed = 1; - link->transmitter = my_subscriber; + link->transmitter = get_my_subscriber(); link->link_version = 1; link->destination = interface->destination; diff --git a/server.c b/server.c index bfc1c237..80c804b6 100644 --- a/server.c +++ b/server.c @@ -195,11 +195,6 @@ JNIEXPORT jint JNICALL Java_org_servalproject_servaldna_ServalDCommand_server( } } - if (keyring_seed(keyring) == -1){ - Throw(env, "java/lang/IllegalStateException", "Failed to seed keyring"); - goto end; - } - if (server_env){ Throw(env, "java/lang/IllegalStateException", "Server java env variable already set"); goto end; @@ -320,7 +315,7 @@ static int server_bind() if (httpd_server_start(config.rhizome.http.port, config.rhizome.http.port + HTTPD_PORT_RANGE)==-1) { serverMode = 0; return -1; - } + } /* For testing, it can be very helpful to delay the start of the server process, for example to * check that the start/stop logic is robust. @@ -368,7 +363,6 @@ static void server_loop() const char *ppath = server_pidfile_path(); unlink(ppath); } - serverMode = 0; } static int server() @@ -659,6 +653,8 @@ static void serverCleanUp() dna_helper_shutdown(); overlay_interface_close_all(); overlay_mdp_clean_socket_files(); + release_my_subscriber(); + serverMode = 0; clean_proc(); } @@ -690,7 +686,7 @@ static void signal_handler(int signal) DEFINE_CMD(app_server_start, 0, "Start daemon with instance path from SERVALINSTANCE_PATH environment variable.", - "start" KEYRING_PIN_OPTIONS, "[foreground|exec ]"); + "start" KEYRING_PIN_OPTIONS, "[--seed]", "[foreground|exec ]"); static int app_server_start(const struct cli_parsed *parsed, struct cli_context *context) { IN(); @@ -700,6 +696,7 @@ static int app_server_start(const struct cli_parsed *parsed, struct cli_context const char *execpath; if (cli_arg(parsed, "exec", &execpath, cli_absolute_path, NULL) == -1) RETURN(-1); + int seed = cli_arg(parsed, "--seed", NULL, NULL, NULL) == 0; int foregroundP = cli_arg(parsed, "foreground", NULL, NULL, NULL) == 0; /* Create the instance directory if it does not yet exist */ if (create_serval_instance_dir() == -1) @@ -728,9 +725,12 @@ static int app_server_start(const struct cli_parsed *parsed, struct cli_context keyring = keyring_open_instance_cli(parsed); if (!keyring) RETURN(WHY("Could not open keyring file")); - if (keyring_seed(keyring) == -1) { - WHY("Could not seed keyring"); - goto exit; + if (seed && !keyring->identities){ + if (keyring_create_identity(keyring, "")==NULL){ + ret = WHY("Could not create new identity"); + goto exit; + } + keyring_commit(keyring); } if (foregroundP) { ret = server(); @@ -850,7 +850,6 @@ static int app_server_start(const struct cli_parsed *parsed, struct cli_context sleep_ms(milliseconds); } exit: - serverMode = 0; keyring_free(keyring); keyring = NULL; RETURN(ret); diff --git a/server_httpd.c b/server_httpd.c index eb7e0945..812e474d 100644 --- a/server_httpd.c +++ b/server_httpd.c @@ -24,7 +24,7 @@ static int root_page(httpd_request *r, const char *remainder) strbuf b = strbuf_local_buf(temp); strbuf_sprintf(b, "" "

Hello, I'm %s*

", - alloca_tohex_sid_t_trunc(my_subscriber->sid, 16)); + alloca_tohex_sid_t_trunc(get_my_subscriber()->sid, 16)); if (config.server.motd[0]) { strbuf_puts(b, "

"); strbuf_html_escape(b, config.server.motd, strlen(config.server.motd)); diff --git a/tests/keyring b/tests/keyring index 8cbbf089..41308bfe 100755 --- a/tests/keyring +++ b/tests/keyring @@ -172,11 +172,16 @@ test_KeyringPinIdentityPin() { assert_keyring_list 0 } -doc_KeyringAutoCreate="Starting a server with no keyring creates a valid identity" +doc_KeyringAutoCreate="Starting a server with no interfaces does not create an identity" test_KeyringAutoCreate() { + configure_servald_server() { + : + } start_servald_server executeOk_servald keyring list - assert_keyring_list 1 + assert_keyring_list 0 + executeOk_servald id self + assertStdoutLineCount == 2 } finally_KeyringAutoCreate() { stop_servald_server @@ -185,6 +190,24 @@ teardown_KeyringAutoCreate() { teardown_servald } +doc_KeyringNoAutoCreate="Starting a server with interface creates in-memory identity" +test_KeyringNoAutoCreate() { + configure_servald_server() { + add_servald_interface + } + start_servald_server + executeOk_servald keyring list + assert_keyring_list 0 + executeOk_servald id self + assertStdoutLineCount == 3 +} +finally_KeyringNoAutoCreate() { + stop_servald_server +} +teardown_KeyringNoAutoCreate() { + teardown_servald +} + doc_KeyringPinServer="Start daemon with a keyring PIN" setup_KeyringPinServer() { setup @@ -242,8 +265,8 @@ teardown_KeyringKeyringPinServer() { teardown_servald } -doc_KeyringEntryPinServer="Start daemon, unlock and lock identities" -setup_KeyringEntryPinServer() { +doc_ServerLockUnlock="Start daemon, unlock and lock identities" +setup_ServerLockUnlock() { setup executeOk_servald config set debug.mdprequests on create_single_identity @@ -255,36 +278,36 @@ setup_KeyringEntryPinServer() { extract_stdout_keyvalue TWOB sid "$rexp_sid" start_servald_server } -test_KeyringEntryPinServer() { +test_ServerLockUnlock() { executeOk_servald id self - assertStdoutLineCount == 3 assertStdoutGrep --matches=1 --fixed-strings "$SIDA" + assertStdoutLineCount == 3 executeOk_servald id enter pin 'one' executeOk_servald id list - assertStdoutLineCount == 4 assertStdoutGrep --matches=1 --fixed-strings "$SIDA" assertStdoutGrep --matches=1 --fixed-strings "$ONE" + assertStdoutLineCount == 4 executeOk_servald id enter pin 'two' executeOk_servald id list - assertStdoutLineCount == 6 assertStdoutGrep --matches=1 --fixed-strings "$SIDA" assertStdoutGrep --matches=1 --fixed-strings "$ONE" assertStdoutGrep --matches=1 --fixed-strings "$TWOA" assertStdoutGrep --matches=1 --fixed-strings "$TWOB" + assertStdoutLineCount == 6 executeOk_servald id relinquish pin 'one' executeOk_servald id list - assertStdoutLineCount == 5 assertStdoutGrep --matches=1 --fixed-strings "$SIDA" assertStdoutGrep --matches=1 --fixed-strings "$TWOA" assertStdoutGrep --matches=1 --fixed-strings "$TWOB" + assertStdoutLineCount == 5 executeOk_servald id relinquish sid "$TWOB" tfw_cat --stderr executeOk_servald id list - assertStdoutLineCount == 4 assertStdoutGrep --matches=1 --fixed-strings "$SIDA" assertStdoutGrep --matches=1 --fixed-strings "$TWOA" + assertStdoutLineCount == 4 } -teardown_KeyringEntryPinServer() { +teardown_ServerLockUnlock() { teardown_servald }