1 /*
2  * Copyright (C) Tildeslash Ltd. All rights reserved.
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU Affero General Public License version 3.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU Affero General Public License
13  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
14  *
15  * In addition, as a special exception, the copyright holders give
16  * permission to link the code of portions of this program with the
17  * OpenSSL library under certain conditions as described in each
18  * individual source file, and distribute linked combinations
19  * including the two.
20  *
21  * You must obey the GNU Affero General Public License in all respects
22  * for all of the code used other than OpenSSL.
23  */
24 
25 #include "config.h"
26 
27 #ifdef HAVE_STDIO_H
28 #include <stdio.h>
29 #endif
30 
31 #ifdef HAVE_STDLIB_H
32 #include <stdlib.h>
33 #endif
34 
35 #ifdef HAVE_ERRNO_H
36 #include <errno.h>
37 #endif
38 
39 #ifdef HAVE_SYS_TYPES_H
40 #include <sys/types.h>
41 #endif
42 
43 #ifdef HAVE_SYS_SOCKET_H
44 #include <sys/socket.h>
45 #endif
46 
47 #ifdef HAVE_NETDB_H
48 #include <netdb.h>
49 #endif
50 
51 #ifdef HAVE_UNISTD_H
52 #include <unistd.h>
53 #endif
54 
55 #ifdef HAVE_FCNTL_H
56 #include <fcntl.h>
57 #endif
58 
59 #ifdef HAVE_STRING_H
60 #include <string.h>
61 #endif
62 
63 #ifdef HAVE_CTYPE_H
64 #include <ctype.h>
65 #endif
66 
67 #ifdef HAVE_STRINGS_H
68 #include <strings.h>
69 #endif
70 
71 #ifdef HAVE_SYS_UN_H
72 #include <sys/un.h>
73 #endif
74 
75 #ifdef HAVE_NETINET_IN_H
76 #include <netinet/in.h>
77 #endif
78 
79 #ifdef HAVE_ARPA_INET_H
80 #include <arpa/inet.h>
81 #endif
82 
83 #ifdef HAVE_POLL_H
84 #include <poll.h>
85 #endif
86 
87 #include "monit.h"
88 #include "engine.h"
89 #include "processor.h"
90 #include "cervlet.h"
91 #include "net/net.h"
92 #include "SslServer.h"
93 
94 // libmonit
95 #include "system/Net.h"
96 #include "exceptions/AssertException.h"
97 #include "exceptions/IOException.h"
98 
99 
100 /**
101  *  A naive http 1.0 server. The server delegates handling of a HTTP
102  *  request and response to the processor module.
103  *
104  *  NOTE
105  *    This server does not use threads or forks; Requests are
106  *    serialized and pending requests will be popped from the
107  *    connection queue when the current request finish.
108  *
109  *    Since this server is written for monit, low traffic is expected.
110  *    Connect from not-authenticated clients will be closed down
111  *    promptly. The authentication schema or access control is based
112  *    on client name/address/pam and only requests from known clients are
113  *    accepted. Hosts allowed to connect to this server should be
114  *    added to the access control list by calling Engine_addHostAllow().
115  *
116  *  @file
117  */
118 
119 
120 /* ------------------------------------------------------------- Definitions */
121 
122 
123 typedef struct HostsAllow_T {
124         uint32_t address[4]; // IPv4 or IPv6 address
125         uint32_t mask[4];    // mask
126         /* For internal use */
127         struct HostsAllow_T *next;
128 } *HostsAllow_T;
129 
130 
131 #define MAX_SERVER_SOCKETS 3
132 
133 
134 static struct {
135         Socket_Family family;
136         union {
137                 struct sockaddr_storage addr_in;
138                 struct sockaddr_un addr_un;
139         } _addr;
140         struct sockaddr *addr;
141         socklen_t addrlen;
142 #ifdef HAVE_OPENSSL
143         SslServer_T ssl;
144 #endif
145 } data[MAX_SERVER_SOCKETS] = {};
146 
147 
148 static volatile bool stopped = false;
149 static int myServerSocketsCount = 0;
150 static struct pollfd myServerSockets[3] = {};
151 static HostsAllow_T allowlist = NULL;
152 
153 
154 /* ----------------------------------------------------------------- Private */
155 
156 
_hasAllow(HostsAllow_T host)157 static bool _hasAllow(HostsAllow_T host) {
158         for (HostsAllow_T p = allowlist; p; p = p->next)
159                 if (memcmp(p->address, &(host->address), 16) == 0 && memcmp(p->mask, &(host->mask), 16) == 0)
160                         return true;
161         return false;
162 }
163 
164 
_pushAllow(HostsAllow_T h,const char * pattern)165 static void _pushAllow(HostsAllow_T h, const char *pattern) {
166         char buf[INET6_ADDRSTRLEN] = {};
167         if (! Str_sub(pattern, "/"))
168                 inet_ntop(AF_INET6, &(h->address), buf, sizeof(buf));
169         if (_hasAllow(h))  {
170                 if (*buf)
171                         Log_warning("Skipping 'allow %s' -- host resolved to [%s] which is present in ACL already\n", pattern, buf);
172                 else
173                         Log_warning("Skipping 'allow %s' -- present in ACL already\n", pattern);
174                 FREE(h);
175         } else {
176                 if (*buf)
177                         DEBUG("Adding 'allow %s' -- host resolved to [%s]\n", pattern, buf);
178                 else
179                         DEBUG("Adding 'allow %s'\n", pattern);
180                 h->next = allowlist;
181                 allowlist = h;
182         }
183 }
184 
185 
_matchAllow(uint32_t address1[4],uint32_t address2[4],uint32_t mask[4])186 static bool _matchAllow(uint32_t address1[4], uint32_t address2[4], uint32_t mask[4]) {
187         for (int i = 0; i < 4; i++)
188                 if ((address1[i] & mask[i]) != (address2[i] & mask[i]))
189                         return false;
190         return true;
191 }
192 
193 
_isAllowed(uint32_t address[4])194 static bool _isAllowed(uint32_t address[4]) {
195         if (allowlist) {
196                 for (HostsAllow_T p = allowlist; p; p = p->next)
197                         if (_matchAllow(p->address, address, p->mask))
198                                 return true;
199                 return false;
200         }
201         return true;
202 }
203 
204 
_copyAllow(HostsAllow_T source)205 static HostsAllow_T _copyAllow(HostsAllow_T source) {
206         HostsAllow_T copy;
207         NEW(copy);
208         memcpy(copy, source, sizeof(struct HostsAllow_T));
209         return copy;
210 }
211 
212 
_mapIPv4toIPv6(uint32_t * address4,uint32_t * address6)213 static void _mapIPv4toIPv6(uint32_t *address4, uint32_t *address6) {
214         // Map IPv4 address to IPv6 "::ffff:x.x.x.x" notation, so we can compare IPv4 address in IPv6 namespace
215         *(address6 + 0) = 0x00000000;
216         *(address6 + 1) = 0x00000000;
217         *(address6 + 2) = htonl(0x0000ffff);
218         *(address6 + 3) = *address4;
219 }
220 
221 
_parseNetwork(char * pattern)222 static bool _parseNetwork(char *pattern) {
223         char *longmask = NULL;
224         int shortmask = 0;
225         int slashcount = 0;
226         int dotcount = 0;
227         int columncount = 0;
228         int count = 0;
229 
230         char buf[STRLEN];
231         strncpy(buf, pattern, sizeof(buf) - 1);
232         char *temp = buf;
233         Socket_Family family = Socket_Ip4;
234         // check if we have IPv4/IPv6 CIDR notation (x.x.x.x/yyy or x::/y) or IPv4 dot-decimal (x.x.x.x/y.y.y.y)
235         while (*temp) {
236                 if (*temp == '/') {
237                         if (slashcount > 0 || (family == Socket_Ip4 && dotcount != 3) || (family == Socket_Ip6 && columncount < 2))
238                                 return false; // The "/" was found already or its prefix doesn't look like valid address
239                         *temp = 0;
240                         longmask = *(temp + 1) ? temp + 1 : NULL;
241                         slashcount++;
242                         dotcount = columncount = count = 0;
243                 } else if (*temp == '.') {
244                         if (family == Socket_Ip6 && slashcount > 0)
245                                 return false; // No "." allowed past "/" for IPv6 address
246                         dotcount++;
247                 } else if (*temp == ':') {
248                         if (slashcount > 0)
249                                 return false; // ":" not allowed past "/"
250                         columncount++;
251                         family = Socket_Ip6;
252                 } else {
253                         if (slashcount == 0) {
254                                 // [0-9a-fA-F] allowed before "/"
255                                 if (! isxdigit((int)*temp))
256                                         return false;
257                         } else {
258                                 // only [0-9] allowed past "/"
259                                 if (! isdigit((int)*temp))
260                                         return false;
261                         }
262                         count++;
263                 }
264                 temp++;
265         }
266         if (slashcount == 0) {
267                 // Host part only
268                 return false;
269         } else if (dotcount == 0 && count > 0 && count < 4) {
270                 // Mask in CIDR notation
271                 if (longmask) {
272                         shortmask = atoi(longmask);
273                         longmask = NULL;
274                 }
275         } else if (family == Socket_Ip4 && dotcount != 3) {
276                 // The IPv4 dot-decimal mask requires three dots
277                 return false;
278         }
279         struct HostsAllow_T net = {};
280         if (family == Socket_Ip4) {
281                 struct sockaddr_in addr;
282                 if (inet_pton(AF_INET, buf, &(addr.sin_addr)) != 1)
283                         return false;
284                 _mapIPv4toIPv6((uint32_t *)&(addr.sin_addr), net.address);
285         } else {
286 #ifdef HAVE_IPV6
287                 struct sockaddr_in6 addr;
288                 if (inet_pton(AF_INET6, buf, &(addr.sin6_addr)) != 1)
289                         return false;
290                 memcpy(net.address, &(addr.sin6_addr), 16);
291 #else
292                 THROW(AssertException, "IPv6 not supported on this system");
293 #endif
294         }
295         if (longmask == NULL) {
296                 // Convert CIDR notation to integer mask
297                 if (shortmask < 0)
298                         return false;
299                 if (family == Socket_Ip4) {
300                         if (shortmask > 32) {
301                                 return false;
302                         } else if (shortmask == 32) {
303                                 memset(net.mask, 0xff, 16);
304                         } else if (shortmask > 0) {
305                                 memset(net.mask, 0xff, 16);
306                                 net.mask[3] = htonl(0xffffffff << (32 - shortmask));
307                         }
308                 } else {
309                         if (shortmask > 128) {
310                                 return false;
311                         } else if (shortmask == 128) {
312                                 memset(net.mask, 0xff, 16);
313                         } else {
314                                 for (int i = 0; i < 4; i++) {
315                                         if (shortmask > 32) {
316                                                 net.mask[i] = 0xffffffff;
317                                                 shortmask -= 32;
318                                         } else if (shortmask > 0) {
319                                                 net.mask[i] = htonl(0xffffffff << (32 - shortmask));
320                                                 shortmask = 0;
321                                         } else {
322                                                 net.mask[i] = 0x00000000;
323                                         }
324                                 }
325                         }
326                 }
327         } else {
328                 // Parse IPv4 dot-decimal mask
329                 struct sockaddr_in addr;
330                 if (! inet_aton(longmask, &(addr.sin_addr)))
331                         return false;
332                 _mapIPv4toIPv6((uint32_t *)&(addr.sin_addr), net.mask);
333         }
334         _pushAllow(_copyAllow(&net), pattern);
335         return true;
336 }
337 
338 
339 //FIXME: don't store the translated hostname->IPaddress on Monit startup to support DHCP hosts ... resolve the hostname in _authenticateHost()
_parseHost(char * pattern)340 static bool _parseHost(char *pattern) {
341         struct addrinfo *res, hints = {
342                 .ai_protocol = IPPROTO_TCP
343         };
344         int added = 0;
345         if (! getaddrinfo(pattern, NULL, &hints, &res)) {
346                 for (struct addrinfo *_res = res; _res; _res = _res->ai_next) {
347                         HostsAllow_T h = NULL;
348                         if (_res->ai_family == AF_INET) {
349                                 NEW(h);
350                                 struct sockaddr_in *sin = (struct sockaddr_in *)_res->ai_addr;
351                                 _mapIPv4toIPv6((uint32_t *)&(sin->sin_addr), h->address);
352                         }
353 #ifdef HAVE_IPV6
354                         else if (_res->ai_family == AF_INET6) {
355                                 NEW(h);
356                                 struct sockaddr_in6 *sin = (struct sockaddr_in6 *)_res->ai_addr;
357                                 memcpy(&h->address, &(sin->sin6_addr), 16);
358                         }
359 #endif
360                         if (h) {
361                                 memset(h->mask, 0xff, 16); // compare all 128 bits
362                                 _pushAllow(h, pattern);
363                                 added++;
364                         }
365                 }
366                 freeaddrinfo(res);
367         }
368         return added ? true : false;
369 }
370 
371 
_authenticateHost(struct sockaddr * addr)372 static bool _authenticateHost(struct sockaddr *addr) {
373         if (addr->sa_family == AF_INET) {
374                 bool allow = false;
375                 struct sockaddr_in *a = (struct sockaddr_in *)addr;
376                 uint32_t address[4];
377                 _mapIPv4toIPv6((uint32_t *)&(a->sin_addr), (uint32_t *)&address);
378                 if (! (allow = _isAllowed(address)))
379                         Log_error("Denied connection from non-authorized client [%s]\n", inet_ntop(addr->sa_family, &a->sin_addr, (char[INET_ADDRSTRLEN]){}, INET_ADDRSTRLEN));
380                 return allow;
381         }
382 #ifdef HAVE_IPV6
383         else if (addr->sa_family == AF_INET6) {
384                 bool allow = false;
385                 struct sockaddr_in6 *a = (struct sockaddr_in6 *)addr;
386                 if (! (allow = _isAllowed((uint32_t *)&(a->sin6_addr))))
387                         Log_error("Denied connection from non-authorized client [%s]\n", inet_ntop(addr->sa_family, &(a->sin6_addr), (char[INET6_ADDRSTRLEN]){}, INET6_ADDRSTRLEN));
388                 return allow;
389         }
390 #endif
391         else if (addr->sa_family == AF_UNIX) {
392                 return true;
393         }
394         return false;
395 }
396 
397 
_socketProducer(void)398 static Socket_T _socketProducer(void) {
399         int r = 0;
400         do {
401                 r = poll(myServerSockets, myServerSocketsCount, 1000);
402         } while (r == -1 && errno == EINTR);
403         if (r > 0) {
404                 for (int i = 0; i < myServerSocketsCount; i++) {
405                         if (myServerSockets[i].revents & POLLIN) {
406                                 int client = accept(myServerSockets[i].fd, data[i].addr, &(data[i].addrlen));
407                                 if (client < 0) {
408                                         Log_error("HTTP server: cannot accept connection -- %s\n", stopped ? "service stopped" : STRERROR);
409                                         return NULL;
410                                 }
411                                 if (!Net_setNonBlocking(client) || !Net_canRead(client, 500) || !Net_canWrite(client, 500) || ! _authenticateHost(data[i].addr)) {
412                                         Net_abort(client);
413                                         return NULL;
414                                 }
415 #ifdef HAVE_OPENSSL
416                                 return Socket_createAccepted(client, data[i].addr, data[i].ssl);
417 #else
418                                 return Socket_createAccepted(client, data[i].addr, NULL);
419 #endif
420                         }
421                 }
422         }
423         return NULL;
424 }
425 
426 
_createTcpServer(Socket_Family family,char error[STRLEN])427 static void _createTcpServer(Socket_Family family, char error[STRLEN]) {
428         myServerSockets[myServerSocketsCount].fd = create_server_socket_tcp(Run.httpd.socket.net.address, Run.httpd.socket.net.port, family, 1024, error);
429         if (myServerSockets[myServerSocketsCount].fd != -1) {
430 #ifdef HAVE_OPENSSL
431                 if (Run.httpd.socket.net.ssl.flags & SSL_Enabled) {
432                         if (! (data[myServerSocketsCount].ssl = SslServer_new(myServerSockets[myServerSocketsCount].fd, &(Run.httpd.socket.net.ssl)))) {
433                                 strncpy(error, "Could not initialize SSL engine", STRLEN - 1);
434                                 Net_close(myServerSockets[myServerSocketsCount].fd);
435                                 return;
436                         }
437                 }
438 #endif
439                 data[myServerSocketsCount].family = family;
440                 data[myServerSocketsCount].addr = (struct sockaddr *)&(data[myServerSocketsCount]._addr.addr_in);
441                 data[myServerSocketsCount].addrlen = sizeof(struct sockaddr_storage);
442                 myServerSockets[myServerSocketsCount].events = POLLIN;
443                 myServerSocketsCount++;
444         }
445 }
446 
447 
_createUnixServer(char error[STRLEN])448 static void _createUnixServer(char error[STRLEN]) {
449         myServerSockets[myServerSocketsCount].fd = create_server_socket_unix(Run.httpd.socket.unix.path, 1024, error);
450         if (myServerSockets[myServerSocketsCount].fd != -1) {
451                 if (Run.httpd.flags & Httpd_UnixPermission) {
452                         if (chmod(Run.httpd.socket.unix.path, Run.httpd.socket.unix.permission) != 0) {
453                                 snprintf(error, STRLEN, "Could not change unix socket permission -- %s", STRERROR);
454                                 goto error;
455                         }
456                 }
457                 if (Run.httpd.flags & Httpd_UnixUid) {
458                         if (chown(Run.httpd.socket.unix.path, Run.httpd.socket.unix.uid, -1) != 0) {
459                                 snprintf(error, STRLEN, "Could not change unix socket uid -- %s", STRERROR);
460                                 goto error;
461                         }
462                 }
463                 if (Run.httpd.flags & Httpd_UnixGid) {
464                         if (chown(Run.httpd.socket.unix.path, -1, Run.httpd.socket.unix.gid) != 0) {
465                                 snprintf(error, STRLEN, "Could not change unix socket gid -- %s", STRERROR);
466                                 goto error;
467                         }
468                 }
469                 data[myServerSocketsCount].family = Socket_Unix;
470                 data[myServerSocketsCount].addr = (struct sockaddr *)&(data[myServerSocketsCount]._addr.addr_un);
471                 data[myServerSocketsCount].addrlen = sizeof(struct sockaddr_un);
472                 myServerSockets[myServerSocketsCount].events = POLLIN;
473                 myServerSocketsCount++;
474         }
475         return;
476 error:
477         Net_close(myServerSockets[myServerSocketsCount].fd);
478         unlink(Run.httpd.socket.unix.path);
479 }
480 
481 
482 /* ------------------------------------------------------------------ Public */
483 
484 
Engine_start()485 void Engine_start() {
486         if (Run.flags & Run_Stopped) {
487                 return;
488         }
489         Engine_cleanup();
490         init_service();
491         char error[MAX_SERVER_SOCKETS][STRLEN] = {};
492         if (Run.httpd.flags & Httpd_Net) {
493                 _createTcpServer(Socket_Ip4, error[0]);
494                 _createTcpServer(Socket_Ip6, error[1]);
495         }
496         if (Run.httpd.flags & Httpd_Unix) {
497                 _createUnixServer(error[2]);
498         }
499         if (myServerSocketsCount == 0) {
500                 // Log error only if no socket was created
501                 for (int i = 0; i < MAX_SERVER_SOCKETS; i++)
502                         if (STR_DEF(error[i]))
503                                 Log_error("HTTP server -- %s\n", error[i]);
504         } else {
505                 while (! stopped) {
506                         Socket_T S = _socketProducer();
507                         if (S)
508                                 http_processor(S);
509                 }
510                 for (int i = 0; i < myServerSocketsCount; i++) {
511 #ifdef HAVE_OPENSSL
512                         if (data[i].ssl)
513                                 SslServer_free(&(data[i].ssl));
514 #endif
515                         Net_close(myServerSockets[i].fd);
516                 }
517                 Engine_cleanup();
518         }
519 }
520 
521 
Engine_setStopped(bool stop)522 void Engine_setStopped(bool stop) {
523         stopped = stop;
524 }
525 
526 
Engine_stop()527 void Engine_stop() {
528         Engine_setStopped(true);
529 }
530 
531 
Engine_cleanup()532 void Engine_cleanup() {
533         myServerSocketsCount = 0;
534         if (Run.httpd.flags & Httpd_Unix && Run.httpd.socket.unix.path)
535                 unlink(Run.httpd.socket.unix.path);
536 }
537 
538 
Engine_addAllow(char * pattern)539 bool Engine_addAllow(char *pattern) {
540         ASSERT(pattern);
541         if (_parseNetwork(pattern) || _parseHost(pattern))
542                 return true;
543         return false;
544 }
545 
546 
Engine_hasAllow()547 bool Engine_hasAllow() {
548         return allowlist ? true : false;
549 }
550 
551 
Engine_destroyAllow()552 void Engine_destroyAllow() {
553         for (HostsAllow_T current = allowlist, next = NULL; current; current = next) {
554                 next = current->next;
555                 FREE(current);
556         }
557         allowlist = NULL;
558 }
559 
560