diff --git a/src/libproxychains.c b/src/libproxychains.c index 40d8a11..d0f81ec 100644 --- a/src/libproxychains.c +++ b/src/libproxychains.c @@ -306,6 +306,11 @@ static void get_chain_data(proxy_data * pd, unsigned int *proxy_count, chain_typ tcp_connect_time_out = 10 * 1000; *ct = DYNAMIC_TYPE; + if(getenv("PROXYCHAINS_PROXY")) { + proxychains_write_log(LOG_PREFIX "using -x proxy, no config file\n"); + goto use_proxy_env; + } + env = get_config_path(getenv(PROXYCHAINS_CONF_FILE_ENV_VAR), buf, sizeof(buf)); if( ( file = fopen(env, "r") ) == NULL ) { @@ -564,9 +569,41 @@ static void get_chain_data(proxy_data * pd, unsigned int *proxy_count, chain_typ fclose(file); #endif if(!count) { + if(getenv("PROXYCHAINS_PROXY")) + goto use_proxy_env; fprintf(stderr, "error: no valid proxy found in config\n"); exit(1); } + goto done; + +use_proxy_env: +{ + int port_n = 0; + char *proxy_env = getenv("PROXYCHAINS_PROXY"); + + if(!proxy_from_string(proxy_env, type, host, &port_n, pd[0].user, pd[0].pass)) { + fprintf(stderr, "error: invalid proxy specified in -x: %s\n", proxy_env); + exit(1); + } + + pd[0].ip.is_v6 = !!strchr(host, ':'); + pd[0].port = htons((unsigned short) port_n); + if(1 != inet_pton(pd[0].ip.is_v6 ? AF_INET6 : AF_INET, host, pd[0].ip.addr.v6)) { + fprintf(stderr, "error: proxy host must be a numeric ip: %s\n", host); + exit(1); + } + + if(!strcmp(type, "http")) + pd[0].pt = HTTP_TYPE; + else if(!strcmp(type, "socks4")) + pd[0].pt = SOCKS4_TYPE; + else + pd[0].pt = SOCKS5_TYPE; + + count = 1; +} + +done: *proxy_count = count; proxychains_got_chain_data = 1; PDEBUG("proxy_dns: %s\n", rdns_resolver_string(proxychains_resolver)); diff --git a/src/main.c b/src/main.c index 381c71c..11c336b 100644 --- a/src/main.c +++ b/src/main.c @@ -24,9 +24,12 @@ #include "common.h" static int usage(char **argv) { - printf("\nUsage:\t%s -q -f config_file program_name [arguments]\n" + printf("\nUsage:\t%s -q -f config_file -x proxy_url program_name [arguments]\n" "\t-q makes proxychains quiet - this overrides the config setting\n" "\t-f allows one to manually specify a configfile to use\n" + "\t-x allows one to manually specify a proxy (e.g. socks5://127.0.0.1:1080)\n" + "\t proxy types: http, socks4, socks5, raw\n" + "\t syntax: type://[user:pass@]host:port\n" "\tfor example : proxychains telnet somehost.com\n" "More help in README file\n\n", argv[0]); return EXIT_FAILURE; } @@ -63,7 +66,7 @@ static void set_own_dir(const char *argv0) { } } -#define MAX_COMMANDLINE_FLAGS 2 +#define MAX_COMMANDLINE_FLAGS 3 int main(int argc, char *argv[]) { char *path = NULL; @@ -90,7 +93,16 @@ int main(int argc, char *argv[]) { return usage(argv); start_argv += 2; - } + } else if(argv[start_argv][1] == 'x') { + + if(start_argv + 1 < argc) + setenv("PROXYCHAINS_PROXY", argv[start_argv + 1], 1); + else + return usage(argv); + + start_argv += 2; + } else + break; } else break; } @@ -99,7 +111,10 @@ int main(int argc, char *argv[]) { return usage(argv); /* check if path of config file has not been passed via command line */ - path = get_config_path(path, pbuf, sizeof(pbuf)); + if(getenv("PROXYCHAINS_PROXY")) + path = "./proxychains.conf"; + else + path = get_config_path(path, pbuf, sizeof(pbuf)); if(!quiet) fprintf(stderr, LOG_PREFIX "config file found: %s\n", path);