Skip to content

Commit 6d7eefb

Browse files
committed
Add HTTP proxy support to iotcored
Allows MQTT connections on networks where all outbound communication is gated by a proxy server. Tested by running a deployment to a remote tinyproxy server. Configure the network proxy by writing the following configuration object to services/aws.greengrass.NucleusLite/configuration/networkProxy: networkProxy: { noProxyAddresses: "192.168.1.1,*.example.com:80", proxy: { url: "http://www.myproxy.io:8888" } } These settings are equivalent to setting no_proxy and https_proxy environment variables for OpenSSL
1 parent a0dc02a commit 6d7eefb

File tree

10 files changed

+434
-37
lines changed

10 files changed

+434
-37
lines changed

Diff for: bins/ggdeploymentd/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ ggl_init_module(
1010
ggl-constants
1111
ggl-file
1212
ggl-http
13+
ggl-uri
1314
ggl-json
1415
ggl-proxy-environment
1516
ggl-recipe

Diff for: bins/iotcored/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ ggl_init_module(
1010
core_mqtt
1111
ggl-backoff
1212
ggl-file
13+
ggl-uri
1314
PkgConfig::openssl)

Diff for: bins/iotcored/include/iotcored.h

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ typedef struct {
1414
char *rootca;
1515
char *cert;
1616
char *key;
17+
char *no_proxy;
18+
char *proxy_uri;
1719
} IotcoredArgs;
1820

1921
GglError run_iotcored(IotcoredArgs *args);

Diff for: bins/iotcored/src/entry.c

+90
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,102 @@
88
#include <ggl/buffer.h>
99
#include <ggl/core_bus/gg_config.h>
1010
#include <ggl/error.h>
11+
#include <ggl/log.h>
1112
#include <ggl/object.h>
1213
#include <limits.h>
1314
#include <string.h>
15+
#include <stdbool.h>
1416
#include <stdint.h>
17+
#include <stdlib.h>
1518

1619
#define MAX_ENDPOINT_LEN 128
1720
#define MAX_THINGNAME_LEN 128
1821

22+
static bool get_proxy_variable(GglBufList aliases, GglBuffer *destination) {
23+
for (size_t i = 0; i < aliases.len; ++i) {
24+
char *name = (char *) aliases.bufs[i].data;
25+
if (name == NULL) {
26+
continue;
27+
}
28+
// This is safe as long as getenv is reentrant
29+
// and no other threads call setenv.
30+
// NOLINTNEXTLINE(concurrency-mt-unsafe)
31+
char *value = getenv(name);
32+
if (value == NULL) {
33+
continue;
34+
}
35+
GglBuffer source = ggl_buffer_from_null_term(value);
36+
if (source.len >= destination->len) {
37+
GGL_LOGW("%s too long.", name);
38+
continue;
39+
}
40+
memcpy(destination->data, source.data, source.len);
41+
destination->len = source.len;
42+
destination->data[destination->len] = '\0';
43+
return true;
44+
}
45+
return false;
46+
}
47+
48+
static void set_proxy_args(IotcoredArgs *args) {
49+
static uint8_t proxy_uri_mem[PATH_MAX] = { 0 };
50+
if (args->proxy_uri == NULL) {
51+
GglBuffer proxy_uri = GGL_BUF(proxy_uri_mem);
52+
if (get_proxy_variable(
53+
GGL_BUF_LIST(GGL_STR("https_proxy"), GGL_STR("HTTPS_PROXY")),
54+
&proxy_uri
55+
)) {
56+
args->proxy_uri = (char *) proxy_uri_mem;
57+
}
58+
}
59+
if (args->proxy_uri == NULL) {
60+
GglBuffer proxy_uri = GGL_BUF(proxy_uri_mem);
61+
proxy_uri.len -= 1;
62+
GglError ret = ggl_gg_config_read_str(
63+
GGL_BUF_LIST(
64+
GGL_STR("services"),
65+
GGL_STR("aws.greengrass.NucleusLite"),
66+
GGL_STR("configuration"),
67+
GGL_STR("networkProxy"),
68+
GGL_STR("proxy"),
69+
GGL_STR("url")
70+
),
71+
&proxy_uri
72+
);
73+
if (ret == GGL_ERR_OK) {
74+
args->proxy_uri = (char *) proxy_uri_mem;
75+
}
76+
}
77+
78+
static uint8_t no_proxy_mem[PATH_MAX] = { 0 };
79+
if (args->no_proxy == NULL) {
80+
GglBuffer no_proxy = GGL_BUF(no_proxy_mem);
81+
if (get_proxy_variable(
82+
GGL_BUF_LIST(GGL_STR("no_proxy"), GGL_STR("NO_PROXY")),
83+
&no_proxy
84+
)) {
85+
args->no_proxy = (char *) no_proxy_mem;
86+
}
87+
}
88+
if (args->no_proxy == NULL) {
89+
GglBuffer no_proxy = GGL_BUF(no_proxy_mem);
90+
no_proxy.len -= 1;
91+
GglError ret = ggl_gg_config_read_str(
92+
GGL_BUF_LIST(
93+
GGL_STR("services"),
94+
GGL_STR("aws.greengrass.NucleusLite"),
95+
GGL_STR("configuration"),
96+
GGL_STR("networkProxy"),
97+
GGL_STR("noproxy"),
98+
),
99+
&no_proxy
100+
);
101+
if (ret == GGL_ERR_OK) {
102+
args->no_proxy = (char *) no_proxy_mem;
103+
}
104+
}
105+
}
106+
19107
GglError run_iotcored(IotcoredArgs *args) {
20108
if (args->cert == NULL) {
21109
static uint8_t cert_mem[PATH_MAX] = { 0 };
@@ -94,6 +182,8 @@ GglError run_iotcored(IotcoredArgs *args) {
94182
args->rootca = (char *) rootca_mem;
95183
}
96184

185+
set_proxy_args(args);
186+
97187
GglError ret = iotcored_mqtt_connect(args);
98188
if (ret != GGL_ERR_OK) {
99189
return ret;

0 commit comments

Comments
 (0)