diff -ur -x CVS monit.orig/CHANGES.txt monit/CHANGES.txt
--- monit.orig/CHANGES.txt 2004-12-19 19:43:30.000000000 +0100
+++ monit/CHANGES.txt 2004-12-19 19:41:42.000000000 +0100
@@ -29,6 +29,11 @@
the mod_status module, this test may be useful since you can test
the internals of Apache as reported by mod_status.
+* Allow statements accept additionally numeric networks in IP/MASK
+ syntax:
+ allow 192.168.1.0/255.255.255.0
+ allow 10.0.0.0/8
+
BUGFIXES:
* Fix total real memory usage statistic on Darwin.
Binary files monit.orig/doc/presentation.sxi and monit/doc/presentation.sxi differ
diff -ur -x CVS monit.orig/http/cervlet.c monit/http/cervlet.c
--- monit.orig/http/cervlet.c 2004-12-19 19:43:34.000000000 +0100
+++ monit/http/cervlet.c 2004-12-19 18:11:56.000000000 +0100
@@ -433,10 +433,10 @@
out_print(res,
"
httpd auth. style | %s |
",
- (Run.credentials!=NULL)&&has_hosts_allow()?
- "Basic Authentication and Host allow list":
+ (Run.credentials!=NULL)&&(has_hosts_allow())?
+ "Basic Authentication and Host/Net allow list":
(Run.credentials!=NULL)?"Basic Authentication":
- has_hosts_allow()?"Host allow list":
+ (has_hosts_allow())?"Host/Net allow list":
"No authentication");
print_alerts(res, Run.maillist);
diff -ur -x CVS monit.orig/http/engine.c monit/http/engine.c
--- monit.orig/http/engine.c 2004-10-30 15:04:53.000000000 +0200
+++ monit/http/engine.c 2004-12-19 19:38:45.000000000 +0100
@@ -66,6 +66,10 @@
#include
#endif
+#ifdef HAVE_CTYPE_H
+#include
+#endif
+
#ifdef HAVE_STRINGS_H
#include
#endif
@@ -117,6 +121,10 @@
static volatile int stopped= FALSE;
ssl_server_connection *mySSLServerConnection= NULL;
static pthread_mutex_t hostlist_mutex= PTHREAD_MUTEX_INITIALIZER;
+struct ulong_net {
+ unsigned long network;
+ unsigned long mask;
+};
/* -------------------------------------------------------------- Prototypes */
@@ -124,11 +132,11 @@
static void check_Impl();
static void initialize_service();
-static int authenticate(const char*);
-static int is_host_allow(const char *);
+static int authenticate(const struct in_addr);
+static int is_host_allow(const struct in_addr);
static void destroy_host_allow(HostsAllow);
static Socket_T socket_producer(int, int, void*);
-
+static int parse_network(char *, struct ulong_net *);
/* ------------------------------------------------------------------ Public */
@@ -222,6 +230,7 @@
int add_host_allow(char *name) {
struct hostent *hp;
+ struct in_addr *inp;
if(! (hp= gethostbyname(name))) {
@@ -234,9 +243,12 @@
NEW(h);
while(*hp->h_addr_list) {
+
+ inp = (struct in_addr *) *hp->h_addr_list++;
- h->name= xstrdup( inet_ntoa( *(struct in_addr *) *hp->h_addr_list++));
-
+ h->network= inp->s_addr;
+ h->mask= 0xffffffff;
+
LOCK(hostlist_mutex)
if(hostlist) {
@@ -244,20 +256,28 @@
HostsAllow p, n;
for(n= p= hostlist; p; n= p, p= p->next) {
-
- if(!strcasecmp(p->name, name)) {
-
+
+ if((p->network == h->network) && ((p->mask == h->mask))) {
+ DEBUG("%s: Debug: Skipping redundant host '%s' (%s).\n",
+ prog, name, inet_ntoa(*(struct in_addr *) &h->network));
+
destroy_host_allow(h);
goto done;
}
}
-
+
+ DEBUG("%s: Debug: Adding host allow '%s' (%s).\n",
+ prog, name, inet_ntoa(*(struct in_addr *) &h->network));
+
n->next= h;
} else {
+ DEBUG("%s: Debug: Adding host allow '%s' (%s).\n",
+ prog, name, inet_ntoa(*(struct in_addr *) &h->network));
+
hostlist= h;
}
@@ -273,6 +293,71 @@
}
+/**
+ * Add network allowed to connect to this server.
+ * @param s_network A network identifier in IP/mask format to be added
+ * to the hosts allow list
+ * @return FALSE if no correct network identifier is provided,
+ * otherwise TRUE
+ */
+
+int add_net_allow(char *s_network) {
+
+ struct ulong_net net;
+ HostsAllow h;
+
+ /* Add the network */
+
+ NEW(h);
+
+ if (!parse_network(s_network, &net)) {
+
+ return FALSE;
+
+ }
+
+ h->network=net.network;
+ h->mask=net.mask;
+
+ LOCK(hostlist_mutex)
+
+ if(hostlist) {
+
+ HostsAllow p, n;
+
+ for(n= p= hostlist; p; n= p, p= p->next) {
+
+ if((p->network == net.network) && ((p->mask == net.mask))) {
+
+ DEBUG("%s: Debug: Skipping redundant net '%s'.\n",
+ prog, s_network);
+ destroy_host_allow(h);
+ goto done;
+
+ }
+
+ }
+
+ DEBUG("%s: Debug: Adding net allow '%s'.\n",
+ prog, s_network);
+
+ n->next= h;
+
+ } else {
+
+ DEBUG("%s: Debug: Adding net allow '%s'.\n",
+ prog, s_network);
+
+ hostlist= h;
+
+ }
+
+ done:
+ END_LOCK;
+
+ return TRUE;
+}
+
/**
* Are any hosts present in the host allow list?
@@ -307,6 +392,119 @@
}
+/**
+ * Parse network string and return numeric IP and netmask
+ * @param s_network A network identifier in IP/mask format to be parsed
+ * @param net A structure holding IP and mask of the network
+ * @return FALSE if parsing failsm otherwise TRUE
+ */
+int parse_network(char *s_network, struct ulong_net *net) {
+
+ char *temp=s_network;
+ char *copy;
+ char *longmask=NULL;
+ int shortmask=0;
+ int slashcount=0;
+ int dotcount=0;
+ int count=0;
+ int rv=FALSE;
+ struct in_addr inp;
+
+ ASSERT(s_network);
+ ASSERT(net);
+
+ copy=xstrdup(s_network);
+ temp=copy;
+
+ /* decide if we have xxx.xxx.xxx.xxx/yyy or
+ xxx.xxx.xxx.xxx/yyy.yyy.yyy.yyy */
+ while (*temp!=0) {
+ if (*temp=='/') {
+ if ((slashcount==1) || (dotcount !=3)) {
+
+ goto done;
+
+ }
+ *temp=0;
+ temp++;
+ longmask=temp;
+ count=0;
+ slashcount=1;
+ dotcount=0;
+ } else if (*temp=='.') {
+
+ dotcount++;
+
+ } else if (!isdigit(*temp)) {
+
+ goto done;
+
+ }
+
+ count++;
+ temp++;
+ }
+
+ if ((dotcount==0) && (count > 1) && (count < 4)) {
+
+ shortmask=atoi(longmask);
+ longmask=NULL;
+
+ } else if (dotcount != 3) {
+
+ goto done;
+
+ }
+
+ /* Parse the network */
+
+ if (inet_aton(copy, &inp) == 0) {
+
+ goto done;
+
+ }
+ net->network=inp.s_addr;
+
+ if (longmask==NULL) {
+ if ((shortmask > 32) || (shortmask < 0)) {
+
+ goto done;
+
+ } else if ( shortmask == 32 ) {
+
+ net->mask=-1;
+
+ } else {
+
+ net->mask=(1<mask=inp.s_addr;
+
+ }
+
+ /* Remove bogus network components */
+ net->network&=net->mask;
+
+ /* Everything went fine, so we return TRUE! */
+ rv=TRUE;
+
+ done:
+
+ FREE(copy);
+ return rv;
+
+}
+
/* ----------------------------------------------------------------- Private */
@@ -345,10 +543,10 @@
* FALSE. If allow Basic Authentication is defined in the Run.Auth
* object, authentication is delegated to the processor module.
*/
-static int authenticate(const char *host) {
+static int authenticate(const struct in_addr addr) {
+
+ if(is_host_allow(addr)) {
- if(is_host_allow(host)) {
-
return TRUE;
}
@@ -359,7 +557,8 @@
}
- log("%s: Denied connection from non-authorized client [%s]\n", prog, host);
+ log("%s: Denied connection from non-authorized client [%s]\n", prog,
+ inet_ntoa(addr));
return FALSE;
@@ -370,7 +569,7 @@
* Returns TRUE if host is allowed to connect to
* this server
*/
-static int is_host_allow(const char *name) {
+static int is_host_allow(const struct in_addr addr) {
HostsAllow p;
int rv= FALSE;
@@ -379,8 +578,8 @@
for(p= hostlist; p; p= p->next) {
- if(!strncasecmp(p->name, name, STRLEN)) {
-
+ if((p->network & p->mask) == (addr.s_addr & p->mask)) {
+
rv= TRUE;
break;
@@ -390,6 +589,9 @@
END_LOCK;
+ if (rv)
+ return rv;
+
return rv;
}
@@ -439,7 +641,7 @@
goto error;
}
- if(! authenticate(inet_ntoa(in.sin_addr))) {
+ if(! authenticate(in.sin_addr)) {
goto error;
}
@@ -467,7 +669,6 @@
destroy_host_allow(a->next);
}
- FREE(a->name);
FREE(a);
}
diff -ur -x CVS monit.orig/http/engine.h monit/http/engine.h
--- monit.orig/http/engine.h 2004-03-12 19:56:03.000000000 +0100
+++ monit/http/engine.h 2004-12-19 18:04:28.000000000 +0100
@@ -34,7 +34,8 @@
#define DEFAULT_QUEUE_LEN 10
typedef struct host_allow {
- char *name;
+ unsigned long network;
+ unsigned long mask;
/* For internal use */
struct host_allow *next;
} *HostsAllow;
@@ -43,6 +44,7 @@
void start_httpd(int port, int backlog, char *bindAddr);
void stop_httpd();
int add_host_allow(char *);
+int add_net_allow(char *);
int has_hosts_allow();
void destroy_hosts_allow();
diff -ur -x CVS monit.orig/monit.pod monit/monit.pod
--- monit.orig/monit.pod 2004-12-19 19:43:31.000000000 +0100
+++ monit/monit.pod 2004-12-19 19:39:40.000000000 +0100
@@ -2015,13 +2015,15 @@
validation). Both schema's can be used together or by itself. You
B choose at least one.
-=head4 Host allow list
+=head4 Host and network allow list
-The http server maintains an access-control list of hosts allowed
-to connect to the server. You can add as many hosts as you want
-to, but only hosts with a valid domain name or its IP address are
-allowed. If you specify a hostname that does not resolve, monit
-will write an error message in the console and not start.
+The http server maintains an access-control list of hosts and
+networks allowed to connect to the server. You can add as many
+hosts as you want to, but only hosts with a valid domain name
+or its IP address are allowed. If you specify a hostname that
+does not resolve, monit will write an error message in the console
+and not start. Networks require a network IP and a netmask to be
+accepted.
The http server will query a name server to check any hosts
connecting to the server. If a host (client) is trying to connect
@@ -2035,6 +2037,8 @@
allow localhost
allow my.other.work.machine.com
allow 10.1.1.1
+ allow 192.168.1.0/255.255.255.0
+ allow 10.0.0.0/8
Clients, not mentioned in the allow list that tries to connect to
the server are logged with their ip-address.
diff -ur -x CVS monit.orig/p.y monit/p.y
--- monit.orig/p.y 2004-12-19 19:43:31.000000000 +0100
+++ monit/p.y 2004-12-19 19:46:19.000000000 +0100
@@ -569,12 +569,11 @@
| ALLOW CRYPT PATH { htpasswd_file= $3;
digesttype= DIGEST_CRYPT; }
allowuserlist { FREE(htpasswd_file);}
- | ALLOW STRING {
- if(!add_host_allow($2)) {
- yyerror2("hostname did not resolve",$2);
- }
- FREE($2);
- }
+ | ALLOW STRING { ;if (! (add_net_allow($2) || add_host_allow($2))) {
+ yyerror2("erroneous network or host identifier %s", $2);
+ }
+ FREE($2);
+ }
;
allowuserlist : allowuser
Exit 2