- bin2hex(buffer, buffer, len);
- buffer[len * 2] = '\0';
-
- /* Send the meta key */
-
- x = send_request(c, "%d %d %d %d %d %s", METAKEY,
- c->outcipher ? c->outcipher->nid : 0,
- c->outdigest ? c->outdigest->type : 0, c->outmaclength,
- c->outcompression, buffer);
-
- /* Further outgoing requests are encrypted with the key we just generated */
-
- if(c->outcipher) {
- if(!EVP_EncryptInit(c->outctx, c->outcipher,
- (unsigned char *)c->outkey + len - c->outcipher->key_len,
- (unsigned char *)c->outkey + len - c->outcipher->key_len -
- c->outcipher->iv_len)) {
- logger(LOG_ERR, "Error during initialisation of cipher for %s (%s): %s",
- c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL));
- return false;
- }
-
- c->status.encryptout = true;
+ // Recover the filename from the cookie and the key
+ char *fingerprint = ecdsa_get_base64_public_key(mesh->invitation_key);
+ char hash[64];
+ char hashbuf[18 + strlen(fingerprint)];
+ char cookie[25];
+ memcpy(hashbuf, data, 18);
+ memcpy(hashbuf + 18, fingerprint, sizeof hashbuf - 18);
+ sha512(hashbuf, sizeof hashbuf, hash);
+ b64encode_urlsafe(hash, cookie, 18);
+ free(fingerprint);
+
+ char filename[PATH_MAX], usedname[PATH_MAX];
+ snprintf(filename, sizeof filename, "%s" SLASH "invitations" SLASH "%s", mesh->confbase, cookie);
+ snprintf(usedname, sizeof usedname, "%s" SLASH "invitations" SLASH "%s.used", mesh->confbase, cookie);
+
+ // Atomically rename the invitation file
+ if(rename(filename, usedname)) {
+ if(errno == ENOENT)
+ logger(DEBUG_ALWAYS, LOG_ERR, "Peer %s tried to use non-existing invitation %s\n", c->hostname, cookie);
+ else
+ logger(DEBUG_ALWAYS, LOG_ERR, "Error trying to rename invitation %s\n", cookie);
+ return false;