/*
net_setup.c -- Setup.
Copyright (C) 1998-2005 Ivo Timmermans,
- 2000-2012 Guus Sliepen <guus@tinc-vpn.org>
+ 2000-2013 Guus Sliepen <guus@tinc-vpn.org>
2006 Scott Lamb <slamb@slamb.org>
2010 Brandon Black <blblack@gmail.com>
char *myport;
devops_t devops;
+char *proxyhost;
+char *proxyport;
+char *proxyuser;
+char *proxypass;
+proxytype_t proxytype;
+
bool read_rsa_public_key(connection_t *c) {
FILE *fp;
- char *fname;
+ char *pubname;
+ char *hcfname;
char *key;
if(!c->rsa_key) {
/* First, check for simple PublicKey statement */
if(get_config_string(lookup_config(c->config_tree, "PublicKey"), &key)) {
- BN_hex2bn(&c->rsa_key->n, key);
+ if(BN_hex2bn(&c->rsa_key->n, key) != strlen(key)) {
+ logger(LOG_ERR, "Invalid PublicKey for %s!", c->name);
+ return false;
+ }
BN_hex2bn(&c->rsa_key->e, "FFFF");
free(key);
return true;
/* Else, check for PublicKeyFile statement and read it */
- if(get_config_string(lookup_config(c->config_tree, "PublicKeyFile"), &fname)) {
- fp = fopen(fname, "r");
+ if(get_config_string(lookup_config(c->config_tree, "PublicKeyFile"), &pubname)) {
+ fp = fopen(pubname, "r");
if(!fp) {
- logger(LOG_ERR, "Error reading RSA public key file `%s': %s",
- fname, strerror(errno));
- free(fname);
+ logger(LOG_ERR, "Error reading RSA public key file `%s': %s", pubname, strerror(errno));
+ free(pubname);
return false;
}
- free(fname);
c->rsa_key = PEM_read_RSAPublicKey(fp, &c->rsa_key, NULL, NULL);
fclose(fp);
- if(c->rsa_key)
+ if(c->rsa_key) {
+ free(pubname);
return true; /* Woohoo. */
+ }
/* If it fails, try PEM_read_RSA_PUBKEY. */
- fp = fopen(fname, "r");
+ fp = fopen(pubname, "r");
if(!fp) {
- logger(LOG_ERR, "Error reading RSA public key file `%s': %s",
- fname, strerror(errno));
- free(fname);
+ logger(LOG_ERR, "Error reading RSA public key file `%s': %s", pubname, strerror(errno));
+ free(pubname);
return false;
}
- free(fname);
c->rsa_key = PEM_read_RSA_PUBKEY(fp, &c->rsa_key, NULL, NULL);
fclose(fp);
if(c->rsa_key) {
// RSA_blinding_on(c->rsa_key, NULL);
+ free(pubname);
return true;
}
- logger(LOG_ERR, "Reading RSA public key file `%s' failed: %s",
- fname, strerror(errno));
+ logger(LOG_ERR, "Reading RSA public key file `%s' failed: %s", pubname, strerror(errno));
+ free(pubname);
return false;
}
/* Else, check if a harnessed public key is in the config file */
- xasprintf(&fname, "%s/hosts/%s", confbase, c->name);
- fp = fopen(fname, "r");
+ xasprintf(&hcfname, "%s/hosts/%s", confbase, c->name);
+ fp = fopen(hcfname, "r");
if(!fp) {
- logger(LOG_ERR, "Error reading RSA public key file `%s': %s", fname, strerror(errno));
- free(fname);
+ logger(LOG_ERR, "Error reading RSA public key file `%s': %s", hcfname, strerror(errno));
+ free(hcfname);
return false;
}
c->rsa_key = PEM_read_RSAPublicKey(fp, &c->rsa_key, NULL, NULL);
fclose(fp);
- free(fname);
- if(c->rsa_key)
+ if(c->rsa_key) {
+ free(hcfname);
return true;
+ }
/* Try again with PEM_read_RSA_PUBKEY. */
- xasprintf(&fname, "%s/hosts/%s", confbase, c->name);
- fp = fopen(fname, "r");
+ fp = fopen(hcfname, "r");
if(!fp) {
- logger(LOG_ERR, "Error reading RSA public key file `%s': %s", fname, strerror(errno));
- free(fname);
+ logger(LOG_ERR, "Error reading RSA public key file `%s': %s", hcfname, strerror(errno));
+ free(hcfname);
return false;
}
+ free(hcfname);
c->rsa_key = PEM_read_RSA_PUBKEY(fp, &c->rsa_key, NULL, NULL);
// RSA_blinding_on(c->rsa_key, NULL);
fclose(fp);
- free(fname);
if(c->rsa_key)
return true;
static bool read_rsa_private_key(void) {
FILE *fp;
char *fname, *key, *pubkey;
- struct stat s;
if(get_config_string(lookup_config(config_tree, "PrivateKey"), &key)) {
if(!get_config_string(lookup_config(config_tree, "PublicKey"), &pubkey)) {
}
myself->connection->rsa_key = RSA_new();
// RSA_blinding_on(myself->connection->rsa_key, NULL);
- BN_hex2bn(&myself->connection->rsa_key->d, key);
- BN_hex2bn(&myself->connection->rsa_key->n, pubkey);
+ 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!");
+ return false;
+ }
BN_hex2bn(&myself->connection->rsa_key->e, "FFFF");
free(key);
free(pubkey);
}
#if !defined(HAVE_MINGW) && !defined(HAVE_CYGWIN)
+ struct stat s;
+
if(fstat(fileno(fp), &s)) {
logger(LOG_ERR, "Could not stat RSA private key file `%s': %s'",
fname, strerror(errno));
fprintf(stderr, "Invalid Name: environment variable %s does not exist\n", name + 1);
return false;
}
- envname = alloca(32);
+ char envname[32];
if(gethostname(envname, 32)) {
fprintf(stderr, "Could not get hostname: %s\n", strerror(errno));
return false;
char *name, *hostname, *mode, *afname, *cipher, *digest, *type;
char *fname = NULL;
char *address = NULL;
- char *envp[5];
+ char *proxy = NULL;
+ char *space;
+ char *envp[5] = {NULL};
struct addrinfo *ai, *aip, hint = {0};
bool choice;
int i, err;
sockaddr2str(&sa, NULL, &myport);
}
+ get_config_string(lookup_config(config_tree, "Proxy"), &proxy);
+ if(proxy) {
+ if((space = strchr(proxy, ' ')))
+ *space++ = 0;
+
+ if(!strcasecmp(proxy, "none")) {
+ proxytype = PROXY_NONE;
+ } else if(!strcasecmp(proxy, "socks4")) {
+ proxytype = PROXY_SOCKS4;
+ } else if(!strcasecmp(proxy, "socks4a")) {
+ proxytype = PROXY_SOCKS4A;
+ } else if(!strcasecmp(proxy, "socks5")) {
+ proxytype = PROXY_SOCKS5;
+ } else if(!strcasecmp(proxy, "http")) {
+ proxytype = PROXY_HTTP;
+ } else if(!strcasecmp(proxy, "exec")) {
+ proxytype = PROXY_EXEC;
+ } else {
+ logger(LOG_ERR, "Unknown proxy type %s!", proxy);
+ return false;
+ }
+
+ switch(proxytype) {
+ case PROXY_NONE:
+ default:
+ break;
+
+ case PROXY_EXEC:
+ if(!space || !*space) {
+ logger(LOG_ERR, "Argument expected for proxy type exec!");
+ return false;
+ }
+ proxyhost = xstrdup(space);
+ break;
+
+ case PROXY_SOCKS4:
+ case PROXY_SOCKS4A:
+ case PROXY_SOCKS5:
+ case PROXY_HTTP:
+ proxyhost = space;
+ if(space && (space = strchr(space, ' ')))
+ *space++ = 0, proxyport = space;
+ if(space && (space = strchr(space, ' ')))
+ *space++ = 0, proxyuser = space;
+ if(space && (space = strchr(space, ' ')))
+ *space++ = 0, proxypass = space;
+ if(!proxyhost || !*proxyhost || !proxyport || !*proxyport) {
+ logger(LOG_ERR, "Host and port argument expected for proxy!");
+ return false;
+ }
+ proxyhost = xstrdup(proxyhost);
+ proxyport = xstrdup(proxyport);
+ if(proxyuser && *proxyuser)
+ proxyuser = xstrdup(proxyuser);
+ if(proxypass && *proxypass)
+ proxypass = xstrdup(proxypass);
+ break;
+ }
+
+ free(proxy);
+ }
+
/* Read in all the subnets specified in the host configuration file */
cfg = lookup_config(config_tree, "Subnet");
xasprintf(&envp[1], "DEVICE=%s", device ? : "");
xasprintf(&envp[2], "INTERFACE=%s", iface ? : "");
xasprintf(&envp[3], "NAME=%s", myself->name);
- envp[4] = NULL;
execute_script("tinc-up", envp);
- for(i = 0; i < 5; i++)
+ for(i = 0; i < 4; i++)
free(envp[i]);
/* Run subnet-up scripts for our own subnets */
void close_network_connections(void) {
avl_node_t *node, *next;
connection_t *c;
- char *envp[5];
+ char *envp[5] = {NULL};
int i;
for(node = connection_tree->head; node; node = next) {
xasprintf(&envp[1], "DEVICE=%s", device ? : "");
xasprintf(&envp[2], "INTERFACE=%s", iface ? : "");
xasprintf(&envp[3], "NAME=%s", myself->name);
- envp[4] = NULL;
exit_requests();
exit_edges();