mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-01-18 02:39:44 +00:00
Add fromhere=2 to Rhizome list output
Need a way for the client to distinguish between authenticated (certain) and unauthenticated (likely) author SIDs in the context of a bundle list, since the bundle list does not verify manifest signatures for performance and battery life reasons.
This commit is contained in:
parent
419364b5a9
commit
3c993f0273
@ -551,11 +551,23 @@ convey optional fields that are present in the bundle's manifest:
|
||||
Serval-Rhizome-Bundle-Name: <quotedstring>
|
||||
Serval-Rhizome-Bundle-Date: <integer>
|
||||
|
||||
If the bundle's author, as verified by its signature, is present in the keyring,
|
||||
then the following HTTP header is present:
|
||||
All single-bundle operations, unless otherwise specified, attempt to deduce the
|
||||
bundle's author by finding whether the manifest's signature could be re-created
|
||||
using a Rhizome Secret from a currently unlocked identity in the keyring. If
|
||||
the manifest `sender` field is present or the author has been cached in the
|
||||
Rhizome database, then only that identity is tried, otherwise every single
|
||||
identity in the keyring is tested. If a signing identity is found, then the
|
||||
following HTTP header is present:
|
||||
|
||||
Serval-Rhizome-Bundle-Author: <hex64sid>
|
||||
|
||||
(Note that there is no manifest “author” field, and the “sender” field is
|
||||
optional, in order to support anonymous bundles. This is why the author must
|
||||
be deduced in this fashion. Serval DNA caches the authors it discovers, to
|
||||
avoid redundant re-testing of all keyring identities, but cached authors are
|
||||
not automatically treated as verified when read from the Rhizome database,
|
||||
because the database can be altered by external means.)
|
||||
|
||||
If the bundle's secret is known, either because it was supplied in the request
|
||||
or was deduced from the manifest's Bundle Key (BK) field and the author's
|
||||
Rhizome Secret (RS), then the following HTTP header is present:
|
||||
@ -681,21 +693,37 @@ table](#json-table) format with the following columns:
|
||||
store. This field is created using the local system clock, so comparisons
|
||||
with the `date` field cannot be relied upon as having any meaning.
|
||||
|
||||
* `.author` - the [SID][] of the local (unlocked) identity that (allegedly)
|
||||
created the bundle; either a string containing 64 hexadecimal digits, or
|
||||
*null* if the author cannot be deduced (the manifest lacks a *BK* field) or
|
||||
is not an [unlocked identity](#get-restful-keyring-identities-json). For
|
||||
performance reasons bundle authorship is not verified when listing bundles,
|
||||
because that would impose unreasonable CPU and battery load (regenerating
|
||||
the cryptographic signature of every single manifest in the list), so the
|
||||
[bundle fetch request](#get-restful-rhizome-bid.rhm) and similar
|
||||
single-bundle requests which do perform a signature authorship check may
|
||||
return a different `Serval-Rhizome-Bundle-Author` header; in particular if
|
||||
the manifest was not signed by the alleged author then that header will be
|
||||
absent.
|
||||
* `.author` - the [SID][] of the local (unlocked) identity that created the
|
||||
bundle; either a string containing 64 hexadecimal digits, or *null* if the
|
||||
author cannot be deduced (the manifest lacks a *BK* field) or is not an
|
||||
[unlocked identity](#get-restful-keyring-identities-json). In the case of
|
||||
*null*, the `.fromhere` field will be 0 (“not authored here”). In the case
|
||||
of a SID, the `.fromhere` indicates whether authorship was absent, likely or
|
||||
certain.
|
||||
|
||||
* `.fromhere` - a boolean flag that is set if the `.author` field is
|
||||
non-*null*; an integer either 1 or 0.
|
||||
* `.fromhere` - an integer flag that indicates whether the bundle was authored
|
||||
on the local device:
|
||||
|
||||
* `0` (“absent”) means the bundle was not authored by any identity on this
|
||||
device, which could be because either:
|
||||
* the author's identity is not unlocked in the local keyring, or
|
||||
* the author's identity is in the local keyring but does not verify
|
||||
cryptographically as the author.
|
||||
|
||||
* `1` (“likely”) means the author whose [SID][] is given in the `.author`
|
||||
field is present in the local keyring but authorship (the manifest's
|
||||
signature) has not been cryptographically verified, so attempting to
|
||||
update this bundle may yet fail. This is the usual value for most
|
||||
bundles in a list because cryptographic verification is not performed
|
||||
while listing bundles, since it is slow and costly in CPU and battery.
|
||||
|
||||
* `2` (“certain”) means the author whose [SID][] is given in the `.author`
|
||||
field is present in the local keyring and has been cryptographically
|
||||
verified as the true author of the bundle, so it is possible to update
|
||||
this bundle. This value will usually only be returned for
|
||||
locally-authored bundles that have recently been examined individually
|
||||
(eg, [GET /restful/rhizome/BID.rhm](#get-restful-rhizome-bid-rhm)), if
|
||||
Serval DNA has cached the result of the verification in memory.
|
||||
|
||||
* `filesize` - the number of bytes in the bundle's payload; an integer zero or
|
||||
positive with a maximum value of 2^64 − 1.
|
||||
|
@ -1587,8 +1587,10 @@ int rhizome_lookup_author(rhizome_manifest *m)
|
||||
{
|
||||
IN();
|
||||
keyring_iterator it;
|
||||
|
||||
switch (m->authorship) {
|
||||
case AUTHOR_LOCAL:
|
||||
case AUTHOR_AUTHENTIC:
|
||||
RETURN(1);
|
||||
case AUTHOR_NOT_CHECKED:
|
||||
DEBUGF(rhizome, "manifest[%d] lookup author=%s", m->manifest_record_number, alloca_tohex_sid_t(m->author));
|
||||
keyring_iterator_start(keyring, &it);
|
||||
@ -1609,13 +1611,11 @@ int rhizome_lookup_author(rhizome_manifest *m)
|
||||
RETURN(1);
|
||||
}
|
||||
}
|
||||
// fall through
|
||||
case AUTHENTICATION_ERROR:
|
||||
case AUTHOR_UNKNOWN:
|
||||
case AUTHOR_IMPOSTOR:
|
||||
RETURN(0);
|
||||
case AUTHOR_LOCAL:
|
||||
case AUTHOR_AUTHENTIC:
|
||||
RETURN(1);
|
||||
}
|
||||
FATALF("m->authorship = %d", m->authorship);
|
||||
RETURN(0);
|
||||
|
@ -751,17 +751,27 @@ static int app_rhizome_list(const struct cli_parsed *parsed, struct cli_context
|
||||
cli_put_long(context, m->version, ":");
|
||||
cli_put_long(context, m->has_date ? m->date : 0, ":");
|
||||
cli_put_long(context, m->inserttime, ":");
|
||||
// The 'fromhere' flag indicates if the author is a known (unlocked) identity in the local
|
||||
// keyring. The values are 0 (no), 1 (yes), 2 (yes and cryptographically verified). In the
|
||||
// implementation below, the 0 value (no) is redundant, because it only occurs when the
|
||||
// 'author' column is null, but in future the author SID might be reported for non-local
|
||||
// authors, so clients should only use 'fromhere != 0', never 'author != null', to detect
|
||||
// local authorship.
|
||||
int fromhere = 0;
|
||||
switch (m->authorship) {
|
||||
case AUTHOR_LOCAL:
|
||||
case AUTHOR_AUTHENTIC:
|
||||
fromhere = 2;
|
||||
cli_put_hexvalue(context, m->author.binary, sizeof m->author.binary, ":");
|
||||
break;
|
||||
case AUTHOR_LOCAL:
|
||||
fromhere = 1;
|
||||
cli_put_hexvalue(context, m->author.binary, sizeof m->author.binary, ":");
|
||||
cli_put_long(context, 1, ":");
|
||||
break;
|
||||
default:
|
||||
cli_put_string(context, NULL, ":");
|
||||
cli_put_long(context, 0, ":");
|
||||
break;
|
||||
}
|
||||
cli_put_long(context, fromhere, ":");
|
||||
cli_put_long(context, m->filesize, ":");
|
||||
cli_put_hexvalue(context, m->filesize ? m->filehash.binary : NULL, sizeof m->filehash.binary, ":");
|
||||
cli_put_hexvalue(context, m->has_sender ? m->sender.binary : NULL, sizeof m->sender.binary, ":");
|
||||
|
@ -299,17 +299,29 @@ static int restful_rhizome_bundlelist_json_content_chunk(struct http_request *hr
|
||||
strbuf_json_null(b);
|
||||
strbuf_putc(b, ',');
|
||||
strbuf_sprintf(b, "%"PRItime_ms_t",", m->inserttime);
|
||||
// The 'fromhere' flag indicates if the author is a known (unlocked) identity in the local
|
||||
// keyring. The values are 0 (no), 1 (yes), 2 (yes and cryptographically verified). In the
|
||||
// implementation below, the 0 value (no) is redundant, because it only occurs when the
|
||||
// 'author' column is null, but in future the author SID might be reported for non-local
|
||||
// authors, so clients should only use 'fromhere != 0', never 'author != null', to detect
|
||||
// local authorship.
|
||||
int fromhere = 0;
|
||||
switch (m->authorship) {
|
||||
case AUTHOR_LOCAL:
|
||||
case AUTHOR_AUTHENTIC:
|
||||
fromhere = 2;
|
||||
strbuf_json_hex(b, m->author.binary, sizeof m->author.binary);
|
||||
break;
|
||||
case AUTHOR_LOCAL:
|
||||
fromhere = 1;
|
||||
strbuf_json_hex(b, m->author.binary, sizeof m->author.binary);
|
||||
strbuf_puts(b, ",1,");
|
||||
break;
|
||||
default:
|
||||
strbuf_json_null(b);
|
||||
strbuf_puts(b, ",1,");
|
||||
break;
|
||||
}
|
||||
strbuf_putc(b, ',');
|
||||
strbuf_sprintf(b, "%d", fromhere);
|
||||
strbuf_putc(b, ',');
|
||||
strbuf_sprintf(b, "%"PRIu64, m->filesize);
|
||||
strbuf_putc(b, ',');
|
||||
strbuf_json_hex(b, m->filesize ? m->filehash.binary : NULL, sizeof m->filehash.binary);
|
||||
|
Loading…
Reference in New Issue
Block a user