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.
// Create a random cookie for this invitation.
char cookie[25];
randomize(cookie, 18);
// Create a random cookie for this invitation.
char cookie[25];
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);
// Create a file containing the details of the invitation.
b64encode_urlsafe(cookie, cookie, 18);
// 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);
if(!ifd) {
fprintf(stderr, "Could not create invitation file %s: %s\n", filename, strerror(errno));
int ifd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
if(!ifd) {
fprintf(stderr, "Could not create invitation file %s: %s\n", filename, strerror(errno));
if(type != 0 || len != 18 || c->status.invitation_used)
return false;
if(type != 0 || len != 18 || c->status.invitation_used)
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)];
- 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];
snprintf(filename, sizeof filename, "%s" SLASH "invitations" SLASH "%s", confbase, cookie);
char filename[PATH_MAX], usedname[PATH_MAX];
snprintf(filename, sizeof filename, "%s" SLASH "invitations" SLASH "%s", confbase, cookie);