diff options
author | thiagoftsm <thiagoftsm@gmail.com> | 2019-07-25 16:43:04 +0000 |
---|---|---|
committer | Chris Akritidis <43294513+cakrit@users.noreply.github.com> | 2019-07-25 18:43:04 +0200 |
commit | 2f7962c9e154dcce1684f2275387c9b6ac4d0b4c (patch) | |
tree | 10a3f5d7451d429a1bd8df91176b04cd82551abb /libnetdata | |
parent | d95912af0834c45fa8a4aee2892b97fbd2e9b520 (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.c | 18 | ||||
-rw-r--r-- | libnetdata/socket/security.h | 4 | ||||
-rw-r--r-- | libnetdata/socket/socket.c | 66 | ||||
-rw-r--r-- | libnetdata/socket/socket.h | 8 |
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 |