Roll an in memory identity when the keyring is empty

This commit is contained in:
Jeremy Lakeman 2016-06-15 17:08:25 +09:30
parent 96b7cfa46f
commit 83b6ecb453
20 changed files with 190 additions and 165 deletions

View File

@ -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 {

121
keyring.c
View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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 [",

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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 <path>]");
"start" KEYRING_PIN_OPTIONS, "[--seed]", "[foreground|exec <path>]");
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);

View File

@ -24,7 +24,7 @@ static int root_page(httpd_request *r, const char *remainder)
strbuf b = strbuf_local_buf(temp);
strbuf_sprintf(b, "<html><head><meta http-equiv=\"refresh\" content=\"5\" ></head><body>"
"<h1>Hello, I'm %s*</h1>",
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, "<p>");
strbuf_html_escape(b, config.server.motd, strlen(config.server.motd));

View File

@ -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
}