mirror of
https://github.com/rizsotto/Bear.git
synced 2025-12-12 20:35:47 +01:00
Disable network proxies by default (#631)
* Disable network proxies by default and allow the user to enable them with the new --enable-network-proxy flag * Update man with new --enable-network-proxy flag * Increase help space for option names to accommodate the new option --enable-network-proxy
This commit is contained in:
@@ -54,6 +54,12 @@ Force to use the dynamic linker method of \f[C]intercept\f[R] command.
|
||||
.TP
|
||||
--force-wrapper
|
||||
Force to use the compiler wrapper method of \f[C]intercept\f[R] command.
|
||||
.TP
|
||||
--enable-network-proxy
|
||||
Forward HTTP proxy environment variables (\f[C]http_proxy\f[R],
|
||||
\f[C]https_proxy\f[R], \f[C]grpc_proxy\f[R] and their capitalized
|
||||
versions) to \f[C]intercept\f[R] command.
|
||||
They are unset by default.
|
||||
.SH COMMANDS
|
||||
.TP
|
||||
\f[B]\f[CB]bear-intercept(1)\f[B]\f[R]
|
||||
|
||||
@@ -55,6 +55,11 @@ compilation database.
|
||||
\--force-wrapper
|
||||
: Force to use the compiler wrapper method of `intercept` command.
|
||||
|
||||
\--enable-network-proxy
|
||||
: Forward HTTP proxy environment variables (`http_proxy`, `https_proxy`,
|
||||
`grpc_proxy` and their capitalized versions) to `intercept` command.
|
||||
They are unset by default.
|
||||
|
||||
# COMMANDS
|
||||
|
||||
`bear-intercept(1)`
|
||||
|
||||
@@ -36,10 +36,11 @@ namespace {
|
||||
auto verbose = arguments.as_bool(flags::VERBOSE).unwrap_or(false);
|
||||
auto force_wrapper = arguments.as_bool(cmd::intercept::FLAG_FORCE_WRAPPER).unwrap_or(false);
|
||||
auto force_preload = arguments.as_bool(cmd::intercept::FLAG_FORCE_PRELOAD).unwrap_or(false);
|
||||
auto enable_network_proxy = arguments.as_bool(cmd::intercept::FLAG_ENABLE_NETWORK_PROXY).unwrap_or(false);
|
||||
|
||||
return rust::merge(program, command, rust::merge(library, wrapper, wrapper_dir))
|
||||
.map<sys::Process::Builder>(
|
||||
[&environment, &output, &verbose, &force_wrapper, &force_preload](auto tuple) {
|
||||
[&environment, &output, &verbose, &force_wrapper, &force_preload, &enable_network_proxy](auto tuple) {
|
||||
const auto&[program, command, pack] = tuple;
|
||||
const auto&[library, wrapper, wrapper_dir] = pack;
|
||||
|
||||
@@ -57,6 +58,9 @@ namespace {
|
||||
if (force_preload) {
|
||||
builder.add_argument(cmd::intercept::FLAG_FORCE_PRELOAD);
|
||||
}
|
||||
if (enable_network_proxy) {
|
||||
builder.add_argument(cmd::intercept::FLAG_ENABLE_NETWORK_PROXY);
|
||||
}
|
||||
if (verbose) {
|
||||
builder.add_argument(flags::VERBOSE);
|
||||
}
|
||||
@@ -146,13 +150,14 @@ namespace bear {
|
||||
rust::Result<flags::Arguments> Application::parse(int argc, const char **argv) const
|
||||
{
|
||||
const flags::Parser intercept_parser("intercept", cmd::VERSION, {
|
||||
{cmd::intercept::FLAG_OUTPUT, {1, false, "path of the result file", {cmd::intercept::DEFAULT_OUTPUT}, std::nullopt}},
|
||||
{cmd::intercept::FLAG_FORCE_PRELOAD, {0, false, "force to use library preload", std::nullopt, DEVELOPER_GROUP}},
|
||||
{cmd::intercept::FLAG_FORCE_WRAPPER, {0, false, "force to use compiler wrappers", std::nullopt, DEVELOPER_GROUP}},
|
||||
{cmd::intercept::FLAG_LIBRARY, {1, false, "path to the preload library", {cmd::library::DEFAULT_PATH}, DEVELOPER_GROUP}},
|
||||
{cmd::intercept::FLAG_WRAPPER, {1, false, "path to the wrapper executable", {cmd::wrapper::DEFAULT_PATH}, DEVELOPER_GROUP}},
|
||||
{cmd::intercept::FLAG_WRAPPER_DIR, {1, false, "path to the wrapper directory", {cmd::wrapper::DEFAULT_DIR_PATH}, DEVELOPER_GROUP}},
|
||||
{cmd::intercept::FLAG_COMMAND, {-1, true, "command to execute", std::nullopt, std::nullopt}}
|
||||
{cmd::intercept::FLAG_OUTPUT, {1, false, "path of the result file", {cmd::intercept::DEFAULT_OUTPUT}, std::nullopt}},
|
||||
{cmd::intercept::FLAG_FORCE_PRELOAD, {0, false, "force to use library preload", std::nullopt, DEVELOPER_GROUP}},
|
||||
{cmd::intercept::FLAG_FORCE_WRAPPER, {0, false, "force to use compiler wrappers", std::nullopt, DEVELOPER_GROUP}},
|
||||
{cmd::intercept::FLAG_ENABLE_NETWORK_PROXY, {0, false, "enable http and https proxy", std::nullopt, DEVELOPER_GROUP}},
|
||||
{cmd::intercept::FLAG_LIBRARY, {1, false, "path to the preload library", {cmd::library::DEFAULT_PATH}, DEVELOPER_GROUP}},
|
||||
{cmd::intercept::FLAG_WRAPPER, {1, false, "path to the wrapper executable", {cmd::wrapper::DEFAULT_PATH}, DEVELOPER_GROUP}},
|
||||
{cmd::intercept::FLAG_WRAPPER_DIR, {1, false, "path to the wrapper directory", {cmd::wrapper::DEFAULT_DIR_PATH}, DEVELOPER_GROUP}},
|
||||
{cmd::intercept::FLAG_COMMAND, {-1, true, "command to execute", std::nullopt, std::nullopt}}
|
||||
});
|
||||
|
||||
const flags::Parser citnames_parser("citnames", cmd::VERSION, {
|
||||
@@ -164,16 +169,17 @@ namespace bear {
|
||||
});
|
||||
|
||||
const flags::Parser parser("bear", cmd::VERSION, {intercept_parser, citnames_parser}, {
|
||||
{cmd::citnames::FLAG_OUTPUT, {1, false, "path of the result file", {cmd::citnames::DEFAULT_OUTPUT}, std::nullopt}},
|
||||
{cmd::citnames::FLAG_APPEND, {0, false, "append result to an existing output file", std::nullopt, ADVANCED_GROUP}},
|
||||
{cmd::citnames::FLAG_CONFIG, {1, false, "path of the config file", std::nullopt, ADVANCED_GROUP}},
|
||||
{cmd::intercept::FLAG_FORCE_PRELOAD, {0, false, "force to use library preload", std::nullopt, ADVANCED_GROUP}},
|
||||
{cmd::intercept::FLAG_FORCE_WRAPPER, {0, false, "force to use compiler wrappers", std::nullopt, ADVANCED_GROUP}},
|
||||
{cmd::bear::FLAG_BEAR, {1, false, "path to the bear executable", {cmd::bear::DEFAULT_PATH}, DEVELOPER_GROUP}},
|
||||
{cmd::intercept::FLAG_LIBRARY, {1, false, "path to the preload library", {cmd::library::DEFAULT_PATH}, DEVELOPER_GROUP}},
|
||||
{cmd::intercept::FLAG_WRAPPER, {1, false, "path to the wrapper executable", {cmd::wrapper::DEFAULT_PATH}, DEVELOPER_GROUP}},
|
||||
{cmd::intercept::FLAG_WRAPPER_DIR, {1, false, "path to the wrapper directory", {cmd::wrapper::DEFAULT_DIR_PATH}, DEVELOPER_GROUP}},
|
||||
{cmd::intercept::FLAG_COMMAND, {-1, true, "command to execute", std::nullopt, std::nullopt}}
|
||||
{cmd::citnames::FLAG_OUTPUT, {1, false, "path of the result file", {cmd::citnames::DEFAULT_OUTPUT}, std::nullopt}},
|
||||
{cmd::citnames::FLAG_APPEND, {0, false, "append result to an existing output file", std::nullopt, ADVANCED_GROUP}},
|
||||
{cmd::citnames::FLAG_CONFIG, {1, false, "path of the config file", std::nullopt, ADVANCED_GROUP}},
|
||||
{cmd::intercept::FLAG_FORCE_PRELOAD, {0, false, "force to use library preload", std::nullopt, ADVANCED_GROUP}},
|
||||
{cmd::intercept::FLAG_FORCE_WRAPPER, {0, false, "force to use compiler wrappers", std::nullopt, ADVANCED_GROUP}},
|
||||
{cmd::intercept::FLAG_ENABLE_NETWORK_PROXY, {0, false, "enable http and https proxy", std::nullopt, ADVANCED_GROUP}},
|
||||
{cmd::bear::FLAG_BEAR, {1, false, "path to the bear executable", {cmd::bear::DEFAULT_PATH}, DEVELOPER_GROUP}},
|
||||
{cmd::intercept::FLAG_LIBRARY, {1, false, "path to the preload library", {cmd::library::DEFAULT_PATH}, DEVELOPER_GROUP}},
|
||||
{cmd::intercept::FLAG_WRAPPER, {1, false, "path to the wrapper executable", {cmd::wrapper::DEFAULT_PATH}, DEVELOPER_GROUP}},
|
||||
{cmd::intercept::FLAG_WRAPPER_DIR, {1, false, "path to the wrapper directory", {cmd::wrapper::DEFAULT_DIR_PATH}, DEVELOPER_GROUP}},
|
||||
{cmd::intercept::FLAG_COMMAND, {-1, true, "command to execute", std::nullopt, std::nullopt}}
|
||||
});
|
||||
return parser.parse_or_exit(argc, const_cast<const char **>(argv));
|
||||
}
|
||||
@@ -186,6 +192,12 @@ namespace bear {
|
||||
return citnames.subcommand(args, envp);
|
||||
}
|
||||
if (auto intercept = ic::Intercept(log_config_); intercept.matches(args)) {
|
||||
// Network proxy is disabled by default unless user explicitly enables it
|
||||
if (!args.as_bool(cmd::intercept::FLAG_ENABLE_NETWORK_PROXY).unwrap_or(false)) {
|
||||
for (auto proxyEnv : cmd::intercept::PROXY_ENV_VARS) {
|
||||
unsetenv(proxyEnv);
|
||||
}
|
||||
}
|
||||
return intercept.subcommand(args, envp);
|
||||
}
|
||||
return rust::Err(std::runtime_error("Invalid subcommand"));
|
||||
|
||||
@@ -102,6 +102,8 @@ namespace cmd {
|
||||
constexpr char FLAG_COMMAND[] = "--";
|
||||
constexpr char FLAG_FORCE_WRAPPER[] = "--force-wrapper";
|
||||
constexpr char FLAG_FORCE_PRELOAD[] = "--force-preload";
|
||||
constexpr char FLAG_ENABLE_NETWORK_PROXY[] = "--enable-network-proxy";
|
||||
constexpr const char* PROXY_ENV_VARS[] = {"http_proxy", "https_proxy", "grpc_proxy","all_proxy", "HTTP_PROXY", "HTTPS_PROXY", "GRPC_PROXY", "ALL_PROXY"};
|
||||
|
||||
constexpr char DEFAULT_OUTPUT[] = "events.json";
|
||||
}
|
||||
|
||||
@@ -110,11 +110,11 @@ namespace {
|
||||
// print flag name
|
||||
os << flag_name;
|
||||
// decide if the help text goes into the same line or not
|
||||
if (flag_size > 22) {
|
||||
if (flag_size > 25) {
|
||||
os << std::endl
|
||||
<< std::string(15, ' ');
|
||||
} else {
|
||||
os << std::string(23 - flag_size, ' ');
|
||||
os << std::string(26 - flag_size, ' ');
|
||||
}
|
||||
os << option.help;
|
||||
// print default value if exists
|
||||
|
||||
@@ -177,16 +177,16 @@ namespace {
|
||||
const char *expected =
|
||||
"Usage: test [--flag] [--option <arg>] [--options <arg0> <arg1> <arg2>] [--verbose] [-- ...]\n"
|
||||
"\n"
|
||||
" --flag a single flag\n"
|
||||
" --option <arg> a flag with a value\n"
|
||||
" --flag a single flag\n"
|
||||
" --option <arg> a flag with a value\n"
|
||||
" --options <arg0> <arg1> <arg2>\n"
|
||||
" a flag with 3 values\n"
|
||||
" --verbose run in verbose mode\n"
|
||||
" -- ... rest of the arguments\n"
|
||||
" --verbose run in verbose mode\n"
|
||||
" -- ... rest of the arguments\n"
|
||||
"\n"
|
||||
"query options\n"
|
||||
" --help print help and exit\n"
|
||||
" --version print version and exit\n";
|
||||
" --help print help and exit\n"
|
||||
" --version print version and exit\n";
|
||||
|
||||
std::ostringstream out;
|
||||
sut.print_help(nullptr, out);
|
||||
@@ -367,8 +367,8 @@ namespace {
|
||||
" dump\n"
|
||||
"\n"
|
||||
"query options\n"
|
||||
" --help print help and exit\n"
|
||||
" --version print version and exit\n";
|
||||
" --help print help and exit\n"
|
||||
" --version print version and exit\n";
|
||||
|
||||
std::ostringstream out;
|
||||
sut.print_help(nullptr, out);
|
||||
@@ -378,11 +378,11 @@ namespace {
|
||||
const char *expected =
|
||||
"Usage: test append [--option <arg>] [--verbose]\n"
|
||||
"\n"
|
||||
" --option <arg> a flag with a value\n"
|
||||
" --verbose run in verbose mode\n"
|
||||
" --option <arg> a flag with a value\n"
|
||||
" --verbose run in verbose mode\n"
|
||||
"\n"
|
||||
"query options\n"
|
||||
" --help print help and exit\n";
|
||||
" --help print help and exit\n";
|
||||
|
||||
std::ostringstream out;
|
||||
sut.print_help(&append, out);
|
||||
|
||||
25
test/cases/intercept/wrapper/shell_enable_network_proxy.sh
Normal file
25
test/cases/intercept/wrapper/shell_enable_network_proxy.sh
Normal file
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# REQUIRES: shell, cc
|
||||
|
||||
# If an unreachable or an invalid http proxy is set, an error is returned if '--enable-network-proxy' is set
|
||||
#
|
||||
# RUN: env http_proxy=http://localhost:9999 %{intercept} --enable-network-proxy --output %t.json -- %{shell} %s 2> %t.stderr
|
||||
# RUN: grep "failed to connect to all addresses" %t.stderr
|
||||
# RUN: assert_intercepted %t.json count -eq 0
|
||||
|
||||
# If no http proxy is set, it should run correctly even with '--enable-network-proxy'
|
||||
#
|
||||
# RUN: %{intercept} --enable-network-proxy --output %t.json -- %{shell} %s
|
||||
# RUN: assert_intercepted %t.json count -eq 1
|
||||
# RUN: assert_intercepted %t.json contains -program %{c_compiler} -arguments %{c_compiler} -c shell_enable_network_proxy.c -o shell_enable_network_proxy.o
|
||||
|
||||
# By default, even with an invalid http proxy set, it should run correctly
|
||||
#
|
||||
# RUN: env http_proxy=http://localhost:9999 %{intercept} --output %t.json -- %{shell}
|
||||
# RUN: assert_intercepted %t.json count -eq 1
|
||||
|
||||
touch shell_enable_network_proxy.c
|
||||
|
||||
$CC -c shell_enable_network_proxy.c -o shell_enable_network_proxy.o
|
||||
|
||||
Reference in New Issue
Block a user