diff -x CVS -ru monit.orig/gc.c monit/gc.c
--- monit.orig/gc.c 2004-10-30 15:04:51.000000000 +0200
+++ monit/gc.c 2004-11-05 21:26:03.000000000 +0100
@@ -77,6 +77,7 @@
void gc() {
destroy_hosts_allow();
+ destroy_nets_allow();
gc_protocols();
diff -x CVS -ru monit.orig/http/cervlet.c monit/http/cervlet.c
--- monit.orig/http/cervlet.c 2004-10-30 15:04:53.000000000 +0200
+++ monit/http/cervlet.c 2004-11-05 22:42:47.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()||has_nets_allow())?
+ "Basic Authentication and Host/Net allow list":
(Run.credentials!=NULL)?"Basic Authentication":
- has_hosts_allow()?"Host allow list":
+ (has_hosts_allow()||has_nets_allow())?"Host/Net allow list":
"No authentication");
print_alerts(res, Run.maillist);
diff -x CVS -ru 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-11-05 23:22:58.000000000 +0100
@@ -66,6 +66,10 @@
#include
#endif
+#ifdef HAVE_CTYPE_H
+#include
+#endif
+
#ifdef HAVE_STRINGS_H
#include
#endif
@@ -114,9 +118,11 @@
static int myServerSocket= 0;
static HostsAllow hostlist= NULL;
+static NetsAllow netlist= NULL;
static volatile int stopped= FALSE;
ssl_server_connection *mySSLServerConnection= NULL;
static pthread_mutex_t hostlist_mutex= PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t netlist_mutex= PTHREAD_MUTEX_INITIALIZER;
/* -------------------------------------------------------------- Prototypes */
@@ -124,9 +130,10 @@
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 void destroy_net_allow(NetsAllow);
static Socket_T socket_producer(int, int, void*);
@@ -307,6 +314,163 @@
}
+int add_net_allow(char *s_network) {
+
+ unsigned long network=0;
+ unsigned long mask=0;
+ char *temp=s_network;
+ char *longmask=NULL;
+ int shortmask=0;
+ int slashcount=0;
+ int dotcount=0;
+ int count=0;
+ NetsAllow h;
+
+ struct in_addr inp;
+
+ /* 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)) {
+
+ return FALSE;
+
+ }
+ *temp=0;
+ temp++;
+ longmask=temp;
+ count=0;
+ slashcount=1;
+ dotcount=0;
+ } else if (*temp=='.') {
+
+ dotcount++;
+
+ } else if (!isdigit(*temp)) {
+
+ return FALSE;
+
+ }
+
+ count++;
+ temp++;
+ }
+
+ if ((dotcount==0) && (count > 1) && (count < 4)) {
+
+ shortmask=atoi(longmask);
+ longmask=NULL;
+
+ } else if (dotcount != 3) {
+
+ return FALSE;
+
+ }
+
+ /* Parse the network */
+
+ if (inet_aton(s_network, &inp) == 0) {
+
+ return FALSE;
+
+ }
+ network=inp.s_addr;
+
+ if (longmask==NULL) {
+ if ((shortmask > 32) || (shortmask < 0)) {
+
+ return FALSE;
+
+ } else if ( shortmask == 32 ) {
+
+ mask=-1;
+
+ } else {
+
+ mask=(1<network=network;
+ h->mask=mask;
+
+ LOCK(netlist_mutex)
+
+ if(netlist) {
+
+ NetsAllow p, n;
+
+ for(n= p= netlist; p; n= p, p= p->next) {
+
+ if((p->network == network) && ((p->mask == mask))) {
+
+ destroy_net_allow(h);
+ goto done;
+
+ }
+
+ }
+
+ n->next= h;
+
+ } else {
+
+ netlist= h;
+
+ }
+
+ done:
+ END_LOCK;
+
+ return TRUE;
+}
+
+/**
+ * Are any networks present in the net allow list?
+ * @return TRUE if the host allow list is non-empty, otherwise FALSE
+ */
+int has_nets_allow() {
+
+ int rv;
+
+ LOCK(netlist_mutex)
+ rv= (netlist != NULL);
+ END_LOCK;
+
+ return rv;
+
+}
+
+/**
+ * Free the net allow list
+ */
+void destroy_nets_allow() {
+
+ if(has_nets_allow()) {
+
+ LOCK(netlist_mutex)
+ destroy_net_allow(netlist);
+ netlist= NULL;
+ END_LOCK;
+
+ }
+
+}
+
/* ----------------------------------------------------------------- Private */
@@ -345,21 +509,22 @@
* 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;
}
- if(! has_hosts_allow() && (Run.credentials!=NULL)) {
+ if(! has_hosts_allow() && ! has_nets_allow() && (Run.credentials!=NULL)) {
return TRUE;
}
- 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,17 +535,36 @@
* 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;
+ NetsAllow n;
int rv= FALSE;
LOCK(hostlist_mutex)
for(p= hostlist; p; p= p->next) {
- if(!strncasecmp(p->name, name, STRLEN)) {
+ if(!strncasecmp(p->name, inet_ntoa(addr), STRLEN)) {
+
+ rv= TRUE;
+ break;
+ }
+
+ }
+
+ END_LOCK;
+
+ if (rv)
+ return rv;
+
+ LOCK(netlist_mutex)
+
+ for(n= netlist; n; n= n->next) {
+
+ if((n->network & n->mask) == (addr.s_addr & n->mask)) {
+
rv= TRUE;
break;
@@ -439,7 +623,7 @@
goto error;
}
- if(! authenticate(inet_ntoa(in.sin_addr))) {
+ if(! authenticate(in.sin_addr)) {
goto error;
}
@@ -472,3 +656,18 @@
}
+/**
+ * Free a (linked list of) net_allow ojbect(s).
+ */
+static void destroy_net_allow(NetsAllow p) {
+
+ NetsAllow a= p;
+
+ if(a->next) {
+ destroy_net_allow(a->next);
+ }
+
+ FREE(a);
+
+}
+
diff -x CVS -ru 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-11-05 21:57:05.000000000 +0100
@@ -39,12 +39,22 @@
struct host_allow *next;
} *HostsAllow;
+typedef struct net_allow {
+ unsigned long network;
+ unsigned long mask;
+ /* For internal use */
+ struct net_allow *next;
+} *NetsAllow;
+
/* Public prototypes */
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();
+int has_nets_allow();
void destroy_hosts_allow();
+void destroy_nets_allow();
#endif
diff -x CVS -ru monit.orig/l.l monit/l.l
--- monit.orig/l.l 2004-10-30 15:04:51.000000000 +0200
+++ monit/l.l 2004-11-05 21:55:03.000000000 +0100
@@ -232,6 +232,7 @@
recovered { return RECOVERED; }
else { return ELSE; }
collector { return COLLECTOR; }
+net { return NET; }
include { BEGIN(INCLUDE); }
{byte} { return BYTE; }
@@ -316,7 +317,7 @@
yylval.string= handle_quoted_string(yytext);
save_arg(); return STRING;
}
-
+
\'[^\']*\' {
steplinenobycr(yytext);
yylval.string= handle_quoted_string(yytext);
diff -x CVS -ru monit.orig/monit.pod monit/monit.pod
--- monit.orig/monit.pod 2004-10-30 15:04:51.000000000 +0200
+++ monit/monit.pod 2004-11-05 23:18:00.000000000 +0100
@@ -1953,13 +1953,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
@@ -1973,6 +1975,8 @@
allow localhost
allow my.other.work.machine.com
allow 10.1.1.1
+ allow net 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 -x CVS -ru monit.orig/p.y monit/p.y
--- monit.orig/p.y 2004-10-30 15:04:51.000000000 +0200
+++ monit/p.y 2004-11-05 21:58:07.000000000 +0100
@@ -326,6 +326,7 @@
%token BYTE KILOBYTE MEGABYTE GIGABYTE
%token INODE SPACE PERMISSION SIZE
%token EXEC UNMONITOR ICMP ICMPECHO NONEXIST INVALID DATA RECOVERED
+%token NET
%left GREATER LESS EQUAL NOTEQUAL
@@ -647,6 +648,11 @@
| ALLOW CRYPT PATH { htpasswd_file= $3;
digesttype= DIGEST_CRYPT; }
allowuserlist { FREE(htpasswd_file);}
+ | ALLOW NET STRING { ;if (! add_net_allow($3)) {
+ yyerror2("erroneous network identifier %s", $3);
+ }
+ FREE($3);
+ }
| ALLOW STRING {
if(!add_host_allow($2)) {
yyerror2("hostname did not resolve",$2);