X-Git-Url: https://www.tinc-vpn.org/git/browse?p=tinc;a=blobdiff_plain;f=src%2Fnet_setup.c;h=ddb0bcfd7f2fdc32c53ddc598c7577a8cee08bfc;hp=b8e17da9bbbdf4c8dc32b20ed18d18310921c46d;hb=0eceee6a66b28535a9c44d282e07a5825c7a1f04;hpb=84531fb6e621959e06519fdbb7f2a8f7578f66bd diff --git a/src/net_setup.c b/src/net_setup.c index b8e17da9..ddb0bcfd 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -47,9 +47,16 @@ 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) { @@ -60,7 +67,10 @@ bool read_rsa_public_key(connection_t *c) { /* 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; @@ -68,80 +78,79 @@ bool read_rsa_public_key(connection_t *c) { /* 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; @@ -163,8 +172,14 @@ static bool read_rsa_private_key(void) { } 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); @@ -284,7 +299,7 @@ char *get_name(void) { 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; @@ -316,6 +331,8 @@ static bool setup_myself(void) { char *name, *hostname, *mode, *afname, *cipher, *digest, *type; char *fname = NULL; char *address = NULL; + char *proxy = NULL; + char *space; char *envp[5]; struct addrinfo *ai, *aip, hint = {0}; bool choice; @@ -359,6 +376,68 @@ static bool setup_myself(void) { 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");