char *hostname;
char *registry_to_announce;
time_t persons_expiration; // seconds to expire idle persons
+ int verify_cookies_redirects;
size_t max_url_length;
size_t max_name_length;
#define REGISTRY_STATUS_FAILED "failed"
#define REGISTRY_STATUS_DISABLED "disabled"
-static inline void registry_set_person_cookie(struct web_client *w, PERSON *p) {
+int registry_verify_cookies_redirects(void) {
+ return registry.verify_cookies_redirects;
+}
+
+const char *registry_to_announce(void) {
+ return registry.registry_to_announce;
+}
+
+void registry_set_cookie(struct web_client *w, const char *guid) {
char edate[100];
time_t et = time(NULL) + registry.persons_expiration;
struct tm etmbuf, *etm = gmtime_r(&et, &etmbuf);
strftime(edate, sizeof(edate), "%a, %d %b %Y %H:%M:%S %Z", etm);
- snprintfz(w->cookie1, COOKIE_MAX, NETDATA_REGISTRY_COOKIE_NAME "=%s; Expires=%s", p->guid, edate);
+ snprintfz(w->cookie1, COOKIE_MAX, NETDATA_REGISTRY_COOKIE_NAME "=%s; Expires=%s", guid, edate);
if(registry.registry_domain && registry.registry_domain[0])
- snprintfz(w->cookie2, COOKIE_MAX, NETDATA_REGISTRY_COOKIE_NAME "=%s; Domain=%s; Expires=%s", p->guid, registry.registry_domain, edate);
+ snprintfz(w->cookie2, COOKIE_MAX, NETDATA_REGISTRY_COOKIE_NAME "=%s; Domain=%s; Expires=%s", guid, registry.registry_domain, edate);
+}
+
+static inline void registry_set_person_cookie(struct web_client *w, PERSON *p) {
+ registry_set_cookie(w, p->guid);
}
static inline void registry_json_header(struct web_client *w, const char *action, const char *status) {
registry.registry_to_announce = config_get("registry", "registry to announce", "https://registry.my-netdata.io");
registry.hostname = config_get("registry", "registry hostname", config_get("global", "hostname", hostname));
+ registry.verify_cookies_redirects = config_get_number("registry", "verify browser cookies support max redirects", 2);
+ if(registry.verify_cookies_redirects < 0) {
+ registry.verify_cookies_redirects = 0;
+ config_set_number("registry", "verify browser cookies support max redirects", registry.verify_cookies_redirects);
+ }
+
registry.max_url_length = config_get_number("registry", "max URL length", 1024);
- registry.max_name_length = config_get_number("registry", "max URL name length", 50);
+ if(registry.max_url_length < 10) {
+ registry.max_url_length = 10;
+ config_set_number("registry", "max URL length", registry.max_url_length);
+ }
+ registry.max_name_length = config_get_number("registry", "max URL name length", 50);
+ if(registry.max_name_length < 10) {
+ registry.max_name_length = 10;
+ config_set_number("registry", "max URL name length", registry.max_name_length);
+ }
// initialize entries counters
registry.persons_count = 0;
#define NETDATA_REGISTRY_COOKIE_NAME "netdata_registry_id"
+extern void registry_set_cookie(struct web_client *w, const char *guid);
+extern const char *registry_to_announce(void);
+extern int registry_verify_cookies_redirects(void);
+
extern int registry_request_access_json(struct web_client *w, char *person_guid, char *machine_guid, char *url, char *name, time_t when);
extern int registry_request_delete_json(struct web_client *w, char *person_guid, char *machine_guid, char *url, char *delete_url, time_t when);
extern int registry_request_search_json(struct web_client *w, char *person_guid, char *machine_guid, char *url, char *request_machine, time_t when);
{
static uint32_t hash_action = 0, hash_access = 0, hash_hello = 0, hash_delete = 0, hash_search = 0,
hash_switch = 0, hash_machine = 0, hash_url = 0, hash_name = 0, hash_delete_url = 0, hash_for = 0,
- hash_to = 0;
+ hash_to = 0, hash_redirects = 0;
if(unlikely(!hash_action)) {
hash_action = simple_hash("action");
hash_delete_url = simple_hash("delete_url");
hash_for = simple_hash("for");
hash_to = simple_hash("to");
+ hash_redirects = simple_hash("redirects");
}
char person_guid[36 + 1] = "";
// FIXME
// The browser may send multiple cookies with our id
- char *cookie = strstr(w->response.data->buffer, " " NETDATA_REGISTRY_COOKIE_NAME "=");
+ char *cookie = strstr(w->response.data->buffer, NETDATA_REGISTRY_COOKIE_NAME "=");
if(cookie)
- strncpyz(person_guid, &cookie[sizeof(NETDATA_REGISTRY_COOKIE_NAME) + 1], 36);
+ strncpyz(person_guid, &cookie[sizeof(NETDATA_REGISTRY_COOKIE_NAME)], 36);
char action = '\0';
char *machine_guid = NULL,
*search_machine_guid = NULL,
*delete_url = NULL,
*to_person_guid = NULL;
+ int redirects = 0;
while(url) {
char *value = mystrsep(&url, "?&[]");
else if(vhash == hash_delete && !strcmp(value, "delete")) action = 'D';
else if(vhash == hash_search && !strcmp(value, "search")) action = 'S';
else if(vhash == hash_switch && !strcmp(value, "switch")) action = 'W';
+#ifdef NETDATA_INTERNAL_CHECKS
+ else error("unknown registry action '%s'", value);
+#endif /* NETDATA_INTERNAL_CHECKS */
}
+ else if(hash == hash_redirects && !strcmp(name, "redirects"))
+ redirects = atoi(value);
+
else if(hash == hash_machine && !strcmp(name, "machine"))
machine_guid = value;
if(hash == hash_to && !strcmp(name, "to"))
to_person_guid = value;
}
+#ifdef NETDATA_INTERNAL_CHECKS
+ else error("unused registry URL parameter '%s' with value '%s'", name, value);
+#endif /* NETDATA_INTERNAL_CHECKS */
}
if(action == 'A' && (!machine_guid || !machine_url || !url_name)) {
switch(action) {
case 'A':
+ if(registry_verify_cookies_redirects() > 0 && (!cookie || !person_guid[0])) {
+ buffer_flush(w->response.data);
+
+ if(redirects > registry_verify_cookies_redirects()) {
+ buffer_sprintf(w->response.data, "Your browser does not support cookies");
+ return 400;
+ }
+
+ redirects++;
+
+ char *encoded_url = url_encode(machine_url);
+ if(!encoded_url) {
+ error("%llu: Cannot URL encode string '%s'", w->id, machine_url);
+ return 500;
+ }
+
+ char *encoded_name = url_encode(url_name);
+ if(!encoded_name) {
+ free(encoded_url);
+ error("%llu: Cannot URL encode string '%s'", w->id, url_name);
+ return 500;
+ }
+
+ char *encoded_guid = url_encode(machine_guid);
+ if(!encoded_guid) {
+ free(encoded_url);
+ free(encoded_name);
+ error("%llu: Cannot URL encode string '%s'", w->id, machine_guid);
+ return 500;
+ }
+
+ registry_set_cookie(w, "give-me-back-this-cookie-please");
+ buffer_sprintf(w->response.header, "Location: %s/api/v1/registry?action=access&machine=%s&name=%s&url=%s&redirects=%d\r\n",
+ registry_to_announce(), encoded_guid, encoded_name, encoded_url, redirects);
+ free(encoded_guid);
+ free(encoded_name);
+ free(encoded_url);
+ return 307;
+ }
return registry_request_access_json(w, person_guid, machine_guid, machine_url, url_name, time(NULL));
case 'D':