summaryrefslogtreecommitdiffstats
path: root/libnetdata
diff options
context:
space:
mode:
authorthiagoftsm <thiagoftsm@gmail.com>2019-07-25 16:43:04 +0000
committerChris Akritidis <43294513+cakrit@users.noreply.github.com>2019-07-25 18:43:04 +0200
commit2f7962c9e154dcce1684f2275387c9b6ac4d0b4c (patch)
tree10a3f5d7451d429a1bd8df91176b04cd82551abb /libnetdata
parentd95912af0834c45fa8a4aee2892b97fbd2e9b520 (diff)
Fix parsing SSL ACL along with others (#6468)
* sslstream: ACL parser It was noticed in the issue 6457 that the some ACLs were not parsing correctly when they were along SSL acl, this commit fixes this' * sslstream: remove comments This commit removes the comments that were present while I was testing the code * sslstream: Tests This commit adds ACL tests to check the Netdata response to them * sslstream: Tests Fix the extension to upload the files * sslstream: more tests In this commit I am bringing more tests, including the ssl tests' * sslstream: leading space Remove leading space from variable that was creating problem with shellcheck * sslstream: glob Remove special character from script * sslstream: Makefile The Makefile diretives were pointed to wrong files * sslstream: Missing stream encrypt This commit solves the problem of the stream not be encrypted, but it is not the final solution, because the parser made is incomplete. * sslstream: Finish encrypt channel This commit brings the step that I was missing, the complete encryptation in the communication between Master and Slave * sslstream: Fix argument in script After the latest tests, it was verified that two arguments given to a function inside the script were not correct, with this PR I am fixing this! * sslstream: Fix argument in info Instead to call a function to deliver an integer I was passing a size_t value. Only cmake showed this, but not in my clion! :/ * sslstream: Fix redirect When we were having different SSL configuration, the system were not applying the option for all * sslstream: Update documentation Our documentation was not clear about the rules according our code so I am updating the text to explain for the users * sslstream: Adjust script With this last commit, I am adjusting the tests to avoid false positive * sslstream: Missing elif The previous commit had a missing elif in the shell script * sslstream: Split ports Before this commit Netdata was having SSL as a global option, now it has as a real ACL. * sslstream: reduce context The stream variable will not be affected in the master side, it is only necessary on the slave side, so I am reducing the context of it * sslstream: Force SSL When the user has certificate and he does not set any SSL flag, it is necessary to append the SSL=force flag * sslstream: Default flag It is necessary to have a default flag when the SSL flags are not SET * sslstream: remove comments Remove comments from the scrip * sslstream: moving flag It is better the flag to be set inside socket instead everytime there is a new connection * sslstream: documentation Fix a sentence in the web/server/README.md
Diffstat (limited to 'libnetdata')
-rw-r--r--libnetdata/socket/security.c18
-rw-r--r--libnetdata/socket/security.h4
-rw-r--r--libnetdata/socket/socket.c66
-rw-r--r--libnetdata/socket/socket.h8
4 files changed, 63 insertions, 33 deletions
diff --git a/libnetdata/socket/security.c b/libnetdata/socket/security.c
index 7f69b17e00..9eb8e60247 100644
--- a/libnetdata/socket/security.c
+++ b/libnetdata/socket/security.c
@@ -7,8 +7,6 @@ SSL_CTX *netdata_client_ctx=NULL;
SSL_CTX *netdata_srv_ctx=NULL;
const char *security_key=NULL;
const char *security_cert=NULL;
-int netdata_use_ssl_on_stream = NETDATA_SSL_OPTIONAL;
-int netdata_use_ssl_on_http = NETDATA_SSL_FORCE; //We force SSL due safety reasons
int netdata_validate_server = NETDATA_SSL_VALID_CERTIFICATE;
/**
@@ -176,6 +174,9 @@ void security_start_ssl(int selector) {
}
case NETDATA_SSL_CONTEXT_STREAMING: {
netdata_client_ctx = security_initialize_openssl_client();
+ //This is necessary for the stream, because it is working sometimes with nonblock socket.
+ //It returns the bitmask afte to change, there is not any description of errors in the documentation
+ SSL_CTX_set_mode(netdata_client_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |SSL_MODE_AUTO_RETRY);
break;
}
case NETDATA_SSL_CONTEXT_OPENTSDB: {
@@ -206,6 +207,17 @@ void security_clean_openssl() {
#endif
}
+/**
+ * Process accept
+ *
+ * Process the SSL handshake with the client case it is necessary.
+ *
+ * @param ssl is a pointer for the SSL structure
+ * @param msg is a copy of the first 8 bytes of the initial message received
+ *
+ * @return it returns 0 case it performs the handshake, 8 case it is clean connection
+ * and another integer power of 2 otherwise.
+ */
int security_process_accept(SSL *ssl,int msg) {
int sock = SSL_get_fd(ssl);
int test;
@@ -250,7 +262,7 @@ int security_process_accept(SSL *ssl,int msg) {
debug(D_WEB_CLIENT_ACCESS,"SSL Handshake finished %s errno %d on socket fd %d", ERR_error_string((long)SSL_get_error(ssl, test), NULL), errno, sock);
}
- return 0;
+ return NETDATA_SSL_HANDSHAKE_COMPLETE;
}
int security_test_certificate(SSL *ssl) {
diff --git a/libnetdata/socket/security.h b/libnetdata/socket/security.h
index 8beb9672f2..cc870ce17b 100644
--- a/libnetdata/socket/security.h
+++ b/libnetdata/socket/security.h
@@ -25,7 +25,7 @@
struct netdata_ssl{
SSL *conn; //SSL connection
- int flags;
+ int flags; //The flags for SSL connection
};
extern SSL_CTX *netdata_opentsdb_ctx;
@@ -33,8 +33,6 @@ extern SSL_CTX *netdata_client_ctx;
extern SSL_CTX *netdata_srv_ctx;
extern const char *security_key;
extern const char *security_cert;
-extern int netdata_use_ssl_on_stream;
-extern int netdata_use_ssl_on_http;
extern int netdata_validate_server;
void security_openssl_library();
diff --git a/libnetdata/socket/socket.c b/libnetdata/socket/socket.c
index 2827100815..22abb47f4b 100644
--- a/libnetdata/socket/socket.c
+++ b/libnetdata/socket/socket.c
@@ -301,39 +301,47 @@ void listen_sockets_close(LISTEN_SOCKETS *sockets) {
sockets->failed = 0;
}
-WEB_CLIENT_ACL socket_ssl_acl(char *ssl) {
+/*
+ * SSL ACL
+ *
+ * Search the SSL acl and apply it case it is set.
+ *
+ * @param acl is the acl given by the user.
+ */
+WEB_CLIENT_ACL socket_ssl_acl(char *acl) {
+ char *ssl = strchr(acl,'^');
+ if(ssl) {
+ //Due the format of the SSL command it is always the last command,
+ //we finish it here to avoid problems with the ACLs
+ *ssl = '\0';
#ifdef ENABLE_HTTPS
- if (!strcmp(ssl,"optional")) {
- netdata_use_ssl_on_http = NETDATA_SSL_OPTIONAL;
- return WEB_CLIENT_ACL_DASHBOARD | WEB_CLIENT_ACL_REGISTRY | WEB_CLIENT_ACL_BADGE | WEB_CLIENT_ACL_MGMT | WEB_CLIENT_ACL_NETDATACONF | WEB_CLIENT_ACL_STREAMING;
- }
- else if (!strcmp(ssl,"force")) {
- netdata_use_ssl_on_stream = NETDATA_SSL_FORCE;
- return WEB_CLIENT_ACL_DASHBOARD | WEB_CLIENT_ACL_REGISTRY | WEB_CLIENT_ACL_BADGE | WEB_CLIENT_ACL_MGMT | WEB_CLIENT_ACL_NETDATACONF | WEB_CLIENT_ACL_STREAMING;
- }
+ ssl++;
+ if (!strncmp("SSL=",ssl,4)) {
+ ssl += 4;
+ if (!strcmp(ssl,"optional")) {
+ return WEB_CLIENT_ACL_SSL_OPTIONAL;
+ }
+ else if (!strcmp(ssl,"force")) {
+ return WEB_CLIENT_ACL_SSL_FORCE;
+ }
+ }
#endif
+ }
return WEB_CLIENT_ACL_NONE;
}
WEB_CLIENT_ACL read_acl(char *st) {
- char *ssl = strchr(st,'^');
- if (ssl) {
- ssl++;
- if (!strncmp("SSL=",ssl,4)) {
- ssl += 4;
- }
- socket_ssl_acl(ssl);
- }
+ WEB_CLIENT_ACL ret = socket_ssl_acl(st);
- if (!strcmp(st,"dashboard")) return WEB_CLIENT_ACL_DASHBOARD;
- if (!strcmp(st,"registry")) return WEB_CLIENT_ACL_REGISTRY;
- if (!strcmp(st,"badges")) return WEB_CLIENT_ACL_BADGE;
- if (!strcmp(st,"management")) return WEB_CLIENT_ACL_MGMT;
- if (!strcmp(st,"streaming")) return WEB_CLIENT_ACL_STREAMING;
- if (!strcmp(st,"netdata.conf")) return WEB_CLIENT_ACL_NETDATACONF;
+ if (!strcmp(st,"dashboard")) ret |= WEB_CLIENT_ACL_DASHBOARD;
+ if (!strcmp(st,"registry")) ret |= WEB_CLIENT_ACL_REGISTRY;
+ if (!strcmp(st,"badges")) ret |= WEB_CLIENT_ACL_BADGE;
+ if (!strcmp(st,"management")) ret |= WEB_CLIENT_ACL_MGMT;
+ if (!strcmp(st,"streaming")) ret |= WEB_CLIENT_ACL_STREAMING;
+ if (!strcmp(st,"netdata.conf")) ret |= WEB_CLIENT_ACL_NETDATACONF;
- return socket_ssl_acl(st);
+ return ret;
}
static inline int bind_to_this(LISTEN_SOCKETS *sockets, const char *definition, uint16_t default_port, int listen_backlog) {
@@ -375,7 +383,7 @@ static inline int bind_to_this(LISTEN_SOCKETS *sockets, const char *definition,
error("LISTENER: Cannot create unix socket '%s'", path);
sockets->failed++;
} else {
- acl_flags = WEB_CLIENT_ACL_DASHBOARD | WEB_CLIENT_ACL_REGISTRY | WEB_CLIENT_ACL_BADGE | WEB_CLIENT_ACL_MGMT | WEB_CLIENT_ACL_NETDATACONF | WEB_CLIENT_ACL_STREAMING;
+ acl_flags = WEB_CLIENT_ACL_DASHBOARD | WEB_CLIENT_ACL_REGISTRY | WEB_CLIENT_ACL_BADGE | WEB_CLIENT_ACL_MGMT | WEB_CLIENT_ACL_NETDATACONF | WEB_CLIENT_ACL_STREAMING | WEB_CLIENT_ACL_SSL_DEFAULT;
listen_sockets_add(sockets, fd, AF_UNIX, socktype, protocol_str, path, 0, acl_flags);
added++;
}
@@ -425,7 +433,13 @@ static inline int bind_to_this(LISTEN_SOCKETS *sockets, const char *definition,
}
acl_flags |= read_acl(portconfig);
} else {
- acl_flags = WEB_CLIENT_ACL_DASHBOARD | WEB_CLIENT_ACL_REGISTRY | WEB_CLIENT_ACL_BADGE | WEB_CLIENT_ACL_MGMT | WEB_CLIENT_ACL_NETDATACONF | WEB_CLIENT_ACL_STREAMING;
+ acl_flags = WEB_CLIENT_ACL_DASHBOARD | WEB_CLIENT_ACL_REGISTRY | WEB_CLIENT_ACL_BADGE | WEB_CLIENT_ACL_MGMT | WEB_CLIENT_ACL_NETDATACONF | WEB_CLIENT_ACL_STREAMING | WEB_CLIENT_ACL_SSL_DEFAULT;
+ }
+
+ //Case the user does not set the option SSL in the "bind to", but he has
+ //the certificates, I must redirect, so I am assuming here the default option
+ if(!(acl_flags & WEB_CLIENT_ACL_SSL_OPTIONAL) && !(acl_flags & WEB_CLIENT_ACL_SSL_FORCE)) {
+ acl_flags |= WEB_CLIENT_ACL_SSL_DEFAULT;
}
uint32_t scope_id = 0;
diff --git a/libnetdata/socket/socket.h b/libnetdata/socket/socket.h
index 9ea83bcc0f..76b15def52 100644
--- a/libnetdata/socket/socket.h
+++ b/libnetdata/socket/socket.h
@@ -17,7 +17,10 @@ typedef enum web_client_acl {
WEB_CLIENT_ACL_BADGE = 1 << 2,
WEB_CLIENT_ACL_MGMT = 1 << 3,
WEB_CLIENT_ACL_STREAMING = 1 << 4,
- WEB_CLIENT_ACL_NETDATACONF = 1 << 5
+ WEB_CLIENT_ACL_NETDATACONF = 1 << 5,
+ WEB_CLIENT_ACL_SSL_OPTIONAL = 1 << 6,
+ WEB_CLIENT_ACL_SSL_FORCE = 1 << 7,
+ WEB_CLIENT_ACL_SSL_DEFAULT = 1 << 8
} WEB_CLIENT_ACL;
#define web_client_can_access_dashboard(w) ((w)->acl & WEB_CLIENT_ACL_DASHBOARD)
@@ -26,6 +29,9 @@ typedef enum web_client_acl {
#define web_client_can_access_mgmt(w) ((w)->acl & WEB_CLIENT_ACL_MGMT)
#define web_client_can_access_stream(w) ((w)->acl & WEB_CLIENT_ACL_STREAMING)
#define web_client_can_access_netdataconf(w) ((w)->acl & WEB_CLIENT_ACL_NETDATACONF)
+#define web_client_is_using_ssl_optional(w) ((w)->port_acl & WEB_CLIENT_ACL_SSL_OPTIONAL)
+#define web_client_is_using_ssl_force(w) ((w)->port_acl & WEB_CLIENT_ACL_SSL_FORCE)
+#define web_client_is_using_ssl_default(w) ((w)->port_acl & WEB_CLIENT_ACL_SSL_DEFAULT)
typedef struct listen_sockets {
struct config *config; // the config file to use