Ensure the invitation filenames do not reveal the secret cookie.
authorGuus Sliepen <guus@tinc-vpn.org>
Tue, 20 Aug 2013 21:09:36 +0000 (23:09 +0200)
committerGuus Sliepen <guus@tinc-vpn.org>
Tue, 20 Aug 2013 21:09:36 +0000 (23:09 +0200)
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.

src/invitation.c
src/protocol_auth.c

index 749870458e61a7ec9f3292af831c9d2401bc6d05..5175ba92003c07be3c2a6a37833bc9d786db2126 100644 (file)
@@ -349,10 +349,19 @@ int cmd_invite(int argc, char *argv[]) {
        // 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.
-       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));
index 1623e75e4992307f0b460e78f66a8f870301c689..d69c8ab722913732c2521ec94356df5ec9e35106 100644 (file)
@@ -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)
                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];
-       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);