summaryrefslogtreecommitdiffstats
path: root/collectors/plugins.d
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 /collectors/plugins.d
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 'collectors/plugins.d')
-rw-r--r--collectors/plugins.d/plugins_d.c132
-rw-r--r--collectors/plugins.d/plugins_d.h1
2 files changed, 132 insertions, 1 deletions
diff --git a/collectors/plugins.d/plugins_d.c b/collectors/plugins.d/plugins_d.c
index d333ae2413..0c6010103c 100644
--- a/collectors/plugins.d/plugins_d.c
+++ b/collectors/plugins.d/plugins_d.c
@@ -117,6 +117,103 @@ inline int pluginsd_split_words(char *str, char **words, int max_words) {
return quoted_strings_splitter(str, words, max_words, pluginsd_space);
}
+#ifdef ENABLE_HTTPS
+/**
+ * Update Buffer
+ *
+ * Update the temporary buffer used to parse data received from slave
+ *
+ * @param output is a pointer to the vector where I will store the data
+ * @param ssl is the connection pointer with the server
+ *
+ * @return it returns the total of bytes read on success and a negative number otherwise
+ */
+int pluginsd_update_buffer(char *output, SSL *ssl) {
+ ERR_clear_error();
+ int bytesleft = SSL_read(ssl, output, PLUGINSD_LINE_MAX_SSL_READ);
+ if(bytesleft <= 0) {
+ int sslerrno = SSL_get_error(ssl, bytesleft);
+ switch(sslerrno) {
+ case SSL_ERROR_WANT_READ:
+ case SSL_ERROR_WANT_WRITE:
+ {
+ break;
+ }
+ default:
+ {
+ u_long err;
+ char buf[256];
+ int counter = 0;
+ while ((err = ERR_get_error()) != 0) {
+ ERR_error_string_n(err, buf, sizeof(buf));
+ info("%d SSL Handshake error (%s) on socket %d ", counter++, ERR_error_string((long)SSL_get_error(ssl, bytesleft), NULL), SSL_get_fd(ssl));
+ }
+ }
+
+ }
+ } else {
+ output[bytesleft] = '\0';
+ }
+
+ return bytesleft;
+}
+
+/**
+ * Get from Buffer
+ *
+ * Get data to process from buffer
+ *
+ * @param output is the output vector that will be used to parse the string.
+ * @param bytesread the amount of bytes read in the previous iteration.
+ * @param input the input vector where there are data to process
+ * @param ssl a pointer to the connection with the server
+ * @param src the first address of the input, because sometime will be necessary to restart the addr with it.
+ *
+ * @return It returns a pointer for the next iteration on success and NULL otherwise.
+ */
+char * pluginsd_get_from_buffer(char *output, int *bytesread, char *input, SSL *ssl, char *src) {
+ int copying = 1;
+ char *endbuffer;
+ size_t length;
+ while(copying) {
+ if(*bytesread > 0) {
+ endbuffer = strchr(input, '\n');
+ if(endbuffer) {
+ copying = 0;
+ endbuffer++; //Advance due the fact I wanna copy '\n'
+ length = endbuffer - input;
+ *bytesread -= length;
+
+ memcpy(output, input, length);
+ output += length;
+ *output = '\0';
+ input += length;
+ }else {
+ length = strlen(input);
+ memcpy(output, input, length);
+ output += length;
+ input = src;
+
+ *bytesread = pluginsd_update_buffer(input, ssl);
+ if(*bytesread <= 0) {
+ input = NULL;
+ copying = 0;
+ }
+ }
+ }else {
+ //reduce sample of bytes read, print the length
+ *bytesread = pluginsd_update_buffer(input, ssl);
+ if(*bytesread <= 0) {
+ input = NULL;
+ copying = 0;
+ }
+ }
+ }
+
+ return input;
+}
+#endif
+
inline size_t pluginsd_process(RRDHOST *host, struct plugind *cd, FILE *fp, int trust_durations) {
int enabled = cd->enabled;
@@ -149,10 +246,43 @@ inline size_t pluginsd_process(RRDHOST *host, struct plugind *cd, FILE *fp, int
goto cleanup;
}
+#ifdef ENABLE_HTTPS
+ int bytesleft = 0;
+ char tmpbuffer[PLUGINSD_LINE_MAX];
+ char *readfrom;
+#endif
while(!ferror(fp)) {
if(unlikely(netdata_exit)) break;
- char *r = fgets(line, PLUGINSD_LINE_MAX, fp);
+ char *r;
+#ifdef ENABLE_HTTPS
+ int normalread = 1;
+ if(netdata_srv_ctx) {
+ if(host->ssl.conn && !host->ssl.flags) {
+ if(!bytesleft) {
+ r = line;
+ readfrom = tmpbuffer;
+ bytesleft = pluginsd_update_buffer(readfrom, host->ssl.conn);
+ if(bytesleft <= 0) {
+ break;
+ }
+ }
+
+ readfrom = pluginsd_get_from_buffer(line, &bytesleft, readfrom, host->ssl.conn, tmpbuffer);
+ if(!readfrom) {
+ r = NULL;
+ }
+
+ normalread = 0;
+ }
+ }
+
+ if(normalread) {
+ r = fgets(line, PLUGINSD_LINE_MAX, fp);
+ }
+#else
+ r = fgets(line, PLUGINSD_LINE_MAX, fp);
+#endif
if(unlikely(!r)) {
if(feof(fp))
error("read failed: end of file");
diff --git a/collectors/plugins.d/plugins_d.h b/collectors/plugins.d/plugins_d.h
index 04d5de3d32..7d5c7dda47 100644
--- a/collectors/plugins.d/plugins_d.h
+++ b/collectors/plugins.d/plugins_d.h
@@ -31,6 +31,7 @@
#define PLUGINSD_KEYWORD_VARIABLE "VARIABLE"
#define PLUGINSD_LINE_MAX 1024
+#define PLUGINSD_LINE_MAX_SSL_READ 512
#define PLUGINSD_MAX_WORDS 20
#define PLUGINSD_MAX_DIRECTORIES 20