Import Upstream version 1.0.31

This commit is contained in:
Guus Sliepen 2019-08-26 13:44:47 +02:00
parent 1077a20a8c
commit 81ce06b6c9
22 changed files with 250 additions and 93 deletions

View file

@ -1,6 +1,6 @@
/*
connection.c -- connection list management
Copyright (C) 2000-2012 Guus Sliepen <guus@tinc-vpn.org>,
Copyright (C) 2000-2016 Guus Sliepen <guus@tinc-vpn.org>,
2000-2005 Ivo Timmermans
2008 Max Rijevski <maksuf@gmail.com>
@ -91,6 +91,8 @@ void free_connection_partially(connection_t *c) {
c->outbufstart = 0;
c->last_ping_time = 0;
c->last_flushed_time = 0;
c->inbudget = 0;
c->outbudget = 0;
if(c->inctx) {
EVP_CIPHER_CTX_cleanup(c->inctx);

View file

@ -1,6 +1,6 @@
/*
connection.h -- header for connection.c
Copyright (C) 2000-2012 Guus Sliepen <guus@tinc-vpn.org>,
Copyright (C) 2000-2016 Guus Sliepen <guus@tinc-vpn.org>,
2000-2005 Ivo Timmermans
This program is free software; you can redistribute it and/or modify
@ -41,7 +41,8 @@ typedef struct connection_status_t {
unsigned int encryptout:1; /* 1 if we can encrypt outgoing traffic */
unsigned int decryptin:1; /* 1 if we have to decrypt incoming traffic */
unsigned int mst:1; /* 1 if this connection is part of a minimum spanning tree */
unsigned int unused:23;
unsigned int proxy_passed:1; /* 1 if we are connecting via a proxy and we have finished talking with it */
unsigned int unused:22;
} connection_status_t;
#include "edge.h"
@ -70,6 +71,8 @@ typedef struct connection_t {
const EVP_CIPHER *outcipher; /* Cipher we will use to send data to him */
EVP_CIPHER_CTX *inctx; /* Context of encrypted meta data that will come from him to us */
EVP_CIPHER_CTX *outctx; /* Context of encrypted meta data that will be sent from us to him */
uint64_t inbudget; /* Encrypted bytes send budget */
uint64_t outbudget; /* Encrypted bytes receive budget */
char *inkey; /* His symmetric meta key + iv */
char *outkey; /* Our symmetric meta key + iv */
int inkeylength; /* Length of his key + iv */

View file

@ -1,6 +1,6 @@
/*
meta.c -- handle the meta communication
Copyright (C) 2000-2015 Guus Sliepen <guus@tinc-vpn.org>,
Copyright (C) 2000-2016 Guus Sliepen <guus@tinc-vpn.org>,
2000-2005 Ivo Timmermans
2006 Scott Lamb <slamb@slamb.org>
@ -62,6 +62,14 @@ bool send_meta(connection_t *c, const char *buffer, int length) {
/* Add our data to buffer */
if(c->status.encryptout) {
/* Check encryption limits */
if(length > c->outbudget) {
ifdebug(META) logger(LOG_ERR, "Byte limit exceeded for encryption to %s (%s)", c->name, c->hostname);
return false;
} else {
c->outbudget -= length;
}
result = EVP_EncryptUpdate(c->outctx, (unsigned char *)c->outbuf + c->outbufstart + c->outbuflen,
&outlen, (unsigned char *)buffer, length);
if(!result || outlen < length) {
@ -175,6 +183,14 @@ bool receive_meta(connection_t *c) {
/* Decrypt */
if(c->status.decryptin && !decrypted) {
/* Check decryption limits */
if(lenin > c->inbudget) {
ifdebug(META) logger(LOG_ERR, "Byte limit exceeded for decryption from %s (%s)", c->name, c->hostname);
return false;
} else {
c->inbudget -= lenin;
}
result = EVP_DecryptUpdate(c->inctx, (unsigned char *)inbuf, &lenout, (unsigned char *)c->buffer + oldlen, lenin);
if(!result || lenout != lenin) {
logger(LOG_ERR, "Error while decrypting metadata from %s (%s): %s",

View file

@ -650,14 +650,25 @@ static bool setup_myself(void) {
}
free(cipher);
} else
myself->incipher = EVP_bf_cbc();
myself->incipher = EVP_aes_256_cbc();
if(myself->incipher)
myself->inkeylength = EVP_CIPHER_key_length(myself->incipher) + EVP_CIPHER_iv_length(myself->incipher);
else
myself->inkeylength = 1;
myself->connection->outcipher = EVP_bf_ofb();
/* We need to use a stream mode for the meta protocol. Use AES for this,
but try to match the key size with the one from the cipher selected
by Cipher.
*/
int keylen = EVP_CIPHER_key_length(myself->incipher);
if(keylen <= 16)
myself->connection->outcipher = EVP_aes_128_cfb();
else if(keylen <= 24)
myself->connection->outcipher = EVP_aes_192_cfb();
else
myself->connection->outcipher = EVP_aes_256_cfb();
if(!get_config_int(lookup_config(config_tree, "KeyExpire"), &keylifetime))
keylifetime = 3600;
@ -681,9 +692,9 @@ static bool setup_myself(void) {
free(digest);
} else
myself->indigest = EVP_sha1();
myself->indigest = EVP_sha256();
myself->connection->outdigest = EVP_sha1();
myself->connection->outdigest = EVP_sha256();
if(get_config_int(lookup_config(config_tree, "MACLength"), &myself->inmaclength)) {
if(myself->indigest) {

View file

@ -41,9 +41,8 @@
#include "xalloc.h"
bool send_id(connection_t *c) {
if(proxytype && c->outgoing)
if(!send_proxyrequest(c))
return false;
if(proxytype && c->outgoing && !c->status.proxy_passed)
return send_proxyrequest(c);
return send_request(c, "%d %s %d", ID, myself->connection->name,
myself->connection->protocol_version);
@ -114,6 +113,21 @@ bool id_h(connection_t *c) {
return send_metakey(c);
}
static uint64_t byte_budget(const EVP_CIPHER *cipher) {
/* Hopefully some failsafe way to calculate the maximum amount of bytes to
send/receive with a given cipher before we might run into birthday paradox
attacks. Because we might use different modes, the block size of the mode
might be 1 byte. In that case, use the IV length. Ensure the whole thing
is limited to what can be represented with a 64 bits integer.
*/
int ivlen = EVP_CIPHER_iv_length(cipher);
int blklen = EVP_CIPHER_block_size(cipher);
int len = blklen > 1 ? blklen : ivlen > 1 ? ivlen : 8;
int bits = len * 4 - 1;
return bits < 64 ? UINT64_C(1) << bits : UINT64_MAX;
}
bool send_metakey(connection_t *c) {
bool x;
@ -196,6 +210,7 @@ bool send_metakey(connection_t *c) {
return false;
}
c->outbudget = byte_budget(c->outcipher);
c->status.encryptout = true;
}
@ -274,6 +289,7 @@ bool metakey_h(connection_t *c) {
return false;
}
c->inbudget = byte_budget(c->incipher);
c->status.decryptin = true;
} else {
c->incipher = NULL;

View file

@ -1,6 +1,6 @@
/*
proxy.c -- Proxy handling functions.
Copyright (C) 2015 Guus Sliepen <guus@tinc-vpn.org>
Copyright (C) 2015-2016 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -194,6 +194,8 @@ int receive_proxy_meta(connection_t *c, int start, int lenin) {
ifdebug(CONNECTIONS) logger(LOG_DEBUG, "Proxy request granted");
c->allow_request = ID;
c->status.proxy_passed = true;
send_id(c);
return 8;
} else {
logger(LOG_ERR, "Proxy request rejected");
@ -249,6 +251,8 @@ int receive_proxy_meta(connection_t *c, int start, int lenin) {
} else {
ifdebug(CONNECTIONS) logger(LOG_DEBUG, "Proxy request granted");
c->allow_request = ID;
c->status.proxy_passed = true;
send_id(c);
return replen;
}
@ -256,7 +260,12 @@ int receive_proxy_meta(connection_t *c, int start, int lenin) {
char *p = memchr(c->buffer, '\n', c->buflen);
if(!p || p - c->buffer >= c->buflen)
return 0;
p = memchr(p + 1, '\n', c->buflen - (p + 1 - c->buffer));
while((p = memchr(p + 1, '\n', c->buflen - (p + 1 - c->buffer)))) {
if(p > c->buffer + 3 && !memcmp(p - 3, "\r\n\r\n", 4))
break;
}
if(!p)
return 0;
@ -270,8 +279,12 @@ int receive_proxy_meta(connection_t *c, int start, int lenin) {
logger(LOG_DEBUG, "Proxy request granted");
replen = p + 1 - c->buffer;
c->allow_request = ID;
c->status.proxy_passed = true;
send_id(c);
return replen;
} else {
p = memchr(c->buffer, '\n', c->buflen);
p[-1] = 0;
logger(LOG_ERR, "Proxy request rejected: %s", c->buffer + 9);
return false;
}

View file

@ -1,7 +1,7 @@
/*
tincd.c -- the main file for tincd
Copyright (C) 1998-2005 Ivo Timmermans
2000-2016 Guus Sliepen <guus@tinc-vpn.org>
2000-2017 Guus Sliepen <guus@tinc-vpn.org>
2008 Max Rijevski <maksuf@gmail.com>
2009 Michael Tokarev <mjt@tls.msk.ru>
2010 Julien Muchembled <jm@jmuchemb.eu>
@ -583,7 +583,7 @@ int main(int argc, char **argv) {
if(show_version) {
printf("%s version %s\n", PACKAGE, VERSION);
printf("Copyright (C) 1998-2016 Ivo Timmermans, Guus Sliepen and others.\n"
printf("Copyright (C) 1998-2017 Ivo Timmermans, Guus Sliepen and others.\n"
"See the AUTHORS file for a complete list.\n\n"
"tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
"and you are welcome to redistribute it under certain conditions;\n"