Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/zabbix/zabbix.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndris Zeila <andris.zeila@zabbix.com>2021-03-12 13:02:40 +0300
committerAndris Zeila <andris.zeila@zabbix.com>2021-03-12 13:02:40 +0300
commit65a6c53b003bef831288145a59dd75c07dbf0dbd (patch)
tree97e2375ec574c25d2070dac74b3a22f15a56254e /src/libs/zbxembed
parent5ef309d8a24243f6f03fc64f63d61aa5ef6e4661 (diff)
parent671768fb49c5198a6cf174c41f0243d4574610fc (diff)
.......... [ZBXNEXT-6451] merged branch 'master' of ssh://git.zabbix.lan:7999/zbx/zabbix into feature/ZBXNEXT-6451-5.3
Diffstat (limited to 'src/libs/zbxembed')
-rw-r--r--src/libs/zbxembed/embed.c136
-rw-r--r--src/libs/zbxembed/global.c90
-rw-r--r--src/libs/zbxembed/httprequest.c89
3 files changed, 292 insertions, 23 deletions
diff --git a/src/libs/zbxembed/embed.c b/src/libs/zbxembed/embed.c
index 31e9da774d3..c2d6b5ebbb3 100644
--- a/src/libs/zbxembed/embed.c
+++ b/src/libs/zbxembed/embed.c
@@ -27,7 +27,7 @@
#include "xml.h"
#include "embed.h"
-#define ZBX_ES_MEMORY_LIMIT (1024 * 1024 * 10)
+#define ZBX_ES_MEMORY_LIMIT (1024 * 1024 * 64)
#define ZBX_ES_TIMEOUT 10
#define ZBX_ES_STACK_LIMIT 1000
@@ -418,13 +418,13 @@ out:
* *
* Purpose: executes script *
* *
- * Parameters: es - [IN] the embedded scripting engine *
- * script - [IN] the script to execute *
- * code - [IN] the precompiled bytecode *
- * size - [IN] the size of precompiled bytecode *
- * param - [IN] the parameter to pass to the script *
- * output - [OUT] the result value *
- * error - [OUT] the error message *
+ * Parameters: es - [IN] the embedded scripting engine *
+ * script - [IN] the script to execute *
+ * code - [IN] the precompiled bytecode *
+ * size - [IN] the size of precompiled bytecode *
+ * param - [IN] the parameter to pass to the script *
+ * script_ret - [OUT] the result value *
+ * error - [OUT] the error message *
* *
* Return value: SUCCEED *
* FAIL *
@@ -435,7 +435,7 @@ out:
* bytecode parameters. *
* *
******************************************************************************/
-int zbx_es_execute(zbx_es_t *es, const char *script, const char *code, int size, const char *param, char **output,
+int zbx_es_execute(zbx_es_t *es, const char *script, const char *code, int size, const char *param, char **script_ret,
char **error)
{
void *buffer;
@@ -495,24 +495,45 @@ int zbx_es_execute(zbx_es_t *es, const char *script, const char *code, int size,
goto out;
}
- if (0 == duk_check_type(es->env->ctx, -1, DUK_TYPE_UNDEFINED))
+ if (NULL != script_ret || SUCCEED == ZBX_CHECK_LOG_LEVEL(LOG_LEVEL_DEBUG))
{
- if (0 != duk_check_type(es->env->ctx, -1, DUK_TYPE_NULL))
+ if (0 == duk_check_type(es->env->ctx, -1, DUK_TYPE_UNDEFINED))
{
- ret = SUCCEED;
- *output = NULL;
- zabbix_log(LOG_LEVEL_DEBUG, "%s() output: null", __func__);
+ if (0 != duk_check_type(es->env->ctx, -1, DUK_TYPE_NULL))
+ {
+ ret = SUCCEED;
+
+ if (NULL != script_ret)
+ *script_ret = NULL;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "%s() output: null", __func__);
+ }
+ else
+ {
+ char *output = NULL;
+
+ if (SUCCEED != (ret = zbx_cesu8_to_utf8(duk_safe_to_string(es->env->ctx, -1), &output)))
+ *error = zbx_strdup(*error, "could not convert return value to utf8");
+ else
+ zabbix_log(LOG_LEVEL_DEBUG, "%s() output:'%s'", __func__, output);
+
+ if (SUCCEED == ret && NULL != script_ret)
+ *script_ret = output;
+ else
+ zbx_free(output);
+ }
}
else
{
- if (SUCCEED != (ret = zbx_cesu8_to_utf8(duk_safe_to_string(es->env->ctx, -1), output)))
- *error = zbx_strdup(*error, "could not convert return value to utf8");
+ if (NULL == script_ret)
+ {
+ zabbix_log(LOG_LEVEL_DEBUG, "%s(): undefined return value", __func__);
+ ret = SUCCEED;
+ }
else
- zabbix_log(LOG_LEVEL_DEBUG, "%s() output:'%s'", __func__, *output);
+ *error = zbx_strdup(*error, "undefined return value");
}
}
- else
- *error = zbx_strdup(*error, "undefined return value");
duk_pop(es->env->ctx);
es->env->rt_error_num = 0;
@@ -531,7 +552,7 @@ out:
/******************************************************************************
* *
* Function: zbx_es_set_timeout *
- * es_init_global_functions *
+ * *
* Purpose: sets script execution timeout *
* *
* Parameters: es - [IN] the embedded scripting engine *
@@ -568,3 +589,78 @@ void zbx_es_debug_disable(zbx_es_t *es)
zbx_json_free(es->env->json);
zbx_free(es->env->json);
}
+
+/******************************************************************************
+ * *
+ * Function: zbx_es_execute_command *
+ * *
+ * Purpose: executes command (script in form of a text) *
+ * *
+ * Parameters: command - [IN] the command in form of a text *
+ * param - [IN] the script parameters *
+ * timeout - [IN] the timeout for the execution (seconds) *
+ * result - [OUT] the result of an execution *
+ * error - [OUT] the error message *
+ * max_error_len - [IN] the maximum length of an error *
+ * debug - [OUT] the debug data (optional) *
+ * *
+ * Return value: SUCCEED *
+ * FAIL *
+ * *
+ ******************************************************************************/
+int zbx_es_execute_command(const char *command, const char *param, int timeout, char **result,
+ char *error, size_t max_error_len, char **debug)
+{
+ int size, ret = SUCCEED;
+ char *code = NULL, *errmsg = NULL;
+ zbx_es_t es;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
+
+ zbx_es_init(&es);
+ if (FAIL == zbx_es_init_env(&es, &errmsg))
+ {
+ zbx_snprintf(error, max_error_len, "cannot initialize scripting environment: %s", errmsg);
+ zbx_free(errmsg);
+ ret = FAIL;
+ goto failure;
+ }
+
+ if (NULL != debug)
+ zbx_es_debug_enable(&es);
+
+ if (FAIL == zbx_es_compile(&es, command, &code, &size, &errmsg))
+ {
+ zbx_snprintf(error, max_error_len, "cannot compile script: %s", errmsg);
+ zbx_free(errmsg);
+ ret = FAIL;
+ goto out;
+ }
+
+ if (0 != timeout)
+ zbx_es_set_timeout(&es, timeout);
+
+ if (FAIL == zbx_es_execute(&es, NULL, code, size, param, result, &errmsg))
+ {
+ zbx_snprintf(error, max_error_len, "cannot execute script: %s", errmsg);
+ zbx_free(errmsg);
+ ret = FAIL;
+ goto out;
+ }
+out:
+ if (NULL != debug)
+ *debug = zbx_strdup(NULL, zbx_es_debug_info(&es));
+
+ if (FAIL == zbx_es_destroy_env(&es, &errmsg))
+ {
+ zabbix_log(LOG_LEVEL_WARNING, "cannot destroy embedded scripting engine environment: %s", errmsg);
+ zbx_free(errmsg);
+ }
+
+ zbx_free(code);
+ zbx_free(errmsg);
+failure:
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret));
+
+ return ret;
+}
diff --git a/src/libs/zbxembed/global.c b/src/libs/zbxembed/global.c
index b84c3a38bef..58649e18e0f 100644
--- a/src/libs/zbxembed/global.c
+++ b/src/libs/zbxembed/global.c
@@ -23,6 +23,7 @@
#include "global.h"
#include "duktape.h"
#include "base64.h"
+#include "sha256crypt.h"
/******************************************************************************
* *
@@ -83,6 +84,89 @@ static duk_ret_t es_atob(duk_context *ctx)
/******************************************************************************
* *
+ * Function: es_md5 *
+ * *
+ * Purpose: compute a md5 checksum *
+ * *
+ * Parameters: ctx - [IN] pointer to duk_context *
+ * *
+ * Comments: Throws an error: *
+ * - if the top value at ctx value stack is not a string *
+ * - if the value stack is empty *
+ * *
+ ******************************************************************************/
+static duk_ret_t es_md5(duk_context *ctx)
+{
+ const char *hex = "0123456789abcdef";
+ md5_state_t state;
+ md5_byte_t hash[MD5_DIGEST_SIZE];
+ int i;
+ char *str = NULL, *md5sum, *ptr;
+
+ if (SUCCEED != zbx_cesu8_to_utf8(duk_require_string(ctx, 0), &str))
+ return duk_error(ctx, DUK_RET_TYPE_ERROR, "cannot convert value to utf8");
+
+ ptr = md5sum = (char *)zbx_malloc(NULL, MD5_DIGEST_SIZE * 2 + 1);
+
+ zbx_md5_init(&state);
+ zbx_md5_append(&state, (const md5_byte_t *)str, strlen(str));
+ zbx_md5_finish(&state, hash);
+
+ for (i = 0; i < MD5_DIGEST_SIZE; i++)
+ {
+ *ptr++ = hex[hash[i] >> 4];
+ *ptr++ = hex[hash[i] & 15];
+ }
+
+ *ptr = '\0';
+
+ duk_push_string(ctx, md5sum);
+ zbx_free(str);
+ zbx_free(md5sum);
+ return 1;
+}
+
+/******************************************************************************
+ * *
+ * Function: es_sha256 *
+ * *
+ * Purpose: compute a sha256 checksum *
+ * *
+ * Parameters: ctx - [IN] pointer to duk_context *
+ * *
+ * Comments: Throws an error: *
+ * - if the top value at ctx value stack is not a string *
+ * - if the value stack is empty *
+ * *
+ ******************************************************************************/
+static duk_ret_t es_sha256(duk_context *ctx)
+{
+ char *str = NULL, hash_res[ZBX_SHA256_DIGEST_SIZE], hash_res_stringhexes[ZBX_SHA256_DIGEST_SIZE * 2 + 1];
+ int i;
+
+ if (SUCCEED != zbx_cesu8_to_utf8(duk_require_string(ctx, 0), &str))
+ return duk_error(ctx, DUK_RET_TYPE_ERROR, "cannot convert value to utf8");
+
+ zbx_sha256_hash(str, hash_res);
+
+ for (i = 0 ; i < ZBX_SHA256_DIGEST_SIZE; i++)
+ {
+ char z[3];
+
+ zbx_snprintf(z, 3, "%02x", (unsigned char)hash_res[i]);
+ hash_res_stringhexes[i * 2] = z[0];
+ hash_res_stringhexes[i * 2 + 1] = z[1];
+ }
+
+ hash_res_stringhexes[ZBX_SHA256_DIGEST_SIZE * 2] = '\0';
+
+ duk_push_string(ctx, hash_res_stringhexes);
+ zbx_free(str);
+ return 1;
+}
+
+/******************************************************************************
+ * *
* Function: es_init_global_functions *
* *
* Purpose: initializes additional global functions *
@@ -97,4 +181,10 @@ void es_init_global_functions(zbx_es_t *es)
duk_push_c_function(es->env->ctx, es_btoa, 1);
duk_put_global_string(es->env->ctx, "btoa");
+
+ duk_push_c_function(es->env->ctx, es_md5, 1);
+ duk_put_global_string(es->env->ctx, "md5");
+
+ duk_push_c_function(es->env->ctx, es_sha256, 1);
+ duk_put_global_string(es->env->ctx, "sha256");
}
diff --git a/src/libs/zbxembed/httprequest.c b/src/libs/zbxembed/httprequest.c
index 41598a5aac8..8ad63a2750a 100644
--- a/src/libs/zbxembed/httprequest.c
+++ b/src/libs/zbxembed/httprequest.c
@@ -28,6 +28,16 @@
#ifdef HAVE_LIBCURL
+#define ZBX_HTTPAUTH_NONE CURLAUTH_NONE
+#define ZBX_HTTPAUTH_BASIC CURLAUTH_BASIC
+#define ZBX_HTTPAUTH_DIGEST CURLAUTH_DIGEST
+#if LIBCURL_VERSION_NUM >= 0x072600
+# define ZBX_HTTPAUTH_NEGOTIATE CURLAUTH_NEGOTIATE
+#else
+# define ZBX_HTTPAUTH_NEGOTIATE CURLAUTH_GSSNEGOTIATE
+#endif
+#define ZBX_HTTPAUTH_NTLM CURLAUTH_NTLM
+
extern char *CONFIG_SOURCE_IP;
typedef struct
@@ -320,8 +330,6 @@ static duk_ret_t es_httprequest_query(duk_context *ctx, const char *http_request
curl_easy_strerror(err));
goto out;
}
-
- duk_push_string(ctx, request->data);
out:
zbx_free(url);
zbx_free(contents);
@@ -329,6 +337,8 @@ out:
if (-1 != err_index)
return duk_throw(ctx);
+ duk_push_string(ctx, request->data);
+
return 1;
}
@@ -401,7 +411,7 @@ out:
if (-1 != err_index)
return duk_throw(ctx);
- return 1;
+ return 0;
}
/******************************************************************************
@@ -486,6 +496,64 @@ static duk_ret_t es_httprequest_get_headers(duk_context *ctx)
return 1;
}
+/******************************************************************************
+ * *
+ * Function: es_httprequest_set_httpauth *
+ * *
+ * Purpose: CurlHttpRequest.SetHttpAuth method *
+ * *
+ ******************************************************************************/
+static duk_ret_t es_httprequest_set_httpauth(duk_context *ctx)
+{
+ zbx_es_httprequest_t *request;
+ char *username = NULL, *password = NULL;
+ int err_index = -1, mask;
+ CURLcode err;
+
+ if (NULL == (request = es_httprequest(ctx)))
+ return duk_error(ctx, DUK_RET_EVAL_ERROR, "internal scripting error: null object");
+
+ mask = duk_to_int32(ctx, 0);
+
+ if (0 != (mask & ~(ZBX_HTTPAUTH_BASIC | ZBX_HTTPAUTH_DIGEST | ZBX_HTTPAUTH_NEGOTIATE | ZBX_HTTPAUTH_NTLM)))
+ return duk_error(ctx, DUK_RET_EVAL_ERROR, "invalid HTTP authentication mask");
+
+ if (0 == duk_is_null_or_undefined(ctx, 1))
+ {
+ if (SUCCEED != zbx_cesu8_to_utf8(duk_to_string(ctx, 1), &username))
+ {
+ err_index = duk_push_error_object(ctx, DUK_RET_TYPE_ERROR, "cannot convert username to utf8");
+ goto out;
+ }
+ }
+
+ if (0 == duk_is_null_or_undefined(ctx, 2))
+ {
+ if (SUCCEED != zbx_cesu8_to_utf8(duk_to_string(ctx, 2), &password))
+ {
+ err_index = duk_push_error_object(ctx, DUK_RET_TYPE_ERROR, "cannot convert username to utf8");
+ goto out;
+ }
+ }
+
+ ZBX_CURL_SETOPT(ctx, request->handle, CURLOPT_HTTPAUTH, mask, err);
+
+ if (NULL != username)
+ ZBX_CURL_SETOPT(ctx, request->handle, CURLOPT_USERNAME, username, err);
+
+ if (NULL != password)
+ ZBX_CURL_SETOPT(ctx, request->handle, CURLOPT_PASSWORD, password, err);
+
+out:
+ zbx_free(password);
+ zbx_free(username);
+
+ if (-1 != err_index)
+ return duk_throw(ctx);
+
+ return 0;
+}
+
static const duk_function_list_entry curlhttprequest_methods[] = {
{"AddHeader", es_httprequest_add_header, 1},
{"ClearHeader", es_httprequest_clear_header, 0},
@@ -496,6 +564,7 @@ static const duk_function_list_entry curlhttprequest_methods[] = {
{"Status", es_httprequest_status, 0},
{"SetProxy", es_httprequest_set_proxy, 1},
{"GetHeaders", es_httprequest_get_headers, 0},
+ {"SetHttpAuth", es_httprequest_set_httpauth, 3},
{NULL, NULL, 0}
};
@@ -509,6 +578,7 @@ static const duk_function_list_entry httprequest_methods[] = {
{"getStatus", es_httprequest_status, 0},
{"setProxy", es_httprequest_set_proxy, 1},
{"getHeaders", es_httprequest_get_headers, 0},
+ {"setHttpAuth", es_httprequest_set_httpauth, 3},
{NULL, NULL, 0}
};
@@ -562,5 +632,18 @@ int zbx_es_init_httprequest(zbx_es_t *es, char **error)
return FAIL;
}
+#ifdef HAVE_LIBCURL
+ duk_push_number(es->env->ctx, ZBX_HTTPAUTH_NONE);
+ duk_put_global_string(es->env->ctx, "HTTPAUTH_NONE");
+ duk_push_number(es->env->ctx, ZBX_HTTPAUTH_BASIC);
+ duk_put_global_string(es->env->ctx, "HTTPAUTH_BASIC");
+ duk_push_number(es->env->ctx, ZBX_HTTPAUTH_DIGEST);
+ duk_put_global_string(es->env->ctx, "HTTPAUTH_DIGEST");
+ duk_push_number(es->env->ctx, ZBX_HTTPAUTH_NEGOTIATE);
+ duk_put_global_string(es->env->ctx, "HTTPAUTH_NEGOTIATE");
+ duk_push_number(es->env->ctx, ZBX_HTTPAUTH_NTLM);
+ duk_put_global_string(es->env->ctx, "HTTPAUTH_NTLM");
+#endif
+
return SUCCEED;
}