master
c 139 lines 4.85 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #include "api_v2_calls.h"
4
5 static bool verify_host_uuids(RRDHOST *host, const char *machine_guid, const char *node_id) {
6 if(!machine_guid || !node_id)
7 return false;
8
9 if(strcmp(machine_guid, host->machine_guid) != 0)
10 return false;
11
12 if(UUIDiszero(host->node_id))
13 return false;
14
15 char buf[UUID_STR_LEN];
16 uuid_unparse_lower(host->node_id.uuid, buf);
17
18 return strcmp(node_id, buf) == 0;
19 }
20
21 int api_v2_bearer_protection(RRDHOST *host __maybe_unused, struct web_client *w __maybe_unused, char *url) {
22 char *machine_guid = NULL;
23 char *claim_id = NULL;
24 char *node_id = NULL;
25 bool protection = netdata_is_protected_by_bearer;
26
27 while (url) {
28 char *value = strsep_skip_consecutive_separators(&url, "&");
29 if (!value || !*value) continue;
30
31 char *name = strsep_skip_consecutive_separators(&value, "=");
32 if (!name || !*name) continue;
33 if (!value || !*value) continue;
34
35 if(!strcmp(name, "bearer_protection")) {
36 if(!strcmp(value, "on") || !strcmp(value, "true") || !strcmp(value, "yes"))
37 protection = true;
38 else
39 protection = false;
40 }
41 else if(!strcmp(name, "machine_guid"))
42 machine_guid = value;
43 else if(!strcmp(name, "claim_id"))
44 claim_id = value;
45 else if(!strcmp(name, "node_id"))
46 node_id = value;
47 }
48
49 if(!claim_id_matches(claim_id)) {
50 buffer_reset(w->response.data);
51 buffer_strcat(w->response.data, "The request is for a different claimed agent");
52 return HTTP_RESP_BAD_REQUEST;
53 }
54
55 if(!verify_host_uuids(localhost, machine_guid, node_id)) {
56 buffer_reset(w->response.data);
57 buffer_strcat(w->response.data, "The request is missing or not matching local UUIDs");
58 return HTTP_RESP_BAD_REQUEST;
59 }
60
61 netdata_is_protected_by_bearer = protection;
62
63 BUFFER *wb = w->response.data;
64 buffer_reset(wb);
65 buffer_json_initialize(wb, "\"", "\"", 0, true, BUFFER_JSON_OPTIONS_DEFAULT);
66 buffer_json_member_add_boolean(wb, "bearer_protection", netdata_is_protected_by_bearer);
67 buffer_json_finalize(wb);
68
69 return HTTP_RESP_OK;
70 }
71
72 int bearer_get_token_json_response(BUFFER *wb, RRDHOST *host, const char *claim_id, const char *machine_guid, const char *node_id, HTTP_USER_ROLE user_role, HTTP_ACCESS access, nd_uuid_t cloud_account_id, const char *client_name) {
73 if(!claim_id_matches_any(claim_id))
74 return rrd_call_function_error(wb, "The request is for a different agent", HTTP_RESP_BAD_REQUEST);
75
76 if(!verify_host_uuids(host, machine_guid, node_id))
77 return rrd_call_function_error(wb, "The request is missing or not matching local node UUIDs", HTTP_RESP_BAD_REQUEST);
78
79 nd_uuid_t uuid;
80 time_t expires_s = bearer_create_token(&uuid, user_role, access, cloud_account_id, client_name);
81
82 buffer_reset(wb);
83 buffer_json_initialize(wb, "\"", "\"", 0, true, BUFFER_JSON_OPTIONS_MINIFY);
84 buffer_json_member_add_int64(wb, "status", HTTP_RESP_OK);
85 buffer_json_member_add_string(wb, "mg", host->machine_guid);
86 buffer_json_member_add_boolean(wb, "bearer_protection", netdata_is_protected_by_bearer);
87 buffer_json_member_add_uuid(wb, "token", uuid);
88 buffer_json_member_add_time_t(wb, "expiration", expires_s);
89 buffer_json_finalize(wb);
90 return HTTP_RESP_OK;
91 }
92
93 int api_v2_bearer_get_token(RRDHOST *host, struct web_client *w, char *url) {
94 char *machine_guid = NULL;
95 char *claim_id = NULL;
96 char *node_id = NULL;
97
98 while(url) {
99 char *value = strsep_skip_consecutive_separators(&url, "&");
100 if (!value || !*value) continue;
101
102 char *name = strsep_skip_consecutive_separators(&value, "=");
103 if (!name || !*name) continue;
104 if (!value || !*value) continue;
105
106 if(!strcmp(name, "machine_guid"))
107 machine_guid = value;
108 else if(!strcmp(name, "claim_id"))
109 claim_id = value;
110 else if(!strcmp(name, "node_id"))
111 node_id = value;
112 }
113
114 if(!claim_id_matches(claim_id)) {
115 buffer_reset(w->response.data);
116 buffer_strcat(w->response.data, "The request is for a different claimed agent");
117 return HTTP_RESP_BAD_REQUEST;
118 }
119
120 if(!verify_host_uuids(host, machine_guid, node_id)) {
121 buffer_reset(w->response.data);
122 buffer_strcat(w->response.data, "The request is missing or not matching local UUIDs");
123 return HTTP_RESP_BAD_REQUEST;
124 }
125
126 if(host != localhost)
127 return call_function_bearer_get_token(host, w, claim_id, machine_guid, node_id);
128
129 return bearer_get_token_json_response(
130 w->response.data,
131 host,
132 claim_id,
133 machine_guid,
134 node_id,
135 w->user_auth.user_role,
136 w->user_auth.access,
137 w->user_auth.cloud_account_id.uuid,
138 w->user_auth.client_name);
139 }