bool challenge_h(connection_t *c, const char *request) { if(!myself->connection->rsa) return false; char buffer[MAX_STRING_SIZE]; const size_t len = rsa_size(myself->connection->rsa); size_t digestlen = digest_length(c->indigest); char digest[digestlen]; if(sscanf(request, "%*d " MAX_STRING, buffer) != 1) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "CHALLENGE", c->name, c->hostname); return false; } /* Convert the challenge from hexadecimal back to binary */ int inlen = hex2bin(buffer, buffer, sizeof buffer); /* Check if the length of the challenge is all right */ if(inlen != len) { logger(DEBUG_ALWAYS, LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong challenge length"); return false; } /* Calculate the hash from the challenge we received */ if(!digest_create(c->indigest, buffer, len, digest)) return false; /* Convert the hash to a hexadecimal formatted string */ bin2hex(digest, buffer, digestlen); /* Send the reply */ c->allow_request = CHAL_REPLY; return send_request(c, "%d %s", CHAL_REPLY, buffer); }
static bool receive_invitation_sptps(void *handle, uint8_t type, const void *data, uint16_t len) { connection_t *c = handle; if(type == 128) return true; if(type == 1 && c->status.invitation_used) return finalize_invitation(c, data, len); 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]; 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); snprintf(usedname, sizeof usedname, "%s" SLASH "invitations" SLASH "%s.used", 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; } // Open the renamed file FILE *f = fopen(usedname, "r"); if(!f) { logger(DEBUG_ALWAYS, LOG_ERR, "Error trying to open invitation %s\n", cookie); return false; } // Read the new node's Name from the file char buf[1024]; fgets(buf, sizeof buf, f); if(*buf) buf[strlen(buf) - 1] = 0; len = strcspn(buf, " \t="); char *name = buf + len; name += strspn(name, " \t"); if(*name == '=') { name++; name += strspn(name, " \t"); } buf[len] = 0; if(!*buf || !*name || strcasecmp(buf, "Name") || !check_id(name)) { logger(DEBUG_ALWAYS, LOG_ERR, "Invalid invitation file %s\n", cookie); fclose(f); return false; } free(c->name); c->name = xstrdup(name); // Send the node the contents of the invitation file rewind(f); size_t result; while((result = fread(buf, 1, sizeof buf, f))) sptps_send_record(&c->sptps, 0, buf, result); sptps_send_record(&c->sptps, 1, buf, 0); fclose(f); unlink(usedname); c->status.invitation_used = true; logger(DEBUG_CONNECTIONS, LOG_INFO, "Invitation %s succesfully sent to %s (%s)", cookie, c->name, c->hostname); return true; }
struct digest_ctx * auth_create(int transform_id) { return digest_create(transform_id, profile, ARRAY_NUM(profile)); }