From: Guus Sliepen <guus@tinc-vpn.org>
Date: Sun, 30 Sep 2012 13:00:47 +0000 (+0200)
Subject: Merge branch 'master' into 1.1
X-Git-Tag: release-1.1pre3~36
X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=6dfdb323612184529b4b83c1be914dda8262de47;p=oweals%2Ftinc.git

Merge branch 'master' into 1.1

Conflicts:
	lib/utils.c
	src/net_setup.c
	src/process.c
	src/protocol_auth.c
	src/protocol_key.c
	src/utils.h
---

6dfdb323612184529b4b83c1be914dda8262de47
diff --cc src/net_setup.c
index ba2ad5f,a28ab7a..c033e22
--- a/src/net_setup.c
+++ b/src/net_setup.c
@@@ -214,28 -162,32 +214,28 @@@ static bool read_ecdsa_private_key(void
  
  static bool read_rsa_private_key(void) {
  	FILE *fp;
 -	char *fname, *key, *pubkey;
 -	struct stat s;
 +	char *fname;
 +	char *n, *d;
 +	bool result;
  
 -	if(get_config_string(lookup_config(config_tree, "PrivateKey"), &key)) {
 -		if(!get_config_string(lookup_config(config_tree, "PublicKey"), &pubkey)) {
 -			logger(LOG_ERR, "PrivateKey used but no PublicKey found!");
 -			return false;
 -		}
 -		myself->connection->rsa_key = RSA_new();
 -//		RSA_blinding_on(myself->connection->rsa_key, NULL);
 -		if(BN_hex2bn(&myself->connection->rsa_key->d, key) != strlen(key)) {
 -			logger(LOG_ERR, "Invalid PrivateKey for myself!");
 -			return false;
 -		}
 -		if(BN_hex2bn(&myself->connection->rsa_key->n, pubkey) != strlen(pubkey)) {
 -			logger(LOG_ERR, "Invalid PublicKey for myself!");
 +	/* First, check for simple PrivateKey statement */
 +
 +	if(get_config_string(lookup_config(config_tree, "PrivateKey"), &d)) {
 +		if(!get_config_string(lookup_config(config_tree, "PublicKey"), &n)) {
 +			logger(DEBUG_ALWAYS, LOG_ERR, "PrivateKey used but no PublicKey found!");
 +			free(d);
  			return false;
  		}
 -		BN_hex2bn(&myself->connection->rsa_key->e, "FFFF");
 -		free(key);
 -		free(pubkey);
 -		return true;
 +		result = rsa_set_hex_private_key(&myself->connection->rsa, n, "FFFF", d);
 +		free(n);
 +		free(d);
- 		return true;
++		return result;
  	}
  
 +	/* Else, check for PrivateKeyFile statement and read it */
 +
  	if(!get_config_string(lookup_config(config_tree, "PrivateKeyFile"), &fname))
 -		xasprintf(&fname, "%s/rsa_key.priv", confbase);
 +		xasprintf(&fname, "%s" SLASH "rsa_key.priv", confbase);
  
  	fp = fopen(fname, "r");
  
diff --cc src/openssl/rsa.c
index 9c880e6,0000000..efd63d5
mode 100644,000000..100644
--- a/src/openssl/rsa.c
+++ b/src/openssl/rsa.c
@@@ -1,101 -1,0 +1,106 @@@
 +/*
 +    rsa.c -- RSA key handling
 +    Copyright (C) 2007 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
 +    the Free Software Foundation; either version 2 of the License, or
 +    (at your option) any later version.
 +
 +    This program is distributed in the hope that it will be useful,
 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +    GNU General Public License for more details.
 +
 +    You should have received a copy of the GNU General Public License along
 +    with this program; if not, write to the Free Software Foundation, Inc.,
 +    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 +*/
 +
 +#include "system.h"
 +
 +#include <openssl/pem.h>
 +#include <openssl/err.h>
 +
 +#include "logger.h"
 +#include "rsa.h"
 +
 +// Set RSA keys
 +
 +bool rsa_set_hex_public_key(rsa_t *rsa, char *n, char *e) {
 +	*rsa = RSA_new();
- 	BN_hex2bn(&(*rsa)->n, n);
- 	BN_hex2bn(&(*rsa)->e, e);
++	if(BN_hex2bn(&(*rsa)->n, n) != strlen(n))
++		return false;
++	if(BN_hex2bn(&(*rsa)->e, e) != strlen(e))
++		return false;
 +	return true;
 +}
 +
 +bool rsa_set_hex_private_key(rsa_t *rsa, char *n, char *e, char *d) {
 +	*rsa = RSA_new();
- 	BN_hex2bn(&(*rsa)->n, n);
- 	BN_hex2bn(&(*rsa)->e, e);
- 	BN_hex2bn(&(*rsa)->d, d);
++	if(BN_hex2bn(&(*rsa)->n, n) != strlen(n))
++		return false;
++	if(BN_hex2bn(&(*rsa)->e, e) != strlen(e))
++		return false;
++	if(BN_hex2bn(&(*rsa)->d, d) != strlen(d))
++		return false;
 +	return true;
 +}
 +
 +// Read PEM RSA keys
 +
 +bool rsa_read_pem_public_key(rsa_t *rsa, FILE *fp) {
 +	*rsa = PEM_read_RSAPublicKey(fp, rsa, NULL, NULL);
 +
 +	if(*rsa)
 +		return true;
 +	
 +	*rsa = PEM_read_RSA_PUBKEY(fp, rsa, NULL, NULL);
 +
 +	if(*rsa)
 +		return true;
 +
 +	logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA public key: %s", ERR_error_string(ERR_get_error(), NULL));
 +	return false;
 +}
 +
 +bool rsa_read_pem_private_key(rsa_t *rsa, FILE *fp) {
 +	*rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL);
 +
 +	if(*rsa)
 +		return true;
 +	
 +	logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA private key: %s", ERR_error_string(ERR_get_error(), NULL));
 +	return false;
 +}
 +
 +size_t rsa_size(rsa_t *rsa) {
 +	return RSA_size(*rsa);
 +}
 +
 +bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out) {
 +	if(RSA_public_encrypt(len, in, out, *rsa, RSA_NO_PADDING) == len)
 +		return true;
 +
 +	logger(DEBUG_ALWAYS, LOG_ERR, "Unable to perform RSA encryption: %s", ERR_error_string(ERR_get_error(), NULL));
 +	return false;	
 +}
 +
 +bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t len, void *out) {
 +	if(RSA_private_decrypt(len, in, out, *rsa, RSA_NO_PADDING) == len)
 +		return true;
 +
 +	logger(DEBUG_ALWAYS, LOG_ERR, "Unable to perform RSA decryption: %s", ERR_error_string(ERR_get_error(), NULL));
 +	return false;	
 +}
 +
 +bool rsa_active(rsa_t *rsa) {
 +	return *rsa;
 +}
 +
 +void rsa_free(rsa_t *rsa) {
 +	if(*rsa) {
 +		RSA_free(*rsa);
 +		*rsa = NULL;
 +	}
 +}
diff --cc src/process.c
index 0e33f26,262b092..362b678
--- a/src/process.c
+++ b/src/process.c
@@@ -229,11 -358,12 +229,12 @@@ bool execute_script(const char *name, c
  	int status, len;
  	char *scriptname;
  	int i;
+ 	char *interpreter = NULL;
  
  #ifndef HAVE_MINGW
 -	len = xasprintf(&scriptname, "\"%s/%s\"", confbase, name);
 +	len = xasprintf(&scriptname, "\"%s" SLASH "%s\"", confbase, name);
  #else
 -	len = xasprintf(&scriptname, "\"%s/%s.bat\"", confbase, name);
 +	len = xasprintf(&scriptname, "\"%s" SLASH "%s.bat\"", confbase, name);
  #endif
  	if(len < 0)
  		return false;
@@@ -249,8 -379,18 +250,19 @@@
  	}
  #endif
  
+ 	// Custom scripts interpreter
+ 	if(get_config_string(lookup_config(config_tree, "ScriptsInterpreter"), &interpreter)) {
+ 		// Force custom scripts interpreter allowing execution of scripts on android without execution flag (such as on /sdcard)
+ 		free(scriptname);
+ 		len = xasprintf(&scriptname, "%s \"%s/%s\"", interpreter, confbase, name);
+ 		free(interpreter);
+ 		if(len < 0)
+ 			return false;
+ 	}
+ 
 -	ifdebug(STATUS) logger(LOG_INFO, "Executing script %s", name);
 +	logger(DEBUG_STATUS, LOG_INFO, "Executing script %s", name);
 +
+ 
  #ifdef HAVE_PUTENV
  	/* Set environment */
  	
diff --cc src/protocol_key.c
index fbd3c16,f2f317d..802f7ca
--- a/src/protocol_key.c
+++ b/src/protocol_key.c
@@@ -331,11 -237,17 +331,14 @@@ bool ans_key_h(connection_t *c, const c
  			return true;
  		}
  
 -		return send_request(to->nexthop->connection, "%s", c->buffer);
 +		return send_request(to->nexthop->connection, "%s", request);
  	}
  
+ 	/* Don't use key material until every check has passed. */
+ 	from->status.validkey = false;
+ 
 -	/* Update our copy of the origin's packet key */
 -	from->outkey = xrealloc(from->outkey, strlen(key) / 2);
 -	from->outkeylength = strlen(key) / 2;
 -	if(!hex2bin(key, from->outkey, from->outkeylength)) {
 -		logger(LOG_ERR, "Got bad %s from %s(%s): %s", "ANS_KEY", from->name, from->hostname, "invalid key");
 +	if(compression < 0 || compression > 11) {
 +		logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus compression level!", from->name, from->hostname);
  		return true;
  	}
  
diff --cc src/utils.c
index e750450,0000000..129622b
mode 100644,000000..100644
--- a/src/utils.c
+++ b/src/utils.c
@@@ -1,162 -1,0 +1,162 @@@
 +/*
 +    utils.c -- gathering of some stupid small functions
 +    Copyright (C) 1999-2005 Ivo Timmermans
 +                  2000-2009 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
 +    the Free Software Foundation; either version 2 of the License, or
 +    (at your option) any later version.
 +
 +    This program is distributed in the hope that it will be useful,
 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +    GNU General Public License for more details.
 +
 +    You should have received a copy of the GNU General Public License along
 +    with this program; if not, write to the Free Software Foundation, Inc.,
 +    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 +*/
 +
 +#include "system.h"
 +
 +#include "../src/logger.h"
 +#include "utils.h"
 +
 +static const char hexadecimals[] = "0123456789ABCDEF";
 +static const char base64imals[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 +
 +static int charhex2bin(char c) {
 +	if(isdigit(c))
 +		return c - '0';
 +	else
 +		return toupper(c) - 'A' + 10;
 +}
 +
 +static int charb64decode(char c) {
 +	if(c >= 'a')
 +		return c - 'a' + 26;
 +	else if(c >= 'A')
 +		return c - 'A';
 +	else if(c >= '0') 
 +		return c - '0' + 52;
 +	else if(c == '+')
 +		return 62;
 +	else
 +		return 63;
 +}
 +
 +int hex2bin(const char *src, char *dst, int length) {
 +	int i;
- 	for(i = 0; i < length && src[i * 2] && src[i * 2 + 1]; i++)
++	for(i = 0; i < length && isxdigit(src[i * 2]) && isxdigit(src[i * 2 + 1]); i++)
 +		dst[i] = charhex2bin(src[i * 2]) * 16 + charhex2bin(src[i * 2 + 1]);
 +	return i;
 +}
 +
 +int bin2hex(const char *src, char *dst, int length) {
 +	int i;
 +	for(i = length - 1; i >= 0; i--) {
 +		dst[i * 2 + 1] = hexadecimals[(unsigned char) src[i] & 15];
 +		dst[i * 2] = hexadecimals[(unsigned char) src[i] >> 4];
 +	}
 +	dst[length * 2] = 0;
 +	return length * 2;
 +}
 +
 +int b64decode(const char *src, char *dst, int length) {
 +	int i;
 +	uint32_t triplet = 0;
 +	unsigned char *udst = (unsigned char *)dst;
 +
 +	for(i = 0; i < length / 3 * 4 && src[i]; i++) {
 +		triplet |= charb64decode(src[i]) << (6 * (i & 3));
 +		if((i & 3) == 3) {
 +			udst[0] = triplet & 0xff; triplet >>= 8;
 +			udst[1] = triplet & 0xff; triplet >>= 8;
 +			udst[2] = triplet;
 +			triplet = 0;
 +			udst += 3;
 +		}
 +	}
 +	if((i & 3) == 3) {
 +		udst[0] = triplet & 0xff; triplet >>= 8;
 +		udst[1] = triplet & 0xff;
 +		return i / 4 * 3 + 2;
 +	} else if((i & 3) == 2) {
 +		udst[0] = triplet & 0xff;
 +		return i / 4 * 3 + 1;
 +	} else {
 +		return i / 4 * 3;
 +	}
 +}
 +
 +int b64encode(const char *src, char *dst, int length) {
 +	uint32_t triplet;
 +	const unsigned char *usrc = (unsigned char *)src;
 +	int si = length / 3 * 3;
 +	int di = length / 3 * 4;
 +
 +	switch(length % 3) {
 +		case 2:	
 +			triplet = usrc[si] | usrc[si + 1] << 8;
 +			dst[di] = base64imals[triplet & 63]; triplet >>= 6;
 +			dst[di + 1] = base64imals[triplet & 63]; triplet >>= 6;
 +			dst[di + 2] = base64imals[triplet];
 +			dst[di + 3] = 0;
 +			length = di + 2;
 +			break;
 +		case 1:
 +			triplet = usrc[si];
 +			dst[di] = base64imals[triplet & 63]; triplet >>= 6;
 +			dst[di + 1] = base64imals[triplet];
 +			dst[di + 2] = 0;
 +			length = di + 1;
 +			break;
 +		default:
 +			dst[di] = 0;
 +			length = di;
 +			break;
 +	}
 +
 +	while(si > 0) {
 +		di -= 4;
 +		si -= 3;
 +		triplet = usrc[si] | usrc[si + 1] << 8 | usrc[si + 2] << 16;
 +		dst[di] = base64imals[triplet & 63]; triplet >>= 6;
 +		dst[di + 1] = base64imals[triplet & 63]; triplet >>= 6;
 +		dst[di + 2] = base64imals[triplet & 63]; triplet >>= 6;
 +		dst[di + 3] = base64imals[triplet];
 +	}
 +
 +	return length;
 +}
 +
 +#if defined(HAVE_MINGW) || defined(HAVE_CYGWIN)
 +#ifdef HAVE_CYGWIN
 +#include <w32api/windows.h>
 +#endif
 +
 +const char *winerror(int err) {
 +	static char buf[1024], *ptr;
 +
 +	ptr = buf + sprintf(buf, "(%d) ", err);
 +
 +	if (!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
 +	        NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), ptr, sizeof(buf) - (ptr - buf), NULL)) {
 +		strncpy(buf, "(unable to format errormessage)", sizeof(buf));
 +	};
 +
 +	if((ptr = strchr(buf, '\r')))
 +		*ptr = '\0';
 +
 +	return buf;
 +}
 +#endif
 +
 +unsigned int bitfield_to_int(const void *bitfield, size_t size) {
 +	unsigned int value = 0;
 +	if(size > sizeof value)
 +		size = sizeof value;
 +	memcpy(&value, bitfield, size);
 +	return value;
 +}