/* ** Copyright (C) 2001-2025 Zabbix SIA ** ** This program is free software: you can redistribute it and/or modify it under the terms of ** the GNU Affero General Public License as published by the Free Software Foundation, version 3. ** ** This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ** without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ** See the GNU Affero General Public License for more details. ** ** You should have received a copy of the GNU Affero General Public License along with this program. ** If not, see <https://www.gnu.org/licenses/>. **/ #include "trapper_history_push.h" #include "trapper_server.h" #include "../proxyconfigread/proxyconfigread.h" #include "proxydata.h" #include "../reporter/reporter.h" #include "zbxtrapper.h" #include "zbxdbhigh.h" #include "zbxalerter.h" #include "zbxipcservice.h" #include "zbxcommshigh.h" #include "zbxnum.h" static void trapper_process_report_test(zbx_socket_t *sock, const struct zbx_json_parse *jp, int config_timeout, zbx_get_config_forks_f get_config_forks) { zbx_user_t user; struct zbx_json_parse jp_data; struct zbx_json j; if (0 == get_config_forks(ZBX_PROCESS_TYPE_REPORTMANAGER)) { zbx_send_response(sock, FAIL, "Report manager is disabled.", config_timeout); return; } zbx_user_init(&user); if (FAIL == zbx_get_user_from_json(jp, &user, NULL)) { zbx_send_response(sock, FAIL, "Permission denied.", config_timeout); goto out; } if (SUCCEED != zbx_json_brackets_by_name(jp, ZBX_PROTO_TAG_DATA, &jp_data)) { char *error; error = zbx_dsprintf(NULL, "cannot find tag: %s", ZBX_PROTO_TAG_DATA); zbx_send_response(sock, FAIL, error, config_timeout); zbx_free(error); goto out; } zbx_report_test(&jp_data, user.userid, &j); zbx_tcp_send_bytes_to(sock, j.buffer, j.buffer_size, config_timeout); zbx_json_clean(&j); out: zbx_user_free(&user); } /****************************************************************************** * * * Purpose: processes alert send request that is used to test media types * * * * Parameters: sock - [IN] request socket * * jp - [IN] request data * * config_timeout - [IN] * * * ******************************************************************************/ static void trapper_process_alert_send(zbx_socket_t *sock, const struct zbx_json_parse *jp, int config_timeout) { zbx_db_result_t result; zbx_db_row_t row; int ret = FAIL, errcode; char tmp[ZBX_MAX_UINT64_LEN + 1], *sendto = NULL, *subject = NULL, *message = NULL, *error = NULL, *params = NULL, *value = NULL, *debug = NULL; zbx_uint64_t mediatypeid; size_t string_alloc; struct zbx_json json; struct zbx_json_parse jp_data, jp_params; unsigned char *data = NULL, smtp_security, smtp_verify_peer, smtp_verify_host, smtp_authentication, message_format, *response = NULL; zbx_uint32_t size; zbx_user_t user; unsigned short smtp_port; unsigned char type; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__); zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN); zbx_user_init(&user); if (FAIL == zbx_get_user_from_json(jp, &user, NULL) || USER_TYPE_SUPER_ADMIN > user.type) { error = zbx_strdup(NULL, "Permission denied."); goto fail; } if (SUCCEED != zbx_json_brackets_by_name(jp, ZBX_PROTO_TAG_DATA, &jp_data)) { error = zbx_dsprintf(NULL, "Cannot parse request tag: %s.", ZBX_PROTO_TAG_DATA); goto fail; } if (SUCCEED != zbx_json_value_by_name(&jp_data, ZBX_PROTO_TAG_MEDIATYPEID, tmp, sizeof(tmp), NULL) || SUCCEED != zbx_is_uint64(tmp, &mediatypeid)) { error = zbx_dsprintf(NULL, "Cannot parse request tag: %s.", ZBX_PROTO_TAG_MEDIATYPEID); goto fail; } string_alloc = 0; if (SUCCEED == zbx_json_value_by_name_dyn(&jp_data, ZBX_PROTO_TAG_SENDTO, &sendto, &string_alloc, NULL)) { zbx_replace_invalid_utf8(sendto); string_alloc = 0; } if (SUCCEED == zbx_json_value_by_name_dyn(&jp_data, ZBX_PROTO_TAG_SUBJECT, &subject, &string_alloc, NULL)) { zbx_replace_invalid_utf8(subject); string_alloc = 0; } if (SUCCEED == zbx_json_value_by_name_dyn(&jp_data, ZBX_PROTO_TAG_MESSAGE, &message, &string_alloc, NULL)) { zbx_replace_invalid_utf8(message); string_alloc = 0; } if (SUCCEED == zbx_json_brackets_by_name(&jp_data, ZBX_PROTO_TAG_PARAMETERS, &jp_params)) { size_t string_offset = 0; zbx_strncpy_alloc(¶ms, &string_alloc, &string_offset, jp_params.start, (size_t)(jp_params.end - jp_params.start + 1)); zbx_replace_invalid_utf8(params); } result = zbx_db_select( "select type,smtp_server,smtp_helo,smtp_email,exec_path,gsm_modem,username,passwd,smtp_port" ",smtp_security,smtp_verify_peer,smtp_verify_host,smtp_authentication,maxsessions" ",maxattempts,attempt_interval,message_format,script,timeout" " from media_type" " where mediatypeid=" ZBX_FS_UI64, mediatypeid); if (NULL == (row = zbx_db_fetch(result))) { zbx_db_free_result(result); error = zbx_dsprintf(NULL, "Cannot find the specified media type."); goto fail; } if (FAIL == zbx_is_ushort(row[8], &smtp_port)) { zbx_db_free_result(result); error = zbx_dsprintf(NULL, "Invalid port value."); goto fail; } ZBX_STR2UCHAR(smtp_security, row[9]); ZBX_STR2UCHAR(smtp_verify_peer, row[10]); ZBX_STR2UCHAR(smtp_verify_host, row[11]); ZBX_STR2UCHAR(smtp_authentication, row[12]); ZBX_STR2UCHAR(message_format, row[16]); ZBX_STR2UCHAR(type, row[0]); size = zbx_alerter_serialize_alert_send(&data, mediatypeid, type, row[1], row[2], row[3], row[4], row[5], row[6], row[7], smtp_port, smtp_security, smtp_verify_peer, smtp_verify_host, smtp_authentication, atoi(row[13]), atoi(row[14]), row[15], message_format, row[17], row[18], sendto, subject, message, params); zbx_db_free_result(result); if (SUCCEED != zbx_ipc_async_exchange(ZBX_IPC_SERVICE_ALERTER, zbx_alerter_send_alert_code(), SEC_PER_MIN, data, size, &response, &error)) { goto fail; } zbx_free(sendto); zbx_alerter_deserialize_result_ext(response, &sendto, &value, &errcode, &error, &debug); zbx_free(response); if (SUCCEED == errcode) ret = SUCCEED; fail: zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, SUCCEED == ret ? ZBX_PROTO_VALUE_SUCCESS : ZBX_PROTO_VALUE_FAILED, ZBX_JSON_TYPE_STRING); if (SUCCEED == ret) { if (NULL != value) zbx_json_addstring(&json, ZBX_PROTO_TAG_DATA, value, ZBX_JSON_TYPE_STRING); } else { if (NULL != error && '\0' != *error) zbx_json_addstring(&json, ZBX_PROTO_TAG_INFO, error, ZBX_JSON_TYPE_STRING); } if (NULL != debug) zbx_json_addraw(&json, "debug", debug); (void)zbx_tcp_send_to(sock, json.buffer, config_timeout); zbx_free(params); zbx_free(message); zbx_free(subject); zbx_free(sendto); zbx_free(data); zbx_free(value); zbx_free(error); zbx_free(debug); zbx_json_free(&json); zbx_user_free(&user); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret)); } int zbx_trapper_process_request_server(const char *request, zbx_socket_t *sock, const struct zbx_json_parse *jp, const zbx_timespec_t *ts, const zbx_config_comms_args_t *config_comms, const zbx_config_vault_t *config_vault, int proxydata_frequency, zbx_get_program_type_f get_program_type_cb, const zbx_events_funcs_t *events_cbs, zbx_get_config_forks_f get_config_forks) { ZBX_UNUSED(get_program_type_cb); if (0 == strcmp(request, ZBX_PROTO_VALUE_REPORT_TEST)) { trapper_process_report_test(sock, jp, config_comms->config_timeout, get_config_forks); return SUCCEED; } else if (0 == strcmp(request, ZBX_PROTO_VALUE_ZABBIX_ALERT_SEND)) { trapper_process_alert_send(sock, jp, config_comms->config_timeout); return SUCCEED; } else if (0 == strcmp(request, ZBX_PROTO_VALUE_PROXY_CONFIG)) { zbx_send_proxyconfig(sock, jp, config_vault, config_comms->config_timeout, config_comms->config_trapper_timeout, config_comms->config_source_ip, config_comms->config_ssl_ca_location, config_comms->config_ssl_cert_location, config_comms->config_ssl_key_location); return SUCCEED; } else if (0 == strcmp(request, ZBX_PROTO_VALUE_PROXY_DATA)) { recv_proxy_data(sock, jp, ts, events_cbs, config_comms->config_timeout, proxydata_frequency); return SUCCEED; } else if (0 == strcmp(request, ZBX_PROTO_VALUE_HISTORY_PUSH)) { trapper_process_history_push(sock, jp, config_comms->config_timeout); return SUCCEED; } return FAIL; }