Add strict checks to hex to binary conversions.
[oweals/tinc.git] / src / net_setup.c
index b8e17da9bbbdf4c8dc32b20ed18d18310921c46d..a28ab7ad147c7e3989bba3c3231861028098d1c4 100644 (file)
 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;
@@ -60,7 +66,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;
@@ -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");