new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / rootcheck / check_open_ports.c
1 /* Copyright (C) 2009 Trend Micro Inc.
2  * All right reserved.
3  *
4  * This program is a free software; you can redistribute it
5  * and/or modify it under the terms of the GNU General Public
6  * License (version 2) as published by the FSF - Free Software
7  * Foundation
8  */
9
10 #include "shared.h"
11 #include "headers/debug_op.h"
12 #include "headers/defs.h"
13 #include "rootcheck.h"
14
15 #ifndef OSSECHIDS
16
17 /* Prototypes */
18 static int  connect_to_port(int proto, int port);
19 static void try_to_access_ports(void);
20
21 /* Global variables */
22 static int  _ports_open;
23 static int  open_ports_size;
24 static char open_ports_str[OS_SIZE_1024 + 1];
25
26
27 static int connect_to_port(int proto, int port)
28 {
29     int rc = 0;
30     int ossock;
31     struct sockaddr_in server;
32     struct sockaddr_in6 server6;
33 #ifdef WIN32
34     int salen = sizeof(struct sockaddr_in6);
35 #endif
36
37
38     if (proto == IPPROTO_UDP) {
39         if ((ossock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
40             return (0);
41         }
42     } else if (proto == IPPROTO_TCP) {
43         if ((ossock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
44             return (0);
45         }
46     } else {
47         return (0);
48     }
49
50     memset(&server, 0, sizeof(server));
51     server.sin_family      = AF_INET;
52     server.sin_port        = htons(port);
53     server.sin_addr.s_addr = inet_addr("127.0.0.1");
54
55     if (connect(ossock, (struct sockaddr *)&server, sizeof(server)) == 0) {
56         rc = 1;
57     }
58
59     close(ossock);
60
61     /* repeat for IPv6 */
62     if (proto == IPPROTO_UDP) {
63         if ((ossock = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
64             return(0);
65         }
66     } else if (proto == IPPROTO_TCP) {
67         if ((ossock = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP)) < 0) {
68             return(0);
69         }
70     }
71
72     memset(&server6, 0, sizeof(server6));
73 #ifdef WIN32
74     WSAStringToAddress("::1", AF_INET6, NULL, (LPSOCKADDR) &server6,
75                        (LPINT) &salen);
76 #else
77     server6.sin6_family = AF_INET6;
78     inet_pton(AF_INET6, "::1", &server6.sin6_addr.s6_addr);
79 #endif
80     server6.sin6_port = htons( port );
81
82     if(connect(ossock, (struct sockaddr *)&server6, sizeof(server6)) == 0) {
83         rc = 1;
84     }
85
86     close(ossock);
87
88     return (rc);
89 }
90
91 static void try_to_access_ports()
92 {
93     int i;
94
95     for (i = 0; i <= 65535; i++) {
96         if (total_ports_tcp[i] && connect_to_port(IPPROTO_TCP, i)) {
97             char port_proto[64];
98
99             if (_ports_open == 0) {
100                 snprintf(port_proto, 64, "\n      %d (tcp),", i);
101             } else {
102                 snprintf(port_proto, 64, "%d (tcp),", i);
103             }
104             strncat(open_ports_str, port_proto, open_ports_size);
105             open_ports_size -= strlen(port_proto) + 1;
106
107             _ports_open++;
108         }
109
110         if (total_ports_udp[i] && connect_to_port(IPPROTO_UDP, i)) {
111             char port_proto[64];
112
113             if (_ports_open == 0) {
114                 snprintf(port_proto, 64, "\n      %d (udp),", i);
115             } else {
116                 snprintf(port_proto, 64, "%d (udp),", i);
117             }
118
119             strncat(open_ports_str, port_proto, open_ports_size);
120             open_ports_size -= strlen(port_proto) + 1;
121
122             _ports_open++;
123         }
124
125         if (_ports_open >= 4) {
126             _ports_open = 0;
127         }
128     }
129
130 }
131 #endif
132
133 void check_open_ports()
134 {
135 #ifndef OSSECHIDS
136     memset(open_ports_str, '\0', OS_SIZE_1024 + 1);
137     open_ports_size = OS_SIZE_1024 - 1;
138     _ports_open = 0;
139
140     snprintf(open_ports_str, OS_SIZE_1024, "The following ports are open:");
141     open_ports_size -= strlen(open_ports_str) + 1;
142
143     /* Testing All ports */
144     try_to_access_ports();
145
146     open_ports_str[strlen(open_ports_str) - 1] = '\0';
147
148     notify_rk(ALERT_OK, open_ports_str);
149
150 #endif
151     return;
152 }
153