Skip to content

Commit 0a49313

Browse files
authored
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
1 parent 14c2e01 commit 0a49313

File tree

7 files changed

+81
-31
lines changed

7 files changed

+81
-31
lines changed

source/bear/man/bear.1

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ Force to use the dynamic linker method of \f[C]intercept\f[R] command.
5454
.TP
5555
--force-wrapper
5656
Force to use the compiler wrapper method of \f[C]intercept\f[R] command.
57+
.TP
58+
--enable-network-proxy
59+
Forward HTTP proxy environment variables (\f[C]http_proxy\f[R],
60+
\f[C]https_proxy\f[R], \f[C]grpc_proxy\f[R] and their capitalized
61+
versions) to \f[C]intercept\f[R] command.
62+
They are unset by default.
5763
.SH COMMANDS
5864
.TP
5965
\f[B]\f[CB]bear-intercept(1)\f[B]\f[R]

source/bear/man/bear.1.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ compilation database.
5555
\--force-wrapper
5656
: Force to use the compiler wrapper method of `intercept` command.
5757

58+
\--enable-network-proxy
59+
: Forward HTTP proxy environment variables (`http_proxy`, `https_proxy`,
60+
`grpc_proxy` and their capitalized versions) to `intercept` command.
61+
They are unset by default.
62+
5863
# COMMANDS
5964

6065
`bear-intercept(1)`

source/bear/source/Application.cc

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,11 @@ namespace {
3636
auto verbose = arguments.as_bool(flags::VERBOSE).unwrap_or(false);
3737
auto force_wrapper = arguments.as_bool(cmd::intercept::FLAG_FORCE_WRAPPER).unwrap_or(false);
3838
auto force_preload = arguments.as_bool(cmd::intercept::FLAG_FORCE_PRELOAD).unwrap_or(false);
39+
auto enable_network_proxy = arguments.as_bool(cmd::intercept::FLAG_ENABLE_NETWORK_PROXY).unwrap_or(false);
3940

4041
return rust::merge(program, command, rust::merge(library, wrapper, wrapper_dir))
4142
.map<sys::Process::Builder>(
42-
[&environment, &output, &verbose, &force_wrapper, &force_preload](auto tuple) {
43+
[&environment, &output, &verbose, &force_wrapper, &force_preload, &enable_network_proxy](auto tuple) {
4344
const auto&[program, command, pack] = tuple;
4445
const auto&[library, wrapper, wrapper_dir] = pack;
4546

@@ -57,6 +58,9 @@ namespace {
5758
if (force_preload) {
5859
builder.add_argument(cmd::intercept::FLAG_FORCE_PRELOAD);
5960
}
61+
if (enable_network_proxy) {
62+
builder.add_argument(cmd::intercept::FLAG_ENABLE_NETWORK_PROXY);
63+
}
6064
if (verbose) {
6165
builder.add_argument(flags::VERBOSE);
6266
}
@@ -146,13 +150,14 @@ namespace bear {
146150
rust::Result<flags::Arguments> Application::parse(int argc, const char **argv) const
147151
{
148152
const flags::Parser intercept_parser("intercept", cmd::VERSION, {
149-
{cmd::intercept::FLAG_OUTPUT, {1, false, "path of the result file", {cmd::intercept::DEFAULT_OUTPUT}, std::nullopt}},
150-
{cmd::intercept::FLAG_FORCE_PRELOAD, {0, false, "force to use library preload", std::nullopt, DEVELOPER_GROUP}},
151-
{cmd::intercept::FLAG_FORCE_WRAPPER, {0, false, "force to use compiler wrappers", std::nullopt, DEVELOPER_GROUP}},
152-
{cmd::intercept::FLAG_LIBRARY, {1, false, "path to the preload library", {cmd::library::DEFAULT_PATH}, DEVELOPER_GROUP}},
153-
{cmd::intercept::FLAG_WRAPPER, {1, false, "path to the wrapper executable", {cmd::wrapper::DEFAULT_PATH}, DEVELOPER_GROUP}},
154-
{cmd::intercept::FLAG_WRAPPER_DIR, {1, false, "path to the wrapper directory", {cmd::wrapper::DEFAULT_DIR_PATH}, DEVELOPER_GROUP}},
155-
{cmd::intercept::FLAG_COMMAND, {-1, true, "command to execute", std::nullopt, std::nullopt}}
153+
{cmd::intercept::FLAG_OUTPUT, {1, false, "path of the result file", {cmd::intercept::DEFAULT_OUTPUT}, std::nullopt}},
154+
{cmd::intercept::FLAG_FORCE_PRELOAD, {0, false, "force to use library preload", std::nullopt, DEVELOPER_GROUP}},
155+
{cmd::intercept::FLAG_FORCE_WRAPPER, {0, false, "force to use compiler wrappers", std::nullopt, DEVELOPER_GROUP}},
156+
{cmd::intercept::FLAG_ENABLE_NETWORK_PROXY, {0, false, "enable http and https proxy", std::nullopt, DEVELOPER_GROUP}},
157+
{cmd::intercept::FLAG_LIBRARY, {1, false, "path to the preload library", {cmd::library::DEFAULT_PATH}, DEVELOPER_GROUP}},
158+
{cmd::intercept::FLAG_WRAPPER, {1, false, "path to the wrapper executable", {cmd::wrapper::DEFAULT_PATH}, DEVELOPER_GROUP}},
159+
{cmd::intercept::FLAG_WRAPPER_DIR, {1, false, "path to the wrapper directory", {cmd::wrapper::DEFAULT_DIR_PATH}, DEVELOPER_GROUP}},
160+
{cmd::intercept::FLAG_COMMAND, {-1, true, "command to execute", std::nullopt, std::nullopt}}
156161
});
157162

158163
const flags::Parser citnames_parser("citnames", cmd::VERSION, {
@@ -164,16 +169,17 @@ namespace bear {
164169
});
165170

166171
const flags::Parser parser("bear", cmd::VERSION, {intercept_parser, citnames_parser}, {
167-
{cmd::citnames::FLAG_OUTPUT, {1, false, "path of the result file", {cmd::citnames::DEFAULT_OUTPUT}, std::nullopt}},
168-
{cmd::citnames::FLAG_APPEND, {0, false, "append result to an existing output file", std::nullopt, ADVANCED_GROUP}},
169-
{cmd::citnames::FLAG_CONFIG, {1, false, "path of the config file", std::nullopt, ADVANCED_GROUP}},
170-
{cmd::intercept::FLAG_FORCE_PRELOAD, {0, false, "force to use library preload", std::nullopt, ADVANCED_GROUP}},
171-
{cmd::intercept::FLAG_FORCE_WRAPPER, {0, false, "force to use compiler wrappers", std::nullopt, ADVANCED_GROUP}},
172-
{cmd::bear::FLAG_BEAR, {1, false, "path to the bear executable", {cmd::bear::DEFAULT_PATH}, DEVELOPER_GROUP}},
173-
{cmd::intercept::FLAG_LIBRARY, {1, false, "path to the preload library", {cmd::library::DEFAULT_PATH}, DEVELOPER_GROUP}},
174-
{cmd::intercept::FLAG_WRAPPER, {1, false, "path to the wrapper executable", {cmd::wrapper::DEFAULT_PATH}, DEVELOPER_GROUP}},
175-
{cmd::intercept::FLAG_WRAPPER_DIR, {1, false, "path to the wrapper directory", {cmd::wrapper::DEFAULT_DIR_PATH}, DEVELOPER_GROUP}},
176-
{cmd::intercept::FLAG_COMMAND, {-1, true, "command to execute", std::nullopt, std::nullopt}}
172+
{cmd::citnames::FLAG_OUTPUT, {1, false, "path of the result file", {cmd::citnames::DEFAULT_OUTPUT}, std::nullopt}},
173+
{cmd::citnames::FLAG_APPEND, {0, false, "append result to an existing output file", std::nullopt, ADVANCED_GROUP}},
174+
{cmd::citnames::FLAG_CONFIG, {1, false, "path of the config file", std::nullopt, ADVANCED_GROUP}},
175+
{cmd::intercept::FLAG_FORCE_PRELOAD, {0, false, "force to use library preload", std::nullopt, ADVANCED_GROUP}},
176+
{cmd::intercept::FLAG_FORCE_WRAPPER, {0, false, "force to use compiler wrappers", std::nullopt, ADVANCED_GROUP}},
177+
{cmd::intercept::FLAG_ENABLE_NETWORK_PROXY, {0, false, "enable http and https proxy", std::nullopt, ADVANCED_GROUP}},
178+
{cmd::bear::FLAG_BEAR, {1, false, "path to the bear executable", {cmd::bear::DEFAULT_PATH}, DEVELOPER_GROUP}},
179+
{cmd::intercept::FLAG_LIBRARY, {1, false, "path to the preload library", {cmd::library::DEFAULT_PATH}, DEVELOPER_GROUP}},
180+
{cmd::intercept::FLAG_WRAPPER, {1, false, "path to the wrapper executable", {cmd::wrapper::DEFAULT_PATH}, DEVELOPER_GROUP}},
181+
{cmd::intercept::FLAG_WRAPPER_DIR, {1, false, "path to the wrapper directory", {cmd::wrapper::DEFAULT_DIR_PATH}, DEVELOPER_GROUP}},
182+
{cmd::intercept::FLAG_COMMAND, {-1, true, "command to execute", std::nullopt, std::nullopt}}
177183
});
178184
return parser.parse_or_exit(argc, const_cast<const char **>(argv));
179185
}
@@ -186,6 +192,12 @@ namespace bear {
186192
return citnames.subcommand(args, envp);
187193
}
188194
if (auto intercept = ic::Intercept(log_config_); intercept.matches(args)) {
195+
// Network proxy is disabled by default unless user explicitly enables it
196+
if (!args.as_bool(cmd::intercept::FLAG_ENABLE_NETWORK_PROXY).unwrap_or(false)) {
197+
for (auto proxyEnv : cmd::intercept::PROXY_ENV_VARS) {
198+
unsetenv(proxyEnv);
199+
}
200+
}
189201
return intercept.subcommand(args, envp);
190202
}
191203
return rust::Err(std::runtime_error("Invalid subcommand"));

source/config.h.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ namespace cmd {
102102
constexpr char FLAG_COMMAND[] = "--";
103103
constexpr char FLAG_FORCE_WRAPPER[] = "--force-wrapper";
104104
constexpr char FLAG_FORCE_PRELOAD[] = "--force-preload";
105+
constexpr char FLAG_ENABLE_NETWORK_PROXY[] = "--enable-network-proxy";
106+
constexpr const char* PROXY_ENV_VARS[] = {"http_proxy", "https_proxy", "grpc_proxy","all_proxy", "HTTP_PROXY", "HTTPS_PROXY", "GRPC_PROXY", "ALL_PROXY"};
105107

106108
constexpr char DEFAULT_OUTPUT[] = "events.json";
107109
}

source/libflags/source/Flags.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,11 @@ namespace {
110110
// print flag name
111111
os << flag_name;
112112
// decide if the help text goes into the same line or not
113-
if (flag_size > 22) {
113+
if (flag_size > 25) {
114114
os << std::endl
115115
<< std::string(15, ' ');
116116
} else {
117-
os << std::string(23 - flag_size, ' ');
117+
os << std::string(26 - flag_size, ' ');
118118
}
119119
os << option.help;
120120
// print default value if exists

source/libflags/test/FlagsTest.cc

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -177,16 +177,16 @@ namespace {
177177
const char *expected =
178178
"Usage: test [--flag] [--option <arg>] [--options <arg0> <arg1> <arg2>] [--verbose] [-- ...]\n"
179179
"\n"
180-
" --flag a single flag\n"
181-
" --option <arg> a flag with a value\n"
180+
" --flag a single flag\n"
181+
" --option <arg> a flag with a value\n"
182182
" --options <arg0> <arg1> <arg2>\n"
183183
" a flag with 3 values\n"
184-
" --verbose run in verbose mode\n"
185-
" -- ... rest of the arguments\n"
184+
" --verbose run in verbose mode\n"
185+
" -- ... rest of the arguments\n"
186186
"\n"
187187
"query options\n"
188-
" --help print help and exit\n"
189-
" --version print version and exit\n";
188+
" --help print help and exit\n"
189+
" --version print version and exit\n";
190190

191191
std::ostringstream out;
192192
sut.print_help(nullptr, out);
@@ -367,8 +367,8 @@ namespace {
367367
" dump\n"
368368
"\n"
369369
"query options\n"
370-
" --help print help and exit\n"
371-
" --version print version and exit\n";
370+
" --help print help and exit\n"
371+
" --version print version and exit\n";
372372

373373
std::ostringstream out;
374374
sut.print_help(nullptr, out);
@@ -378,11 +378,11 @@ namespace {
378378
const char *expected =
379379
"Usage: test append [--option <arg>] [--verbose]\n"
380380
"\n"
381-
" --option <arg> a flag with a value\n"
382-
" --verbose run in verbose mode\n"
381+
" --option <arg> a flag with a value\n"
382+
" --verbose run in verbose mode\n"
383383
"\n"
384384
"query options\n"
385-
" --help print help and exit\n";
385+
" --help print help and exit\n";
386386

387387
std::ostringstream out;
388388
sut.print_help(&append, out);
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/usr/bin/env sh
2+
3+
# REQUIRES: shell, cc
4+
5+
# If an unreachable or an invalid http proxy is set, an error is returned if '--enable-network-proxy' is set
6+
#
7+
# RUN: env http_proxy=http://localhost:9999 %{intercept} --enable-network-proxy --output %t.json -- %{shell} %s 2> %t.stderr
8+
# RUN: grep "failed to connect to all addresses" %t.stderr
9+
# RUN: assert_intercepted %t.json count -eq 0
10+
11+
# If no http proxy is set, it should run correctly even with '--enable-network-proxy'
12+
#
13+
# RUN: %{intercept} --enable-network-proxy --output %t.json -- %{shell} %s
14+
# RUN: assert_intercepted %t.json count -eq 1
15+
# RUN: assert_intercepted %t.json contains -program %{c_compiler} -arguments %{c_compiler} -c shell_enable_network_proxy.c -o shell_enable_network_proxy.o
16+
17+
# By default, even with an invalid http proxy set, it should run correctly
18+
#
19+
# RUN: env http_proxy=http://localhost:9999 %{intercept} --output %t.json -- %{shell}
20+
# RUN: assert_intercepted %t.json count -eq 1
21+
22+
touch shell_enable_network_proxy.c
23+
24+
$CC -c shell_enable_network_proxy.c -o shell_enable_network_proxy.o
25+

0 commit comments

Comments
 (0)