From 9699f08afc6420d2bdac1063ea6789b585aaf42e Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Tue, 20 Aug 2013 23:09:36 +0200 Subject: [PATCH] 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. --- src/invitation.c | 11 ++++++++++- src/protocol_auth.c | 13 ++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/invitation.c b/src/invitation.c index 74987045..5175ba92 100644 --- a/src/invitation.c +++ b/src/invitation.c @@ -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)); diff --git a/src/protocol_auth.c b/src/protocol_auth.c index 1623e75e..d69c8ab7 100644 --- a/src/protocol_auth.c +++ b/src/protocol_auth.c @@ -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);