Ensure the invitation filenames do not reveal the secret cookie.
Since filenames could potentially leak to unprivileged users (for example, because of locatedb), it should not contain the cookie used for invitations. Instead, tinc now uses the hash of the cookie and the invitation key as the filename to store pending invitations in.
This commit is contained in:
parent
5dec1c2571
commit
9699f08afc
2 changed files with 22 additions and 2 deletions
|
@ -349,10 +349,19 @@ int cmd_invite(int argc, char *argv[]) {
|
||||||
// Create a random cookie for this invitation.
|
// Create a random cookie for this invitation.
|
||||||
char cookie[25];
|
char cookie[25];
|
||||||
randomize(cookie, 18);
|
randomize(cookie, 18);
|
||||||
|
|
||||||
|
// Create a filename that doesn't reveal the cookie itself
|
||||||
|
char buf[18 + strlen(fingerprint)];
|
||||||
|
char cookiehash[25];
|
||||||
|
memcpy(buf, cookie, 18);
|
||||||
|
memcpy(buf + 18, fingerprint, sizeof buf - 18);
|
||||||
|
digest_create(digest, buf, sizeof buf, cookiehash);
|
||||||
|
b64encode_urlsafe(cookiehash, cookiehash, 18);
|
||||||
|
|
||||||
b64encode_urlsafe(cookie, cookie, 18);
|
b64encode_urlsafe(cookie, cookie, 18);
|
||||||
|
|
||||||
// Create a file containing the details of the invitation.
|
// Create a file containing the details of the invitation.
|
||||||
xasprintf(&filename, "%s" SLASH "invitations" SLASH "%s", confbase, cookie);
|
xasprintf(&filename, "%s" SLASH "invitations" SLASH "%s", confbase, cookiehash);
|
||||||
int ifd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
|
int ifd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
|
||||||
if(!ifd) {
|
if(!ifd) {
|
||||||
fprintf(stderr, "Could not create invitation file %s: %s\n", filename, strerror(errno));
|
fprintf(stderr, "Could not create invitation file %s: %s\n", filename, strerror(errno));
|
||||||
|
|
|
@ -190,8 +190,19 @@ static bool receive_invitation_sptps(void *handle, uint8_t type, const char *dat
|
||||||
if(type != 0 || len != 18 || c->status.invitation_used)
|
if(type != 0 || len != 18 || c->status.invitation_used)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Recover the filename from the cookie and the key
|
||||||
|
digest_t *digest = digest_open_by_name("sha256", 18);
|
||||||
|
if(!digest)
|
||||||
|
abort();
|
||||||
|
char *fingerprint = ecdsa_get_base64_public_key(invitation_key);
|
||||||
|
char hashbuf[18 + strlen(fingerprint)];
|
||||||
char cookie[25];
|
char cookie[25];
|
||||||
b64encode_urlsafe(data, cookie, 18);
|
memcpy(hashbuf, data, 18);
|
||||||
|
memcpy(hashbuf + 18, fingerprint, sizeof hashbuf - 18);
|
||||||
|
digest_create(digest, hashbuf, sizeof hashbuf, cookie);
|
||||||
|
b64encode_urlsafe(cookie, cookie, 18);
|
||||||
|
digest_close(digest);
|
||||||
|
free(fingerprint);
|
||||||
|
|
||||||
char filename[PATH_MAX], usedname[PATH_MAX];
|
char filename[PATH_MAX], usedname[PATH_MAX];
|
||||||
snprintf(filename, sizeof filename, "%s" SLASH "invitations" SLASH "%s", confbase, cookie);
|
snprintf(filename, sizeof filename, "%s" SLASH "invitations" SLASH "%s", confbase, cookie);
|
||||||
|
|
Loading…
Reference in a new issue