From: Guus Sliepen 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://tinc-vpn.org/git/browse?p=tinc;a=commitdiff_plain;h=6dfdb323612184529b4b83c1be914dda8262de47 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 ba2ad5fc,a28ab7ad..c033e220 --- 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 9c880e69,00000000..efd63d53 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 + + 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 +#include + +#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 0e33f264,262b092c..362b678c --- 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 fbd3c16f,f2f317de..802f7ca6 --- 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 e750450e,00000000..129622b2 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 + + 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 +#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; +}