X-Git-Url: https://www.tinc-vpn.org/git/browse?p=tinc;a=blobdiff_plain;f=src%2Fnet_setup.c;h=3e435ddaebfd87b125f016298f10ead62aa1381d;hp=a179228be7f5075f0bfcd2e23e257a768e76602c;hb=8793fb7d43161f4d5358ff73b7a4937ad7e642e2;hpb=535a55100bb77f107c85361e9f72a194e92bc8bc diff --git a/src/net_setup.c b/src/net_setup.c index a179228b..3e435dda 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); @@ -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"); @@ -429,7 +508,19 @@ static bool setup_myself(void) { get_config_bool(lookup_config(config_tree, "PriorityInheritance"), &priorityinheritance); get_config_bool(lookup_config(config_tree, "DecrementTTL"), &decrement_ttl); - get_config_bool(lookup_config(config_tree, "Broadcast"), &broadcast); + if(get_config_string(lookup_config(config_tree, "Broadcast"), &mode)) { + if(!strcasecmp(mode, "no")) + broadcast_mode = BMODE_NONE; + else if(!strcasecmp(mode, "yes") || !strcasecmp(mode, "mst")) + broadcast_mode = BMODE_MST; + else if(!strcasecmp(mode, "direct")) + broadcast_mode = BMODE_DIRECT; + else { + logger(LOG_ERR, "Invalid broadcast mode!"); + return false; + } + free(mode); + } #if !defined(SOL_IP) || !defined(IP_TOS) if(priorityinheritance)