Merge branch 'development' into install-target

This commit is contained in:
Petter Reinholdtsen 2013-10-21 21:28:28 +02:00
commit ad21cef345
14 changed files with 235 additions and 76 deletions

View File

@ -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", "<entry-pin>", NULL}, 0,
"Unlock any pin protected identities and enable routing packets to them"},
{app_revoke_pin, {"id", "revoke", "pin", "<entry-pin>", NULL}, 0,
{app_revoke_pin, {"id", "relinquish", "pin", "<entry-pin>", NULL}, 0,
"Unload any identities protected by this pin and drop all routes to them"},
{app_revoke_pin, {"id", "revoke", "sid", "<sid>", NULL}, 0,
{app_revoke_pin, {"id", "relinquish", "sid", "<sid>", NULL}, 0,
"Unload a specific identity and drop all routes to it"},
{app_route_print, {"route","print",NULL}, 0,
"Print the routing table"},

View File

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

View File

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

222
keyring.c
View File

@ -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;i<PKR_MAX_KEYPAIRS;i++)
if (id->keypairs[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");
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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]"'