summaryrefslogtreecommitdiffstats
path: root/src/libs
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs')
-rw-r--r--src/libs/zbxcommon/misc.c275
-rw-r--r--src/libs/zbxcomms/comms.c250
-rw-r--r--src/libs/zbxemail/email.c176
3 files changed, 522 insertions, 179 deletions
diff --git a/src/libs/zbxcommon/misc.c b/src/libs/zbxcommon/misc.c
index d0178da4..9f004783 100644
--- a/src/libs/zbxcommon/misc.c
+++ b/src/libs/zbxcommon/misc.c
@@ -233,6 +233,203 @@ int calculate_item_nextcheck(zbx_uint64_t itemid, int item_type, int delay, char
return i;
}
+#if defined(HAVE_IPV6)
+/******************************************************************************
+ * *
+ * Function: expand_ipv6 *
+ * *
+ * Purpose: convert short ipv6 addresses to expanded type *
+ * *
+ * Parameters: ip - IPv6 IPs [12fc::2] *
+ * buf - result value [12fc:0000:0000:0000:0000:0000:0000:0002] *
+ * *
+ * Return value: FAIL - invlid IP address, SUCCEED - conversion OK *
+ * *
+ * Author: Alksander Vladishev *
+ * *
+ * Comments: *
+ * *
+ ******************************************************************************/
+int expand_ipv6(const char *ip, char *str, size_t str_len )
+{
+ unsigned int i[8]; /* x:x:x:x:x:x:x:x */
+ char buf[5], *ptr;
+ int c, dc, pos = 0, j, len, ip_len, ret = FAIL;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In expand_ipv6(ip:%s)", ip);
+
+ c = 0; /* colons count */
+ for(ptr = strchr(ip, ':'); ptr != NULL; ptr = strchr(ptr + 1, ':'))
+ {
+ c ++;
+ }
+
+ if(c < 2 || c > 7)
+ {
+ goto out;
+ }
+
+ ip_len = strlen(ip);
+ if((ip[0] == ':' && ip[1] != ':') || (ip[ip_len - 1] == ':' && ip[ip_len - 2] != ':'))
+ {
+ goto out;
+ }
+
+ memset(i, 0x00, sizeof(i));
+
+ dc = 0; /* double colon flag */
+ len = 0;
+ for(j = 0; j<ip_len; j++)
+ {
+ if((ip[j] >= '0' && ip[j] <= '9') || (ip[j] >= 'A' && ip[j] <= 'F') || (ip[j] >= 'a' && ip[j] <= 'f'))
+ {
+ if(len > 3)
+ {
+ goto out;
+ }
+ buf[len ++] = ip[j];
+ }
+ else if(ip[j] != ':')
+ {
+ goto out;
+ }
+
+ if(ip[j] == ':' || ip[j + 1] == '\0')
+ {
+ if(len)
+ {
+ buf[len] = 0x00;
+ sscanf(buf, "%x", &i[pos]);
+ pos ++;
+ len = 0;
+ }
+
+ if(ip[j + 1] == ':')
+ {
+ if(dc == 0)
+ {
+ dc = 1;
+ pos = ( 8 - c ) + pos + (j == 0 ? 1 : 0);
+ }
+ else
+ {
+ goto out;
+ }
+ }
+ }
+ }
+ zbx_snprintf(str, str_len, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x", i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]);
+ ret = SUCCEED;
+out:
+ zabbix_log(LOG_LEVEL_DEBUG, "End expand_ipv6(ip:%s,str:%s,ret:%s)", ip, str, ret == SUCCEED ? "SUCCEED" : "FAIL");
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
+ * Function: ip_in_list_ipv6 *
+ * *
+ * Purpose: check if ip matches range of ip addresses *
+ * *
+ * Parameters: list - IPs [12fc::2-55,::45] *
+ * *
+ * Return value: FAIL - out of range, SUCCEED - within the range *
+ * *
+ * Author: Alexei Vladishev *
+ * *
+ * Comments: *
+ * *
+ ******************************************************************************/
+int ip_in_list_ipv6(char *list, char *ip)
+{
+ char *start, *comma = NULL, *dash = NULL, buffer[MAX_STRING_LEN];
+ int i[8], j[9], ret = FAIL;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In ip_in_list(list:%s,ip:%s)", list, ip);
+
+ if(FAIL == expand_ipv6(ip, buffer, sizeof(buffer)))
+ {
+ goto out;
+ }
+
+ if(sscanf(buffer, "%x:%x:%x:%x:%x:%x:%x:%x", &i[0], &i[1], &i[2], &i[3], &i[4], &i[5], &i[6], &i[7]) != 8)
+ {
+ goto out;
+ }
+
+ for(start = list; start[0] != '\0';)
+ {
+
+ if(NULL != (comma = strchr(start, ',')))
+ {
+ comma[0] = '\0';
+ }
+
+ if(NULL != (dash = strchr(start, '-')))
+ {
+ dash[0] = '\0';
+ if(sscanf(dash + 1, "%x", &j[8]) != 1)
+ {
+ goto next;
+ }
+ }
+
+ if(FAIL == expand_ipv6(start, buffer, sizeof(buffer)))
+ {
+ goto next;
+ }
+
+ if(sscanf(buffer, "%x:%x:%x:%x:%x:%x:%x:%x", &j[0], &j[1], &j[2], &j[3], &j[4], &j[5], &j[6], &j[7]) != 8)
+ {
+ goto next;
+ }
+
+ if(dash == NULL)
+ {
+ j[8] = j[7];
+ }
+
+ if(i[0] == j[0] && i[1] == j[1] && i[2] == j[2] && i[3] == j[3] &&
+ i[4] == j[4] && i[5] == j[5] && i[6] == j[6] &&
+ i[7] >= j[7] && i[7] <= j[8])
+ {
+ ret = SUCCEED;
+ break;
+ }
+next:
+ if(dash != NULL)
+ {
+ dash[0] = '-';
+ dash = NULL;
+ }
+
+ if(comma != NULL)
+ {
+ comma[0] = ',';
+ start = comma + 1;
+ comma = NULL;
+ }
+ else
+ {
+ break;
+ }
+ }
+out:
+ if(dash != NULL)
+ {
+ dash[0] = '-';
+ }
+
+ if(comma != NULL)
+ {
+ comma[0] = ',';
+ }
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End ip_in_list(ret:%s)", ret == SUCCEED ? "SUCCEED" : "FAIL");
+ return ret;
+}
+#endif /*HAVE_IPV6*/
/******************************************************************************
* *
* Function: ip_in_list *
@@ -240,7 +437,6 @@ int calculate_item_nextcheck(zbx_uint64_t itemid, int item_type, int delay, char
* Purpose: check if ip matches range of ip addresses *
* *
* Parameters: list - IPs [192.168.1.1-244,192.168.1.250] *
- * value- value *
* *
* Return value: FAIL - out of range, SUCCEED - within the range *
* *
@@ -252,49 +448,63 @@ int calculate_item_nextcheck(zbx_uint64_t itemid, int item_type, int delay, char
int ip_in_list(char *list, char *ip)
{
char c = '\0';
- int i1,i2,i3,i4,i5,j1,j2,j3,j4;
+ int i[4], j[5];
int ret = FAIL;
- char *start = NULL, *end = NULL;
-
+ char *start = NULL, *comma = NULL, *dash = NULL;
- zabbix_log( LOG_LEVEL_DEBUG, "In ip_in_list(list:%s,ip:%s)",
- list,
- ip);
+ zabbix_log( LOG_LEVEL_DEBUG, "In ip_in_list(list:%s,ip:%s)", list, ip);
- if(sscanf(ip,"%d.%d.%d.%d",&j1,&j2,&j3,&j4) != 4)
- return FAIL;
+ if(sscanf(ip, "%d.%d.%d.%d", &i[0], &i[1], &i[2], &i[3]) != 4)
+ {
+#if defined(HAVE_IPV6)
+ ret = ip_in_list_ipv6(list, ip);
+#endif /*HAVE_IPV6*/
+ goto out;
+ }
for(start = list; start[0] != '\0';)
{
- end=strchr(start, ',');
-
- if(end != NULL)
+ if(NULL != (comma = strchr(start, ',')))
{
- c=end[0];
- end[0]='\0';
+ comma[0] = '\0';
}
- if(sscanf(start,"%d.%d.%d.%d-%d",&i1,&i2,&i3,&i4,&i5) == 5)
+ if(NULL != (dash = strchr(start, '-')))
{
- if(i1==j1 && i2==j2 && i3==j3 && j4>=i4 && j4<=i5)
+ dash[0] = '\0';
+ if(sscanf(dash + 1, "%d", &j[4]) != 1)
{
- ret = SUCCEED;
- break;
+ goto next;
}
}
- else if(sscanf(start,"%d.%d.%d.%d",&i1,&i2,&i3,&i4) == 4)
+
+ if(sscanf(start, "%d.%d.%d.%d", &j[0], &j[1], &j[2], &j[3]) != 4)
{
- if(i1==j1 && i2==j2 && i3==j3 && j4==i4)
- {
- ret = SUCCEED;
- break;
- }
+ goto next;
}
- if(end != NULL)
+ if(dash == NULL)
{
- end[0]=c;
- start=end+1;
+ j[4] = j[3];
+ }
+
+ if(i[0] == j[0] && i[1] == j[1] && i[2] == j[2] && i[3] >= j[3] && i[3] <= j[4])
+ {
+ ret = SUCCEED;
+ break;
+ }
+next:
+ if(dash != NULL)
+ {
+ dash[0] = '-';
+ dash = NULL;
+ }
+
+ if(comma != NULL)
+ {
+ comma[0] = ',';
+ start = comma + 1;
+ comma = NULL;
}
else
{
@@ -302,13 +512,18 @@ int ip_in_list(char *list, char *ip)
}
}
- if(end != NULL)
+out:
+ if(dash != NULL)
{
- end[0]=c;
+ dash[0] = '-';
}
- zabbix_log( LOG_LEVEL_DEBUG, "End ip_in_list(ret:%s)", ret == SUCCEED?"SUCCEED":"FAIL");
+ if(comma != NULL)
+ {
+ comma[0] = ',';
+ }
+ zabbix_log( LOG_LEVEL_DEBUG, "End ip_in_list(ret:%s)", ret == SUCCEED ? "SUCCEED" : "FAIL");
return ret;
}
diff --git a/src/libs/zbxcomms/comms.c b/src/libs/zbxcomms/comms.c
index e1f9f075..534fe010 100644
--- a/src/libs/zbxcomms/comms.c
+++ b/src/libs/zbxcomms/comms.c
@@ -112,28 +112,59 @@ static void __zbx_zbx_set_tcp_strerror(const char *fmt, ...)
* *
* Parameters: *
* *
- * Return value: hostent or NULL - an error occured *
+ * Return value: *
* *
* Author: Alexei Vladishev *
* *
* Comments: *
* *
******************************************************************************/
-struct hostent *zbx_gethost_by_ip(const char *ip)
+
+#if defined(HAVE_IPV6)
+void zbx_gethost_by_ip(const char *ip, char *host, size_t hostlen)
+{
+ struct addrinfo hints, *ai = NULL;
+
+ assert(ip);
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ if(0 != getaddrinfo(ip, NULL, &hints, &ai))
+ {
+ host[0] = '\0';
+ goto out;
+ }
+ if(0 != getnameinfo(ai->ai_addr, ai->ai_addrlen, host, hostlen, NULL, 0, NI_NAMEREQD))
+ {
+ host[0] = '\0';
+ goto out;
+ }
+out:
+ freeaddrinfo(ai);
+}
+#else
+void zbx_gethost_by_ip(const char *ip, char *host, size_t hostlen)
{
struct in_addr addr;
- struct hostent* host;
+ struct hostent *hst;
assert(ip);
- if(inet_aton(ip, &addr) != 0)
+ if(inet_aton(ip, &addr) == 0)
{
- host = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET);
- if(host) return host;
+ host[0] = '\0';
+ return;
}
- return (struct hostent*) NULL;
+ if(NULL == (hst = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET)))
+ {
+ host[0] = '\0';
+ return;
+ }
+
+ zbx_strlcpy(host, hst->h_name, hostlen);
}
+#endif /*HAVE_IPV6*/
#endif /* WINDOWS */
/******************************************************************************
@@ -232,7 +263,7 @@ static int zbx_tcp_start(void)
* *
* Parameters: *
* *
- * Return value: *
+ * Return value: *
* *
* Author: Alexei Vladishev *
* *
@@ -254,7 +285,7 @@ static void zbx_tcp_clean(zbx_sock_t *s)
* *
* Parameters: *
* *
- * Return value: *
+ * Return value: *
* *
* Author: Eugene Grigorjev *
* *
@@ -275,7 +306,7 @@ void zbx_tcp_init(zbx_sock_t *s, ZBX_SOCKET o)
* *
* Parameters: *
* *
- * Return value: sockfd - open socket *
+ * Return value: sockfd - open socket *
* FAIL - an error occured *
* *
* Author: Alexei Vladishev *
@@ -283,9 +314,48 @@ void zbx_tcp_init(zbx_sock_t *s, ZBX_SOCKET o)
* Comments: *
* *
******************************************************************************/
-int zbx_tcp_connect(zbx_sock_t *s, const char *ip, unsigned short port)
+#if defined(HAVE_IPV6)
+int zbx_tcp_connect(zbx_sock_t *s, const char *ip, unsigned short port)
+{
+ int ret=SUCCEED;
+ struct addrinfo *ai, hints;
+ char service[MAX_STRING_LEN];
+
+ ZBX_TCP_START();
+
+ zbx_tcp_clean(s);
+
+ zbx_snprintf(service, sizeof(service), "%d", port);
+ memset(&hints, 0x00, sizeof(struct addrinfo));
+ hints.ai_flags = AI_ADDRCONFIG;
+ hints.ai_socktype = SOCK_STREAM;
+
+ if( 0 != getaddrinfo (ip, service, &hints, &ai)) {
+ zbx_set_tcp_strerror("Cannot resolve [%s]", ip);
+ ret=FAIL;
+ goto out;
+ }
+
+ if( ZBX_SOCK_ERROR == (s->socket = socket (ai->ai_family, ai->ai_socktype, ai->ai_protocol)))
+ {
+ zbx_set_tcp_strerror("Cannot create socket [%s]:%d [%s]", ip, port ,strerror_from_system(zbx_sock_last_error()));
+ ret=FAIL;
+ goto out;
+ }
+
+ if( ZBX_TCP_ERROR == connect(s->socket, ai->ai_addr, ai->ai_addrlen)) {
+ zbx_set_tcp_strerror("*** Cannot connect to [%s]:%d [%s]", ip, port, strerror_from_system(zbx_sock_last_error()));
+ zbx_tcp_close(s);
+ ret=FAIL;
+ goto out;
+ }
+out:
+ freeaddrinfo (ai);
+ return ret;
+}
+#else
+int zbx_tcp_connect(zbx_sock_t *s, const char *ip, unsigned short port)
{
- ZBX_SOCKADDR myaddr_in;
ZBX_SOCKADDR servaddr_in;
struct hostent *hp;
@@ -299,7 +369,6 @@ int zbx_tcp_connect(zbx_sock_t *s, const char *ip, unsigned short port)
zbx_set_tcp_strerror("Cannot resolve [%s]", ip);
return FAIL;
}
-
servaddr_in.sin_family = AF_INET;
servaddr_in.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr;
servaddr_in.sin_port = htons(port);
@@ -310,10 +379,6 @@ int zbx_tcp_connect(zbx_sock_t *s, const char *ip, unsigned short port)
return FAIL;
}
- myaddr_in.sin_family = AF_INET;
- myaddr_in.sin_port = 0;
- myaddr_in.sin_addr.s_addr = INADDR_ANY;
-
if( ZBX_TCP_ERROR == connect(s->socket,(struct sockaddr *)&servaddr_in,sizeof(ZBX_SOCKADDR)) )
{
zbx_set_tcp_strerror("Cannot connect to [%s:%d] [%s]", ip, port, strerror_from_system(zbx_sock_last_error()));
@@ -323,7 +388,7 @@ int zbx_tcp_connect(zbx_sock_t *s, const char *ip, unsigned short port)
return SUCCEED;
}
-
+#endif /*HAVE_IPV6*/
/******************************************************************************
* *
* Function: zbx_tcp_send *
@@ -332,7 +397,7 @@ int zbx_tcp_connect(zbx_sock_t *s, const char *ip, unsigned short port)
* *
* Parameters: *
* *
- * Return value: SUCCEED - success *
+ * Return value: SUCCEED - success *
* FAIL - an error occured *
* *
* Author: Eugene Grigorjev *
@@ -420,7 +485,7 @@ void zbx_tcp_close(zbx_sock_t *s)
* *
* Parameters: *
* *
- * Return value: SUCCEED - success *
+ * Return value: SUCCEED - success *
* FAIL - an error occured *
* *
* Author: Alexei Vladishev *
@@ -434,17 +499,35 @@ int zbx_tcp_listen(
unsigned short listen_port
)
{
- ZBX_SOCKADDR serv_addr;
- int on;
+#if defined(HAVE_IPV6)
+ struct addrinfo hints, *ai = NULL;
+ char port[MAX_STRING_LEN];
+#else
+ ZBX_SOCKADDR serv_addr;
+#endif /*HAVE_IPV6*/
+ int on, res = FAIL, e;
ZBX_TCP_START();
zbx_tcp_clean(s);
- if( ZBX_SOCK_ERROR == (s->socket = socket(AF_INET,SOCK_STREAM,0)) )
+#if defined(HAVE_IPV6)
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
+ hints.ai_socktype = SOCK_STREAM;
+ zbx_snprintf(port, sizeof(port), "%d", listen_port);
+ if(0 != (e = getaddrinfo(listen_ip, port, &hints, &ai)))
{
- zbx_set_tcp_strerror("Cannot create socket [%s:%u] [%s]", listen_ip, listen_port ,strerror_from_system(zbx_sock_last_error()));
- return FAIL;
+ zbx_set_tcp_strerror("Cannot getaddrinfo [%s:%u] [%s]", listen_ip, listen_port, gai_strerror(e));
+ goto out;
+ }
+ if(ZBX_SOCK_ERROR == (s->socket = socket(ai->ai_family, ai->ai_socktype,0)))
+#else
+ if(ZBX_SOCK_ERROR == (s->socket = socket(AF_INET,SOCK_STREAM,0)))
+#endif /*HAVE_IPV6*/
+ {
+ zbx_set_tcp_strerror("Cannot create socket [%s:%u] [%s]", listen_ip, listen_port, strerror_from_system(zbx_sock_last_error()));
+ goto out;
}
/* Enable address reuse */
@@ -457,29 +540,38 @@ int zbx_tcp_listen(
}
/* Create socket Fill in local address structure */
+#if defined(HAVE_IPV6)
+ if( -1 == bind(s->socket, ai->ai_addr, ai->ai_addrlen))
+#else
memset(&serv_addr, 0, sizeof(ZBX_SOCKADDR));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = listen_ip ? inet_addr(listen_ip) : htonl(INADDR_ANY);
- serv_addr.sin_port = htons((unsigned short)listen_port);
+ serv_addr.sin_port = htons((unsigned short)listen_port);
/* Bind socket */
if (ZBX_SOCK_ERROR == bind(s->socket,(struct sockaddr *)&serv_addr,sizeof(ZBX_SOCKADDR)) )
+#endif /*HAVE_IPV6*/
{
zbx_set_tcp_strerror("Cannot bind to port %u for server %s. Error [%s]. Another zabbix_agentd already running ?",
listen_port,
listen_ip ? listen_ip : "[ANY]",
strerror_from_system(zbx_sock_last_error()));
- return FAIL;
+ goto out;
}
if( ZBX_SOCK_ERROR == listen(s->socket, SOMAXCONN) )
{
zbx_set_tcp_strerror("Listen failed. [%s]", strerror_from_system(zbx_sock_last_error()));
- return FAIL;
+ goto out;
}
- return SUCCEED;
+ res = SUCCEED;
+out:
+#if defined(HAVE_IPV6)
+ freeaddrinfo (ai);
+#endif /*HAVE_IPV6*/
+ return res;
}
/******************************************************************************
@@ -578,7 +670,7 @@ void zbx_tcp_free(zbx_sock_t *s)
* *
* Parameters: *
* *
- * Return value: SUCCEED - success *
+ * Return value: SUCCEED - success *
* FAIL - an error occured *
* *
* Author: Eugene Grigorjev *
@@ -722,16 +814,21 @@ int zbx_tcp_check_security(
int allow_if_empty
)
{
- ZBX_SOCKADDR name;
+#if defined(HAVE_IPV6)
+ struct sockaddr_storage name;
+ struct addrinfo hints, *ai = NULL;
+#else
+ ZBX_SOCKADDR name;
+ struct hostent *hp;
+ char *sip;
+#endif
socklen_t nlen;
- struct hostent *hp;
-
- char
- tmp[MAX_STRING_LEN],
+ char tmp[MAX_STRING_LEN],
sname[MAX_STRING_LEN],
- *sip,
- *host;
+ *start = NULL,
+ *end = NULL,
+ c = '\0';
zabbix_log( LOG_LEVEL_DEBUG, "In check_security()");
@@ -739,7 +836,11 @@ int zbx_tcp_check_security(
{
return SUCCEED;
}
+#if defined(HAVE_IPV6)
+ nlen = sizeof(struct sockaddr_storage);
+#else
nlen = sizeof(ZBX_SOCKADDR);
+#endif /*HAVE_IPV6*/
if( ZBX_TCP_ERROR == getpeername(s->socket, (struct sockaddr*)&name, &nlen))
{
zbx_set_tcp_strerror("Connection rejected. Getpeername failed [%s]", strerror_from_system(zbx_sock_last_error()));
@@ -747,27 +848,86 @@ int zbx_tcp_check_security(
}
else
{
+#if !defined(HAVE_IPV6)
strcpy(sname, inet_ntoa(name.sin_addr));
-
+#endif /*HAVE_IPV6*/
strscpy(tmp,ip_list);
- host = (char *)strtok(tmp,",");
-
- while( NULL != host )
+ for(start = tmp; start[0] != '\0';)
{
+ end = strchr(start, ',');
+
+ if(end != NULL)
+ {
+ c = end[0];
+ end[0] = '\0';
+ }
+
/* Allow IP addresses or DNS names for authorization */
- if( 0 != (hp = zbx_gethost(host)))
+#if defined(HAVE_IPV6)
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ if(0 == getaddrinfo(start, NULL, &hints, &ai))
+ {
+ if(ai->ai_family == name.ss_family)
+ {
+ switch(ai->ai_family)
+ {
+ case AF_INET :
+ if(((struct sockaddr_in*)&name)->sin_addr.s_addr == ((struct sockaddr_in*)ai->ai_addr)->sin_addr.s_addr)
+ {
+ freeaddrinfo(ai);
+ return SUCCEED;
+ }
+ case AF_INET6 :
+ if(0 == memcmp(((struct sockaddr_in6*)&name)->sin6_addr.s6_addr,
+ ((struct sockaddr_in6*)ai->ai_addr)->sin6_addr.s6_addr,
+ sizeof(struct in6_addr)))
+ {
+ freeaddrinfo(ai);
+ return SUCCEED;
+ }
+ }
+ }
+ }
+ freeaddrinfo(ai);
+#else
+ if( 0 != (hp = zbx_gethost(start)))
{
sip = inet_ntoa(*((struct in_addr *)hp->h_addr));
if( 0 == strcmp(sname, sip))
{
- return SUCCEED;
+ return SUCCEED;
}
}
- host = (char *)strtok(NULL,",");
+#endif /*HAVE_IPV6*/
+ if(end != NULL)
+ {
+ end[0] = c;
+ start = end + 1;
+ }
+ else
+ {
+ break;
+ }
}
+
+ if(end != NULL)
+ {
+ end[0] = c;
+ }
+ }
+#if defined(HAVE_IPV6)
+ if(0 == getnameinfo((struct sockaddr*)&name, sizeof(name), sname, sizeof(sname), NULL, 0, NI_NUMERICHOST))
+ {
+ zbx_set_tcp_strerror("Connection from [%s] rejected. Allowed server is [%s] ",sname, ip_list);
}
+ else
+ {
+ zbx_set_tcp_strerror("Connection rejected. Allowed server is [%s] ", ip_list);
+ }
+#else
zbx_set_tcp_strerror("Connection from [%s] rejected. Allowed server is [%s] ",sname, ip_list);
+#endif /*HAVE_IPV6*/
return FAIL;
}
-
diff --git a/src/libs/zbxemail/email.c b/src/libs/zbxemail/email.c
index b89b9cac..f507ea1b 100644
--- a/src/libs/zbxemail/email.c
+++ b/src/libs/zbxemail/email.c
@@ -46,111 +46,81 @@
*/
int send_email(char *smtp_server,char *smtp_helo,char *smtp_email,char *mailto,char *mailsubject,char *mailbody, char *error, int max_error_len)
{
- int s;
- int i,e;
- char c[MAX_STRING_LEN], *cp = NULL;
- struct hostent *hp;
+ int ret=SUCCEED;
+ zbx_sock_t s;
+ int i,e;
+ char c[MAX_STRING_LEN], *cp = NULL;
- char str_time[MAX_STRING_LEN];
- struct tm *local_time = NULL;
- time_t email_time;
+ char str_time[MAX_STRING_LEN];
+ struct tm *local_time = NULL;
+ time_t email_time;
- struct sockaddr_in myaddr_in;
- struct sockaddr_in servaddr_in;
+ char *OK_220="220";
+ char *OK_250="250";
+ char *OK_251="251";
+ char *OK_354="354";
- char *OK_220="220";
- char *OK_250="250";
- char *OK_251="251";
- char *OK_354="354";
+ zabbix_log( LOG_LEVEL_DEBUG, "In send_email[smtp_server:%s]", smtp_server);
- zabbix_log( LOG_LEVEL_DEBUG, "In send_email[smtp_server:%s]",
- smtp_server);
-
- servaddr_in.sin_family=AF_INET;
-
- if(NULL == (hp = zbx_gethost(smtp_server)))
- {
- zbx_snprintf(error,max_error_len,"Cannot get IP for mailserver [%s]",smtp_server);
- zabbix_log(LOG_LEVEL_DEBUG, "%s",error);
- zabbix_syslog("%s",error);
- return FAIL;
- }
-
- servaddr_in.sin_addr.s_addr=((struct in_addr *)(hp->h_addr))->s_addr;
- servaddr_in.sin_port=htons(25);
-
- s=socket(AF_INET,SOCK_STREAM,0);
- if(s == -1)
- {
- zbx_snprintf(error,max_error_len,"Cannot create socket [%s]",strerror(errno));
- zabbix_log(LOG_LEVEL_DEBUG, "%s", error);
- zabbix_syslog("%s", error);
- return FAIL;
- }
-
- myaddr_in.sin_family = AF_INET;
- myaddr_in.sin_port=0;
- myaddr_in.sin_addr.s_addr=INADDR_ANY;
-
- if( connect(s,(struct sockaddr *)&servaddr_in,sizeof(struct sockaddr_in)) == -1 )
+ if(FAIL == zbx_tcp_connect(&s, smtp_server, 25))
{
- zbx_snprintf(error,max_error_len,"Cannot connect to SMTP server [%s] [%s]", smtp_server, strerror(errno));
+ zbx_snprintf(error,max_error_len,"Cannot connect to SMTP server [%s] [%s]", smtp_server, zbx_tcp_strerror());
zabbix_log(LOG_LEVEL_DEBUG, "%s", error);
zabbix_syslog("%s",error);
- close(s);
- return FAIL;
+ ret=FAIL;
+ goto out;
}
memset(c,0,MAX_STRING_LEN);
- i=read(s,c,MAX_STRING_LEN);
+ i=read(s.socket,c,MAX_STRING_LEN);
if(i == -1)
{
zbx_snprintf(error,max_error_len,"Error receiving initial string from SMTP server [%s]", strerror(errno));
zabbix_log(LOG_LEVEL_DEBUG, "%s", error);
zabbix_syslog("%s", error);
- close(s);
- return FAIL;
+ ret=FAIL;
+ goto out;
}
if(strncmp(OK_220,c,strlen(OK_220)) != 0)
{
zbx_snprintf(error,max_error_len,"No welcome message 220* from SMTP server [%s]", c);
zabbix_log(LOG_LEVEL_DEBUG, "%s", error);
zabbix_syslog("%s", error);
- close(s);
- return FAIL;
+ ret=FAIL;
+ goto out;
}
if(strlen(smtp_helo) != 0)
{
memset(c,0,MAX_STRING_LEN);
zbx_snprintf(c,sizeof(c),"HELO %s\r\n",smtp_helo);
- e=write(s,c,strlen(c));
+ e=write(s.socket,c,strlen(c));
if(e == -1)
{
zbx_snprintf(error,max_error_len,"Error sending HELO to mailserver [%s]", strerror(errno));
zabbix_log(LOG_LEVEL_DEBUG, "%s", error);
zabbix_syslog("%s", error);
- close(s);
- return FAIL;
+ ret=FAIL;
+ goto out;
}
memset(c,0,MAX_STRING_LEN);
- i=read(s,c,MAX_STRING_LEN);
+ i=read(s.socket,c,MAX_STRING_LEN);
if(i == -1)
{
zbx_snprintf(error,max_error_len,"Error receiving answer on HELO request [%s]", strerror(errno));
zabbix_log(LOG_LEVEL_DEBUG, "%s", error);
zabbix_syslog("%s", error);
- close(s);
- return FAIL;
+ ret=FAIL;
+ goto out;
}
if(strncmp(OK_250,c,strlen(OK_250)) != 0)
{
zbx_snprintf(error,max_error_len,"Wrong answer on HELO [%s]", c);
zabbix_log(LOG_LEVEL_DEBUG, "%s",error);
zabbix_syslog("%s",error);
- close(s);
- return FAIL;
+ ret=FAIL;
+ goto out;
}
}
@@ -158,55 +128,55 @@ int send_email(char *smtp_server,char *smtp_helo,char *smtp_email,char *mailto,c
zbx_snprintf(c,sizeof(c),"MAIL FROM: <%s>\r\n",smtp_email);
- e=write(s,c,strlen(c));
+ e=write(s.socket,c,strlen(c));
if(e == -1)
{
zbx_snprintf(error,max_error_len,"Error sending MAIL FROM to mailserver [%s]", strerror(errno));
zabbix_log(LOG_LEVEL_DEBUG, "%s", error);
zabbix_syslog("%s", error);
- close(s);
- return FAIL;
+ ret=FAIL;
+ goto out;
}
memset(c,0,MAX_STRING_LEN);
- i=read(s,c,MAX_STRING_LEN);
+ i=read(s.socket,c,MAX_STRING_LEN);
if(i == -1)
{
zbx_snprintf(error,max_error_len,"Error receiving answer on MAIL FROM request [%s]", strerror(errno));
zabbix_log(LOG_LEVEL_DEBUG, "%s", error);
zabbix_syslog("%s", error);
- close(s);
- return FAIL;
+ ret=FAIL;
+ goto out;
}
if(strncmp(OK_250,c,strlen(OK_250)) != 0)
{
zbx_snprintf(error,max_error_len,"Wrong answer on MAIL FROM [%s]", c);
zabbix_log(LOG_LEVEL_DEBUG, "%s", error);
zabbix_syslog("%s", error);
- close(s);
- return FAIL;
+ ret=FAIL;
+ goto out;
}
memset(c,0,MAX_STRING_LEN);
zbx_snprintf(c,sizeof(c),"RCPT TO: <%s>\r\n",mailto);
- e=write(s,c,strlen(c));
+ e=write(s.socket,c,strlen(c));
if(e == -1)
{
zbx_snprintf(error,max_error_len,"Error sending RCPT TO to mailserver [%s]", strerror(errno));
zabbix_log(LOG_LEVEL_DEBUG, "%s", error);
zabbix_syslog("%s", error);
- close(s);
- return FAIL;
+ ret=FAIL;
+ goto out;
}
memset(c,0,MAX_STRING_LEN);
- i=read(s,c,MAX_STRING_LEN);
+ i=read(s.socket,c,MAX_STRING_LEN);
if(i == -1)
{
zbx_snprintf(error,max_error_len,"Error receiving answer on RCPT TO request [%s]", strerror(errno));
zabbix_log(LOG_LEVEL_DEBUG, "%s", error);
zabbix_syslog("%s", error);
- close(s);
- return FAIL;
+ ret=FAIL;
+ goto out;
}
/* May return 251 as well: User not local; will forward to <forward-path>. See RFC825 */
if( strncmp(OK_250,c,strlen(OK_250)) != 0 && strncmp(OK_251,c,strlen(OK_251)) != 0)
@@ -214,38 +184,38 @@ int send_email(char *smtp_server,char *smtp_helo,char *smtp_email,char *mailto,c
zbx_snprintf(error,max_error_len,"Wrong answer on RCPT TO [%s]", c);
zabbix_log(LOG_LEVEL_DEBUG, "%s", error);
zabbix_syslog("%s", error);
- close(s);
- return FAIL;
+ ret=FAIL;
+ goto out;
}
memset(c,0,MAX_STRING_LEN);
zbx_snprintf(c,sizeof(c),"DATA\r\n");
- e=write(s,c,strlen(c));
+ e=write(s.socket,c,strlen(c));
if(e == -1)
{
zbx_snprintf(error,max_error_len,"Error sending DATA to mailserver [%s]", strerror(errno));
zabbix_log(LOG_LEVEL_DEBUG, "%s", error);
zabbix_syslog("%s", error);
- close(s);
- return FAIL;
+ ret=FAIL;
+ goto out;
}
memset(c,0,MAX_STRING_LEN);
- i=read(s,c,MAX_STRING_LEN);
+ i=read(s.socket,c,MAX_STRING_LEN);
if(i == -1)
{
zbx_snprintf(error,max_error_len,"Error receivng answer on DATA request [%s]", strerror(errno));
zabbix_log(LOG_LEVEL_DEBUG, "%s", error);
zabbix_syslog("%s", error);
- close(s);
- return FAIL;
+ ret=FAIL;
+ goto out;
}
if(strncmp(OK_354,c,strlen(OK_354)) != 0)
{
zbx_snprintf(error,max_error_len,"Wrong answer on DATA [%s]", c);
zabbix_log(LOG_LEVEL_DEBUG, "%s", error);
zabbix_syslog("%s", error);
- close(s);
- return FAIL;
+ ret=FAIL;
+ goto out;
}
cp = string_replace(mailsubject, "\r\n", "\n");
@@ -261,7 +231,7 @@ int send_email(char *smtp_server,char *smtp_helo,char *smtp_email,char *mailto,c
local_time = localtime(&email_time);
strftime( str_time, MAX_STRING_LEN, "%a, %d %b %Y %H:%M:%S %z", local_time );
cp = zbx_dsprintf(cp,"From:<%s>\r\nTo:<%s>\r\nDate: %s\r\nSubject: %s\r\n\r\n%s",smtp_email,mailto,str_time,mailsubject, mailbody);
- e=write(s,cp,strlen(cp));
+ e=write(s.socket,cp,strlen(cp));
zbx_free(cp);
zbx_free(mailsubject);
zbx_free(mailbody);
@@ -270,54 +240,52 @@ int send_email(char *smtp_server,char *smtp_helo,char *smtp_email,char *mailto,c
zbx_snprintf(error,max_error_len,"Error sending mail subject and body to mailserver [%s]", strerror(errno));
zabbix_log(LOG_LEVEL_DEBUG, "%s", error);
zabbix_syslog("%s", error);
- close(s);
- return FAIL;
+ ret=FAIL;
+ goto out;
}
memset(c,0,MAX_STRING_LEN);
zbx_snprintf(c,sizeof(c),"\r\n.\r\n");
- e=write(s,c,strlen(c));
+ e=write(s.socket,c,strlen(c));
if(e == -1)
{
zbx_snprintf(error,max_error_len,"Error sending . to mailserver [%s]", strerror(errno));
zabbix_log(LOG_LEVEL_DEBUG, "%s", error);
zabbix_syslog("%s",error);
- close(s);
- return FAIL;
+ ret=FAIL;
+ goto out;
}
memset(c,0,MAX_STRING_LEN);
- i=read(s,c,MAX_STRING_LEN);
+ i=read(s.socket,c,MAX_STRING_LEN);
if(i == -1)
{
- zabbix_log(LOG_LEVEL_DEBUG, "Error receivng answer on . request [%s]", strerror(errno));
- zabbix_syslog("Error receivng answer on . request [%s]", strerror(errno));
zbx_snprintf(error,max_error_len,"Error receivng answer on . request [%s]", strerror(errno));
- close(s);
- return FAIL;
+ zabbix_log(LOG_LEVEL_DEBUG, "%s", error);
+ zabbix_syslog("%s", error);
+ ret=FAIL;
+ goto out;
}
if(strncmp(OK_250,c,strlen(OK_250)) != 0)
{
zbx_snprintf(error,max_error_len,"Wrong answer on end of data [%s]", c);
zabbix_log(LOG_LEVEL_DEBUG, "%s", error);
zabbix_syslog("%s",error);
- close(s);
- return FAIL;
+ ret=FAIL;
+ goto out;
}
memset(c,0,MAX_STRING_LEN);
zbx_snprintf(c,sizeof(c),"QUIT\r\n");
- e=write(s,c,strlen(c));
+ e=write(s.socket,c,strlen(c));
if(e == -1)
{
zbx_snprintf(error,max_error_len,"Error sending QUIT to mailserver [%s]", strerror(errno));
zabbix_log(LOG_LEVEL_DEBUG, "%s", error);
zabbix_syslog("%s",error);
- close(s);
- return FAIL;
+ ret=FAIL;
+ goto out;
}
-
- close(s);
-
-
- return SUCCEED;
+out:
+ zbx_tcp_close(&s);
+ return ret;
}