X-Git-Url: https://tinc-vpn.org/git/browse?a=blobdiff_plain;f=src%2Fprotocol_auth.c;h=a270ffcdbd3f7b1ffa3f421e8bd09140fec8e472;hb=de7d5a03c2b956ab5753faf63b8148a279a71f29;hp=c0a2aeaf263fbb6e6b13fd9f29779d733506f545;hpb=6123ed30992d671b94fc016660086be6a62a3871;p=tinc diff --git a/src/protocol_auth.c b/src/protocol_auth.c index c0a2aeaf..a270ffcd 100644 --- a/src/protocol_auth.c +++ b/src/protocol_auth.c @@ -176,6 +176,8 @@ bool send_id(connection_t *c) { } static bool finalize_invitation(connection_t *c, const char *data, uint16_t len) { + (void)len; + if(strchr(data, '\n')) { logger(DEBUG_ALWAYS, LOG_ERR, "Received invalid key from invited node %s (%s)!\n", c->name, c->hostname); return false; @@ -200,7 +202,7 @@ static bool finalize_invitation(connection_t *c, const char *data, uint16_t len) fprintf(f, "Ed25519PublicKey = %s\n", data); fclose(f); - logger(DEBUG_CONNECTIONS, LOG_INFO, "Key succesfully received from %s (%s)", c->name, c->hostname); + logger(DEBUG_CONNECTIONS, LOG_INFO, "Key successfully received from %s (%s)", c->name, c->hostname); // Call invitation-accepted script environment_t env; @@ -282,13 +284,16 @@ static bool receive_invitation_sptps(void *handle, uint8_t type, const void *dat } // Read the new node's Name from the file - char buf[1024]; + char buf[1024] = ""; fgets(buf, sizeof(buf), f); + size_t buflen = strlen(buf); - if(*buf) { - buf[strlen(buf) - 1] = 0; + // Strip whitespace at the end + while(buflen && strchr(" \t\r\n", buf[buflen - 1])) { + buf[--buflen] = 0; } + // Split the first line into variable and value len = strcspn(buf, " \t="); char *name = buf + len; name += strspn(name, " \t"); @@ -300,7 +305,8 @@ static bool receive_invitation_sptps(void *handle, uint8_t type, const void *dat buf[len] = 0; - if(!*buf || !*name || strcasecmp(buf, "Name") || !check_id(name)) { + // Check that it is a valid Name + if(!*buf || !*name || strcasecmp(buf, "Name") || !check_id(name) || !strcmp(name, myself->name)) { logger(DEBUG_ALWAYS, LOG_ERR, "Invalid invitation file %s\n", cookie); fclose(f); return false; @@ -323,7 +329,7 @@ static bool receive_invitation_sptps(void *handle, uint8_t type, const void *dat c->status.invitation_used = true; - logger(DEBUG_CONNECTIONS, LOG_INFO, "Invitation %s succesfully sent to %s (%s)", cookie, c->name, c->hostname); + logger(DEBUG_CONNECTIONS, LOG_INFO, "Invitation %s successfully sent to %s (%s)", cookie, c->name, c->hostname); return true; } @@ -346,6 +352,10 @@ bool id_h(connection_t *c, const char *request) { free(c->name); c->name = xstrdup(""); + if(!c->outgoing) { + send_id(c); + } + return send_request(c, "%d %d %d", ACK, TINC_CTL_VERSION_CURRENT, getpid()); } @@ -369,6 +379,10 @@ bool id_h(connection_t *c, const char *request) { return false; } + if(!c->outgoing) { + send_id(c); + } + if(!send_request(c, "%d %s", ACK, mykey)) { return false; } @@ -382,7 +396,7 @@ bool id_h(connection_t *c, const char *request) { /* Check if identity is a valid name */ - if(!check_id(name)) { + if(!check_id(name) || !strcmp(name, myself->name)) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ID", c->name, c->hostname, "invalid name"); return false; @@ -397,10 +411,7 @@ bool id_h(connection_t *c, const char *request) { return false; } } else { - if(c->name) { - free(c->name); - } - + free(c->name); c->name = xstrdup(name); } @@ -418,6 +429,11 @@ bool id_h(connection_t *c, const char *request) { } c->allow_request = ACK; + + if(!c->outgoing) { + send_id(c); + } + return send_ack(c); } @@ -454,6 +470,10 @@ bool id_h(connection_t *c, const char *request) { c->allow_request = METAKEY; + if(!c->outgoing) { + send_id(c); + } + if(c->protocol_minor >= 2) { c->allow_request = ACK; char label[25 + strlen(myself->name) + strlen(c->name)]; @@ -470,11 +490,8 @@ bool id_h(connection_t *c, const char *request) { } } +#ifndef DISABLE_LEGACY 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; @@ -564,14 +581,9 @@ 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; } @@ -589,7 +601,7 @@ bool metakey_h(connection_t *c, const char *request) { /* Convert the challenge from hexadecimal back to binary */ - int inlen = hex2bin(hexkey, enckey, sizeof(enckey)); + size_t inlen = hex2bin(hexkey, enckey, sizeof(enckey)); /* Check if the length of the meta key is all right */ @@ -618,7 +630,8 @@ bool metakey_h(connection_t *c, const char *request) { return false; } } else { - c->incipher = NULL; + logger(DEBUG_ALWAYS, LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "null cipher"); + return false; } c->inbudget = cipher_budget(c->incipher); @@ -629,7 +642,8 @@ bool metakey_h(connection_t *c, const char *request) { return false; } } else { - c->indigest = NULL; + logger(DEBUG_ALWAYS, LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "null digest"); + return false; } c->status.decryptin = true; @@ -637,19 +651,13 @@ bool metakey_h(connection_t *c, const char *request) { c->allow_request = CHALLENGE; return send_challenge(c); -#endif } bool send_challenge(connection_t *c) { -#ifdef DISABLE_LEGACY - return false; -#else const size_t len = rsa_size(c->rsa); char buffer[len * 2 + 1]; - if(!c->hischallenge) { - c->hischallenge = xrealloc(c->hischallenge, len); - } + c->hischallenge = xrealloc(c->hischallenge, len); /* Copy random data to the buffer */ @@ -662,61 +670,69 @@ 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]; 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) { + if(strlen(buffer) != (size_t)len * 2) { logger(DEBUG_ALWAYS, LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong challenge length"); return false; } + c->mychallenge = xrealloc(c->mychallenge, len); + + /* Convert the challenge from hexadecimal back to binary */ + + hex2bin(buffer, c->mychallenge, len); + + /* The rest is done by send_chal_reply() */ + + c->allow_request = CHAL_REPLY; + + if(c->outgoing) { + return send_chal_reply(c); + } else { + return true; + } +} + +bool send_chal_reply(connection_t *c) { + const size_t len = rsa_size(myself->connection->rsa); + size_t digestlen = digest_length(c->indigest); + char digest[digestlen * 2 + 1]; + /* Calculate the hash from the challenge we received */ - if(!digest_create(c->indigest, buffer, len, digest)) { + if(!digest_create(c->indigest, c->mychallenge, len, digest)) { return false; } + free(c->mychallenge); + c->mychallenge = NULL; + /* Convert the hash to a hexadecimal formatted string */ - bin2hex(digest, buffer, digestlen); + bin2hex(digest, digest, digestlen); /* Send the reply */ - c->allow_request = CHAL_REPLY; - - return send_request(c, "%d %s", CHAL_REPLY, buffer); -#endif + return send_request(c, "%d %s", CHAL_REPLY, digest); } 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) { @@ -727,7 +743,7 @@ bool chal_reply_h(connection_t *c, const char *request) { /* Convert the hash to binary format */ - int inlen = hex2bin(hishash, hishash, sizeof(hishash)); + size_t inlen = hex2bin(hishash, hishash, sizeof(hishash)); /* Check if the length of the hash is all right */ @@ -752,14 +768,14 @@ bool chal_reply_h(connection_t *c, const char *request) { c->hischallenge = NULL; c->allow_request = ACK; + if(!c->outgoing) { + send_chal_reply(c); + } + 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. */ @@ -772,8 +788,46 @@ static bool send_upgrade(connection_t *c) { bool result = send_request(c, "%d %s", ACK, pubkey); free(pubkey); return result; -#endif } +#else +bool send_metakey(connection_t *c) { + (void)c; + return false; +} + +bool metakey_h(connection_t *c, const char *request) { + (void)c; + (void)request; + return false; +} + +bool send_challenge(connection_t *c) { + (void)c; + return false; +} + +bool challenge_h(connection_t *c, const char *request) { + (void)c; + (void)request; + return false; +} + +bool send_chal_reply(connection_t *c) { + (void)c; + return false; +} + +bool chal_reply_h(connection_t *c, const char *request) { + (void)c; + (void)request; + return false; +} + +static bool send_upgrade(connection_t *c) { + (void)c; + return false; +} +#endif bool send_ack(connection_t *c) { if(c->protocol_minor == 1) {