X-Git-Url: https://tinc-vpn.org/git/browse?p=tinc;a=blobdiff_plain;f=src%2Fprotocol_auth.c;h=0a7ad1ca383ea8c0bf21cd44df7c8e762a7f59dc;hp=be90d92bfe5a619ddcb01a915bfc72101cf0d55f;hb=d4410d0cce40929db9a0ce7042ef962f1867234d;hpb=660a2c7d1bf7f5fba905b525bc7c3b9a5ac2ec99 diff --git a/src/protocol_auth.c b/src/protocol_auth.c index be90d92b..0a7ad1ca 100644 --- a/src/protocol_auth.c +++ b/src/protocol_auth.c @@ -45,6 +45,8 @@ #include "utils.h" #include "xalloc.h" +#include "ed25519/sha512.h" + ecdsa_t *invitation_key = NULL; static bool send_proxyrequest(connection_t *c) { @@ -115,7 +117,7 @@ static bool send_proxyrequest(connection_t *c) { i += 2; c->tcplen += 22; } else { - logger(DEBUG_ALWAYS, LOG_ERR, "Address family %hx not supported for SOCKS 5 proxies!", c->address.sa.sa_family); + logger(DEBUG_ALWAYS, LOG_ERR, "Address family %x not supported for SOCKS 5 proxies!", c->address.sa.sa_family); return false; } if(i > len) @@ -198,7 +200,7 @@ static bool finalize_invitation(connection_t *c, const char *data, uint16_t len) return true; } -static bool receive_invitation_sptps(void *handle, uint8_t type, const char *data, uint16_t len) { +static bool receive_invitation_sptps(void *handle, uint8_t type, const void *data, uint16_t len) { connection_t *c = handle; if(type == 128) @@ -211,17 +213,13 @@ static bool receive_invitation_sptps(void *handle, uint8_t type, const char *dat 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]; + char cookie[64]; memcpy(hashbuf, data, 18); memcpy(hashbuf + 18, fingerprint, sizeof hashbuf - 18); - digest_create(digest, hashbuf, sizeof hashbuf, cookie); + sha512(hashbuf, sizeof hashbuf, cookie); b64encode_urlsafe(cookie, cookie, 18); - digest_close(digest); free(fingerprint); char filename[PATH_MAX], usedname[PATH_MAX]; @@ -381,14 +379,14 @@ bool id_h(connection_t *c, const char *request) { if(experimental) read_ecdsa_public_key(c); /* Ignore failures if no key known yet */ - } else { - if(c->protocol_minor && !ecdsa_active(c->ecdsa)) - c->protocol_minor = 1; } + if(c->protocol_minor && !ecdsa_active(c->ecdsa)) + c->protocol_minor = 1; + /* Forbid version rollback for nodes whose Ed25519 key we know */ - if(ecdsa_active(c->ecdsa) && c->protocol_minor < 2) { + if(ecdsa_active(c->ecdsa) && c->protocol_minor < 1) { logger(DEBUG_ALWAYS, LOG_ERR, "Peer %s (%s) tries to roll back protocol version to %d.%d", c->name, c->hostname, c->protocol_major, c->protocol_minor); return false; @@ -412,6 +410,14 @@ bool id_h(connection_t *c, const char *request) { } bool send_metakey(connection_t *c) { +#ifdef DISABLE_LEGACY + return false; +#else + if(!myself->connection->rsa) { + logger(DEBUG_CONNECTIONS, LOG_ERR, "Peer %s (%s) uses legacy protocol which we don't support", c->name, c->hostname); + return false; + } + if(!read_rsa_public_key(c)) return false; @@ -421,7 +427,7 @@ bool send_metakey(connection_t *c) { if(!(c->outdigest = digest_open_sha1(-1))) return false; - size_t len = rsa_size(c->rsa); + const size_t len = rsa_size(c->rsa); char key[len]; char enckey[len]; char hexkey[2 * len + 1]; @@ -475,12 +481,19 @@ bool send_metakey(connection_t *c) { c->status.encryptout = true; return result; +#endif } bool metakey_h(connection_t *c, const char *request) { +#ifdef DISABLE_LEGACY + return false; +#else + if(!myself->connection->rsa) + return false; + char hexkey[MAX_STRING_SIZE]; int cipher, digest, maclength, compression; - size_t len = rsa_size(myself->connection->rsa); + const size_t len = rsa_size(myself->connection->rsa); char enckey[len]; char key[len]; @@ -537,10 +550,14 @@ bool metakey_h(connection_t *c, const char *request) { c->allow_request = CHALLENGE; return send_challenge(c); +#endif } bool send_challenge(connection_t *c) { - size_t len = rsa_size(c->rsa); +#ifdef DISABLE_LEGACY + return false; +#else + const size_t len = rsa_size(c->rsa); char buffer[len * 2 + 1]; if(!c->hischallenge) @@ -557,11 +574,18 @@ bool send_challenge(connection_t *c) { /* Send the challenge */ return send_request(c, "%d %s", CHALLENGE, buffer); +#endif } bool challenge_h(connection_t *c, const char *request) { +#ifdef DISABLE_LEGACY + return false; +#else + if(!myself->connection->rsa) + return false; + char buffer[MAX_STRING_SIZE]; - size_t len = rsa_size(myself->connection->rsa); + const size_t len = rsa_size(myself->connection->rsa); size_t digestlen = digest_length(c->indigest); char digest[digestlen]; @@ -595,9 +619,13 @@ bool challenge_h(connection_t *c, const char *request) { c->allow_request = CHAL_REPLY; return send_request(c, "%d %s", CHAL_REPLY, buffer); +#endif } bool chal_reply_h(connection_t *c, const char *request) { +#ifdef DISABLE_LEGACY + return false; +#else char hishash[MAX_STRING_SIZE]; if(sscanf(request, "%*d " MAX_STRING, hishash) != 1) { @@ -634,9 +662,13 @@ bool chal_reply_h(connection_t *c, const char *request) { c->allow_request = ACK; return send_ack(c); +#endif } static bool send_upgrade(connection_t *c) { +#ifdef DISABLE_LEGACY + return false; +#else /* Special case when protocol_minor is 1: the other end is Ed25519 capable, * but doesn't know our key yet. So send it now. */ @@ -648,6 +680,7 @@ static bool send_upgrade(connection_t *c) { bool result = send_request(c, "%d %s", ACK, pubkey); free(pubkey); return result; +#endif } bool send_ack(connection_t *c) { @@ -726,8 +759,16 @@ static bool upgrade_h(connection_t *c, const char *request) { } if(ecdsa_active(c->ecdsa) || read_ecdsa_public_key(c)) { - logger(DEBUG_ALWAYS, LOG_INFO, "Already have Ed25519 public key from %s (%s), not upgrading.", c->name, c->hostname); - return false; + char *knownkey = ecdsa_get_base64_public_key(c->ecdsa); + bool different = strcmp(knownkey, pubkey); + free(knownkey); + if(different) { + logger(DEBUG_ALWAYS, LOG_ERR, "Already have an Ed25519 public key from %s (%s) which is different from the one presented now!", c->name, c->hostname); + return false; + } + logger(DEBUG_ALWAYS, LOG_INFO, "Already have Ed25519 public key from %s (%s), ignoring.", c->name, c->hostname); + c->allow_request = TERMREQ; + return send_termreq(c); } c->ecdsa = ecdsa_set_base64_public_key(pubkey); @@ -739,6 +780,8 @@ static bool upgrade_h(connection_t *c, const char *request) { logger(DEBUG_ALWAYS, LOG_INFO, "Got Ed25519 public key from %s (%s), upgrading!", c->name, c->hostname); append_config_file(c->name, "Ed25519PublicKey", pubkey); c->allow_request = TERMREQ; + if(c->outgoing) + c->outgoing->timeout = 0; return send_termreq(c); }