combine patches to "1001-cloud-setup-IMDSv2-rh2151987.patch"

It's confusing enough to keep track of which patches are where.
Combine the patches that are related in a single file.

Also, don't do

   # Bugfixes that are only relevant until next rebase of the package.
   # Patch1001: 1001-some.patch
   Patch11: 0001-cloud-setup-use-nm_strv_dup_packed-in-nm_http_client.patch

Related: #2151987
This commit is contained in:
Thomas Haller 2023-03-23 07:15:24 +01:00
parent 1da3f15a5a
commit 78a7cae283
No known key found for this signature in database
GPG Key ID: 29C2366E4DFC5728
7 changed files with 659 additions and 664 deletions

View File

@ -1,47 +0,0 @@
From 89a6ce575d52bbaa1b928275c39517a071449da7 Mon Sep 17 00:00:00 2001
From: Thomas Haller <thaller@redhat.com>
Date: Mon, 27 Feb 2023 09:14:10 +0100
Subject: [PATCH 1/6] cloud-setup: use nm_strv_dup_packed() in
nm_http_client_poll_get()
No need to do a deep clone. The strv array is not ever modified and we
pack it together in one memory allocation.
(cherry picked from commit 599fe234ea4864396eb70530513b2646aa97f576)
(cherry picked from commit 3787eacac9c1fc9ff9b423f9d9cea9907e209ebb)
---
src/nm-cloud-setup/nm-http-client.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/nm-cloud-setup/nm-http-client.c b/src/nm-cloud-setup/nm-http-client.c
index a0964e2165..98ede1e403 100644
--- a/src/nm-cloud-setup/nm-http-client.c
+++ b/src/nm-cloud-setup/nm-http-client.c
@@ -419,7 +419,7 @@ _poll_get_data_free(gpointer data)
g_free(poll_get_data->uri);
nm_clear_pointer(&poll_get_data->response_data, g_bytes_unref);
- g_strfreev((char **) poll_get_data->http_headers);
+ g_free((gpointer) poll_get_data->http_headers);
nm_g_slice_free(poll_get_data);
}
@@ -552,9 +552,14 @@ nm_http_client_poll_get(NMHttpClient *self,
.check_fcn = check_fcn,
.check_user_data = check_user_data,
.response_code = -1,
- .http_headers = NM_CAST_STRV_CC(g_strdupv((char **) http_headers)),
+ .http_headers = NULL,
};
+ if (http_headers) {
+ poll_get_data->http_headers =
+ nm_strv_dup_packed(http_headers, -1) ?: g_new(const char *, 1);
+ }
+
nmcs_wait_for_objects_register(poll_get_data->task);
g_task_set_task_data(poll_get_data->task, poll_get_data, _poll_get_data_free);
--
2.39.2

View File

@ -1,65 +0,0 @@
From 36d417af60a2a09863e00cae869899883265ee8c Mon Sep 17 00:00:00 2001
From: Lubomir Rintel <lkundrak@v3.sk>
Date: Mon, 27 Feb 2023 00:09:13 +0100
Subject: [PATCH 2/6] cloud_setup: unexport nm_http_client_get()
It's not used anywhere.
(cherry picked from commit ce225b2c06089adc402277f2b80afacb9da8cc5f)
(cherry picked from commit 23b9514080c0c578ec5a8e023081837240f41896)
---
src/nm-cloud-setup/nm-http-client.c | 4 ++--
src/nm-cloud-setup/nm-http-client.h | 15 ---------------
2 files changed, 2 insertions(+), 17 deletions(-)
diff --git a/src/nm-cloud-setup/nm-http-client.c b/src/nm-cloud-setup/nm-http-client.c
index 98ede1e403..e6cc20fa75 100644
--- a/src/nm-cloud-setup/nm-http-client.c
+++ b/src/nm-cloud-setup/nm-http-client.c
@@ -256,7 +256,7 @@ _get_cancelled_cb(GObject *object, gpointer user_data)
_ehandle_complete(edata, error);
}
-void
+static void
nm_http_client_get(NMHttpClient *self,
const char *url,
int timeout_msec,
@@ -366,7 +366,7 @@ nm_http_client_get(NMHttpClient *self,
*
* Returns: %TRUE on success or %FALSE with an error code.
*/
-gboolean
+static gboolean
nm_http_client_get_finish(NMHttpClient *self,
GAsyncResult *result,
long *out_response_code,
diff --git a/src/nm-cloud-setup/nm-http-client.h b/src/nm-cloud-setup/nm-http-client.h
index 0a7052ae25..6cc08ba97c 100644
--- a/src/nm-cloud-setup/nm-http-client.h
+++ b/src/nm-cloud-setup/nm-http-client.h
@@ -27,21 +27,6 @@ GMainContext *nm_http_client_get_main_context(NMHttpClient *self);
/*****************************************************************************/
-void nm_http_client_get(NMHttpClient *self,
- const char *uri,
- int timeout_msec,
- gssize max_data,
- const char *const *http_headers,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
-gboolean nm_http_client_get_finish(NMHttpClient *self,
- GAsyncResult *result,
- long *out_response_code,
- GBytes **out_response_data,
- GError **error);
-
typedef gboolean (*NMHttpClientPollGetCheckFcn)(long response_code,
GBytes *response_data,
gpointer check_user_data,
--
2.39.2

View File

@ -1,280 +0,0 @@
From aaf66e9174eb04d2df1f45530ebdca16e77a6ec5 Mon Sep 17 00:00:00 2001
From: Lubomir Rintel <lkundrak@v3.sk>
Date: Mon, 27 Feb 2023 00:13:31 +0100
Subject: [PATCH 4/6] cloud-setup: make nm_http_client_req() accept a method
argument
We'll need to be able to issue PUT calls.
(cherry picked from commit cd74d75002783a79d1a4fca24b2fbe99ced933a8)
(cherry picked from commit eff4372045290ad380bddf03e5075ab671a7cff6)
---
src/nm-cloud-setup/nm-http-client.c | 7 +++++++
src/nm-cloud-setup/nm-http-client.h | 1 +
src/nm-cloud-setup/nmcs-provider-aliyun.c | 7 +++++++
src/nm-cloud-setup/nmcs-provider-azure.c | 7 +++++++
src/nm-cloud-setup/nmcs-provider-ec2.c | 4 ++++
src/nm-cloud-setup/nmcs-provider-gcp.c | 5 +++++
6 files changed, 31 insertions(+)
diff --git a/src/nm-cloud-setup/nm-http-client.c b/src/nm-cloud-setup/nm-http-client.c
index ed7914df8f..b3db93e058 100644
--- a/src/nm-cloud-setup/nm-http-client.c
+++ b/src/nm-cloud-setup/nm-http-client.c
@@ -262,6 +262,7 @@ nm_http_client_req(NMHttpClient *self,
int timeout_msec,
gssize max_data,
const char *const *http_headers,
+ const char *http_method,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
@@ -328,6 +329,9 @@ nm_http_client_req(NMHttpClient *self,
curl_easy_setopt(edata->ehandle, CURLOPT_HTTPHEADER, edata->headers);
}
+ if (http_method)
+ curl_easy_setopt(edata->ehandle, CURLOPT_CUSTOMREQUEST, http_method);
+
if (timeout_msec > 0) {
edata->timeout_source = _source_attach(self,
nm_g_timeout_source_new(timeout_msec,
@@ -403,6 +407,7 @@ typedef struct {
GTask *task;
char *uri;
const char *const *http_headers;
+ const char *http_method;
NMHttpClientPollReqCheckFcn check_fcn;
gpointer check_user_data;
GBytes *response_data;
@@ -440,6 +445,7 @@ _poll_req_probe_start_fcn(GCancellable *cancellable,
poll_req_data->request_timeout_ms,
poll_req_data->request_max_data,
poll_req_data->http_headers,
+ poll_req_data->http_method,
cancellable,
callback,
user_data);
@@ -526,6 +532,7 @@ nm_http_client_poll_req(NMHttpClient *self,
int poll_timeout_ms,
int ratelimit_timeout_ms,
const char *const *http_headers,
+ const char *http_method,
GCancellable *cancellable,
NMHttpClientPollReqCheckFcn check_fcn,
gpointer check_user_data,
diff --git a/src/nm-cloud-setup/nm-http-client.h b/src/nm-cloud-setup/nm-http-client.h
index c8d3ffb458..641efb1f47 100644
--- a/src/nm-cloud-setup/nm-http-client.h
+++ b/src/nm-cloud-setup/nm-http-client.h
@@ -39,6 +39,7 @@ void nm_http_client_poll_req(NMHttpClient *self,
int poll_timeout_ms,
int ratelimit_timeout_ms,
const char *const *http_headers,
+ const char *http_method,
GCancellable *cancellable,
NMHttpClientPollReqCheckFcn check_fcn,
gpointer check_user_data,
diff --git a/src/nm-cloud-setup/nmcs-provider-aliyun.c b/src/nm-cloud-setup/nmcs-provider-aliyun.c
index 93f26e7505..0500922058 100644
--- a/src/nm-cloud-setup/nmcs-provider-aliyun.c
+++ b/src/nm-cloud-setup/nmcs-provider-aliyun.c
@@ -111,6 +111,7 @@ detect(NMCSProvider *provider, GTask *task)
7000,
1000,
NULL,
+ NULL,
g_task_get_cancellable(task),
NULL,
NULL,
@@ -372,6 +373,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us
10000,
1000,
NULL,
+ NULL,
get_config_data->intern_cancellable,
NULL,
NULL,
@@ -389,6 +391,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us
10000,
1000,
NULL,
+ NULL,
get_config_data->intern_cancellable,
NULL,
NULL,
@@ -406,6 +409,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us
10000,
1000,
NULL,
+ NULL,
get_config_data->intern_cancellable,
NULL,
NULL,
@@ -423,6 +427,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us
10000,
1000,
NULL,
+ NULL,
get_config_data->intern_cancellable,
NULL,
NULL,
@@ -440,6 +445,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us
10000,
1000,
NULL,
+ NULL,
get_config_data->intern_cancellable,
NULL,
NULL,
@@ -537,6 +543,7 @@ get_config(NMCSProvider *provider, NMCSProviderGetConfigTaskData *get_config_dat
15000,
1000,
NULL,
+ NULL,
get_config_data->intern_cancellable,
_get_config_metadata_ready_check,
get_config_data,
diff --git a/src/nm-cloud-setup/nmcs-provider-azure.c b/src/nm-cloud-setup/nmcs-provider-azure.c
index b1f48f5c18..e74d042026 100644
--- a/src/nm-cloud-setup/nmcs-provider-azure.c
+++ b/src/nm-cloud-setup/nmcs-provider-azure.c
@@ -76,6 +76,7 @@ detect(NMCSProvider *provider, GTask *task)
7000,
1000,
NM_MAKE_STRV(NM_AZURE_METADATA_HEADER),
+ NULL,
g_task_get_cancellable(task),
NULL,
NULL,
@@ -294,6 +295,7 @@ _get_config_ips_prefix_list_cb(GObject *source, GAsyncResult *result, gpointer u
10000,
1000,
NM_MAKE_STRV(NM_AZURE_METADATA_HEADER),
+ NULL,
get_config_data->intern_cancellable,
NULL,
NULL,
@@ -316,6 +318,7 @@ _get_config_ips_prefix_list_cb(GObject *source, GAsyncResult *result, gpointer u
10000,
1000,
NM_MAKE_STRV(NM_AZURE_METADATA_HEADER),
+ NULL,
get_config_data->intern_cancellable,
NULL,
NULL,
@@ -333,6 +336,7 @@ _get_config_ips_prefix_list_cb(GObject *source, GAsyncResult *result, gpointer u
10000,
1000,
NM_MAKE_STRV(NM_AZURE_METADATA_HEADER),
+ NULL,
get_config_data->intern_cancellable,
NULL,
NULL,
@@ -415,6 +419,7 @@ _get_config_iface_cb(GObject *source, GAsyncResult *result, gpointer user_data)
10000,
1000,
NM_MAKE_STRV(NM_AZURE_METADATA_HEADER),
+ NULL,
get_config_data->intern_cancellable,
NULL,
NULL,
@@ -515,6 +520,7 @@ _get_net_ifaces_list_cb(GObject *source, GAsyncResult *result, gpointer user_dat
10000,
1000,
NM_MAKE_STRV(NM_AZURE_METADATA_HEADER),
+ NULL,
get_config_data->intern_cancellable,
NULL,
NULL,
@@ -538,6 +544,7 @@ get_config(NMCSProvider *provider, NMCSProviderGetConfigTaskData *get_config_dat
15000,
1000,
NM_MAKE_STRV(NM_AZURE_METADATA_HEADER),
+ NULL,
get_config_data->intern_cancellable,
NULL,
NULL,
diff --git a/src/nm-cloud-setup/nmcs-provider-ec2.c b/src/nm-cloud-setup/nmcs-provider-ec2.c
index 35f7176c4d..c3c527cfd4 100644
--- a/src/nm-cloud-setup/nmcs-provider-ec2.c
+++ b/src/nm-cloud-setup/nmcs-provider-ec2.c
@@ -106,6 +106,7 @@ detect(NMCSProvider *provider, GTask *task)
7000,
1000,
NULL,
+ NULL,
g_task_get_cancellable(task),
_detect_get_meta_data_check_cb,
NULL,
@@ -264,6 +265,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us
10000,
1000,
NULL,
+ NULL,
get_config_data->intern_cancellable,
NULL,
NULL,
@@ -281,6 +283,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us
10000,
1000,
NULL,
+ NULL,
get_config_data->intern_cancellable,
NULL,
NULL,
@@ -378,6 +381,7 @@ get_config(NMCSProvider *provider, NMCSProviderGetConfigTaskData *get_config_dat
15000,
1000,
NULL,
+ NULL,
get_config_data->intern_cancellable,
_get_config_metadata_ready_check,
get_config_data,
diff --git a/src/nm-cloud-setup/nmcs-provider-gcp.c b/src/nm-cloud-setup/nmcs-provider-gcp.c
index 571c0fb826..ca354865dd 100644
--- a/src/nm-cloud-setup/nmcs-provider-gcp.c
+++ b/src/nm-cloud-setup/nmcs-provider-gcp.c
@@ -79,6 +79,7 @@ detect(NMCSProvider *provider, GTask *task)
7000,
1000,
NM_MAKE_STRV(NM_GCP_METADATA_HEADER),
+ NULL,
g_task_get_cancellable(task),
NULL,
NULL,
@@ -227,6 +228,7 @@ _get_config_ips_list_cb(GObject *source, GAsyncResult *result, gpointer user_dat
HTTP_POLL_TIMEOUT_MS,
HTTP_RATE_LIMIT_MS,
NM_MAKE_STRV(NM_GCP_METADATA_HEADER),
+ NULL,
get_config_data->intern_cancellable,
NULL,
NULL,
@@ -313,6 +315,7 @@ _get_config_iface_cb(GObject *source, GAsyncResult *result, gpointer user_data)
HTTP_POLL_TIMEOUT_MS,
HTTP_RATE_LIMIT_MS,
NM_MAKE_STRV(NM_GCP_METADATA_HEADER),
+ NULL,
get_config_data->intern_cancellable,
NULL,
NULL,
@@ -412,6 +415,7 @@ _get_net_ifaces_list_cb(GObject *source, GAsyncResult *result, gpointer user_dat
HTTP_POLL_TIMEOUT_MS,
HTTP_RATE_LIMIT_MS,
NM_MAKE_STRV(NM_GCP_METADATA_HEADER),
+ NULL,
get_config_data->intern_cancellable,
NULL,
NULL,
@@ -435,6 +439,7 @@ get_config(NMCSProvider *provider, NMCSProviderGetConfigTaskData *get_config_dat
HTTP_POLL_TIMEOUT_MS,
HTTP_RATE_LIMIT_MS,
NM_MAKE_STRV(NM_GCP_METADATA_HEADER),
+ NULL,
get_config_data->intern_cancellable,
NULL,
NULL,
--
2.39.2

View File

@ -1,60 +0,0 @@
From 06fc0ef35dc7e5e6295ab9beecba6071e556d55e Mon Sep 17 00:00:00 2001
From: Lubomir Rintel <lkundrak@v3.sk>
Date: Tue, 7 Mar 2023 13:51:57 +0100
Subject: [PATCH 5/6] cloud-setup: document detect() and get_config() methods
Clarify that detect() needs to succeed before get_config().
I thought it's sort of common sense, but it's better to be explicit as
we're going to rely on that.
(cherry picked from commit 088bfd817ab5eb8aa0fb9cffe52fa3f456030ecc)
(cherry picked from commit d99864ccba6d7c9bac66dcbbcc49c01be0ddd719)
---
src/nm-cloud-setup/nmcs-provider.h | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/src/nm-cloud-setup/nmcs-provider.h b/src/nm-cloud-setup/nmcs-provider.h
index 502f1d0323..3662fbe391 100644
--- a/src/nm-cloud-setup/nmcs-provider.h
+++ b/src/nm-cloud-setup/nmcs-provider.h
@@ -152,8 +152,36 @@ typedef struct {
const char *_name;
const char *_env_provider_enabled;
+ /**
+ * detect:
+ * @self: the #NMCSProvider
+ * @task: a #GTask that's completed when the detection finishes.
+ *
+ * Checks whether the metadata of a particular cloud provider is
+ * accessible on the host machine. The check runs asynchronously.
+ *
+ * When the check finishes, @task is completed. If the check was
+ * successful, @task returns a gboolean of %TRUE. Otherwise
+ * a %FALSE value or an error is returned.
+ *
+ * The routine has to be called before the get_config() can be
+ * used.
+ */
void (*detect)(NMCSProvider *self, GTask *task);
+ /**
+ * get_config:
+ * @self: the #NMCSProvider
+ * @get_config_data: encapsulates a #GTask and network configuration data
+ *
+ * Collects the network configuration from metadata service of a
+ * particular cloud provider. The metadata is traversed and checked
+ * asynchronously, completing a task encapsulated in @get_config_data
+ * upon finishing.
+ *
+ * Call to detect() with a successful result is necessary before
+ * using this routine.
+ */
void (*get_config)(NMCSProvider *self, NMCSProviderGetConfigTaskData *get_config_data);
} NMCSProviderClass;
--
2.39.2

View File

@ -1,206 +0,0 @@
From e3ac982b32361105708d489a73eaed2bc4dc5f9f Mon Sep 17 00:00:00 2001
From: Lubomir Rintel <lkundrak@v3.sk>
Date: Mon, 27 Feb 2023 00:15:11 +0100
Subject: [PATCH 6/6] cloud-setup/ec2: start with requesting a IMDSv2 token
The present version of the EC2 metadata API (IMDSv2) requires a header
with a token to be present in all requests. The token is essentially a
cookie that's not actually a cookie that's obtained with a PUT call that
doesn't put anything. Apparently it's too easy to trick someone into
calling a GET method.
EC2 now supports IMDSv2 everywhere with IMDSv1 being optional, so let's
just use IMDSv2 unconditionally. Also, the presence of a token API can
be used to detect the AWS EC2 cloud.
https://bugzilla.redhat.com/show_bug.cgi?id=2151986
(cherry picked from commit 8b7e12c2d631c47292258c29429cd565715ea186)
(cherry picked from commit 429f36cd81ddbe337f04c09a352fd78cd29e394d)
---
src/nm-cloud-setup/nmcs-provider-ec2.c | 74 +++++++++++++++++++-------
1 file changed, 54 insertions(+), 20 deletions(-)
diff --git a/src/nm-cloud-setup/nmcs-provider-ec2.c b/src/nm-cloud-setup/nmcs-provider-ec2.c
index c3c527cfd4..3a27a30e68 100644
--- a/src/nm-cloud-setup/nmcs-provider-ec2.c
+++ b/src/nm-cloud-setup/nmcs-provider-ec2.c
@@ -16,6 +16,11 @@
#define NM_EC2_METADATA_URL_BASE /* $NM_EC2_BASE/$NM_EC2_API_VERSION */ \
"/meta-data/network/interfaces/macs/"
+/* Token TTL of 180 seconds is chosen abitrarily, in hope that it is
+ * surely more than enough to read all relevant metadata. */
+#define NM_EC2_TOKEN_TTL_HEADER "X-aws-ec2-metadata-token-ttl-seconds: 180"
+#define NM_EC2_TOKEN_HEADER "X-aws-ec2-metadata-token: "
+
static const char *
_ec2_base(void)
{
@@ -44,8 +49,15 @@ again:
/*****************************************************************************/
+enum {
+ NM_EC2_HTTP_HEADER_TOKEN,
+ NM_EC2_HTTP_HEADER_SENTINEL,
+ _NM_EC2_HTTP_HEADER_NUM,
+};
+
struct _NMCSProviderEC2 {
NMCSProvider parent;
+ char *token;
};
struct _NMCSProviderEC2Class {
@@ -56,23 +68,18 @@ G_DEFINE_TYPE(NMCSProviderEC2, nmcs_provider_ec2, NMCS_TYPE_PROVIDER);
/*****************************************************************************/
-static gboolean
-_detect_get_meta_data_check_cb(long response_code,
- GBytes *response,
- gpointer check_user_data,
- GError **error)
-{
- return response_code == 200 && nmcs_utils_parse_get_full_line(response, "ami-id");
-}
-
static void
-_detect_get_meta_data_done_cb(GObject *source, GAsyncResult *result, gpointer user_data)
+_detect_get_token_done_cb(GObject *source, GAsyncResult *result, gpointer user_data)
{
gs_unref_object GTask *task = user_data;
+ NMCSProviderEC2 *self = NMCS_PROVIDER_EC2(g_task_get_source_object(task));
+ gs_unref_bytes GBytes *response = NULL;
gs_free_error GError *get_error = NULL;
gs_free_error GError *error = NULL;
- nm_http_client_poll_req_finish(NM_HTTP_CLIENT(source), result, NULL, NULL, &get_error);
+ nm_clear_g_free(&self->token);
+
+ nm_http_client_poll_req_finish(NM_HTTP_CLIENT(source), result, NULL, &response, &get_error);
if (nm_utils_error_is_cancelled(get_error)) {
g_task_return_error(task, g_steal_pointer(&get_error));
@@ -88,6 +95,12 @@ _detect_get_meta_data_done_cb(GObject *source, GAsyncResult *result, gpointer us
return;
}
+ /* We use the token as-is. Special characters can cause confusion (e.g.
+ * response splitting), but we're not crossing a security boundary.
+ * None of the examples in AWS documentation does any sort of
+ * sanitization either. */
+ self->token = g_strconcat(NM_EC2_TOKEN_HEADER, g_bytes_get_data(response, NULL), NULL);
+
g_task_return_boolean(task, TRUE);
}
@@ -100,17 +113,17 @@ detect(NMCSProvider *provider, GTask *task)
http_client = nmcs_provider_get_http_client(provider);
nm_http_client_poll_req(http_client,
- (uri = _ec2_uri_concat("latest/meta-data/")),
+ (uri = _ec2_uri_concat("latest/api/token")),
HTTP_TIMEOUT_MS,
256 * 1024,
7000,
1000,
- NULL,
- NULL,
+ NM_MAKE_STRV(NM_EC2_TOKEN_TTL_HEADER),
+ "PUT",
g_task_get_cancellable(task),
- _detect_get_meta_data_check_cb,
NULL,
- _detect_get_meta_data_done_cb,
+ NULL,
+ _detect_get_token_done_cb,
task);
}
@@ -198,6 +211,7 @@ static void
_get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer user_data)
{
NMCSProviderGetConfigTaskData *get_config_data;
+ NMCSProviderEC2 *self;
gs_unref_hashtable GHashTable *response_parsed = NULL;
gs_free_error GError *error = NULL;
GetConfigMetadataMac *v_mac_data;
@@ -211,6 +225,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us
return;
get_config_data = user_data;
+ self = NMCS_PROVIDER_EC2(get_config_data->self);
response_parsed = g_steal_pointer(&get_config_data->extra_data);
get_config_data->extra_data_destroy = NULL;
@@ -264,7 +279,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us
512 * 1024,
10000,
1000,
- NULL,
+ NM_MAKE_STRV(self->token),
NULL,
get_config_data->intern_cancellable,
NULL,
@@ -282,7 +297,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us
512 * 1024,
10000,
1000,
- NULL,
+ NM_MAKE_STRV(self->token),
NULL,
get_config_data->intern_cancellable,
NULL,
@@ -368,7 +383,13 @@ _get_config_metadata_ready_check(long response_code,
static void
get_config(NMCSProvider *provider, NMCSProviderGetConfigTaskData *get_config_data)
{
- gs_free char *uri = NULL;
+ NMCSProviderEC2 *self = NMCS_PROVIDER_EC2(provider);
+ gs_free char *uri = NULL;
+
+ /* This can be called only if detect() succeeded, which implies
+ * there must be a token.
+ */
+ nm_assert(self->token);
/* First we fetch the "macs/". If the caller requested some particular
* MAC addresses, then we poll until we see them. They might not yet be
@@ -380,7 +401,7 @@ get_config(NMCSProvider *provider, NMCSProviderGetConfigTaskData *get_config_dat
256 * 1024,
15000,
1000,
- NULL,
+ NM_MAKE_STRV(self->token),
NULL,
get_config_data->intern_cancellable,
_get_config_metadata_ready_check,
@@ -395,11 +416,24 @@ static void
nmcs_provider_ec2_init(NMCSProviderEC2 *self)
{}
+static void
+dispose(GObject *object)
+{
+ NMCSProviderEC2 *self = NMCS_PROVIDER_EC2(object);
+
+ nm_clear_g_free(&self->token);
+
+ G_OBJECT_CLASS(nmcs_provider_ec2_parent_class)->dispose(object);
+}
+
static void
nmcs_provider_ec2_class_init(NMCSProviderEC2Class *klass)
{
+ GObjectClass *object_class = G_OBJECT_CLASS(klass);
NMCSProviderClass *provider_class = NMCS_PROVIDER_CLASS(klass);
+ object_class->dispose = dispose;
+
provider_class->_name = "ec2";
provider_class->_env_provider_enabled = NMCS_ENV_VARIABLE("NM_CLOUD_SETUP_EC2");
provider_class->detect = detect;
--
2.39.2

View File

@ -1,3 +1,115 @@
From 89a6ce575d52bbaa1b928275c39517a071449da7 Mon Sep 17 00:00:00 2001
From: Thomas Haller <thaller@redhat.com>
Date: Mon, 27 Feb 2023 09:14:10 +0100
Subject: [PATCH 1/6] cloud-setup: use nm_strv_dup_packed() in
nm_http_client_poll_get()
No need to do a deep clone. The strv array is not ever modified and we
pack it together in one memory allocation.
(cherry picked from commit 599fe234ea4864396eb70530513b2646aa97f576)
(cherry picked from commit 3787eacac9c1fc9ff9b423f9d9cea9907e209ebb)
---
src/nm-cloud-setup/nm-http-client.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/nm-cloud-setup/nm-http-client.c b/src/nm-cloud-setup/nm-http-client.c
index a0964e2165..98ede1e403 100644
--- a/src/nm-cloud-setup/nm-http-client.c
+++ b/src/nm-cloud-setup/nm-http-client.c
@@ -419,7 +419,7 @@ _poll_get_data_free(gpointer data)
g_free(poll_get_data->uri);
nm_clear_pointer(&poll_get_data->response_data, g_bytes_unref);
- g_strfreev((char **) poll_get_data->http_headers);
+ g_free((gpointer) poll_get_data->http_headers);
nm_g_slice_free(poll_get_data);
}
@@ -552,9 +552,14 @@ nm_http_client_poll_get(NMHttpClient *self,
.check_fcn = check_fcn,
.check_user_data = check_user_data,
.response_code = -1,
- .http_headers = NM_CAST_STRV_CC(g_strdupv((char **) http_headers)),
+ .http_headers = NULL,
};
+ if (http_headers) {
+ poll_get_data->http_headers =
+ nm_strv_dup_packed(http_headers, -1) ?: g_new(const char *, 1);
+ }
+
nmcs_wait_for_objects_register(poll_get_data->task);
g_task_set_task_data(poll_get_data->task, poll_get_data, _poll_get_data_free);
--
2.39.2
From 36d417af60a2a09863e00cae869899883265ee8c Mon Sep 17 00:00:00 2001
From: Lubomir Rintel <lkundrak@v3.sk>
Date: Mon, 27 Feb 2023 00:09:13 +0100
Subject: [PATCH 2/6] cloud_setup: unexport nm_http_client_get()
It's not used anywhere.
(cherry picked from commit ce225b2c06089adc402277f2b80afacb9da8cc5f)
(cherry picked from commit 23b9514080c0c578ec5a8e023081837240f41896)
---
src/nm-cloud-setup/nm-http-client.c | 4 ++--
src/nm-cloud-setup/nm-http-client.h | 15 ---------------
2 files changed, 2 insertions(+), 17 deletions(-)
diff --git a/src/nm-cloud-setup/nm-http-client.c b/src/nm-cloud-setup/nm-http-client.c
index 98ede1e403..e6cc20fa75 100644
--- a/src/nm-cloud-setup/nm-http-client.c
+++ b/src/nm-cloud-setup/nm-http-client.c
@@ -256,7 +256,7 @@ _get_cancelled_cb(GObject *object, gpointer user_data)
_ehandle_complete(edata, error);
}
-void
+static void
nm_http_client_get(NMHttpClient *self,
const char *url,
int timeout_msec,
@@ -366,7 +366,7 @@ nm_http_client_get(NMHttpClient *self,
*
* Returns: %TRUE on success or %FALSE with an error code.
*/
-gboolean
+static gboolean
nm_http_client_get_finish(NMHttpClient *self,
GAsyncResult *result,
long *out_response_code,
diff --git a/src/nm-cloud-setup/nm-http-client.h b/src/nm-cloud-setup/nm-http-client.h
index 0a7052ae25..6cc08ba97c 100644
--- a/src/nm-cloud-setup/nm-http-client.h
+++ b/src/nm-cloud-setup/nm-http-client.h
@@ -27,21 +27,6 @@ GMainContext *nm_http_client_get_main_context(NMHttpClient *self);
/*****************************************************************************/
-void nm_http_client_get(NMHttpClient *self,
- const char *uri,
- int timeout_msec,
- gssize max_data,
- const char *const *http_headers,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
-gboolean nm_http_client_get_finish(NMHttpClient *self,
- GAsyncResult *result,
- long *out_response_code,
- GBytes **out_response_data,
- GError **error);
-
typedef gboolean (*NMHttpClientPollGetCheckFcn)(long response_code,
GBytes *response_data,
gpointer check_user_data,
--
2.39.2
From 20cd11ee4974bb1690d523d5700492ad9c618688 Mon Sep 17 00:00:00 2001
From: Lubomir Rintel <lkundrak@v3.sk>
Date: Mon, 27 Feb 2023 00:09:40 +0100
@ -776,3 +888,549 @@ index a325f31a17..571c0fb826 100644
--
2.39.2
From aaf66e9174eb04d2df1f45530ebdca16e77a6ec5 Mon Sep 17 00:00:00 2001
From: Lubomir Rintel <lkundrak@v3.sk>
Date: Mon, 27 Feb 2023 00:13:31 +0100
Subject: [PATCH 4/6] cloud-setup: make nm_http_client_req() accept a method
argument
We'll need to be able to issue PUT calls.
(cherry picked from commit cd74d75002783a79d1a4fca24b2fbe99ced933a8)
(cherry picked from commit eff4372045290ad380bddf03e5075ab671a7cff6)
---
src/nm-cloud-setup/nm-http-client.c | 7 +++++++
src/nm-cloud-setup/nm-http-client.h | 1 +
src/nm-cloud-setup/nmcs-provider-aliyun.c | 7 +++++++
src/nm-cloud-setup/nmcs-provider-azure.c | 7 +++++++
src/nm-cloud-setup/nmcs-provider-ec2.c | 4 ++++
src/nm-cloud-setup/nmcs-provider-gcp.c | 5 +++++
6 files changed, 31 insertions(+)
diff --git a/src/nm-cloud-setup/nm-http-client.c b/src/nm-cloud-setup/nm-http-client.c
index ed7914df8f..b3db93e058 100644
--- a/src/nm-cloud-setup/nm-http-client.c
+++ b/src/nm-cloud-setup/nm-http-client.c
@@ -262,6 +262,7 @@ nm_http_client_req(NMHttpClient *self,
int timeout_msec,
gssize max_data,
const char *const *http_headers,
+ const char *http_method,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
@@ -328,6 +329,9 @@ nm_http_client_req(NMHttpClient *self,
curl_easy_setopt(edata->ehandle, CURLOPT_HTTPHEADER, edata->headers);
}
+ if (http_method)
+ curl_easy_setopt(edata->ehandle, CURLOPT_CUSTOMREQUEST, http_method);
+
if (timeout_msec > 0) {
edata->timeout_source = _source_attach(self,
nm_g_timeout_source_new(timeout_msec,
@@ -403,6 +407,7 @@ typedef struct {
GTask *task;
char *uri;
const char *const *http_headers;
+ const char *http_method;
NMHttpClientPollReqCheckFcn check_fcn;
gpointer check_user_data;
GBytes *response_data;
@@ -440,6 +445,7 @@ _poll_req_probe_start_fcn(GCancellable *cancellable,
poll_req_data->request_timeout_ms,
poll_req_data->request_max_data,
poll_req_data->http_headers,
+ poll_req_data->http_method,
cancellable,
callback,
user_data);
@@ -526,6 +532,7 @@ nm_http_client_poll_req(NMHttpClient *self,
int poll_timeout_ms,
int ratelimit_timeout_ms,
const char *const *http_headers,
+ const char *http_method,
GCancellable *cancellable,
NMHttpClientPollReqCheckFcn check_fcn,
gpointer check_user_data,
diff --git a/src/nm-cloud-setup/nm-http-client.h b/src/nm-cloud-setup/nm-http-client.h
index c8d3ffb458..641efb1f47 100644
--- a/src/nm-cloud-setup/nm-http-client.h
+++ b/src/nm-cloud-setup/nm-http-client.h
@@ -39,6 +39,7 @@ void nm_http_client_poll_req(NMHttpClient *self,
int poll_timeout_ms,
int ratelimit_timeout_ms,
const char *const *http_headers,
+ const char *http_method,
GCancellable *cancellable,
NMHttpClientPollReqCheckFcn check_fcn,
gpointer check_user_data,
diff --git a/src/nm-cloud-setup/nmcs-provider-aliyun.c b/src/nm-cloud-setup/nmcs-provider-aliyun.c
index 93f26e7505..0500922058 100644
--- a/src/nm-cloud-setup/nmcs-provider-aliyun.c
+++ b/src/nm-cloud-setup/nmcs-provider-aliyun.c
@@ -111,6 +111,7 @@ detect(NMCSProvider *provider, GTask *task)
7000,
1000,
NULL,
+ NULL,
g_task_get_cancellable(task),
NULL,
NULL,
@@ -372,6 +373,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us
10000,
1000,
NULL,
+ NULL,
get_config_data->intern_cancellable,
NULL,
NULL,
@@ -389,6 +391,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us
10000,
1000,
NULL,
+ NULL,
get_config_data->intern_cancellable,
NULL,
NULL,
@@ -406,6 +409,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us
10000,
1000,
NULL,
+ NULL,
get_config_data->intern_cancellable,
NULL,
NULL,
@@ -423,6 +427,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us
10000,
1000,
NULL,
+ NULL,
get_config_data->intern_cancellable,
NULL,
NULL,
@@ -440,6 +445,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us
10000,
1000,
NULL,
+ NULL,
get_config_data->intern_cancellable,
NULL,
NULL,
@@ -537,6 +543,7 @@ get_config(NMCSProvider *provider, NMCSProviderGetConfigTaskData *get_config_dat
15000,
1000,
NULL,
+ NULL,
get_config_data->intern_cancellable,
_get_config_metadata_ready_check,
get_config_data,
diff --git a/src/nm-cloud-setup/nmcs-provider-azure.c b/src/nm-cloud-setup/nmcs-provider-azure.c
index b1f48f5c18..e74d042026 100644
--- a/src/nm-cloud-setup/nmcs-provider-azure.c
+++ b/src/nm-cloud-setup/nmcs-provider-azure.c
@@ -76,6 +76,7 @@ detect(NMCSProvider *provider, GTask *task)
7000,
1000,
NM_MAKE_STRV(NM_AZURE_METADATA_HEADER),
+ NULL,
g_task_get_cancellable(task),
NULL,
NULL,
@@ -294,6 +295,7 @@ _get_config_ips_prefix_list_cb(GObject *source, GAsyncResult *result, gpointer u
10000,
1000,
NM_MAKE_STRV(NM_AZURE_METADATA_HEADER),
+ NULL,
get_config_data->intern_cancellable,
NULL,
NULL,
@@ -316,6 +318,7 @@ _get_config_ips_prefix_list_cb(GObject *source, GAsyncResult *result, gpointer u
10000,
1000,
NM_MAKE_STRV(NM_AZURE_METADATA_HEADER),
+ NULL,
get_config_data->intern_cancellable,
NULL,
NULL,
@@ -333,6 +336,7 @@ _get_config_ips_prefix_list_cb(GObject *source, GAsyncResult *result, gpointer u
10000,
1000,
NM_MAKE_STRV(NM_AZURE_METADATA_HEADER),
+ NULL,
get_config_data->intern_cancellable,
NULL,
NULL,
@@ -415,6 +419,7 @@ _get_config_iface_cb(GObject *source, GAsyncResult *result, gpointer user_data)
10000,
1000,
NM_MAKE_STRV(NM_AZURE_METADATA_HEADER),
+ NULL,
get_config_data->intern_cancellable,
NULL,
NULL,
@@ -515,6 +520,7 @@ _get_net_ifaces_list_cb(GObject *source, GAsyncResult *result, gpointer user_dat
10000,
1000,
NM_MAKE_STRV(NM_AZURE_METADATA_HEADER),
+ NULL,
get_config_data->intern_cancellable,
NULL,
NULL,
@@ -538,6 +544,7 @@ get_config(NMCSProvider *provider, NMCSProviderGetConfigTaskData *get_config_dat
15000,
1000,
NM_MAKE_STRV(NM_AZURE_METADATA_HEADER),
+ NULL,
get_config_data->intern_cancellable,
NULL,
NULL,
diff --git a/src/nm-cloud-setup/nmcs-provider-ec2.c b/src/nm-cloud-setup/nmcs-provider-ec2.c
index 35f7176c4d..c3c527cfd4 100644
--- a/src/nm-cloud-setup/nmcs-provider-ec2.c
+++ b/src/nm-cloud-setup/nmcs-provider-ec2.c
@@ -106,6 +106,7 @@ detect(NMCSProvider *provider, GTask *task)
7000,
1000,
NULL,
+ NULL,
g_task_get_cancellable(task),
_detect_get_meta_data_check_cb,
NULL,
@@ -264,6 +265,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us
10000,
1000,
NULL,
+ NULL,
get_config_data->intern_cancellable,
NULL,
NULL,
@@ -281,6 +283,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us
10000,
1000,
NULL,
+ NULL,
get_config_data->intern_cancellable,
NULL,
NULL,
@@ -378,6 +381,7 @@ get_config(NMCSProvider *provider, NMCSProviderGetConfigTaskData *get_config_dat
15000,
1000,
NULL,
+ NULL,
get_config_data->intern_cancellable,
_get_config_metadata_ready_check,
get_config_data,
diff --git a/src/nm-cloud-setup/nmcs-provider-gcp.c b/src/nm-cloud-setup/nmcs-provider-gcp.c
index 571c0fb826..ca354865dd 100644
--- a/src/nm-cloud-setup/nmcs-provider-gcp.c
+++ b/src/nm-cloud-setup/nmcs-provider-gcp.c
@@ -79,6 +79,7 @@ detect(NMCSProvider *provider, GTask *task)
7000,
1000,
NM_MAKE_STRV(NM_GCP_METADATA_HEADER),
+ NULL,
g_task_get_cancellable(task),
NULL,
NULL,
@@ -227,6 +228,7 @@ _get_config_ips_list_cb(GObject *source, GAsyncResult *result, gpointer user_dat
HTTP_POLL_TIMEOUT_MS,
HTTP_RATE_LIMIT_MS,
NM_MAKE_STRV(NM_GCP_METADATA_HEADER),
+ NULL,
get_config_data->intern_cancellable,
NULL,
NULL,
@@ -313,6 +315,7 @@ _get_config_iface_cb(GObject *source, GAsyncResult *result, gpointer user_data)
HTTP_POLL_TIMEOUT_MS,
HTTP_RATE_LIMIT_MS,
NM_MAKE_STRV(NM_GCP_METADATA_HEADER),
+ NULL,
get_config_data->intern_cancellable,
NULL,
NULL,
@@ -412,6 +415,7 @@ _get_net_ifaces_list_cb(GObject *source, GAsyncResult *result, gpointer user_dat
HTTP_POLL_TIMEOUT_MS,
HTTP_RATE_LIMIT_MS,
NM_MAKE_STRV(NM_GCP_METADATA_HEADER),
+ NULL,
get_config_data->intern_cancellable,
NULL,
NULL,
@@ -435,6 +439,7 @@ get_config(NMCSProvider *provider, NMCSProviderGetConfigTaskData *get_config_dat
HTTP_POLL_TIMEOUT_MS,
HTTP_RATE_LIMIT_MS,
NM_MAKE_STRV(NM_GCP_METADATA_HEADER),
+ NULL,
get_config_data->intern_cancellable,
NULL,
NULL,
--
2.39.2
From 06fc0ef35dc7e5e6295ab9beecba6071e556d55e Mon Sep 17 00:00:00 2001
From: Lubomir Rintel <lkundrak@v3.sk>
Date: Tue, 7 Mar 2023 13:51:57 +0100
Subject: [PATCH 5/6] cloud-setup: document detect() and get_config() methods
Clarify that detect() needs to succeed before get_config().
I thought it's sort of common sense, but it's better to be explicit as
we're going to rely on that.
(cherry picked from commit 088bfd817ab5eb8aa0fb9cffe52fa3f456030ecc)
(cherry picked from commit d99864ccba6d7c9bac66dcbbcc49c01be0ddd719)
---
src/nm-cloud-setup/nmcs-provider.h | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/src/nm-cloud-setup/nmcs-provider.h b/src/nm-cloud-setup/nmcs-provider.h
index 502f1d0323..3662fbe391 100644
--- a/src/nm-cloud-setup/nmcs-provider.h
+++ b/src/nm-cloud-setup/nmcs-provider.h
@@ -152,8 +152,36 @@ typedef struct {
const char *_name;
const char *_env_provider_enabled;
+ /**
+ * detect:
+ * @self: the #NMCSProvider
+ * @task: a #GTask that's completed when the detection finishes.
+ *
+ * Checks whether the metadata of a particular cloud provider is
+ * accessible on the host machine. The check runs asynchronously.
+ *
+ * When the check finishes, @task is completed. If the check was
+ * successful, @task returns a gboolean of %TRUE. Otherwise
+ * a %FALSE value or an error is returned.
+ *
+ * The routine has to be called before the get_config() can be
+ * used.
+ */
void (*detect)(NMCSProvider *self, GTask *task);
+ /**
+ * get_config:
+ * @self: the #NMCSProvider
+ * @get_config_data: encapsulates a #GTask and network configuration data
+ *
+ * Collects the network configuration from metadata service of a
+ * particular cloud provider. The metadata is traversed and checked
+ * asynchronously, completing a task encapsulated in @get_config_data
+ * upon finishing.
+ *
+ * Call to detect() with a successful result is necessary before
+ * using this routine.
+ */
void (*get_config)(NMCSProvider *self, NMCSProviderGetConfigTaskData *get_config_data);
} NMCSProviderClass;
--
2.39.2
From e3ac982b32361105708d489a73eaed2bc4dc5f9f Mon Sep 17 00:00:00 2001
From: Lubomir Rintel <lkundrak@v3.sk>
Date: Mon, 27 Feb 2023 00:15:11 +0100
Subject: [PATCH 6/6] cloud-setup/ec2: start with requesting a IMDSv2 token
The present version of the EC2 metadata API (IMDSv2) requires a header
with a token to be present in all requests. The token is essentially a
cookie that's not actually a cookie that's obtained with a PUT call that
doesn't put anything. Apparently it's too easy to trick someone into
calling a GET method.
EC2 now supports IMDSv2 everywhere with IMDSv1 being optional, so let's
just use IMDSv2 unconditionally. Also, the presence of a token API can
be used to detect the AWS EC2 cloud.
https://bugzilla.redhat.com/show_bug.cgi?id=2151986
(cherry picked from commit 8b7e12c2d631c47292258c29429cd565715ea186)
(cherry picked from commit 429f36cd81ddbe337f04c09a352fd78cd29e394d)
---
src/nm-cloud-setup/nmcs-provider-ec2.c | 74 +++++++++++++++++++-------
1 file changed, 54 insertions(+), 20 deletions(-)
diff --git a/src/nm-cloud-setup/nmcs-provider-ec2.c b/src/nm-cloud-setup/nmcs-provider-ec2.c
index c3c527cfd4..3a27a30e68 100644
--- a/src/nm-cloud-setup/nmcs-provider-ec2.c
+++ b/src/nm-cloud-setup/nmcs-provider-ec2.c
@@ -16,6 +16,11 @@
#define NM_EC2_METADATA_URL_BASE /* $NM_EC2_BASE/$NM_EC2_API_VERSION */ \
"/meta-data/network/interfaces/macs/"
+/* Token TTL of 180 seconds is chosen abitrarily, in hope that it is
+ * surely more than enough to read all relevant metadata. */
+#define NM_EC2_TOKEN_TTL_HEADER "X-aws-ec2-metadata-token-ttl-seconds: 180"
+#define NM_EC2_TOKEN_HEADER "X-aws-ec2-metadata-token: "
+
static const char *
_ec2_base(void)
{
@@ -44,8 +49,15 @@ again:
/*****************************************************************************/
+enum {
+ NM_EC2_HTTP_HEADER_TOKEN,
+ NM_EC2_HTTP_HEADER_SENTINEL,
+ _NM_EC2_HTTP_HEADER_NUM,
+};
+
struct _NMCSProviderEC2 {
NMCSProvider parent;
+ char *token;
};
struct _NMCSProviderEC2Class {
@@ -56,23 +68,18 @@ G_DEFINE_TYPE(NMCSProviderEC2, nmcs_provider_ec2, NMCS_TYPE_PROVIDER);
/*****************************************************************************/
-static gboolean
-_detect_get_meta_data_check_cb(long response_code,
- GBytes *response,
- gpointer check_user_data,
- GError **error)
-{
- return response_code == 200 && nmcs_utils_parse_get_full_line(response, "ami-id");
-}
-
static void
-_detect_get_meta_data_done_cb(GObject *source, GAsyncResult *result, gpointer user_data)
+_detect_get_token_done_cb(GObject *source, GAsyncResult *result, gpointer user_data)
{
gs_unref_object GTask *task = user_data;
+ NMCSProviderEC2 *self = NMCS_PROVIDER_EC2(g_task_get_source_object(task));
+ gs_unref_bytes GBytes *response = NULL;
gs_free_error GError *get_error = NULL;
gs_free_error GError *error = NULL;
- nm_http_client_poll_req_finish(NM_HTTP_CLIENT(source), result, NULL, NULL, &get_error);
+ nm_clear_g_free(&self->token);
+
+ nm_http_client_poll_req_finish(NM_HTTP_CLIENT(source), result, NULL, &response, &get_error);
if (nm_utils_error_is_cancelled(get_error)) {
g_task_return_error(task, g_steal_pointer(&get_error));
@@ -88,6 +95,12 @@ _detect_get_meta_data_done_cb(GObject *source, GAsyncResult *result, gpointer us
return;
}
+ /* We use the token as-is. Special characters can cause confusion (e.g.
+ * response splitting), but we're not crossing a security boundary.
+ * None of the examples in AWS documentation does any sort of
+ * sanitization either. */
+ self->token = g_strconcat(NM_EC2_TOKEN_HEADER, g_bytes_get_data(response, NULL), NULL);
+
g_task_return_boolean(task, TRUE);
}
@@ -100,17 +113,17 @@ detect(NMCSProvider *provider, GTask *task)
http_client = nmcs_provider_get_http_client(provider);
nm_http_client_poll_req(http_client,
- (uri = _ec2_uri_concat("latest/meta-data/")),
+ (uri = _ec2_uri_concat("latest/api/token")),
HTTP_TIMEOUT_MS,
256 * 1024,
7000,
1000,
- NULL,
- NULL,
+ NM_MAKE_STRV(NM_EC2_TOKEN_TTL_HEADER),
+ "PUT",
g_task_get_cancellable(task),
- _detect_get_meta_data_check_cb,
NULL,
- _detect_get_meta_data_done_cb,
+ NULL,
+ _detect_get_token_done_cb,
task);
}
@@ -198,6 +211,7 @@ static void
_get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer user_data)
{
NMCSProviderGetConfigTaskData *get_config_data;
+ NMCSProviderEC2 *self;
gs_unref_hashtable GHashTable *response_parsed = NULL;
gs_free_error GError *error = NULL;
GetConfigMetadataMac *v_mac_data;
@@ -211,6 +225,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us
return;
get_config_data = user_data;
+ self = NMCS_PROVIDER_EC2(get_config_data->self);
response_parsed = g_steal_pointer(&get_config_data->extra_data);
get_config_data->extra_data_destroy = NULL;
@@ -264,7 +279,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us
512 * 1024,
10000,
1000,
- NULL,
+ NM_MAKE_STRV(self->token),
NULL,
get_config_data->intern_cancellable,
NULL,
@@ -282,7 +297,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us
512 * 1024,
10000,
1000,
- NULL,
+ NM_MAKE_STRV(self->token),
NULL,
get_config_data->intern_cancellable,
NULL,
@@ -368,7 +383,13 @@ _get_config_metadata_ready_check(long response_code,
static void
get_config(NMCSProvider *provider, NMCSProviderGetConfigTaskData *get_config_data)
{
- gs_free char *uri = NULL;
+ NMCSProviderEC2 *self = NMCS_PROVIDER_EC2(provider);
+ gs_free char *uri = NULL;
+
+ /* This can be called only if detect() succeeded, which implies
+ * there must be a token.
+ */
+ nm_assert(self->token);
/* First we fetch the "macs/". If the caller requested some particular
* MAC addresses, then we poll until we see them. They might not yet be
@@ -380,7 +401,7 @@ get_config(NMCSProvider *provider, NMCSProviderGetConfigTaskData *get_config_dat
256 * 1024,
15000,
1000,
- NULL,
+ NM_MAKE_STRV(self->token),
NULL,
get_config_data->intern_cancellable,
_get_config_metadata_ready_check,
@@ -395,11 +416,24 @@ static void
nmcs_provider_ec2_init(NMCSProviderEC2 *self)
{}
+static void
+dispose(GObject *object)
+{
+ NMCSProviderEC2 *self = NMCS_PROVIDER_EC2(object);
+
+ nm_clear_g_free(&self->token);
+
+ G_OBJECT_CLASS(nmcs_provider_ec2_parent_class)->dispose(object);
+}
+
static void
nmcs_provider_ec2_class_init(NMCSProviderEC2Class *klass)
{
+ GObjectClass *object_class = G_OBJECT_CLASS(klass);
NMCSProviderClass *provider_class = NMCS_PROVIDER_CLASS(klass);
+ object_class->dispose = dispose;
+
provider_class->_name = "ec2";
provider_class->_env_provider_enabled = NMCS_ENV_VARIABLE("NM_CLOUD_SETUP_EC2");
provider_class->detect = detect;
--
2.39.2

View File

@ -196,12 +196,7 @@ Patch3: 0003-order-ipv6-addresses.patch
# Bugfixes that are only relevant until next rebase of the package.
# Patch1001: 1001-some.patch
Patch11: 0001-cloud-setup-use-nm_strv_dup_packed-in-nm_http_client.patch
Patch12: 0002-cloud_setup-unexport-nm_http_client_get.patch
Patch13: 0003-cloud-setup-rename-get-Get-identifiers-to-req-and-Re.patch
Patch14: 0004-cloud-setup-make-nm_http_client_req-accept-a-method-.patch
Patch15: 0005-cloud-setup-document-detect-and-get_config-methods.patch
Patch16: 0006-cloud-setup-ec2-start-with-requesting-a-IMDSv2-token.patch
Patch1001: 1001-cloud-setup-IMDSv2-rh2151987.patch
Requires(post): systemd
%if 0%{?fedora} || 0%{?rhel} >= 8