@cryptotaxi247 / netdata-1 / commits / 52331eb4a

added more access control lists; #2636

Costa Tsaousis (ktsaou) committed Sep 18, 2017 at 00:29 UTC 52331eb4ab5ccc1239edb4398ed02e1a8ae4cc00
4 files changed +63 -33
src/main.c
+4 -1
@@ -83,7 +83,10 @@ void web_server_config_options(void) {
83 web_x_frame_options = config_get(CONFIG_SECTION_WEB, "x-frame-options response header", "");
84 if(!*web_x_frame_options) web_x_frame_options = NULL;
85
86 - web_client_access_list = simple_pattern_create(config_get(CONFIG_SECTION_WEB, "global API allow from", "127.* ::1 *"), SIMPLE_PATTERN_EXACT);
86 + web_allow_connections_from = simple_pattern_create(config_get(CONFIG_SECTION_WEB, "allow connections from", "127.* ::1 *"), SIMPLE_PATTERN_EXACT);
87 + web_allow_badges_from = simple_pattern_create(config_get(CONFIG_SECTION_WEB, "allow badges from", "*"), SIMPLE_PATTERN_EXACT);
88 + web_allow_registry_from = simple_pattern_create(config_get(CONFIG_SECTION_REGISTRY, "allow from", "*"), SIMPLE_PATTERN_EXACT);
89 + web_allow_streaming_from = simple_pattern_create(config_get(CONFIG_SECTION_WEB, "allow streaming from", "*"), SIMPLE_PATTERN_EXACT);
90
91 #ifdef NETDATA_WITH_ZLIB
92 web_enable_gzip = config_get_boolean(CONFIG_SECTION_WEB, "enable gzip compression", web_enable_gzip);
src/web_api_v1.c
+35 -29
@@ -298,6 +298,9 @@ inline int web_client_api_request_v1_chart(RRDHOST *host, struct web_client *w,
298 }
299
300 int web_client_api_request_v1_badge(RRDHOST *host, struct web_client *w, char *url) {
301 + if(unlikely(web_allow_badges_from && !simple_pattern_matches(web_allow_badges_from, w->client_ip)))
302 + return web_client_permission_denied(w);
303 +
304 int ret = 400;
305 buffer_flush(w->response.data);
306
@@ -816,55 +819,58 @@ inline int web_client_api_request_v1_registry(RRDHOST *host, struct web_client *
819 #endif /* NETDATA_INTERNAL_CHECKS */
820 }
821
819 - if(respect_web_browser_do_not_track_policy && web_client_has_donottrack(w)) {
822 + if(unlikely(respect_web_browser_do_not_track_policy && web_client_has_donottrack(w))) {
823 buffer_flush(w->response.data);
824 buffer_sprintf(w->response.data, "Your web browser is sending 'DNT: 1' (Do Not Track). The registry requires persistent cookies on your browser to work.");
825 return 400;
826 }
827
825 - if(action == 'A' && (!machine_guid || !machine_url || !url_name)) {
826 - error("Invalid registry request - access requires these parameters: machine ('%s'), url ('%s'), name ('%s')",
827 - machine_guid?machine_guid:"UNSET", machine_url?machine_url:"UNSET", url_name?url_name:"UNSET");
828 - buffer_flush(w->response.data);
829 - buffer_strcat(w->response.data, "Invalid registry Access request.");
830 - return 400;
831 - }
832 - else if(action == 'D' && (!machine_guid || !machine_url || !delete_url)) {
833 - error("Invalid registry request - delete requires these parameters: machine ('%s'), url ('%s'), delete_url ('%s')",
834 - machine_guid?machine_guid:"UNSET", machine_url?machine_url:"UNSET", delete_url?delete_url:"UNSET");
835 - buffer_flush(w->response.data);
836 - buffer_strcat(w->response.data, "Invalid registry Delete request.");
837 - return 400;
838 - }
839 - else if(action == 'S' && (!machine_guid || !machine_url || !search_machine_guid)) {
840 - error("Invalid registry request - search requires these parameters: machine ('%s'), url ('%s'), for ('%s')",
841 - machine_guid?machine_guid:"UNSET", machine_url?machine_url:"UNSET", search_machine_guid?search_machine_guid:"UNSET");
842 - buffer_flush(w->response.data);
843 - buffer_strcat(w->response.data, "Invalid registry Search request.");
844 - return 400;
845 - }
846 - else if(action == 'W' && (!machine_guid || !machine_url || !to_person_guid)) {
847 - error("Invalid registry request - switching identity requires these parameters: machine ('%s'), url ('%s'), to ('%s')",
848 - machine_guid?machine_guid:"UNSET", machine_url?machine_url:"UNSET", to_person_guid?to_person_guid:"UNSET");
849 - buffer_flush(w->response.data);
850 - buffer_strcat(w->response.data, "Invalid registry Switch request.");
851 - return 400;
852 - }
828 + // for all calls except HELLO, we have to check the ACL
829 + if(unlikely(action != 'H' && web_allow_registry_from && !simple_pattern_matches(web_allow_registry_from, w->client_ip)))
830 + return web_client_permission_denied(w);
831
832 switch(action) {
833 case 'A':
834 + if(unlikely(!machine_guid || !machine_url || !url_name)) {
835 + error("Invalid registry request - access requires these parameters: machine ('%s'), url ('%s'), name ('%s')", machine_guid ? machine_guid : "UNSET", machine_url ? machine_url : "UNSET", url_name ? url_name : "UNSET");
836 + buffer_flush(w->response.data);
837 + buffer_strcat(w->response.data, "Invalid registry Access request.");
838 + return 400;
839 + }
840 +
841 web_client_enable_tracking_required(w);
842 return registry_request_access_json(host, w, person_guid, machine_guid, machine_url, url_name, now_realtime_sec());
843
844 case 'D':
845 + if(unlikely(!machine_guid || !machine_url || !delete_url)) {
846 + error("Invalid registry request - delete requires these parameters: machine ('%s'), url ('%s'), delete_url ('%s')", machine_guid?machine_guid:"UNSET", machine_url?machine_url:"UNSET", delete_url?delete_url:"UNSET");
847 + buffer_flush(w->response.data);
848 + buffer_strcat(w->response.data, "Invalid registry Delete request.");
849 + return 400;
850 + }
851 +
852 web_client_enable_tracking_required(w);
853 return registry_request_delete_json(host, w, person_guid, machine_guid, machine_url, delete_url, now_realtime_sec());
854
855 case 'S':
856 + if(unlikely(!machine_guid || !machine_url || !search_machine_guid)) {
857 + error("Invalid registry request - search requires these parameters: machine ('%s'), url ('%s'), for ('%s')", machine_guid?machine_guid:"UNSET", machine_url?machine_url:"UNSET", search_machine_guid?search_machine_guid:"UNSET");
858 + buffer_flush(w->response.data);
859 + buffer_strcat(w->response.data, "Invalid registry Search request.");
860 + return 400;
861 + }
862 +
863 web_client_enable_tracking_required(w);
864 return registry_request_search_json(host, w, person_guid, machine_guid, machine_url, search_machine_guid, now_realtime_sec());
865
866 case 'W':
867 + if(unlikely(!machine_guid || !machine_url || !to_person_guid)) {
868 + error("Invalid registry request - switching identity requires these parameters: machine ('%s'), url ('%s'), to ('%s')", machine_guid?machine_guid:"UNSET", machine_url?machine_url:"UNSET", to_person_guid?to_person_guid:"UNSET");
869 + buffer_flush(w->response.data);
870 + buffer_strcat(w->response.data, "Invalid registry Switch request.");
871 + return 400;
872 + }
873 +
874 web_client_enable_tracking_required(w);
875 return registry_request_switch_json(host, w, person_guid, machine_guid, machine_url, to_person_guid, now_realtime_sec());
876
src/web_client.c
+18 -2
@@ -8,7 +8,10 @@ int web_client_timeout = DEFAULT_DISCONNECT_IDLE_WEB_CLIENTS_AFTER_SECONDS;
8 int respect_web_browser_do_not_track_policy = 0;
9 char *web_x_frame_options = NULL;
10
11 -SIMPLE_PATTERN *web_client_access_list = NULL;
11 +SIMPLE_PATTERN *web_allow_connections_from = NULL;
12 +SIMPLE_PATTERN *web_allow_registry_from = NULL;
13 +SIMPLE_PATTERN *web_allow_badges_from = NULL;
14 +SIMPLE_PATTERN *web_allow_streaming_from = NULL;
15
16 #ifdef NETDATA_WITH_ZLIB
17 int web_enable_gzip = 1, web_gzip_level = 3, web_gzip_strategy = Z_DEFAULT_STRATEGY;
@@ -52,6 +55,14 @@ static inline int web_client_uncrock_socket(struct web_client *w) {
55 return 0;
56 }
57
58 +inline int web_client_permission_denied(struct web_client *w) {
59 + w->response.data->contenttype = CT_TEXT_PLAIN;
60 + buffer_flush(w->response.data);
61 + buffer_strcat(w->response.data, "You do not allowed to access this resource.");
62 + w->response.code = 403;
63 + return 403;
64 +}
65 +
66 static void log_connection(struct web_client *w, const char *msg) {
67 log_access("%llu: %d '[%s]:%s' '%s'", w->id, gettid(), w->client_ip, w->client_port, msg);
68 }
@@ -64,7 +75,7 @@ struct web_client *web_client_create(int listener) {
75 w->mode = WEB_CLIENT_MODE_NORMAL;
76
77 {
67 - w->ifd = accept_socket(listener, SOCK_NONBLOCK, w->client_ip, sizeof(w->client_ip), w->client_port, sizeof(w->client_port), web_client_access_list);
78 + w->ifd = accept_socket(listener, SOCK_NONBLOCK, w->client_ip, sizeof(w->client_ip), w->client_port, sizeof(w->client_port), web_allow_connections_from);
79
80 if(unlikely(!*w->client_ip)) strcpy(w->client_ip, "-");
81 if(unlikely(!*w->client_port)) strcpy(w->client_port, "-");
@@ -1235,6 +1246,11 @@ void web_client_process_request(struct web_client *w) {
1246 case HTTP_VALIDATION_OK:
1247 switch(w->mode) {
1248 case WEB_CLIENT_MODE_STREAM:
1249 + if(unlikely(web_allow_streaming_from && !simple_pattern_matches(web_allow_streaming_from, w->client_ip))) {
1250 + web_client_permission_denied(w);
1251 + return;
1252 + }
1253 +
1254 w->response.code = rrdpush_receiver_thread_spawn(localhost, w, w->decoded_url);
1255 return;
1256
src/web_client.h
+6 -1
@@ -142,11 +142,16 @@ struct web_client {
142 };
143
144 extern struct web_client *web_clients;
145 -extern SIMPLE_PATTERN *web_client_access_list;
145 +extern SIMPLE_PATTERN *web_allow_connections_from;
146 +extern SIMPLE_PATTERN *web_allow_registry_from;
147 +extern SIMPLE_PATTERN *web_allow_badges_from;
148 +extern SIMPLE_PATTERN *web_allow_streaming_from;
149
150 extern uid_t web_files_uid(void);
151 extern uid_t web_files_gid(void);
152
153 +extern int web_client_permission_denied(struct web_client *w);
154 +
155 extern struct web_client *web_client_create(int listener);
156 extern struct web_client *web_client_free(struct web_client *w);
157 extern ssize_t web_client_send(struct web_client *w);