diff options
Diffstat (limited to 'src/libs/zbxsysinfo/simple/simple.c')
-rw-r--r-- | src/libs/zbxsysinfo/simple/simple.c | 117 |
1 files changed, 97 insertions, 20 deletions
diff --git a/src/libs/zbxsysinfo/simple/simple.c b/src/libs/zbxsysinfo/simple/simple.c index 9a095a26de8..2bda3087114 100644 --- a/src/libs/zbxsysinfo/simple/simple.c +++ b/src/libs/zbxsysinfo/simple/simple.c @@ -97,29 +97,59 @@ lbl_ret: } #endif /* HAVE_LDAP */ +/****************************************************************************** + * * + * Function: find_ssh_ident_string * + * * + * Purpose: parse recv_buf for ssh identification string as per * + * RFC 4253, section 4.2 * + * * + * Parameters: recv_buf - [IN] buffer to parse * + * remote_major - [OUT] memory pointer where protocol major is * + * to be written to * + * remote_minor - [OUT] memory pointer where protocol minor is * + * to be written to * + * * + * Returns: SUCCEED - if a string matching the specification is found * + * FAIL - otherwise * + * * + ******************************************************************************/ +static int find_ssh_ident_string(const char *recv_buf, int *remote_major, int *remote_minor) +{ + const char *r, *l = recv_buf; + + while (NULL != (r = strchr(l, '\n'))) + { + if (2 == sscanf(l, "SSH-%d.%d-%*s", remote_major, remote_minor)) + return SUCCEED; + + l = r + 1; + } + + return FAIL; +} + static int check_ssh(const char *host, unsigned short port, int timeout, int *value_int) { int ret; zbx_sock_t s; - char send_buf[MAX_STRING_LEN], *recv_buf, *ssh_server, *ssh_proto; + char send_buf[MAX_STRING_LEN]; + int remote_major, remote_minor; *value_int = 0; if (SUCCEED == (ret = zbx_tcp_connect(&s, CONFIG_SOURCE_IP, host, port, timeout))) { - if (SUCCEED == (ret = zbx_tcp_recv(&s, &recv_buf))) + if (SUCCEED == (ret = zbx_tcp_recv(&s))) { - if (0 == strncmp(recv_buf, "SSH", 3)) + if (SUCCEED == find_ssh_ident_string(s.buffer, &remote_major, &remote_minor)) { - ssh_server = ssh_proto = recv_buf + 4; - ssh_server += strspn(ssh_proto, "0123456789-. "); - ssh_server[-1] = '\0'; - - zbx_snprintf(send_buf, sizeof(send_buf), "SSH-%s-%s\n", ssh_proto, "zabbix_agent"); + zbx_snprintf(send_buf, sizeof(send_buf), "SSH-%d.%d-zabbix_agent\r\n", + remote_major, remote_minor); *value_int = 1; } else - zbx_snprintf(send_buf, sizeof(send_buf), "0\n"); + strscpy(send_buf, "0\n"); ret = zbx_tcp_send_raw(&s, send_buf); } @@ -211,6 +241,47 @@ static int check_telnet(const char *host, unsigned short port, int timeout, int return SYSINFO_RET_OK; } +/* validation functions for service checks */ +static int validate_smtp(const char *line) +{ + if (0 == strncmp(line, "220", 3)) + { + if ('-' == line[3]) + return ZBX_TCP_EXPECT_IGNORE; + + if ('\0' == line[3] || ' ' == line[3]) + return ZBX_TCP_EXPECT_OK; + } + + return ZBX_TCP_EXPECT_FAIL; +} + +static int validate_ftp(const char *line) +{ + if (0 == strncmp(line, "220 ", 4)) + return ZBX_TCP_EXPECT_OK; + + return ZBX_TCP_EXPECT_IGNORE; +} + +static int validate_pop(const char *line) +{ + return 0 == strncmp(line, "+OK", 3) ? ZBX_TCP_EXPECT_OK : ZBX_TCP_EXPECT_FAIL; +} + +static int validate_nntp(const char *line) +{ + if (0 == strncmp(line, "200", 3) || 0 == strncmp(line, "201", 3)) + return ZBX_TCP_EXPECT_OK; + + return ZBX_TCP_EXPECT_FAIL; +} + +static int validate_imap(const char *line) +{ + return 0 == strncmp(line, "* OK", 4) ? ZBX_TCP_EXPECT_OK : ZBX_TCP_EXPECT_FAIL; +} + int check_service(AGENT_REQUEST *request, const char *default_addr, AGENT_RESULT *result, int perf) { unsigned short port = 0; @@ -221,14 +292,20 @@ int check_service(AGENT_REQUEST *request, const char *default_addr, AGENT_RESULT check_time = zbx_time(); if (3 < request->nparam) - return ret; + { + SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters.")); + return SYSINFO_RET_FAIL; + } service = get_rparam(request, 0); ip_str = get_rparam(request, 1); port_str = get_rparam(request, 2); if (NULL == service || '\0' == *service) - return ret; + { + SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter.")); + return SYSINFO_RET_FAIL; + } if (NULL == ip_str || '\0' == *ip_str) strscpy(ip, default_addr); @@ -237,8 +314,8 @@ int check_service(AGENT_REQUEST *request, const char *default_addr, AGENT_RESULT if (NULL != port_str && SUCCEED != is_ushort(port_str, &port)) { - SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Invalid \"port\" parameter")); - return ret; + SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter.")); + return SYSINFO_RET_FAIL; } if (0 == strcmp(service, "ssh")) @@ -265,13 +342,13 @@ int check_service(AGENT_REQUEST *request, const char *default_addr, AGENT_RESULT { if (NULL == port_str || '\0' == *port_str) port = ZBX_DEFAULT_SMTP_PORT; - ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, "220", "QUIT\r\n", &value_int); + ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, validate_smtp, "QUIT\r\n", &value_int); } else if (0 == strcmp(service, "ftp")) { if (NULL == port_str || '\0' == *port_str) port = ZBX_DEFAULT_FTP_PORT; - ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, "220", "QUIT\n", &value_int); + ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, validate_ftp, "QUIT\r\n", &value_int); } else if (0 == strcmp(service, "http")) { @@ -283,26 +360,26 @@ int check_service(AGENT_REQUEST *request, const char *default_addr, AGENT_RESULT { if (NULL == port_str || '\0' == *port_str) port = ZBX_DEFAULT_POP_PORT; - ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, "+OK", "QUIT\n", &value_int); + ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, validate_pop, "QUIT\r\n", &value_int); } else if (0 == strcmp(service, "nntp")) { if (NULL == port_str || '\0' == *port_str) port = ZBX_DEFAULT_NNTP_PORT; - ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, "200", "QUIT\n", &value_int); + ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, validate_nntp, "QUIT\r\n", &value_int); } else if (0 == strcmp(service, "imap")) { if (NULL == port_str || '\0' == *port_str) port = ZBX_DEFAULT_IMAP_PORT; - ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, "* OK", "a1 LOGOUT\n", &value_int); + ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, validate_imap, "a1 LOGOUT\r\n", &value_int); } else if (0 == strcmp(service, "tcp")) { if (NULL == port_str || '\0' == *port_str) { - SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Required \"port\" parameter missing")); - return ret; + SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter.")); + return SYSINFO_RET_FAIL; } ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, NULL, NULL, &value_int); } |