Import Upstream version 1.0.31
This commit is contained in:
parent
1077a20a8c
commit
81ce06b6c9
22 changed files with 250 additions and 93 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
18
src/meta.c
18
src/meta.c
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
17
src/proxy.c
17
src/proxy.c
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue